OSDN Git Service

* doc/extend.texi (MIPS DSP Built-in Functions): Document the DSP
[pf3gnuchains/gcc-fork.git] / gcc / config / ia64 / ia64.md
1 ;; IA-64 Machine description template
2 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
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 \f
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 \f
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 \f
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 constrained 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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 "bswapdi2"
2494   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2495         (bswap:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2496   ""
2497   "mux1 %0 = %1, @rev"
2498   [(set_attr "itanium_class" "mmshf")])
2499
2500 (define_insn "*getf_exp_xf"
2501   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2502         (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
2503                    UNSPEC_GETF_EXP))]
2504   ""
2505   "getf.exp %0 = %1"
2506   [(set_attr "itanium_class" "frfr")])
2507
2508 (define_expand "divdi3"
2509   [(set (match_operand:DI 0 "register_operand" "")
2510         (div:DI (match_operand:DI 1 "general_operand" "")
2511                 (match_operand:DI 2 "general_operand" "")))]
2512   "TARGET_INLINE_INT_DIV"
2513 {
2514   rtx op1_xf, op2_xf, op0_xf;
2515
2516   op0_xf = gen_reg_rtx (XFmode);
2517
2518   if (CONSTANT_P (operands[1]))
2519     operands[1] = force_reg (DImode, operands[1]);
2520   op1_xf = gen_reg_rtx (XFmode);
2521   expand_float (op1_xf, operands[1], 0);
2522
2523   if (CONSTANT_P (operands[2]))
2524     operands[2] = force_reg (DImode, operands[2]);
2525   op2_xf = gen_reg_rtx (XFmode);
2526   expand_float (op2_xf, operands[2], 0);
2527
2528   emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
2529                             CONST1_RTX (DImode)));
2530
2531   if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
2532     emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2533   else
2534     emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2535
2536   emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2537   DONE;
2538 })
2539
2540 (define_expand "moddi3"
2541   [(set (match_operand:DI 0 "register_operand" "")
2542         (mod:SI (match_operand:DI 1 "general_operand" "")
2543                 (match_operand:DI 2 "general_operand" "")))]
2544   "TARGET_INLINE_INT_DIV"
2545 {
2546   rtx op2_neg, div;
2547
2548   div = gen_reg_rtx (DImode);
2549   emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2550
2551   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2552
2553   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2554   DONE;
2555 })
2556
2557 (define_expand "udivdi3"
2558   [(set (match_operand:DI 0 "register_operand" "")
2559         (udiv:DI (match_operand:DI 1 "general_operand" "")
2560                  (match_operand:DI 2 "general_operand" "")))]
2561   "TARGET_INLINE_INT_DIV"
2562 {
2563   rtx op1_xf, op2_xf, op0_xf;
2564
2565   op0_xf = gen_reg_rtx (XFmode);
2566
2567   if (CONSTANT_P (operands[1]))
2568     operands[1] = force_reg (DImode, operands[1]);
2569   op1_xf = gen_reg_rtx (XFmode);
2570   expand_float (op1_xf, operands[1], 1);
2571
2572   if (CONSTANT_P (operands[2]))
2573     operands[2] = force_reg (DImode, operands[2]);
2574   op2_xf = gen_reg_rtx (XFmode);
2575   expand_float (op2_xf, operands[2], 1);
2576
2577   emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
2578                             CONST1_RTX (DImode)));
2579
2580   if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
2581     emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2582   else
2583     emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2584
2585   emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2586   DONE;
2587 })
2588
2589 (define_expand "umoddi3"
2590   [(set (match_operand:DI 0 "register_operand" "")
2591         (umod:DI (match_operand:DI 1 "general_operand" "")
2592                  (match_operand:DI 2 "general_operand" "")))]
2593   "TARGET_INLINE_INT_DIV"
2594 {
2595   rtx op2_neg, div;
2596
2597   div = gen_reg_rtx (DImode);
2598   emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2599
2600   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2601
2602   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2603   DONE;
2604 })
2605
2606 (define_insn_and_split "divdi3_internal_lat"
2607   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2608         (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2609                           (match_operand:XF 2 "fr_register_operand" "f"))))
2610    (clobber (match_scratch:XF 3 "=&f"))
2611    (clobber (match_scratch:XF 4 "=&f"))
2612    (clobber (match_scratch:XF 5 "=&f"))
2613    (clobber (match_scratch:BI 6 "=c"))]
2614   "TARGET_INLINE_INT_DIV == INL_MIN_LAT"
2615   "#"
2616   "&& reload_completed"
2617   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2618               (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2619                                             UNSPEC_FR_RECIP_APPROX))
2620               (use (const_int 1))])
2621    (cond_exec (ne (match_dup 6) (const_int 0))
2622      (parallel [(set (match_dup 3)
2623                      (minus:XF (match_dup 7)
2624                                (mult:XF (match_dup 2) (match_dup 0))))
2625                 (use (const_int 1))]))
2626    (cond_exec (ne (match_dup 6) (const_int 0))
2627      (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
2628                 (use (const_int 1))]))
2629    (cond_exec (ne (match_dup 6) (const_int 0))
2630      (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
2631                 (use (const_int 1))]))
2632    (cond_exec (ne (match_dup 6) (const_int 0))
2633      (parallel [(set (match_dup 4)
2634                      (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2635                               (match_dup 4)))
2636                 (use (const_int 1))]))
2637    (cond_exec (ne (match_dup 6) (const_int 0))
2638      (parallel [(set (match_dup 0)
2639                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2640                               (match_dup 0)))
2641                 (use (const_int 1))]))
2642    (cond_exec (ne (match_dup 6) (const_int 0))
2643      (parallel [(set (match_dup 3)
2644                      (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2645                               (match_dup 4)))
2646                 (use (const_int 1))]))
2647    (cond_exec (ne (match_dup 6) (const_int 0))
2648      (parallel [(set (match_dup 0)
2649                      (plus:XF (mult:XF (match_dup 5) (match_dup 0))
2650                               (match_dup 0)))
2651                 (use (const_int 1))]))
2652    (cond_exec (ne (match_dup 6) (const_int 0))
2653      (parallel [(set (match_dup 4)
2654                      (minus:XF (match_dup 1)
2655                                (mult:XF (match_dup 2) (match_dup 3))))
2656                 (use (const_int 1))]))
2657    (cond_exec (ne (match_dup 6) (const_int 0))
2658      (parallel [(set (match_dup 0)
2659                      (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2660                               (match_dup 3)))
2661                 (use (const_int 1))]))
2662   ] 
2663   "operands[7] = CONST1_RTX (XFmode);"
2664   [(set_attr "predicable" "no")])
2665
2666 (define_insn_and_split "divdi3_internal_thr"
2667   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2668         (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2669                           (match_operand:XF 2 "fr_register_operand" "f"))))
2670    (clobber (match_scratch:XF 3 "=&f"))
2671    (clobber (match_scratch:XF 4 "=f"))
2672    (clobber (match_scratch:BI 5 "=c"))]
2673   "TARGET_INLINE_INT_DIV == INL_MAX_THR"
2674   "#"
2675   "&& reload_completed"
2676   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2677               (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 
2678                                             UNSPEC_FR_RECIP_APPROX))
2679               (use (const_int 1))])
2680    (cond_exec (ne (match_dup 5) (const_int 0))
2681      (parallel [(set (match_dup 3)
2682                      (minus:XF (match_dup 6)
2683                                (mult:XF (match_dup 2) (match_dup 0))))
2684                 (use (const_int 1))]))
2685    (cond_exec (ne (match_dup 5) (const_int 0))
2686      (parallel [(set (match_dup 0)
2687                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2688                               (match_dup 0)))
2689                 (use (const_int 1))]))
2690    (cond_exec (ne (match_dup 5) (const_int 0))
2691      (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
2692                 (use (const_int 1))]))
2693    (cond_exec (ne (match_dup 5) (const_int 0))
2694      (parallel [(set (match_dup 0)
2695                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2696                               (match_dup 0)))
2697                 (use (const_int 1))]))
2698    (cond_exec (ne (match_dup 5) (const_int 0))
2699      (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
2700                 (use (const_int 1))]))
2701    (cond_exec (ne (match_dup 5) (const_int 0))
2702      (parallel [(set (match_dup 4)
2703                      (minus:XF (match_dup 1)
2704                                (mult:XF (match_dup 2) (match_dup 3))))
2705                 (use (const_int 1))]))
2706    (cond_exec (ne (match_dup 5) (const_int 0))
2707      (parallel [(set (match_dup 0)
2708                      (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2709                               (match_dup 3)))
2710                 (use (const_int 1))]))
2711   ] 
2712   "operands[6] = CONST1_RTX (XFmode);"
2713   [(set_attr "predicable" "no")])
2714 \f
2715 ;; ::::::::::::::::::::
2716 ;; ::
2717 ;; :: 128-bit Integer arithmetic
2718 ;; ::
2719 ;; ::::::::::::::::::::
2720
2721 (define_insn "addti3"
2722   [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2723         (plus:TI (match_operand:TI 1 "gr_register_operand" "%r")
2724                  (match_operand:TI 2 "gr_reg_or_14bit_operand" "rI")))
2725    (clobber (match_scratch:BI 3 "=&c"))]
2726   ""
2727   "#"
2728   [(set_attr "itanium_class" "unknown")])
2729
2730 (define_split
2731   [(set (match_operand:TI 0 "register_operand" "")
2732         (plus:TI (match_operand:TI 1 "register_operand" "")
2733                  (match_operand:TI 2 "register_operand" "")))
2734    (clobber (match_scratch:BI 3 ""))]
2735   "reload_completed"
2736   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
2737    (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
2738    (cond_exec (eq (match_dup 3) (const_int 0))
2739               (set (match_dup 4) (plus:DI (match_dup 5) (match_dup 6))))
2740    (cond_exec (ne (match_dup 3) (const_int 0))
2741               (set (match_dup 4)
2742                    (plus:DI (plus:DI (match_dup 5) (match_dup 6))
2743                             (const_int 1))))]
2744 {
2745   operands[4] = gen_highpart (DImode, operands[0]);
2746   operands[0] = gen_lowpart (DImode, operands[0]);
2747   operands[5] = gen_highpart (DImode, operands[1]);
2748   operands[1] = gen_lowpart (DImode, operands[1]);
2749   operands[6] = gen_highpart (DImode, operands[2]);
2750   operands[2] = gen_lowpart (DImode, operands[2]);
2751 })
2752
2753 (define_split
2754   [(set (match_operand:TI 0 "register_operand" "")
2755         (plus:TI (match_operand:TI 1 "register_operand" "")
2756                  (match_operand:TI 2 "immediate_operand" "")))
2757    (clobber (match_scratch:BI 3 ""))]
2758   "reload_completed"
2759   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
2760    (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
2761    (cond_exec (eq (match_dup 3) (const_int 0))
2762               (set (match_dup 4)
2763                    (plus:DI (match_dup 5) (match_dup 6))))
2764    (cond_exec (ne (match_dup 3) (const_int 0))
2765               (set (match_dup 4)
2766                    (plus:DI (match_dup 5) (match_dup 7))))]
2767 {
2768   operands[4] = gen_highpart (DImode, operands[0]);
2769   operands[0] = gen_lowpart (DImode, operands[0]);
2770   operands[5] = gen_highpart (DImode, operands[1]);
2771   operands[1] = gen_lowpart (DImode, operands[1]);
2772   operands[6] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
2773   operands[7] = INTVAL (operands[2]) < 0 ? const0_rtx : const1_rtx;
2774 })
2775
2776 (define_insn "subti3"
2777   [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2778         (minus:TI (match_operand:TI 1 "gr_reg_or_8bit_operand" "rK")
2779                   (match_operand:TI 2 "gr_register_operand" "r")))
2780    (clobber (match_scratch:BI 3 "=&c"))]
2781   ""
2782   "#"
2783   [(set_attr "itanium_class" "unknown")])
2784
2785 (define_split
2786   [(set (match_operand:TI 0 "register_operand" "")
2787         (minus:TI (match_operand:TI 1 "register_operand" "")
2788                   (match_operand:TI 2 "register_operand" "")))
2789    (clobber (match_scratch:BI 3 "=&c"))]
2790   "reload_completed"
2791   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
2792    (set (match_dup 3) (ltu:BI (match_dup 1) (match_dup 0)))
2793    (cond_exec (eq (match_dup 3) (const_int 0))
2794               (set (match_dup 4) (minus:DI (match_dup 5) (match_dup 6))))
2795    (cond_exec (ne (match_dup 3) (const_int 0))
2796               (set (match_dup 4)
2797                    (plus:DI (not:DI (match_dup 6)) (match_dup 5))))]
2798 {
2799   operands[4] = gen_highpart (DImode, operands[0]);
2800   operands[0] = gen_lowpart (DImode, operands[0]);
2801   operands[5] = gen_highpart (DImode, operands[1]);
2802   operands[1] = gen_lowpart (DImode, operands[1]);
2803   operands[6] = gen_highpart (DImode, operands[2]);
2804   operands[2] = gen_lowpart (DImode, operands[2]);
2805 })
2806
2807 (define_split
2808   [(set (match_operand:TI 0 "register_operand" "")
2809         (minus:TI (match_operand:TI 1 "immediate_operand" "")
2810                   (match_operand:TI 2 "register_operand" "")))
2811    (clobber (match_scratch:BI 3 "=&c"))]
2812   "reload_completed && CONST_OK_FOR_K (INTVAL (operands[1]))"
2813   [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
2814    (set (match_dup 3) (gtu:BI (match_dup 0) (match_dup 1)))
2815    (cond_exec (ne (match_dup 3) (const_int 0))
2816               (set (match_dup 4) (minus:DI (match_dup 6) (match_dup 5))))
2817    (cond_exec (eq (match_dup 3) (const_int 0))
2818               (set (match_dup 4) (minus:DI (match_dup 7) (match_dup 5))))]
2819 {
2820   operands[4] = gen_highpart (DImode, operands[0]);
2821   operands[0] = gen_lowpart (DImode, operands[0]);
2822   operands[5] = gen_highpart (DImode, operands[2]);
2823   operands[2] = gen_lowpart (DImode, operands[2]);
2824   operands[6] = INTVAL (operands[1]) < 0 ? GEN_INT (-2) : constm1_rtx;
2825   operands[7] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
2826 })
2827
2828 (define_expand "mulditi3"
2829   [(set (match_operand:TI 0 "fr_register_operand" "")
2830         (mult:TI (sign_extend:TI
2831                    (match_operand:DI 1 "fr_register_operand" ""))
2832                  (sign_extend:TI
2833                    (match_operand:DI 2 "fr_register_operand" ""))))]
2834   ""
2835   "")
2836
2837 (define_insn_and_split "*mulditi3_internal"
2838   [(set (match_operand:TI 0 "fr_register_operand" "=&f")
2839         (mult:TI (sign_extend:TI
2840                    (match_operand:DI 1 "fr_register_operand" "%f"))
2841                  (sign_extend:TI
2842                    (match_operand:DI 2 "fr_register_operand" "f"))))]
2843   ""
2844   "#"
2845   "reload_completed"
2846   [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
2847    (set (match_dup 3) (truncate:DI
2848                         (lshiftrt:TI
2849                           (mult:TI (sign_extend:TI (match_dup 1))
2850                                    (sign_extend:TI (match_dup 2)))
2851                           (const_int 64))))]
2852 {
2853   operands[3] = gen_highpart (DImode, operands[0]);
2854   operands[0] = gen_lowpart (DImode, operands[0]);
2855 }
2856   [(set_attr "itanium_class" "unknown")])
2857
2858 (define_expand "umulditi3"
2859   [(set (match_operand:TI 0 "fr_register_operand" "")
2860         (mult:TI (zero_extend:TI
2861                    (match_operand:DI 1 "fr_register_operand" ""))
2862                  (zero_extend:TI
2863                    (match_operand:DI 2 "fr_register_operand" ""))))]
2864   ""
2865   "")
2866
2867 (define_insn_and_split "*umulditi3_internal"
2868   [(set (match_operand:TI 0 "fr_register_operand" "=&f")
2869         (mult:TI (zero_extend:TI
2870                    (match_operand:DI 1 "fr_register_operand" "%f"))
2871                  (zero_extend:TI
2872                    (match_operand:DI 2 "fr_register_operand" "f"))))]
2873   ""
2874   "#"
2875   "reload_completed"
2876   [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
2877    (set (match_dup 3) (truncate:DI
2878                         (lshiftrt:TI
2879                           (mult:TI (zero_extend:TI (match_dup 1))
2880                                    (zero_extend:TI (match_dup 2)))
2881                           (const_int 64))))]
2882 {
2883   operands[3] = gen_highpart (DImode, operands[0]);
2884   operands[0] = gen_lowpart (DImode, operands[0]);
2885 }
2886   [(set_attr "itanium_class" "unknown")])
2887
2888 (define_insn_and_split "negti2"
2889   [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2890         (neg:TI (match_operand:TI 1 "gr_register_operand" "r")))
2891    (clobber (match_scratch:BI 2 "=&c"))]
2892   ""
2893   "#"
2894   "reload_completed"
2895   [(set (match_dup 2) (eq:BI (match_dup 1) (const_int 0)))
2896    (set (match_dup 0) (minus:DI (const_int 0) (match_dup 1)))
2897    (cond_exec (eq (match_dup 2) (const_int 0))
2898               (set (match_dup 3) (minus:DI (const_int -1) (match_dup 4))))
2899    (cond_exec (ne (match_dup 2) (const_int 0))
2900               (set (match_dup 3) (minus:DI (const_int 0) (match_dup 4))))]
2901 {
2902   operands[3] = gen_highpart (DImode, operands[0]);
2903   operands[0] = gen_lowpart (DImode, operands[0]);
2904   operands[4] = gen_highpart (DImode, operands[1]);
2905   operands[1] = gen_lowpart (DImode, operands[1]);
2906 }
2907   [(set_attr "itanium_class" "unknown")])
2908 \f
2909 ;; ::::::::::::::::::::
2910 ;; ::
2911 ;; :: 32-bit floating point arithmetic
2912 ;; ::
2913 ;; ::::::::::::::::::::
2914
2915 (define_insn "addsf3"
2916   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2917         (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2918                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2919   ""
2920   "fadd.s %0 = %1, %F2"
2921   [(set_attr "itanium_class" "fmac")])
2922
2923 (define_insn "subsf3"
2924   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2925         (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2926                   (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2927   ""
2928   "fsub.s %0 = %F1, %F2"
2929   [(set_attr "itanium_class" "fmac")])
2930
2931 (define_insn "mulsf3"
2932   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2933         (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2934                  (match_operand:SF 2 "fr_register_operand" "f")))]
2935   ""
2936   "fmpy.s %0 = %1, %2"
2937   [(set_attr "itanium_class" "fmac")])
2938
2939 (define_insn "abssf2"
2940   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2941         (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2942   ""
2943   "fabs %0 = %1"
2944   [(set_attr "itanium_class" "fmisc")])
2945
2946 (define_insn "negsf2"
2947   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2948         (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2949   ""
2950   "fneg %0 = %1"
2951   [(set_attr "itanium_class" "fmisc")])
2952
2953 (define_insn "*nabssf2"
2954   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2955         (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
2956   ""
2957   "fnegabs %0 = %1"
2958   [(set_attr "itanium_class" "fmisc")])
2959
2960 (define_insn "copysignsf3"
2961   [(set (match_operand:SF 0 "register_operand" "=f")
2962         (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2963                     (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2964                    UNSPEC_COPYSIGN))]
2965   ""
2966   "fmerge.s %0 = %F2, %F1"
2967   [(set_attr "itanium_class" "fmisc")])
2968
2969 (define_insn "*ncopysignsf3"
2970   [(set (match_operand:SF 0 "register_operand" "=f")
2971         (neg:SF (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2972                             (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2973                            UNSPEC_COPYSIGN)))]
2974   ""
2975   "fmerge.ns %0 = %F2, %F1"
2976   [(set_attr "itanium_class" "fmisc")])
2977
2978 (define_insn "sminsf3"
2979   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2980         (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2981                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2982   ""
2983   "fmin %0 = %1, %F2"
2984   [(set_attr "itanium_class" "fmisc")])
2985
2986 (define_insn "smaxsf3"
2987   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2988         (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2989                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2990   ""
2991   "fmax %0 = %1, %F2"
2992   [(set_attr "itanium_class" "fmisc")])
2993
2994 (define_insn "*maddsf4"
2995   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2996         (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2997                           (match_operand:SF 2 "fr_register_operand" "f"))
2998                  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2999   ""
3000   "fma.s %0 = %1, %2, %F3"
3001   [(set_attr "itanium_class" "fmac")])
3002
3003 (define_insn "*msubsf4"
3004   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3005         (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
3006                            (match_operand:SF 2 "fr_register_operand" "f"))
3007                   (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
3008   ""
3009   "fms.s %0 = %1, %2, %F3"
3010   [(set_attr "itanium_class" "fmac")])
3011
3012 (define_insn "*nmulsf3"
3013   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3014         (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
3015                          (match_operand:SF 2 "fr_register_operand" "f"))))]
3016   ""
3017   "fnmpy.s %0 = %1, %2"
3018   [(set_attr "itanium_class" "fmac")])
3019
3020 (define_insn "*nmaddsf4"
3021   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3022         (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
3023                   (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
3024                            (match_operand:SF 2 "fr_register_operand" "f"))))]
3025   ""
3026   "fnma.s %0 = %1, %2, %F3"
3027   [(set_attr "itanium_class" "fmac")])
3028
3029 (define_insn "*nmaddsf4_alts"
3030   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3031         (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
3032                   (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
3033                            (match_operand:SF 2 "fr_register_operand" "f"))))
3034    (use (match_operand:SI 4 "const_int_operand" ""))]
3035   ""
3036   "fnma.s.s%4 %0 = %1, %2, %F3"
3037   [(set_attr "itanium_class" "fmac")])
3038
3039 (define_expand "divsf3"
3040   [(set (match_operand:SF 0 "fr_register_operand" "")
3041         (div:SF (match_operand:SF 1 "fr_register_operand" "")
3042                 (match_operand:SF 2 "fr_register_operand" "")))]
3043   "TARGET_INLINE_FLOAT_DIV"
3044 {
3045   rtx insn;
3046   if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
3047     insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
3048   else
3049     insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
3050   emit_insn (insn);
3051   DONE;
3052 })
3053
3054 (define_insn_and_split "divsf3_internal_lat"
3055   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
3056         (div:SF (match_operand:SF 1 "fr_register_operand" "f")
3057                 (match_operand:SF 2 "fr_register_operand" "f")))
3058    (clobber (match_scratch:XF 3 "=&f"))
3059    (clobber (match_scratch:XF 4 "=f"))
3060    (clobber (match_scratch:BI 5 "=c"))]
3061   "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT"
3062   "#"
3063   "&& reload_completed"
3064   [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3065               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3066                                             UNSPEC_FR_RECIP_APPROX))
3067               (use (const_int 0))])
3068    (cond_exec (ne (match_dup 5) (const_int 0))
3069      (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
3070                 (use (const_int 1))]))
3071    (cond_exec (ne (match_dup 5) (const_int 0))
3072      (parallel [(set (match_dup 4)
3073                      (minus:XF (match_dup 10)
3074                                (mult:XF (match_dup 8) (match_dup 6))))
3075                 (use (const_int 1))]))
3076    (cond_exec (ne (match_dup 5) (const_int 0))
3077      (parallel [(set (match_dup 3)
3078                      (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3079                               (match_dup 3)))
3080                 (use (const_int 1))]))
3081    (cond_exec (ne (match_dup 5) (const_int 0))
3082      (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
3083                 (use (const_int 1))]))
3084    (cond_exec (ne (match_dup 5) (const_int 0))
3085      (parallel [(set (match_dup 3)
3086                      (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3087                               (match_dup 3)))
3088                 (use (const_int 1))]))
3089    (cond_exec (ne (match_dup 5) (const_int 0))
3090      (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
3091                 (use (const_int 1))]))
3092    (cond_exec (ne (match_dup 5) (const_int 0))
3093      (parallel [(set (match_dup 9)
3094                      (float_truncate:DF
3095                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3096                               (match_dup 3))))
3097                 (use (const_int 1))]))
3098    (cond_exec (ne (match_dup 5) (const_int 0))
3099      (set (match_dup 0)
3100           (float_truncate:SF (match_dup 6))))
3101   ] 
3102 {
3103   operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3104   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3105   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3106   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
3107   operands[10] = CONST1_RTX (XFmode);
3108 }
3109   [(set_attr "predicable" "no")])
3110
3111 (define_insn_and_split "divsf3_internal_thr"
3112   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
3113         (div:SF (match_operand:SF 1 "fr_register_operand" "f")
3114                 (match_operand:SF 2 "fr_register_operand" "f")))
3115    (clobber (match_scratch:XF 3 "=&f"))
3116    (clobber (match_scratch:XF 4 "=f"))
3117    (clobber (match_scratch:BI 5 "=c"))]
3118   "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR"
3119   "#"
3120   "&& reload_completed"
3121   [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3122               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3123                                             UNSPEC_FR_RECIP_APPROX))
3124               (use (const_int 0))])
3125    (cond_exec (ne (match_dup 5) (const_int 0))
3126      (parallel [(set (match_dup 3)
3127                      (minus:XF (match_dup 10)
3128                                (mult:XF (match_dup 8) (match_dup 6))))
3129                 (use (const_int 1))]))
3130    (cond_exec (ne (match_dup 5) (const_int 0))
3131      (parallel [(set (match_dup 3)
3132                      (plus:XF (mult:XF (match_dup 3) (match_dup 3))
3133                               (match_dup 3)))
3134                 (use (const_int 1))]))
3135    (cond_exec (ne (match_dup 5) (const_int 0))
3136      (parallel [(set (match_dup 6)
3137                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3138                               (match_dup 6)))
3139                 (use (const_int 1))]))
3140    (cond_exec (ne (match_dup 5) (const_int 0))
3141      (parallel [(set (match_dup 9)
3142                      (float_truncate:SF
3143                        (mult:XF (match_dup 7) (match_dup 6))))
3144                 (use (const_int 1))]))
3145    (cond_exec (ne (match_dup 5) (const_int 0))
3146      (parallel [(set (match_dup 4)
3147                      (minus:XF (match_dup 7)
3148                                (mult:XF (match_dup 8) (match_dup 3))))
3149                 (use (const_int 1))]))
3150    (cond_exec (ne (match_dup 5) (const_int 0))
3151      (set (match_dup 0)
3152           (float_truncate:SF
3153             (plus:XF (mult:XF (match_dup 4) (match_dup 6))
3154                               (match_dup 3)))))
3155   ] 
3156 {
3157   operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3158   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3159   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3160   operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
3161   operands[10] = CONST1_RTX (XFmode);
3162 }
3163   [(set_attr "predicable" "no")])
3164
3165 ;; Inline square root.
3166
3167 (define_insn "*sqrt_approx"
3168   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3169         (div:XF (const_int 1)
3170                 (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
3171    (set (match_operand:BI 1 "register_operand" "=c")
3172         (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
3173    (use (match_operand:SI 3 "const_int_operand" "")) ]
3174   ""
3175   "frsqrta.s%3 %0, %1 = %2"
3176   [(set_attr "itanium_class" "fmisc")
3177    (set_attr "predicable" "no")])
3178
3179 (define_insn "setf_exp_xf"
3180   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3181         (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
3182                   UNSPEC_SETF_EXP))]
3183   ""
3184   "setf.exp %0 = %1"
3185   [(set_attr "itanium_class" "frfr")])
3186
3187 (define_expand "sqrtsf2"
3188   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
3189         (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))]
3190   "TARGET_INLINE_SQRT"
3191 {
3192   rtx insn;
3193 #if 0
3194   if (TARGET_INLINE_SQRT == INL_MIN_LAT)
3195     insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
3196   else
3197 #else
3198   gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
3199 #endif
3200   insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
3201   emit_insn (insn);
3202   DONE;
3203 })
3204
3205 ;; Latency-optimized square root.
3206 ;; FIXME: Implement.
3207
3208 ;; Throughput-optimized square root.
3209
3210 (define_insn_and_split "sqrtsf2_internal_thr"
3211   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
3212         (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))
3213    ;; Register r2 in optimization guide.
3214    (clobber (match_scratch:DI 2 "=r"))
3215    ;; Register f8 in optimization guide
3216    (clobber (match_scratch:XF 3 "=&f"))
3217    ;; Register f9 in optimization guide
3218    (clobber (match_scratch:XF 4 "=&f"))
3219    ;; Register f10 in optimization guide
3220    (clobber (match_scratch:XF 5 "=&f"))
3221    ;; Register p6 in optimization guide.
3222    (clobber (match_scratch:BI 6 "=c"))]
3223   "TARGET_INLINE_SQRT == INL_MAX_THR"
3224   "#"
3225   "&& reload_completed"
3226   [ ;; exponent of +1/2 in r2
3227     (set (match_dup 2) (const_int 65534))
3228     ;; +1/2 in f8
3229     (set (match_dup 3) 
3230          (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3231     ;; Step 1
3232     ;; y0 = 1/sqrt(a) in f7
3233     (parallel [(set (match_dup 7)
3234                     (div:XF (const_int 1)
3235                             (sqrt:XF (match_dup 8))))
3236                (set (match_dup 6)
3237                     (unspec:BI [(match_dup 8)]
3238                                  UNSPEC_FR_SQRT_RECIP_APPROX))
3239                (use (const_int 0))])
3240     ;; Step 2
3241     ;; H0 = 1/2 * y0 in f9
3242     (cond_exec (ne (match_dup 6) (const_int 0))
3243       (parallel [(set (match_dup 4)
3244                       (plus:XF (mult:XF (match_dup 3) (match_dup 7))
3245                                (match_dup 9)))
3246                  (use (const_int 1))]))
3247     ;; Step 3
3248     ;; S0 = a * y0 in f7
3249     (cond_exec (ne (match_dup 6) (const_int 0))
3250       (parallel [(set (match_dup 7)
3251                       (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3252                                (match_dup 9)))
3253                  (use (const_int 1))]))
3254     ;; Step 4
3255     ;; d = 1/2 - S0 * H0 in f10
3256     (cond_exec (ne (match_dup 6) (const_int 0))
3257       (parallel [(set (match_dup 5)
3258                       (minus:XF (match_dup 3)
3259                                 (mult:XF (match_dup 7) (match_dup 4))))
3260                  (use (const_int 1))]))
3261     ;; Step 5
3262     ;; d' = d + 1/2 * 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 3) (match_dup 5))
3266                                 (match_dup 5)))
3267                   (use (const_int 1))]))
3268     ;; Step 6
3269     ;; e = d + d * d' in f8
3270     (cond_exec (ne (match_dup 6) (const_int 0))
3271        (parallel [(set (match_dup 3)
3272                        (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3273                                 (match_dup 5)))
3274                   (use (const_int 1))]))
3275     ;; Step 7
3276     ;; S1 = S0 + e * S0 in f7
3277     (cond_exec (ne (match_dup 6) (const_int 0))
3278       (parallel [(set (match_dup 0)
3279                       (float_truncate:SF
3280                         (plus:XF (mult:XF (match_dup 3) (match_dup 7))
3281                                  (match_dup 7))))
3282                  (use (const_int 1))]))
3283     ;; Step 8
3284     ;; H1 = H0 + e * H0 in f8
3285     (cond_exec (ne (match_dup 6) (const_int 0))
3286        (parallel [(set (match_dup 3)
3287                        (plus:XF (mult:XF (match_dup 3) (match_dup 4))
3288                                 (match_dup 4)))
3289                   (use (const_int 1))]))
3290     ;; Step 9 
3291     ;; d1 = a - S1 * S1 in f9
3292     (cond_exec (ne (match_dup 6) (const_int 0))
3293        (parallel [(set (match_dup 4)
3294                        (minus:XF (match_dup 8)
3295                                  (mult:XF (match_dup 7) (match_dup 7))))
3296                   (use (const_int 1))]))
3297     ;; Step 10
3298     ;; S = S1 + d1 * H1 in f7
3299     (cond_exec (ne (match_dup 6) (const_int 0))
3300        (parallel [(set (match_dup 0)
3301                        (float_truncate:SF
3302                          (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3303                                   (match_dup 7))))
3304                   (use (const_int 0))]))]
3305 {
3306   /* Generate 82-bit versions of the input and output operands.  */
3307   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3308   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3309   /* Generate required floating-point constants.  */
3310   operands[9] = CONST0_RTX (XFmode);
3311 }
3312   [(set_attr "predicable" "no")])
3313 \f
3314 ;; ::::::::::::::::::::
3315 ;; ::
3316 ;; :: 64-bit floating point arithmetic
3317 ;; ::
3318 ;; ::::::::::::::::::::
3319
3320 (define_insn "adddf3"
3321   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3322         (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
3323                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
3324   ""
3325   "fadd.d %0 = %1, %F2"
3326   [(set_attr "itanium_class" "fmac")])
3327
3328 (define_insn "*adddf3_trunc"
3329   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3330         (float_truncate:SF
3331           (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
3332                    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
3333   ""
3334   "fadd.s %0 = %1, %F2"
3335   [(set_attr "itanium_class" "fmac")])
3336
3337 (define_insn "subdf3"
3338   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3339         (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3340                   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
3341   ""
3342   "fsub.d %0 = %F1, %F2"
3343   [(set_attr "itanium_class" "fmac")])
3344
3345 (define_insn "*subdf3_trunc"
3346   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3347         (float_truncate:SF
3348           (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3349                     (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
3350   ""
3351   "fsub.s %0 = %F1, %F2"
3352   [(set_attr "itanium_class" "fmac")])
3353
3354 (define_insn "muldf3"
3355   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3356         (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3357                  (match_operand:DF 2 "fr_register_operand" "f")))]
3358   ""
3359   "fmpy.d %0 = %1, %2"
3360   [(set_attr "itanium_class" "fmac")])
3361
3362 (define_insn "*muldf3_trunc"
3363   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3364         (float_truncate:SF
3365           (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3366                    (match_operand:DF 2 "fr_register_operand" "f"))))]
3367   ""
3368   "fmpy.s %0 = %1, %2"
3369   [(set_attr "itanium_class" "fmac")])
3370
3371 (define_insn "absdf2"
3372   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3373         (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3374   ""
3375   "fabs %0 = %1"
3376   [(set_attr "itanium_class" "fmisc")])
3377
3378 (define_insn "negdf2"
3379   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3380         (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3381   ""
3382   "fneg %0 = %1"
3383   [(set_attr "itanium_class" "fmisc")])
3384
3385 (define_insn "*nabsdf2"
3386   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3387         (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
3388   ""
3389   "fnegabs %0 = %1"
3390   [(set_attr "itanium_class" "fmisc")])
3391
3392 (define_insn "copysigndf3"
3393   [(set (match_operand:DF 0 "register_operand" "=f")
3394         (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3395                     (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
3396                    UNSPEC_COPYSIGN))]
3397   ""
3398   "fmerge.s %0 = %F2, %F1"
3399   [(set_attr "itanium_class" "fmisc")])
3400
3401 (define_insn "*ncopysigndf3"
3402   [(set (match_operand:DF 0 "register_operand" "=f")
3403         (neg:DF (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3404                             (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
3405                            UNSPEC_COPYSIGN)))]
3406   ""
3407   "fmerge.ns %0 = %F2, %F1"
3408   [(set_attr "itanium_class" "fmisc")])
3409
3410 (define_insn "smindf3"
3411   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3412         (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
3413                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
3414   ""
3415   "fmin %0 = %1, %F2"
3416   [(set_attr "itanium_class" "fmisc")])
3417
3418 (define_insn "smaxdf3"
3419   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3420         (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
3421                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
3422   ""
3423   "fmax %0 = %1, %F2"
3424   [(set_attr "itanium_class" "fmisc")])
3425
3426 (define_insn "*madddf4"
3427   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3428         (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3429                           (match_operand:DF 2 "fr_register_operand" "f"))
3430                  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3431   ""
3432   "fma.d %0 = %1, %2, %F3"
3433   [(set_attr "itanium_class" "fmac")])
3434
3435 (define_insn "*madddf4_trunc"
3436   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3437         (float_truncate:SF
3438           (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3439                             (match_operand:DF 2 "fr_register_operand" "f"))
3440                    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3441   ""
3442   "fma.s %0 = %1, %2, %F3"
3443   [(set_attr "itanium_class" "fmac")])
3444
3445 (define_insn "*msubdf4"
3446   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3447         (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3448                            (match_operand:DF 2 "fr_register_operand" "f"))
3449                   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3450   ""
3451   "fms.d %0 = %1, %2, %F3"
3452   [(set_attr "itanium_class" "fmac")])
3453
3454 (define_insn "*msubdf4_trunc"
3455   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3456         (float_truncate:SF
3457           (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3458                              (match_operand:DF 2 "fr_register_operand" "f"))
3459                     (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3460   ""
3461   "fms.s %0 = %1, %2, %F3"
3462   [(set_attr "itanium_class" "fmac")])
3463
3464 (define_insn "*nmuldf3"
3465   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3466         (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3467                          (match_operand:DF 2 "fr_register_operand" "f"))))]
3468   ""
3469   "fnmpy.d %0 = %1, %2"
3470   [(set_attr "itanium_class" "fmac")])
3471
3472 (define_insn "*nmuldf3_trunc"
3473   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3474         (float_truncate:SF
3475           (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3476                            (match_operand:DF 2 "fr_register_operand" "f")))))]
3477   ""
3478   "fnmpy.s %0 = %1, %2"
3479   [(set_attr "itanium_class" "fmac")])
3480
3481 (define_insn "*nmadddf4"
3482   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3483         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3484                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3485                            (match_operand:DF 2 "fr_register_operand" "f"))))]
3486   ""
3487   "fnma.d %0 = %1, %2, %F3"
3488   [(set_attr "itanium_class" "fmac")])
3489
3490 (define_insn "*nmadddf4_alts"
3491   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3492         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3493                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3494                            (match_operand:DF 2 "fr_register_operand" "f"))))
3495    (use (match_operand:SI 4 "const_int_operand" ""))]
3496   ""
3497   "fnma.d.s%4 %0 = %1, %2, %F3"
3498   [(set_attr "itanium_class" "fmac")])
3499
3500 (define_insn "*nmadddf4_truncsf"
3501   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3502         (float_truncate:SF
3503         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3504                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3505                            (match_operand:DF 2 "fr_register_operand" "f")))))]
3506   ""
3507   "fnma.s %0 = %1, %2, %F3"
3508   [(set_attr "itanium_class" "fmac")])
3509
3510 (define_insn "*nmadddf4_truncsf_alts"
3511   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3512         (float_truncate:SF
3513         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3514                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3515                            (match_operand:DF 2 "fr_register_operand" "f")))))
3516    (use (match_operand:SI 4 "const_int_operand" ""))]
3517   ""
3518   "fnma.s.s%4 %0 = %1, %2, %F3"
3519   [(set_attr "itanium_class" "fmac")])
3520
3521 (define_expand "divdf3"
3522   [(set (match_operand:DF 0 "fr_register_operand" "")
3523         (div:DF (match_operand:DF 1 "fr_register_operand" "")
3524                 (match_operand:DF 2 "fr_register_operand" "")))]
3525   "TARGET_INLINE_FLOAT_DIV"
3526 {
3527   rtx insn;
3528   if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
3529     insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
3530   else
3531     insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
3532   emit_insn (insn);
3533   DONE;
3534 })
3535
3536 (define_insn_and_split "divdf3_internal_lat"
3537   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3538         (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3539                 (match_operand:DF 2 "fr_register_operand" "f")))
3540    (clobber (match_scratch:XF 3 "=&f"))
3541    (clobber (match_scratch:XF 4 "=&f"))
3542    (clobber (match_scratch:XF 5 "=&f"))
3543    (clobber (match_scratch:BI 6 "=c"))]
3544   "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT"
3545   "#"
3546   "&& reload_completed"
3547   [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
3548               (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3549                                             UNSPEC_FR_RECIP_APPROX))
3550               (use (const_int 0))])
3551    (cond_exec (ne (match_dup 6) (const_int 0))
3552      (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
3553                 (use (const_int 1))]))
3554    (cond_exec (ne (match_dup 6) (const_int 0))
3555      (parallel [(set (match_dup 4)
3556                      (minus:XF (match_dup 12)
3557                                (mult:XF (match_dup 9) (match_dup 7))))
3558                 (use (const_int 1))]))
3559    (cond_exec (ne (match_dup 6) (const_int 0))
3560      (parallel [(set (match_dup 3)
3561                      (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3562                               (match_dup 3)))
3563                 (use (const_int 1))]))
3564    (cond_exec (ne (match_dup 6) (const_int 0))
3565      (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
3566                 (use (const_int 1))]))
3567    (cond_exec (ne (match_dup 6) (const_int 0))
3568      (parallel [(set (match_dup 7)
3569                      (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3570                               (match_dup 7)))
3571                 (use (const_int 1))]))
3572    (cond_exec (ne (match_dup 6) (const_int 0))
3573      (parallel [(set (match_dup 3)
3574                      (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3575                               (match_dup 3)))
3576                 (use (const_int 1))]))
3577    (cond_exec (ne (match_dup 6) (const_int 0))
3578      (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
3579                 (use (const_int 1))]))
3580    (cond_exec (ne (match_dup 6) (const_int 0))
3581      (parallel [(set (match_dup 7)
3582                      (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3583                               (match_dup 7)))
3584                 (use (const_int 1))]))
3585    (cond_exec (ne (match_dup 6) (const_int 0))
3586      (parallel [(set (match_dup 10)
3587                      (float_truncate:DF
3588                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3589                               (match_dup 3))))
3590                 (use (const_int 1))]))
3591    (cond_exec (ne (match_dup 6) (const_int 0))
3592      (parallel [(set (match_dup 7)
3593                      (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3594                               (match_dup 7)))
3595                 (use (const_int 1))]))
3596    (cond_exec (ne (match_dup 6) (const_int 0))
3597      (parallel [(set (match_dup 11)
3598                      (float_truncate:DF
3599                        (minus:XF (match_dup 8)
3600                                  (mult:XF (match_dup 9) (match_dup 3)))))
3601                 (use (const_int 1))]))
3602    (cond_exec (ne (match_dup 6) (const_int 0))
3603      (set (match_dup 0)
3604           (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3605                               (match_dup 3)))))
3606   ] 
3607 {
3608   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3609   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3610   operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3611   operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3612   operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3613   operands[12] = CONST1_RTX (XFmode);
3614 }
3615   [(set_attr "predicable" "no")])
3616
3617 (define_insn_and_split "divdf3_internal_thr"
3618   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3619         (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3620                 (match_operand:DF 2 "fr_register_operand" "f")))
3621    (clobber (match_scratch:XF 3 "=&f"))
3622    (clobber (match_scratch:DF 4 "=f"))
3623    (clobber (match_scratch:BI 5 "=c"))]
3624   "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR"
3625   "#"
3626   "&& reload_completed"
3627   [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3628               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3629                                             UNSPEC_FR_RECIP_APPROX))
3630               (use (const_int 0))])
3631    (cond_exec (ne (match_dup 5) (const_int 0))
3632      (parallel [(set (match_dup 3)
3633                      (minus:XF (match_dup 10)
3634                                (mult:XF (match_dup 8) (match_dup 6))))
3635                 (use (const_int 1))]))
3636    (cond_exec (ne (match_dup 5) (const_int 0))
3637      (parallel [(set (match_dup 6)
3638                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3639                               (match_dup 6)))
3640                 (use (const_int 1))]))
3641    (cond_exec (ne (match_dup 5) (const_int 0))
3642      (parallel [(set (match_dup 3)
3643                      (mult:XF (match_dup 3) (match_dup 3)))
3644                 (use (const_int 1))]))
3645    (cond_exec (ne (match_dup 5) (const_int 0))
3646      (parallel [(set (match_dup 6)
3647                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3648                               (match_dup 6)))
3649                 (use (const_int 1))]))
3650    (cond_exec (ne (match_dup 5) (const_int 0))
3651      (parallel [(set (match_dup 3)
3652                      (mult:XF (match_dup 3) (match_dup 3)))
3653                 (use (const_int 1))]))
3654    (cond_exec (ne (match_dup 5) (const_int 0))
3655      (parallel [(set (match_dup 6)
3656                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3657                               (match_dup 6)))
3658                 (use (const_int 1))]))
3659    (cond_exec (ne (match_dup 5) (const_int 0))
3660      (parallel [(set (match_dup 9)
3661                      (float_truncate:DF
3662                        (mult:XF (match_dup 7) (match_dup 6))))
3663                 (use (const_int 1))]))
3664    (cond_exec (ne (match_dup 5) (const_int 0))
3665      (parallel [(set (match_dup 4)
3666                      (minus:DF (match_dup 1)
3667                                (mult:DF (match_dup 2) (match_dup 9))))
3668                 (use (const_int 1))]))
3669    (cond_exec (ne (match_dup 5) (const_int 0))
3670      (set (match_dup 0)
3671           (plus:DF (mult:DF (match_dup 4) (match_dup 0))
3672                             (match_dup 9))))
3673   ] 
3674 {
3675   operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3676   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3677   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3678   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3679   operands[10] = CONST1_RTX (XFmode);
3680 }
3681   [(set_attr "predicable" "no")])
3682
3683 ;; Inline square root.
3684
3685 (define_expand "sqrtdf2"
3686   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3687         (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3688   "TARGET_INLINE_SQRT"
3689 {
3690   rtx insn;
3691 #if 0
3692   if (TARGET_INLINE_SQRT == INL_MIN_LAT)
3693     insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
3694   else
3695 #else
3696   gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
3697 #endif
3698   insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
3699   emit_insn (insn);
3700   DONE;
3701 })
3702
3703 ;; Latency-optimized square root.
3704 ;; FIXME: Implement.
3705
3706 ;; Throughput-optimized square root.
3707
3708 (define_insn_and_split "sqrtdf2_internal_thr"
3709   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3710         (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))
3711    ;; Register r2 in optimization guide.
3712    (clobber (match_scratch:DI 2 "=r"))
3713    ;; Register f8 in optimization guide
3714    (clobber (match_scratch:XF 3 "=&f"))
3715    ;; Register f9 in optimization guide
3716    (clobber (match_scratch:XF 4 "=&f"))
3717    ;; Register f10 in optimization guide
3718    (clobber (match_scratch:XF 5 "=&f"))
3719    ;; Register p6 in optimization guide.
3720    (clobber (match_scratch:BI 6 "=c"))]
3721   "TARGET_INLINE_SQRT == INL_MAX_THR"
3722   "#"
3723   "&& reload_completed"
3724   [ ;; exponent of +1/2 in r2
3725     (set (match_dup 2) (const_int 65534))
3726     ;; +1/2 in f10
3727     (set (match_dup 5) 
3728          (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3729     ;; Step 1
3730     ;; y0 = 1/sqrt(a) in f7
3731     (parallel [(set (match_dup 7)
3732                     (div:XF (const_int 1)
3733                             (sqrt:XF (match_dup 8))))
3734                (set (match_dup 6)
3735                     (unspec:BI [(match_dup 8)]
3736                                  UNSPEC_FR_SQRT_RECIP_APPROX))
3737                (use (const_int 0))])
3738     ;; Step 2
3739     ;; H0 = 1/2 * y0 in f8
3740     (cond_exec (ne (match_dup 6) (const_int 0))
3741       (parallel [(set (match_dup 3)
3742                       (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3743                                (match_dup 9)))
3744                  (use (const_int 1))]))
3745     ;; Step 3
3746     ;; G0 = a * y0 in f7
3747     (cond_exec (ne (match_dup 6) (const_int 0))
3748       (parallel [(set (match_dup 7)
3749                       (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3750                                (match_dup 9)))
3751                  (use (const_int 1))]))
3752     ;; Step 4
3753     ;; r0 = 1/2 - G0 * H0 in f9
3754     (cond_exec (ne (match_dup 6) (const_int 0))
3755       (parallel [(set (match_dup 4)
3756                       (minus:XF (match_dup 5)
3757                                 (mult:XF (match_dup 7) (match_dup 3))))
3758                  (use (const_int 1))]))
3759     ;; Step 5
3760     ;; H1 = H0 + r0 * H0 in f8
3761     (cond_exec (ne (match_dup 6) (const_int 0))
3762        (parallel [(set (match_dup 3)
3763                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3764                                 (match_dup 3)))
3765                   (use (const_int 1))]))
3766     ;; Step 6
3767     ;; G1 = G0 + r0 * G0 in f7
3768     (cond_exec (ne (match_dup 6) (const_int 0))
3769        (parallel [(set (match_dup 7)
3770                        (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3771                                 (match_dup 7)))
3772                   (use (const_int 1))]))
3773     ;; Step 7
3774     ;; r1 = 1/2 - G1 * H1 in f9
3775     (cond_exec (ne (match_dup 6) (const_int 0))
3776       (parallel [(set (match_dup 4)
3777                       (minus:XF (match_dup 5)
3778                                 (mult:XF (match_dup 7) (match_dup 3))))
3779                  (use (const_int 1))]))
3780     ;; Step 8
3781     ;; H2 = H1 + r1 * H1 in f8
3782     (cond_exec (ne (match_dup 6) (const_int 0))
3783        (parallel [(set (match_dup 3)
3784                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3785                                 (match_dup 3)))
3786                   (use (const_int 1))]))
3787     ;; Step 9 
3788     ;; G2 = G1 + r1 * G1 in f7
3789     (cond_exec (ne (match_dup 6) (const_int 0))
3790        (parallel [(set (match_dup 7)
3791                        (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3792                                 (match_dup 7)))
3793                   (use (const_int 1))]))
3794     ;; Step 10
3795     ;; d2 = a - G2 * G2 in f9
3796     (cond_exec (ne (match_dup 6) (const_int 0))
3797        (parallel [(set (match_dup 4)
3798                        (minus:XF (match_dup 8)
3799                                  (mult:XF (match_dup 7) (match_dup 7))))
3800                   (use (const_int 1))]))
3801     ;; Step 11
3802     ;; G3 = G2 + d2 * H2 in f7
3803     (cond_exec (ne (match_dup 6) (const_int 0))
3804        (parallel [(set (match_dup 7)
3805                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3806                                 (match_dup 7)))
3807                   (use (const_int 1))]))
3808     ;; Step 12
3809     ;; d3 = a - G3 * G3 in f9
3810     (cond_exec (ne (match_dup 6) (const_int 0))
3811        (parallel [(set (match_dup 4)
3812                        (minus:XF (match_dup 8)
3813                                  (mult:XF (match_dup 7) (match_dup 7))))
3814                   (use (const_int 1))]))
3815     ;; Step 13
3816     ;; S = G3 + d3 * H2 in f7
3817     (cond_exec (ne (match_dup 6) (const_int 0))
3818        (parallel [(set (match_dup 0)
3819                        (float_truncate:DF
3820                          (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3821                                   (match_dup 7))))
3822                   (use (const_int 0))]))]
3823 {
3824   /* Generate 82-bit versions of the input and output operands.  */
3825   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3826   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3827   /* Generate required floating-point constants.  */
3828   operands[9] = CONST0_RTX (XFmode);
3829 }
3830   [(set_attr "predicable" "no")])
3831 \f
3832 ;; ::::::::::::::::::::
3833 ;; ::
3834 ;; :: 80-bit floating point arithmetic
3835 ;; ::
3836 ;; ::::::::::::::::::::
3837
3838 (define_insn "addxf3"
3839   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3840         (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3841                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3842   ""
3843   "fadd %0 = %F1, %F2"
3844   [(set_attr "itanium_class" "fmac")])
3845
3846 (define_insn "*addxf3_truncsf"
3847   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3848         (float_truncate:SF
3849           (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3850                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3851   ""
3852   "fadd.s %0 = %F1, %F2"
3853   [(set_attr "itanium_class" "fmac")])
3854
3855 (define_insn "*addxf3_truncdf"
3856   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3857         (float_truncate:DF
3858           (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3859                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3860   ""
3861   "fadd.d %0 = %F1, %F2"
3862   [(set_attr "itanium_class" "fmac")])
3863
3864 (define_insn "subxf3"
3865   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3866         (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3867                   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3868   ""
3869   "fsub %0 = %F1, %F2"
3870   [(set_attr "itanium_class" "fmac")])
3871
3872 (define_insn "*subxf3_truncsf"
3873   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3874         (float_truncate:SF
3875           (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3876                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3877   ""
3878   "fsub.s %0 = %F1, %F2"
3879   [(set_attr "itanium_class" "fmac")])
3880
3881 (define_insn "*subxf3_truncdf"
3882   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3883         (float_truncate:DF
3884           (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3885                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3886   ""
3887   "fsub.d %0 = %F1, %F2"
3888   [(set_attr "itanium_class" "fmac")])
3889
3890 (define_insn "mulxf3"
3891   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3892         (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3893                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3894   ""
3895   "fmpy %0 = %F1, %F2"
3896   [(set_attr "itanium_class" "fmac")])
3897
3898 (define_insn "*mulxf3_truncsf"
3899   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3900         (float_truncate:SF
3901           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3902                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3903   ""
3904   "fmpy.s %0 = %F1, %F2"
3905   [(set_attr "itanium_class" "fmac")])
3906
3907 (define_insn "*mulxf3_truncdf"
3908   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3909         (float_truncate:DF
3910           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3911                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3912   ""
3913   "fmpy.d %0 = %F1, %F2"
3914   [(set_attr "itanium_class" "fmac")])
3915
3916 (define_insn "*mulxf3_alts"
3917   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3918         (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3919                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3920    (use (match_operand:SI 3 "const_int_operand" ""))]
3921   ""
3922   "fmpy.s%3 %0 = %F1, %F2"
3923   [(set_attr "itanium_class" "fmac")])
3924
3925 (define_insn "*mulxf3_truncsf_alts"
3926   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3927         (float_truncate:SF
3928           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3929                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3930    (use (match_operand:SI 3 "const_int_operand" ""))]
3931   ""
3932   "fmpy.s.s%3 %0 = %F1, %F2"
3933   [(set_attr "itanium_class" "fmac")])
3934
3935 (define_insn "*mulxf3_truncdf_alts"
3936   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3937         (float_truncate:DF
3938           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3939                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3940    (use (match_operand:SI 3 "const_int_operand" ""))]
3941   ""
3942   "fmpy.d.s%3 %0 = %F1, %F2"
3943   [(set_attr "itanium_class" "fmac")])
3944
3945 (define_insn "absxf2"
3946   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3947         (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3948   ""
3949   "fabs %0 = %F1"
3950   [(set_attr "itanium_class" "fmisc")])
3951
3952 (define_insn "negxf2"
3953   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3954         (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3955   ""
3956   "fneg %0 = %F1"
3957   [(set_attr "itanium_class" "fmisc")])
3958
3959 (define_insn "*nabsxf2"
3960   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3961         (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
3962   ""
3963   "fnegabs %0 = %F1"
3964   [(set_attr "itanium_class" "fmisc")])
3965
3966 (define_insn "copysignxf3"
3967   [(set (match_operand:XF 0 "register_operand" "=f")
3968         (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3969                     (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3970                    UNSPEC_COPYSIGN))]
3971   ""
3972   "fmerge.s %0 = %F2, %F1"
3973   [(set_attr "itanium_class" "fmisc")])
3974
3975 (define_insn "*ncopysignxf3"
3976   [(set (match_operand:XF 0 "register_operand" "=f")
3977         (neg:XF (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3978                             (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3979                            UNSPEC_COPYSIGN)))]
3980   ""
3981   "fmerge.ns %0 = %F2, %F1"
3982   [(set_attr "itanium_class" "fmisc")])
3983
3984 (define_insn "sminxf3"
3985   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3986         (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3987                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3988   ""
3989   "fmin %0 = %F1, %F2"
3990   [(set_attr "itanium_class" "fmisc")])
3991
3992 (define_insn "smaxxf3"
3993   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3994         (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3995                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3996   ""
3997   "fmax %0 = %F1, %F2"
3998   [(set_attr "itanium_class" "fmisc")])
3999
4000 (define_insn "*maddxf4"
4001   [(set (match_operand:XF 0 "fr_register_operand" "=f")
4002         (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4003                           (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4004                  (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
4005   ""
4006   "fma %0 = %F1, %F2, %F3"
4007   [(set_attr "itanium_class" "fmac")])
4008
4009 (define_insn "*maddxf4_truncsf"
4010   [(set (match_operand:SF 0 "fr_register_operand" "=f")
4011         (float_truncate:SF
4012           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4013                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4014                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4015   ""
4016   "fma.s %0 = %F1, %F2, %F3"
4017   [(set_attr "itanium_class" "fmac")])
4018
4019 (define_insn "*maddxf4_truncdf"
4020   [(set (match_operand:DF 0 "fr_register_operand" "=f")
4021         (float_truncate:DF
4022           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4023                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4024                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4025   ""
4026   "fma.d %0 = %F1, %F2, %F3"
4027   [(set_attr "itanium_class" "fmac")])
4028
4029 (define_insn "*maddxf4_alts"
4030   [(set (match_operand:XF 0 "fr_register_operand" "=f")
4031         (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4032                           (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4033                  (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
4034    (use (match_operand:SI 4 "const_int_operand" ""))]
4035   ""
4036   "fma.s%4 %0 = %F1, %F2, %F3"
4037   [(set_attr "itanium_class" "fmac")])
4038
4039 (define_insn "*maddxf4_alts_truncsf"
4040   [(set (match_operand:SF 0 "fr_register_operand" "=f")
4041         (float_truncate:SF
4042           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4043                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4044                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
4045    (use (match_operand:SI 4 "const_int_operand" ""))]
4046   ""
4047   "fma.s.s%4 %0 = %F1, %F2, %F3"
4048   [(set_attr "itanium_class" "fmac")])
4049
4050 (define_insn "*maddxf4_alts_truncdf"
4051   [(set (match_operand:DF 0 "fr_register_operand" "=f")
4052         (float_truncate:DF
4053           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4054                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4055                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
4056    (use (match_operand:SI 4 "const_int_operand" ""))]
4057   ""
4058   "fma.d.s%4 %0 = %F1, %F2, %F3"
4059   [(set_attr "itanium_class" "fmac")])
4060
4061 (define_insn "*msubxf4"
4062   [(set (match_operand:XF 0 "fr_register_operand" "=f")
4063         (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4064                            (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4065                   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
4066   ""
4067   "fms %0 = %F1, %F2, %F3"
4068   [(set_attr "itanium_class" "fmac")])
4069
4070 (define_insn "*msubxf4_truncsf"
4071   [(set (match_operand:SF 0 "fr_register_operand" "=f")
4072         (float_truncate:SF
4073           (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4074                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4075                     (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4076   ""
4077   "fms.s %0 = %F1, %F2, %F3"
4078   [(set_attr "itanium_class" "fmac")])
4079
4080 (define_insn "*msubxf4_truncdf"
4081   [(set (match_operand:DF 0 "fr_register_operand" "=f")
4082         (float_truncate:DF
4083           (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4084                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4085                     (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4086   ""
4087   "fms.d %0 = %F1, %F2, %F3"
4088   [(set_attr "itanium_class" "fmac")])
4089
4090 (define_insn "*nmulxf3"
4091   [(set (match_operand:XF 0 "fr_register_operand" "=f")
4092         (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4093                          (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
4094   ""
4095   "fnmpy %0 = %F1, %F2"
4096   [(set_attr "itanium_class" "fmac")])
4097
4098 (define_insn "*nmulxf3_truncsf"
4099   [(set (match_operand:SF 0 "fr_register_operand" "=f")
4100         (float_truncate:SF
4101           (neg:XF (mult:XF
4102                     (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4103                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
4104   ""
4105   "fnmpy.s %0 = %F1, %F2"
4106   [(set_attr "itanium_class" "fmac")])
4107
4108 (define_insn "*nmulxf3_truncdf"
4109   [(set (match_operand:DF 0 "fr_register_operand" "=f")
4110         (float_truncate:DF
4111           (neg:XF (mult:XF
4112                     (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4113                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
4114   ""
4115   "fnmpy.d %0 = %F1, %F2"
4116   [(set_attr "itanium_class" "fmac")])
4117
4118 (define_insn "*nmaddxf4"
4119   [(set (match_operand:XF 0 "fr_register_operand" "=f")
4120         (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
4121                   (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4122                            (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4123    )))]
4124   ""
4125   "fnma %0 = %F1, %F2, %F3"
4126   [(set_attr "itanium_class" "fmac")])
4127
4128 (define_insn "*nmaddxf4_truncsf"
4129   [(set (match_operand:SF 0 "fr_register_operand" "=f")
4130         (float_truncate:SF
4131           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4132                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4133                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4134    ))))]
4135   ""
4136   "fnma.s %0 = %F1, %F2, %F3"
4137   [(set_attr "itanium_class" "fmac")])
4138
4139 (define_insn "*nmaddxf4_truncdf"
4140   [(set (match_operand:DF 0 "fr_register_operand" "=f")
4141         (float_truncate:DF
4142           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4143                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4144                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4145    ))))]
4146   ""
4147   "fnma.d %0 = %F1, %F2, %F3"
4148   [(set_attr "itanium_class" "fmac")])
4149
4150 (define_insn "*nmaddxf4_alts"
4151   [(set (match_operand:XF 0 "fr_register_operand" "=f")
4152         (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
4153                   (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4154                            (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4155    )))
4156    (use (match_operand:SI 4 "const_int_operand" ""))]
4157   ""
4158   "fnma.s%4 %0 = %F1, %F2, %F3"
4159   [(set_attr "itanium_class" "fmac")])
4160
4161 (define_insn "*nmaddxf4_truncsf_alts"
4162   [(set (match_operand:SF 0 "fr_register_operand" "=f")
4163         (float_truncate:SF
4164           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4165                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4166                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4167    ))))
4168    (use (match_operand:SI 4 "const_int_operand" ""))]
4169   ""
4170   "fnma.s.s%4 %0 = %F1, %F2, %F3"
4171   [(set_attr "itanium_class" "fmac")])
4172
4173 (define_insn "*nmaddxf4_truncdf_alts"
4174   [(set (match_operand:DF 0 "fr_register_operand" "=f")
4175         (float_truncate:DF
4176           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4177                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4178                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4179    ))))
4180    (use (match_operand:SI 4 "const_int_operand" ""))]
4181   ""
4182   "fnma.d.s%4 %0 = %F1, %F2, %F3"
4183   [(set_attr "itanium_class" "fmac")])
4184
4185 (define_expand "divxf3"
4186   [(set (match_operand:XF 0 "fr_register_operand" "")
4187         (div:XF (match_operand:XF 1 "fr_register_operand" "")
4188                 (match_operand:XF 2 "fr_register_operand" "")))]
4189   "TARGET_INLINE_FLOAT_DIV"
4190 {
4191   rtx insn;
4192   if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
4193     insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
4194   else
4195     insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
4196   emit_insn (insn);
4197   DONE;
4198 })
4199
4200 (define_insn_and_split "divxf3_internal_lat"
4201   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4202         (div:XF (match_operand:XF 1 "fr_register_operand" "f")
4203                 (match_operand:XF 2 "fr_register_operand" "f")))
4204    (clobber (match_scratch:XF 3 "=&f"))
4205    (clobber (match_scratch:XF 4 "=&f"))
4206    (clobber (match_scratch:XF 5 "=&f"))
4207    (clobber (match_scratch:XF 6 "=&f"))
4208    (clobber (match_scratch:BI 7 "=c"))]
4209   "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT"
4210   "#"
4211   "&& reload_completed"
4212   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
4213               (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
4214                                             UNSPEC_FR_RECIP_APPROX))
4215               (use (const_int 0))])
4216    (cond_exec (ne (match_dup 7) (const_int 0))
4217      (parallel [(set (match_dup 3)
4218                      (minus:XF (match_dup 8)
4219                                (mult:XF (match_dup 2) (match_dup 0))))
4220                 (use (const_int 1))]))
4221    (cond_exec (ne (match_dup 7) (const_int 0))
4222      (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
4223                 (use (const_int 1))]))
4224    (cond_exec (ne (match_dup 7) (const_int 0))
4225      (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
4226                 (use (const_int 1))]))
4227    (cond_exec (ne (match_dup 7) (const_int 0))
4228      (parallel [(set (match_dup 6)
4229                      (plus:XF (mult:XF (match_dup 3) (match_dup 3))
4230                               (match_dup 3)))
4231                 (use (const_int 1))]))
4232    (cond_exec (ne (match_dup 7) (const_int 0))
4233      (parallel [(set (match_dup 3)
4234                      (plus:XF (mult:XF (match_dup 5) (match_dup 5))
4235                               (match_dup 3)))
4236                 (use (const_int 1))]))
4237    (cond_exec (ne (match_dup 7) (const_int 0))
4238      (parallel [(set (match_dup 5)
4239                      (plus:XF (mult:XF (match_dup 6) (match_dup 0))
4240                               (match_dup 0)))
4241                 (use (const_int 1))]))
4242    (cond_exec (ne (match_dup 7) (const_int 0))
4243      (parallel [(set (match_dup 0)
4244                      (plus:XF (mult:XF (match_dup 5) (match_dup 3))
4245                               (match_dup 0)))
4246                 (use (const_int 1))]))
4247    (cond_exec (ne (match_dup 7) (const_int 0))
4248      (parallel [(set (match_dup 4)
4249                      (minus:XF (match_dup 1)
4250                                (mult:XF (match_dup 2) (match_dup 4))))
4251                 (use (const_int 1))]))
4252    (cond_exec (ne (match_dup 7) (const_int 0))
4253      (parallel [(set (match_dup 3)
4254                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
4255                               (match_dup 4)))
4256                 (use (const_int 1))]))
4257    (cond_exec (ne (match_dup 7) (const_int 0))
4258      (parallel [(set (match_dup 5)
4259                      (minus:XF (match_dup 8)
4260                                (mult:XF (match_dup 2) (match_dup 0))))
4261                 (use (const_int 1))]))
4262    (cond_exec (ne (match_dup 7) (const_int 0))
4263      (parallel [(set (match_dup 0)
4264                      (plus:XF (mult:XF (match_dup 4) (match_dup 0))
4265                               (match_dup 0)))
4266                 (use (const_int 1))]))
4267    (cond_exec (ne (match_dup 7) (const_int 0))
4268      (parallel [(set (match_dup 4)
4269                      (minus:XF (match_dup 1)
4270                                (mult:XF (match_dup 2) (match_dup 3))))
4271                 (use (const_int 1))]))
4272    (cond_exec (ne (match_dup 7) (const_int 0))
4273      (set (match_dup 0)
4274           (plus:XF (mult:XF (match_dup 4) (match_dup 0))
4275                    (match_dup 3))))
4276   ] 
4277   "operands[8] = CONST1_RTX (XFmode);"
4278   [(set_attr "predicable" "no")])
4279
4280 (define_insn_and_split "divxf3_internal_thr"
4281   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4282         (div:XF (match_operand:XF 1 "fr_register_operand" "f")
4283                 (match_operand:XF 2 "fr_register_operand" "f")))
4284    (clobber (match_scratch:XF 3 "=&f"))
4285    (clobber (match_scratch:XF 4 "=&f"))
4286    (clobber (match_scratch:BI 5 "=c"))]
4287   "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR"
4288   "#"
4289   "&& reload_completed"
4290   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
4291               (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
4292                                             UNSPEC_FR_RECIP_APPROX))
4293               (use (const_int 0))])
4294    (cond_exec (ne (match_dup 5) (const_int 0))
4295      (parallel [(set (match_dup 3)
4296                      (minus:XF (match_dup 6)
4297                                (mult:XF (match_dup 2) (match_dup 0))))
4298                 (use (const_int 1))]))
4299    (cond_exec (ne (match_dup 5) (const_int 0))
4300      (parallel [(set (match_dup 4)
4301                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
4302                               (match_dup 0)))
4303                 (use (const_int 1))]))
4304    (cond_exec (ne (match_dup 5) (const_int 0))
4305      (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
4306                 (use (const_int 1))]))
4307    (cond_exec (ne (match_dup 5) (const_int 0))
4308      (parallel [(set (match_dup 3)
4309                      (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4310                               (match_dup 4)))
4311                 (use (const_int 1))]))
4312    (cond_exec (ne (match_dup 5) (const_int 0))
4313      (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
4314                 (use (const_int 1))]))
4315    (cond_exec (ne (match_dup 5) (const_int 0))
4316      (parallel [(set (match_dup 0)
4317                      (minus:XF (match_dup 6)
4318                                (mult:XF (match_dup 2) (match_dup 3))))
4319                 (use (const_int 1))]))
4320    (cond_exec (ne (match_dup 5) (const_int 0))
4321      (parallel [(set (match_dup 0)
4322                      (plus:XF (mult:XF (match_dup 0) (match_dup 3))
4323                               (match_dup 3)))
4324                 (use (const_int 1))]))
4325    (cond_exec (ne (match_dup 5) (const_int 0))
4326      (parallel [(set (match_dup 3)
4327                      (minus:XF (match_dup 1)
4328                                (mult:XF (match_dup 2) (match_dup 4))))
4329                 (use (const_int 1))]))
4330    (cond_exec (ne (match_dup 5) (const_int 0))
4331      (parallel [(set (match_dup 3)
4332                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
4333                               (match_dup 4)))
4334                 (use (const_int 1))]))
4335    (cond_exec (ne (match_dup 5) (const_int 0))
4336      (parallel [(set (match_dup 4)
4337                      (minus:XF (match_dup 6)
4338                                (mult:XF (match_dup 2) (match_dup 0))))
4339                 (use (const_int 1))]))
4340    (cond_exec (ne (match_dup 5) (const_int 0))
4341      (parallel [(set (match_dup 0)
4342                      (plus:XF (mult:XF (match_dup 4) (match_dup 0))
4343                               (match_dup 0)))
4344                 (use (const_int 1))]))
4345    (cond_exec (ne (match_dup 5) (const_int 0))
4346      (parallel [(set (match_dup 4)
4347                      (minus:XF (match_dup 1)
4348                                (mult:XF (match_dup 2) (match_dup 3))))
4349                 (use (const_int 1))]))
4350    (cond_exec (ne (match_dup 5) (const_int 0))
4351      (set (match_dup 0)
4352           (plus:XF (mult:XF (match_dup 4) (match_dup 0))
4353                    (match_dup 3))))
4354   ] 
4355   "operands[6] = CONST1_RTX (XFmode);"
4356   [(set_attr "predicable" "no")])
4357
4358 ;; Inline square root.
4359
4360 (define_expand "sqrtxf2"
4361   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4362         (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))]
4363   "TARGET_INLINE_SQRT"
4364 {
4365   rtx insn;
4366 #if 0
4367   if (TARGET_INLINE_SQRT == INL_MIN_LAT)
4368     insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
4369   else
4370 #else
4371   gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
4372 #endif
4373   insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]);
4374   emit_insn (insn);
4375   DONE;
4376 })
4377
4378 ;; Latency-optimized square root.
4379 ;; FIXME: Implement.
4380
4381 ;; Throughput-optimized square root.
4382
4383 (define_insn_and_split "sqrtxf2_internal_thr"
4384   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4385         (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))
4386    ;; Register r2 in optimization guide.
4387    (clobber (match_scratch:DI 2 "=r"))
4388    ;; Register f8 in optimization guide
4389    (clobber (match_scratch:XF 3 "=&f"))
4390    ;; Register f9 in optimization guide
4391    (clobber (match_scratch:XF 4 "=&f"))
4392    ;; Register f10 in optimization guide
4393    (clobber (match_scratch:XF 5 "=&f"))
4394    ;; Register f11 in optimization guide
4395    (clobber (match_scratch:XF 6 "=&f"))
4396    ;; Register p6 in optimization guide.
4397    (clobber (match_scratch:BI 7 "=c"))]
4398   "TARGET_INLINE_SQRT == INL_MAX_THR"
4399   "#"
4400   "&& reload_completed"
4401   [ ;; exponent of +1/2 in r2
4402     (set (match_dup 2) (const_int 65534))
4403     ;; +1/2 in f8.  The Intel manual mistakenly specifies f10.
4404     (set (match_dup 3) 
4405          (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
4406     ;; Step 1
4407     ;; y0 = 1/sqrt(a) in f7
4408     (parallel [(set (match_dup 8)
4409                     (div:XF (const_int 1)
4410                             (sqrt:XF (match_dup 9))))
4411                (set (match_dup 7)
4412                     (unspec:BI [(match_dup 9)]
4413                                  UNSPEC_FR_SQRT_RECIP_APPROX))
4414                (use (const_int 0))])
4415     ;; Step 2
4416     ;; H0 = 1/2 * y0 in f9
4417     (cond_exec (ne (match_dup 7) (const_int 0))
4418       (parallel [(set (match_dup 4)
4419                       (plus:XF (mult:XF (match_dup 3) (match_dup 8))
4420                                (match_dup 10)))
4421                  (use (const_int 1))]))
4422     ;; Step 3
4423     ;; S0 = a * y0 in f7
4424     (cond_exec (ne (match_dup 7) (const_int 0))
4425       (parallel [(set (match_dup 8)
4426                       (plus:XF (mult:XF (match_dup 9) (match_dup 8))
4427                                (match_dup 10)))
4428                  (use (const_int 1))]))
4429     ;; Step 4
4430     ;; d0 = 1/2 - S0 * H0 in f10
4431     (cond_exec (ne (match_dup 7) (const_int 0))
4432       (parallel [(set (match_dup 5)
4433                       (minus:XF (match_dup 3)
4434                                 (mult:XF (match_dup 8) (match_dup 4))))
4435                  (use (const_int 1))]))
4436     ;; Step 5
4437     ;; H1 = H0 + d0 * H0 in f9
4438     (cond_exec (ne (match_dup 7) (const_int 0))
4439        (parallel [(set (match_dup 4)
4440                        (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4441                                 (match_dup 4)))
4442                   (use (const_int 1))]))
4443     ;; Step 6
4444     ;; S1 = S0 + d0 * S0 in f7
4445     (cond_exec (ne (match_dup 7) (const_int 0))
4446        (parallel [(set (match_dup 8)
4447                        (plus:XF (mult:XF (match_dup 5) (match_dup 8))
4448                                 (match_dup 8)))
4449                   (use (const_int 1))]))
4450     ;; Step 7
4451     ;; d1 = 1/2 - S1 * H1 in f10
4452     (cond_exec (ne (match_dup 7) (const_int 0))
4453       (parallel [(set (match_dup 5)
4454                       (minus:XF (match_dup 3)
4455                                 (mult:XF (match_dup 8) (match_dup 4))))
4456                  (use (const_int 1))]))
4457     ;; Step 8
4458     ;; H2 = H1 + d1 * H1 in f9
4459     (cond_exec (ne (match_dup 7) (const_int 0))
4460        (parallel [(set (match_dup 4)
4461                        (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4462                                 (match_dup 4)))
4463                   (use (const_int 1))]))
4464     ;; Step 9 
4465     ;; S2 = S1 + d1 * S1 in f7
4466     (cond_exec (ne (match_dup 7) (const_int 0))
4467        (parallel [(set (match_dup 8)
4468                        (plus:XF (mult:XF (match_dup 5) (match_dup 8))
4469                                 (match_dup 8)))
4470                   (use (const_int 1))]))
4471     ;; Step 10
4472     ;; d2 = 1/2 - S2 * H2 in f10
4473     (cond_exec (ne (match_dup 7) (const_int 0))
4474        (parallel [(set (match_dup 5)
4475                        (minus:XF (match_dup 3)
4476                                  (mult:XF (match_dup 8) (match_dup 4))))
4477                   (use (const_int 1))]))
4478     ;; Step 11
4479     ;; e2 = a - S2 * S2 in f8
4480     (cond_exec (ne (match_dup 7) (const_int 0))
4481        (parallel [(set (match_dup 3)
4482                        (minus:XF (match_dup 9)
4483                                  (mult:XF (match_dup 8) (match_dup 8))))
4484                   (use (const_int 1))]))
4485     ;; Step 12
4486     ;; S3 = S2 + e2 * H2 in f7
4487     (cond_exec (ne (match_dup 7) (const_int 0))
4488        (parallel [(set (match_dup 8)
4489                        (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4490                                 (match_dup 8)))
4491                   (use (const_int 1))]))
4492     ;; Step 13
4493     ;; H3 = H2 + d2 * H2 in f9
4494     (cond_exec (ne (match_dup 7) (const_int 0))
4495        (parallel [(set (match_dup 4)
4496                        (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4497                                 (match_dup 4)))
4498                   (use (const_int 1))]))
4499     ;; Step 14
4500     ;; e3 = a - S3 * S3 in f8
4501     (cond_exec (ne (match_dup 7) (const_int 0))
4502        (parallel [(set (match_dup 3)
4503                        (minus:XF (match_dup 9)
4504                                  (mult:XF (match_dup 8) (match_dup 8))))
4505                   (use (const_int 1))]))
4506     ;; Step 15
4507     ;; S = S3 + e3 * H3 in f7
4508     (cond_exec (ne (match_dup 7) (const_int 0))
4509        (parallel [(set (match_dup 0)
4510                        (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4511                                 (match_dup 8)))
4512                   (use (const_int 0))]))]
4513 {
4514   /* Generate 82-bit versions of the input and output operands.  */
4515   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0]));
4516   operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1]));
4517   /* Generate required floating-point constants.  */
4518   operands[10] = CONST0_RTX (XFmode);
4519 }
4520   [(set_attr "predicable" "no")])
4521
4522 ;; ??? frcpa works like cmp.foo.unc.
4523
4524 (define_insn "*recip_approx"
4525   [(set (match_operand:XF 0 "fr_register_operand" "=f")
4526         (div:XF (const_int 1)
4527                 (match_operand:XF 3 "fr_register_operand" "f")))
4528    (set (match_operand:BI 1 "register_operand" "=c")
4529         (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f")
4530                     (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
4531    (use (match_operand:SI 4 "const_int_operand" ""))]
4532   ""
4533   "frcpa.s%4 %0, %1 = %2, %3"
4534   [(set_attr "itanium_class" "fmisc")
4535    (set_attr "predicable" "no")])
4536 \f
4537 ;; ::::::::::::::::::::
4538 ;; ::
4539 ;; :: 32-bit Integer Shifts and Rotates
4540 ;; ::
4541 ;; ::::::::::::::::::::
4542
4543 (define_expand "ashlsi3"
4544   [(set (match_operand:SI 0 "gr_register_operand" "")
4545         (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
4546                    (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4547   ""
4548 {
4549   if (GET_CODE (operands[2]) != CONST_INT)
4550     {
4551       /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
4552          we've got to get rid of stray bits outside the SImode register.  */
4553       rtx subshift = gen_reg_rtx (DImode);
4554       emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4555       operands[2] = subshift;
4556     }
4557 })
4558
4559 (define_insn "*ashlsi3_internal"
4560   [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
4561         (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
4562                    (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
4563   ""
4564   "@
4565    shladd %0 = %1, %2, r0
4566    dep.z %0 = %1, %2, %E2
4567    shl %0 = %1, %2"
4568   [(set_attr "itanium_class" "ialu,ishf,mmshf")])
4569
4570 (define_expand "ashrsi3"
4571   [(set (match_operand:SI 0 "gr_register_operand" "")
4572         (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
4573                      (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4574   ""
4575 {
4576   rtx subtarget = gen_reg_rtx (DImode);
4577   if (GET_CODE (operands[2]) == CONST_INT)
4578     emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
4579                          GEN_INT (32 - INTVAL (operands[2])), operands[2]));
4580   else
4581     {
4582       rtx subshift = gen_reg_rtx (DImode);
4583       emit_insn (gen_extendsidi2 (subtarget, operands[1]));
4584       emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4585       emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
4586     }
4587   emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
4588   DONE;
4589 })
4590
4591 (define_expand "lshrsi3"
4592   [(set (match_operand:SI 0 "gr_register_operand" "")
4593         (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
4594                      (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4595   ""
4596 {
4597   rtx subtarget = gen_reg_rtx (DImode);
4598   if (GET_CODE (operands[2]) == CONST_INT)
4599     emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
4600                           GEN_INT (32 - INTVAL (operands[2])), operands[2]));
4601   else
4602     {
4603       rtx subshift = gen_reg_rtx (DImode);
4604       emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
4605       emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4606       emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
4607     }
4608   emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
4609   DONE;
4610 })
4611
4612 ;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
4613 ;; here, instead of 64 like the patterns above.  Keep the pattern together
4614 ;; until after combine; otherwise it won't get matched often.
4615
4616 (define_expand "rotrsi3"
4617   [(set (match_operand:SI 0 "gr_register_operand" "")
4618         (rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
4619                      (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4620   ""
4621 {
4622   if (GET_MODE (operands[2]) != VOIDmode)
4623     {
4624       rtx tmp = gen_reg_rtx (DImode);
4625       emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
4626       operands[2] = tmp;
4627     }
4628 })
4629
4630 (define_insn_and_split "*rotrsi3_internal"
4631   [(set (match_operand:SI 0 "gr_register_operand" "=&r")
4632         (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
4633                      (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
4634   ""
4635   "#"
4636   "reload_completed"
4637   [(set (match_dup 3)
4638         (ior:DI (zero_extend:DI (match_dup 1))
4639                 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
4640    (set (match_dup 3)
4641         (lshiftrt:DI (match_dup 3) (match_dup 2)))]
4642   "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
4643
4644 (define_expand "rotlsi3"
4645   [(set (match_operand:SI 0 "gr_register_operand" "")
4646         (rotate:SI (match_operand:SI 1 "gr_register_operand" "")
4647                    (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4648   ""
4649 {
4650   if (! shift_32bit_count_operand (operands[2], SImode))
4651     {
4652       rtx tmp = gen_reg_rtx (SImode);
4653       emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
4654       emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
4655       DONE;
4656     }
4657 })
4658
4659 (define_insn_and_split "*rotlsi3_internal"
4660   [(set (match_operand:SI 0 "gr_register_operand" "=r")
4661         (rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
4662                    (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
4663   ""
4664   "mux2 %0 = %1, 0xe1"
4665   "reload_completed && INTVAL (operands[2]) != 16"
4666   [(set (match_dup 3)
4667         (ior:DI (zero_extend:DI (match_dup 1))
4668                 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
4669    (set (match_dup 3)
4670         (lshiftrt:DI (match_dup 3) (match_dup 2)))]
4671 {
4672   operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
4673   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4674 }
4675   [(set_attr "itanium_class" "mmshf")])
4676 \f
4677 ;; ::::::::::::::::::::
4678 ;; ::
4679 ;; :: 64-bit Integer Shifts and Rotates
4680 ;; ::
4681 ;; ::::::::::::::::::::
4682
4683 (define_insn "ashldi3"
4684   [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
4685         (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
4686                    (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
4687   ""
4688   "@
4689    shladd %0 = %1, %2, r0
4690    shl %0 = %1, %2
4691    shl %0 = %1, %2"
4692   [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
4693
4694 ;; ??? Maybe combine this with the multiply and add instruction?
4695
4696 (define_insn "*shladd"
4697   [(set (match_operand:DI 0 "gr_register_operand" "=r")
4698         (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
4699                           (match_operand:DI 2 "shladd_operand" "n"))
4700                  (match_operand:DI 3 "gr_register_operand" "r")))]
4701   ""
4702   "shladd %0 = %1, %S2, %3"
4703   [(set_attr "itanium_class" "ialu")])
4704
4705 ;; This can be created by register elimination if operand3 of shladd is an
4706 ;; eliminable register or has reg_equiv_constant set.
4707
4708 ;; We have to use nonmemory_operand for operand 4, to ensure that the
4709 ;; validate_changes call inside eliminate_regs will always succeed.  If it
4710 ;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
4711 ;; incorrectly.
4712
4713 (define_insn_and_split "*shladd_elim"
4714   [(set (match_operand:DI 0 "gr_register_operand" "=&r")
4715         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
4716                                    (match_operand:DI 2 "shladd_operand" "n"))
4717                           (match_operand:DI 3 "nonmemory_operand" "r"))
4718                  (match_operand:DI 4 "nonmemory_operand" "rI")))]
4719   "reload_in_progress"
4720   "* gcc_unreachable ();"
4721   "reload_completed"
4722   [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
4723                                (match_dup 3)))
4724    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4725   ""
4726   [(set_attr "itanium_class" "unknown")])
4727
4728 (define_insn "ashrdi3"
4729   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4730         (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
4731                      (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
4732   ""
4733   "@
4734    shr %0 = %1, %2
4735    shr %0 = %1, %2"
4736   [(set_attr "itanium_class" "mmshf,mmshfi")])
4737
4738 (define_insn "lshrdi3"
4739   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4740         (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
4741                      (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
4742   ""
4743   "@
4744    shr.u %0 = %1, %2
4745    shr.u %0 = %1, %2"
4746   [(set_attr "itanium_class" "mmshf,mmshfi")])
4747
4748 ;; Using a predicate that accepts only constants doesn't work, because optabs
4749 ;; will load the operand into a register and call the pattern if the predicate
4750 ;; did not accept it on the first try.  So we use nonmemory_operand and then
4751 ;; verify that we have an appropriate constant in the expander.
4752
4753 (define_expand "rotrdi3"
4754   [(set (match_operand:DI 0 "gr_register_operand" "")
4755         (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
4756                      (match_operand:DI 2 "nonmemory_operand" "")))]
4757   ""
4758 {
4759   if (! shift_count_operand (operands[2], DImode))
4760     FAIL;
4761 })
4762
4763 (define_insn "*rotrdi3_internal"
4764   [(set (match_operand:DI 0 "gr_register_operand" "=r")
4765         (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
4766                      (match_operand:DI 2 "shift_count_operand" "M")))]
4767   ""
4768   "shrp %0 = %1, %1, %2"
4769   [(set_attr "itanium_class" "ishf")])
4770
4771 (define_expand "rotldi3"
4772   [(set (match_operand:DI 0 "gr_register_operand" "")
4773         (rotate:DI (match_operand:DI 1 "gr_register_operand" "")
4774                    (match_operand:DI 2 "nonmemory_operand" "")))]
4775   ""
4776 {
4777   if (! shift_count_operand (operands[2], DImode))
4778     FAIL;
4779 })
4780
4781 (define_insn "*rotldi3_internal"
4782   [(set (match_operand:DI 0 "gr_register_operand" "=r")
4783         (rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
4784                    (match_operand:DI 2 "shift_count_operand" "M")))]
4785   ""
4786   "shrp %0 = %1, %1, %e2"
4787   [(set_attr "itanium_class" "ishf")])
4788 \f
4789 ;; ::::::::::::::::::::
4790 ;; ::
4791 ;; :: 128-bit Integer Shifts and Rotates
4792 ;; ::
4793 ;; ::::::::::::::::::::
4794
4795 (define_expand "ashlti3"
4796   [(set (match_operand:TI 0 "gr_register_operand" "")
4797         (ashift:TI (match_operand:TI 1 "gr_register_operand" "")
4798                    (match_operand:DI 2 "nonmemory_operand" "")))]
4799   ""
4800 {
4801   if (!dshift_count_operand (operands[2], DImode))
4802     FAIL;
4803 })
4804
4805 (define_insn_and_split "*ashlti3_internal"
4806   [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4807         (ashift:TI (match_operand:TI 1 "gr_register_operand" "r")
4808                    (match_operand:DI 2 "dshift_count_operand" "n")))]
4809   ""
4810   "#"
4811   "reload_completed"
4812   [(const_int 0)]
4813 {
4814   HOST_WIDE_INT shift = INTVAL (operands[2]);
4815   rtx rl = gen_lowpart (DImode, operands[0]);
4816   rtx rh = gen_highpart (DImode, operands[0]);
4817   rtx lo = gen_lowpart (DImode, operands[1]);
4818   rtx shiftlo = GEN_INT (shift & 63);
4819
4820   if (shift & 64)
4821     {
4822       emit_move_insn (rl, const0_rtx);
4823       if (shift & 63)
4824         emit_insn (gen_ashldi3 (rh, lo, shiftlo));
4825       else
4826         emit_move_insn (rh, lo);
4827     }
4828   else
4829     {
4830       rtx hi = gen_highpart (DImode, operands[1]);
4831
4832       emit_insn (gen_shrp (rh, hi, lo, GEN_INT (-shift & 63)));
4833       emit_insn (gen_ashldi3 (rl, lo, shiftlo));
4834     }
4835   DONE;
4836 })
4837
4838 (define_expand "ashrti3"
4839   [(set (match_operand:TI 0 "gr_register_operand" "")
4840         (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
4841                      (match_operand:DI 2 "nonmemory_operand" "")))]
4842   ""
4843 {
4844   if (!dshift_count_operand (operands[2], DImode))
4845     FAIL;
4846 })
4847
4848 (define_insn_and_split "*ashrti3_internal"
4849   [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4850         (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
4851                      (match_operand:DI 2 "dshift_count_operand" "n")))]
4852   ""
4853   "#"
4854   "reload_completed"
4855   [(const_int 0)]
4856 {
4857   HOST_WIDE_INT shift = INTVAL (operands[2]);
4858   rtx rl = gen_lowpart (DImode, operands[0]);
4859   rtx rh = gen_highpart (DImode, operands[0]);
4860   rtx hi = gen_highpart (DImode, operands[1]);
4861   rtx shiftlo = GEN_INT (shift & 63);
4862
4863   if (shift & 64)
4864     {
4865       if (shift & 63)
4866         emit_insn (gen_ashrdi3 (rl, hi, shiftlo));
4867       else
4868         emit_move_insn (rl, hi);
4869       emit_insn (gen_ashrdi3 (rh, hi, GEN_INT (63)));
4870     }
4871   else
4872     {
4873       rtx lo = gen_lowpart (DImode, operands[1]);
4874
4875       emit_insn (gen_shrp (rl, hi, lo, shiftlo));
4876       emit_insn (gen_ashrdi3 (rh, hi, shiftlo));
4877     }
4878   DONE;
4879 })
4880
4881 (define_expand "lshrti3"
4882   [(set (match_operand:TI 0 "gr_register_operand" "")
4883         (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
4884                      (match_operand:DI 2 "nonmemory_operand" "")))]
4885   ""
4886
4887   if (!dshift_count_operand (operands[2], DImode))
4888     FAIL;
4889 }) 
4890
4891 (define_insn_and_split "*lshrti3_internal"
4892   [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4893         (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
4894                      (match_operand:DI 2 "dshift_count_operand" "n")))]
4895   ""
4896   "#"
4897   "reload_completed"
4898   [(const_int 0)]
4899 {
4900   HOST_WIDE_INT shift = INTVAL (operands[2]);
4901   rtx rl = gen_lowpart (DImode, operands[0]);
4902   rtx rh = gen_highpart (DImode, operands[0]);
4903   rtx hi = gen_highpart (DImode, operands[1]);
4904   rtx shiftlo = GEN_INT (shift & 63);
4905
4906   if (shift & 64)
4907     {
4908       if (shift & 63)
4909         emit_insn (gen_lshrdi3 (rl, hi, shiftlo));
4910       else
4911         emit_move_insn (rl, hi);
4912       emit_move_insn (rh, const0_rtx);
4913     }
4914   else
4915     {
4916       rtx lo = gen_lowpart (DImode, operands[1]);
4917
4918       emit_insn (gen_shrp (rl, hi, lo, shiftlo));
4919       emit_insn (gen_lshrdi3 (rh, hi, shiftlo));
4920     }
4921   DONE;
4922 })
4923
4924 (define_expand "rotlti3"
4925   [(set (match_operand:TI 0 "gr_register_operand" "")
4926         (rotate:TI (match_operand:TI 1 "gr_register_operand" "")
4927                    (match_operand:DI 2 "nonmemory_operand" "")))]
4928   ""
4929 {
4930   if (! dshift_count_operand (operands[2], DImode))
4931     FAIL;
4932 })
4933
4934 (define_insn_and_split "*rotlti3_internal"
4935   [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4936         (rotate:TI (match_operand:TI 1 "gr_register_operand" "r")
4937                    (match_operand:DI 2 "dshift_count_operand" "n")))]
4938   ""
4939   "#"
4940   "reload_completed"
4941   [(const_int 0)]
4942 {
4943   HOST_WIDE_INT count = INTVAL (operands[2]);
4944   rtx rl = gen_lowpart (DImode, operands[0]);
4945   rtx rh = gen_highpart (DImode, operands[0]);
4946   rtx lo = gen_lowpart (DImode, operands[1]);
4947   rtx hi = gen_highpart (DImode, operands[1]);
4948   rtx countlo = GEN_INT (-count & 63);
4949
4950   if (count & 64)
4951     {
4952       if (count & 63)
4953         {
4954           emit_insn (gen_shrp (rl, hi, lo, countlo));
4955           emit_insn (gen_shrp (rh, lo, hi, countlo));
4956         }
4957       else
4958         {
4959           emit_move_insn (rl, hi);
4960           emit_move_insn (rh, lo);
4961         }
4962     }
4963   else
4964     {
4965       emit_insn (gen_shrp (rl, lo, hi, countlo));
4966       emit_insn (gen_shrp (rh, hi, lo, countlo));
4967     }
4968   DONE;
4969 }
4970   [(set_attr "itanium_class" "unknown")])
4971
4972 (define_insn "shrp"
4973   [(set (match_operand:DI 0 "gr_register_operand" "=r")
4974         (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")
4975                     (match_operand:DI 2 "gr_register_operand" "r")
4976                     (match_operand:DI 3 "shift_count_operand" "M")]
4977                    UNSPEC_SHRP))]
4978   ""
4979   "shrp %0 = %1, %2, %3"
4980   [(set_attr "itanium_class" "ishf")])
4981 \f
4982 ;; ::::::::::::::::::::
4983 ;; ::
4984 ;; :: 32-bit Integer Logical operations
4985 ;; ::
4986 ;; ::::::::::::::::::::
4987
4988 ;; We don't seem to need any other 32-bit logical operations, because gcc
4989 ;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
4990 ;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
4991 ;; This doesn't work for unary logical operations, because we don't call
4992 ;; apply_distributive_law for them.
4993
4994 ;; ??? Likewise, this doesn't work for andnot, which isn't handled by
4995 ;; apply_distributive_law.  We get inefficient code for
4996 ;; int sub4 (int i, int j) { return i & ~j; }
4997 ;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
4998 ;; (zero_extend (and (not A) B)) in combine.
4999 ;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
5000 ;; one_cmplsi2 pattern.
5001
5002 (define_insn "one_cmplsi2"
5003   [(set (match_operand:SI 0 "gr_register_operand" "=r")
5004         (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
5005   ""
5006   "andcm %0 = -1, %1"
5007   [(set_attr "itanium_class" "ilog")])
5008 \f
5009 ;; ::::::::::::::::::::
5010 ;; ::
5011 ;; :: 64-bit Integer Logical operations
5012 ;; ::
5013 ;; ::::::::::::::::::::
5014
5015 (define_insn "anddi3"
5016   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
5017         (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
5018                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
5019   ""
5020   "@
5021    and %0 = %2, %1
5022    fand %0 = %2, %1"
5023   [(set_attr "itanium_class" "ilog,fmisc")])
5024
5025 (define_insn "*andnot"
5026   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
5027         (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
5028                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
5029   ""
5030   "@
5031    andcm %0 = %2, %1
5032    fandcm %0 = %2, %1"
5033   [(set_attr "itanium_class" "ilog,fmisc")])
5034
5035 (define_insn "iordi3"
5036   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
5037         (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
5038                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
5039   ""
5040   "@
5041    or %0 = %2, %1
5042    for %0 = %2, %1"
5043   [(set_attr "itanium_class" "ilog,fmisc")])
5044
5045 (define_insn "xordi3"
5046   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
5047         (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
5048                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
5049   ""
5050   "@
5051    xor %0 = %2, %1
5052    fxor %0 = %2, %1"
5053   [(set_attr "itanium_class" "ilog,fmisc")])
5054
5055 (define_insn "one_cmpldi2"
5056   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5057         (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
5058   ""
5059   "andcm %0 = -1, %1"
5060   [(set_attr "itanium_class" "ilog")])
5061 \f
5062 ;; ::::::::::::::::::::
5063 ;; ::
5064 ;; :: Comparisons
5065 ;; ::
5066 ;; ::::::::::::::::::::
5067
5068 (define_expand "cmpbi"
5069   [(set (cc0)
5070         (compare (match_operand:BI 0 "register_operand" "")
5071                  (match_operand:BI 1 "const_int_operand" "")))]
5072   ""
5073 {
5074   ia64_compare_op0 = operands[0];
5075   ia64_compare_op1 = operands[1];
5076   DONE;
5077 })
5078
5079 (define_expand "cmpsi"
5080   [(set (cc0)
5081         (compare (match_operand:SI 0 "gr_register_operand" "")
5082                  (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
5083   ""
5084 {
5085   ia64_compare_op0 = operands[0];
5086   ia64_compare_op1 = operands[1];
5087   DONE;
5088 })
5089
5090 (define_expand "cmpdi"
5091   [(set (cc0)
5092         (compare (match_operand:DI 0 "gr_register_operand" "")
5093                  (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
5094   ""
5095 {
5096   ia64_compare_op0 = operands[0];
5097   ia64_compare_op1 = operands[1];
5098   DONE;
5099 })
5100
5101 (define_expand "cmpsf"
5102   [(set (cc0)
5103         (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
5104                  (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
5105   ""
5106 {
5107   ia64_compare_op0 = operands[0];
5108   ia64_compare_op1 = operands[1];
5109   DONE;
5110 })
5111
5112 (define_expand "cmpdf"
5113   [(set (cc0)
5114         (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
5115                  (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
5116   ""
5117 {
5118   ia64_compare_op0 = operands[0];
5119   ia64_compare_op1 = operands[1];
5120   DONE;
5121 })
5122
5123 (define_expand "cmpxf"
5124   [(set (cc0)
5125         (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
5126                  (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
5127   ""
5128 {
5129   ia64_compare_op0 = operands[0];
5130   ia64_compare_op1 = operands[1];
5131   DONE;
5132 })
5133
5134 (define_expand "cmptf"
5135   [(set (cc0)
5136         (compare (match_operand:TF 0 "gr_register_operand" "")
5137                  (match_operand:TF 1 "gr_register_operand" "")))]
5138   "TARGET_HPUX"
5139 {
5140   ia64_compare_op0 = operands[0];
5141   ia64_compare_op1 = operands[1];
5142   DONE;
5143 })
5144
5145 (define_insn "*cmpsi_normal"
5146   [(set (match_operand:BI 0 "register_operand" "=c")
5147         (match_operator:BI 1 "normal_comparison_operator"
5148            [(match_operand:SI 2 "gr_register_operand" "r")
5149             (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
5150   ""
5151   "cmp4.%C1 %0, %I0 = %3, %2"
5152   [(set_attr "itanium_class" "icmp")])
5153
5154 ;; We use %r3 because it is possible for us to match a 0, and two of the
5155 ;; unsigned comparisons don't accept immediate operands of zero.
5156
5157 (define_insn "*cmpsi_adjusted"
5158   [(set (match_operand:BI 0 "register_operand" "=c")
5159         (match_operator:BI 1 "adjusted_comparison_operator"
5160            [(match_operand:SI 2 "gr_register_operand" "r")
5161             (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
5162   ""
5163   "cmp4.%C1 %0, %I0 = %r3, %2"
5164   [(set_attr "itanium_class" "icmp")])
5165
5166 (define_insn "*cmpdi_normal"
5167   [(set (match_operand:BI 0 "register_operand" "=c")
5168         (match_operator:BI 1 "normal_comparison_operator"
5169            [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
5170             (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
5171   ""
5172   "cmp.%C1 %0, %I0 = %3, %r2"
5173   [(set_attr "itanium_class" "icmp")])
5174
5175 ;; We use %r3 because it is possible for us to match a 0, and two of the
5176 ;; unsigned comparisons don't accept immediate operands of zero.
5177
5178 (define_insn "*cmpdi_adjusted"
5179   [(set (match_operand:BI 0 "register_operand" "=c")
5180         (match_operator:BI 1 "adjusted_comparison_operator"
5181            [(match_operand:DI 2 "gr_register_operand" "r")
5182             (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
5183   ""
5184   "cmp.%C1 %0, %I0 = %r3, %2"
5185   [(set_attr "itanium_class" "icmp")])
5186
5187 (define_insn "*cmpsf_internal"
5188   [(set (match_operand:BI 0 "register_operand" "=c")
5189         (match_operator:BI 1 "comparison_operator"
5190            [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
5191             (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
5192   ""
5193   "fcmp.%D1 %0, %I0 = %F2, %F3"
5194   [(set_attr "itanium_class" "fcmp")])
5195
5196 (define_insn "*cmpdf_internal"
5197   [(set (match_operand:BI 0 "register_operand" "=c")
5198         (match_operator:BI 1 "comparison_operator"
5199            [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
5200             (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
5201   ""
5202   "fcmp.%D1 %0, %I0 = %F2, %F3"
5203   [(set_attr "itanium_class" "fcmp")])
5204
5205 (define_insn "*cmpxf_internal"
5206   [(set (match_operand:BI 0 "register_operand" "=c")
5207         (match_operator:BI 1 "comparison_operator"
5208                    [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
5209                     (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
5210   ""
5211   "fcmp.%D1 %0, %I0 = %F2, %F3"
5212   [(set_attr "itanium_class" "fcmp")])
5213
5214 ;; ??? Can this pattern be generated?
5215
5216 (define_insn "*bit_zero"
5217   [(set (match_operand:BI 0 "register_operand" "=c")
5218         (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
5219                                 (const_int 1)
5220                                 (match_operand:DI 2 "shift_count_operand" "M"))
5221                (const_int 0)))]
5222   ""
5223   "tbit.z %0, %I0 = %1, %2"
5224   [(set_attr "itanium_class" "tbit")])
5225
5226 (define_insn "*bit_one"
5227   [(set (match_operand:BI 0 "register_operand" "=c")
5228         (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
5229                                 (const_int 1)
5230                                 (match_operand:DI 2 "shift_count_operand" "M"))
5231                (const_int 0)))]
5232   ""
5233   "tbit.nz %0, %I0 = %1, %2"
5234   [(set_attr "itanium_class" "tbit")])
5235 \f
5236 ;; ::::::::::::::::::::
5237 ;; ::
5238 ;; :: Branches
5239 ;; ::
5240 ;; ::::::::::::::::::::
5241
5242 (define_expand "beq"
5243   [(set (pc)
5244         (if_then_else (match_dup 1)
5245                       (label_ref (match_operand 0 "" ""))
5246                       (pc)))]
5247   ""
5248   "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
5249
5250 (define_expand "bne"
5251   [(set (pc)
5252         (if_then_else (match_dup 1)
5253                       (label_ref (match_operand 0 "" ""))
5254                       (pc)))]
5255   ""
5256   "operands[1] = ia64_expand_compare (NE, VOIDmode);")
5257
5258 (define_expand "blt"
5259   [(set (pc)
5260         (if_then_else (match_dup 1)
5261                       (label_ref (match_operand 0 "" ""))
5262                       (pc)))]
5263   ""
5264   "operands[1] = ia64_expand_compare (LT, VOIDmode);")
5265
5266 (define_expand "ble"
5267   [(set (pc)
5268         (if_then_else (match_dup 1)
5269                       (label_ref (match_operand 0 "" ""))
5270                       (pc)))]
5271   ""
5272   "operands[1] = ia64_expand_compare (LE, VOIDmode);")
5273
5274 (define_expand "bgt"
5275   [(set (pc)
5276         (if_then_else (match_dup 1)
5277                       (label_ref (match_operand 0 "" ""))
5278                       (pc)))]
5279   ""
5280   "operands[1] = ia64_expand_compare (GT, VOIDmode);")
5281
5282 (define_expand "bge"
5283   [(set (pc)
5284         (if_then_else (match_dup 1)
5285                       (label_ref (match_operand 0 "" ""))
5286                       (pc)))]
5287   ""
5288   "operands[1] = ia64_expand_compare (GE, VOIDmode);")
5289
5290 (define_expand "bltu"
5291   [(set (pc)
5292         (if_then_else (match_dup 1)
5293                       (label_ref (match_operand 0 "" ""))
5294                       (pc)))]
5295   ""
5296   "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
5297
5298 (define_expand "bleu"
5299   [(set (pc)
5300         (if_then_else (match_dup 1)
5301                       (label_ref (match_operand 0 "" ""))
5302                       (pc)))]
5303   ""
5304   "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
5305
5306 (define_expand "bgtu"
5307   [(set (pc)
5308         (if_then_else (match_dup 1)
5309                       (label_ref (match_operand 0 "" ""))
5310                       (pc)))]
5311   ""
5312   "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
5313
5314 (define_expand "bgeu"
5315   [(set (pc)
5316         (if_then_else (match_dup 1)
5317                       (label_ref (match_operand 0 "" ""))
5318                       (pc)))]
5319   ""
5320   "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
5321
5322 (define_expand "bunordered"
5323   [(set (pc)
5324         (if_then_else (match_dup 1)
5325                       (label_ref (match_operand 0 "" ""))
5326                       (pc)))]
5327   ""
5328   "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
5329
5330 (define_expand "bordered"
5331   [(set (pc)
5332         (if_then_else (match_dup 1)
5333                       (label_ref (match_operand 0 "" ""))
5334                       (pc)))]
5335   ""
5336   "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
5337
5338 (define_insn "*br_true"
5339   [(set (pc)
5340         (if_then_else (match_operator 0 "predicate_operator"
5341                         [(match_operand:BI 1 "register_operand" "c")
5342                          (const_int 0)])
5343                       (label_ref (match_operand 2 "" ""))
5344                       (pc)))]
5345   ""
5346   "(%J0) br.cond%+ %l2"
5347   [(set_attr "itanium_class" "br")
5348    (set_attr "predicable" "no")])
5349
5350 (define_insn "*br_false"
5351   [(set (pc)
5352         (if_then_else (match_operator 0 "predicate_operator"
5353                         [(match_operand:BI 1 "register_operand" "c")
5354                          (const_int 0)])
5355                       (pc)
5356                       (label_ref (match_operand 2 "" ""))))]
5357   ""
5358   "(%j0) br.cond%+ %l2"
5359   [(set_attr "itanium_class" "br")
5360    (set_attr "predicable" "no")])
5361 \f
5362 ;; ::::::::::::::::::::
5363 ;; ::
5364 ;; :: Counted loop operations
5365 ;; ::
5366 ;; ::::::::::::::::::::
5367
5368 (define_expand "doloop_end"
5369   [(use (match_operand 0 "" ""))        ; loop pseudo
5370    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
5371    (use (match_operand 2 "" ""))        ; max iterations
5372    (use (match_operand 3 "" ""))        ; loop level
5373    (use (match_operand 4 "" ""))]       ; label
5374   ""
5375 {
5376   /* Only use cloop on innermost loops.  */
5377   if (INTVAL (operands[3]) > 1)
5378     FAIL;
5379   emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
5380                                            operands[4]));
5381   DONE;
5382 })
5383
5384 (define_insn "doloop_end_internal"
5385   [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
5386                                (const_int 0))
5387                 (label_ref (match_operand 1 "" ""))
5388                 (pc)))
5389    (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
5390                          (plus:DI (match_dup 0) (const_int -1))
5391                          (match_dup 0)))]
5392   ""
5393   "br.cloop.sptk.few %l1"
5394   [(set_attr "itanium_class" "br")
5395    (set_attr "predicable" "no")])
5396 \f
5397 ;; ::::::::::::::::::::
5398 ;; ::
5399 ;; :: Set flag operations
5400 ;; ::
5401 ;; ::::::::::::::::::::
5402
5403 (define_expand "seq"
5404   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5405   ""
5406   "operands[1] = ia64_expand_compare (EQ, DImode);")
5407
5408 (define_expand "sne"
5409   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5410   ""
5411   "operands[1] = ia64_expand_compare (NE, DImode);")
5412
5413 (define_expand "slt"
5414   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5415   ""
5416   "operands[1] = ia64_expand_compare (LT, DImode);")
5417
5418 (define_expand "sle"
5419   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5420   ""
5421   "operands[1] = ia64_expand_compare (LE, DImode);")
5422
5423 (define_expand "sgt"
5424   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5425   ""
5426   "operands[1] = ia64_expand_compare (GT, DImode);")
5427
5428 (define_expand "sge"
5429   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5430   ""
5431   "operands[1] = ia64_expand_compare (GE, DImode);")
5432
5433 (define_expand "sltu"
5434   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5435   ""
5436   "operands[1] = ia64_expand_compare (LTU, DImode);")
5437
5438 (define_expand "sleu"
5439   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5440   ""
5441   "operands[1] = ia64_expand_compare (LEU, DImode);")
5442
5443 (define_expand "sgtu"
5444   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5445   ""
5446   "operands[1] = ia64_expand_compare (GTU, DImode);")
5447
5448 (define_expand "sgeu"
5449   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5450   ""
5451   "operands[1] = ia64_expand_compare (GEU, DImode);")
5452
5453 (define_expand "sunordered"
5454   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5455   ""
5456   "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
5457
5458 (define_expand "sordered"
5459   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
5460   ""
5461   "operands[1] = ia64_expand_compare (ORDERED, DImode);")
5462
5463 ;; Don't allow memory as destination here, because cmov/cmov/st is more
5464 ;; efficient than mov/mov/cst/cst.
5465
5466 (define_insn_and_split "*sne_internal"
5467   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5468         (ne:DI (match_operand:BI 1 "register_operand" "c")
5469                (const_int 0)))]
5470   ""
5471   "#"
5472   "reload_completed"
5473   [(cond_exec (ne (match_dup 1) (const_int 0))
5474      (set (match_dup 0) (const_int 1)))
5475    (cond_exec (eq (match_dup 1) (const_int 0))
5476      (set (match_dup 0) (const_int 0)))]
5477   ""
5478   [(set_attr "itanium_class" "unknown")])
5479
5480 (define_insn_and_split "*seq_internal"
5481   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5482         (eq:DI (match_operand:BI 1 "register_operand" "c")
5483                (const_int 0)))]
5484   ""
5485   "#"
5486   "reload_completed"
5487   [(cond_exec (ne (match_dup 1) (const_int 0))
5488      (set (match_dup 0) (const_int 0)))
5489    (cond_exec (eq (match_dup 1) (const_int 0))
5490      (set (match_dup 0) (const_int 1)))]
5491   ""
5492   [(set_attr "itanium_class" "unknown")])
5493 \f
5494 ;; ::::::::::::::::::::
5495 ;; ::
5496 ;; :: Conditional move instructions.
5497 ;; ::
5498 ;; ::::::::::::::::::::
5499
5500 ;; ??? Add movXXcc patterns?
5501
5502 ;;
5503 ;; DImode if_then_else patterns.
5504 ;;
5505
5506 (define_insn "*cmovdi_internal"
5507   [(set (match_operand:DI 0 "destination_operand"
5508            "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
5509         (if_then_else:DI
5510           (match_operator 4 "predicate_operator"
5511             [(match_operand:BI 1 "register_operand"
5512                 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
5513              (const_int 0)])
5514           (match_operand:DI 2 "move_operand"
5515            "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
5516           (match_operand:DI 3 "move_operand"
5517            "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
5518   "ia64_move_ok (operands[0], operands[2])
5519    && ia64_move_ok (operands[0], operands[3])"
5520   { gcc_unreachable (); }
5521   [(set_attr "predicable" "no")])
5522
5523 (define_split
5524   [(set (match_operand 0 "destination_operand" "")
5525         (if_then_else
5526           (match_operator 4 "predicate_operator"
5527             [(match_operand:BI 1 "register_operand" "")
5528              (const_int 0)])
5529           (match_operand 2 "move_operand" "")
5530           (match_operand 3 "move_operand" "")))]
5531   "reload_completed"
5532   [(const_int 0)]
5533 {
5534   bool emitted_something = false;
5535   rtx dest = operands[0];
5536   rtx srct = operands[2];
5537   rtx srcf = operands[3];
5538   rtx cond = operands[4];
5539
5540   if (! rtx_equal_p (dest, srct))
5541     {
5542       ia64_emit_cond_move (dest, srct, cond);
5543       emitted_something = true;
5544     }
5545   if (! rtx_equal_p (dest, srcf))
5546     {
5547       cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
5548                              VOIDmode, operands[1], const0_rtx);
5549       ia64_emit_cond_move (dest, srcf, cond);
5550       emitted_something = true;
5551     }
5552   if (! emitted_something)
5553     emit_note (NOTE_INSN_DELETED);
5554   DONE;
5555 })
5556
5557 ;; Absolute value pattern.
5558
5559 (define_insn "*absdi2_internal"
5560   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
5561         (if_then_else:DI
5562           (match_operator 4 "predicate_operator"
5563             [(match_operand:BI 1 "register_operand" "c,c")
5564              (const_int 0)])
5565           (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
5566           (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
5567   ""
5568   "#"
5569   [(set_attr "itanium_class" "ialu,unknown")
5570    (set_attr "predicable" "no")])
5571
5572 (define_split
5573   [(set (match_operand:DI 0 "register_operand" "")
5574         (if_then_else:DI
5575           (match_operator 4 "predicate_operator"
5576             [(match_operand:BI 1 "register_operand" "c,c")
5577              (const_int 0)])
5578           (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
5579           (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
5580   "reload_completed && rtx_equal_p (operands[0], operands[3])"
5581   [(cond_exec
5582      (match_dup 4)
5583      (set (match_dup 0)
5584           (neg:DI (match_dup 2))))]
5585   "")
5586
5587 (define_split
5588   [(set (match_operand:DI 0 "register_operand" "")
5589         (if_then_else:DI
5590           (match_operator 4 "predicate_operator"
5591             [(match_operand:BI 1 "register_operand" "c,c")
5592              (const_int 0)])
5593           (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
5594           (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
5595   "reload_completed"
5596   [(cond_exec
5597      (match_dup 4)
5598      (set (match_dup 0) (neg:DI (match_dup 2))))
5599    (cond_exec
5600      (match_dup 5)
5601      (set (match_dup 0) (match_dup 3)))]
5602 {
5603   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
5604                                 VOIDmode, operands[1], const0_rtx);
5605 })
5606
5607 ;;
5608 ;; SImode if_then_else patterns.
5609 ;;
5610
5611 (define_insn "*cmovsi_internal"
5612   [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
5613         (if_then_else:SI
5614           (match_operator 4 "predicate_operator"
5615             [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
5616              (const_int 0)])
5617           (match_operand:SI 2 "move_operand"
5618                     "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
5619           (match_operand:SI 3 "move_operand"
5620                     "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
5621   "ia64_move_ok (operands[0], operands[2])
5622    && ia64_move_ok (operands[0], operands[3])"
5623   { gcc_unreachable (); }
5624   [(set_attr "predicable" "no")])
5625
5626 (define_insn "*abssi2_internal"
5627   [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
5628         (if_then_else:SI
5629           (match_operator 4 "predicate_operator"
5630             [(match_operand:BI 1 "register_operand" "c,c")
5631              (const_int 0)])
5632           (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
5633           (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
5634   ""
5635   "#"
5636   [(set_attr "itanium_class" "ialu,unknown")
5637    (set_attr "predicable" "no")])
5638
5639 (define_split
5640   [(set (match_operand:SI 0 "register_operand" "")
5641         (if_then_else:SI
5642           (match_operator 4 "predicate_operator"
5643             [(match_operand:BI 1 "register_operand" "c,c")
5644              (const_int 0)])
5645           (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
5646           (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
5647   "reload_completed && rtx_equal_p (operands[0], operands[3])"
5648   [(cond_exec
5649      (match_dup 4)
5650      (set (match_dup 0)
5651           (neg:SI (match_dup 2))))]
5652   "")
5653
5654 (define_split
5655   [(set (match_operand:SI 0 "register_operand" "")
5656         (if_then_else:SI
5657           (match_operator 4 "predicate_operator"
5658             [(match_operand:BI 1 "register_operand" "c,c")
5659              (const_int 0)])
5660           (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
5661           (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
5662   "reload_completed"
5663   [(cond_exec
5664      (match_dup 4)
5665      (set (match_dup 0) (neg:SI (match_dup 2))))
5666    (cond_exec
5667      (match_dup 5)
5668      (set (match_dup 0) (match_dup 3)))]
5669 {
5670   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
5671                                 VOIDmode, operands[1], const0_rtx);
5672 })
5673
5674 (define_insn_and_split "*cond_opsi2_internal"
5675   [(set (match_operand:SI 0 "gr_register_operand" "=r")
5676         (match_operator:SI 5 "condop_operator"
5677           [(if_then_else:SI
5678              (match_operator 6 "predicate_operator"
5679                [(match_operand:BI 1 "register_operand" "c")
5680                 (const_int 0)])
5681              (match_operand:SI 2 "gr_register_operand" "r")
5682              (match_operand:SI 3 "gr_register_operand" "r"))
5683            (match_operand:SI 4 "gr_register_operand" "r")]))]
5684   ""
5685   "#"
5686   "reload_completed"
5687   [(cond_exec
5688      (match_dup 6)
5689      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
5690    (cond_exec
5691      (match_dup 7)
5692      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
5693 {
5694   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5695                                 VOIDmode, operands[1], const0_rtx);
5696 }
5697   [(set_attr "itanium_class" "ialu")
5698    (set_attr "predicable" "no")])
5699
5700
5701 (define_insn_and_split "*cond_opsi2_internal_b"
5702   [(set (match_operand:SI 0 "gr_register_operand" "=r")
5703         (match_operator:SI 5 "condop_operator"
5704           [(match_operand:SI 4 "gr_register_operand" "r")
5705            (if_then_else:SI
5706              (match_operator 6 "predicate_operator"
5707                [(match_operand:BI 1 "register_operand" "c")
5708                 (const_int 0)])
5709              (match_operand:SI 2 "gr_register_operand" "r")
5710              (match_operand:SI 3 "gr_register_operand" "r"))]))]
5711   ""
5712   "#"
5713   "reload_completed"
5714   [(cond_exec
5715      (match_dup 6)
5716      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
5717    (cond_exec
5718      (match_dup 7)
5719      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
5720 {
5721   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5722                                 VOIDmode, operands[1], const0_rtx);
5723 }
5724   [(set_attr "itanium_class" "ialu")
5725    (set_attr "predicable" "no")])
5726
5727 \f
5728 ;; ::::::::::::::::::::
5729 ;; ::
5730 ;; :: Call and branch instructions
5731 ;; ::
5732 ;; ::::::::::::::::::::
5733
5734 ;; Subroutine call instruction returning no value.  Operand 0 is the function
5735 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
5736 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
5737 ;; registers used as operands.
5738
5739 ;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
5740 ;; is supplied for the sake of some RISC machines which need to put this
5741 ;; information into the assembler code; they can put it in the RTL instead of
5742 ;; operand 1.
5743
5744 (define_expand "call"
5745   [(use (match_operand:DI 0 "" ""))
5746    (use (match_operand 1 "" ""))
5747    (use (match_operand 2 "" ""))
5748    (use (match_operand 3 "" ""))]
5749   ""
5750 {
5751   ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
5752   DONE;
5753 })
5754
5755 (define_expand "sibcall"
5756   [(use (match_operand:DI 0 "" ""))
5757    (use (match_operand 1 "" ""))
5758    (use (match_operand 2 "" ""))
5759    (use (match_operand 3 "" ""))]
5760   ""
5761 {
5762   ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
5763   DONE;
5764 })
5765
5766 ;; Subroutine call instruction returning a value.  Operand 0 is the hard
5767 ;; register in which the value is returned.  There are three more operands,
5768 ;; the same as the three operands of the `call' instruction (but with numbers
5769 ;; increased by one).
5770 ;;
5771 ;; Subroutines that return `BLKmode' objects use the `call' insn.
5772
5773 (define_expand "call_value"
5774   [(use (match_operand 0 "" ""))
5775    (use (match_operand:DI 1 "" ""))
5776    (use (match_operand 2 "" ""))
5777    (use (match_operand 3 "" ""))
5778    (use (match_operand 4 "" ""))]
5779   ""
5780 {
5781   ia64_expand_call (operands[0], operands[1], operands[3], false);
5782   DONE;
5783 })
5784
5785 (define_expand "sibcall_value"
5786   [(use (match_operand 0 "" ""))
5787    (use (match_operand:DI 1 "" ""))
5788    (use (match_operand 2 "" ""))
5789    (use (match_operand 3 "" ""))
5790    (use (match_operand 4 "" ""))]
5791   ""
5792 {
5793   ia64_expand_call (operands[0], operands[1], operands[3], true);
5794   DONE;
5795 })
5796
5797 ;; Call subroutine returning any type.
5798
5799 (define_expand "untyped_call"
5800   [(parallel [(call (match_operand 0 "" "")
5801                     (const_int 0))
5802               (match_operand 1 "" "")
5803               (match_operand 2 "" "")])]
5804   ""
5805 {
5806   int i;
5807
5808   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
5809
5810   for (i = 0; i < XVECLEN (operands[2], 0); i++)
5811     {
5812       rtx set = XVECEXP (operands[2], 0, i);
5813       emit_move_insn (SET_DEST (set), SET_SRC (set));
5814     }
5815
5816   /* The optimizer does not know that the call sets the function value
5817      registers we stored in the result block.  We avoid problems by
5818      claiming that all hard registers are used and clobbered at this
5819      point.  */
5820   emit_insn (gen_blockage ());
5821
5822   DONE;
5823 })
5824
5825 (define_insn "call_nogp"
5826   [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5827          (const_int 0))
5828    (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
5829   ""
5830   "br.call%+.many %1 = %0"
5831   [(set_attr "itanium_class" "br,scall")])
5832
5833 (define_insn "call_value_nogp"
5834   [(set (match_operand 0 "" "=X,X")
5835         (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
5836               (const_int 0)))
5837    (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
5838   ""
5839   "br.call%+.many %2 = %1"
5840   [(set_attr "itanium_class" "br,scall")])
5841
5842 (define_insn "sibcall_nogp"
5843   [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5844          (const_int 0))]
5845   ""
5846   "br%+.many %0"
5847   [(set_attr "itanium_class" "br,scall")])
5848
5849 (define_insn "call_gp"
5850   [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5851          (const_int 1))
5852    (clobber (match_operand:DI 1 "register_operand" "=b,b"))
5853    (clobber (match_scratch:DI 2 "=&r,X"))
5854    (clobber (match_scratch:DI 3 "=b,X"))]
5855   ""
5856   "#"
5857   [(set_attr "itanium_class" "br,scall")])
5858
5859 ;; Irritatingly, we don't have access to INSN within the split body.
5860 ;; See commentary in ia64_split_call as to why these aren't peep2.
5861 (define_split
5862   [(call (mem (match_operand 0 "call_operand" ""))
5863          (const_int 1))
5864    (clobber (match_operand:DI 1 "register_operand" ""))
5865    (clobber (match_scratch:DI 2 ""))
5866    (clobber (match_scratch:DI 3 ""))]
5867   "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5868   [(const_int 0)]
5869 {
5870   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5871                    operands[3], true, false);
5872   DONE;
5873 })
5874
5875 (define_split
5876   [(call (mem (match_operand 0 "call_operand" ""))
5877          (const_int 1))
5878    (clobber (match_operand:DI 1 "register_operand" ""))
5879    (clobber (match_scratch:DI 2 ""))
5880    (clobber (match_scratch:DI 3 ""))]
5881   "reload_completed"
5882   [(const_int 0)]
5883 {
5884   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5885                    operands[3], false, false);
5886   DONE;
5887 })
5888
5889 (define_insn "call_value_gp"
5890   [(set (match_operand 0 "" "=X,X")
5891         (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
5892               (const_int 1)))
5893    (clobber (match_operand:DI 2 "register_operand" "=b,b"))
5894    (clobber (match_scratch:DI 3 "=&r,X"))
5895    (clobber (match_scratch:DI 4 "=b,X"))]
5896   ""
5897   "#"
5898   [(set_attr "itanium_class" "br,scall")])
5899
5900 (define_split
5901   [(set (match_operand 0 "" "")
5902         (call (mem:DI (match_operand:DI 1 "call_operand" ""))
5903               (const_int 1)))
5904    (clobber (match_operand:DI 2 "register_operand" ""))
5905    (clobber (match_scratch:DI 3 ""))
5906    (clobber (match_scratch:DI 4 ""))]
5907   "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5908   [(const_int 0)]
5909 {
5910   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5911                    operands[4], true, false);
5912   DONE;
5913 })
5914
5915 (define_split
5916   [(set (match_operand 0 "" "")
5917         (call (mem:DI (match_operand:DI 1 "call_operand" ""))
5918               (const_int 1)))
5919    (clobber (match_operand:DI 2 "register_operand" ""))
5920    (clobber (match_scratch:DI 3 ""))
5921    (clobber (match_scratch:DI 4 ""))]
5922   "reload_completed"
5923   [(const_int 0)]
5924 {
5925   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5926                    operands[4], false, false);
5927   DONE;
5928 })
5929
5930 (define_insn_and_split "sibcall_gp"
5931   [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5932          (const_int 1))
5933    (clobber (match_scratch:DI 1 "=&r,X"))
5934    (clobber (match_scratch:DI 2 "=b,X"))]
5935   ""
5936   "#"
5937   "reload_completed"
5938   [(const_int 0)]
5939 {
5940   ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
5941                    operands[2], true, true);
5942   DONE;
5943 }
5944   [(set_attr "itanium_class" "br")])
5945
5946 (define_insn "return_internal"
5947   [(return)
5948    (use (match_operand:DI 0 "register_operand" "b"))]
5949   ""
5950   "br.ret.sptk.many %0"
5951   [(set_attr "itanium_class" "br")])
5952
5953 (define_insn "return"
5954   [(return)]
5955   "ia64_direct_return ()"
5956   "br.ret.sptk.many rp"
5957   [(set_attr "itanium_class" "br")])
5958
5959 (define_insn "*return_true"
5960   [(set (pc)
5961         (if_then_else (match_operator 0 "predicate_operator"
5962                         [(match_operand:BI 1 "register_operand" "c")
5963                          (const_int 0)])
5964                       (return)
5965                       (pc)))]
5966   "ia64_direct_return ()"
5967   "(%J0) br.ret%+.many rp"
5968   [(set_attr "itanium_class" "br")
5969    (set_attr "predicable" "no")])
5970
5971 (define_insn "*return_false"
5972   [(set (pc)
5973         (if_then_else (match_operator 0 "predicate_operator"
5974                         [(match_operand:BI 1 "register_operand" "c")
5975                          (const_int 0)])
5976                       (pc)
5977                       (return)))]
5978   "ia64_direct_return ()"
5979   "(%j0) br.ret%+.many rp"
5980   [(set_attr "itanium_class" "br")
5981    (set_attr "predicable" "no")])
5982
5983 (define_insn "jump"
5984   [(set (pc) (label_ref (match_operand 0 "" "")))]
5985   ""
5986   "br %l0"
5987   [(set_attr "itanium_class" "br")])
5988
5989 (define_insn "indirect_jump"
5990   [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
5991   ""
5992   "br %0"
5993   [(set_attr "itanium_class" "br")])
5994
5995 (define_expand "tablejump"
5996   [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
5997               (use (label_ref (match_operand 1 "" "")))])]
5998   ""
5999 {
6000   rtx op0 = operands[0];
6001   rtx addr;
6002
6003   /* ??? Bother -- do_tablejump is "helpful" and pulls the table
6004      element into a register without bothering to see whether that
6005      is necessary given the operand predicate.  Check for MEM just
6006      in case someone fixes this.  */
6007   if (GET_CODE (op0) == MEM)
6008     addr = XEXP (op0, 0);
6009   else
6010     {
6011       /* Otherwise, cheat and guess that the previous insn in the
6012          stream was the memory load.  Grab the address from that.
6013          Note we have to momentarily pop out of the sequence started
6014          by the insn-emit wrapper in order to grab the last insn.  */
6015       rtx last, set;
6016
6017       end_sequence ();
6018       last = get_last_insn ();
6019       start_sequence ();
6020       set = single_set (last);
6021
6022       gcc_assert (rtx_equal_p (SET_DEST (set), op0)
6023                   && GET_CODE (SET_SRC (set)) == MEM);
6024       addr = XEXP (SET_SRC (set), 0);
6025       gcc_assert (!rtx_equal_p (addr, op0));
6026     }
6027
6028   /* Jump table elements are stored pc-relative.  That is, a displacement
6029      from the entry to the label.  Thus to convert to an absolute address
6030      we add the address of the memory from which the value is loaded.  */
6031   operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
6032                                      NULL_RTX, 1, OPTAB_DIRECT);
6033 })
6034
6035 (define_insn "*tablejump_internal"
6036   [(set (pc) (match_operand:DI 0 "register_operand" "b"))
6037    (use (label_ref (match_operand 1 "" "")))]
6038   ""
6039   "br %0"
6040   [(set_attr "itanium_class" "br")])
6041
6042 \f
6043 ;; ::::::::::::::::::::
6044 ;; ::
6045 ;; :: Prologue and Epilogue instructions
6046 ;; ::
6047 ;; ::::::::::::::::::::
6048
6049 (define_expand "prologue"
6050   [(const_int 1)]
6051   ""
6052 {
6053   ia64_expand_prologue ();
6054   DONE;
6055 })
6056
6057 (define_expand "epilogue"
6058   [(return)]
6059   ""
6060 {
6061   ia64_expand_epilogue (0);
6062   DONE;
6063 })
6064
6065 (define_expand "sibcall_epilogue"
6066   [(return)]
6067   ""
6068 {
6069   ia64_expand_epilogue (1);
6070   DONE;
6071 })
6072
6073 ;; This prevents the scheduler from moving the SP decrement past FP-relative
6074 ;; stack accesses.  This is the same as adddi3 plus the extra set.
6075
6076 (define_insn "prologue_allocate_stack"
6077   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6078         (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
6079                  (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
6080    (set (match_operand:DI 3 "register_operand" "+r,r,r")
6081         (match_dup 3))]
6082   ""
6083   "@
6084    add %0 = %1, %2
6085    adds %0 = %2, %1
6086    addl %0 = %2, %1"
6087   [(set_attr "itanium_class" "ialu")])
6088
6089 ;; This prevents the scheduler from moving the SP restore past FP-relative
6090 ;; stack accesses.  This is similar to movdi plus the extra set.
6091
6092 (define_insn "epilogue_deallocate_stack"
6093   [(set (match_operand:DI 0 "register_operand" "=r")
6094         (match_operand:DI 1 "register_operand" "+r"))
6095    (set (match_dup 1) (match_dup 1))]
6096   ""
6097   "mov %0 = %1"
6098   [(set_attr "itanium_class" "ialu")])
6099
6100 ;; As USE insns aren't meaningful after reload, this is used instead
6101 ;; to prevent deleting instructions setting registers for EH handling
6102 (define_insn "prologue_use"
6103   [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
6104               UNSPEC_PROLOGUE_USE)]
6105   ""
6106   ""
6107   [(set_attr "itanium_class" "ignore")
6108    (set_attr "predicable" "no")
6109    (set_attr "empty" "yes")])
6110
6111 ;; Allocate a new register frame.
6112
6113 (define_insn "alloc"
6114   [(set (match_operand:DI 0 "register_operand" "=r")
6115         (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
6116    (use (match_operand:DI 1 "const_int_operand" "i"))
6117    (use (match_operand:DI 2 "const_int_operand" "i"))
6118    (use (match_operand:DI 3 "const_int_operand" "i"))
6119    (use (match_operand:DI 4 "const_int_operand" "i"))]
6120   ""
6121   "alloc %0 = ar.pfs, %1, %2, %3, %4"
6122   [(set_attr "itanium_class" "syst_m0")
6123    (set_attr "predicable" "no")
6124    (set_attr "first_insn" "yes")])
6125
6126 ;; Modifies ar.unat
6127 (define_expand "gr_spill"
6128   [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
6129                    (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6130                                (match_operand:DI 2 "const_int_operand" "")]
6131                               UNSPEC_GR_SPILL))
6132               (clobber (match_dup 3))])]
6133   ""
6134   "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
6135
6136 (define_insn "gr_spill_internal"
6137   [(set (match_operand:DI 0 "destination_operand" "=m")
6138         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6139                     (match_operand:DI 2 "const_int_operand" "")]
6140                    UNSPEC_GR_SPILL))
6141    (clobber (match_operand:DI 3 "register_operand" ""))]
6142   ""
6143 {
6144   /* Note that we use a C output pattern here to avoid the predicate
6145      being automatically added before the .mem.offset directive.  */
6146   return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
6147 }
6148   [(set_attr "itanium_class" "st")])
6149
6150 ;; Reads ar.unat
6151 (define_expand "gr_restore"
6152   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
6153                    (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
6154                                (match_operand:DI 2 "const_int_operand" "")]
6155                               UNSPEC_GR_RESTORE))
6156               (use (match_dup 3))])]
6157   ""
6158   "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
6159
6160 (define_insn "gr_restore_internal"
6161   [(set (match_operand:DI 0 "register_operand" "=r")
6162         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
6163                     (match_operand:DI 2 "const_int_operand" "")]
6164                    UNSPEC_GR_RESTORE))
6165    (use (match_operand:DI 3 "register_operand" ""))]
6166   ""
6167   { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
6168   [(set_attr "itanium_class" "ld")])
6169
6170 (define_insn "fr_spill"
6171   [(set (match_operand:XF 0 "destination_operand" "=m")
6172         (unspec:XF [(match_operand:XF 1 "register_operand" "f")]
6173                    UNSPEC_FR_SPILL))]
6174   ""
6175   "stf.spill %0 = %1%P0"
6176   [(set_attr "itanium_class" "stf")])
6177
6178 (define_insn "fr_restore"
6179   [(set (match_operand:XF 0 "register_operand" "=f")
6180         (unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
6181                    UNSPEC_FR_RESTORE))]
6182   ""
6183   "ldf.fill %0 = %1%P1"
6184   [(set_attr "itanium_class" "fld")])
6185
6186 ;; ??? The explicit stop is not ideal.  It would be better if
6187 ;; rtx_needs_barrier took care of this, but this is something that can be
6188 ;; fixed later.  This avoids an RSE DV.
6189
6190 (define_insn "bsp_value"
6191   [(set (match_operand:DI 0 "register_operand" "=r")
6192         (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
6193   ""
6194   "*
6195 {
6196   return \";;\;%,mov %0 = ar.bsp\";
6197 }"
6198   [(set_attr "itanium_class" "frar_i")])
6199
6200 (define_insn "set_bsp"
6201   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
6202                     UNSPECV_SET_BSP)]
6203   ""
6204   "flushrs
6205         mov r19=ar.rsc
6206         ;;
6207         and r19=0x1c,r19
6208         ;;
6209         mov ar.rsc=r19
6210         ;;
6211         mov ar.bspstore=%0
6212         ;;
6213         or r19=0x3,r19
6214         ;;
6215         loadrs
6216         invala
6217         ;;
6218         mov ar.rsc=r19"
6219   [(set_attr "itanium_class" "unknown")
6220    (set_attr "predicable" "no")])
6221
6222 ;; ??? The explicit stops are not ideal.  It would be better if
6223 ;; rtx_needs_barrier took care of this, but this is something that can be
6224 ;; fixed later.  This avoids an RSE DV.
6225
6226 (define_insn "flushrs"
6227   [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
6228   ""
6229   ";;\;flushrs\;;;"
6230   [(set_attr "itanium_class" "rse_m")
6231    (set_attr "predicable" "no")])
6232 \f
6233 ;; ::::::::::::::::::::
6234 ;; ::
6235 ;; :: Miscellaneous instructions
6236 ;; ::
6237 ;; ::::::::::::::::::::
6238
6239 ;; ??? Emitting a NOP instruction isn't very useful.  This should probably
6240 ;; be emitting ";;" to force a break in the instruction packing.
6241
6242 ;; No operation, needed in case the user uses -g but not -O.
6243 (define_insn "nop"
6244   [(const_int 0)]
6245   ""
6246   "nop 0"
6247   [(set_attr "itanium_class" "nop")])
6248
6249 (define_insn "nop_m"
6250   [(const_int 1)]
6251   ""
6252   "nop.m 0"
6253   [(set_attr "itanium_class" "nop_m")])
6254
6255 (define_insn "nop_i"
6256   [(const_int 2)]
6257   ""
6258   "nop.i 0"
6259   [(set_attr "itanium_class" "nop_i")])
6260
6261 (define_insn "nop_f"
6262   [(const_int 3)]
6263   ""
6264   "nop.f 0"
6265   [(set_attr "itanium_class" "nop_f")])
6266
6267 (define_insn "nop_b"
6268   [(const_int 4)]
6269   ""
6270   "nop.b 0"
6271   [(set_attr "itanium_class" "nop_b")])
6272
6273 (define_insn "nop_x"
6274   [(const_int 5)]
6275   ""
6276   ""
6277   [(set_attr "itanium_class" "nop_x")
6278    (set_attr "empty" "yes")])
6279
6280 ;; The following insn will be never generated.  It is used only by
6281 ;; insn scheduler to change state before advancing cycle.
6282 (define_insn "pre_cycle"
6283   [(const_int 6)]
6284   ""
6285   ""
6286   [(set_attr "itanium_class" "pre_cycle")])
6287
6288 (define_insn "bundle_selector"
6289   [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
6290   ""
6291   { return get_bundle_name (INTVAL (operands[0])); }
6292   [(set_attr "itanium_class" "ignore")
6293    (set_attr "predicable" "no")])
6294
6295 ;; Pseudo instruction that prevents the scheduler from moving code above this
6296 ;; point.
6297 (define_insn "blockage"
6298   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6299   ""
6300   ""
6301   [(set_attr "itanium_class" "ignore")
6302    (set_attr "predicable" "no")])
6303
6304 (define_insn "insn_group_barrier"
6305   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
6306                     UNSPECV_INSN_GROUP_BARRIER)]
6307   ""
6308   ";;"
6309   [(set_attr "itanium_class" "stop_bit")
6310    (set_attr "predicable" "no")
6311    (set_attr "empty" "yes")])
6312
6313 (define_expand "trap"
6314   [(trap_if (const_int 1) (const_int 0))]
6315   ""
6316   "")
6317
6318 ;; ??? We don't have a match-any slot type.  Setting the type to unknown
6319 ;; produces worse code that setting the slot type to A.
6320
6321 (define_insn "*trap"
6322   [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
6323   ""
6324   "break %0"
6325   [(set_attr "itanium_class" "chk_s_i")])
6326
6327 (define_expand "conditional_trap"
6328   [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
6329   ""
6330 {
6331   operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
6332 })
6333
6334 (define_insn "*conditional_trap"
6335   [(trap_if (match_operator 0 "predicate_operator"
6336               [(match_operand:BI 1 "register_operand" "c")
6337                (const_int 0)])  
6338             (match_operand 2 "const_int_operand" ""))]
6339   ""
6340   "(%J0) break %2"
6341   [(set_attr "itanium_class" "chk_s_i")
6342    (set_attr "predicable" "no")])
6343
6344 (define_insn "break_f"
6345   [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
6346   ""
6347   "break.f 0"
6348   [(set_attr "itanium_class" "nop_f")])
6349
6350 (define_insn "prefetch"
6351   [(prefetch (match_operand:DI 0 "address_operand" "p")
6352              (match_operand:DI 1 "const_int_operand" "n")
6353              (match_operand:DI 2 "const_int_operand" "n"))]
6354   ""
6355 {
6356   static const char * const alt[2][4] = {
6357     {
6358       "%,lfetch.nta [%0]",
6359       "%,lfetch.nt1 [%0]",
6360       "%,lfetch.nt2 [%0]",
6361       "%,lfetch [%0]"
6362     },
6363     {
6364       "%,lfetch.excl.nta [%0]",
6365       "%,lfetch.excl.nt1 [%0]",
6366       "%,lfetch.excl.nt2 [%0]",
6367       "%,lfetch.excl [%0]"
6368     }
6369   };
6370   int i = (INTVAL (operands[1]));
6371   int j = (INTVAL (operands[2]));
6372
6373   gcc_assert (i == 0 || i == 1);
6374   gcc_assert (j >= 0 && j <= 3);
6375   return alt[i][j];
6376 }
6377   [(set_attr "itanium_class" "lfetch")])
6378 \f
6379 ;; Non-local goto support.
6380
6381 (define_expand "save_stack_nonlocal"
6382   [(use (match_operand:OI 0 "memory_operand" ""))
6383    (use (match_operand:DI 1 "register_operand" ""))]
6384   ""
6385 {
6386   emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
6387                                          \"__ia64_save_stack_nonlocal\"),
6388                      0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
6389                      operands[1], Pmode);
6390   DONE;
6391 })
6392
6393 (define_expand "nonlocal_goto"
6394   [(use (match_operand 0 "general_operand" ""))
6395    (use (match_operand 1 "general_operand" ""))
6396    (use (match_operand 2 "general_operand" ""))
6397    (use (match_operand 3 "general_operand" ""))]
6398   ""
6399 {
6400   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
6401                      LCT_NORETURN, VOIDmode, 3,
6402                      operands[1], Pmode,
6403                      copy_to_reg (XEXP (operands[2], 0)), Pmode,
6404                      operands[3], Pmode);
6405   emit_barrier ();
6406   DONE;
6407 })
6408
6409 (define_insn_and_split "builtin_setjmp_receiver"
6410   [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
6411   ""
6412   "#"
6413   "reload_completed"
6414   [(const_int 0)]
6415 {
6416   ia64_reload_gp ();
6417   DONE;
6418 })
6419
6420 (define_expand "eh_epilogue"
6421   [(use (match_operand:DI 0 "register_operand" "r"))
6422    (use (match_operand:DI 1 "register_operand" "r"))
6423    (use (match_operand:DI 2 "register_operand" "r"))]
6424   ""
6425 {
6426   rtx bsp = gen_rtx_REG (Pmode, 10);
6427   rtx sp = gen_rtx_REG (Pmode, 9);
6428
6429   if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
6430     {
6431       emit_move_insn (bsp, operands[0]);
6432       operands[0] = bsp;
6433     }
6434   if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
6435     {
6436       emit_move_insn (sp, operands[2]);
6437       operands[2] = sp;
6438     }
6439   emit_insn (gen_rtx_USE (VOIDmode, sp));
6440   emit_insn (gen_rtx_USE (VOIDmode, bsp));
6441
6442   cfun->machine->ia64_eh_epilogue_sp = sp;
6443   cfun->machine->ia64_eh_epilogue_bsp = bsp;
6444 })
6445 \f
6446 ;; Builtin apply support.
6447
6448 (define_expand "restore_stack_nonlocal"
6449   [(use (match_operand:DI 0 "register_operand" ""))
6450    (use (match_operand:OI 1 "memory_operand" ""))]
6451   ""
6452 {
6453   emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
6454                                          "__ia64_restore_stack_nonlocal"),
6455                      0, VOIDmode, 1,
6456                      copy_to_reg (XEXP (operands[1], 0)), Pmode);
6457   DONE;
6458 })
6459
6460 \f
6461 ;; Predication.
6462
6463 (define_cond_exec
6464   [(match_operator 0 "predicate_operator"
6465      [(match_operand:BI 1 "register_operand" "c")
6466       (const_int 0)])]
6467   ""
6468   "(%J0)")
6469
6470 (define_insn "pred_rel_mutex"
6471   [(set (match_operand:BI 0 "register_operand" "+c")
6472        (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
6473   ""
6474   ".pred.rel.mutex %0, %I0"
6475   [(set_attr "itanium_class" "ignore")
6476    (set_attr "predicable" "no")])
6477
6478 (define_insn "safe_across_calls_all"
6479   [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
6480   ""
6481   ".pred.safe_across_calls p1-p63"
6482   [(set_attr "itanium_class" "ignore")
6483    (set_attr "predicable" "no")])
6484
6485 (define_insn "safe_across_calls_normal"
6486   [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
6487   ""
6488 {
6489   emit_safe_across_calls ();
6490   return "";
6491 }
6492   [(set_attr "itanium_class" "ignore")
6493    (set_attr "predicable" "no")])
6494
6495 ;; UNSPEC instruction definition to "swizzle" 32-bit pointer into 64-bit
6496 ;; pointer.  This is used by the HP-UX 32 bit mode.
6497
6498 (define_insn "ptr_extend"
6499   [(set (match_operand:DI 0 "gr_register_operand" "=r")
6500         (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
6501                    UNSPEC_ADDP4))]
6502   ""
6503   "addp4 %0 = 0,%1"
6504   [(set_attr "itanium_class" "ialu")])
6505
6506 ;;
6507 ;; Optimizations for ptr_extend
6508
6509 (define_insn "ptr_extend_plus_imm"
6510   [(set (match_operand:DI 0 "gr_register_operand" "=r")
6511         (unspec:DI
6512          [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
6513                    (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
6514          UNSPEC_ADDP4))]
6515   "addp4_optimize_ok (operands[1], operands[2])"
6516   "addp4 %0 = %2, %1"
6517   [(set_attr "itanium_class" "ialu")])
6518
6519 (define_insn "*ptr_extend_plus_2"
6520   [(set (match_operand:DI 0 "gr_register_operand" "=r")
6521         (unspec:DI
6522          [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
6523                    (match_operand:SI 2 "basereg_operand" "r"))]
6524          UNSPEC_ADDP4))]
6525   "addp4_optimize_ok (operands[1], operands[2])"
6526   "addp4 %0 = %1, %2"
6527   [(set_attr "itanium_class" "ialu")])
6528
6529 ;;
6530 ;; Get instruction pointer
6531
6532 (define_insn "ip_value"
6533   [(set (match_operand:DI 0 "register_operand" "=r")
6534         (pc))]
6535  ""
6536  "mov %0 = ip"
6537   [(set_attr "itanium_class" "ialu")])
6538
6539 ;; Vector operations
6540 (include "vect.md")
6541 ;; Atomic operations
6542 (include "sync.md")