ia64.md revision 119256
1119610Sache;; IA-64 Machine description template
2119610Sache;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3136644Sache;; Contributed by James E. Wilson <wilson@cygnus.com> and
4119610Sache;;		  David Mosberger <davidm@hpl.hp.com>.
5119610Sache
6119610Sache;; This file is part of GNU CC.
7119610Sache
8119610Sache;; GNU CC is free software; you can redistribute it and/or modify
9119610Sache;; it under the terms of the GNU General Public License as published by
10119610Sache;; the Free Software Foundation; either version 2, or (at your option)
11119610Sache;; any later version.
12119610Sache
13119610Sache;; GNU CC is distributed in the hope that it will be useful,
14119610Sache;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15119610Sache;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16119610Sache;; GNU General Public License for more details.
17119610Sache
18119610Sache;; You should have received a copy of the GNU General Public License
19119610Sache;; along with GNU CC; see the file COPYING.  If not, write to
20119610Sache;; the Free Software Foundation, 59 Temple Place - Suite 330,
21119610Sache;; Boston, MA 02111-1307, USA.
22119610Sache
23119610Sache;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24119610Sache
25119610Sache;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
26119610Sache;; reload.  This will be fixed once scheduling support is turned on.
27119610Sache
28119610Sache;; ??? Optimize for post-increment addressing modes.
29119610Sache
30119610Sache;; ??? fselect is not supported, because there is no integer register
31119610Sache;; equivalent.
32119610Sache
33119610Sache;; ??? fp abs/min/max instructions may also work for integer values.
34119610Sache
35119610Sache;; ??? Would a predicate_reg_operand predicate be useful?  The HP one is buggy,
36119610Sache;; it assumes the operand is a register and takes REGNO of it without checking.
37119610Sache
38119610Sache;; ??? Would a branch_reg_operand predicate be useful?  The HP one is buggy,
39119610Sache;; it assumes the operand is a register and takes REGNO of it without checking.
40119610Sache
41119610Sache;; ??? Go through list of documented named patterns and look for more to
42119610Sache;; implement.
43119610Sache
44119610Sache;; ??? Go through instruction manual and look for more instructions that
45119610Sache;; can be emitted.
46119610Sache
47119610Sache;; ??? Add function unit scheduling info for Itanium (TM) processor.
48119610Sache
49119610Sache;; ??? Need a better way to describe alternate fp status registers.
50119610Sache
51119610Sache(define_constants
52119610Sache  [; Relocations
53119610Sache   (UNSPEC_LTOFF_DTPMOD		0)
54119610Sache   (UNSPEC_LTOFF_DTPREL		1)
55119610Sache   (UNSPEC_DTPREL		2)
56119610Sache   (UNSPEC_LTOFF_TPREL		3)
57119610Sache   (UNSPEC_TPREL		4)
58119610Sache
59119610Sache   (UNSPEC_LD_BASE		9)
60119610Sache   (UNSPEC_GR_SPILL		10)
61119610Sache   (UNSPEC_GR_RESTORE		11)
62119610Sache   (UNSPEC_FR_SPILL		12)
63119610Sache   (UNSPEC_FR_RESTORE		13)
64119610Sache   (UNSPEC_FR_RECIP_APPROX	14)
65119610Sache   (UNSPEC_PRED_REL_MUTEX	15)
66119610Sache   (UNSPEC_POPCNT		16)
67119610Sache   (UNSPEC_PIC_CALL		17)
68119610Sache   (UNSPEC_MF			18)
69119610Sache   (UNSPEC_CMPXCHG_ACQ		19)
70119610Sache   (UNSPEC_FETCHADD_ACQ		20)
71119610Sache   (UNSPEC_BSP_VALUE		21)
72119610Sache   (UNSPEC_FLUSHRS		22)
73119610Sache   (UNSPEC_BUNDLE_SELECTOR	23)
74119610Sache   (UNSPEC_ADDP4		24)
75119610Sache   (UNSPEC_PROLOGUE_USE		25)
76119610Sache  ])
77119610Sache
78119610Sache(define_constants
79119610Sache  [(UNSPECV_ALLOC		0)
80119610Sache   (UNSPECV_BLOCKAGE		1)
81119610Sache   (UNSPECV_INSN_GROUP_BARRIER	2)
82119610Sache   (UNSPECV_BREAK		3)
83119610Sache   (UNSPECV_SET_BSP		4)
84119610Sache   (UNSPECV_PSAC_ALL		5)	; pred.safe_across_calls
85119610Sache   (UNSPECV_PSAC_NORMAL		6)
86119610Sache   (UNSPECV_SETJMP_RECEIVER	7)
87119610Sache  ])
88119610Sache
89119610Sache;; ::::::::::::::::::::
90119610Sache;; ::
91119610Sache;; :: Attributes
92119610Sache;; ::
93119610Sache;; ::::::::::::::::::::
94119610Sache
95136644Sache;; Instruction type.  This primarily determines how instructions can be
96119610Sache;; packed in bundles, and secondarily affects scheduling to function units.
97119610Sache
98119610Sache;; A alu, can go in I or M syllable of a bundle
99119610Sache;; I integer
100136644Sache;; M memory
101119610Sache;; F floating-point
102119610Sache;; B branch
103119610Sache;; L long immediate, takes two syllables
104119610Sache;; S stop bit
105119610Sache
106119610Sache;; ??? Should not have any pattern with type unknown.  Perhaps add code to
107119610Sache;; check this in md_reorg?  Currently use unknown for patterns which emit
108136644Sache;; multiple instructions, patterns which emit 0 instructions, and patterns
109136644Sache;; which emit instruction that can go in any slot (e.g. nop).
110119610Sache
111119610Sache(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
112119610Sache	fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
113119610Sache	chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
114119610Sache	syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f,
115119610Sache	nop_i,nop_m,nop_x,lfetch"
116119610Sache  (const_string "unknown"))
117119610Sache
118119610Sache;; chk_s has an I and an M form; use type A for convenience.
119119610Sache(define_attr "type" "unknown,A,I,M,F,B,L,X,S"
120119610Sache  (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
121119610Sache	 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
122119610Sache	 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
123119610Sache	 (eq_attr "itanium_class" "lfetch") (const_string "M")
124119610Sache	 (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A")
125119610Sache	 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
126119610Sache	 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
127119610Sache	 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
128119610Sache	 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
129119610Sache	 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
130119610Sache	 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
131119610Sache	 (eq_attr "itanium_class" "stop_bit") (const_string "S")
132119610Sache	 (eq_attr "itanium_class" "nop_x") (const_string "X")
133119610Sache	 (eq_attr "itanium_class" "long_i") (const_string "L")]
134119610Sache	(const_string "unknown")))
135119610Sache
136119610Sache(define_attr "itanium_requires_unit0" "no,yes"
137119610Sache  (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
138119610Sache	 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
139119610Sache	 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
140119610Sache	 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
141119610Sache	 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
142119610Sache	 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
143119610Sache	(const_string "no")))
144119610Sache
145119610Sache;; Predication.  True iff this instruction can be predicated.
146119610Sache
147119610Sache(define_attr "predicable" "no,yes" (const_string "yes"))
148119610Sache
149119610Sache
150119610Sache;; ::::::::::::::::::::
151119610Sache;; ::
152119610Sache;; :: Function Units
153119610Sache;; ::
154119610Sache;; ::::::::::::::::::::
155119610Sache
156119610Sache;; We define 6 "dummy" functional units.  All the real work to decide which
157119610Sache;; insn uses which unit is done by our MD_SCHED_REORDER hooks.  We only
158119610Sache;; have to ensure here that there are enough copies of the dummy unit so
159119610Sache;; that the scheduler doesn't get confused by MD_SCHED_REORDER.
160119610Sache;; Other than the 6 dummies for normal insns, we also add a single dummy unit
161119610Sache;; for stop bits.
162136644Sache
163119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br")     0 0)
164119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall")  0 0)
165119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp")   2 0)
166119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0)
167119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld")    9 0)
168119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac")   5 0)
169119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc")  5 0)
170119610Sache
171136644Sache;; There is only one insn `mov = ar.bsp' for frar_i:
172136644Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0)
173136644Sache;; There is only ony insn `mov = ar.unat' for frar_m:
174136644Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0)
175119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr")   2 0)
176136644Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr")   2 0)
177119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr")   2 0)
178119610Sache
179119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu")   1 0)
180119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp")   1 0)
181119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog")   1 0)
182119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf")   1 0)
183119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld")     2 0)
184119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0)
185119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul")  2 0)
186119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf")  2 0)
187119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi")  2 0)
188119610Sache
189119610Sache;; Now we have only one insn (flushrs) of such class.  We assume that flushrs
190119610Sache;; is the 1st syllable of the bundle after stop bit.
191119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m")  0 0)
192119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem")   11 0)
193119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf")    1 0)
194119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st")     1 0)
195119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0)
196119610Sache;; Now we use only one insn `mf'.  Therfore latency time is set up to 0.
197119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0)
198119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit")   1 0)
199119610Sache
200119610Sache;; There is only one insn `mov ar.pfs =' for toar_i therefore we use
201119610Sache;; latency time equal to 0:
202119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0)
203119610Sache;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
204119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0)
205119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr")   1 0)
206119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr")   9 0)
207119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr")   1 0)
208119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy")   7 0)
209119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd")    1 0)
210119610Sache
211125759Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m")  0 0)
212125759Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i")  0 0)
213119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f")  0 0)
214119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b")  0 0)
215119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x")  0 0)
216119610Sache
217119610Sache(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0)
218119610Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0)
219125759Sache(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0)
220125759Sache
221119610Sache;; ::::::::::::::::::::
222119610Sache;; ::
223119610Sache;; :: Moves
224119610Sache;; ::
225119610Sache;; ::::::::::::::::::::
226119610Sache
227119610Sache;; Set of a single predicate register.  This is only used to implement
228119610Sache;; pr-to-pr move and complement.
229119610Sache
230119610Sache(define_insn "*movcci"
231119610Sache  [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
232119610Sache	(match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
233125759Sache  ""
234125759Sache  "@
235125759Sache   cmp.ne %0, p0 = r0, r0
236125759Sache   cmp.eq %0, p0 = r0, r0
237125759Sache   (%1) cmp.eq.unc %0, p0 = r0, r0"
238125759Sache  [(set_attr "itanium_class" "icmp")
239119610Sache   (set_attr "predicable" "no")])
240119610Sache
241119610Sache(define_insn "movbi"
242119610Sache  [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
243119610Sache	(match_operand:BI 1 "move_operand"         " O,n, c,  c,*r, n,*m,*r,*r"))]
244119610Sache  ""
245119610Sache  "@
246119610Sache   cmp.ne %0, %I0 = r0, r0
247119610Sache   cmp.eq %0, %I0 = r0, r0
248119610Sache   #
249119610Sache   #
250119610Sache   tbit.nz %0, %I0 = %1, 0
251119610Sache   adds %0 = %1, r0
252119610Sache   ld1%O1 %0 = %1%P1
253119610Sache   st1%Q0 %0 = %1%P0
254119610Sache   mov %0 = %1"
255119610Sache  [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
256119610Sache
257119610Sache(define_split
258119610Sache  [(set (match_operand:BI 0 "register_operand" "")
259119610Sache	(match_operand:BI 1 "register_operand" ""))]
260119610Sache  "reload_completed
261119610Sache   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
262119610Sache   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
263119610Sache  [(cond_exec (ne (match_dup 1) (const_int 0))
264119610Sache     (set (match_dup 0) (const_int 1)))
265119610Sache   (cond_exec (eq (match_dup 1) (const_int 0))
266119610Sache     (set (match_dup 0) (const_int 0)))]
267119610Sache  "")
268119610Sache
269119610Sache(define_split
270119610Sache  [(set (match_operand:BI 0 "register_operand" "")
271119610Sache	(match_operand:BI 1 "register_operand" ""))]
272119610Sache  "reload_completed
273119610Sache   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
274119610Sache   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
275119610Sache  [(set (match_dup 2) (match_dup 4))
276119610Sache   (set (match_dup 3) (match_dup 5))
277119610Sache   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
278119610Sache  "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
279136644Sache   operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
280119610Sache   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
281119610Sache   operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
282119610Sache
283119610Sache(define_expand "movqi"
284119610Sache  [(set (match_operand:QI 0 "general_operand" "")
285119610Sache	(match_operand:QI 1 "general_operand" ""))]
286119610Sache  ""
287125759Sache{
288125759Sache  rtx op1 = ia64_expand_move (operands[0], operands[1]);
289119610Sache  if (!op1)
290136644Sache    DONE;
291125759Sache  operands[1] = op1;
292119610Sache})
293119610Sache
294119610Sache(define_insn "*movqi_internal"
295119610Sache  [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
296119610Sache	(match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
297119610Sache  "ia64_move_ok (operands[0], operands[1])"
298119610Sache  "@
299119610Sache   mov %0 = %r1
300119610Sache   addl %0 = %1, r0
301119610Sache   ld1%O1 %0 = %1%P1
302119610Sache   st1%Q0 %0 = %r1%P0
303119610Sache   getf.sig %0 = %1
304119610Sache   setf.sig %0 = %r1
305119610Sache   mov %0 = %1"
306119610Sache  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
307119610Sache
308119610Sache(define_expand "movhi"
309119610Sache  [(set (match_operand:HI 0 "general_operand" "")
310119610Sache	(match_operand:HI 1 "general_operand" ""))]
311119610Sache  ""
312119610Sache{
313119610Sache  rtx op1 = ia64_expand_move (operands[0], operands[1]);
314119610Sache  if (!op1)
315119610Sache    DONE;
316119610Sache  operands[1] = op1;
317119610Sache})
318119610Sache
319119610Sache(define_insn "*movhi_internal"
320119610Sache  [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
321119610Sache	(match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
322119610Sache  "ia64_move_ok (operands[0], operands[1])"
323119610Sache  "@
324119610Sache   mov %0 = %r1
325119610Sache   addl %0 = %1, r0
326119610Sache   ld2%O1 %0 = %1%P1
327119610Sache   st2%Q0 %0 = %r1%P0
328119610Sache   getf.sig %0 = %1
329119610Sache   setf.sig %0 = %r1
330119610Sache   mov %0 = %1"
331119610Sache  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
332119610Sache
333119610Sache(define_expand "movsi"
334119610Sache  [(set (match_operand:SI 0 "general_operand" "")
335119610Sache	(match_operand:SI 1 "general_operand" ""))]
336119610Sache  ""
337119610Sache{
338119610Sache  rtx op1 = ia64_expand_move (operands[0], operands[1]);
339119610Sache  if (!op1)
340119610Sache    DONE;
341119610Sache  operands[1] = op1;
342119610Sache})
343119610Sache
344119610Sache;; This is used during early compilation to delay the decision on
345119610Sache;; how to refer to a variable as long as possible.  This is especially
346119610Sache;; important between initial rtl generation and optimization for
347119610Sache;; deferred functions, since we may acquire additional information
348119610Sache;; on the variables used in the meantime.
349
350(define_insn_and_split "movsi_symbolic"
351  [(set (match_operand:SI 0 "register_operand" "=r")
352	(match_operand:SI 1 "symbolic_operand" "s"))
353   (clobber (match_scratch:DI 2 "=r"))
354   (use (reg:DI 1))]
355  ""
356  "* abort ();"
357  "!no_new_pseudos || reload_completed"
358  [(const_int 0)]
359{
360  rtx scratch = operands[2];
361  if (!reload_completed)
362    scratch = gen_reg_rtx (Pmode);
363  ia64_expand_load_address (operands[0], operands[1], scratch); 
364  DONE;
365})
366
367(define_insn "*movsi_internal"
368  [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
369	(match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
370  "ia64_move_ok (operands[0], operands[1])"
371  "@
372  mov %0 = %r1
373  addl %0 = %1, r0
374  movl %0 = %1
375  ld4%O1 %0 = %1%P1
376  st4%Q0 %0 = %r1%P0
377  getf.sig %0 = %1
378  setf.sig %0 = %r1
379  mov %0 = %1
380  mov %0 = %1
381  mov %0 = %r1"
382  ;; frar_m, toar_m ??? why not frar_i and toar_i
383  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
384
385(define_expand "movdi"
386  [(set (match_operand:DI 0 "general_operand" "")
387	(match_operand:DI 1 "general_operand" ""))]
388  ""
389{
390  rtx op1 = ia64_expand_move (operands[0], operands[1]);
391  if (!op1)
392    DONE;
393  operands[1] = op1;
394})
395
396;; This is used during early compilation to delay the decision on
397;; how to refer to a variable as long as possible.  This is especially
398;; important between initial rtl generation and optimization for
399;; deferred functions, since we may acquire additional information
400;; on the variables used in the meantime.
401
402(define_insn_and_split "movdi_symbolic"
403  [(set (match_operand:DI 0 "register_operand" "=r")
404	(match_operand:DI 1 "symbolic_operand" "s"))
405   (clobber (match_scratch:DI 2 "=r"))
406   (use (reg:DI 1))]
407  ""
408  "* abort ();"
409  "!no_new_pseudos || reload_completed"
410  [(const_int 0)]
411{
412  rtx scratch = operands[2];
413  if (!reload_completed)
414    scratch = gen_reg_rtx (Pmode);
415  ia64_expand_load_address (operands[0], operands[1], scratch); 
416  DONE;
417})
418
419(define_insn "*movdi_internal"
420  [(set (match_operand:DI 0 "destination_operand"
421		    "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
422	(match_operand:DI 1 "move_operand"
423		    "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
424  "ia64_move_ok (operands[0], operands[1])"
425{
426  static const char * const alt[] = {
427    "%,mov %0 = %r1",
428    "%,addl %0 = %1, r0",
429    "%,movl %0 = %1",
430    "%,ld8%O1 %0 = %1%P1",
431    "%,st8%Q0 %0 = %r1%P0",
432    "%,getf.sig %0 = %1",
433    "%,setf.sig %0 = %r1",
434    "%,mov %0 = %1",
435    "%,ldf8 %0 = %1%P1",
436    "%,stf8 %0 = %1%P0",
437    "%,mov %0 = %1",
438    "%,mov %0 = %r1",
439    "%,mov %0 = %1",
440    "%,mov %0 = %1",
441    "%,mov %0 = %1",
442    "%,mov %0 = %1",
443    "mov %0 = pr",
444    "mov pr = %1, -1"
445  };
446
447  if (which_alternative == 2 && ! TARGET_NO_PIC
448      && symbolic_operand (operands[1], VOIDmode))
449    abort ();
450
451  return alt[which_alternative];
452}
453  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,fld,stf,frbr,tobr,frar_i,toar_i,frar_m,toar_m,frpr,topr")])
454
455(define_split
456  [(set (match_operand:DI 0 "register_operand" "")
457	(match_operand:DI 1 "symbolic_operand" ""))]
458  "reload_completed && ! TARGET_NO_PIC"
459  [(const_int 0)]
460{
461  ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
462  DONE;
463})
464
465(define_expand "load_fptr"
466  [(set (match_dup 2)
467	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
468   (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
469  ""
470{
471  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
472  operands[3] = gen_rtx_MEM (DImode, operands[2]);
473  RTX_UNCHANGING_P (operands[3]) = 1;
474})
475
476(define_insn "*load_fptr_internal1"
477  [(set (match_operand:DI 0 "register_operand" "=r")
478	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
479  ""
480  "addl %0 = @ltoff(@fptr(%1)), gp"
481  [(set_attr "itanium_class" "ialu")])
482
483(define_insn "load_gprel"
484  [(set (match_operand:DI 0 "register_operand" "=r")
485	(plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
486  ""
487  "addl %0 = @gprel(%1), gp"
488  [(set_attr "itanium_class" "ialu")])
489
490(define_insn "gprel64_offset"
491  [(set (match_operand:DI 0 "register_operand" "=r")
492	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
493  ""
494  "movl %0 = @gprel(%1)"
495  [(set_attr "itanium_class" "long_i")])
496
497(define_expand "load_gprel64"
498  [(set (match_dup 2)
499	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
500   (set (match_operand:DI 0 "register_operand" "")
501	(plus:DI (match_dup 3) (match_dup 2)))]
502  ""
503{
504  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
505  operands[3] = pic_offset_table_rtx;
506})
507
508(define_expand "load_symptr"
509  [(set (match_operand:DI 2 "register_operand" "")
510	(plus:DI (high:DI (match_operand:DI 1 "got_symbolic_operand" ""))
511		 (match_dup 3)))
512   (set (match_operand:DI 0 "register_operand" "")
513	(lo_sum:DI (match_dup 2) (match_dup 1)))]
514  ""
515{
516  operands[3] = pic_offset_table_rtx;
517})
518
519(define_insn "*load_symptr_high"
520  [(set (match_operand:DI 0 "register_operand" "=r")
521	(plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
522		 (match_operand:DI 2 "register_operand" "a")))]
523  ""
524{
525  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
526    return "%,addl %0 = @ltoffx(%1), %2";
527  else
528    return "%,addl %0 = @ltoff(%1), %2";
529}
530  [(set_attr "itanium_class" "ialu")])
531
532(define_insn "*load_symptr_low"
533  [(set (match_operand:DI 0 "register_operand" "=r")
534	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
535		   (match_operand 2 "got_symbolic_operand" "s")))]
536  ""
537{
538  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
539    return "%,ld8.mov %0 = [%1], %2";
540  else
541    return "%,ld8 %0 = [%1]";
542}
543  [(set_attr "itanium_class" "ld")])
544
545(define_insn "load_ltoff_dtpmod"
546  [(set (match_operand:DI 0 "register_operand" "=r")
547	(plus:DI (reg:DI 1)
548		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
549			    UNSPEC_LTOFF_DTPMOD)))]
550  ""
551  "addl %0 = @ltoff(@dtpmod(%1)), gp"
552  [(set_attr "itanium_class" "ialu")])
553
554(define_insn "load_ltoff_dtprel"
555  [(set (match_operand:DI 0 "register_operand" "=r")
556	(plus:DI (reg:DI 1)
557		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
558			    UNSPEC_LTOFF_DTPREL)))]
559  ""
560  "addl %0 = @ltoff(@dtprel(%1)), gp"
561  [(set_attr "itanium_class" "ialu")])
562
563(define_expand "load_dtprel"
564  [(set (match_operand:DI 0 "register_operand" "")
565	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
566		   UNSPEC_DTPREL))]
567  ""
568  "")
569
570(define_insn "*load_dtprel64"
571  [(set (match_operand:DI 0 "register_operand" "=r")
572	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
573		   UNSPEC_DTPREL))]
574  "TARGET_TLS64"
575  "movl %0 = @dtprel(%1)"
576  [(set_attr "itanium_class" "long_i")])
577
578(define_insn "*load_dtprel22"
579  [(set (match_operand:DI 0 "register_operand" "=r")
580	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
581		   UNSPEC_DTPREL))]
582  ""
583  "addl %0 = @dtprel(%1), r0"
584  [(set_attr "itanium_class" "ialu")])
585
586(define_expand "add_dtprel"
587  [(set (match_operand:DI 0 "register_operand" "")
588	(plus:DI (match_operand:DI 1 "register_operand" "")
589		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
590			    UNSPEC_DTPREL)))]
591  "!TARGET_TLS64"
592  "")
593
594(define_insn "*add_dtprel14"
595  [(set (match_operand:DI 0 "register_operand" "=r")
596	(plus:DI (match_operand:DI 1 "register_operand" "r")
597		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
598			    UNSPEC_DTPREL)))]
599  "TARGET_TLS14"
600  "adds %0 = @dtprel(%2), %1"
601  [(set_attr "itanium_class" "ialu")])
602
603(define_insn "*add_dtprel22"
604  [(set (match_operand:DI 0 "register_operand" "=r")
605	(plus:DI (match_operand:DI 1 "register_operand" "a")
606		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
607			    UNSPEC_DTPREL)))]
608  "TARGET_TLS22"
609  "addl %0 = @dtprel(%2), %1"
610  [(set_attr "itanium_class" "ialu")])
611
612(define_insn "load_ltoff_tprel"
613  [(set (match_operand:DI 0 "register_operand" "=r")
614	(plus:DI (reg:DI 1)
615		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
616			    UNSPEC_LTOFF_TPREL)))]
617  ""
618  "addl %0 = @ltoff(@tprel(%1)), gp"
619  [(set_attr "itanium_class" "ialu")])
620
621(define_expand "load_tprel"
622  [(set (match_operand:DI 0 "register_operand" "")
623	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
624		   UNSPEC_TPREL))]
625  ""
626  "")
627
628(define_insn "*load_tprel64"
629  [(set (match_operand:DI 0 "register_operand" "=r")
630	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
631		   UNSPEC_TPREL))]
632  "TARGET_TLS64"
633  "movl %0 = @tprel(%1)"
634  [(set_attr "itanium_class" "long_i")])
635
636(define_insn "*load_tprel22"
637  [(set (match_operand:DI 0 "register_operand" "=r")
638	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
639		   UNSPEC_TPREL))]
640  ""
641  "addl %0 = @tprel(%1), r0"
642  [(set_attr "itanium_class" "ialu")])
643
644(define_expand "add_tprel"
645  [(set (match_operand:DI 0 "register_operand" "")
646	(plus:DI (match_operand:DI 1 "register_operand" "")
647		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
648			    UNSPEC_TPREL)))]
649  "!TARGET_TLS64"
650  "")
651
652(define_insn "*add_tprel14"
653  [(set (match_operand:DI 0 "register_operand" "=r")
654	(plus:DI (match_operand:DI 1 "register_operand" "r")
655		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
656			    UNSPEC_TPREL)))]
657  "TARGET_TLS14"
658  "adds %0 = @tprel(%2), %1"
659  [(set_attr "itanium_class" "ialu")])
660
661(define_insn "*add_tprel22"
662  [(set (match_operand:DI 0 "register_operand" "=r")
663	(plus:DI (match_operand:DI 1 "register_operand" "a")
664		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
665			    UNSPEC_TPREL)))]
666  "TARGET_TLS22"
667  "addl %0 = @tprel(%2), %1"
668  [(set_attr "itanium_class" "ialu")])
669
670;; With no offsettable memory references, we've got to have a scratch
671;; around to play with the second word.
672(define_expand "movti"
673  [(parallel [(set (match_operand:TI 0 "general_operand" "")
674		   (match_operand:TI 1 "general_operand" ""))
675	      (clobber (match_scratch:DI 2 ""))])]
676  ""
677{
678  rtx op1 = ia64_expand_move (operands[0], operands[1]);
679  if (!op1)
680    DONE;
681  operands[1] = op1;
682})
683
684(define_insn_and_split "*movti_internal"
685  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
686	(match_operand:TI 1 "general_operand"      "ri,m,r"))
687   (clobber (match_scratch:DI 2 "=X,&r,&r"))]
688  "ia64_move_ok (operands[0], operands[1])"
689  "#"
690  "reload_completed"
691  [(const_int 0)]
692{
693  rtx adj1, adj2, in[2], out[2], insn;
694  int first;
695
696  adj1 = ia64_split_timode (in, operands[1], operands[2]);
697  adj2 = ia64_split_timode (out, operands[0], operands[2]);
698
699  first = 0;
700  if (reg_overlap_mentioned_p (out[0], in[1]))
701    {
702      if (reg_overlap_mentioned_p (out[1], in[0]))
703	abort ();
704      first = 1;
705    }
706
707  if (adj1 && adj2)
708    abort ();
709  if (adj1)
710    emit_insn (adj1);
711  if (adj2)
712    emit_insn (adj2);
713  insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
714  if (GET_CODE (out[first]) == MEM
715      && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
716    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
717					  XEXP (XEXP (out[first], 0), 0),
718					  REG_NOTES (insn));
719  insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
720  if (GET_CODE (out[!first]) == MEM
721      && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
722    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
723					  XEXP (XEXP (out[!first], 0), 0),
724					  REG_NOTES (insn));
725  DONE;
726}
727  [(set_attr "itanium_class" "unknown")
728   (set_attr "predicable" "no")])
729
730;; ??? SSA creates these.  Can't allow memories since we don't have
731;; the scratch register.  Fortunately combine will know how to add
732;; the clobber and scratch.
733(define_insn_and_split "*movti_internal_reg"
734  [(set (match_operand:TI 0 "register_operand"  "=r")
735	(match_operand:TI 1 "nonmemory_operand" "ri"))]
736  ""
737  "#"
738  "reload_completed"
739  [(const_int 0)]
740{
741  rtx in[2], out[2];
742  int first;
743
744  ia64_split_timode (in, operands[1], NULL_RTX);
745  ia64_split_timode (out, operands[0], NULL_RTX);
746
747  first = 0;
748  if (reg_overlap_mentioned_p (out[0], in[1]))
749    {
750      if (reg_overlap_mentioned_p (out[1], in[0]))
751	abort ();
752      first = 1;
753    }
754
755  emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
756  emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
757  DONE;
758}
759  [(set_attr "itanium_class" "unknown")
760   (set_attr "predicable" "no")])
761
762(define_expand "reload_inti"
763  [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
764		   (match_operand:TI 1 "" "m"))
765	      (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
766  ""
767{
768  unsigned int s_regno = REGNO (operands[2]);
769  if (s_regno == REGNO (operands[0]))
770    s_regno += 1;
771  operands[2] = gen_rtx_REG (DImode, s_regno);
772})
773
774(define_expand "reload_outti"
775  [(parallel [(set (match_operand:TI 0 "" "=m")
776		   (match_operand:TI 1 "register_operand" "r"))
777	      (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
778  ""
779{
780  unsigned int s_regno = REGNO (operands[2]);
781  if (s_regno == REGNO (operands[1]))
782    s_regno += 1;
783  operands[2] = gen_rtx_REG (DImode, s_regno);
784})
785
786;; Floating Point Moves
787;;
788;; Note - Patterns for SF mode moves are compulsory, but
789;; patterns for DF are optional, as GCC can synthesize them.
790
791(define_expand "movsf"
792  [(set (match_operand:SF 0 "general_operand" "")
793	(match_operand:SF 1 "general_operand" ""))]
794  ""
795{
796  rtx op1 = ia64_expand_move (operands[0], operands[1]);
797  if (!op1)
798    DONE;
799  operands[1] = op1;
800})
801
802(define_insn "*movsf_internal"
803  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
804	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
805  "ia64_move_ok (operands[0], operands[1])"
806  "@
807   mov %0 = %F1
808   ldfs %0 = %1%P1
809   stfs %0 = %F1%P0
810   getf.s %0 = %F1
811   setf.s %0 = %1
812   mov %0 = %1
813   ld4%O1 %0 = %1%P1
814   st4%Q0 %0 = %1%P0"
815  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
816
817(define_expand "movdf"
818  [(set (match_operand:DF 0 "general_operand" "")
819	(match_operand:DF 1 "general_operand" ""))]
820  ""
821{
822  rtx op1 = ia64_expand_move (operands[0], operands[1]);
823  if (!op1)
824    DONE;
825  operands[1] = op1;
826})
827
828(define_insn "*movdf_internal"
829  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
830	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
831  "ia64_move_ok (operands[0], operands[1])"
832  "@
833   mov %0 = %F1
834   ldfd %0 = %1%P1
835   stfd %0 = %F1%P0
836   getf.d %0 = %F1
837   setf.d %0 = %1
838   mov %0 = %1
839   ld8%O1 %0 = %1%P1
840   st8%Q0 %0 = %1%P0"
841  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
842
843;; With no offsettable memory references, we've got to have a scratch
844;; around to play with the second word if the variable winds up in GRs.
845(define_expand "movtf"
846  [(set (match_operand:TF 0 "general_operand" "")
847	(match_operand:TF 1 "general_operand" ""))]
848  "INTEL_EXTENDED_IEEE_FORMAT"
849{
850  /* We must support TFmode loads into general registers for stdarg/vararg
851     and unprototyped calls.  We split them into DImode loads for convenience.
852     We don't need TFmode stores from general regs, because a stdarg/vararg
853     routine does a block store to memory of unnamed arguments.  */
854  if (GET_CODE (operands[0]) == REG
855      && GR_REGNO_P (REGNO (operands[0])))
856    {
857      /* We're hoping to transform everything that deals with TFmode
858	 quantities and GR registers early in the compiler.  */
859      if (no_new_pseudos)
860	abort ();
861
862      /* Struct to register can just use TImode instead.  */
863      if ((GET_CODE (operands[1]) == SUBREG
864	   && GET_MODE (SUBREG_REG (operands[1])) == TImode)
865	  || (GET_CODE (operands[1]) == REG
866	      && GR_REGNO_P (REGNO (operands[1]))))
867	{
868	  emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
869			  SUBREG_REG (operands[1]));
870	  DONE;
871	}
872
873      if (GET_CODE (operands[1]) == CONST_DOUBLE)
874	{
875	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
876			  operand_subword (operands[1], 0, 0, TFmode));
877	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
878			  operand_subword (operands[1], 1, 0, TFmode));
879	  DONE;
880	}
881
882      /* If the quantity is in a register not known to be GR, spill it.  */
883      if (register_operand (operands[1], TFmode))
884	operands[1] = spill_tfmode_operand (operands[1], 1);
885
886      if (GET_CODE (operands[1]) == MEM)
887	{
888	  rtx out[2];
889
890	  out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
891	  out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
892
893	  emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
894	  emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
895	  DONE;
896	}
897
898      abort ();
899    }
900
901  if (! reload_in_progress && ! reload_completed)
902    {
903      operands[0] = spill_tfmode_operand (operands[0], 0);
904      operands[1] = spill_tfmode_operand (operands[1], 0);
905
906      if (! ia64_move_ok (operands[0], operands[1]))
907	operands[1] = force_reg (TFmode, operands[1]);
908    }
909})
910
911;; ??? There's no easy way to mind volatile acquire/release semantics.
912
913(define_insn "*movtf_internal"
914  [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
915	(match_operand:TF 1 "general_tfmode_operand"     "fG,m,fG"))]
916  "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])"
917  "@
918   mov %0 = %F1
919   ldfe %0 = %1%P1
920   stfe %0 = %F1%P0"
921  [(set_attr "itanium_class" "fmisc,fld,stf")])
922
923;; ::::::::::::::::::::
924;; ::
925;; :: Conversions
926;; ::
927;; ::::::::::::::::::::
928
929;; Signed conversions from a smaller integer to a larger integer
930
931(define_insn "extendqidi2"
932  [(set (match_operand:DI 0 "gr_register_operand" "=r")
933	(sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
934  ""
935  "sxt1 %0 = %1"
936  [(set_attr "itanium_class" "xtd")])
937
938(define_insn "extendhidi2"
939  [(set (match_operand:DI 0 "gr_register_operand" "=r")
940	(sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
941  ""
942  "sxt2 %0 = %1"
943  [(set_attr "itanium_class" "xtd")])
944
945(define_insn "extendsidi2"
946  [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
947	(sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
948  ""
949  "@
950   sxt4 %0 = %1
951   fsxt.r %0 = %1, %1"
952  [(set_attr "itanium_class" "xtd,fmisc")])
953
954;; Unsigned conversions from a smaller integer to a larger integer
955
956(define_insn "zero_extendqidi2"
957  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
958	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
959  ""
960  "@
961   zxt1 %0 = %1
962   ld1%O1 %0 = %1%P1"
963  [(set_attr "itanium_class" "xtd,ld")])
964
965(define_insn "zero_extendhidi2"
966  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
967	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
968  ""
969  "@
970   zxt2 %0 = %1
971   ld2%O1 %0 = %1%P1"
972  [(set_attr "itanium_class" "xtd,ld")])
973
974(define_insn "zero_extendsidi2"
975  [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
976	(zero_extend:DI
977	  (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
978  ""
979  "@
980   zxt4 %0 = %1
981   ld4%O1 %0 = %1%P1
982   fmix.r %0 = f0, %1"
983  [(set_attr "itanium_class" "xtd,ld,fmisc")])
984
985;; Convert between floating point types of different sizes.
986
987;; At first glance, it would appear that emitting fnorm for an extending
988;; conversion is unnecessary.  However, the stf and getf instructions work
989;; correctly only if the input is properly rounded for its type.  In
990;; particular, we get the wrong result for getf.d/stfd if the input is a
991;; denorm single.  Since we don't know what the next instruction will be, we
992;; have to emit an fnorm.
993
994;; ??? Optimization opportunity here.  Get rid of the insn altogether
995;; when we can.  Should probably use a scheme like has been proposed
996;; for ia32 in dealing with operands that match unary operators.  This
997;; would let combine merge the thing into adjacent insns.  See also how the
998;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
999;; se_register_operand.
1000
1001(define_insn "extendsfdf2"
1002  [(set (match_operand:DF 0 "fr_register_operand" "=f")
1003	(float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
1004  ""
1005  "fnorm.d %0 = %1"
1006  [(set_attr "itanium_class" "fmac")])
1007
1008(define_insn "extendsftf2"
1009  [(set (match_operand:TF 0 "fr_register_operand" "=f")
1010	(float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))]
1011  "INTEL_EXTENDED_IEEE_FORMAT"
1012  "fnorm %0 = %1"
1013  [(set_attr "itanium_class" "fmac")])
1014
1015(define_insn "extenddftf2"
1016  [(set (match_operand:TF 0 "fr_register_operand" "=f")
1017	(float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))]
1018  "INTEL_EXTENDED_IEEE_FORMAT"
1019  "fnorm %0 = %1"
1020  [(set_attr "itanium_class" "fmac")])
1021
1022(define_insn "truncdfsf2"
1023  [(set (match_operand:SF 0 "fr_register_operand" "=f")
1024	(float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
1025  ""
1026  "fnorm.s %0 = %1"
1027  [(set_attr "itanium_class" "fmac")])
1028
1029(define_insn "trunctfsf2"
1030  [(set (match_operand:SF 0 "fr_register_operand" "=f")
1031	(float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
1032  "INTEL_EXTENDED_IEEE_FORMAT"
1033  "fnorm.s %0 = %1"
1034  [(set_attr "itanium_class" "fmac")])
1035
1036(define_insn "trunctfdf2"
1037  [(set (match_operand:DF 0 "fr_register_operand" "=f")
1038	(float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
1039  "INTEL_EXTENDED_IEEE_FORMAT"
1040  "fnorm.d %0 = %1"
1041  [(set_attr "itanium_class" "fmac")])
1042
1043;; Convert between signed integer types and floating point.
1044
1045(define_insn "floatditf2"
1046  [(set (match_operand:TF 0 "fr_register_operand" "=f")
1047	(float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
1048  "INTEL_EXTENDED_IEEE_FORMAT"
1049  "fcvt.xf %0 = %1"
1050  [(set_attr "itanium_class" "fcvtfx")])
1051
1052;; ??? Suboptimal.  This should be split somehow.
1053(define_insn "floatdidf2"
1054  [(set (match_operand:DF 0 "register_operand" "=f")
1055        (float:DF (match_operand:DI 1 "register_operand" "f")))]
1056  "!INTEL_EXTENDED_IEEE_FORMAT"
1057  "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0"
1058  [(set_attr "itanium_class" "fcvtfx")])
1059
1060;; ??? Suboptimal.  This should be split somehow.
1061(define_insn "floatdisf2"
1062  [(set (match_operand:SF 0 "register_operand" "=f")
1063        (float:SF (match_operand:DI 1 "register_operand" "f")))]
1064  "!INTEL_EXTENDED_IEEE_FORMAT"
1065  "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0"
1066  [(set_attr "itanium_class" "fcvtfx")])
1067
1068(define_insn "fix_truncsfdi2"
1069  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1070	(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1071  ""
1072  "fcvt.fx.trunc %0 = %1"
1073  [(set_attr "itanium_class" "fcvtfx")])
1074
1075(define_insn "fix_truncdfdi2"
1076  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1077	(fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1078  ""
1079  "fcvt.fx.trunc %0 = %1"
1080  [(set_attr "itanium_class" "fcvtfx")])
1081
1082(define_insn "fix_trunctfdi2"
1083  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1084	(fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
1085  "INTEL_EXTENDED_IEEE_FORMAT"
1086  "fcvt.fx.trunc %0 = %1"
1087  [(set_attr "itanium_class" "fcvtfx")])
1088
1089(define_insn "fix_trunctfdi2_alts"
1090  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1091	(fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
1092   (use (match_operand:SI 2 "const_int_operand" ""))]
1093  "INTEL_EXTENDED_IEEE_FORMAT"
1094  "fcvt.fx.trunc.s%2 %0 = %1"
1095  [(set_attr "itanium_class" "fcvtfx")])
1096
1097;; Convert between unsigned integer types and floating point.
1098
1099(define_insn "floatunsdisf2"
1100  [(set (match_operand:SF 0 "fr_register_operand" "=f")
1101	(unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
1102  ""
1103  "fcvt.xuf.s %0 = %1"
1104  [(set_attr "itanium_class" "fcvtfx")])
1105
1106(define_insn "floatunsdidf2"
1107  [(set (match_operand:DF 0 "fr_register_operand" "=f")
1108	(unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
1109  ""
1110  "fcvt.xuf.d %0 = %1"
1111  [(set_attr "itanium_class" "fcvtfx")])
1112
1113(define_insn "floatunsditf2"
1114  [(set (match_operand:TF 0 "fr_register_operand" "=f")
1115	(unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
1116  "INTEL_EXTENDED_IEEE_FORMAT"
1117  "fcvt.xuf %0 = %1"
1118  [(set_attr "itanium_class" "fcvtfx")])
1119
1120(define_insn "fixuns_truncsfdi2"
1121  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1122	(unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1123  ""
1124  "fcvt.fxu.trunc %0 = %1"
1125  [(set_attr "itanium_class" "fcvtfx")])
1126
1127(define_insn "fixuns_truncdfdi2"
1128  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1129	(unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1130  ""
1131  "fcvt.fxu.trunc %0 = %1"
1132  [(set_attr "itanium_class" "fcvtfx")])
1133
1134(define_insn "fixuns_trunctfdi2"
1135  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1136	(unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
1137  "INTEL_EXTENDED_IEEE_FORMAT"
1138  "fcvt.fxu.trunc %0 = %1"
1139  [(set_attr "itanium_class" "fcvtfx")])
1140
1141(define_insn "fixuns_trunctfdi2_alts"
1142  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1143	(unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
1144   (use (match_operand:SI 2 "const_int_operand" ""))]
1145  "INTEL_EXTENDED_IEEE_FORMAT"
1146  "fcvt.fxu.trunc.s%2 %0 = %1"
1147  [(set_attr "itanium_class" "fcvtfx")])
1148
1149;; ::::::::::::::::::::
1150;; ::
1151;; :: Bit field extraction
1152;; ::
1153;; ::::::::::::::::::::
1154
1155(define_insn "extv"
1156  [(set (match_operand:DI 0 "gr_register_operand" "=r")
1157	(sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1158			 (match_operand:DI 2 "const_int_operand" "n")
1159			 (match_operand:DI 3 "const_int_operand" "n")))]
1160  ""
1161  "extr %0 = %1, %3, %2"
1162  [(set_attr "itanium_class" "ishf")])
1163
1164(define_insn "extzv"
1165  [(set (match_operand:DI 0 "gr_register_operand" "=r")
1166	(zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1167			 (match_operand:DI 2 "const_int_operand" "n")
1168			 (match_operand:DI 3 "const_int_operand" "n")))]
1169  ""
1170  "extr.u %0 = %1, %3, %2"
1171  [(set_attr "itanium_class" "ishf")])
1172
1173;; Insert a bit field.
1174;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1175;; Source1 can be 0 or -1.
1176;; Source2 can be 0.
1177
1178;; ??? Actual dep instruction is more powerful than what these insv
1179;; patterns support.  Unfortunately, combine is unable to create patterns
1180;; where source2 != dest.
1181
1182(define_expand "insv"
1183  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1184			 (match_operand:DI 1 "const_int_operand" "")
1185			 (match_operand:DI 2 "const_int_operand" ""))
1186	(match_operand:DI 3 "nonmemory_operand" ""))]
1187  ""
1188{
1189  int width = INTVAL (operands[1]);
1190  int shift = INTVAL (operands[2]);
1191
1192  /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1193     pseudo.  */
1194  if (! register_operand (operands[3], DImode)
1195      && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1196    operands[3] = force_reg (DImode, operands[3]);
1197
1198  /* If this is a single dep instruction, we have nothing to do.  */
1199  if (! ((register_operand (operands[3], DImode) && width <= 16)
1200	 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1201    {
1202      /* Check for cases that can be implemented with a mix instruction.  */
1203      if (width == 32 && shift == 0)
1204	{
1205	  /* Directly generating the mix4left instruction confuses
1206	     optimize_bit_field in function.c.  Since this is performing
1207	     a useful optimization, we defer generation of the complicated
1208	     mix4left RTL to the first splitting phase.  */
1209	  rtx tmp = gen_reg_rtx (DImode);
1210	  emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1211	  DONE;
1212	}
1213      else if (width == 32 && shift == 32)
1214	{
1215	  emit_insn (gen_mix4right (operands[0], operands[3]));
1216	  DONE;
1217	}
1218
1219      /* We could handle remaining cases by emitting multiple dep
1220	 instructions.
1221
1222	 If we need more than two dep instructions then we lose.  A 6
1223	 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1224	 mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,
1225	 the latter is 6 cycles on an Itanium (TM) processor, because there is
1226	 only one function unit that can execute dep and shr immed.
1227
1228	 If we only need two dep instruction, then we still lose.
1229	 mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away
1230	 the unnecessary mov, this is still undesirable because it will be
1231	 hard to optimize, and it creates unnecessary pressure on the I0
1232	 function unit.  */
1233
1234      FAIL;
1235
1236#if 0
1237      /* This code may be useful for other IA-64 processors, so we leave it in
1238	 for now.  */
1239      while (width > 16)
1240	{
1241	  rtx tmp;
1242
1243	  emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1244			       operands[3]));
1245	  shift += 16;
1246	  width -= 16;
1247	  tmp = gen_reg_rtx (DImode);
1248	  emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1249	  operands[3] = tmp;
1250	}
1251      operands[1] = GEN_INT (width);
1252      operands[2] = GEN_INT (shift);
1253#endif
1254    }
1255})
1256
1257(define_insn "*insv_internal"
1258  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1259			 (match_operand:DI 1 "const_int_operand" "n")
1260			 (match_operand:DI 2 "const_int_operand" "n"))
1261	(match_operand:DI 3 "nonmemory_operand" "rP"))]
1262  "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1263   || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1264  "dep %0 = %3, %0, %2, %1"
1265  [(set_attr "itanium_class" "ishf")])
1266
1267;; Combine doesn't like to create bit-field insertions into zero.
1268(define_insn "*depz_internal"
1269  [(set (match_operand:DI 0 "gr_register_operand" "=r")
1270	(and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1271			   (match_operand:DI 2 "const_int_operand" "n"))
1272		(match_operand:DI 3 "const_int_operand" "n")))]
1273  "CONST_OK_FOR_M (INTVAL (operands[2]))
1274   && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1275{
1276  operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1277  return "%,dep.z %0 = %1, %2, %3";
1278}
1279  [(set_attr "itanium_class" "ishf")])
1280
1281(define_insn "shift_mix4left"
1282  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1283			 (const_int 32) (const_int 0))
1284	(match_operand:DI 1 "gr_register_operand" "r"))
1285   (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1286  ""
1287  "#"
1288  [(set_attr "itanium_class" "unknown")])
1289
1290(define_split
1291  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1292			 (const_int 32) (const_int 0))
1293	(match_operand:DI 1 "register_operand" ""))
1294   (clobber (match_operand:DI 2 "register_operand" ""))]
1295  "reload_completed"
1296  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1297   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1298	(lshiftrt:DI (match_dup 3) (const_int 32)))]
1299  "operands[3] = operands[2];")
1300
1301(define_split
1302  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1303			 (const_int 32) (const_int 0))
1304	(match_operand:DI 1 "register_operand" ""))
1305   (clobber (match_operand:DI 2 "register_operand" ""))]
1306  "! reload_completed"
1307  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1308   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1309	(lshiftrt:DI (match_dup 3) (const_int 32)))]
1310  "operands[3] = operands[2];")
1311
1312(define_insn "*mix4left"
1313  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1314			 (const_int 32) (const_int 0))
1315	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1316		     (const_int 32)))]
1317  ""
1318  "mix4.l %0 = %0, %r1"
1319  [(set_attr "itanium_class" "mmshf")])
1320
1321(define_insn "mix4right"
1322  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1323			 (const_int 32) (const_int 32))
1324	(match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1325  ""
1326  "mix4.r %0 = %r1, %0"
1327  [(set_attr "itanium_class" "mmshf")])
1328
1329;; This is used by the rotrsi3 pattern.
1330
1331(define_insn "*mix4right_3op"
1332  [(set (match_operand:DI 0 "gr_register_operand" "=r")
1333	(ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1334		(ashift:DI (zero_extend:DI
1335			     (match_operand:SI 2 "gr_register_operand" "r"))
1336			   (const_int 32))))]
1337  ""
1338  "mix4.r %0 = %2, %1"
1339  [(set_attr "itanium_class" "mmshf")])
1340
1341
1342;; ::::::::::::::::::::
1343;; ::
1344;; :: 1 bit Integer arithmetic
1345;; ::
1346;; ::::::::::::::::::::
1347
1348(define_insn_and_split "andbi3"
1349  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1350	(and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1351		(match_operand:BI 2 "register_operand" "c,r,r")))]
1352  ""
1353  "@
1354   #
1355   tbit.nz.and.orcm %0, %I0 = %2, 0
1356   and %0 = %2, %1"
1357  "reload_completed
1358   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1359   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1360  [(cond_exec (eq (match_dup 2) (const_int 0))
1361     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1362				(match_dup 0))))]
1363  ""
1364  [(set_attr "itanium_class" "unknown,tbit,ilog")])
1365
1366(define_insn_and_split "*andcmbi3"
1367  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1368	(and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
1369		(match_operand:BI 2 "register_operand" "0,0,r")))]
1370  ""
1371  "@
1372   #
1373   tbit.z.and.orcm %0, %I0 = %1, 0
1374   andcm %0 = %2, %1"
1375  "reload_completed
1376   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1377   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1378  [(cond_exec (ne (match_dup 1) (const_int 0))
1379     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1380				(match_dup 0))))]
1381  ""
1382  [(set_attr "itanium_class" "unknown,tbit,ilog")])
1383
1384(define_insn_and_split "iorbi3"
1385  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1386	(ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1387		(match_operand:BI 2 "register_operand" "c,r,r")))]
1388  ""
1389  "@
1390   #
1391   tbit.nz.or.andcm %0, %I0 = %2, 0
1392   or %0 = %2, %1"
1393  "reload_completed
1394   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1395   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1396  [(cond_exec (ne (match_dup 2) (const_int 0))
1397     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1398				(match_dup 0))))]
1399  ""
1400  [(set_attr "itanium_class" "unknown,tbit,ilog")])
1401
1402(define_insn_and_split "*iorcmbi3"
1403  [(set (match_operand:BI 0 "register_operand" "=c,c")
1404	(ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
1405		(match_operand:BI 2 "register_operand" "0,0")))]
1406  ""
1407  "@
1408   #
1409   tbit.z.or.andcm %0, %I0 = %1, 0"
1410  "reload_completed
1411   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1412   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1413  [(cond_exec (eq (match_dup 1) (const_int 0))
1414     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1415				(match_dup 0))))]
1416  ""
1417  [(set_attr "itanium_class" "unknown,tbit")])
1418
1419(define_insn "one_cmplbi2"
1420  [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
1421	(not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
1422   (clobber (match_scratch:BI 2 "=X,X,c,X"))]
1423  ""
1424  "@
1425   tbit.z %0, %I0 = %1, 0
1426   xor %0 = 1, %1
1427   #
1428   #"
1429  [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
1430
1431(define_split
1432  [(set (match_operand:BI 0 "register_operand" "")
1433	(not:BI (match_operand:BI 1 "register_operand" "")))
1434   (clobber (match_scratch:BI 2 ""))]
1435  "reload_completed
1436   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1437   && rtx_equal_p (operands[0], operands[1])"
1438  [(set (match_dup 4) (match_dup 3))
1439   (set (match_dup 0) (const_int 1))
1440   (cond_exec (ne (match_dup 2) (const_int 0))
1441     (set (match_dup 0) (const_int 0)))
1442   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1443  "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
1444   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
1445
1446(define_split
1447  [(set (match_operand:BI 0 "register_operand" "")
1448	(not:BI (match_operand:BI 1 "register_operand" "")))
1449   (clobber (match_scratch:BI 2 ""))]
1450  "reload_completed
1451   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1452   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1453   && ! rtx_equal_p (operands[0], operands[1])"
1454  [(cond_exec (ne (match_dup 1) (const_int 0))
1455     (set (match_dup 0) (const_int 0)))
1456   (cond_exec (eq (match_dup 1) (const_int 0))
1457     (set (match_dup 0) (const_int 1)))
1458   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1459  "")
1460
1461(define_insn "*cmpsi_and_0"
1462  [(set (match_operand:BI 0 "register_operand" "=c")
1463	(and:BI (match_operator:BI 4 "predicate_operator"
1464		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1465		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1466		(match_operand:BI 1 "register_operand" "0")))]
1467  ""
1468  "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
1469  [(set_attr "itanium_class" "icmp")])
1470
1471(define_insn "*cmpsi_and_1"
1472  [(set (match_operand:BI 0 "register_operand" "=c")
1473	(and:BI (match_operator:BI 3 "signed_inequality_operator"
1474		  [(match_operand:SI 2 "gr_register_operand" "r")
1475		   (const_int 0)])
1476		(match_operand:BI 1 "register_operand" "0")))]
1477  ""
1478  "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
1479  [(set_attr "itanium_class" "icmp")])
1480
1481(define_insn "*cmpsi_andnot_0"
1482  [(set (match_operand:BI 0 "register_operand" "=c")
1483	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1484			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1485			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1486		(match_operand:BI 1 "register_operand" "0")))]
1487  ""
1488  "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
1489  [(set_attr "itanium_class" "icmp")])
1490
1491(define_insn "*cmpsi_andnot_1"
1492  [(set (match_operand:BI 0 "register_operand" "=c")
1493	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1494			  [(match_operand:SI 2 "gr_register_operand" "r")
1495			   (const_int 0)]))
1496		(match_operand:BI 1 "register_operand" "0")))]
1497  ""
1498  "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
1499  [(set_attr "itanium_class" "icmp")])
1500
1501(define_insn "*cmpdi_and_0"
1502  [(set (match_operand:BI 0 "register_operand" "=c")
1503	(and:BI (match_operator:BI 4 "predicate_operator"
1504		  [(match_operand:DI 2 "gr_register_operand" "r")
1505		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1506		(match_operand:BI 1 "register_operand" "0")))]
1507  ""
1508  "cmp.%C4.and.orcm %0, %I0 = %3, %2"
1509  [(set_attr "itanium_class" "icmp")])
1510
1511(define_insn "*cmpdi_and_1"
1512  [(set (match_operand:BI 0 "register_operand" "=c")
1513	(and:BI (match_operator:BI 3 "signed_inequality_operator"
1514		  [(match_operand:DI 2 "gr_register_operand" "r")
1515		   (const_int 0)])
1516		(match_operand:BI 1 "register_operand" "0")))]
1517  ""
1518  "cmp.%C3.and.orcm %0, %I0 = r0, %2"
1519  [(set_attr "itanium_class" "icmp")])
1520
1521(define_insn "*cmpdi_andnot_0"
1522  [(set (match_operand:BI 0 "register_operand" "=c")
1523	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1524			 [(match_operand:DI 2 "gr_register_operand" "r")
1525			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1526		(match_operand:BI 1 "register_operand" "0")))]
1527  ""
1528  "cmp.%C4.or.andcm %I0, %0 = %3, %2"
1529  [(set_attr "itanium_class" "icmp")])
1530
1531(define_insn "*cmpdi_andnot_1"
1532  [(set (match_operand:BI 0 "register_operand" "=c")
1533	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1534			  [(match_operand:DI 2 "gr_register_operand" "r")
1535			   (const_int 0)]))
1536		(match_operand:BI 1 "register_operand" "0")))]
1537  ""
1538  "cmp.%C3.or.andcm %I0, %0 = r0, %2"
1539  [(set_attr "itanium_class" "icmp")])
1540
1541(define_insn "*tbit_and_0"
1542  [(set (match_operand:BI 0 "register_operand" "=c")
1543	(and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1544			       (const_int 1))
1545		       (const_int 0))
1546		(match_operand:BI 2 "register_operand" "0")))]
1547  ""
1548  "tbit.nz.and.orcm %0, %I0 = %1, 0"
1549  [(set_attr "itanium_class" "tbit")])
1550
1551(define_insn "*tbit_and_1"
1552  [(set (match_operand:BI 0 "register_operand" "=c")
1553	(and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1554			       (const_int 1))
1555		       (const_int 0))
1556		(match_operand:BI 2 "register_operand" "0")))]
1557  ""
1558  "tbit.z.and.orcm %0, %I0 = %1, 0"
1559  [(set_attr "itanium_class" "tbit")])
1560
1561(define_insn "*tbit_and_2"
1562  [(set (match_operand:BI 0 "register_operand" "=c")
1563	(and:BI (ne:BI (zero_extract:DI
1564			 (match_operand:DI 1 "gr_register_operand" "r")
1565			 (const_int 1)
1566			 (match_operand:DI 2 "const_int_operand" "n"))
1567		       (const_int 0))
1568		(match_operand:BI 3 "register_operand" "0")))]
1569  ""
1570  "tbit.nz.and.orcm %0, %I0 = %1, %2"
1571  [(set_attr "itanium_class" "tbit")])
1572
1573(define_insn "*tbit_and_3"
1574  [(set (match_operand:BI 0 "register_operand" "=c")
1575	(and:BI (eq:BI (zero_extract:DI
1576			 (match_operand:DI 1 "gr_register_operand" "r")
1577			 (const_int 1)
1578			 (match_operand:DI 2 "const_int_operand" "n"))
1579		       (const_int 0))
1580		(match_operand:BI 3 "register_operand" "0")))]
1581  ""
1582  "tbit.z.and.orcm %0, %I0 = %1, %2"
1583  [(set_attr "itanium_class" "tbit")])
1584
1585(define_insn "*cmpsi_or_0"
1586  [(set (match_operand:BI 0 "register_operand" "=c")
1587	(ior:BI (match_operator:BI 4 "predicate_operator"
1588		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1589		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1590		(match_operand:BI 1 "register_operand" "0")))]
1591  ""
1592  "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
1593  [(set_attr "itanium_class" "icmp")])
1594
1595(define_insn "*cmpsi_or_1"
1596  [(set (match_operand:BI 0 "register_operand" "=c")
1597	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
1598		  [(match_operand:SI 2 "gr_register_operand" "r")
1599		   (const_int 0)])
1600		(match_operand:BI 1 "register_operand" "0")))]
1601  ""
1602  "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
1603  [(set_attr "itanium_class" "icmp")])
1604
1605(define_insn "*cmpsi_orcm_0"
1606  [(set (match_operand:BI 0 "register_operand" "=c")
1607	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1608			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1609			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1610		(match_operand:BI 1 "register_operand" "0")))]
1611  ""
1612  "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
1613  [(set_attr "itanium_class" "icmp")])
1614
1615(define_insn "*cmpsi_orcm_1"
1616  [(set (match_operand:BI 0 "register_operand" "=c")
1617	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1618			  [(match_operand:SI 2 "gr_register_operand" "r")
1619			   (const_int 0)]))
1620		(match_operand:BI 1 "register_operand" "0")))]
1621  ""
1622  "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
1623  [(set_attr "itanium_class" "icmp")])
1624
1625(define_insn "*cmpdi_or_0"
1626  [(set (match_operand:BI 0 "register_operand" "=c")
1627	(ior:BI (match_operator:BI 4 "predicate_operator"
1628		  [(match_operand:DI 2 "gr_register_operand" "r")
1629		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1630		(match_operand:BI 1 "register_operand" "0")))]
1631  ""
1632  "cmp.%C4.or.andcm %0, %I0 = %3, %2"
1633  [(set_attr "itanium_class" "icmp")])
1634
1635(define_insn "*cmpdi_or_1"
1636  [(set (match_operand:BI 0 "register_operand" "=c")
1637	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
1638		  [(match_operand:DI 2 "gr_register_operand" "r")
1639		   (const_int 0)])
1640		(match_operand:BI 1 "register_operand" "0")))]
1641  ""
1642  "cmp.%C3.or.andcm %0, %I0 = r0, %2"
1643  [(set_attr "itanium_class" "icmp")])
1644
1645(define_insn "*cmpdi_orcm_0"
1646  [(set (match_operand:BI 0 "register_operand" "=c")
1647	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1648			 [(match_operand:DI 2 "gr_register_operand" "r")
1649			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1650		(match_operand:BI 1 "register_operand" "0")))]
1651  ""
1652  "cmp.%C4.and.orcm %I0, %0 = %3, %2"
1653  [(set_attr "itanium_class" "icmp")])
1654
1655(define_insn "*cmpdi_orcm_1"
1656  [(set (match_operand:BI 0 "register_operand" "=c")
1657	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1658			  [(match_operand:DI 2 "gr_register_operand" "r")
1659			   (const_int 0)]))
1660		(match_operand:BI 1 "register_operand" "0")))]
1661  ""
1662  "cmp.%C3.and.orcm %I0, %0 = r0, %2"
1663  [(set_attr "itanium_class" "icmp")])
1664
1665(define_insn "*tbit_or_0"
1666  [(set (match_operand:BI 0 "register_operand" "=c")
1667	(ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1668			       (const_int 1))
1669		       (const_int 0))
1670		(match_operand:BI 2 "register_operand" "0")))]
1671  ""
1672  "tbit.nz.or.andcm %0, %I0 = %1, 0"
1673  [(set_attr "itanium_class" "tbit")])
1674
1675(define_insn "*tbit_or_1"
1676  [(set (match_operand:BI 0 "register_operand" "=c")
1677	(ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1678			       (const_int 1))
1679		       (const_int 0))
1680		(match_operand:BI 2 "register_operand" "0")))]
1681  ""
1682  "tbit.z.or.andcm %0, %I0 = %1, 0"
1683  [(set_attr "itanium_class" "tbit")])
1684
1685(define_insn "*tbit_or_2"
1686  [(set (match_operand:BI 0 "register_operand" "=c")
1687	(ior:BI (ne:BI (zero_extract:DI
1688			 (match_operand:DI 1 "gr_register_operand" "r")
1689			 (const_int 1)
1690			 (match_operand:DI 2 "const_int_operand" "n"))
1691		       (const_int 0))
1692		(match_operand:BI 3 "register_operand" "0")))]
1693  ""
1694  "tbit.nz.or.andcm %0, %I0 = %1, %2"
1695  [(set_attr "itanium_class" "tbit")])
1696
1697(define_insn "*tbit_or_3"
1698  [(set (match_operand:BI 0 "register_operand" "=c")
1699	(ior:BI (eq:BI (zero_extract:DI
1700			 (match_operand:DI 1 "gr_register_operand" "r")
1701			 (const_int 1)
1702			 (match_operand:DI 2 "const_int_operand" "n"))
1703		       (const_int 0))
1704		(match_operand:BI 3 "register_operand" "0")))]
1705  ""
1706  "tbit.z.or.andcm %0, %I0 = %1, %2"
1707  [(set_attr "itanium_class" "tbit")])
1708
1709;; Transform test of and/or of setcc into parallel comparisons.
1710
1711(define_split
1712  [(set (match_operand:BI 0 "register_operand" "")
1713	(ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1714			      (const_int 0))
1715		       (match_operand:DI 3 "register_operand" ""))
1716	       (const_int 0)))]
1717  ""
1718  [(set (match_dup 0)
1719	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1720		(match_dup 2)))]
1721  "")
1722
1723(define_split
1724  [(set (match_operand:BI 0 "register_operand" "")
1725	(eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1726			      (const_int 0))
1727		       (match_operand:DI 3 "register_operand" ""))
1728	       (const_int 0)))]
1729  ""
1730  [(set (match_dup 0)
1731	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1732		(match_dup 2)))
1733   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1734	      (clobber (scratch))])]
1735  "")
1736
1737(define_split
1738  [(set (match_operand:BI 0 "register_operand" "")
1739	(ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1740			      (const_int 0))
1741		       (match_operand:DI 3 "register_operand" ""))
1742	       (const_int 0)))]
1743  ""
1744  [(set (match_dup 0) 
1745	(ior:BI (ne:BI (match_dup 3) (const_int 0))
1746		(match_dup 2)))]
1747  "")
1748
1749(define_split
1750  [(set (match_operand:BI 0 "register_operand" "")
1751	(eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1752			      (const_int 0))
1753		       (match_operand:DI 3 "register_operand" ""))
1754	       (const_int 0)))]
1755  ""
1756  [(set (match_dup 0) 
1757	(ior:BI (ne:BI (match_dup 3) (const_int 0))
1758		(match_dup 2)))
1759   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1760	      (clobber (scratch))])]
1761  "")
1762
1763;; ??? Incredibly hackish.  Either need four proper patterns with all
1764;; the alternatives, or rely on sched1 to split the insn and hope that
1765;; nothing bad happens to the comparisons in the meantime.
1766;;
1767;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1768;; that we're doing height reduction.
1769;
1770;(define_insn_and_split ""
1771;  [(set (match_operand:BI 0 "register_operand" "=c")
1772;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1773;			  [(match_operand 2 "" "")
1774;			   (match_operand 3 "" "")])
1775;			(match_operator:BI 4 "comparison_operator"
1776;			  [(match_operand 5 "" "")
1777;			   (match_operand 6 "" "")]))
1778;		(match_dup 0)))]
1779;  "flag_schedule_insns"
1780;  "#"
1781;  ""
1782;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
1783;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
1784;  "")
1785;
1786;(define_insn_and_split ""
1787;  [(set (match_operand:BI 0 "register_operand" "=c")
1788;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1789;			  [(match_operand 2 "" "")
1790;			   (match_operand 3 "" "")])
1791;			(match_operator:BI 4 "comparison_operator"
1792;			  [(match_operand 5 "" "")
1793;			   (match_operand 6 "" "")]))
1794;		(match_dup 0)))]
1795;  "flag_schedule_insns"
1796;  "#"
1797;  ""
1798;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
1799;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
1800;  "")
1801;
1802;(define_split
1803;  [(set (match_operand:BI 0 "register_operand" "")
1804;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1805;			  [(match_operand 2 "" "")
1806;			   (match_operand 3 "" "")])
1807;			(match_operand:BI 7 "register_operand" ""))
1808;		(and:BI (match_operator:BI 4 "comparison_operator"
1809;			  [(match_operand 5 "" "")
1810;			   (match_operand 6 "" "")])
1811;			(match_operand:BI 8 "register_operand" ""))))]
1812;  ""
1813;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
1814;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
1815;			      (match_dup 0)))]
1816;  "")
1817;
1818;(define_split
1819;  [(set (match_operand:BI 0 "register_operand" "")
1820;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1821;			  [(match_operand 2 "" "")
1822;			   (match_operand 3 "" "")])
1823;			(match_operand:BI 7 "register_operand" ""))
1824;		(ior:BI (match_operator:BI 4 "comparison_operator"
1825;			  [(match_operand 5 "" "")
1826;			   (match_operand 6 "" "")])
1827;			(match_operand:BI 8 "register_operand" ""))))]
1828;  ""
1829;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
1830;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
1831;			      (match_dup 0)))]
1832;  "")
1833
1834;; Try harder to avoid predicate copies by duplicating compares.
1835;; Note that we'll have already split the predicate copy, which
1836;; is kind of a pain, but oh well.
1837
1838(define_peephole2
1839  [(set (match_operand:BI 0 "register_operand" "")
1840	(match_operand:BI 1 "comparison_operator" ""))
1841   (set (match_operand:CCI 2 "register_operand" "")
1842	(match_operand:CCI 3 "register_operand" ""))
1843   (set (match_operand:CCI 4 "register_operand" "")
1844	(match_operand:CCI 5 "register_operand" ""))
1845   (set (match_operand:BI 6 "register_operand" "")
1846	(unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
1847  "REGNO (operands[3]) == REGNO (operands[0])
1848   && REGNO (operands[4]) == REGNO (operands[0]) + 1
1849   && REGNO (operands[4]) == REGNO (operands[2]) + 1
1850   && REGNO (operands[6]) == REGNO (operands[2])"
1851  [(set (match_dup 0) (match_dup 1))
1852   (set (match_dup 6) (match_dup 7))]
1853  "operands[7] = copy_rtx (operands[1]);")
1854
1855;; ::::::::::::::::::::
1856;; ::
1857;; :: 16 bit Integer arithmetic
1858;; ::
1859;; ::::::::::::::::::::
1860
1861(define_insn "mulhi3"
1862  [(set (match_operand:HI 0 "gr_register_operand" "=r")
1863	(mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1864		 (match_operand:HI 2 "gr_register_operand" "r")))]
1865  ""
1866  "pmpy2.r %0 = %1, %2"
1867  [(set_attr "itanium_class" "mmmul")])
1868
1869
1870;; ::::::::::::::::::::
1871;; ::
1872;; :: 32 bit Integer arithmetic
1873;; ::
1874;; ::::::::::::::::::::
1875
1876(define_insn "addsi3"
1877  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1878	(plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1879		 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1880  ""
1881  "@
1882   add %0 = %1, %2
1883   adds %0 = %2, %1
1884   addl %0 = %2, %1"
1885  [(set_attr "itanium_class" "ialu")])
1886
1887(define_insn "*addsi3_plus1"
1888  [(set (match_operand:SI 0 "gr_register_operand" "=r")
1889	(plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1890			  (match_operand:SI 2 "gr_register_operand" "r"))
1891		 (const_int 1)))]
1892  ""
1893  "add %0 = %1, %2, 1"
1894  [(set_attr "itanium_class" "ialu")])
1895
1896(define_insn "*addsi3_plus1_alt"
1897  [(set (match_operand:SI 0 "gr_register_operand" "=r")
1898	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1899			  (const_int 2))
1900		 (const_int 1)))]
1901  ""
1902  "add %0 = %1, %1, 1"
1903  [(set_attr "itanium_class" "ialu")])
1904
1905(define_insn "*addsi3_shladd"
1906  [(set (match_operand:SI 0 "gr_register_operand" "=r")
1907	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1908			  (match_operand:SI 2 "shladd_operand" "n"))
1909		 (match_operand:SI 3 "gr_register_operand" "r")))]
1910  ""
1911  "shladd %0 = %1, %S2, %3"
1912  [(set_attr "itanium_class" "ialu")])
1913
1914(define_insn "subsi3"
1915  [(set (match_operand:SI 0 "gr_register_operand" "=r")
1916	(minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1917		  (match_operand:SI 2 "gr_register_operand" "r")))]
1918  ""
1919  "sub %0 = %1, %2"
1920  [(set_attr "itanium_class" "ialu")])
1921
1922(define_insn "*subsi3_minus1"
1923  [(set (match_operand:SI 0 "gr_register_operand" "=r")
1924	(plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1925		 (match_operand:SI 2 "gr_register_operand" "r")))]
1926  ""
1927  "sub %0 = %2, %1, 1"
1928  [(set_attr "itanium_class" "ialu")])
1929
1930;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
1931
1932(define_insn "mulsi3"
1933  [(set (match_operand:SI 0 "fr_register_operand" "=f")
1934	(mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1935		 (match_operand:SI 2 "grfr_register_operand" "f")))]
1936  ""
1937  "xmpy.l %0 = %1, %2"
1938  [(set_attr "itanium_class" "xmpy")])
1939
1940(define_insn "maddsi4"
1941  [(set (match_operand:SI 0 "fr_register_operand" "=f")
1942	(plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1943			  (match_operand:SI 2 "grfr_register_operand" "f"))
1944		 (match_operand:SI 3 "grfr_register_operand" "f")))]
1945  ""
1946  "xma.l %0 = %1, %2, %3"
1947  [(set_attr "itanium_class" "xmpy")])
1948
1949(define_insn "negsi2"
1950  [(set (match_operand:SI 0 "gr_register_operand" "=r")
1951	(neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
1952  ""
1953  "sub %0 = r0, %1"
1954  [(set_attr "itanium_class" "ialu")])
1955
1956(define_expand "abssi2"
1957  [(set (match_dup 2)
1958	(ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1959   (set (match_operand:SI 0 "gr_register_operand" "")
1960	(if_then_else:SI (eq (match_dup 2) (const_int 0))
1961			 (neg:SI (match_dup 1))
1962			 (match_dup 1)))]
1963  ""
1964  { operands[2] = gen_reg_rtx (BImode); })
1965
1966(define_expand "sminsi3"
1967  [(set (match_dup 3)
1968	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
1969	       (match_operand:SI 2 "gr_register_operand" "")))
1970   (set (match_operand:SI 0 "gr_register_operand" "")
1971	(if_then_else:SI (ne (match_dup 3) (const_int 0))
1972			 (match_dup 2) (match_dup 1)))]
1973  ""
1974  { operands[3] = gen_reg_rtx (BImode); })
1975
1976(define_expand "smaxsi3"
1977  [(set (match_dup 3)
1978	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
1979	       (match_operand:SI 2 "gr_register_operand" "")))
1980   (set (match_operand:SI 0 "gr_register_operand" "")
1981	(if_then_else:SI (ne (match_dup 3) (const_int 0))
1982			 (match_dup 1) (match_dup 2)))]
1983  ""
1984  { operands[3] = gen_reg_rtx (BImode); })
1985
1986(define_expand "uminsi3"
1987  [(set (match_dup 3)
1988	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
1989		(match_operand:SI 2 "gr_register_operand" "")))
1990   (set (match_operand:SI 0 "gr_register_operand" "")
1991	(if_then_else:SI (ne (match_dup 3) (const_int 0))
1992			 (match_dup 2) (match_dup 1)))]
1993  ""
1994  { operands[3] = gen_reg_rtx (BImode); })
1995
1996(define_expand "umaxsi3"
1997  [(set (match_dup 3)
1998	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
1999		(match_operand:SI 2 "gr_register_operand" "")))
2000   (set (match_operand:SI 0 "gr_register_operand" "")
2001	(if_then_else:SI (ne (match_dup 3) (const_int 0))
2002			 (match_dup 1) (match_dup 2)))]
2003  ""
2004  { operands[3] = gen_reg_rtx (BImode); })
2005
2006(define_expand "divsi3"
2007  [(set (match_operand:SI 0 "register_operand" "")
2008	(div:SI (match_operand:SI 1 "general_operand" "")
2009		(match_operand:SI 2 "general_operand" "")))]
2010  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2011{
2012  rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
2013  REAL_VALUE_TYPE twon34_r;
2014
2015  op0_tf = gen_reg_rtx (TFmode);
2016  op0_di = gen_reg_rtx (DImode);
2017
2018  if (CONSTANT_P (operands[1]))
2019    operands[1] = force_reg (SImode, operands[1]);
2020  op1_tf = gen_reg_rtx (TFmode);
2021  expand_float (op1_tf, operands[1], 0);
2022
2023  if (CONSTANT_P (operands[2]))
2024    operands[2] = force_reg (SImode, operands[2]);
2025  op2_tf = gen_reg_rtx (TFmode);
2026  expand_float (op2_tf, operands[2], 0);
2027
2028  /* 2^-34 */
2029  real_2expN (&twon34_r, -34);
2030  twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
2031  twon34 = force_reg (TFmode, twon34);
2032
2033  emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
2034
2035  emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
2036  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
2037  DONE;
2038})
2039
2040(define_expand "modsi3"
2041  [(set (match_operand:SI 0 "register_operand" "")
2042	(mod:SI (match_operand:SI 1 "general_operand" "")
2043		(match_operand:SI 2 "general_operand" "")))]
2044  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2045{
2046  rtx op2_neg, op1_di, div;
2047
2048  div = gen_reg_rtx (SImode);
2049  emit_insn (gen_divsi3 (div, operands[1], operands[2]));
2050
2051  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2052
2053  /* This is a trick to get us to reuse the value that we're sure to
2054     have already copied to the FP regs.  */
2055  op1_di = gen_reg_rtx (DImode);
2056  convert_move (op1_di, operands[1], 0);
2057
2058  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2059			  gen_lowpart (SImode, op1_di)));
2060  DONE;
2061})
2062
2063(define_expand "udivsi3"
2064  [(set (match_operand:SI 0 "register_operand" "")
2065	(udiv:SI (match_operand:SI 1 "general_operand" "")
2066		 (match_operand:SI 2 "general_operand" "")))]
2067  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2068{
2069  rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
2070  REAL_VALUE_TYPE twon34_r;
2071
2072  op0_tf = gen_reg_rtx (TFmode);
2073  op0_di = gen_reg_rtx (DImode);
2074
2075  if (CONSTANT_P (operands[1]))
2076    operands[1] = force_reg (SImode, operands[1]);
2077  op1_tf = gen_reg_rtx (TFmode);
2078  expand_float (op1_tf, operands[1], 1);
2079
2080  if (CONSTANT_P (operands[2]))
2081    operands[2] = force_reg (SImode, operands[2]);
2082  op2_tf = gen_reg_rtx (TFmode);
2083  expand_float (op2_tf, operands[2], 1);
2084
2085  /* 2^-34 */
2086  real_2expN (&twon34_r, -34);
2087  twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
2088  twon34 = force_reg (TFmode, twon34);
2089
2090  emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
2091
2092  emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
2093  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
2094  DONE;
2095})
2096
2097(define_expand "umodsi3"
2098  [(set (match_operand:SI 0 "register_operand" "")
2099	(umod:SI (match_operand:SI 1 "general_operand" "")
2100		 (match_operand:SI 2 "general_operand" "")))]
2101  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2102{
2103  rtx op2_neg, op1_di, div;
2104
2105  div = gen_reg_rtx (SImode);
2106  emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
2107
2108  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2109
2110  /* This is a trick to get us to reuse the value that we're sure to
2111     have already copied to the FP regs.  */
2112  op1_di = gen_reg_rtx (DImode);
2113  convert_move (op1_di, operands[1], 1);
2114
2115  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2116			  gen_lowpart (SImode, op1_di)));
2117  DONE;
2118})
2119
2120(define_insn_and_split "divsi3_internal"
2121  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2122	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2123			  (match_operand:TF 2 "fr_register_operand" "f"))))
2124   (clobber (match_scratch:TF 4 "=&f"))
2125   (clobber (match_scratch:TF 5 "=&f"))
2126   (clobber (match_scratch:BI 6 "=c"))
2127   (use (match_operand:TF 3 "fr_register_operand" "f"))]
2128  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2129  "#"
2130  "&& reload_completed"
2131  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2132	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2133					    UNSPEC_FR_RECIP_APPROX))
2134	      (use (const_int 1))])
2135   (cond_exec (ne (match_dup 6) (const_int 0))
2136     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
2137		(use (const_int 1))]))
2138   (cond_exec (ne (match_dup 6) (const_int 0))
2139     (parallel [(set (match_dup 5)
2140		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2141			      (match_dup 7)))
2142		(use (const_int 1))]))
2143   (cond_exec (ne (match_dup 6) (const_int 0))
2144     (parallel [(set (match_dup 4)
2145		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2146			      (match_dup 4)))
2147		(use (const_int 1))]))
2148   (cond_exec (ne (match_dup 6) (const_int 0))
2149     (parallel [(set (match_dup 5)
2150		     (plus:TF (mult:TF (match_dup 5) (match_dup 5))
2151			      (match_dup 3)))
2152		(use (const_int 1))]))
2153   (cond_exec (ne (match_dup 6) (const_int 0))
2154     (parallel [(set (match_dup 0)
2155		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2156			      (match_dup 4)))
2157		(use (const_int 1))]))
2158  ] 
2159  "operands[7] = CONST1_RTX (TFmode);"
2160  [(set_attr "predicable" "no")])
2161
2162;; ::::::::::::::::::::
2163;; ::
2164;; :: 64 bit Integer arithmetic
2165;; ::
2166;; ::::::::::::::::::::
2167
2168(define_insn "adddi3"
2169  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
2170	(plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
2171		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
2172  ""
2173  "@
2174   add %0 = %1, %2
2175   adds %0 = %2, %1
2176   addl %0 = %2, %1"
2177  [(set_attr "itanium_class" "ialu")])
2178
2179(define_insn "*adddi3_plus1"
2180  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2181	(plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
2182			  (match_operand:DI 2 "gr_register_operand" "r"))
2183		 (const_int 1)))]
2184  ""
2185  "add %0 = %1, %2, 1"
2186  [(set_attr "itanium_class" "ialu")])
2187
2188;; This has some of the same problems as shladd.  We let the shladd
2189;; eliminator hack handle it, which results in the 1 being forced into
2190;; a register, but not more ugliness here.
2191(define_insn "*adddi3_plus1_alt"
2192  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2193	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2194			  (const_int 2))
2195		 (const_int 1)))]
2196  ""
2197  "add %0 = %1, %1, 1"
2198  [(set_attr "itanium_class" "ialu")])
2199
2200(define_insn "subdi3"
2201  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2202	(minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
2203		  (match_operand:DI 2 "gr_register_operand" "r")))]
2204  ""
2205  "sub %0 = %1, %2"
2206  [(set_attr "itanium_class" "ialu")])
2207
2208(define_insn "*subdi3_minus1"
2209  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2210	(plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
2211		 (match_operand:DI 2 "gr_register_operand" "r")))]
2212  ""
2213  "sub %0 = %2, %1, 1"
2214  [(set_attr "itanium_class" "ialu")])
2215
2216;; ??? Use grfr instead of fr because of virtual register elimination
2217;; and silly test cases multiplying by the frame pointer.
2218(define_insn "muldi3"
2219  [(set (match_operand:DI 0 "fr_register_operand" "=f")
2220	(mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2221		 (match_operand:DI 2 "grfr_register_operand" "f")))]
2222  ""
2223  "xmpy.l %0 = %1, %2"
2224  [(set_attr "itanium_class" "xmpy")])
2225
2226;; ??? If operand 3 is an eliminable reg, then register elimination causes the
2227;; same problem that we have with shladd below.  Unfortunately, this case is
2228;; much harder to fix because the multiply puts the result in an FP register,
2229;; but the add needs inputs from a general register.  We add a spurious clobber
2230;; here so that it will be present just in case register elimination gives us
2231;; the funny result.
2232
2233;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2234
2235;; ??? Maybe we should change how adds are canonicalized.
2236
2237(define_insn "madddi4"
2238  [(set (match_operand:DI 0 "fr_register_operand" "=f")
2239	(plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2240			  (match_operand:DI 2 "grfr_register_operand" "f"))
2241		 (match_operand:DI 3 "grfr_register_operand" "f")))
2242   (clobber (match_scratch:DI 4 "=X"))]
2243  ""
2244  "xma.l %0 = %1, %2, %3"
2245  [(set_attr "itanium_class" "xmpy")])
2246
2247;; This can be created by register elimination if operand3 of shladd is an
2248;; eliminable register or has reg_equiv_constant set.
2249
2250;; We have to use nonmemory_operand for operand 4, to ensure that the
2251;; validate_changes call inside eliminate_regs will always succeed.  If it
2252;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
2253;; incorrectly.
2254
2255(define_insn "*madddi4_elim"
2256  [(set (match_operand:DI 0 "register_operand" "=&r")
2257	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
2258				   (match_operand:DI 2 "register_operand" "f"))
2259			  (match_operand:DI 3 "register_operand" "f"))
2260		 (match_operand:DI 4 "nonmemory_operand" "rI")))
2261   (clobber (match_scratch:DI 5 "=f"))]
2262  "reload_in_progress"
2263  "#"
2264  [(set_attr "itanium_class" "unknown")])
2265
2266(define_split
2267  [(set (match_operand:DI 0 "register_operand" "")
2268	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2269				   (match_operand:DI 2 "register_operand" ""))
2270			  (match_operand:DI 3 "register_operand" ""))
2271		 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
2272   (clobber (match_scratch:DI 5 ""))]
2273  "reload_completed"
2274  [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2275					  (match_dup 3)))
2276	      (clobber (match_dup 0))])
2277   (set (match_dup 0) (match_dup 5))
2278   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2279  "")
2280
2281;; ??? There are highpart multiply and add instructions, but we have no way
2282;; to generate them.
2283
2284(define_insn "smuldi3_highpart"
2285  [(set (match_operand:DI 0 "fr_register_operand" "=f")
2286	(truncate:DI
2287	 (lshiftrt:TI
2288	  (mult:TI (sign_extend:TI
2289		     (match_operand:DI 1 "fr_register_operand" "f"))
2290		   (sign_extend:TI
2291		     (match_operand:DI 2 "fr_register_operand" "f")))
2292	  (const_int 64))))]
2293  ""
2294  "xmpy.h %0 = %1, %2"
2295  [(set_attr "itanium_class" "xmpy")])
2296
2297(define_insn "umuldi3_highpart"
2298  [(set (match_operand:DI 0 "fr_register_operand" "=f")
2299	(truncate:DI
2300	 (lshiftrt:TI
2301	  (mult:TI (zero_extend:TI
2302		     (match_operand:DI 1 "fr_register_operand" "f"))
2303		   (zero_extend:TI
2304		     (match_operand:DI 2 "fr_register_operand" "f")))
2305	  (const_int 64))))]
2306  ""
2307  "xmpy.hu %0 = %1, %2"
2308  [(set_attr "itanium_class" "xmpy")])
2309
2310(define_insn "negdi2"
2311  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2312	(neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2313  ""
2314  "sub %0 = r0, %1"
2315  [(set_attr "itanium_class" "ialu")])
2316
2317(define_expand "absdi2"
2318  [(set (match_dup 2)
2319	(ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2320   (set (match_operand:DI 0 "gr_register_operand" "")
2321	(if_then_else:DI (eq (match_dup 2) (const_int 0))
2322			 (neg:DI (match_dup 1))
2323			 (match_dup 1)))]
2324  ""
2325  { operands[2] = gen_reg_rtx (BImode); })
2326
2327(define_expand "smindi3"
2328  [(set (match_dup 3)
2329	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
2330	       (match_operand:DI 2 "gr_register_operand" "")))
2331   (set (match_operand:DI 0 "gr_register_operand" "")
2332	(if_then_else:DI (ne (match_dup 3) (const_int 0))
2333			 (match_dup 2) (match_dup 1)))]
2334  ""
2335  { operands[3] = gen_reg_rtx (BImode); })
2336
2337(define_expand "smaxdi3"
2338  [(set (match_dup 3)
2339	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
2340	       (match_operand:DI 2 "gr_register_operand" "")))
2341   (set (match_operand:DI 0 "gr_register_operand" "")
2342	(if_then_else:DI (ne (match_dup 3) (const_int 0))
2343			 (match_dup 1) (match_dup 2)))]
2344  ""
2345  { operands[3] = gen_reg_rtx (BImode); })
2346
2347(define_expand "umindi3"
2348  [(set (match_dup 3)
2349	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
2350		(match_operand:DI 2 "gr_register_operand" "")))
2351   (set (match_operand:DI 0 "gr_register_operand" "")
2352	(if_then_else:DI (ne (match_dup 3) (const_int 0))
2353			 (match_dup 2) (match_dup 1)))]
2354  ""
2355  { operands[3] = gen_reg_rtx (BImode); })
2356
2357(define_expand "umaxdi3"
2358  [(set (match_dup 3)
2359	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
2360		(match_operand:DI 2 "gr_register_operand" "")))
2361   (set (match_operand:DI 0 "gr_register_operand" "")
2362	(if_then_else:DI (ne (match_dup 3) (const_int 0))
2363			 (match_dup 1) (match_dup 2)))]
2364  ""
2365  { operands[3] = gen_reg_rtx (BImode); })
2366
2367(define_expand "ffsdi2"
2368  [(set (match_dup 6)
2369	(eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2370   (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
2371   (set (match_dup 5) (const_int 0))
2372   (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2373   (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_POPCNT))
2374   (set (match_operand:DI 0 "gr_register_operand" "")
2375	(if_then_else:DI (ne (match_dup 6) (const_int 0))
2376			 (match_dup 5) (match_dup 4)))]
2377  ""
2378{
2379  operands[2] = gen_reg_rtx (DImode);
2380  operands[3] = gen_reg_rtx (DImode);
2381  operands[4] = gen_reg_rtx (DImode);
2382  operands[5] = gen_reg_rtx (DImode);
2383  operands[6] = gen_reg_rtx (BImode);
2384})
2385
2386(define_insn "*popcnt"
2387  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2388	(unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")]
2389		   UNSPEC_POPCNT))]
2390  ""
2391  "popcnt %0 = %1"
2392  [(set_attr "itanium_class" "mmmul")])
2393
2394(define_expand "divdi3"
2395  [(set (match_operand:DI 0 "register_operand" "")
2396	(div:DI (match_operand:DI 1 "general_operand" "")
2397		(match_operand:DI 2 "general_operand" "")))]
2398  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2399{
2400  rtx op1_tf, op2_tf, op0_tf;
2401
2402  op0_tf = gen_reg_rtx (TFmode);
2403
2404  if (CONSTANT_P (operands[1]))
2405    operands[1] = force_reg (DImode, operands[1]);
2406  op1_tf = gen_reg_rtx (TFmode);
2407  expand_float (op1_tf, operands[1], 0);
2408
2409  if (CONSTANT_P (operands[2]))
2410    operands[2] = force_reg (DImode, operands[2]);
2411  op2_tf = gen_reg_rtx (TFmode);
2412  expand_float (op2_tf, operands[2], 0);
2413
2414  if (TARGET_INLINE_INT_DIV_LAT)
2415    emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
2416  else
2417    emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
2418
2419  emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
2420  DONE;
2421})
2422
2423(define_expand "moddi3"
2424  [(set (match_operand:DI 0 "register_operand" "")
2425	(mod:SI (match_operand:DI 1 "general_operand" "")
2426		(match_operand:DI 2 "general_operand" "")))]
2427  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2428{
2429  rtx op2_neg, div;
2430
2431  div = gen_reg_rtx (DImode);
2432  emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2433
2434  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2435
2436  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2437  DONE;
2438})
2439
2440(define_expand "udivdi3"
2441  [(set (match_operand:DI 0 "register_operand" "")
2442	(udiv:DI (match_operand:DI 1 "general_operand" "")
2443		 (match_operand:DI 2 "general_operand" "")))]
2444  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2445{
2446  rtx op1_tf, op2_tf, op0_tf;
2447
2448  op0_tf = gen_reg_rtx (TFmode);
2449
2450  if (CONSTANT_P (operands[1]))
2451    operands[1] = force_reg (DImode, operands[1]);
2452  op1_tf = gen_reg_rtx (TFmode);
2453  expand_float (op1_tf, operands[1], 1);
2454
2455  if (CONSTANT_P (operands[2]))
2456    operands[2] = force_reg (DImode, operands[2]);
2457  op2_tf = gen_reg_rtx (TFmode);
2458  expand_float (op2_tf, operands[2], 1);
2459
2460  if (TARGET_INLINE_INT_DIV_LAT)
2461    emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
2462  else
2463    emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
2464
2465  emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
2466  DONE;
2467})
2468
2469(define_expand "umoddi3"
2470  [(set (match_operand:DI 0 "register_operand" "")
2471	(umod:DI (match_operand:DI 1 "general_operand" "")
2472		 (match_operand:DI 2 "general_operand" "")))]
2473  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2474{
2475  rtx op2_neg, div;
2476
2477  div = gen_reg_rtx (DImode);
2478  emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2479
2480  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2481
2482  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2483  DONE;
2484})
2485
2486(define_insn_and_split "divdi3_internal_lat"
2487  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2488	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2489			  (match_operand:TF 2 "fr_register_operand" "f"))))
2490   (clobber (match_scratch:TF 3 "=&f"))
2491   (clobber (match_scratch:TF 4 "=&f"))
2492   (clobber (match_scratch:TF 5 "=&f"))
2493   (clobber (match_scratch:BI 6 "=c"))]
2494  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_LAT"
2495  "#"
2496  "&& reload_completed"
2497  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2498	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2499					    UNSPEC_FR_RECIP_APPROX))
2500	      (use (const_int 1))])
2501   (cond_exec (ne (match_dup 6) (const_int 0))
2502     (parallel [(set (match_dup 3)
2503		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2504			      (match_dup 7)))
2505		(use (const_int 1))]))
2506   (cond_exec (ne (match_dup 6) (const_int 0))
2507     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
2508		(use (const_int 1))]))
2509   (cond_exec (ne (match_dup 6) (const_int 0))
2510     (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
2511		(use (const_int 1))]))
2512   (cond_exec (ne (match_dup 6) (const_int 0))
2513     (parallel [(set (match_dup 4)
2514		     (plus:TF (mult:TF (match_dup 3) (match_dup 4))
2515			      (match_dup 4)))
2516		(use (const_int 1))]))
2517   (cond_exec (ne (match_dup 6) (const_int 0))
2518     (parallel [(set (match_dup 0)
2519		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2520			      (match_dup 0)))
2521		(use (const_int 1))]))
2522   (cond_exec (ne (match_dup 6) (const_int 0))
2523     (parallel [(set (match_dup 3)
2524		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2525			      (match_dup 4)))
2526		(use (const_int 1))]))
2527   (cond_exec (ne (match_dup 6) (const_int 0))
2528     (parallel [(set (match_dup 0)
2529		     (plus:TF (mult:TF (match_dup 5) (match_dup 0))
2530			      (match_dup 0)))
2531		(use (const_int 1))]))
2532   (cond_exec (ne (match_dup 6) (const_int 0))
2533     (parallel [(set (match_dup 4)
2534		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2535			      (match_dup 1)))
2536		(use (const_int 1))]))
2537   (cond_exec (ne (match_dup 6) (const_int 0))
2538     (parallel [(set (match_dup 0)
2539		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2540			      (match_dup 3)))
2541		(use (const_int 1))]))
2542  ] 
2543  "operands[7] = CONST1_RTX (TFmode);"
2544  [(set_attr "predicable" "no")])
2545
2546(define_insn_and_split "divdi3_internal_thr"
2547  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2548	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2549			  (match_operand:TF 2 "fr_register_operand" "f"))))
2550   (clobber (match_scratch:TF 3 "=&f"))
2551   (clobber (match_scratch:TF 4 "=f"))
2552   (clobber (match_scratch:BI 5 "=c"))]
2553  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_THR"
2554  "#"
2555  "&& reload_completed"
2556  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2557	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 
2558					    UNSPEC_FR_RECIP_APPROX))
2559	      (use (const_int 1))])
2560   (cond_exec (ne (match_dup 5) (const_int 0))
2561     (parallel [(set (match_dup 3)
2562		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2563			      (match_dup 6)))
2564		(use (const_int 1))]))
2565   (cond_exec (ne (match_dup 5) (const_int 0))
2566     (parallel [(set (match_dup 0)
2567		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2568			      (match_dup 0)))
2569		(use (const_int 1))]))
2570   (cond_exec (ne (match_dup 5) (const_int 0))
2571     (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
2572		(use (const_int 1))]))
2573   (cond_exec (ne (match_dup 5) (const_int 0))
2574     (parallel [(set (match_dup 0)
2575		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2576			      (match_dup 0)))
2577		(use (const_int 1))]))
2578   (cond_exec (ne (match_dup 5) (const_int 0))
2579     (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
2580		(use (const_int 1))]))
2581   (cond_exec (ne (match_dup 5) (const_int 0))
2582     (parallel [(set (match_dup 4)
2583		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2584			      (match_dup 1)))
2585		(use (const_int 1))]))
2586   (cond_exec (ne (match_dup 5) (const_int 0))
2587     (parallel [(set (match_dup 0)
2588		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2589			      (match_dup 3)))
2590		(use (const_int 1))]))
2591  ] 
2592  "operands[6] = CONST1_RTX (TFmode);"
2593  [(set_attr "predicable" "no")])
2594
2595;; ::::::::::::::::::::
2596;; ::
2597;; :: 32 bit floating point arithmetic
2598;; ::
2599;; ::::::::::::::::::::
2600
2601(define_insn "addsf3"
2602  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2603	(plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2604		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2605  ""
2606  "fadd.s %0 = %1, %F2"
2607  [(set_attr "itanium_class" "fmac")])
2608
2609(define_insn "subsf3"
2610  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2611	(minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2612		  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2613  ""
2614  "fsub.s %0 = %F1, %F2"
2615  [(set_attr "itanium_class" "fmac")])
2616
2617(define_insn "mulsf3"
2618  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2619	(mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2620		 (match_operand:SF 2 "fr_register_operand" "f")))]
2621  ""
2622  "fmpy.s %0 = %1, %2"
2623  [(set_attr "itanium_class" "fmac")])
2624
2625(define_insn "abssf2"
2626  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2627	(abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2628  ""
2629  "fabs %0 = %1"
2630  [(set_attr "itanium_class" "fmisc")])
2631
2632(define_insn "negsf2"
2633  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2634	(neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2635  ""
2636  "fneg %0 = %1"
2637  [(set_attr "itanium_class" "fmisc")])
2638
2639(define_insn "*nabssf2"
2640  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2641	(neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
2642  ""
2643  "fnegabs %0 = %1"
2644  [(set_attr "itanium_class" "fmisc")])
2645
2646(define_insn "minsf3"
2647  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2648	(smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2649		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2650  ""
2651  "fmin %0 = %1, %F2"
2652  [(set_attr "itanium_class" "fmisc")])
2653
2654(define_insn "maxsf3"
2655  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2656	(smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2657		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2658  ""
2659  "fmax %0 = %1, %F2"
2660  [(set_attr "itanium_class" "fmisc")])
2661
2662(define_insn "*maddsf4"
2663  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2664	(plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2665			  (match_operand:SF 2 "fr_register_operand" "f"))
2666		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2667  ""
2668  "fma.s %0 = %1, %2, %F3"
2669  [(set_attr "itanium_class" "fmac")])
2670
2671(define_insn "*msubsf4"
2672  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2673	(minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2674			   (match_operand:SF 2 "fr_register_operand" "f"))
2675		  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2676  ""
2677  "fms.s %0 = %1, %2, %F3"
2678  [(set_attr "itanium_class" "fmac")])
2679
2680(define_insn "*nmulsf3"
2681  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2682	(neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2683			 (match_operand:SF 2 "fr_register_operand" "f"))))]
2684  ""
2685  "fnmpy.s %0 = %1, %2"
2686  [(set_attr "itanium_class" "fmac")])
2687
2688;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2689
2690(define_insn "*nmaddsf4"
2691  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2692	(plus:SF (neg:SF (mult:SF
2693			   (match_operand:SF 1 "fr_register_operand" "f")
2694			   (match_operand:SF 2 "fr_register_operand" "f")))
2695		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2696  ""
2697  "fnma.s %0 = %1, %2, %F3"
2698  [(set_attr "itanium_class" "fmac")])
2699
2700(define_expand "divsf3"
2701  [(set (match_operand:SF 0 "fr_register_operand" "")
2702	(div:SF (match_operand:SF 1 "fr_register_operand" "")
2703		(match_operand:SF 2 "fr_register_operand" "")))]
2704  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
2705{
2706  rtx insn;
2707  if (TARGET_INLINE_FLOAT_DIV_LAT)
2708    insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
2709  else
2710    insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
2711  emit_insn (insn);
2712  DONE;
2713})
2714
2715(define_insn_and_split "divsf3_internal_lat"
2716  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2717	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
2718		(match_operand:SF 2 "fr_register_operand" "f")))
2719   (clobber (match_scratch:TF 3 "=&f"))
2720   (clobber (match_scratch:TF 4 "=f"))
2721   (clobber (match_scratch:BI 5 "=c"))]
2722  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
2723  "#"
2724  "&& reload_completed"
2725  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
2726	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2727					    UNSPEC_FR_RECIP_APPROX))
2728	      (use (const_int 1))])
2729   (cond_exec (ne (match_dup 5) (const_int 0))
2730     (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
2731		(use (const_int 1))]))
2732   (cond_exec (ne (match_dup 5) (const_int 0))
2733     (parallel [(set (match_dup 4)
2734		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
2735			      (match_dup 10)))
2736		(use (const_int 1))]))
2737   (cond_exec (ne (match_dup 5) (const_int 0))
2738     (parallel [(set (match_dup 3)
2739		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2740			      (match_dup 3)))
2741		(use (const_int 1))]))
2742   (cond_exec (ne (match_dup 5) (const_int 0))
2743     (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
2744		(use (const_int 1))]))
2745   (cond_exec (ne (match_dup 5) (const_int 0))
2746     (parallel [(set (match_dup 3)
2747		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2748			      (match_dup 3)))
2749		(use (const_int 1))]))
2750   (cond_exec (ne (match_dup 5) (const_int 0))
2751     (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
2752		(use (const_int 1))]))
2753   (cond_exec (ne (match_dup 5) (const_int 0))
2754     (parallel [(set (match_dup 9)
2755		     (float_truncate:DF
2756		       (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2757			      (match_dup 3))))
2758		(use (const_int 1))]))
2759   (cond_exec (ne (match_dup 5) (const_int 0))
2760     (set (match_dup 0)
2761	  (float_truncate:SF (match_dup 6))))
2762  ] 
2763{
2764  operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2765  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2766  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2767  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2768  operands[10] = CONST1_RTX (TFmode);
2769}
2770  [(set_attr "predicable" "no")])
2771
2772(define_insn_and_split "divsf3_internal_thr"
2773  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2774	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
2775		(match_operand:SF 2 "fr_register_operand" "f")))
2776   (clobber (match_scratch:TF 3 "=&f"))
2777   (clobber (match_scratch:TF 4 "=f"))
2778   (clobber (match_scratch:BI 5 "=c"))]
2779  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
2780  "#"
2781  "&& reload_completed"
2782  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
2783	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2784					    UNSPEC_FR_RECIP_APPROX))
2785	      (use (const_int 1))])
2786   (cond_exec (ne (match_dup 5) (const_int 0))
2787     (parallel [(set (match_dup 3)
2788		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
2789			      (match_dup 10)))
2790		(use (const_int 1))]))
2791   (cond_exec (ne (match_dup 5) (const_int 0))
2792     (parallel [(set (match_dup 3)
2793		     (plus:TF (mult:TF (match_dup 3) (match_dup 3))
2794			      (match_dup 3)))
2795		(use (const_int 1))]))
2796   (cond_exec (ne (match_dup 5) (const_int 0))
2797     (parallel [(set (match_dup 6)
2798		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
2799			      (match_dup 6)))
2800		(use (const_int 1))]))
2801   (cond_exec (ne (match_dup 5) (const_int 0))
2802     (parallel [(set (match_dup 9)
2803		     (float_truncate:SF
2804		       (mult:TF (match_dup 7) (match_dup 6))))
2805		(use (const_int 1))]))
2806   (cond_exec (ne (match_dup 5) (const_int 0))
2807     (parallel [(set (match_dup 4)
2808		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3)))
2809			      (match_dup 7)))
2810		(use (const_int 1))]))
2811   (cond_exec (ne (match_dup 5) (const_int 0))
2812     (set (match_dup 0)
2813	  (float_truncate:SF
2814	    (plus:TF (mult:TF (match_dup 4) (match_dup 6))
2815			      (match_dup 3)))))
2816  ] 
2817{
2818  operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2819  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2820  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2821  operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
2822  operands[10] = CONST1_RTX (TFmode);
2823}
2824  [(set_attr "predicable" "no")])
2825
2826;; ::::::::::::::::::::
2827;; ::
2828;; :: 64 bit floating point arithmetic
2829;; ::
2830;; ::::::::::::::::::::
2831
2832(define_insn "adddf3"
2833  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2834	(plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2835		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2836  ""
2837  "fadd.d %0 = %1, %F2"
2838  [(set_attr "itanium_class" "fmac")])
2839
2840(define_insn "*adddf3_trunc"
2841  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2842	(float_truncate:SF
2843	  (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2844		   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2845  ""
2846  "fadd.s %0 = %1, %F2"
2847  [(set_attr "itanium_class" "fmac")])
2848
2849(define_insn "subdf3"
2850  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2851	(minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2852		  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2853  ""
2854  "fsub.d %0 = %F1, %F2"
2855  [(set_attr "itanium_class" "fmac")])
2856
2857(define_insn "*subdf3_trunc"
2858  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2859	(float_truncate:SF
2860	  (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2861		    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2862  ""
2863  "fsub.s %0 = %F1, %F2"
2864  [(set_attr "itanium_class" "fmac")])
2865
2866(define_insn "muldf3"
2867  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2868	(mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2869		 (match_operand:DF 2 "fr_register_operand" "f")))]
2870  ""
2871  "fmpy.d %0 = %1, %2"
2872  [(set_attr "itanium_class" "fmac")])
2873
2874(define_insn "*muldf3_trunc"
2875  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2876	(float_truncate:SF
2877	  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2878		   (match_operand:DF 2 "fr_register_operand" "f"))))]
2879  ""
2880  "fmpy.s %0 = %1, %2"
2881  [(set_attr "itanium_class" "fmac")])
2882
2883(define_insn "absdf2"
2884  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2885	(abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2886  ""
2887  "fabs %0 = %1"
2888  [(set_attr "itanium_class" "fmisc")])
2889
2890(define_insn "negdf2"
2891  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2892	(neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2893  ""
2894  "fneg %0 = %1"
2895  [(set_attr "itanium_class" "fmisc")])
2896
2897(define_insn "*nabsdf2"
2898  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2899	(neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
2900  ""
2901  "fnegabs %0 = %1"
2902  [(set_attr "itanium_class" "fmisc")])
2903
2904(define_insn "mindf3"
2905  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2906	(smin:DF (match_operand:DF 1 "fr_register_operand" "f")
2907		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2908  ""
2909  "fmin %0 = %1, %F2"
2910  [(set_attr "itanium_class" "fmisc")])
2911
2912(define_insn "maxdf3"
2913  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2914	(smax:DF (match_operand:DF 1 "fr_register_operand" "f")
2915		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2916  ""
2917  "fmax %0 = %1, %F2"
2918  [(set_attr "itanium_class" "fmisc")])
2919
2920(define_insn "*madddf4"
2921  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2922	(plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2923			  (match_operand:DF 2 "fr_register_operand" "f"))
2924		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2925  ""
2926  "fma.d %0 = %1, %2, %F3"
2927  [(set_attr "itanium_class" "fmac")])
2928
2929(define_insn "*madddf4_trunc"
2930  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2931	(float_truncate:SF
2932	  (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2933			    (match_operand:DF 2 "fr_register_operand" "f"))
2934		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
2935  ""
2936  "fma.s %0 = %1, %2, %F3"
2937  [(set_attr "itanium_class" "fmac")])
2938
2939(define_insn "*msubdf4"
2940  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2941	(minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2942			   (match_operand:DF 2 "fr_register_operand" "f"))
2943		  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2944  ""
2945  "fms.d %0 = %1, %2, %F3"
2946  [(set_attr "itanium_class" "fmac")])
2947
2948(define_insn "*msubdf4_trunc"
2949  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2950	(float_truncate:SF
2951	  (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2952			     (match_operand:DF 2 "fr_register_operand" "f"))
2953		    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
2954  ""
2955  "fms.s %0 = %1, %2, %F3"
2956  [(set_attr "itanium_class" "fmac")])
2957
2958(define_insn "*nmuldf3"
2959  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2960	(neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2961			 (match_operand:DF 2 "fr_register_operand" "f"))))]
2962  ""
2963  "fnmpy.d %0 = %1, %2"
2964  [(set_attr "itanium_class" "fmac")])
2965
2966(define_insn "*nmuldf3_trunc"
2967  [(set (match_operand:SF 0 "fr_register_operand" "=f")
2968	(float_truncate:SF
2969	  (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2970			   (match_operand:DF 2 "fr_register_operand" "f")))))]
2971  ""
2972  "fnmpy.s %0 = %1, %2"
2973  [(set_attr "itanium_class" "fmac")])
2974
2975;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2976
2977(define_insn "*nmadddf4"
2978  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2979	(plus:DF (neg:DF (mult:DF
2980			   (match_operand:DF 1 "fr_register_operand" "f")
2981			   (match_operand:DF 2 "fr_register_operand" "f")))
2982		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2983  ""
2984  "fnma.d %0 = %1, %2, %F3"
2985  [(set_attr "itanium_class" "fmac")])
2986
2987(define_insn "*nmadddf4_alts"
2988  [(set (match_operand:DF 0 "fr_register_operand" "=f")
2989	(plus:DF (neg:DF (mult:DF
2990			   (match_operand:DF 1 "fr_register_operand" "f")
2991			   (match_operand:DF 2 "fr_register_operand" "f")))
2992		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
2993   (use (match_operand:SI 4 "const_int_operand" ""))]
2994  ""
2995  "fnma.d.s%4 %0 = %1, %2, %F3"
2996  [(set_attr "itanium_class" "fmac")])
2997
2998(define_insn "*nmadddf4_trunc"
2999  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3000	(float_truncate:SF
3001	  (plus:DF (neg:DF (mult:DF
3002			     (match_operand:DF 1 "fr_register_operand" "f")
3003			     (match_operand:DF 2 "fr_register_operand" "f")))
3004		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3005  ""
3006  "fnma.s %0 = %1, %2, %F3"
3007  [(set_attr "itanium_class" "fmac")])
3008
3009(define_expand "divdf3"
3010  [(set (match_operand:DF 0 "fr_register_operand" "")
3011	(div:DF (match_operand:DF 1 "fr_register_operand" "")
3012		(match_operand:DF 2 "fr_register_operand" "")))]
3013  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
3014{
3015  rtx insn;
3016  if (TARGET_INLINE_FLOAT_DIV_LAT)
3017    insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
3018  else
3019    insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
3020  emit_insn (insn);
3021  DONE;
3022})
3023
3024(define_insn_and_split "divdf3_internal_lat"
3025  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3026	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
3027		(match_operand:DF 2 "fr_register_operand" "f")))
3028   (clobber (match_scratch:TF 3 "=&f"))
3029   (clobber (match_scratch:TF 4 "=&f"))
3030   (clobber (match_scratch:TF 5 "=&f"))
3031   (clobber (match_scratch:BI 6 "=c"))]
3032  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
3033  "#"
3034  "&& reload_completed"
3035  [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
3036	      (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3037					    UNSPEC_FR_RECIP_APPROX))
3038	      (use (const_int 1))])
3039   (cond_exec (ne (match_dup 6) (const_int 0))
3040     (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
3041		(use (const_int 1))]))
3042   (cond_exec (ne (match_dup 6) (const_int 0))
3043     (parallel [(set (match_dup 4)
3044		     (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7)))
3045			      (match_dup 12)))
3046		(use (const_int 1))]))
3047   (cond_exec (ne (match_dup 6) (const_int 0))
3048     (parallel [(set (match_dup 3)
3049		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
3050			      (match_dup 3)))
3051		(use (const_int 1))]))
3052   (cond_exec (ne (match_dup 6) (const_int 0))
3053     (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4)))
3054		(use (const_int 1))]))
3055   (cond_exec (ne (match_dup 6) (const_int 0))
3056     (parallel [(set (match_dup 7)
3057		     (plus:TF (mult:TF (match_dup 4) (match_dup 7))
3058			      (match_dup 7)))
3059		(use (const_int 1))]))
3060   (cond_exec (ne (match_dup 6) (const_int 0))
3061     (parallel [(set (match_dup 3)
3062		     (plus:TF (mult:TF (match_dup 5) (match_dup 3))
3063			      (match_dup 3)))
3064		(use (const_int 1))]))
3065   (cond_exec (ne (match_dup 6) (const_int 0))
3066     (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5)))
3067		(use (const_int 1))]))
3068   (cond_exec (ne (match_dup 6) (const_int 0))
3069     (parallel [(set (match_dup 7)
3070		     (plus:TF (mult:TF (match_dup 5) (match_dup 7))
3071			      (match_dup 7)))
3072		(use (const_int 1))]))
3073   (cond_exec (ne (match_dup 6) (const_int 0))
3074     (parallel [(set (match_dup 10)
3075		     (float_truncate:DF
3076		       (plus:TF (mult:TF (match_dup 4) (match_dup 3))
3077			      (match_dup 3))))
3078		(use (const_int 1))]))
3079   (cond_exec (ne (match_dup 6) (const_int 0))
3080     (parallel [(set (match_dup 7)
3081		     (plus:TF (mult:TF (match_dup 4) (match_dup 7))
3082			      (match_dup 7)))
3083		(use (const_int 1))]))
3084   (cond_exec (ne (match_dup 6) (const_int 0))
3085     (parallel [(set (match_dup 11)
3086		     (float_truncate:DF
3087		       (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3)))
3088			        (match_dup 8))))
3089		(use (const_int 1))]))
3090   (cond_exec (ne (match_dup 6) (const_int 0))
3091     (set (match_dup 0)
3092	  (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7))
3093			      (match_dup 3)))))
3094  ] 
3095{
3096  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3097  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3098  operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3099  operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3100  operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3101  operands[12] = CONST1_RTX (TFmode);
3102}
3103  [(set_attr "predicable" "no")])
3104
3105(define_insn_and_split "divdf3_internal_thr"
3106  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3107	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
3108		(match_operand:DF 2 "fr_register_operand" "f")))
3109   (clobber (match_scratch:TF 3 "=&f"))
3110   (clobber (match_scratch:DF 4 "=f"))
3111   (clobber (match_scratch:BI 5 "=c"))]
3112  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
3113  "#"
3114  "&& reload_completed"
3115  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
3116	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3117					    UNSPEC_FR_RECIP_APPROX))
3118	      (use (const_int 1))])
3119   (cond_exec (ne (match_dup 5) (const_int 0))
3120     (parallel [(set (match_dup 3)
3121		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
3122			      (match_dup 10)))
3123		(use (const_int 1))]))
3124   (cond_exec (ne (match_dup 5) (const_int 0))
3125     (parallel [(set (match_dup 6)
3126		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3127			      (match_dup 6)))
3128		(use (const_int 1))]))
3129   (cond_exec (ne (match_dup 5) (const_int 0))
3130     (parallel [(set (match_dup 3)
3131		     (mult:TF (match_dup 3) (match_dup 3)))
3132		(use (const_int 1))]))
3133   (cond_exec (ne (match_dup 5) (const_int 0))
3134     (parallel [(set (match_dup 6)
3135		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3136			      (match_dup 6)))
3137		(use (const_int 1))]))
3138   (cond_exec (ne (match_dup 5) (const_int 0))
3139     (parallel [(set (match_dup 3)
3140		     (mult:TF (match_dup 3) (match_dup 3)))
3141		(use (const_int 1))]))
3142   (cond_exec (ne (match_dup 5) (const_int 0))
3143     (parallel [(set (match_dup 6)
3144		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3145			      (match_dup 6)))
3146		(use (const_int 1))]))
3147   (cond_exec (ne (match_dup 5) (const_int 0))
3148     (parallel [(set (match_dup 9)
3149		     (float_truncate:DF
3150		       (mult:TF (match_dup 7) (match_dup 3))))
3151		(use (const_int 1))]))
3152   (cond_exec (ne (match_dup 5) (const_int 0))
3153     (parallel [(set (match_dup 4)
3154		     (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
3155			      (match_dup 1)))
3156		(use (const_int 1))]))
3157   (cond_exec (ne (match_dup 5) (const_int 0))
3158     (set (match_dup 0)
3159	  (plus:DF (mult:DF (match_dup 4) (match_dup 0))
3160			    (match_dup 9))))
3161  ] 
3162{
3163  operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3164  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3165  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3166  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3167  operands[10] = CONST1_RTX (TFmode);
3168}
3169  [(set_attr "predicable" "no")])
3170
3171;; ::::::::::::::::::::
3172;; ::
3173;; :: 80 bit floating point arithmetic
3174;; ::
3175;; ::::::::::::::::::::
3176
3177(define_insn "addtf3"
3178  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3179	(plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3180		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3181  "INTEL_EXTENDED_IEEE_FORMAT"
3182  "fadd %0 = %F1, %F2"
3183  [(set_attr "itanium_class" "fmac")])
3184
3185(define_insn "*addtf3_truncsf"
3186  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3187	(float_truncate:SF
3188	  (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3189		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3190  "INTEL_EXTENDED_IEEE_FORMAT"
3191  "fadd.s %0 = %F1, %F2"
3192  [(set_attr "itanium_class" "fmac")])
3193
3194(define_insn "*addtf3_truncdf"
3195  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3196	(float_truncate:DF
3197	  (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3198		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3199  "INTEL_EXTENDED_IEEE_FORMAT"
3200  "fadd.d %0 = %F1, %F2"
3201  [(set_attr "itanium_class" "fmac")])
3202
3203(define_insn "subtf3"
3204  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3205	(minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3206		  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3207  "INTEL_EXTENDED_IEEE_FORMAT"
3208  "fsub %0 = %F1, %F2"
3209  [(set_attr "itanium_class" "fmac")])
3210
3211(define_insn "*subtf3_truncsf"
3212  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3213	(float_truncate:SF
3214	  (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3215		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3216  "INTEL_EXTENDED_IEEE_FORMAT"
3217  "fsub.s %0 = %F1, %F2"
3218  [(set_attr "itanium_class" "fmac")])
3219
3220(define_insn "*subtf3_truncdf"
3221  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3222	(float_truncate:DF
3223	  (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3224		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3225  "INTEL_EXTENDED_IEEE_FORMAT"
3226  "fsub.d %0 = %F1, %F2"
3227  [(set_attr "itanium_class" "fmac")])
3228
3229(define_insn "multf3"
3230  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3231	(mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3232		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3233  "INTEL_EXTENDED_IEEE_FORMAT"
3234  "fmpy %0 = %F1, %F2"
3235  [(set_attr "itanium_class" "fmac")])
3236
3237(define_insn "*multf3_truncsf"
3238  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3239	(float_truncate:SF
3240	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3241		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3242  "INTEL_EXTENDED_IEEE_FORMAT"
3243  "fmpy.s %0 = %F1, %F2"
3244  [(set_attr "itanium_class" "fmac")])
3245
3246(define_insn "*multf3_truncdf"
3247  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3248	(float_truncate:DF
3249	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3250		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3251  "INTEL_EXTENDED_IEEE_FORMAT"
3252  "fmpy.d %0 = %F1, %F2"
3253  [(set_attr "itanium_class" "fmac")])
3254
3255(define_insn "*multf3_alts"
3256  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3257	(mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3258		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3259   (use (match_operand:SI 3 "const_int_operand" ""))]
3260  "INTEL_EXTENDED_IEEE_FORMAT"
3261  "fmpy.s%3 %0 = %F1, %F2"
3262  [(set_attr "itanium_class" "fmac")])
3263
3264(define_insn "*multf3_truncsf_alts"
3265  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3266	(float_truncate:SF
3267	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3268		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
3269   (use (match_operand:SI 3 "const_int_operand" ""))]
3270  "INTEL_EXTENDED_IEEE_FORMAT"
3271  "fmpy.s.s%3 %0 = %F1, %F2"
3272  [(set_attr "itanium_class" "fmac")])
3273
3274(define_insn "*multf3_truncdf_alts"
3275  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3276	(float_truncate:DF
3277	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3278		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
3279   (use (match_operand:SI 3 "const_int_operand" ""))]
3280  "INTEL_EXTENDED_IEEE_FORMAT"
3281  "fmpy.d.s%3 %0 = %F1, %F2"
3282  [(set_attr "itanium_class" "fmac")])
3283
3284(define_insn "abstf2"
3285  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3286	(abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
3287  "INTEL_EXTENDED_IEEE_FORMAT"
3288  "fabs %0 = %F1"
3289  [(set_attr "itanium_class" "fmisc")])
3290
3291(define_insn "negtf2"
3292  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3293	(neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
3294  "INTEL_EXTENDED_IEEE_FORMAT"
3295  "fneg %0 = %F1"
3296  [(set_attr "itanium_class" "fmisc")])
3297
3298(define_insn "*nabstf2"
3299  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3300	(neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
3301  "INTEL_EXTENDED_IEEE_FORMAT"
3302  "fnegabs %0 = %F1"
3303  [(set_attr "itanium_class" "fmisc")])
3304
3305(define_insn "mintf3"
3306  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3307	(smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3308		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3309  "INTEL_EXTENDED_IEEE_FORMAT"
3310  "fmin %0 = %F1, %F2"
3311  [(set_attr "itanium_class" "fmisc")])
3312
3313(define_insn "maxtf3"
3314  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3315	(smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3316		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3317  "INTEL_EXTENDED_IEEE_FORMAT"
3318  "fmax %0 = %F1, %F2"
3319  [(set_attr "itanium_class" "fmisc")])
3320
3321(define_insn "*maddtf4"
3322  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3323	(plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3324			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3325		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3326  "INTEL_EXTENDED_IEEE_FORMAT"
3327  "fma %0 = %F1, %F2, %F3"
3328  [(set_attr "itanium_class" "fmac")])
3329
3330(define_insn "*maddtf4_truncsf"
3331  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3332	(float_truncate:SF
3333	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3334			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3335		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3336  "INTEL_EXTENDED_IEEE_FORMAT"
3337  "fma.s %0 = %F1, %F2, %F3"
3338  [(set_attr "itanium_class" "fmac")])
3339
3340(define_insn "*maddtf4_truncdf"
3341  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3342	(float_truncate:DF
3343	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3344			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3345		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3346  "INTEL_EXTENDED_IEEE_FORMAT"
3347  "fma.d %0 = %F1, %F2, %F3"
3348  [(set_attr "itanium_class" "fmac")])
3349
3350(define_insn "*maddtf4_alts"
3351  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3352	(plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3353			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3354		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
3355   (use (match_operand:SI 4 "const_int_operand" ""))]
3356  "INTEL_EXTENDED_IEEE_FORMAT"
3357  "fma.s%4 %0 = %F1, %F2, %F3"
3358  [(set_attr "itanium_class" "fmac")])
3359
3360(define_insn "*maddtf4_alts_truncdf"
3361  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3362	(float_truncate:DF
3363	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3364			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3365		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
3366   (use (match_operand:SI 4 "const_int_operand" ""))]
3367  "INTEL_EXTENDED_IEEE_FORMAT"
3368  "fma.d.s%4 %0 = %F1, %F2, %F3"
3369  [(set_attr "itanium_class" "fmac")])
3370
3371(define_insn "*msubtf4"
3372  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3373	(minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3374			   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3375		  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3376  "INTEL_EXTENDED_IEEE_FORMAT"
3377  "fms %0 = %F1, %F2, %F3"
3378  [(set_attr "itanium_class" "fmac")])
3379
3380(define_insn "*msubtf4_truncsf"
3381  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3382	(float_truncate:SF
3383	  (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3384			     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3385		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3386  "INTEL_EXTENDED_IEEE_FORMAT"
3387  "fms.s %0 = %F1, %F2, %F3"
3388  [(set_attr "itanium_class" "fmac")])
3389
3390(define_insn "*msubtf4_truncdf"
3391  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3392	(float_truncate:DF
3393	  (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3394			     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3395		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3396  "INTEL_EXTENDED_IEEE_FORMAT"
3397  "fms.d %0 = %F1, %F2, %F3"
3398  [(set_attr "itanium_class" "fmac")])
3399
3400(define_insn "*nmultf3"
3401  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3402	(neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3403			 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3404  "INTEL_EXTENDED_IEEE_FORMAT"
3405  "fnmpy %0 = %F1, %F2"
3406  [(set_attr "itanium_class" "fmac")])
3407
3408(define_insn "*nmultf3_truncsf"
3409  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3410	(float_truncate:SF
3411	  (neg:TF (mult:TF
3412		    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3413		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
3414  "INTEL_EXTENDED_IEEE_FORMAT"
3415  "fnmpy.s %0 = %F1, %F2"
3416  [(set_attr "itanium_class" "fmac")])
3417
3418(define_insn "*nmultf3_truncdf"
3419  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3420	(float_truncate:DF
3421	  (neg:TF (mult:TF
3422		    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3423		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
3424  "INTEL_EXTENDED_IEEE_FORMAT"
3425  "fnmpy.d %0 = %F1, %F2"
3426  [(set_attr "itanium_class" "fmac")])
3427
3428;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3429
3430(define_insn "*nmaddtf4"
3431  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3432	(plus:TF (neg:TF (mult:TF
3433			  (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3434			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3435		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3436  "INTEL_EXTENDED_IEEE_FORMAT"
3437  "fnma %0 = %F1, %F2, %F3"
3438  [(set_attr "itanium_class" "fmac")])
3439
3440(define_insn "*nmaddtf4_truncsf"
3441  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3442	(float_truncate:SF
3443	  (plus:TF (neg:TF (mult:TF
3444			    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3445			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3446		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3447  "INTEL_EXTENDED_IEEE_FORMAT"
3448  "fnma.s %0 = %F1, %F2, %F3"
3449  [(set_attr "itanium_class" "fmac")])
3450
3451(define_insn "*nmaddtf4_truncdf"
3452  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3453	(float_truncate:DF
3454	  (plus:TF (neg:TF (mult:TF
3455			    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3456			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3457		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3458  "INTEL_EXTENDED_IEEE_FORMAT"
3459  "fnma.d %0 = %F1, %F2, %F3"
3460  [(set_attr "itanium_class" "fmac")])
3461
3462(define_insn "*nmaddtf4_alts"
3463  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3464	(plus:TF (neg:TF (mult:TF
3465			  (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3466			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3467		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
3468   (use (match_operand:SI 4 "const_int_operand" ""))]
3469  "INTEL_EXTENDED_IEEE_FORMAT"
3470  "fnma.s%4 %0 = %F1, %F2, %F3"
3471  [(set_attr "itanium_class" "fmac")])
3472
3473(define_insn "*nmaddtf4_truncdf_alts"
3474  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3475	(float_truncate:DF
3476	  (plus:TF (neg:TF
3477		     (mult:TF
3478		       (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3479		       (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3480		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
3481   (use (match_operand:SI 4 "const_int_operand" ""))]
3482  "INTEL_EXTENDED_IEEE_FORMAT"
3483  "fnma.d.s%4 %0 = %F1, %F2, %F3"
3484  [(set_attr "itanium_class" "fmac")])
3485
3486(define_expand "divtf3"
3487  [(set (match_operand:TF 0 "fr_register_operand" "")
3488	(div:TF (match_operand:TF 1 "fr_register_operand" "")
3489		(match_operand:TF 2 "fr_register_operand" "")))]
3490  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
3491{
3492  rtx insn;
3493  if (TARGET_INLINE_FLOAT_DIV_LAT)
3494    insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]);
3495  else
3496    insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]);
3497  emit_insn (insn);
3498  DONE;
3499})
3500
3501(define_insn_and_split "divtf3_internal_lat"
3502  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
3503	(div:TF (match_operand:TF 1 "fr_register_operand" "f")
3504		(match_operand:TF 2 "fr_register_operand" "f")))
3505   (clobber (match_scratch:TF 3 "=&f"))
3506   (clobber (match_scratch:TF 4 "=&f"))
3507   (clobber (match_scratch:TF 5 "=&f"))
3508   (clobber (match_scratch:TF 6 "=&f"))
3509   (clobber (match_scratch:BI 7 "=c"))]
3510  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
3511  "#"
3512  "&& reload_completed"
3513  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
3514	      (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
3515					    UNSPEC_FR_RECIP_APPROX))
3516	      (use (const_int 1))])
3517   (cond_exec (ne (match_dup 7) (const_int 0))
3518     (parallel [(set (match_dup 3)
3519		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3520			      (match_dup 8)))
3521		(use (const_int 1))]))
3522   (cond_exec (ne (match_dup 7) (const_int 0))
3523     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
3524		(use (const_int 1))]))
3525   (cond_exec (ne (match_dup 7) (const_int 0))
3526     (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
3527		(use (const_int 1))]))
3528   (cond_exec (ne (match_dup 7) (const_int 0))
3529     (parallel [(set (match_dup 6)
3530		     (plus:TF (mult:TF (match_dup 3) (match_dup 3))
3531			      (match_dup 3)))
3532		(use (const_int 1))]))
3533   (cond_exec (ne (match_dup 7) (const_int 0))
3534     (parallel [(set (match_dup 3)
3535		     (plus:TF (mult:TF (match_dup 5) (match_dup 5))
3536			      (match_dup 3)))
3537		(use (const_int 1))]))
3538   (cond_exec (ne (match_dup 7) (const_int 0))
3539     (parallel [(set (match_dup 5)
3540		     (plus:TF (mult:TF (match_dup 6) (match_dup 0))
3541			      (match_dup 0)))
3542		(use (const_int 1))]))
3543   (cond_exec (ne (match_dup 7) (const_int 0))
3544     (parallel [(set (match_dup 0)
3545		     (plus:TF (mult:TF (match_dup 5) (match_dup 3))
3546			      (match_dup 0)))
3547		(use (const_int 1))]))
3548   (cond_exec (ne (match_dup 7) (const_int 0))
3549     (parallel [(set (match_dup 4)
3550		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
3551			      (match_dup 1)))
3552		(use (const_int 1))]))
3553   (cond_exec (ne (match_dup 7) (const_int 0))
3554     (parallel [(set (match_dup 3)
3555		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3556			      (match_dup 4)))
3557		(use (const_int 1))]))
3558   (cond_exec (ne (match_dup 7) (const_int 0))
3559     (parallel [(set (match_dup 5)
3560		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3561			      (match_dup 8)))
3562		(use (const_int 1))]))
3563   (cond_exec (ne (match_dup 7) (const_int 0))
3564     (parallel [(set (match_dup 0)
3565		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3566			      (match_dup 0)))
3567		(use (const_int 1))]))
3568   (cond_exec (ne (match_dup 7) (const_int 0))
3569     (parallel [(set (match_dup 4)
3570		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3571			      (match_dup 1)))
3572		(use (const_int 1))]))
3573   (cond_exec (ne (match_dup 7) (const_int 0))
3574     (set (match_dup 0)
3575	  (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3576		   (match_dup 3))))
3577  ] 
3578  "operands[8] = CONST1_RTX (TFmode);"
3579  [(set_attr "predicable" "no")])
3580
3581(define_insn_and_split "divtf3_internal_thr"
3582  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
3583	(div:TF (match_operand:TF 1 "fr_register_operand" "f")
3584		(match_operand:TF 2 "fr_register_operand" "f")))
3585   (clobber (match_scratch:TF 3 "=&f"))
3586   (clobber (match_scratch:TF 4 "=&f"))
3587   (clobber (match_scratch:BI 5 "=c"))]
3588  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
3589  "#"
3590  "&& reload_completed"
3591  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
3592	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
3593					    UNSPEC_FR_RECIP_APPROX))
3594	      (use (const_int 1))])
3595   (cond_exec (ne (match_dup 5) (const_int 0))
3596     (parallel [(set (match_dup 3)
3597		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3598			      (match_dup 6)))
3599		(use (const_int 1))]))
3600   (cond_exec (ne (match_dup 5) (const_int 0))
3601     (parallel [(set (match_dup 4)
3602		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3603			      (match_dup 0)))
3604		(use (const_int 1))]))
3605   (cond_exec (ne (match_dup 5) (const_int 0))
3606     (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
3607		(use (const_int 1))]))
3608   (cond_exec (ne (match_dup 5) (const_int 0))
3609     (parallel [(set (match_dup 3)
3610		     (plus:TF (mult:TF (match_dup 3) (match_dup 4))
3611			      (match_dup 4)))
3612		(use (const_int 1))]))
3613   (cond_exec (ne (match_dup 5) (const_int 0))
3614     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
3615		(use (const_int 1))]))
3616   (cond_exec (ne (match_dup 5) (const_int 0))
3617     (parallel [(set (match_dup 0)
3618		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3619			      (match_dup 6)))
3620		(use (const_int 1))]))
3621   (cond_exec (ne (match_dup 5) (const_int 0))
3622     (parallel [(set (match_dup 0)
3623		     (plus:TF (mult:TF (match_dup 0) (match_dup 3))
3624			      (match_dup 3)))
3625		(use (const_int 1))]))
3626   (cond_exec (ne (match_dup 5) (const_int 0))
3627     (parallel [(set (match_dup 3)
3628		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
3629			      (match_dup 1)))
3630		(use (const_int 1))]))
3631   (cond_exec (ne (match_dup 5) (const_int 0))
3632     (parallel [(set (match_dup 3)
3633		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3634			      (match_dup 4)))
3635		(use (const_int 1))]))
3636   (cond_exec (ne (match_dup 5) (const_int 0))
3637     (parallel [(set (match_dup 4)
3638		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3639			      (match_dup 6)))
3640		(use (const_int 1))]))
3641   (cond_exec (ne (match_dup 5) (const_int 0))
3642     (parallel [(set (match_dup 0)
3643		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3644			      (match_dup 0)))
3645		(use (const_int 1))]))
3646   (cond_exec (ne (match_dup 5) (const_int 0))
3647     (parallel [(set (match_dup 4)
3648		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3649			      (match_dup 1)))
3650		(use (const_int 1))]))
3651   (cond_exec (ne (match_dup 5) (const_int 0))
3652     (set (match_dup 0)
3653	  (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3654		   (match_dup 3))))
3655  ] 
3656  "operands[6] = CONST1_RTX (TFmode);"
3657  [(set_attr "predicable" "no")])
3658
3659;; ??? frcpa works like cmp.foo.unc.
3660
3661(define_insn "*recip_approx"
3662  [(set (match_operand:TF 0 "fr_register_operand" "=f")
3663	(div:TF (const_int 1)
3664		(match_operand:TF 3 "fr_register_operand" "f")))
3665   (set (match_operand:BI 1 "register_operand" "=c")
3666	(unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
3667		    (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
3668   (use (match_operand:SI 4 "const_int_operand" ""))]
3669  "INTEL_EXTENDED_IEEE_FORMAT"
3670  "frcpa.s%4 %0, %1 = %2, %3"
3671  [(set_attr "itanium_class" "fmisc")
3672   (set_attr "predicable" "no")])
3673
3674;; ::::::::::::::::::::
3675;; ::
3676;; :: 32 bit Integer Shifts and Rotates
3677;; ::
3678;; ::::::::::::::::::::
3679
3680(define_expand "ashlsi3"
3681  [(set (match_operand:SI 0 "gr_register_operand" "")
3682	(ashift:SI (match_operand:SI 1 "gr_register_operand" "")
3683		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3684  ""
3685{
3686  if (GET_CODE (operands[2]) != CONST_INT)
3687    {
3688      /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
3689	 we've got to get rid of stray bits outside the SImode register.  */
3690      rtx subshift = gen_reg_rtx (DImode);
3691      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3692      operands[2] = subshift;
3693    }
3694})
3695
3696(define_insn "*ashlsi3_internal"
3697  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
3698	(ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
3699		   (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
3700  ""
3701  "@
3702   shladd %0 = %1, %2, r0
3703   dep.z %0 = %1, %2, %E2
3704   shl %0 = %1, %2"
3705  [(set_attr "itanium_class" "ialu,ishf,mmshf")])
3706
3707(define_expand "ashrsi3"
3708  [(set (match_operand:SI 0 "gr_register_operand" "")
3709	(ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3710		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3711  ""
3712{
3713  rtx subtarget = gen_reg_rtx (DImode);
3714  if (GET_CODE (operands[2]) == CONST_INT)
3715    emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
3716			 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3717  else
3718    {
3719      rtx subshift = gen_reg_rtx (DImode);
3720      emit_insn (gen_extendsidi2 (subtarget, operands[1]));
3721      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3722      emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
3723    }
3724  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3725  DONE;
3726})
3727
3728(define_expand "lshrsi3"
3729  [(set (match_operand:SI 0 "gr_register_operand" "")
3730	(lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3731		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3732  ""
3733{
3734  rtx subtarget = gen_reg_rtx (DImode);
3735  if (GET_CODE (operands[2]) == CONST_INT)
3736    emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
3737			  GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3738  else
3739    {
3740      rtx subshift = gen_reg_rtx (DImode);
3741      emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
3742      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3743      emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
3744    }
3745  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3746  DONE;
3747})
3748
3749;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
3750;; here, instead of 64 like the patterns above.  Keep the pattern together
3751;; until after combine; otherwise it won't get matched often.
3752
3753(define_expand "rotrsi3"
3754  [(set (match_operand:SI 0 "gr_register_operand" "")
3755	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
3756		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3757  ""
3758{
3759  if (GET_MODE (operands[2]) != VOIDmode)
3760    {
3761      rtx tmp = gen_reg_rtx (DImode);
3762      emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
3763      operands[2] = tmp;
3764    }
3765})
3766
3767(define_insn_and_split "*rotrsi3_internal"
3768  [(set (match_operand:SI 0 "gr_register_operand" "=&r")
3769	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
3770		     (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
3771  ""
3772  "#"
3773  "reload_completed"
3774  [(set (match_dup 3)
3775	(ior:DI (zero_extend:DI (match_dup 1))
3776		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
3777   (set (match_dup 3)
3778	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
3779  "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
3780
3781(define_expand "rotlsi3"
3782  [(set (match_operand:SI 0 "gr_register_operand" "")
3783	(rotate:SI (match_operand:SI 1 "gr_register_operand" "")
3784		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3785  ""
3786{
3787  if (! shift_32bit_count_operand (operands[2], SImode))
3788    {
3789      rtx tmp = gen_reg_rtx (SImode);
3790      emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
3791      emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
3792      DONE;
3793    }
3794})
3795
3796(define_insn_and_split "*rotlsi3_internal"
3797  [(set (match_operand:SI 0 "gr_register_operand" "=r")
3798	(rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
3799		   (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
3800  ""
3801  "#"
3802  "reload_completed"
3803  [(set (match_dup 3)
3804	(ior:DI (zero_extend:DI (match_dup 1))
3805		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
3806   (set (match_dup 3)
3807	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
3808{
3809  operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
3810  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
3811})
3812
3813;; ::::::::::::::::::::
3814;; ::
3815;; :: 64 bit Integer Shifts and Rotates
3816;; ::
3817;; ::::::::::::::::::::
3818
3819(define_insn "ashldi3"
3820  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
3821	(ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
3822		   (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
3823  ""
3824  "@
3825   shladd %0 = %1, %2, r0
3826   shl %0 = %1, %2
3827   shl %0 = %1, %2"
3828  [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
3829
3830;; ??? Maybe combine this with the multiply and add instruction?
3831
3832(define_insn "*shladd"
3833  [(set (match_operand:DI 0 "gr_register_operand" "=r")
3834	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
3835			  (match_operand:DI 2 "shladd_operand" "n"))
3836		 (match_operand:DI 3 "gr_register_operand" "r")))]
3837  ""
3838  "shladd %0 = %1, %S2, %3"
3839  [(set_attr "itanium_class" "ialu")])
3840
3841;; This can be created by register elimination if operand3 of shladd is an
3842;; eliminable register or has reg_equiv_constant set.
3843
3844;; We have to use nonmemory_operand for operand 4, to ensure that the
3845;; validate_changes call inside eliminate_regs will always succeed.  If it
3846;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
3847;; incorrectly.
3848
3849(define_insn_and_split "*shladd_elim"
3850  [(set (match_operand:DI 0 "gr_register_operand" "=&r")
3851	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
3852				   (match_operand:DI 2 "shladd_operand" "n"))
3853			  (match_operand:DI 3 "nonmemory_operand" "r"))
3854		 (match_operand:DI 4 "nonmemory_operand" "rI")))]
3855  "reload_in_progress"
3856  "* abort ();"
3857  "reload_completed"
3858  [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
3859			       (match_dup 3)))
3860   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
3861  ""
3862  [(set_attr "itanium_class" "unknown")])
3863
3864(define_insn "ashrdi3"
3865  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3866	(ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
3867		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
3868  ""
3869  "@
3870   shr %0 = %1, %2
3871   shr %0 = %1, %2"
3872  [(set_attr "itanium_class" "mmshf,mmshfi")])
3873
3874(define_insn "lshrdi3"
3875  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3876	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
3877		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
3878  ""
3879  "@
3880   shr.u %0 = %1, %2
3881   shr.u %0 = %1, %2"
3882  [(set_attr "itanium_class" "mmshf,mmshfi")])
3883
3884;; Using a predicate that accepts only constants doesn't work, because optabs
3885;; will load the operand into a register and call the pattern if the predicate
3886;; did not accept it on the first try.  So we use nonmemory_operand and then
3887;; verify that we have an appropriate constant in the expander.
3888
3889(define_expand "rotrdi3"
3890  [(set (match_operand:DI 0 "gr_register_operand" "")
3891	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
3892		     (match_operand:DI 2 "nonmemory_operand" "")))]
3893  ""
3894{
3895  if (! shift_count_operand (operands[2], DImode))
3896    FAIL;
3897})
3898
3899(define_insn "*rotrdi3_internal"
3900  [(set (match_operand:DI 0 "gr_register_operand" "=r")
3901	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
3902		     (match_operand:DI 2 "shift_count_operand" "M")))]
3903  ""
3904  "shrp %0 = %1, %1, %2"
3905  [(set_attr "itanium_class" "ishf")])
3906
3907(define_expand "rotldi3"
3908  [(set (match_operand:DI 0 "gr_register_operand" "")
3909	(rotate:DI (match_operand:DI 1 "gr_register_operand" "")
3910		   (match_operand:DI 2 "nonmemory_operand" "")))]
3911  ""
3912{
3913  if (! shift_count_operand (operands[2], DImode))
3914    FAIL;
3915})
3916
3917(define_insn "*rotldi3_internal"
3918  [(set (match_operand:DI 0 "gr_register_operand" "=r")
3919	(rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
3920		   (match_operand:DI 2 "shift_count_operand" "M")))]
3921  ""
3922  "shrp %0 = %1, %1, %e2"
3923  [(set_attr "itanium_class" "ishf")])
3924
3925;; ::::::::::::::::::::
3926;; ::
3927;; :: 32 bit Integer Logical operations
3928;; ::
3929;; ::::::::::::::::::::
3930
3931;; We don't seem to need any other 32-bit logical operations, because gcc
3932;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
3933;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
3934;; This doesn't work for unary logical operations, because we don't call
3935;; apply_distributive_law for them.
3936
3937;; ??? Likewise, this doesn't work for andnot, which isn't handled by
3938;; apply_distributive_law.  We get inefficient code for
3939;; int sub4 (int i, int j) { return i & ~j; }
3940;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
3941;; (zero_extend (and (not A) B)) in combine.
3942;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
3943;; one_cmplsi2 pattern.
3944
3945(define_insn "one_cmplsi2"
3946  [(set (match_operand:SI 0 "gr_register_operand" "=r")
3947	(not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
3948  ""
3949  "andcm %0 = -1, %1"
3950  [(set_attr "itanium_class" "ilog")])
3951
3952;; ::::::::::::::::::::
3953;; ::
3954;; :: 64 bit Integer Logical operations
3955;; ::
3956;; ::::::::::::::::::::
3957
3958(define_insn "anddi3"
3959  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3960	(and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3961		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3962  ""
3963  "@
3964   and %0 = %2, %1
3965   fand %0 = %2, %1"
3966  [(set_attr "itanium_class" "ilog,fmisc")])
3967
3968(define_insn "*andnot"
3969  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3970	(and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
3971		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3972  ""
3973  "@
3974   andcm %0 = %2, %1
3975   fandcm %0 = %2, %1"
3976  [(set_attr "itanium_class" "ilog,fmisc")])
3977
3978(define_insn "iordi3"
3979  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3980	(ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3981		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3982  ""
3983  "@
3984   or %0 = %2, %1
3985   for %0 = %2, %1"
3986  [(set_attr "itanium_class" "ilog,fmisc")])
3987
3988(define_insn "xordi3"
3989  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3990	(xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3991		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3992  ""
3993  "@
3994   xor %0 = %2, %1
3995   fxor %0 = %2, %1"
3996  [(set_attr "itanium_class" "ilog,fmisc")])
3997
3998(define_insn "one_cmpldi2"
3999  [(set (match_operand:DI 0 "gr_register_operand" "=r")
4000	(not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
4001  ""
4002  "andcm %0 = -1, %1"
4003  [(set_attr "itanium_class" "ilog")])
4004
4005;; ::::::::::::::::::::
4006;; ::
4007;; :: Comparisons
4008;; ::
4009;; ::::::::::::::::::::
4010
4011(define_expand "cmpbi"
4012  [(set (cc0)
4013        (compare (match_operand:BI 0 "register_operand" "")
4014  		 (match_operand:BI 1 "const_int_operand" "")))]
4015  ""
4016{
4017  ia64_compare_op0 = operands[0];
4018  ia64_compare_op1 = operands[1];
4019  DONE;
4020})
4021
4022(define_expand "cmpsi"
4023  [(set (cc0)
4024        (compare (match_operand:SI 0 "gr_register_operand" "")
4025  		 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
4026  ""
4027{
4028  ia64_compare_op0 = operands[0];
4029  ia64_compare_op1 = operands[1];
4030  DONE;
4031})
4032
4033(define_expand "cmpdi"
4034  [(set (cc0)
4035        (compare (match_operand:DI 0 "gr_register_operand" "")
4036  		 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
4037  ""
4038{
4039  ia64_compare_op0 = operands[0];
4040  ia64_compare_op1 = operands[1];
4041  DONE;
4042})
4043
4044(define_expand "cmpsf"
4045  [(set (cc0)
4046        (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
4047  		 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
4048  ""
4049{
4050  ia64_compare_op0 = operands[0];
4051  ia64_compare_op1 = operands[1];
4052  DONE;
4053})
4054
4055(define_expand "cmpdf"
4056  [(set (cc0)
4057        (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
4058  		 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
4059  ""
4060{
4061  ia64_compare_op0 = operands[0];
4062  ia64_compare_op1 = operands[1];
4063  DONE;
4064})
4065
4066(define_expand "cmptf"
4067  [(set (cc0)
4068        (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
4069  		 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
4070  "INTEL_EXTENDED_IEEE_FORMAT"
4071{
4072  ia64_compare_op0 = operands[0];
4073  ia64_compare_op1 = operands[1];
4074  DONE;
4075})
4076
4077(define_insn "*cmpsi_normal"
4078  [(set (match_operand:BI 0 "register_operand" "=c")
4079	(match_operator:BI 1 "normal_comparison_operator"
4080	   [(match_operand:SI 2 "gr_register_operand" "r")
4081	    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
4082  ""
4083  "cmp4.%C1 %0, %I0 = %3, %2"
4084  [(set_attr "itanium_class" "icmp")])
4085
4086;; We use %r3 because it is possible for us to match a 0, and two of the
4087;; unsigned comparisons don't accept immediate operands of zero.
4088
4089(define_insn "*cmpsi_adjusted"
4090  [(set (match_operand:BI 0 "register_operand" "=c")
4091	(match_operator:BI 1 "adjusted_comparison_operator"
4092	   [(match_operand:SI 2 "gr_register_operand" "r")
4093	    (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4094  ""
4095  "cmp4.%C1 %0, %I0 = %r3, %2"
4096  [(set_attr "itanium_class" "icmp")])
4097
4098(define_insn "*cmpdi_normal"
4099  [(set (match_operand:BI 0 "register_operand" "=c")
4100	(match_operator:BI 1 "normal_comparison_operator"
4101	   [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
4102	    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
4103  ""
4104  "cmp.%C1 %0, %I0 = %3, %r2"
4105  [(set_attr "itanium_class" "icmp")])
4106
4107;; We use %r3 because it is possible for us to match a 0, and two of the
4108;; unsigned comparisons don't accept immediate operands of zero.
4109
4110(define_insn "*cmpdi_adjusted"
4111  [(set (match_operand:BI 0 "register_operand" "=c")
4112	(match_operator:BI 1 "adjusted_comparison_operator"
4113	   [(match_operand:DI 2 "gr_register_operand" "r")
4114	    (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4115  ""
4116  "cmp.%C1 %0, %I0 = %r3, %2"
4117  [(set_attr "itanium_class" "icmp")])
4118
4119(define_insn "*cmpsf_internal"
4120  [(set (match_operand:BI 0 "register_operand" "=c")
4121	(match_operator:BI 1 "comparison_operator"
4122	   [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
4123	    (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
4124  ""
4125  "fcmp.%D1 %0, %I0 = %F2, %F3"
4126  [(set_attr "itanium_class" "fcmp")])
4127
4128(define_insn "*cmpdf_internal"
4129  [(set (match_operand:BI 0 "register_operand" "=c")
4130	(match_operator:BI 1 "comparison_operator"
4131	   [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
4132	    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
4133  ""
4134  "fcmp.%D1 %0, %I0 = %F2, %F3"
4135  [(set_attr "itanium_class" "fcmp")])
4136
4137(define_insn "*cmptf_internal"
4138  [(set (match_operand:BI 0 "register_operand" "=c")
4139	(match_operator:BI 1 "comparison_operator"
4140		   [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
4141		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
4142  "INTEL_EXTENDED_IEEE_FORMAT"
4143  "fcmp.%D1 %0, %I0 = %F2, %F3"
4144  [(set_attr "itanium_class" "fcmp")])
4145
4146;; ??? Can this pattern be generated?
4147
4148(define_insn "*bit_zero"
4149  [(set (match_operand:BI 0 "register_operand" "=c")
4150	(eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4151				(const_int 1)
4152				(match_operand:DI 2 "immediate_operand" "n"))
4153	       (const_int 0)))]
4154  ""
4155  "tbit.z %0, %I0 = %1, %2"
4156  [(set_attr "itanium_class" "tbit")])
4157
4158(define_insn "*bit_one"
4159  [(set (match_operand:BI 0 "register_operand" "=c")
4160	(ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4161				(const_int 1)
4162				(match_operand:DI 2 "immediate_operand" "n"))
4163	       (const_int 0)))]
4164  ""
4165  "tbit.nz %0, %I0 = %1, %2"
4166  [(set_attr "itanium_class" "tbit")])
4167
4168;; ::::::::::::::::::::
4169;; ::
4170;; :: Branches
4171;; ::
4172;; ::::::::::::::::::::
4173
4174(define_expand "beq"
4175  [(set (pc)
4176	(if_then_else (match_dup 1)
4177		      (label_ref (match_operand 0 "" ""))
4178		      (pc)))]
4179  ""
4180  "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
4181
4182(define_expand "bne"
4183  [(set (pc)
4184	(if_then_else (match_dup 1)
4185		      (label_ref (match_operand 0 "" ""))
4186		      (pc)))]
4187  ""
4188  "operands[1] = ia64_expand_compare (NE, VOIDmode);")
4189
4190(define_expand "blt"
4191  [(set (pc)
4192	(if_then_else (match_dup 1)
4193		      (label_ref (match_operand 0 "" ""))
4194		      (pc)))]
4195  ""
4196  "operands[1] = ia64_expand_compare (LT, VOIDmode);")
4197
4198(define_expand "ble"
4199  [(set (pc)
4200	(if_then_else (match_dup 1)
4201		      (label_ref (match_operand 0 "" ""))
4202		      (pc)))]
4203  ""
4204  "operands[1] = ia64_expand_compare (LE, VOIDmode);")
4205
4206(define_expand "bgt"
4207  [(set (pc)
4208	(if_then_else (match_dup 1)
4209		      (label_ref (match_operand 0 "" ""))
4210		      (pc)))]
4211  ""
4212  "operands[1] = ia64_expand_compare (GT, VOIDmode);")
4213
4214(define_expand "bge"
4215  [(set (pc)
4216	(if_then_else (match_dup 1)
4217		      (label_ref (match_operand 0 "" ""))
4218		      (pc)))]
4219  ""
4220  "operands[1] = ia64_expand_compare (GE, VOIDmode);")
4221
4222(define_expand "bltu"
4223  [(set (pc)
4224	(if_then_else (match_dup 1)
4225		      (label_ref (match_operand 0 "" ""))
4226		      (pc)))]
4227  ""
4228  "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
4229
4230(define_expand "bleu"
4231  [(set (pc)
4232	(if_then_else (match_dup 1)
4233		      (label_ref (match_operand 0 "" ""))
4234		      (pc)))]
4235  ""
4236  "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
4237
4238(define_expand "bgtu"
4239  [(set (pc)
4240	(if_then_else (match_dup 1)
4241		      (label_ref (match_operand 0 "" ""))
4242		      (pc)))]
4243  ""
4244  "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
4245
4246(define_expand "bgeu"
4247  [(set (pc)
4248	(if_then_else (match_dup 1)
4249		      (label_ref (match_operand 0 "" ""))
4250		      (pc)))]
4251  ""
4252  "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
4253
4254(define_expand "bunordered"
4255  [(set (pc)
4256	(if_then_else (match_dup 1)
4257		      (label_ref (match_operand 0 "" ""))
4258		      (pc)))]
4259  ""
4260  "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
4261
4262(define_expand "bordered"
4263  [(set (pc)
4264	(if_then_else (match_dup 1)
4265		      (label_ref (match_operand 0 "" ""))
4266		      (pc)))]
4267  ""
4268  "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
4269
4270(define_insn "*br_true"
4271  [(set (pc)
4272	(if_then_else (match_operator 0 "predicate_operator"
4273			[(match_operand:BI 1 "register_operand" "c")
4274			 (const_int 0)])
4275		      (label_ref (match_operand 2 "" ""))
4276		      (pc)))]
4277  ""
4278  "(%J0) br.cond%+ %l2"
4279  [(set_attr "itanium_class" "br")
4280   (set_attr "predicable" "no")])
4281
4282(define_insn "*br_false"
4283  [(set (pc)
4284	(if_then_else (match_operator 0 "predicate_operator"
4285			[(match_operand:BI 1 "register_operand" "c")
4286			 (const_int 0)])
4287		      (pc)
4288		      (label_ref (match_operand 2 "" ""))))]
4289  ""
4290  "(%j0) br.cond%+ %l2"
4291  [(set_attr "itanium_class" "br")
4292   (set_attr "predicable" "no")])
4293
4294;; ::::::::::::::::::::
4295;; ::
4296;; :: Counted loop operations
4297;; ::
4298;; ::::::::::::::::::::
4299
4300(define_expand "doloop_end"
4301  [(use (match_operand 0 "" ""))	; loop pseudo
4302   (use (match_operand 1 "" ""))	; iterations; zero if unknown
4303   (use (match_operand 2 "" ""))	; max iterations
4304   (use (match_operand 3 "" ""))	; loop level
4305   (use (match_operand 4 "" ""))]	; label
4306  ""
4307{
4308  /* Only use cloop on innermost loops.  */
4309  if (INTVAL (operands[3]) > 1)
4310    FAIL;
4311  emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
4312					   operands[4]));
4313  DONE;
4314})
4315
4316(define_insn "doloop_end_internal"
4317  [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
4318			       (const_int 0))
4319		(label_ref (match_operand 1 "" ""))
4320		(pc)))
4321   (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
4322			 (plus:DI (match_dup 0) (const_int -1))
4323			 (match_dup 0)))]
4324  ""
4325  "br.cloop.sptk.few %l1"
4326  [(set_attr "itanium_class" "br")
4327   (set_attr "predicable" "no")])
4328
4329;; ::::::::::::::::::::
4330;; ::
4331;; :: Set flag operations
4332;; ::
4333;; ::::::::::::::::::::
4334
4335(define_expand "seq"
4336  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4337  ""
4338  "operands[1] = ia64_expand_compare (EQ, DImode);")
4339
4340(define_expand "sne"
4341  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4342  ""
4343  "operands[1] = ia64_expand_compare (NE, DImode);")
4344
4345(define_expand "slt"
4346  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4347  ""
4348  "operands[1] = ia64_expand_compare (LT, DImode);")
4349
4350(define_expand "sle"
4351  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4352  ""
4353  "operands[1] = ia64_expand_compare (LE, DImode);")
4354
4355(define_expand "sgt"
4356  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4357  ""
4358  "operands[1] = ia64_expand_compare (GT, DImode);")
4359
4360(define_expand "sge"
4361  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4362  ""
4363  "operands[1] = ia64_expand_compare (GE, DImode);")
4364
4365(define_expand "sltu"
4366  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4367  ""
4368  "operands[1] = ia64_expand_compare (LTU, DImode);")
4369
4370(define_expand "sleu"
4371  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4372  ""
4373  "operands[1] = ia64_expand_compare (LEU, DImode);")
4374
4375(define_expand "sgtu"
4376  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4377  ""
4378  "operands[1] = ia64_expand_compare (GTU, DImode);")
4379
4380(define_expand "sgeu"
4381  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4382  ""
4383  "operands[1] = ia64_expand_compare (GEU, DImode);")
4384
4385(define_expand "sunordered"
4386  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4387  ""
4388  "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
4389
4390(define_expand "sordered"
4391  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4392  ""
4393  "operands[1] = ia64_expand_compare (ORDERED, DImode);")
4394
4395;; Don't allow memory as destination here, because cmov/cmov/st is more
4396;; efficient than mov/mov/cst/cst.
4397
4398(define_insn_and_split "*sne_internal"
4399  [(set (match_operand:DI 0 "gr_register_operand" "=r")
4400	(ne:DI (match_operand:BI 1 "register_operand" "c")
4401	       (const_int 0)))]
4402  ""
4403  "#"
4404  "reload_completed"
4405  [(cond_exec (ne (match_dup 1) (const_int 0))
4406     (set (match_dup 0) (const_int 1)))
4407   (cond_exec (eq (match_dup 1) (const_int 0))
4408     (set (match_dup 0) (const_int 0)))]
4409  ""
4410  [(set_attr "itanium_class" "unknown")])
4411
4412(define_insn_and_split "*seq_internal"
4413  [(set (match_operand:DI 0 "gr_register_operand" "=r")
4414	(eq:DI (match_operand:BI 1 "register_operand" "c")
4415	       (const_int 0)))]
4416  ""
4417  "#"
4418  "reload_completed"
4419  [(cond_exec (ne (match_dup 1) (const_int 0))
4420     (set (match_dup 0) (const_int 0)))
4421   (cond_exec (eq (match_dup 1) (const_int 0))
4422     (set (match_dup 0) (const_int 1)))]
4423  ""
4424  [(set_attr "itanium_class" "unknown")])
4425
4426;; ::::::::::::::::::::
4427;; ::
4428;; :: Conditional move instructions.
4429;; ::
4430;; ::::::::::::::::::::
4431
4432;; ??? Add movXXcc patterns?
4433
4434;;
4435;; DImode if_then_else patterns.
4436;;
4437
4438(define_insn "*cmovdi_internal"
4439  [(set (match_operand:DI 0 "destination_operand"
4440	   "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
4441	(if_then_else:DI
4442	  (match_operator 4 "predicate_operator"
4443	    [(match_operand:BI 1 "register_operand"
4444		"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
4445	     (const_int 0)])
4446	  (match_operand:DI 2 "move_operand"
4447	   "rnm, *f, *b,*d*e,rnm,rnm, rnm,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
4448	  (match_operand:DI 3 "move_operand"
4449	   "rnm,rnm,rnm, rnm, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
4450  "ia64_move_ok (operands[0], operands[2])
4451   && ia64_move_ok (operands[0], operands[3])"
4452  { abort (); }
4453  [(set_attr "predicable" "no")])
4454
4455(define_split
4456  [(set (match_operand 0 "destination_operand" "")
4457	(if_then_else
4458	  (match_operator 4 "predicate_operator"
4459	    [(match_operand:BI 1 "register_operand" "")
4460	     (const_int 0)])
4461	  (match_operand 2 "move_operand" "")
4462	  (match_operand 3 "move_operand" "")))]
4463  "reload_completed"
4464  [(const_int 0)]
4465{
4466  rtx tmp;
4467  int emitted_something;
4468
4469  emitted_something = 0;
4470  if (! rtx_equal_p (operands[0], operands[2]))
4471    {
4472      tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
4473      tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
4474      emit_insn (tmp);
4475      emitted_something = 1;
4476    }
4477  if (! rtx_equal_p (operands[0], operands[3]))
4478    {
4479      tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4480			    VOIDmode, operands[1], const0_rtx);
4481      tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
4482			       gen_rtx_SET (VOIDmode, operands[0],
4483					    operands[3]));
4484      emit_insn (tmp);
4485      emitted_something = 1;
4486    }
4487  if (! emitted_something)
4488    emit_note (NULL, NOTE_INSN_DELETED);
4489  DONE;
4490})
4491
4492;; Absolute value pattern.
4493
4494(define_insn "*absdi2_internal"
4495  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4496	(if_then_else:DI
4497	  (match_operator 4 "predicate_operator"
4498	    [(match_operand:BI 1 "register_operand" "c,c")
4499	     (const_int 0)])
4500	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
4501	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
4502  ""
4503  "#"
4504  [(set_attr "itanium_class" "ialu,unknown")
4505   (set_attr "predicable" "no")])
4506
4507(define_split
4508  [(set (match_operand:DI 0 "register_operand" "")
4509	(if_then_else:DI
4510	  (match_operator 4 "predicate_operator"
4511	    [(match_operand:BI 1 "register_operand" "c,c")
4512	     (const_int 0)])
4513	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4514	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4515  "reload_completed && rtx_equal_p (operands[0], operands[3])"
4516  [(cond_exec
4517     (match_dup 4)
4518     (set (match_dup 0)
4519	  (neg:DI (match_dup 2))))]
4520  "")
4521
4522(define_split
4523  [(set (match_operand:DI 0 "register_operand" "")
4524	(if_then_else:DI
4525	  (match_operator 4 "predicate_operator"
4526	    [(match_operand:BI 1 "register_operand" "c,c")
4527	     (const_int 0)])
4528	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4529	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4530  "reload_completed"
4531  [(cond_exec
4532     (match_dup 4)
4533     (set (match_dup 0) (neg:DI (match_dup 2))))
4534   (cond_exec
4535     (match_dup 5)
4536     (set (match_dup 0) (match_dup 3)))]
4537{
4538  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4539				VOIDmode, operands[1], const0_rtx);
4540})
4541
4542;;
4543;; SImode if_then_else patterns.
4544;;
4545
4546(define_insn "*cmovsi_internal"
4547  [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
4548	(if_then_else:SI
4549	  (match_operator 4 "predicate_operator"
4550	    [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
4551	     (const_int 0)])
4552	  (match_operand:SI 2 "move_operand"
4553		    "0,0,0,rnm*f,rO,rO,rnm*f,rO,rO")
4554	  (match_operand:SI 3 "move_operand"
4555		    "rnm*f,rO,rO,0,0,0,rnm*f,rO,rO")))]
4556  "ia64_move_ok (operands[0], operands[2])
4557   && ia64_move_ok (operands[0], operands[3])"
4558  { abort (); }
4559  [(set_attr "predicable" "no")])
4560
4561(define_insn "*abssi2_internal"
4562  [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
4563	(if_then_else:SI
4564	  (match_operator 4 "predicate_operator"
4565	    [(match_operand:BI 1 "register_operand" "c,c")
4566	     (const_int 0)])
4567	  (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
4568	  (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
4569  ""
4570  "#"
4571  [(set_attr "itanium_class" "ialu,unknown")
4572   (set_attr "predicable" "no")])
4573
4574(define_split
4575  [(set (match_operand:SI 0 "register_operand" "")
4576	(if_then_else:SI
4577	  (match_operator 4 "predicate_operator"
4578	    [(match_operand:BI 1 "register_operand" "c,c")
4579	     (const_int 0)])
4580	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4581	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4582  "reload_completed && rtx_equal_p (operands[0], operands[3])"
4583  [(cond_exec
4584     (match_dup 4)
4585     (set (match_dup 0)
4586	  (neg:SI (match_dup 2))))]
4587  "")
4588
4589(define_split
4590  [(set (match_operand:SI 0 "register_operand" "")
4591	(if_then_else:SI
4592	  (match_operator 4 "predicate_operator"
4593	    [(match_operand:BI 1 "register_operand" "c,c")
4594	     (const_int 0)])
4595	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4596	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4597  "reload_completed"
4598  [(cond_exec
4599     (match_dup 4)
4600     (set (match_dup 0) (neg:SI (match_dup 2))))
4601   (cond_exec
4602     (match_dup 5)
4603     (set (match_dup 0) (match_dup 3)))]
4604{
4605  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4606				VOIDmode, operands[1], const0_rtx);
4607})
4608
4609(define_insn_and_split "*cond_opsi2_internal"
4610  [(set (match_operand:SI 0 "gr_register_operand" "=r")
4611	(match_operator:SI 5 "condop_operator"
4612	  [(if_then_else:SI
4613	     (match_operator 6 "predicate_operator"
4614	       [(match_operand:BI 1 "register_operand" "c")
4615	        (const_int 0)])
4616	     (match_operand:SI 2 "gr_register_operand" "r")
4617	     (match_operand:SI 3 "gr_register_operand" "r"))
4618	   (match_operand:SI 4 "gr_register_operand" "r")]))]
4619  ""
4620  "#"
4621  "reload_completed"
4622  [(cond_exec
4623     (match_dup 6)
4624     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
4625   (cond_exec
4626     (match_dup 7)
4627     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
4628{
4629  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
4630				VOIDmode, operands[1], const0_rtx);
4631}
4632  [(set_attr "itanium_class" "ialu")
4633   (set_attr "predicable" "no")])
4634
4635
4636(define_insn_and_split "*cond_opsi2_internal_b"
4637  [(set (match_operand:SI 0 "gr_register_operand" "=r")
4638	(match_operator:SI 5 "condop_operator"
4639	  [(match_operand:SI 4 "gr_register_operand" "r")
4640	   (if_then_else:SI
4641	     (match_operator 6 "predicate_operator"
4642	       [(match_operand:BI 1 "register_operand" "c")
4643	        (const_int 0)])
4644	     (match_operand:SI 2 "gr_register_operand" "r")
4645	     (match_operand:SI 3 "gr_register_operand" "r"))]))]
4646  ""
4647  "#"
4648  "reload_completed"
4649  [(cond_exec
4650     (match_dup 6)
4651     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
4652   (cond_exec
4653     (match_dup 7)
4654     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
4655{
4656  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
4657				VOIDmode, operands[1], const0_rtx);
4658}
4659  [(set_attr "itanium_class" "ialu")
4660   (set_attr "predicable" "no")])
4661
4662
4663;; ::::::::::::::::::::
4664;; ::
4665;; :: Call and branch instructions
4666;; ::
4667;; ::::::::::::::::::::
4668
4669;; Subroutine call instruction returning no value.  Operand 0 is the function
4670;; to call; operand 1 is the number of bytes of arguments pushed (in mode
4671;; `SImode', except it is normally a `const_int'); operand 2 is the number of
4672;; registers used as operands.
4673
4674;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
4675;; is supplied for the sake of some RISC machines which need to put this
4676;; information into the assembler code; they can put it in the RTL instead of
4677;; operand 1.
4678
4679(define_expand "call"
4680  [(use (match_operand:DI 0 "" ""))
4681   (use (match_operand 1 "" ""))
4682   (use (match_operand 2 "" ""))
4683   (use (match_operand 3 "" ""))]
4684  ""
4685{
4686  ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
4687  DONE;
4688})
4689
4690(define_expand "sibcall"
4691  [(use (match_operand:DI 0 "" ""))
4692   (use (match_operand 1 "" ""))
4693   (use (match_operand 2 "" ""))
4694   (use (match_operand 3 "" ""))]
4695  ""
4696{
4697  ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
4698  DONE;
4699})
4700
4701;; Subroutine call instruction returning a value.  Operand 0 is the hard
4702;; register in which the value is returned.  There are three more operands,
4703;; the same as the three operands of the `call' instruction (but with numbers
4704;; increased by one).
4705;;
4706;; Subroutines that return `BLKmode' objects use the `call' insn.
4707
4708(define_expand "call_value"
4709  [(use (match_operand 0 "" ""))
4710   (use (match_operand:DI 1 "" ""))
4711   (use (match_operand 2 "" ""))
4712   (use (match_operand 3 "" ""))
4713   (use (match_operand 4 "" ""))]
4714  ""
4715{
4716  ia64_expand_call (operands[0], operands[1], operands[3], false);
4717  DONE;
4718})
4719
4720(define_expand "sibcall_value"
4721  [(use (match_operand 0 "" ""))
4722   (use (match_operand:DI 1 "" ""))
4723   (use (match_operand 2 "" ""))
4724   (use (match_operand 3 "" ""))
4725   (use (match_operand 4 "" ""))]
4726  ""
4727{
4728  ia64_expand_call (operands[0], operands[1], operands[3], true);
4729  DONE;
4730})
4731
4732;; Call subroutine returning any type.
4733
4734(define_expand "untyped_call"
4735  [(parallel [(call (match_operand 0 "" "")
4736		    (const_int 0))
4737	      (match_operand 1 "" "")
4738	      (match_operand 2 "" "")])]
4739  ""
4740{
4741  int i;
4742
4743  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4744
4745  for (i = 0; i < XVECLEN (operands[2], 0); i++)
4746    {
4747      rtx set = XVECEXP (operands[2], 0, i);
4748      emit_move_insn (SET_DEST (set), SET_SRC (set));
4749    }
4750
4751  /* The optimizer does not know that the call sets the function value
4752     registers we stored in the result block.  We avoid problems by
4753     claiming that all hard registers are used and clobbered at this
4754     point.  */
4755  emit_insn (gen_blockage ());
4756
4757  DONE;
4758})
4759
4760(define_insn "call_nogp"
4761  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
4762	 (const_int 0))
4763   (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
4764  ""
4765  "br.call%+.many %1 = %0"
4766  [(set_attr "itanium_class" "br,scall")])
4767
4768(define_insn "call_value_nogp"
4769  [(set (match_operand 0 "" "")
4770	(call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
4771	      (const_int 0)))
4772   (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
4773  ""
4774  "br.call%+.many %2 = %1"
4775  [(set_attr "itanium_class" "br,scall")])
4776
4777(define_insn "sibcall_nogp"
4778  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
4779	 (const_int 0))]
4780  ""
4781  "br%+.many %0"
4782  [(set_attr "itanium_class" "br,scall")])
4783
4784(define_insn "call_gp"
4785  [(call (mem (match_operand 0 "call_operand" "?r,i"))
4786	 (const_int 1))
4787   (clobber (match_operand:DI 1 "register_operand" "=b,b"))
4788   (clobber (match_scratch:DI 2 "=&r,X"))
4789   (clobber (match_scratch:DI 3 "=b,X"))]
4790  ""
4791  "#"
4792  [(set_attr "itanium_class" "br,scall")])
4793
4794;; Irritatingly, we don't have access to INSN within the split body.
4795;; See commentary in ia64_split_call as to why these aren't peep2.
4796(define_split
4797  [(call (mem (match_operand 0 "call_operand" ""))
4798	 (const_int 1))
4799   (clobber (match_operand:DI 1 "register_operand" ""))
4800   (clobber (match_scratch:DI 2 ""))
4801   (clobber (match_scratch:DI 3 ""))]
4802  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4803  [(const_int 0)]
4804{
4805  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4806		   operands[3], true, false);
4807  DONE;
4808})
4809
4810(define_split
4811  [(call (mem (match_operand 0 "call_operand" ""))
4812	 (const_int 1))
4813   (clobber (match_operand:DI 1 "register_operand" ""))
4814   (clobber (match_scratch:DI 2 ""))
4815   (clobber (match_scratch:DI 3 ""))]
4816  "reload_completed"
4817  [(const_int 0)]
4818{
4819  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4820		   operands[3], false, false);
4821  DONE;
4822})
4823
4824(define_insn "call_value_gp"
4825  [(set (match_operand 0 "" "")
4826	(call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
4827	      (const_int 1)))
4828   (clobber (match_operand:DI 2 "register_operand" "=b,b"))
4829   (clobber (match_scratch:DI 3 "=&r,X"))
4830   (clobber (match_scratch:DI 4 "=b,X"))]
4831  ""
4832  "#"
4833  [(set_attr "itanium_class" "br,scall")])
4834
4835(define_split
4836  [(set (match_operand 0 "" "")
4837	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
4838	      (const_int 1)))
4839   (clobber (match_operand:DI 2 "register_operand" ""))
4840   (clobber (match_scratch:DI 3 ""))
4841   (clobber (match_scratch:DI 4 ""))]
4842  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4843  [(const_int 0)]
4844{
4845  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4846		   operands[4], true, false);
4847  DONE;
4848})
4849
4850(define_split
4851  [(set (match_operand 0 "" "")
4852	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
4853	      (const_int 1)))
4854   (clobber (match_operand:DI 2 "register_operand" ""))
4855   (clobber (match_scratch:DI 3 ""))
4856   (clobber (match_scratch:DI 4 ""))]
4857  "reload_completed"
4858  [(const_int 0)]
4859{
4860  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4861		   operands[4], false, false);
4862  DONE;
4863})
4864
4865(define_insn_and_split "sibcall_gp"
4866  [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
4867	 (const_int 1))
4868   (clobber (match_scratch:DI 1 "=&r,X"))
4869   (clobber (match_scratch:DI 2 "=b,X"))]
4870  ""
4871  "#"
4872  "reload_completed"
4873  [(const_int 0)]
4874{
4875  ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
4876		   operands[2], true, true);
4877  DONE;
4878}
4879  [(set_attr "itanium_class" "br")])
4880
4881(define_insn "return_internal"
4882  [(return)
4883   (use (match_operand:DI 0 "register_operand" "b"))]
4884  ""
4885  "br.ret.sptk.many %0"
4886  [(set_attr "itanium_class" "br")])
4887
4888(define_insn "return"
4889  [(return)]
4890  "ia64_direct_return ()"
4891  "br.ret.sptk.many rp"
4892  [(set_attr "itanium_class" "br")])
4893
4894(define_insn "*return_true"
4895  [(set (pc)
4896	(if_then_else (match_operator 0 "predicate_operator"
4897			[(match_operand:BI 1 "register_operand" "c")
4898			 (const_int 0)])
4899		      (return)
4900		      (pc)))]
4901  "ia64_direct_return ()"
4902  "(%J0) br.ret%+.many rp"
4903  [(set_attr "itanium_class" "br")
4904   (set_attr "predicable" "no")])
4905
4906(define_insn "*return_false"
4907  [(set (pc)
4908	(if_then_else (match_operator 0 "predicate_operator"
4909			[(match_operand:BI 1 "register_operand" "c")
4910			 (const_int 0)])
4911		      (pc)
4912		      (return)))]
4913  "ia64_direct_return ()"
4914  "(%j0) br.ret%+.many rp"
4915  [(set_attr "itanium_class" "br")
4916   (set_attr "predicable" "no")])
4917
4918(define_insn "jump"
4919  [(set (pc) (label_ref (match_operand 0 "" "")))]
4920  ""
4921  "br %l0"
4922  [(set_attr "itanium_class" "br")])
4923
4924(define_insn "indirect_jump"
4925  [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
4926  ""
4927  "br %0"
4928  [(set_attr "itanium_class" "br")])
4929
4930(define_expand "tablejump"
4931  [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
4932	      (use (label_ref (match_operand 1 "" "")))])]
4933  ""
4934{
4935  rtx op0 = operands[0];
4936  rtx addr;
4937
4938  /* ??? Bother -- do_tablejump is "helpful" and pulls the table
4939     element into a register without bothering to see whether that
4940     is necessary given the operand predicate.  Check for MEM just
4941     in case someone fixes this.  */
4942  if (GET_CODE (op0) == MEM)
4943    addr = XEXP (op0, 0);
4944  else
4945    {
4946      /* Otherwise, cheat and guess that the previous insn in the
4947	 stream was the memory load.  Grab the address from that.
4948	 Note we have to momentarily pop out of the sequence started
4949	 by the insn-emit wrapper in order to grab the last insn.  */
4950      rtx last, set;
4951
4952      end_sequence ();
4953      last = get_last_insn ();
4954      start_sequence ();
4955      set = single_set (last);
4956
4957      if (! rtx_equal_p (SET_DEST (set), op0)
4958	  || GET_CODE (SET_SRC (set)) != MEM)
4959	abort ();
4960      addr = XEXP (SET_SRC (set), 0);
4961      if (rtx_equal_p (addr, op0))
4962	abort ();
4963    }
4964
4965  /* Jump table elements are stored pc-relative.  That is, a displacement
4966     from the entry to the label.  Thus to convert to an absolute address
4967     we add the address of the memory from which the value is loaded.  */
4968  operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
4969				     NULL_RTX, 1, OPTAB_DIRECT);
4970})
4971
4972(define_insn "*tablejump_internal"
4973  [(set (pc) (match_operand:DI 0 "register_operand" "b"))
4974   (use (label_ref (match_operand 1 "" "")))]
4975  ""
4976  "br %0"
4977  [(set_attr "itanium_class" "br")])
4978
4979
4980;; ::::::::::::::::::::
4981;; ::
4982;; :: Prologue and Epilogue instructions
4983;; ::
4984;; ::::::::::::::::::::
4985
4986(define_expand "prologue"
4987  [(const_int 1)]
4988  ""
4989{
4990  ia64_expand_prologue ();
4991  DONE;
4992})
4993
4994(define_expand "epilogue"
4995  [(return)]
4996  ""
4997{
4998  ia64_expand_epilogue (0);
4999  DONE;
5000})
5001
5002(define_expand "sibcall_epilogue"
5003  [(return)]
5004  ""
5005{
5006  ia64_expand_epilogue (1);
5007  DONE;
5008})
5009
5010;; This prevents the scheduler from moving the SP decrement past FP-relative
5011;; stack accesses.  This is the same as adddi3 plus the extra set.
5012
5013(define_insn "prologue_allocate_stack"
5014  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5015	(plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
5016		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
5017   (set (match_operand:DI 3 "register_operand" "+r,r,r")
5018	(match_dup 3))]
5019  ""
5020  "@
5021   add %0 = %1, %2
5022   adds %0 = %2, %1
5023   addl %0 = %2, %1"
5024  [(set_attr "itanium_class" "ialu")])
5025
5026;; This prevents the scheduler from moving the SP restore past FP-relative
5027;; stack accesses.  This is similar to movdi plus the extra set.
5028
5029(define_insn "epilogue_deallocate_stack"
5030  [(set (match_operand:DI 0 "register_operand" "=r")
5031	(match_operand:DI 1 "register_operand" "+r"))
5032   (set (match_dup 1) (match_dup 1))]
5033  ""
5034  "mov %0 = %1"
5035  [(set_attr "itanium_class" "ialu")])
5036
5037;; As USE insns aren't meaningful after reload, this is used instead
5038;; to prevent deleting instructions setting registers for EH handling
5039(define_insn "prologue_use"
5040  [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
5041	      UNSPEC_PROLOGUE_USE)]
5042  ""
5043  ""
5044  [(set_attr "itanium_class" "ignore")
5045   (set_attr "predicable" "no")])
5046
5047;; Allocate a new register frame.
5048
5049(define_insn "alloc"
5050  [(set (match_operand:DI 0 "register_operand" "=r")
5051	(unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
5052   (use (match_operand:DI 1 "const_int_operand" "i"))
5053   (use (match_operand:DI 2 "const_int_operand" "i"))
5054   (use (match_operand:DI 3 "const_int_operand" "i"))
5055   (use (match_operand:DI 4 "const_int_operand" "i"))]
5056  ""
5057  "alloc %0 = ar.pfs, %1, %2, %3, %4"
5058  [(set_attr "itanium_class" "syst_m0")
5059   (set_attr "predicable" "no")])
5060
5061;; Modifies ar.unat
5062(define_expand "gr_spill"
5063  [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
5064		   (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5065			       (match_operand:DI 2 "const_int_operand" "")]
5066			      UNSPEC_GR_SPILL))
5067	      (clobber (match_dup 3))])]
5068  ""
5069  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5070
5071(define_insn "gr_spill_internal"
5072  [(set (match_operand:DI 0 "memory_operand" "=m")
5073	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5074		    (match_operand:DI 2 "const_int_operand" "")]
5075		   UNSPEC_GR_SPILL))
5076   (clobber (match_operand:DI 3 "register_operand" ""))]
5077  ""
5078{
5079  /* Note that we use a C output pattern here to avoid the predicate
5080     being automatically added before the .mem.offset directive.  */
5081  return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
5082}
5083  [(set_attr "itanium_class" "st")])
5084
5085;; Reads ar.unat
5086(define_expand "gr_restore"
5087  [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5088		   (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5089			       (match_operand:DI 2 "const_int_operand" "")]
5090			      UNSPEC_GR_RESTORE))
5091	      (use (match_dup 3))])]
5092  ""
5093  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5094
5095(define_insn "gr_restore_internal"
5096  [(set (match_operand:DI 0 "register_operand" "=r")
5097	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5098		    (match_operand:DI 2 "const_int_operand" "")]
5099		   UNSPEC_GR_RESTORE))
5100   (use (match_operand:DI 3 "register_operand" ""))]
5101  ""
5102  { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
5103  [(set_attr "itanium_class" "ld")])
5104
5105(define_insn "fr_spill"
5106  [(set (match_operand:TF 0 "memory_operand" "=m")
5107	(unspec:TF [(match_operand:TF 1 "register_operand" "f")]
5108		   UNSPEC_FR_SPILL))]
5109  ""
5110  "stf.spill %0 = %1%P0"
5111  [(set_attr "itanium_class" "stf")])
5112
5113(define_insn "fr_restore"
5114  [(set (match_operand:TF 0 "register_operand" "=f")
5115	(unspec:TF [(match_operand:TF 1 "memory_operand" "m")]
5116		   UNSPEC_FR_RESTORE))]
5117  ""
5118  "ldf.fill %0 = %1%P1"
5119  [(set_attr "itanium_class" "fld")])
5120
5121;; ??? The explicit stop is not ideal.  It would be better if
5122;; rtx_needs_barrier took care of this, but this is something that can be
5123;; fixed later.  This avoids an RSE DV.
5124
5125(define_insn "bsp_value"
5126  [(set (match_operand:DI 0 "register_operand" "=r")
5127	(unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
5128  ""
5129  "*
5130{
5131  return \";;\;%,mov %0 = ar.bsp\";
5132}"
5133  [(set_attr "itanium_class" "frar_i")])
5134
5135(define_insn "set_bsp"
5136  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
5137		    UNSPECV_SET_BSP)]
5138  ""
5139  "flushrs
5140	mov r19=ar.rsc
5141	;;
5142	and r19=0x1c,r19
5143	;;
5144	mov ar.rsc=r19
5145	;;
5146	mov ar.bspstore=%0
5147	;;
5148	or r19=0x3,r19
5149	;;
5150	loadrs
5151	invala
5152	;;
5153	mov ar.rsc=r19"
5154  [(set_attr "itanium_class" "unknown")
5155   (set_attr "predicable" "no")])
5156
5157;; ??? The explicit stops are not ideal.  It would be better if
5158;; rtx_needs_barrier took care of this, but this is something that can be
5159;; fixed later.  This avoids an RSE DV.
5160
5161(define_insn "flushrs"
5162  [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
5163  ""
5164  ";;\;flushrs\;;;"
5165  [(set_attr "itanium_class" "rse_m")
5166   (set_attr "predicable" "no")])
5167
5168;; ::::::::::::::::::::
5169;; ::
5170;; :: Miscellaneous instructions
5171;; ::
5172;; ::::::::::::::::::::
5173
5174;; ??? Emiting a NOP instruction isn't very useful.  This should probably
5175;; be emitting ";;" to force a break in the instruction packing.
5176
5177;; No operation, needed in case the user uses -g but not -O.
5178(define_insn "nop"
5179  [(const_int 0)]
5180  ""
5181  "nop 0"
5182  [(set_attr "itanium_class" "unknown")])
5183
5184(define_insn "nop_m"
5185  [(const_int 1)]
5186  ""
5187  "nop.m 0"
5188  [(set_attr "itanium_class" "nop_m")])
5189
5190(define_insn "nop_i"
5191  [(const_int 2)]
5192  ""
5193  "nop.i 0"
5194  [(set_attr "itanium_class" "nop_i")])
5195
5196(define_insn "nop_f"
5197  [(const_int 3)]
5198  ""
5199  "nop.f 0"
5200  [(set_attr "itanium_class" "nop_f")])
5201
5202(define_insn "nop_b"
5203  [(const_int 4)]
5204  ""
5205  "nop.b 0"
5206  [(set_attr "itanium_class" "nop_b")])
5207
5208(define_insn "nop_x"
5209  [(const_int 5)]
5210  ""
5211  ""
5212  [(set_attr "itanium_class" "nop_x")])
5213
5214(define_insn "bundle_selector"
5215  [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
5216  ""
5217  { return get_bundle_name (INTVAL (operands[0])); }
5218  [(set_attr "itanium_class" "ignore")
5219   (set_attr "predicable" "no")])
5220
5221;; Pseudo instruction that prevents the scheduler from moving code above this
5222;; point.
5223(define_insn "blockage"
5224  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
5225  ""
5226  ""
5227  [(set_attr "itanium_class" "ignore")
5228   (set_attr "predicable" "no")])
5229
5230(define_insn "insn_group_barrier"
5231  [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5232		    UNSPECV_INSN_GROUP_BARRIER)]
5233  ""
5234  ";;"
5235  [(set_attr "itanium_class" "stop_bit")
5236   (set_attr "predicable" "no")])
5237
5238(define_expand "trap"
5239  [(trap_if (const_int 1) (const_int 0))]
5240  ""
5241  "")
5242
5243;; ??? We don't have a match-any slot type.  Setting the type to unknown
5244;; produces worse code that setting the slot type to A.
5245
5246(define_insn "*trap"
5247  [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
5248  ""
5249  "break %0"
5250  [(set_attr "itanium_class" "chk_s")])
5251
5252(define_expand "conditional_trap"
5253  [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
5254  ""
5255{
5256  operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
5257})
5258
5259(define_insn "*conditional_trap"
5260  [(trap_if (match_operator 0 "predicate_operator"
5261	      [(match_operand:BI 1 "register_operand" "c")
5262	       (const_int 0)])  
5263	    (match_operand 2 "const_int_operand" ""))]
5264  ""
5265  "(%J0) break %2"
5266  [(set_attr "itanium_class" "chk_s")
5267   (set_attr "predicable" "no")])
5268
5269(define_insn "break_f"
5270  [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
5271  ""
5272  "break.f 0"
5273  [(set_attr "itanium_class" "nop_f")])
5274
5275(define_insn "prefetch"
5276  [(prefetch (match_operand:DI 0 "address_operand" "p")
5277	     (match_operand:DI 1 "const_int_operand" "n")
5278	     (match_operand:DI 2 "const_int_operand" "n"))]
5279  ""
5280{
5281  static const char * const alt[2][4] = {
5282    {
5283      "%,lfetch.nta [%0]",
5284      "%,lfetch.nt1 [%0]",
5285      "%,lfetch.nt2 [%0]",
5286      "%,lfetch [%0]"
5287    },
5288    {
5289      "%,lfetch.excl.nta [%0]",
5290      "%,lfetch.excl.nt1 [%0]",
5291      "%,lfetch.excl.nt2 [%0]",
5292      "%,lfetch.excl [%0]"
5293    }
5294  };
5295  int i = (INTVAL (operands[1]));
5296  int j = (INTVAL (operands[2]));
5297
5298  if (i != 0 && i != 1)
5299    abort ();
5300  if (j < 0 || j > 3)
5301    abort ();
5302  return alt[i][j];
5303}
5304  [(set_attr "itanium_class" "lfetch")])
5305
5306;; Non-local goto support.
5307
5308(define_expand "save_stack_nonlocal"
5309  [(use (match_operand:OI 0 "memory_operand" ""))
5310   (use (match_operand:DI 1 "register_operand" ""))]
5311  ""
5312{
5313  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5314					 \"__ia64_save_stack_nonlocal\"),
5315		     0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
5316		     operands[1], Pmode);
5317  DONE;
5318})
5319
5320(define_expand "nonlocal_goto"
5321  [(use (match_operand 0 "general_operand" ""))
5322   (use (match_operand 1 "general_operand" ""))
5323   (use (match_operand 2 "general_operand" ""))
5324   (use (match_operand 3 "general_operand" ""))]
5325  ""
5326{
5327  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
5328		     LCT_NORETURN, VOIDmode, 3,
5329		     operands[1], Pmode,
5330		     copy_to_reg (XEXP (operands[2], 0)), Pmode,
5331		     operands[3], Pmode);
5332  emit_barrier ();
5333  DONE;
5334})
5335
5336(define_insn_and_split "builtin_setjmp_receiver"
5337  [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
5338  ""
5339  "#"
5340  "reload_completed"
5341  [(const_int 0)]
5342{
5343  ia64_reload_gp ();
5344  DONE;
5345})
5346
5347(define_expand "eh_epilogue"
5348  [(use (match_operand:DI 0 "register_operand" "r"))
5349   (use (match_operand:DI 1 "register_operand" "r"))
5350   (use (match_operand:DI 2 "register_operand" "r"))]
5351  ""
5352{
5353  rtx bsp = gen_rtx_REG (Pmode, 10);
5354  rtx sp = gen_rtx_REG (Pmode, 9);
5355
5356  if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
5357    {
5358      emit_move_insn (bsp, operands[0]);
5359      operands[0] = bsp;
5360    }
5361  if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
5362    {
5363      emit_move_insn (sp, operands[2]);
5364      operands[2] = sp;
5365    }
5366  emit_insn (gen_rtx_USE (VOIDmode, sp));
5367  emit_insn (gen_rtx_USE (VOIDmode, bsp));
5368
5369  cfun->machine->ia64_eh_epilogue_sp = sp;
5370  cfun->machine->ia64_eh_epilogue_bsp = bsp;
5371})
5372
5373;; Builtin apply support.
5374
5375(define_expand "restore_stack_nonlocal"
5376  [(use (match_operand:DI 0 "register_operand" ""))
5377   (use (match_operand:OI 1 "memory_operand" ""))]
5378  ""
5379{
5380  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5381					 "__ia64_restore_stack_nonlocal"),
5382		     0, VOIDmode, 1,
5383		     copy_to_reg (XEXP (operands[1], 0)), Pmode);
5384  DONE;
5385})
5386
5387
5388;;; Intrinsics support.
5389
5390(define_expand "mf"
5391  [(set (mem:BLK (match_dup 0))
5392	(unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
5393  ""
5394{
5395  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
5396  MEM_VOLATILE_P (operands[0]) = 1;
5397})
5398
5399(define_insn "*mf_internal"
5400  [(set (match_operand:BLK 0 "" "")
5401	(unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
5402  ""
5403  "mf"
5404  [(set_attr "itanium_class" "syst_m")])
5405
5406(define_insn "fetchadd_acq_si"
5407  [(set (match_operand:SI 0 "gr_register_operand" "=r")
5408	(match_dup 1))
5409   (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5410	(unspec:SI [(match_dup 1)
5411		    (match_operand:SI 2 "fetchadd_operand" "n")]
5412		   UNSPEC_FETCHADD_ACQ))]
5413  ""
5414  "fetchadd4.acq %0 = %1, %2"
5415  [(set_attr "itanium_class" "sem")])
5416
5417(define_insn "fetchadd_acq_di"
5418  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5419	(match_dup 1))
5420   (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5421	(unspec:DI [(match_dup 1)
5422		    (match_operand:DI 2 "fetchadd_operand" "n")]
5423		   UNSPEC_FETCHADD_ACQ))]
5424  ""
5425  "fetchadd8.acq %0 = %1, %2"
5426  [(set_attr "itanium_class" "sem")])
5427
5428(define_insn "cmpxchg_acq_si"
5429  [(set (match_operand:SI 0 "gr_register_operand" "=r")
5430	(match_dup 1))
5431   (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5432        (unspec:SI [(match_dup 1)
5433                    (match_operand:SI 2 "gr_register_operand" "r")
5434		    (match_operand 3 "ar_ccv_reg_operand" "")]
5435		   UNSPEC_CMPXCHG_ACQ))]
5436  ""
5437  "cmpxchg4.acq %0 = %1, %2, %3"
5438  [(set_attr "itanium_class" "sem")])
5439
5440(define_insn "cmpxchg_acq_di"
5441  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5442	(match_dup 1))
5443   (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5444        (unspec:DI [(match_dup 1)
5445                    (match_operand:DI 2 "gr_register_operand" "r")
5446		    (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5447		   UNSPEC_CMPXCHG_ACQ))]
5448  ""
5449  "cmpxchg8.acq %0 = %1, %2, %3"
5450  [(set_attr "itanium_class" "sem")])
5451
5452(define_insn "xchgsi"
5453  [(set (match_operand:SI 0 "gr_register_operand" "=r")
5454        (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5455   (set (match_dup 1)
5456        (match_operand:SI 2 "gr_register_operand" "r"))]
5457  ""
5458  "xchg4 %0 = %1, %2"
5459  [(set_attr "itanium_class" "sem")])
5460
5461(define_insn "xchgdi"
5462  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5463        (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5464   (set (match_dup 1)
5465        (match_operand:DI 2 "gr_register_operand" "r"))]
5466  ""
5467  "xchg8 %0 = %1, %2"
5468  [(set_attr "itanium_class" "sem")])
5469
5470;; Predication.
5471
5472(define_cond_exec
5473  [(match_operator 0 "predicate_operator"
5474     [(match_operand:BI 1 "register_operand" "c")
5475      (const_int 0)])]
5476  ""
5477  "(%J0)")
5478
5479(define_insn "pred_rel_mutex"
5480  [(set (match_operand:BI 0 "register_operand" "+c")
5481       (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
5482  ""
5483  ".pred.rel.mutex %0, %I0"
5484  [(set_attr "itanium_class" "ignore")
5485   (set_attr "predicable" "no")])
5486
5487(define_insn "safe_across_calls_all"
5488  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
5489  ""
5490  ".pred.safe_across_calls p1-p63"
5491  [(set_attr "itanium_class" "ignore")
5492   (set_attr "predicable" "no")])
5493
5494(define_insn "safe_across_calls_normal"
5495  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
5496  ""
5497{
5498  emit_safe_across_calls (asm_out_file);
5499  return "";
5500}
5501  [(set_attr "itanium_class" "ignore")
5502   (set_attr "predicable" "no")])
5503
5504;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
5505;; pointer.  This is used by the HP-UX 32 bit mode.
5506
5507(define_insn "ptr_extend"
5508  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5509        (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
5510		   UNSPEC_ADDP4))]
5511  ""
5512  "addp4 %0 = 0,%1"
5513  [(set_attr "itanium_class" "ialu")])
5514
5515;;
5516;; Optimizations for ptr_extend
5517
5518(define_insn "*ptr_extend_plus_1"
5519  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5520        (unspec:DI
5521         [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
5522                   (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
5523         UNSPEC_ADDP4))]
5524  "addp4_optimize_ok (operands[1], operands[2])"
5525  "addp4 %0 = %2, %1"
5526  [(set_attr "itanium_class" "ialu")])
5527
5528(define_insn "*ptr_extend_plus_2"
5529  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5530        (unspec:DI
5531         [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
5532                   (match_operand:SI 2 "basereg_operand" "r"))]
5533         UNSPEC_ADDP4))]
5534  "addp4_optimize_ok (operands[1], operands[2])"
5535  "addp4 %0 = %1, %2"
5536  [(set_attr "itanium_class" "ialu")])
5537