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