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