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