OSDN Git Service

cb5dd10abc292a751fb3f93ea31c00834c58aa59
[pf3gnuchains/gcc-fork.git] / gcc / config / ia64 / ia64.md
1 ;; IA-64 Machine description template
2 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
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, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, 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
60    (UNSPEC_LD_BASE              9)
61    (UNSPEC_GR_SPILL             10)
62    (UNSPEC_GR_RESTORE           11)
63    (UNSPEC_FR_SPILL             12)
64    (UNSPEC_FR_RESTORE           13)
65    (UNSPEC_FR_RECIP_APPROX      14)
66    (UNSPEC_PRED_REL_MUTEX       15)
67    (UNSPEC_GETF_EXP             16)
68    (UNSPEC_PIC_CALL             17)
69    (UNSPEC_MF                   18)
70    (UNSPEC_CMPXCHG_ACQ          19)
71    (UNSPEC_FETCHADD_ACQ         20)
72    (UNSPEC_BSP_VALUE            21)
73    (UNSPEC_FLUSHRS              22)
74    (UNSPEC_BUNDLE_SELECTOR      23)
75    (UNSPEC_ADDP4                24)
76    (UNSPEC_PROLOGUE_USE         25)
77    (UNSPEC_RET_ADDR             26)
78    (UNSPEC_SETF_EXP             27)
79    (UNSPEC_FR_SQRT_RECIP_APPROX 28)
80    (UNSPEC_SHRP                 29)
81    (UNSPEC_COPYSIGN             30)
82   ])
83
84 (define_constants
85   [(UNSPECV_ALLOC               0)
86    (UNSPECV_BLOCKAGE            1)
87    (UNSPECV_INSN_GROUP_BARRIER  2)
88    (UNSPECV_BREAK               3)
89    (UNSPECV_SET_BSP             4)
90    (UNSPECV_PSAC_ALL            5)      ; pred.safe_across_calls
91    (UNSPECV_PSAC_NORMAL         6)
92    (UNSPECV_SETJMP_RECEIVER     7)
93   ])
94
95 (include "predicates.md")
96 \f
97 ;; ::::::::::::::::::::
98 ;; ::
99 ;; :: Attributes
100 ;; ::
101 ;; ::::::::::::::::::::
102
103 ;; Processor type.  This attribute must exactly match the processor_type
104 ;; enumeration in ia64.h.
105 (define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
106
107 ;; Instruction type.  This primarily determines how instructions can be
108 ;; packed in bundles, and secondarily affects scheduling to function units.
109
110 ;; A alu, can go in I or M syllable of a bundle
111 ;; I integer
112 ;; M memory
113 ;; F floating-point
114 ;; B branch
115 ;; L long immediate, takes two syllables
116 ;; S stop bit
117
118 ;; ??? Should not have any pattern with type unknown.  Perhaps add code to
119 ;; check this in md_reorg?  Currently use unknown for patterns which emit
120 ;; multiple instructions, patterns which emit 0 instructions, and patterns
121 ;; which emit instruction that can go in any slot (e.g. nop).
122
123 (define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
124         fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
125         chk_s,long_i,mmalua,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,
126         st,syst_m0, syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,
127         nop_b,nop_f,nop_i,nop_m,nop_x,lfetch,pre_cycle"
128   (const_string "unknown"))
129
130 ;; chk_s has an I and an M form; use type A for convenience.
131 (define_attr "type" "unknown,A,I,M,F,B,L,X,S"
132   (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
133          (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
134          (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
135          (eq_attr "itanium_class" "lfetch") (const_string "M")
136          (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog,mmalua")
137            (const_string "A")
138          (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
139          (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
140          (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
141          (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
142          (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
143          (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
144          (eq_attr "itanium_class" "stop_bit") (const_string "S")
145          (eq_attr "itanium_class" "nop_x") (const_string "X")
146          (eq_attr "itanium_class" "long_i") (const_string "L")]
147         (const_string "unknown")))
148
149 (define_attr "itanium_requires_unit0" "no,yes"
150   (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
151          (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
152          (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
153          (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
154          (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
155          (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
156         (const_string "no")))
157
158 ;; Predication.  True iff this instruction can be predicated.
159
160 (define_attr "predicable" "no,yes" (const_string "yes"))
161
162 ;; Empty.  True iff this insn does not generate any code.
163
164 (define_attr "empty" "no,yes" (const_string "no"))
165
166 \f
167 ;; DFA descriptions of ia64 processors used for insn scheduling and
168 ;; bundling.
169
170 (automata_option "ndfa")
171
172 ;; Uncomment the following line to output automata for debugging.
173 ;; (automata_option "v")
174
175 (automata_option "w")
176
177 (include "itanium1.md")
178 (include "itanium2.md")
179
180 \f
181 ;; ::::::::::::::::::::
182 ;; ::
183 ;; :: Moves
184 ;; ::
185 ;; ::::::::::::::::::::
186
187 ;; Set of a single predicate register.  This is only used to implement
188 ;; pr-to-pr move and complement.
189
190 (define_insn "*movcci"
191   [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
192         (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
193   ""
194   "@
195    cmp.ne %0, p0 = r0, r0
196    cmp.eq %0, p0 = r0, r0
197    (%1) cmp.eq.unc %0, p0 = r0, r0"
198   [(set_attr "itanium_class" "icmp")
199    (set_attr "predicable" "no")])
200
201 (define_insn "movbi"
202   [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
203         (match_operand:BI 1 "move_operand"         " O,n, c,  c,*r, n,*m,*r,*r"))]
204   ""
205   "@
206    cmp.ne %0, %I0 = r0, r0
207    cmp.eq %0, %I0 = r0, r0
208    #
209    #
210    tbit.nz %0, %I0 = %1, 0
211    adds %0 = %1, r0
212    ld1%O1 %0 = %1%P1
213    st1%Q0 %0 = %1%P0
214    mov %0 = %1"
215   [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
216
217 (define_split
218   [(set (match_operand:BI 0 "register_operand" "")
219         (match_operand:BI 1 "register_operand" ""))]
220   "reload_completed
221    && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
222    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
223   [(cond_exec (ne (match_dup 1) (const_int 0))
224      (set (match_dup 0) (const_int 1)))
225    (cond_exec (eq (match_dup 1) (const_int 0))
226      (set (match_dup 0) (const_int 0)))]
227   "")
228
229 (define_split
230   [(set (match_operand:BI 0 "register_operand" "")
231         (match_operand:BI 1 "register_operand" ""))]
232   "reload_completed
233    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
234    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
235   [(set (match_dup 2) (match_dup 4))
236    (set (match_dup 3) (match_dup 5))
237    (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
238   "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
239    operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
240    operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
241    operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
242
243 (define_expand "movqi"
244   [(set (match_operand:QI 0 "general_operand" "")
245         (match_operand:QI 1 "general_operand" ""))]
246   ""
247 {
248   rtx op1 = ia64_expand_move (operands[0], operands[1]);
249   if (!op1)
250     DONE;
251   operands[1] = op1;
252 })
253
254 (define_insn "*movqi_internal"
255   [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
256         (match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
257   "ia64_move_ok (operands[0], operands[1])"
258   "@
259    mov %0 = %r1
260    addl %0 = %1, r0
261    ld1%O1 %0 = %1%P1
262    st1%Q0 %0 = %r1%P0
263    getf.sig %0 = %1
264    setf.sig %0 = %r1
265    mov %0 = %1"
266   [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
267
268 (define_expand "movhi"
269   [(set (match_operand:HI 0 "general_operand" "")
270         (match_operand:HI 1 "general_operand" ""))]
271   ""
272 {
273   rtx op1 = ia64_expand_move (operands[0], operands[1]);
274   if (!op1)
275     DONE;
276   operands[1] = op1;
277 })
278
279 (define_insn "*movhi_internal"
280   [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
281         (match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
282   "ia64_move_ok (operands[0], operands[1])"
283   "@
284    mov %0 = %r1
285    addl %0 = %1, r0
286    ld2%O1 %0 = %1%P1
287    st2%Q0 %0 = %r1%P0
288    getf.sig %0 = %1
289    setf.sig %0 = %r1
290    mov %0 = %1"
291   [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
292
293 (define_expand "movsi"
294   [(set (match_operand:SI 0 "general_operand" "")
295         (match_operand:SI 1 "general_operand" ""))]
296   ""
297 {
298   rtx op1 = ia64_expand_move (operands[0], operands[1]);
299   if (!op1)
300     DONE;
301   operands[1] = op1;
302 })
303
304 (define_insn "*movsi_internal"
305   [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
306         (match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
307   "ia64_move_ok (operands[0], operands[1])"
308   "@
309   mov %0 = %r1
310   addl %0 = %1, r0
311   movl %0 = %1
312   ld4%O1 %0 = %1%P1
313   st4%Q0 %0 = %r1%P0
314   getf.sig %0 = %1
315   setf.sig %0 = %r1
316   mov %0 = %1
317   mov %0 = %1
318   mov %0 = %r1"
319   ;; frar_m, toar_m ??? why not frar_i and toar_i
320   [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
321
322 (define_expand "movdi"
323   [(set (match_operand:DI 0 "general_operand" "")
324         (match_operand:DI 1 "general_operand" ""))]
325   ""
326 {
327   rtx op1 = ia64_expand_move (operands[0], operands[1]);
328   if (!op1)
329     DONE;
330   operands[1] = op1;
331 })
332
333 (define_insn "*movdi_internal"
334   [(set (match_operand:DI 0 "destination_operand"
335                     "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
336         (match_operand:DI 1 "move_operand"
337                     "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
338   "ia64_move_ok (operands[0], operands[1])"
339 {
340   static const char * const alt[] = {
341     "%,mov %0 = %r1",
342     "%,addl %0 = %1, r0",
343     "%,movl %0 = %1",
344     "%,ld8%O1 %0 = %1%P1",
345     "%,st8%Q0 %0 = %r1%P0",
346     "%,getf.sig %0 = %1",
347     "%,setf.sig %0 = %r1",
348     "%,mov %0 = %1",
349     "%,ldf8 %0 = %1%P1",
350     "%,stf8 %0 = %1%P0",
351     "%,mov %0 = %1",
352     "%,mov %0 = %r1",
353     "%,mov %0 = %1",
354     "%,mov %0 = %1",
355     "%,mov %0 = %1",
356     "%,mov %0 = %1",
357     "mov %0 = pr",
358     "mov pr = %1, -1"
359   };
360
361   if (which_alternative == 2 && ! TARGET_NO_PIC
362       && symbolic_operand (operands[1], VOIDmode))
363     abort ();
364
365   return alt[which_alternative];
366 }
367   [(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")])
368
369 (define_split
370   [(set (match_operand 0 "register_operand" "")
371         (match_operand 1 "symbolic_operand" ""))]
372   "reload_completed && ! TARGET_NO_PIC"
373   [(const_int 0)]
374 {
375   ia64_expand_load_address (operands[0], operands[1]);
376   DONE;
377 })
378
379 (define_expand "load_fptr"
380   [(set (match_dup 2)
381         (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
382    (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
383   ""
384 {
385   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
386   operands[3] = gen_const_mem (DImode, operands[2]);
387 })
388
389 (define_insn "*load_fptr_internal1"
390   [(set (match_operand:DI 0 "register_operand" "=r")
391         (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
392   ""
393   "addl %0 = @ltoff(@fptr(%1)), gp"
394   [(set_attr "itanium_class" "ialu")])
395
396 (define_insn "load_gprel"
397   [(set (match_operand:DI 0 "register_operand" "=r")
398         (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
399   ""
400   "addl %0 = @gprel(%1), gp"
401   [(set_attr "itanium_class" "ialu")])
402
403 (define_insn "gprel64_offset"
404   [(set (match_operand:DI 0 "register_operand" "=r")
405         (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
406   ""
407   "movl %0 = @gprel(%1)"
408   [(set_attr "itanium_class" "long_i")])
409
410 (define_expand "load_gprel64"
411   [(set (match_dup 2)
412         (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
413    (set (match_operand:DI 0 "register_operand" "")
414         (plus:DI (match_dup 3) (match_dup 2)))]
415   ""
416 {
417   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
418   operands[3] = pic_offset_table_rtx;
419 })
420
421 ;; This is used as a placeholder for the return address during early
422 ;; compilation.  We won't know where we've placed this until during
423 ;; reload, at which point it can wind up in b0, a general register,
424 ;; or memory.  The only safe destination under these conditions is a
425 ;; general register.
426
427 (define_insn_and_split "*movdi_ret_addr"
428   [(set (match_operand:DI 0 "register_operand" "=r")
429         (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
430   ""
431   "#"
432   "reload_completed"
433   [(const_int 0)]
434 {
435   ia64_split_return_addr_rtx (operands[0]);
436   DONE;
437 }
438   [(set_attr "itanium_class" "ialu")])
439
440 (define_insn "*load_symptr_high"
441   [(set (match_operand:DI 0 "register_operand" "=r")
442         (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
443                  (match_operand:DI 2 "register_operand" "a")))]
444   ""
445 {
446   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
447     return "%,addl %0 = @ltoffx(%1), %2";
448   else
449     return "%,addl %0 = @ltoff(%1), %2";
450 }
451   [(set_attr "itanium_class" "ialu")])
452
453 (define_insn "*load_symptr_low"
454   [(set (match_operand:DI 0 "register_operand" "=r")
455         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
456                    (match_operand 2 "got_symbolic_operand" "s")))]
457   ""
458 {
459   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
460     return "%,ld8.mov %0 = [%1], %2";
461   else
462     return "%,ld8 %0 = [%1]";
463 }
464   [(set_attr "itanium_class" "ld")])
465
466 (define_insn "load_ltoff_dtpmod"
467   [(set (match_operand:DI 0 "register_operand" "=r")
468         (plus:DI (reg:DI 1)
469                  (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
470                             UNSPEC_LTOFF_DTPMOD)))]
471   ""
472   "addl %0 = @ltoff(@dtpmod(%1)), gp"
473   [(set_attr "itanium_class" "ialu")])
474
475 (define_insn "load_ltoff_dtprel"
476   [(set (match_operand:DI 0 "register_operand" "=r")
477         (plus:DI (reg:DI 1)
478                  (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
479                             UNSPEC_LTOFF_DTPREL)))]
480   ""
481   "addl %0 = @ltoff(@dtprel(%1)), gp"
482   [(set_attr "itanium_class" "ialu")])
483
484 (define_expand "load_dtprel"
485   [(set (match_operand:DI 0 "register_operand" "")
486         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
487                    UNSPEC_DTPREL))]
488   ""
489   "")
490
491 (define_insn "*load_dtprel64"
492   [(set (match_operand:DI 0 "register_operand" "=r")
493         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
494                    UNSPEC_DTPREL))]
495   "TARGET_TLS64"
496   "movl %0 = @dtprel(%1)"
497   [(set_attr "itanium_class" "long_i")])
498
499 (define_insn "*load_dtprel22"
500   [(set (match_operand:DI 0 "register_operand" "=r")
501         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
502                    UNSPEC_DTPREL))]
503   ""
504   "addl %0 = @dtprel(%1), r0"
505   [(set_attr "itanium_class" "ialu")])
506
507 (define_expand "add_dtprel"
508   [(set (match_operand:DI 0 "register_operand" "")
509         (plus:DI (match_operand:DI 1 "register_operand" "")
510                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
511                             UNSPEC_DTPREL)))]
512   "!TARGET_TLS64"
513   "")
514
515 (define_insn "*add_dtprel14"
516   [(set (match_operand:DI 0 "register_operand" "=r")
517         (plus:DI (match_operand:DI 1 "register_operand" "r")
518                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
519                             UNSPEC_DTPREL)))]
520   "TARGET_TLS14"
521   "adds %0 = @dtprel(%2), %1"
522   [(set_attr "itanium_class" "ialu")])
523
524 (define_insn "*add_dtprel22"
525   [(set (match_operand:DI 0 "register_operand" "=r")
526         (plus:DI (match_operand:DI 1 "register_operand" "a")
527                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
528                             UNSPEC_DTPREL)))]
529   "TARGET_TLS22"
530   "addl %0 = @dtprel(%2), %1"
531   [(set_attr "itanium_class" "ialu")])
532
533 (define_insn "load_ltoff_tprel"
534   [(set (match_operand:DI 0 "register_operand" "=r")
535         (plus:DI (reg:DI 1)
536                  (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
537                             UNSPEC_LTOFF_TPREL)))]
538   ""
539   "addl %0 = @ltoff(@tprel(%1)), gp"
540   [(set_attr "itanium_class" "ialu")])
541
542 (define_expand "load_tprel"
543   [(set (match_operand:DI 0 "register_operand" "")
544         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
545                    UNSPEC_TPREL))]
546   ""
547   "")
548
549 (define_insn "*load_tprel64"
550   [(set (match_operand:DI 0 "register_operand" "=r")
551         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
552                    UNSPEC_TPREL))]
553   "TARGET_TLS64"
554   "movl %0 = @tprel(%1)"
555   [(set_attr "itanium_class" "long_i")])
556
557 (define_insn "*load_tprel22"
558   [(set (match_operand:DI 0 "register_operand" "=r")
559         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
560                    UNSPEC_TPREL))]
561   ""
562   "addl %0 = @tprel(%1), r0"
563   [(set_attr "itanium_class" "ialu")])
564
565 (define_expand "add_tprel"
566   [(set (match_operand:DI 0 "register_operand" "")
567         (plus:DI (match_operand:DI 1 "register_operand" "")
568                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
569                             UNSPEC_TPREL)))]
570   "!TARGET_TLS64"
571   "")
572
573 (define_insn "*add_tprel14"
574   [(set (match_operand:DI 0 "register_operand" "=r")
575         (plus:DI (match_operand:DI 1 "register_operand" "r")
576                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
577                             UNSPEC_TPREL)))]
578   "TARGET_TLS14"
579   "adds %0 = @tprel(%2), %1"
580   [(set_attr "itanium_class" "ialu")])
581
582 (define_insn "*add_tprel22"
583   [(set (match_operand:DI 0 "register_operand" "=r")
584         (plus:DI (match_operand:DI 1 "register_operand" "a")
585                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
586                             UNSPEC_TPREL)))]
587   "TARGET_TLS22"
588   "addl %0 = @tprel(%2), %1"
589   [(set_attr "itanium_class" "ialu")])
590
591 ;; With no offsettable memory references, we've got to have a scratch
592 ;; around to play with the second word.  However, in order to avoid a
593 ;; reload nightmare we lie, claim we don't need one, and fix it up
594 ;; in ia64_split_tmode_move.
595 (define_expand "movti"
596   [(set (match_operand:TI 0 "general_operand" "")
597         (match_operand:TI 1 "general_operand" ""))]
598   ""
599 {
600   rtx op1 = ia64_expand_move (operands[0], operands[1]);
601   if (!op1)
602     DONE;
603   operands[1] = op1;
604 })
605
606 (define_insn_and_split "*movti_internal"
607   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
608         (match_operand:TI 1 "general_operand"      "ri,m,r"))]
609   "ia64_move_ok (operands[0], operands[1])"
610   "#"
611   "reload_completed"
612   [(const_int 0)]
613 {
614   ia64_split_tmode_move (operands);
615   DONE;
616 }
617   [(set_attr "itanium_class" "unknown")
618    (set_attr "predicable" "no")])
619
620 ;; Floating Point Moves
621 ;;
622 ;; Note - Patterns for SF mode moves are compulsory, but
623 ;; patterns for DF are optional, as GCC can synthesize them.
624
625 (define_expand "movsf"
626   [(set (match_operand:SF 0 "general_operand" "")
627         (match_operand:SF 1 "general_operand" ""))]
628   ""
629 {
630   rtx op1 = ia64_expand_move (operands[0], operands[1]);
631   if (!op1)
632     DONE;
633   operands[1] = op1;
634 })
635
636 (define_insn "*movsf_internal"
637   [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
638         (match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
639   "ia64_move_ok (operands[0], operands[1])"
640   "@
641    mov %0 = %F1
642    ldfs %0 = %1%P1
643    stfs %0 = %F1%P0
644    getf.s %0 = %F1
645    setf.s %0 = %1
646    mov %0 = %1
647    ld4%O1 %0 = %1%P1
648    st4%Q0 %0 = %1%P0"
649   [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
650
651 (define_expand "movdf"
652   [(set (match_operand:DF 0 "general_operand" "")
653         (match_operand:DF 1 "general_operand" ""))]
654   ""
655 {
656   rtx op1 = ia64_expand_move (operands[0], operands[1]);
657   if (!op1)
658     DONE;
659   operands[1] = op1;
660 })
661
662 (define_insn "*movdf_internal"
663   [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
664         (match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
665   "ia64_move_ok (operands[0], operands[1])"
666   "@
667    mov %0 = %F1
668    ldfd %0 = %1%P1
669    stfd %0 = %F1%P0
670    getf.d %0 = %F1
671    setf.d %0 = %1
672    mov %0 = %1
673    ld8%O1 %0 = %1%P1
674    st8%Q0 %0 = %1%P0"
675   [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
676
677 ;; With no offsettable memory references, we've got to have a scratch
678 ;; around to play with the second word if the variable winds up in GRs.
679 (define_expand "movxf"
680   [(set (match_operand:XF 0 "general_operand" "")
681         (match_operand:XF 1 "general_operand" ""))]
682   ""
683 {
684   rtx op0 = operands[0];
685
686   if (GET_CODE (op0) == SUBREG)
687     op0 = SUBREG_REG (op0);
688
689   /* We must support XFmode loads into general registers for stdarg/vararg,
690      unprototyped calls, and a rare case where a long double is passed as
691      an argument after a float HFA fills the FP registers.  We split them into
692      DImode loads for convenience.  We also need to support XFmode stores
693      for the last case.  This case does not happen for stdarg/vararg routines,
694      because we do a block store to memory of unnamed arguments.  */
695
696   if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
697     {
698       /* We're hoping to transform everything that deals with XFmode
699          quantities and GR registers early in the compiler.  */
700       if (no_new_pseudos)
701         abort ();
702
703       /* Struct to register can just use TImode instead.  */
704       if ((GET_CODE (operands[1]) == SUBREG
705            && GET_MODE (SUBREG_REG (operands[1])) == TImode)
706           || (GET_CODE (operands[1]) == REG
707               && GR_REGNO_P (REGNO (operands[1]))))
708         {
709           rtx op1 = operands[1];
710
711           if (GET_CODE (op1) == SUBREG)
712             op1 = SUBREG_REG (op1);
713           else
714             op1 = gen_rtx_REG (TImode, REGNO (op1));
715
716           emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
717           DONE;
718         }
719
720       if (GET_CODE (operands[1]) == CONST_DOUBLE)
721         {
722           emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)),
723                           operand_subword (operands[1], 0, 0, XFmode));
724           emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1),
725                           operand_subword (operands[1], 1, 0, XFmode));
726           DONE;
727         }
728
729       /* If the quantity is in a register not known to be GR, spill it.  */
730       if (register_operand (operands[1], XFmode))
731         operands[1] = spill_xfmode_operand (operands[1], 1);
732
733       if (GET_CODE (operands[1]) == MEM)
734         {
735           rtx out[2];
736
737           out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0));
738           out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0) + 1);
739
740           emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
741           emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
742           DONE;
743         }
744
745       abort ();
746     }
747
748   if (GET_CODE (operands[1]) == REG && GR_REGNO_P (REGNO (operands[1])))
749     {
750       /* We're hoping to transform everything that deals with XFmode
751          quantities and GR registers early in the compiler.  */
752       if (no_new_pseudos)
753         abort ();
754
755       /* Op0 can't be a GR_REG here, as that case is handled above.
756          If op0 is a register, then we spill op1, so that we now have a
757          MEM operand.  This requires creating an XFmode subreg of a TImode reg
758          to force the spill.  */
759       if (register_operand (operands[0], XFmode))
760         {
761           rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
762           op1 = gen_rtx_SUBREG (XFmode, op1, 0);
763           operands[1] = spill_xfmode_operand (op1, 0);
764         }
765
766       else if (GET_CODE (operands[0]) == MEM)
767         {
768           rtx in[2];
769
770           in[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1]));
771           in[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
772
773           emit_move_insn (adjust_address (operands[0], DImode, 0), in[0]);
774           emit_move_insn (adjust_address (operands[0], DImode, 8), in[1]);
775           DONE;
776         }
777
778       else
779         abort ();
780     }
781
782   if (! reload_in_progress && ! reload_completed)
783     {
784       operands[1] = spill_xfmode_operand (operands[1], 0);
785
786       if (GET_MODE (op0) == TImode && GET_CODE (op0) == REG)
787         {
788           rtx memt, memx, in = operands[1];
789           if (CONSTANT_P (in))
790             in = validize_mem (force_const_mem (XFmode, in));
791           if (GET_CODE (in) == MEM)
792             memt = adjust_address (in, TImode, 0);
793           else
794             {
795               memt = assign_stack_temp (TImode, 16, 0);
796               memx = adjust_address (memt, XFmode, 0);
797               emit_move_insn (memx, in);
798             }
799           emit_move_insn (op0, memt);
800           DONE;
801         }
802
803       if (! ia64_move_ok (operands[0], operands[1]))
804         operands[1] = force_reg (XFmode, operands[1]);
805     }
806 })
807
808 ;; ??? There's no easy way to mind volatile acquire/release semantics.
809
810 (define_insn "*movxf_internal"
811   [(set (match_operand:XF 0 "destination_operand" "=f,f, m")
812         (match_operand:XF 1 "general_operand"     "fG,m,fG"))]
813   "ia64_move_ok (operands[0], operands[1])"
814   "@
815    mov %0 = %F1
816    ldfe %0 = %1%P1
817    stfe %0 = %F1%P0"
818   [(set_attr "itanium_class" "fmisc,fld,stf")])
819
820 ;; Better code generation via insns that deal with TFmode register pairs
821 ;; directly.  Same concerns apply as for TImode.
822 (define_expand "movtf"
823   [(set (match_operand:TF 0 "general_operand" "")
824         (match_operand:TF 1 "general_operand" ""))]
825   ""
826 {
827   rtx op1 = ia64_expand_move (operands[0], operands[1]);
828   if (!op1)
829     DONE;
830   operands[1] = op1;
831 })
832
833 (define_insn_and_split "*movtf_internal"
834   [(set (match_operand:TF 0 "destination_operand"  "=r,r,m")
835         (match_operand:TF 1 "general_operand"      "ri,m,r"))]
836   "ia64_move_ok (operands[0], operands[1])"
837   "#"
838   "reload_completed"
839   [(const_int 0)]
840 {
841   ia64_split_tmode_move (operands);
842   DONE;
843 }
844   [(set_attr "itanium_class" "unknown")
845    (set_attr "predicable" "no")])
846
847 \f
848 ;; ::::::::::::::::::::
849 ;; ::
850 ;; :: Conversions
851 ;; ::
852 ;; ::::::::::::::::::::
853
854 ;; Signed conversions from a smaller integer to a larger integer
855
856 (define_insn "extendqidi2"
857   [(set (match_operand:DI 0 "gr_register_operand" "=r")
858         (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
859   ""
860   "sxt1 %0 = %1"
861   [(set_attr "itanium_class" "xtd")])
862
863 (define_insn "extendhidi2"
864   [(set (match_operand:DI 0 "gr_register_operand" "=r")
865         (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
866   ""
867   "sxt2 %0 = %1"
868   [(set_attr "itanium_class" "xtd")])
869
870 (define_insn "extendsidi2"
871   [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
872         (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
873   ""
874   "@
875    sxt4 %0 = %1
876    fsxt.r %0 = %1, %1"
877   [(set_attr "itanium_class" "xtd,fmisc")])
878
879 ;; Unsigned conversions from a smaller integer to a larger integer
880
881 (define_insn "zero_extendqidi2"
882   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
883         (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
884   ""
885   "@
886    zxt1 %0 = %1
887    ld1%O1 %0 = %1%P1"
888   [(set_attr "itanium_class" "xtd,ld")])
889
890 (define_insn "zero_extendhidi2"
891   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
892         (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
893   ""
894   "@
895    zxt2 %0 = %1
896    ld2%O1 %0 = %1%P1"
897   [(set_attr "itanium_class" "xtd,ld")])
898
899 (define_insn "zero_extendsidi2"
900   [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
901         (zero_extend:DI
902           (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
903   ""
904   "@
905    addp4 %0 = %1, r0
906    ld4%O1 %0 = %1%P1
907    fmix.r %0 = f0, %1"
908   [(set_attr "itanium_class" "ialu,ld,fmisc")])
909
910 ;; Convert between floating point types of different sizes.
911
912 ;; At first glance, it would appear that emitting fnorm for an extending
913 ;; conversion is unnecessary.  However, the stf and getf instructions work
914 ;; correctly only if the input is properly rounded for its type.  In
915 ;; particular, we get the wrong result for getf.d/stfd if the input is a
916 ;; denorm single.  Since we don't know what the next instruction will be, we
917 ;; have to emit an fnorm.
918
919 ;; ??? Optimization opportunity here.  Get rid of the insn altogether
920 ;; when we can.  Should probably use a scheme like has been proposed
921 ;; for ia32 in dealing with operands that match unary operators.  This
922 ;; would let combine merge the thing into adjacent insns.  See also how the
923 ;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
924 ;; se_register_operand.
925
926 (define_insn "extendsfdf2"
927   [(set (match_operand:DF 0 "fr_register_operand" "=f")
928         (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
929   ""
930   "fnorm.d %0 = %1"
931   [(set_attr "itanium_class" "fmac")])
932
933 (define_insn "extendsfxf2"
934   [(set (match_operand:XF 0 "fr_register_operand" "=f")
935         (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]
936   ""
937   "fnorm %0 = %1"
938   [(set_attr "itanium_class" "fmac")])
939
940 (define_insn "extenddfxf2"
941   [(set (match_operand:XF 0 "fr_register_operand" "=f")
942         (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]
943   ""
944   "fnorm %0 = %1"
945   [(set_attr "itanium_class" "fmac")])
946
947 (define_insn "truncdfsf2"
948   [(set (match_operand:SF 0 "fr_register_operand" "=f")
949         (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
950   ""
951   "fnorm.s %0 = %1"
952   [(set_attr "itanium_class" "fmac")])
953
954 (define_insn "truncxfsf2"
955   [(set (match_operand:SF 0 "fr_register_operand" "=f")
956         (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]
957   ""
958   "fnorm.s %0 = %1"
959   [(set_attr "itanium_class" "fmac")])
960
961 (define_insn "truncxfdf2"
962   [(set (match_operand:DF 0 "fr_register_operand" "=f")
963         (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]
964   ""
965   "fnorm.d %0 = %1"
966   [(set_attr "itanium_class" "fmac")])
967
968 ;; Convert between signed integer types and floating point.
969
970 (define_insn "floatdixf2"
971   [(set (match_operand:XF 0 "fr_register_operand" "=f")
972         (float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
973   ""
974   "fcvt.xf %0 = %1"
975   [(set_attr "itanium_class" "fcvtfx")])
976
977 (define_insn "fix_truncsfdi2"
978   [(set (match_operand:DI 0 "fr_register_operand" "=f")
979         (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
980   ""
981   "fcvt.fx.trunc %0 = %1"
982   [(set_attr "itanium_class" "fcvtfx")])
983
984 (define_insn "fix_truncdfdi2"
985   [(set (match_operand:DI 0 "fr_register_operand" "=f")
986         (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
987   ""
988   "fcvt.fx.trunc %0 = %1"
989   [(set_attr "itanium_class" "fcvtfx")])
990
991 (define_insn "fix_truncxfdi2"
992   [(set (match_operand:DI 0 "fr_register_operand" "=f")
993         (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
994   ""
995   "fcvt.fx.trunc %0 = %1"
996   [(set_attr "itanium_class" "fcvtfx")])
997
998 (define_insn "fix_truncxfdi2_alts"
999   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1000         (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
1001    (use (match_operand:SI 2 "const_int_operand" ""))]
1002   ""
1003   "fcvt.fx.trunc.s%2 %0 = %1"
1004   [(set_attr "itanium_class" "fcvtfx")])
1005
1006 ;; Convert between unsigned integer types and floating point.
1007
1008 (define_insn "floatunsdisf2"
1009   [(set (match_operand:SF 0 "fr_register_operand" "=f")
1010         (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
1011   ""
1012   "fcvt.xuf.s %0 = %1"
1013   [(set_attr "itanium_class" "fcvtfx")])
1014
1015 (define_insn "floatunsdidf2"
1016   [(set (match_operand:DF 0 "fr_register_operand" "=f")
1017         (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
1018   ""
1019   "fcvt.xuf.d %0 = %1"
1020   [(set_attr "itanium_class" "fcvtfx")])
1021
1022 (define_insn "floatunsdixf2"
1023   [(set (match_operand:XF 0 "fr_register_operand" "=f")
1024         (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
1025   ""
1026   "fcvt.xuf %0 = %1"
1027   [(set_attr "itanium_class" "fcvtfx")])
1028
1029 (define_insn "fixuns_truncsfdi2"
1030   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1031         (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1032   ""
1033   "fcvt.fxu.trunc %0 = %1"
1034   [(set_attr "itanium_class" "fcvtfx")])
1035
1036 (define_insn "fixuns_truncdfdi2"
1037   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1038         (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1039   ""
1040   "fcvt.fxu.trunc %0 = %1"
1041   [(set_attr "itanium_class" "fcvtfx")])
1042
1043 (define_insn "fixuns_truncxfdi2"
1044   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1045         (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
1046   ""
1047   "fcvt.fxu.trunc %0 = %1"
1048   [(set_attr "itanium_class" "fcvtfx")])
1049
1050 (define_insn "fixuns_truncxfdi2_alts"
1051   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1052         (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
1053    (use (match_operand:SI 2 "const_int_operand" ""))]
1054   ""
1055   "fcvt.fxu.trunc.s%2 %0 = %1"
1056   [(set_attr "itanium_class" "fcvtfx")])
1057 \f
1058 ;; ::::::::::::::::::::
1059 ;; ::
1060 ;; :: Bit field extraction
1061 ;; ::
1062 ;; ::::::::::::::::::::
1063
1064 (define_insn "extv"
1065   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1066         (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1067                          (match_operand:DI 2 "const_int_operand" "n")
1068                          (match_operand:DI 3 "const_int_operand" "n")))]
1069   ""
1070   "extr %0 = %1, %3, %2"
1071   [(set_attr "itanium_class" "ishf")])
1072
1073 (define_insn "extzv"
1074   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1075         (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1076                          (match_operand:DI 2 "const_int_operand" "n")
1077                          (match_operand:DI 3 "const_int_operand" "n")))]
1078   ""
1079   "extr.u %0 = %1, %3, %2"
1080   [(set_attr "itanium_class" "ishf")])
1081
1082 ;; Insert a bit field.
1083 ;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1084 ;; Source1 can be 0 or -1.
1085 ;; Source2 can be 0.
1086
1087 ;; ??? Actual dep instruction is more powerful than what these insv
1088 ;; patterns support.  Unfortunately, combine is unable to create patterns
1089 ;; where source2 != dest.
1090
1091 (define_expand "insv"
1092   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1093                          (match_operand:DI 1 "const_int_operand" "")
1094                          (match_operand:DI 2 "const_int_operand" ""))
1095         (match_operand:DI 3 "nonmemory_operand" ""))]
1096   ""
1097 {
1098   int width = INTVAL (operands[1]);
1099   int shift = INTVAL (operands[2]);
1100
1101   /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1102      pseudo.  */
1103   if (! register_operand (operands[3], DImode)
1104       && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1105     operands[3] = force_reg (DImode, operands[3]);
1106
1107   /* If this is a single dep instruction, we have nothing to do.  */
1108   if (! ((register_operand (operands[3], DImode) && width <= 16)
1109          || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1110     {
1111       /* Check for cases that can be implemented with a mix instruction.  */
1112       if (width == 32 && shift == 0)
1113         {
1114           /* Directly generating the mix4left instruction confuses
1115              optimize_bit_field in function.c.  Since this is performing
1116              a useful optimization, we defer generation of the complicated
1117              mix4left RTL to the first splitting phase.  */
1118           rtx tmp = gen_reg_rtx (DImode);
1119           emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1120           DONE;
1121         }
1122       else if (width == 32 && shift == 32)
1123         {
1124           emit_insn (gen_mix4right (operands[0], operands[3]));
1125           DONE;
1126         }
1127
1128       /* We could handle remaining cases by emitting multiple dep
1129          instructions.
1130
1131          If we need more than two dep instructions then we lose.  A 6
1132          insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1133          mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,
1134          the latter is 6 cycles on an Itanium (TM) processor, because there is
1135          only one function unit that can execute dep and shr immed.
1136
1137          If we only need two dep instruction, then we still lose.
1138          mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away
1139          the unnecessary mov, this is still undesirable because it will be
1140          hard to optimize, and it creates unnecessary pressure on the I0
1141          function unit.  */
1142
1143       FAIL;
1144
1145 #if 0
1146       /* This code may be useful for other IA-64 processors, so we leave it in
1147          for now.  */
1148       while (width > 16)
1149         {
1150           rtx tmp;
1151
1152           emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1153                                operands[3]));
1154           shift += 16;
1155           width -= 16;
1156           tmp = gen_reg_rtx (DImode);
1157           emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1158           operands[3] = tmp;
1159         }
1160       operands[1] = GEN_INT (width);
1161       operands[2] = GEN_INT (shift);
1162 #endif
1163     }
1164 })
1165
1166 (define_insn "*insv_internal"
1167   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1168                          (match_operand:DI 1 "const_int_operand" "n")
1169                          (match_operand:DI 2 "const_int_operand" "n"))
1170         (match_operand:DI 3 "nonmemory_operand" "rP"))]
1171   "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1172    || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1173   "dep %0 = %3, %0, %2, %1"
1174   [(set_attr "itanium_class" "ishf")])
1175
1176 ;; Combine doesn't like to create bit-field insertions into zero.
1177 (define_insn "*shladdp4_internal"
1178   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1179         (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1180                            (match_operand:DI 2 "shladd_log2_operand" "n"))
1181                 (match_operand:DI 3 "const_int_operand" "n")))]
1182   "ia64_depz_field_mask (operands[3], operands[2]) + INTVAL (operands[2]) == 32"
1183   "shladdp4 %0 = %1, %2, r0"
1184   [(set_attr "itanium_class" "ialu")])
1185
1186 (define_insn "*depz_internal"
1187   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1188         (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1189                            (match_operand:DI 2 "const_int_operand" "n"))
1190                 (match_operand:DI 3 "const_int_operand" "n")))]
1191   "CONST_OK_FOR_M (INTVAL (operands[2]))
1192    && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1193 {
1194   operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1195   return "%,dep.z %0 = %1, %2, %3";
1196 }
1197   [(set_attr "itanium_class" "ishf")])
1198
1199 (define_insn "shift_mix4left"
1200   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1201                          (const_int 32) (const_int 0))
1202         (match_operand:DI 1 "gr_register_operand" "r"))
1203    (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1204   ""
1205   "#"
1206   [(set_attr "itanium_class" "unknown")])
1207
1208 (define_split
1209   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1210                          (const_int 32) (const_int 0))
1211         (match_operand:DI 1 "register_operand" ""))
1212    (clobber (match_operand:DI 2 "register_operand" ""))]
1213   ""
1214   [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1215    (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1216         (lshiftrt:DI (match_dup 3) (const_int 32)))]
1217   "operands[3] = operands[2];")
1218
1219 (define_insn "*mix4left"
1220   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1221                          (const_int 32) (const_int 0))
1222         (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1223                      (const_int 32)))]
1224   ""
1225   "mix4.l %0 = %0, %r1"
1226   [(set_attr "itanium_class" "mmshf")])
1227
1228 (define_insn "mix4right"
1229   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1230                          (const_int 32) (const_int 32))
1231         (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1232   ""
1233   "mix4.r %0 = %r1, %0"
1234   [(set_attr "itanium_class" "mmshf")])
1235
1236 ;; This is used by the rotrsi3 pattern.
1237
1238 (define_insn "*mix4right_3op"
1239   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1240         (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1241                 (ashift:DI (zero_extend:DI
1242                              (match_operand:SI 2 "gr_register_operand" "r"))
1243                            (const_int 32))))]
1244   ""
1245   "mix4.r %0 = %2, %1"
1246   [(set_attr "itanium_class" "mmshf")])
1247
1248 \f
1249 ;; ::::::::::::::::::::
1250 ;; ::
1251 ;; :: 1 bit Integer arithmetic
1252 ;; ::
1253 ;; ::::::::::::::::::::
1254
1255 (define_insn_and_split "andbi3"
1256   [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1257         (and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1258                 (match_operand:BI 2 "register_operand" "c,r,r")))]
1259   ""
1260   "@
1261    #
1262    tbit.nz.and.orcm %0, %I0 = %2, 0
1263    and %0 = %2, %1"
1264   "reload_completed
1265    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1266    && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1267   [(cond_exec (eq (match_dup 2) (const_int 0))
1268      (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1269                                 (match_dup 0))))]
1270   ""
1271   [(set_attr "itanium_class" "unknown,tbit,ilog")])
1272
1273 (define_insn_and_split "*andcmbi3"
1274   [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1275         (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
1276                 (match_operand:BI 2 "register_operand" "0,0,r")))]
1277   ""
1278   "@
1279    #
1280    tbit.z.and.orcm %0, %I0 = %1, 0
1281    andcm %0 = %2, %1"
1282   "reload_completed
1283    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1284    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1285   [(cond_exec (ne (match_dup 1) (const_int 0))
1286      (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1287                                 (match_dup 0))))]
1288   ""
1289   [(set_attr "itanium_class" "unknown,tbit,ilog")])
1290
1291 (define_insn_and_split "iorbi3"
1292   [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1293         (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1294                 (match_operand:BI 2 "register_operand" "c,r,r")))]
1295   ""
1296   "@
1297    #
1298    tbit.nz.or.andcm %0, %I0 = %2, 0
1299    or %0 = %2, %1"
1300   "reload_completed
1301    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1302    && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1303   [(cond_exec (ne (match_dup 2) (const_int 0))
1304      (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1305                                 (match_dup 0))))]
1306   ""
1307   [(set_attr "itanium_class" "unknown,tbit,ilog")])
1308
1309 (define_insn_and_split "*iorcmbi3"
1310   [(set (match_operand:BI 0 "register_operand" "=c,c")
1311         (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
1312                 (match_operand:BI 2 "register_operand" "0,0")))]
1313   ""
1314   "@
1315    #
1316    tbit.z.or.andcm %0, %I0 = %1, 0"
1317   "reload_completed
1318    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1319    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1320   [(cond_exec (eq (match_dup 1) (const_int 0))
1321      (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1322                                 (match_dup 0))))]
1323   ""
1324   [(set_attr "itanium_class" "unknown,tbit")])
1325
1326 (define_insn "one_cmplbi2"
1327   [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
1328         (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
1329    (clobber (match_scratch:BI 2 "=X,X,c,X"))]
1330   ""
1331   "@
1332    tbit.z %0, %I0 = %1, 0
1333    xor %0 = 1, %1
1334    #
1335    #"
1336   [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
1337
1338 (define_split
1339   [(set (match_operand:BI 0 "register_operand" "")
1340         (not:BI (match_operand:BI 1 "register_operand" "")))
1341    (clobber (match_scratch:BI 2 ""))]
1342   "reload_completed
1343    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1344    && rtx_equal_p (operands[0], operands[1])"
1345   [(set (match_dup 4) (match_dup 3))
1346    (set (match_dup 0) (const_int 1))
1347    (cond_exec (ne (match_dup 2) (const_int 0))
1348      (set (match_dup 0) (const_int 0)))
1349    (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1350   "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
1351    operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
1352
1353 (define_split
1354   [(set (match_operand:BI 0 "register_operand" "")
1355         (not:BI (match_operand:BI 1 "register_operand" "")))
1356    (clobber (match_scratch:BI 2 ""))]
1357   "reload_completed
1358    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1359    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1360    && ! rtx_equal_p (operands[0], operands[1])"
1361   [(cond_exec (ne (match_dup 1) (const_int 0))
1362      (set (match_dup 0) (const_int 0)))
1363    (cond_exec (eq (match_dup 1) (const_int 0))
1364      (set (match_dup 0) (const_int 1)))
1365    (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1366   "")
1367
1368 (define_insn "*cmpsi_and_0"
1369   [(set (match_operand:BI 0 "register_operand" "=c")
1370         (and:BI (match_operator:BI 4 "predicate_operator"
1371                   [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1372                    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1373                 (match_operand:BI 1 "register_operand" "0")))]
1374   ""
1375   "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
1376   [(set_attr "itanium_class" "icmp")])
1377
1378 (define_insn "*cmpsi_and_1"
1379   [(set (match_operand:BI 0 "register_operand" "=c")
1380         (and:BI (match_operator:BI 3 "signed_inequality_operator"
1381                   [(match_operand:SI 2 "gr_register_operand" "r")
1382                    (const_int 0)])
1383                 (match_operand:BI 1 "register_operand" "0")))]
1384   ""
1385   "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
1386   [(set_attr "itanium_class" "icmp")])
1387
1388 (define_insn "*cmpsi_andnot_0"
1389   [(set (match_operand:BI 0 "register_operand" "=c")
1390         (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1391                          [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1392                           (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1393                 (match_operand:BI 1 "register_operand" "0")))]
1394   ""
1395   "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
1396   [(set_attr "itanium_class" "icmp")])
1397
1398 (define_insn "*cmpsi_andnot_1"
1399   [(set (match_operand:BI 0 "register_operand" "=c")
1400         (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1401                           [(match_operand:SI 2 "gr_register_operand" "r")
1402                            (const_int 0)]))
1403                 (match_operand:BI 1 "register_operand" "0")))]
1404   ""
1405   "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
1406   [(set_attr "itanium_class" "icmp")])
1407
1408 (define_insn "*cmpdi_and_0"
1409   [(set (match_operand:BI 0 "register_operand" "=c")
1410         (and:BI (match_operator:BI 4 "predicate_operator"
1411                   [(match_operand:DI 2 "gr_register_operand" "r")
1412                    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1413                 (match_operand:BI 1 "register_operand" "0")))]
1414   ""
1415   "cmp.%C4.and.orcm %0, %I0 = %3, %2"
1416   [(set_attr "itanium_class" "icmp")])
1417
1418 (define_insn "*cmpdi_and_1"
1419   [(set (match_operand:BI 0 "register_operand" "=c")
1420         (and:BI (match_operator:BI 3 "signed_inequality_operator"
1421                   [(match_operand:DI 2 "gr_register_operand" "r")
1422                    (const_int 0)])
1423                 (match_operand:BI 1 "register_operand" "0")))]
1424   ""
1425   "cmp.%C3.and.orcm %0, %I0 = r0, %2"
1426   [(set_attr "itanium_class" "icmp")])
1427
1428 (define_insn "*cmpdi_andnot_0"
1429   [(set (match_operand:BI 0 "register_operand" "=c")
1430         (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1431                          [(match_operand:DI 2 "gr_register_operand" "r")
1432                           (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1433                 (match_operand:BI 1 "register_operand" "0")))]
1434   ""
1435   "cmp.%C4.or.andcm %I0, %0 = %3, %2"
1436   [(set_attr "itanium_class" "icmp")])
1437
1438 (define_insn "*cmpdi_andnot_1"
1439   [(set (match_operand:BI 0 "register_operand" "=c")
1440         (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1441                           [(match_operand:DI 2 "gr_register_operand" "r")
1442                            (const_int 0)]))
1443                 (match_operand:BI 1 "register_operand" "0")))]
1444   ""
1445   "cmp.%C3.or.andcm %I0, %0 = r0, %2"
1446   [(set_attr "itanium_class" "icmp")])
1447
1448 (define_insn "*tbit_and_0"
1449   [(set (match_operand:BI 0 "register_operand" "=c")
1450         (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1451                                (const_int 1))
1452                        (const_int 0))
1453                 (match_operand:BI 2 "register_operand" "0")))]
1454   ""
1455   "tbit.nz.and.orcm %0, %I0 = %1, 0"
1456   [(set_attr "itanium_class" "tbit")])
1457
1458 (define_insn "*tbit_and_1"
1459   [(set (match_operand:BI 0 "register_operand" "=c")
1460         (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1461                                (const_int 1))
1462                        (const_int 0))
1463                 (match_operand:BI 2 "register_operand" "0")))]
1464   ""
1465   "tbit.z.and.orcm %0, %I0 = %1, 0"
1466   [(set_attr "itanium_class" "tbit")])
1467
1468 (define_insn "*tbit_and_2"
1469   [(set (match_operand:BI 0 "register_operand" "=c")
1470         (and:BI (ne:BI (zero_extract:DI
1471                          (match_operand:DI 1 "gr_register_operand" "r")
1472                          (const_int 1)
1473                          (match_operand:DI 2 "const_int_operand" "n"))
1474                        (const_int 0))
1475                 (match_operand:BI 3 "register_operand" "0")))]
1476   ""
1477   "tbit.nz.and.orcm %0, %I0 = %1, %2"
1478   [(set_attr "itanium_class" "tbit")])
1479
1480 (define_insn "*tbit_and_3"
1481   [(set (match_operand:BI 0 "register_operand" "=c")
1482         (and:BI (eq:BI (zero_extract:DI
1483                          (match_operand:DI 1 "gr_register_operand" "r")
1484                          (const_int 1)
1485                          (match_operand:DI 2 "const_int_operand" "n"))
1486                        (const_int 0))
1487                 (match_operand:BI 3 "register_operand" "0")))]
1488   ""
1489   "tbit.z.and.orcm %0, %I0 = %1, %2"
1490   [(set_attr "itanium_class" "tbit")])
1491
1492 (define_insn "*cmpsi_or_0"
1493   [(set (match_operand:BI 0 "register_operand" "=c")
1494         (ior:BI (match_operator:BI 4 "predicate_operator"
1495                   [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1496                    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1497                 (match_operand:BI 1 "register_operand" "0")))]
1498   ""
1499   "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
1500   [(set_attr "itanium_class" "icmp")])
1501
1502 (define_insn "*cmpsi_or_1"
1503   [(set (match_operand:BI 0 "register_operand" "=c")
1504         (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1505                   [(match_operand:SI 2 "gr_register_operand" "r")
1506                    (const_int 0)])
1507                 (match_operand:BI 1 "register_operand" "0")))]
1508   ""
1509   "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
1510   [(set_attr "itanium_class" "icmp")])
1511
1512 (define_insn "*cmpsi_orcm_0"
1513   [(set (match_operand:BI 0 "register_operand" "=c")
1514         (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1515                          [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1516                           (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1517                 (match_operand:BI 1 "register_operand" "0")))]
1518   ""
1519   "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
1520   [(set_attr "itanium_class" "icmp")])
1521
1522 (define_insn "*cmpsi_orcm_1"
1523   [(set (match_operand:BI 0 "register_operand" "=c")
1524         (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1525                           [(match_operand:SI 2 "gr_register_operand" "r")
1526                            (const_int 0)]))
1527                 (match_operand:BI 1 "register_operand" "0")))]
1528   ""
1529   "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
1530   [(set_attr "itanium_class" "icmp")])
1531
1532 (define_insn "*cmpdi_or_0"
1533   [(set (match_operand:BI 0 "register_operand" "=c")
1534         (ior:BI (match_operator:BI 4 "predicate_operator"
1535                   [(match_operand:DI 2 "gr_register_operand" "r")
1536                    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1537                 (match_operand:BI 1 "register_operand" "0")))]
1538   ""
1539   "cmp.%C4.or.andcm %0, %I0 = %3, %2"
1540   [(set_attr "itanium_class" "icmp")])
1541
1542 (define_insn "*cmpdi_or_1"
1543   [(set (match_operand:BI 0 "register_operand" "=c")
1544         (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1545                   [(match_operand:DI 2 "gr_register_operand" "r")
1546                    (const_int 0)])
1547                 (match_operand:BI 1 "register_operand" "0")))]
1548   ""
1549   "cmp.%C3.or.andcm %0, %I0 = r0, %2"
1550   [(set_attr "itanium_class" "icmp")])
1551
1552 (define_insn "*cmpdi_orcm_0"
1553   [(set (match_operand:BI 0 "register_operand" "=c")
1554         (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1555                          [(match_operand:DI 2 "gr_register_operand" "r")
1556                           (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1557                 (match_operand:BI 1 "register_operand" "0")))]
1558   ""
1559   "cmp.%C4.and.orcm %I0, %0 = %3, %2"
1560   [(set_attr "itanium_class" "icmp")])
1561
1562 (define_insn "*cmpdi_orcm_1"
1563   [(set (match_operand:BI 0 "register_operand" "=c")
1564         (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1565                           [(match_operand:DI 2 "gr_register_operand" "r")
1566                            (const_int 0)]))
1567                 (match_operand:BI 1 "register_operand" "0")))]
1568   ""
1569   "cmp.%C3.and.orcm %I0, %0 = r0, %2"
1570   [(set_attr "itanium_class" "icmp")])
1571
1572 (define_insn "*tbit_or_0"
1573   [(set (match_operand:BI 0 "register_operand" "=c")
1574         (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1575                                (const_int 1))
1576                        (const_int 0))
1577                 (match_operand:BI 2 "register_operand" "0")))]
1578   ""
1579   "tbit.nz.or.andcm %0, %I0 = %1, 0"
1580   [(set_attr "itanium_class" "tbit")])
1581
1582 (define_insn "*tbit_or_1"
1583   [(set (match_operand:BI 0 "register_operand" "=c")
1584         (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1585                                (const_int 1))
1586                        (const_int 0))
1587                 (match_operand:BI 2 "register_operand" "0")))]
1588   ""
1589   "tbit.z.or.andcm %0, %I0 = %1, 0"
1590   [(set_attr "itanium_class" "tbit")])
1591
1592 (define_insn "*tbit_or_2"
1593   [(set (match_operand:BI 0 "register_operand" "=c")
1594         (ior:BI (ne:BI (zero_extract:DI
1595                          (match_operand:DI 1 "gr_register_operand" "r")
1596                          (const_int 1)
1597                          (match_operand:DI 2 "const_int_operand" "n"))
1598                        (const_int 0))
1599                 (match_operand:BI 3 "register_operand" "0")))]
1600   ""
1601   "tbit.nz.or.andcm %0, %I0 = %1, %2"
1602   [(set_attr "itanium_class" "tbit")])
1603
1604 (define_insn "*tbit_or_3"
1605   [(set (match_operand:BI 0 "register_operand" "=c")
1606         (ior:BI (eq:BI (zero_extract:DI
1607                          (match_operand:DI 1 "gr_register_operand" "r")
1608                          (const_int 1)
1609                          (match_operand:DI 2 "const_int_operand" "n"))
1610                        (const_int 0))
1611                 (match_operand:BI 3 "register_operand" "0")))]
1612   ""
1613   "tbit.z.or.andcm %0, %I0 = %1, %2"
1614   [(set_attr "itanium_class" "tbit")])
1615
1616 ;; Transform test of and/or of setcc into parallel comparisons.
1617
1618 (define_split
1619   [(set (match_operand:BI 0 "register_operand" "")
1620         (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1621                               (const_int 0))
1622                        (match_operand:DI 3 "register_operand" ""))
1623                (const_int 0)))]
1624   ""
1625   [(set (match_dup 0)
1626         (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1627                 (match_dup 2)))]
1628   "")
1629
1630 (define_split
1631   [(set (match_operand:BI 0 "register_operand" "")
1632         (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1633                               (const_int 0))
1634                        (match_operand:DI 3 "register_operand" ""))
1635                (const_int 0)))]
1636   ""
1637   [(set (match_dup 0)
1638         (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1639                 (match_dup 2)))
1640    (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1641               (clobber (scratch))])]
1642   "")
1643
1644 (define_split
1645   [(set (match_operand:BI 0 "register_operand" "")
1646         (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1647                               (const_int 0))
1648                        (match_operand:DI 3 "register_operand" ""))
1649                (const_int 0)))]
1650   ""
1651   [(set (match_dup 0) 
1652         (ior:BI (ne:BI (match_dup 3) (const_int 0))
1653                 (match_dup 2)))]
1654   "")
1655
1656 (define_split
1657   [(set (match_operand:BI 0 "register_operand" "")
1658         (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1659                               (const_int 0))
1660                        (match_operand:DI 3 "register_operand" ""))
1661                (const_int 0)))]
1662   ""
1663   [(set (match_dup 0) 
1664         (ior:BI (ne:BI (match_dup 3) (const_int 0))
1665                 (match_dup 2)))
1666    (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1667               (clobber (scratch))])]
1668   "")
1669
1670 ;; ??? Incredibly hackish.  Either need four proper patterns with all
1671 ;; the alternatives, or rely on sched1 to split the insn and hope that
1672 ;; nothing bad happens to the comparisons in the meantime.
1673 ;;
1674 ;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1675 ;; that we're doing height reduction.
1676 ;
1677 ;(define_insn_and_split ""
1678 ;  [(set (match_operand:BI 0 "register_operand" "=c")
1679 ;       (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1680 ;                         [(match_operand 2 "" "")
1681 ;                          (match_operand 3 "" "")])
1682 ;                       (match_operator:BI 4 "comparison_operator"
1683 ;                         [(match_operand 5 "" "")
1684 ;                          (match_operand 6 "" "")]))
1685 ;               (match_dup 0)))]
1686 ;  "flag_schedule_insns"
1687 ;  "#"
1688 ;  ""
1689 ;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
1690 ;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
1691 ;  "")
1692 ;
1693 ;(define_insn_and_split ""
1694 ;  [(set (match_operand:BI 0 "register_operand" "=c")
1695 ;       (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1696 ;                         [(match_operand 2 "" "")
1697 ;                          (match_operand 3 "" "")])
1698 ;                       (match_operator:BI 4 "comparison_operator"
1699 ;                         [(match_operand 5 "" "")
1700 ;                          (match_operand 6 "" "")]))
1701 ;               (match_dup 0)))]
1702 ;  "flag_schedule_insns"
1703 ;  "#"
1704 ;  ""
1705 ;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
1706 ;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
1707 ;  "")
1708 ;
1709 ;(define_split
1710 ;  [(set (match_operand:BI 0 "register_operand" "")
1711 ;       (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1712 ;                         [(match_operand 2 "" "")
1713 ;                          (match_operand 3 "" "")])
1714 ;                       (match_operand:BI 7 "register_operand" ""))
1715 ;               (and:BI (match_operator:BI 4 "comparison_operator"
1716 ;                         [(match_operand 5 "" "")
1717 ;                          (match_operand 6 "" "")])
1718 ;                       (match_operand:BI 8 "register_operand" ""))))]
1719 ;  ""
1720 ;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
1721 ;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
1722 ;                             (match_dup 0)))]
1723 ;  "")
1724 ;
1725 ;(define_split
1726 ;  [(set (match_operand:BI 0 "register_operand" "")
1727 ;       (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1728 ;                         [(match_operand 2 "" "")
1729 ;                          (match_operand 3 "" "")])
1730 ;                       (match_operand:BI 7 "register_operand" ""))
1731 ;               (ior:BI (match_operator:BI 4 "comparison_operator"
1732 ;                         [(match_operand 5 "" "")
1733 ;                          (match_operand 6 "" "")])
1734 ;                       (match_operand:BI 8 "register_operand" ""))))]
1735 ;  ""
1736 ;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
1737 ;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
1738 ;                             (match_dup 0)))]
1739 ;  "")
1740
1741 ;; Try harder to avoid predicate copies by duplicating compares.
1742 ;; Note that we'll have already split the predicate copy, which
1743 ;; is kind of a pain, but oh well.
1744
1745 (define_peephole2
1746   [(set (match_operand:BI 0 "register_operand" "")
1747         (match_operand:BI 1 "comparison_operator" ""))
1748    (set (match_operand:CCI 2 "register_operand" "")
1749         (match_operand:CCI 3 "register_operand" ""))
1750    (set (match_operand:CCI 4 "register_operand" "")
1751         (match_operand:CCI 5 "register_operand" ""))
1752    (set (match_operand:BI 6 "register_operand" "")
1753         (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
1754   "REGNO (operands[3]) == REGNO (operands[0])
1755    && REGNO (operands[4]) == REGNO (operands[0]) + 1
1756    && REGNO (operands[4]) == REGNO (operands[2]) + 1
1757    && REGNO (operands[6]) == REGNO (operands[2])"
1758   [(set (match_dup 0) (match_dup 1))
1759    (set (match_dup 6) (match_dup 7))]
1760   "operands[7] = copy_rtx (operands[1]);")
1761 \f
1762 ;; ::::::::::::::::::::
1763 ;; ::
1764 ;; :: 16 bit Integer arithmetic
1765 ;; ::
1766 ;; ::::::::::::::::::::
1767
1768 (define_insn "mulhi3"
1769   [(set (match_operand:HI 0 "gr_register_operand" "=r")
1770         (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1771                  (match_operand:HI 2 "gr_register_operand" "r")))]
1772   ""
1773   "pmpy2.r %0 = %1, %2"
1774   [(set_attr "itanium_class" "mmmul")])
1775
1776 \f
1777 ;; ::::::::::::::::::::
1778 ;; ::
1779 ;; :: 32 bit Integer arithmetic
1780 ;; ::
1781 ;; ::::::::::::::::::::
1782
1783 (define_insn "addsi3"
1784   [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1785         (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1786                  (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1787   ""
1788   "@
1789    add %0 = %1, %2
1790    adds %0 = %2, %1
1791    addl %0 = %2, %1"
1792   [(set_attr "itanium_class" "ialu")])
1793
1794 (define_insn "*addsi3_plus1"
1795   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1796         (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1797                           (match_operand:SI 2 "gr_register_operand" "r"))
1798                  (const_int 1)))]
1799   ""
1800   "add %0 = %1, %2, 1"
1801   [(set_attr "itanium_class" "ialu")])
1802
1803 (define_insn "*addsi3_plus1_alt"
1804   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1805         (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1806                           (const_int 2))
1807                  (const_int 1)))]
1808   ""
1809   "add %0 = %1, %1, 1"
1810   [(set_attr "itanium_class" "ialu")])
1811
1812 (define_insn "*addsi3_shladd"
1813   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1814         (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1815                           (match_operand:SI 2 "shladd_operand" "n"))
1816                  (match_operand:SI 3 "gr_register_operand" "r")))]
1817   ""
1818   "shladd %0 = %1, %S2, %3"
1819   [(set_attr "itanium_class" "ialu")])
1820
1821 (define_insn "subsi3"
1822   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1823         (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1824                   (match_operand:SI 2 "gr_register_operand" "r")))]
1825   ""
1826   "sub %0 = %1, %2"
1827   [(set_attr "itanium_class" "ialu")])
1828
1829 (define_insn "*subsi3_minus1"
1830   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1831         (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1832                  (match_operand:SI 2 "gr_register_operand" "r")))]
1833   ""
1834   "sub %0 = %2, %1, 1"
1835   [(set_attr "itanium_class" "ialu")])
1836
1837 ;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
1838
1839 (define_insn "mulsi3"
1840   [(set (match_operand:SI 0 "fr_register_operand" "=f")
1841         (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1842                  (match_operand:SI 2 "grfr_register_operand" "f")))]
1843   ""
1844   "xmpy.l %0 = %1, %2"
1845   [(set_attr "itanium_class" "xmpy")])
1846
1847 (define_insn "maddsi4"
1848   [(set (match_operand:SI 0 "fr_register_operand" "=f")
1849         (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1850                           (match_operand:SI 2 "grfr_register_operand" "f"))
1851                  (match_operand:SI 3 "grfr_register_operand" "f")))]
1852   ""
1853   "xma.l %0 = %1, %2, %3"
1854   [(set_attr "itanium_class" "xmpy")])
1855
1856 (define_insn "negsi2"
1857   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1858         (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
1859   ""
1860   "sub %0 = r0, %1"
1861   [(set_attr "itanium_class" "ialu")])
1862
1863 (define_expand "abssi2"
1864   [(set (match_dup 2)
1865         (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1866    (set (match_operand:SI 0 "gr_register_operand" "")
1867         (if_then_else:SI (eq (match_dup 2) (const_int 0))
1868                          (neg:SI (match_dup 1))
1869                          (match_dup 1)))]
1870   ""
1871   { operands[2] = gen_reg_rtx (BImode); })
1872
1873 (define_expand "sminsi3"
1874   [(set (match_dup 3)
1875         (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1876                (match_operand:SI 2 "gr_register_operand" "")))
1877    (set (match_operand:SI 0 "gr_register_operand" "")
1878         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1879                          (match_dup 2) (match_dup 1)))]
1880   ""
1881   { operands[3] = gen_reg_rtx (BImode); })
1882
1883 (define_expand "smaxsi3"
1884   [(set (match_dup 3)
1885         (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1886                (match_operand:SI 2 "gr_register_operand" "")))
1887    (set (match_operand:SI 0 "gr_register_operand" "")
1888         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1889                          (match_dup 1) (match_dup 2)))]
1890   ""
1891   { operands[3] = gen_reg_rtx (BImode); })
1892
1893 (define_expand "uminsi3"
1894   [(set (match_dup 3)
1895         (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1896                 (match_operand:SI 2 "gr_register_operand" "")))
1897    (set (match_operand:SI 0 "gr_register_operand" "")
1898         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1899                          (match_dup 2) (match_dup 1)))]
1900   ""
1901   { operands[3] = gen_reg_rtx (BImode); })
1902
1903 (define_expand "umaxsi3"
1904   [(set (match_dup 3)
1905         (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1906                 (match_operand:SI 2 "gr_register_operand" "")))
1907    (set (match_operand:SI 0 "gr_register_operand" "")
1908         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1909                          (match_dup 1) (match_dup 2)))]
1910   ""
1911   { operands[3] = gen_reg_rtx (BImode); })
1912
1913 (define_expand "divsi3"
1914   [(set (match_operand:SI 0 "register_operand" "")
1915         (div:SI (match_operand:SI 1 "general_operand" "")
1916                 (match_operand:SI 2 "general_operand" "")))]
1917   "TARGET_INLINE_INT_DIV"
1918 {
1919   rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
1920
1921   op0_xf = gen_reg_rtx (XFmode);
1922   op0_di = gen_reg_rtx (DImode);
1923
1924   if (CONSTANT_P (operands[1]))
1925     operands[1] = force_reg (SImode, operands[1]);
1926   op1_xf = gen_reg_rtx (XFmode);
1927   expand_float (op1_xf, operands[1], 0);
1928
1929   if (CONSTANT_P (operands[2]))
1930     operands[2] = force_reg (SImode, operands[2]);
1931   op2_xf = gen_reg_rtx (XFmode);
1932   expand_float (op2_xf, operands[2], 0);
1933
1934   /* 2^-34 */
1935   twon34_exp = gen_reg_rtx (DImode);
1936   emit_move_insn (twon34_exp, GEN_INT (65501));
1937   twon34 = gen_reg_rtx (XFmode);
1938   emit_insn (gen_setf_exp_xf (twon34, twon34_exp));
1939
1940   emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1941
1942   emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
1943   emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1944   DONE;
1945 })
1946
1947 (define_expand "modsi3"
1948   [(set (match_operand:SI 0 "register_operand" "")
1949         (mod:SI (match_operand:SI 1 "general_operand" "")
1950                 (match_operand:SI 2 "general_operand" "")))]
1951   "TARGET_INLINE_INT_DIV"
1952 {
1953   rtx op2_neg, op1_di, div;
1954
1955   div = gen_reg_rtx (SImode);
1956   emit_insn (gen_divsi3 (div, operands[1], operands[2]));
1957
1958   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1959
1960   /* This is a trick to get us to reuse the value that we're sure to
1961      have already copied to the FP regs.  */
1962   op1_di = gen_reg_rtx (DImode);
1963   convert_move (op1_di, operands[1], 0);
1964
1965   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1966                           gen_lowpart (SImode, op1_di)));
1967   DONE;
1968 })
1969
1970 (define_expand "udivsi3"
1971   [(set (match_operand:SI 0 "register_operand" "")
1972         (udiv:SI (match_operand:SI 1 "general_operand" "")
1973                  (match_operand:SI 2 "general_operand" "")))]
1974   "TARGET_INLINE_INT_DIV"
1975 {
1976   rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
1977
1978   op0_xf = gen_reg_rtx (XFmode);
1979   op0_di = gen_reg_rtx (DImode);
1980
1981   if (CONSTANT_P (operands[1]))
1982     operands[1] = force_reg (SImode, operands[1]);
1983   op1_xf = gen_reg_rtx (XFmode);
1984   expand_float (op1_xf, operands[1], 1);
1985
1986   if (CONSTANT_P (operands[2]))
1987     operands[2] = force_reg (SImode, operands[2]);
1988   op2_xf = gen_reg_rtx (XFmode);
1989   expand_float (op2_xf, operands[2], 1);
1990
1991   /* 2^-34 */
1992   twon34_exp = gen_reg_rtx (DImode);
1993   emit_move_insn (twon34_exp, GEN_INT (65501));
1994   twon34 = gen_reg_rtx (XFmode);
1995   emit_insn (gen_setf_exp_xf (twon34, twon34_exp));
1996
1997   emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1998
1999   emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
2000   emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
2001   DONE;
2002 })
2003
2004 (define_expand "umodsi3"
2005   [(set (match_operand:SI 0 "register_operand" "")
2006         (umod:SI (match_operand:SI 1 "general_operand" "")
2007                  (match_operand:SI 2 "general_operand" "")))]
2008   "TARGET_INLINE_INT_DIV"
2009 {
2010   rtx op2_neg, op1_di, div;
2011
2012   div = gen_reg_rtx (SImode);
2013   emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
2014
2015   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2016
2017   /* This is a trick to get us to reuse the value that we're sure to
2018      have already copied to the FP regs.  */
2019   op1_di = gen_reg_rtx (DImode);
2020   convert_move (op1_di, operands[1], 1);
2021
2022   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2023                           gen_lowpart (SImode, op1_di)));
2024   DONE;
2025 })
2026
2027 (define_insn_and_split "divsi3_internal"
2028   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2029         (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2030                           (match_operand:XF 2 "fr_register_operand" "f"))))
2031    (clobber (match_scratch:XF 4 "=&f"))
2032    (clobber (match_scratch:XF 5 "=&f"))
2033    (clobber (match_scratch:BI 6 "=c"))
2034    (use (match_operand:XF 3 "fr_register_operand" "f"))]
2035   "TARGET_INLINE_INT_DIV"
2036   "#"
2037   "&& reload_completed"
2038   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2039               (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2040                                             UNSPEC_FR_RECIP_APPROX))
2041               (use (const_int 1))])
2042    (cond_exec (ne (match_dup 6) (const_int 0))
2043      (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
2044                 (use (const_int 1))]))
2045    (cond_exec (ne (match_dup 6) (const_int 0))
2046      (parallel [(set (match_dup 5)
2047                      (minus:XF (match_dup 7)
2048                                (mult:XF (match_dup 2) (match_dup 0))))
2049                 (use (const_int 1))]))
2050    (cond_exec (ne (match_dup 6) (const_int 0))
2051      (parallel [(set (match_dup 4)
2052                      (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2053                               (match_dup 4)))
2054                 (use (const_int 1))]))
2055    (cond_exec (ne (match_dup 6) (const_int 0))
2056      (parallel [(set (match_dup 5)
2057                      (plus:XF (mult:XF (match_dup 5) (match_dup 5))
2058                               (match_dup 3)))
2059                 (use (const_int 1))]))
2060    (cond_exec (ne (match_dup 6) (const_int 0))
2061      (parallel [(set (match_dup 0)
2062                      (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2063                               (match_dup 4)))
2064                 (use (const_int 1))]))
2065   ] 
2066   "operands[7] = CONST1_RTX (XFmode);"
2067   [(set_attr "predicable" "no")])
2068 \f
2069 ;; ::::::::::::::::::::
2070 ;; ::
2071 ;; :: 64 bit Integer arithmetic
2072 ;; ::
2073 ;; ::::::::::::::::::::
2074
2075 (define_insn "adddi3"
2076   [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
2077         (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
2078                  (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
2079   ""
2080   "@
2081    add %0 = %1, %2
2082    adds %0 = %2, %1
2083    addl %0 = %2, %1"
2084   [(set_attr "itanium_class" "ialu")])
2085
2086 (define_insn "*adddi3_plus1"
2087   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2088         (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
2089                           (match_operand:DI 2 "gr_register_operand" "r"))
2090                  (const_int 1)))]
2091   ""
2092   "add %0 = %1, %2, 1"
2093   [(set_attr "itanium_class" "ialu")])
2094
2095 ;; This has some of the same problems as shladd.  We let the shladd
2096 ;; eliminator hack handle it, which results in the 1 being forced into
2097 ;; a register, but not more ugliness here.
2098 (define_insn "*adddi3_plus1_alt"
2099   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2100         (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2101                           (const_int 2))
2102                  (const_int 1)))]
2103   ""
2104   "add %0 = %1, %1, 1"
2105   [(set_attr "itanium_class" "ialu")])
2106
2107 (define_insn "subdi3"
2108   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2109         (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
2110                   (match_operand:DI 2 "gr_register_operand" "r")))]
2111   ""
2112   "sub %0 = %1, %2"
2113   [(set_attr "itanium_class" "ialu")])
2114
2115 (define_insn "*subdi3_minus1"
2116   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2117         (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
2118                  (match_operand:DI 2 "gr_register_operand" "r")))]
2119   ""
2120   "sub %0 = %2, %1, 1"
2121   [(set_attr "itanium_class" "ialu")])
2122
2123 ;; ??? Use grfr instead of fr because of virtual register elimination
2124 ;; and silly test cases multiplying by the frame pointer.
2125 (define_insn "muldi3"
2126   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2127         (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2128                  (match_operand:DI 2 "grfr_register_operand" "f")))]
2129   ""
2130   "xmpy.l %0 = %1, %2"
2131   [(set_attr "itanium_class" "xmpy")])
2132
2133 ;; ??? If operand 3 is an eliminable reg, then register elimination causes the
2134 ;; same problem that we have with shladd below.  Unfortunately, this case is
2135 ;; much harder to fix because the multiply puts the result in an FP register,
2136 ;; but the add needs inputs from a general register.  We add a spurious clobber
2137 ;; here so that it will be present just in case register elimination gives us
2138 ;; the funny result.
2139
2140 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2141
2142 ;; ??? Maybe we should change how adds are canonicalized.
2143
2144 (define_insn "madddi4"
2145   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2146         (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2147                           (match_operand:DI 2 "grfr_register_operand" "f"))
2148                  (match_operand:DI 3 "grfr_register_operand" "f")))
2149    (clobber (match_scratch:DI 4 "=X"))]
2150   ""
2151   "xma.l %0 = %1, %2, %3"
2152   [(set_attr "itanium_class" "xmpy")])
2153
2154 ;; This can be created by register elimination if operand3 of shladd is an
2155 ;; eliminable register or has reg_equiv_constant set.
2156
2157 ;; We have to use nonmemory_operand for operand 4, to ensure that the
2158 ;; validate_changes call inside eliminate_regs will always succeed.  If it
2159 ;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
2160 ;; incorrectly.
2161
2162 (define_insn "*madddi4_elim"
2163   [(set (match_operand:DI 0 "register_operand" "=&r")
2164         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
2165                                    (match_operand:DI 2 "register_operand" "f"))
2166                           (match_operand:DI 3 "register_operand" "f"))
2167                  (match_operand:DI 4 "nonmemory_operand" "rI")))
2168    (clobber (match_scratch:DI 5 "=f"))]
2169   "reload_in_progress"
2170   "#"
2171   [(set_attr "itanium_class" "unknown")])
2172
2173 (define_split
2174   [(set (match_operand:DI 0 "register_operand" "")
2175         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2176                                    (match_operand:DI 2 "register_operand" ""))
2177                           (match_operand:DI 3 "register_operand" ""))
2178                  (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
2179    (clobber (match_scratch:DI 5 ""))]
2180   "reload_completed"
2181   [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2182                                           (match_dup 3)))
2183               (clobber (match_dup 0))])
2184    (set (match_dup 0) (match_dup 5))
2185    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2186   "")
2187
2188 ;; ??? There are highpart multiply and add instructions, but we have no way
2189 ;; to generate them.
2190
2191 (define_insn "smuldi3_highpart"
2192   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2193         (truncate:DI
2194          (lshiftrt:TI
2195           (mult:TI (sign_extend:TI
2196                      (match_operand:DI 1 "fr_register_operand" "f"))
2197                    (sign_extend:TI
2198                      (match_operand:DI 2 "fr_register_operand" "f")))
2199           (const_int 64))))]
2200   ""
2201   "xmpy.h %0 = %1, %2"
2202   [(set_attr "itanium_class" "xmpy")])
2203
2204 (define_insn "umuldi3_highpart"
2205   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2206         (truncate:DI
2207          (lshiftrt:TI
2208           (mult:TI (zero_extend:TI
2209                      (match_operand:DI 1 "fr_register_operand" "f"))
2210                    (zero_extend:TI
2211                      (match_operand:DI 2 "fr_register_operand" "f")))
2212           (const_int 64))))]
2213   ""
2214   "xmpy.hu %0 = %1, %2"
2215   [(set_attr "itanium_class" "xmpy")])
2216
2217 (define_insn "negdi2"
2218   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2219         (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2220   ""
2221   "sub %0 = r0, %1"
2222   [(set_attr "itanium_class" "ialu")])
2223
2224 (define_expand "absdi2"
2225   [(set (match_dup 2)
2226         (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2227    (set (match_operand:DI 0 "gr_register_operand" "")
2228         (if_then_else:DI (eq (match_dup 2) (const_int 0))
2229                          (neg:DI (match_dup 1))
2230                          (match_dup 1)))]
2231   ""
2232   { operands[2] = gen_reg_rtx (BImode); })
2233
2234 (define_expand "smindi3"
2235   [(set (match_dup 3)
2236         (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2237                (match_operand:DI 2 "gr_register_operand" "")))
2238    (set (match_operand:DI 0 "gr_register_operand" "")
2239         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2240                          (match_dup 2) (match_dup 1)))]
2241   ""
2242   { operands[3] = gen_reg_rtx (BImode); })
2243
2244 (define_expand "smaxdi3"
2245   [(set (match_dup 3)
2246         (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2247                (match_operand:DI 2 "gr_register_operand" "")))
2248    (set (match_operand:DI 0 "gr_register_operand" "")
2249         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2250                          (match_dup 1) (match_dup 2)))]
2251   ""
2252   { operands[3] = gen_reg_rtx (BImode); })
2253
2254 (define_expand "umindi3"
2255   [(set (match_dup 3)
2256         (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2257                 (match_operand:DI 2 "gr_register_operand" "")))
2258    (set (match_operand:DI 0 "gr_register_operand" "")
2259         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2260                          (match_dup 2) (match_dup 1)))]
2261   ""
2262   { operands[3] = gen_reg_rtx (BImode); })
2263
2264 (define_expand "umaxdi3"
2265   [(set (match_dup 3)
2266         (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2267                 (match_operand:DI 2 "gr_register_operand" "")))
2268    (set (match_operand:DI 0 "gr_register_operand" "")
2269         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2270                          (match_dup 1) (match_dup 2)))]
2271   ""
2272   { operands[3] = gen_reg_rtx (BImode); })
2273
2274 (define_expand "ffsdi2"
2275   [(set (match_dup 6)
2276         (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2277    (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
2278    (set (match_dup 5) (const_int 0))
2279    (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2280    (set (match_dup 4) (popcount:DI (match_dup 3)))
2281    (set (match_operand:DI 0 "gr_register_operand" "")
2282         (if_then_else:DI (ne (match_dup 6) (const_int 0))
2283                          (match_dup 5) (match_dup 4)))]
2284   ""
2285 {
2286   operands[2] = gen_reg_rtx (DImode);
2287   operands[3] = gen_reg_rtx (DImode);
2288   operands[4] = gen_reg_rtx (DImode);
2289   operands[5] = gen_reg_rtx (DImode);
2290   operands[6] = gen_reg_rtx (BImode);
2291 })
2292
2293 (define_expand "ctzdi2"
2294   [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
2295                                (const_int -1)))
2296    (set (match_dup 3) (not:DI (match_dup 1)))
2297    (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
2298    (set (match_operand:DI 0 "gr_register_operand" "")
2299         (popcount:DI (match_dup 4)))]
2300   ""
2301 {
2302   operands[2] = gen_reg_rtx (DImode);
2303   operands[3] = gen_reg_rtx (DImode);
2304   operands[4] = gen_reg_rtx (DImode);
2305 })
2306
2307 ;; Note the computation here is op0 = 63 - (exp - 0xffff).
2308 (define_expand "clzdi2"
2309   [(set (match_dup 2)
2310         (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "")))
2311    (set (match_dup 3)
2312         (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
2313    (set (match_dup 4) (const_int 65598))
2314    (set (match_operand:DI 0 "gr_register_operand" "")
2315         (minus:DI (match_dup 4) (match_dup 3)))]
2316   ""
2317 {
2318   operands[2] = gen_reg_rtx (XFmode);
2319   operands[3] = gen_reg_rtx (DImode);
2320   operands[4] = gen_reg_rtx (DImode);
2321 })
2322
2323 (define_insn "popcountdi2"
2324   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2325         (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2326   ""
2327   "popcnt %0 = %1"
2328   [(set_attr "itanium_class" "mmmul")])
2329
2330 (define_insn "*getf_exp_xf"
2331   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2332         (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
2333                    UNSPEC_GETF_EXP))]
2334   ""
2335   "getf.exp %0 = %1"
2336   [(set_attr "itanium_class" "frfr")])
2337
2338 (define_expand "divdi3"
2339   [(set (match_operand:DI 0 "register_operand" "")
2340         (div:DI (match_operand:DI 1 "general_operand" "")
2341                 (match_operand:DI 2 "general_operand" "")))]
2342   "TARGET_INLINE_INT_DIV"
2343 {
2344   rtx op1_xf, op2_xf, op0_xf;
2345
2346   op0_xf = gen_reg_rtx (XFmode);
2347
2348   if (CONSTANT_P (operands[1]))
2349     operands[1] = force_reg (DImode, operands[1]);
2350   op1_xf = gen_reg_rtx (XFmode);
2351   expand_float (op1_xf, operands[1], 0);
2352
2353   if (CONSTANT_P (operands[2]))
2354     operands[2] = force_reg (DImode, operands[2]);
2355   op2_xf = gen_reg_rtx (XFmode);
2356   expand_float (op2_xf, operands[2], 0);
2357
2358   if (TARGET_INLINE_INT_DIV_LAT)
2359     emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2360   else
2361     emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2362
2363   emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2364   DONE;
2365 })
2366
2367 (define_expand "moddi3"
2368   [(set (match_operand:DI 0 "register_operand" "")
2369         (mod:SI (match_operand:DI 1 "general_operand" "")
2370                 (match_operand:DI 2 "general_operand" "")))]
2371   "TARGET_INLINE_INT_DIV"
2372 {
2373   rtx op2_neg, div;
2374
2375   div = gen_reg_rtx (DImode);
2376   emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2377
2378   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2379
2380   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2381   DONE;
2382 })
2383
2384 (define_expand "udivdi3"
2385   [(set (match_operand:DI 0 "register_operand" "")
2386         (udiv:DI (match_operand:DI 1 "general_operand" "")
2387                  (match_operand:DI 2 "general_operand" "")))]
2388   "TARGET_INLINE_INT_DIV"
2389 {
2390   rtx op1_xf, op2_xf, op0_xf;
2391
2392   op0_xf = gen_reg_rtx (XFmode);
2393
2394   if (CONSTANT_P (operands[1]))
2395     operands[1] = force_reg (DImode, operands[1]);
2396   op1_xf = gen_reg_rtx (XFmode);
2397   expand_float (op1_xf, operands[1], 1);
2398
2399   if (CONSTANT_P (operands[2]))
2400     operands[2] = force_reg (DImode, operands[2]);
2401   op2_xf = gen_reg_rtx (XFmode);
2402   expand_float (op2_xf, operands[2], 1);
2403
2404   if (TARGET_INLINE_INT_DIV_LAT)
2405     emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2406   else
2407     emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2408
2409   emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2410   DONE;
2411 })
2412
2413 (define_expand "umoddi3"
2414   [(set (match_operand:DI 0 "register_operand" "")
2415         (umod:DI (match_operand:DI 1 "general_operand" "")
2416                  (match_operand:DI 2 "general_operand" "")))]
2417   "TARGET_INLINE_INT_DIV"
2418 {
2419   rtx op2_neg, div;
2420
2421   div = gen_reg_rtx (DImode);
2422   emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2423
2424   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2425
2426   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2427   DONE;
2428 })
2429
2430 (define_insn_and_split "divdi3_internal_lat"
2431   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2432         (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2433                           (match_operand:XF 2 "fr_register_operand" "f"))))
2434    (clobber (match_scratch:XF 3 "=&f"))
2435    (clobber (match_scratch:XF 4 "=&f"))
2436    (clobber (match_scratch:XF 5 "=&f"))
2437    (clobber (match_scratch:BI 6 "=c"))]
2438   "TARGET_INLINE_INT_DIV_LAT"
2439   "#"
2440   "&& reload_completed"
2441   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2442               (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2443                                             UNSPEC_FR_RECIP_APPROX))
2444               (use (const_int 1))])
2445    (cond_exec (ne (match_dup 6) (const_int 0))
2446      (parallel [(set (match_dup 3)
2447                      (minus:XF (match_dup 7)
2448                                (mult:XF (match_dup 2) (match_dup 0))))
2449                 (use (const_int 1))]))
2450    (cond_exec (ne (match_dup 6) (const_int 0))
2451      (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
2452                 (use (const_int 1))]))
2453    (cond_exec (ne (match_dup 6) (const_int 0))
2454      (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
2455                 (use (const_int 1))]))
2456    (cond_exec (ne (match_dup 6) (const_int 0))
2457      (parallel [(set (match_dup 4)
2458                      (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2459                               (match_dup 4)))
2460                 (use (const_int 1))]))
2461    (cond_exec (ne (match_dup 6) (const_int 0))
2462      (parallel [(set (match_dup 0)
2463                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2464                               (match_dup 0)))
2465                 (use (const_int 1))]))
2466    (cond_exec (ne (match_dup 6) (const_int 0))
2467      (parallel [(set (match_dup 3)
2468                      (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2469                               (match_dup 4)))
2470                 (use (const_int 1))]))
2471    (cond_exec (ne (match_dup 6) (const_int 0))
2472      (parallel [(set (match_dup 0)
2473                      (plus:XF (mult:XF (match_dup 5) (match_dup 0))
2474                               (match_dup 0)))
2475                 (use (const_int 1))]))
2476    (cond_exec (ne (match_dup 6) (const_int 0))
2477      (parallel [(set (match_dup 4)
2478                      (minus:XF (match_dup 1)
2479                                (mult:XF (match_dup 2) (match_dup 3))))
2480                 (use (const_int 1))]))
2481    (cond_exec (ne (match_dup 6) (const_int 0))
2482      (parallel [(set (match_dup 0)
2483                      (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2484                               (match_dup 3)))
2485                 (use (const_int 1))]))
2486   ] 
2487   "operands[7] = CONST1_RTX (XFmode);"
2488   [(set_attr "predicable" "no")])
2489
2490 (define_insn_and_split "divdi3_internal_thr"
2491   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2492         (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2493                           (match_operand:XF 2 "fr_register_operand" "f"))))
2494    (clobber (match_scratch:XF 3 "=&f"))
2495    (clobber (match_scratch:XF 4 "=f"))
2496    (clobber (match_scratch:BI 5 "=c"))]
2497   "TARGET_INLINE_INT_DIV_THR"
2498   "#"
2499   "&& reload_completed"
2500   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2501               (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 
2502                                             UNSPEC_FR_RECIP_APPROX))
2503               (use (const_int 1))])
2504    (cond_exec (ne (match_dup 5) (const_int 0))
2505      (parallel [(set (match_dup 3)
2506                      (minus:XF (match_dup 6)
2507                                (mult:XF (match_dup 2) (match_dup 0))))
2508                 (use (const_int 1))]))
2509    (cond_exec (ne (match_dup 5) (const_int 0))
2510      (parallel [(set (match_dup 0)
2511                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2512                               (match_dup 0)))
2513                 (use (const_int 1))]))
2514    (cond_exec (ne (match_dup 5) (const_int 0))
2515      (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
2516                 (use (const_int 1))]))
2517    (cond_exec (ne (match_dup 5) (const_int 0))
2518      (parallel [(set (match_dup 0)
2519                      (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2520                               (match_dup 0)))
2521                 (use (const_int 1))]))
2522    (cond_exec (ne (match_dup 5) (const_int 0))
2523      (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
2524                 (use (const_int 1))]))
2525    (cond_exec (ne (match_dup 5) (const_int 0))
2526      (parallel [(set (match_dup 4)
2527                      (minus:XF (match_dup 1)
2528                                (mult:XF (match_dup 2) (match_dup 3))))
2529                 (use (const_int 1))]))
2530    (cond_exec (ne (match_dup 5) (const_int 0))
2531      (parallel [(set (match_dup 0)
2532                      (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2533                               (match_dup 3)))
2534                 (use (const_int 1))]))
2535   ] 
2536   "operands[6] = CONST1_RTX (XFmode);"
2537   [(set_attr "predicable" "no")])
2538 \f
2539 ;; ::::::::::::::::::::
2540 ;; ::
2541 ;; :: 32 bit floating point arithmetic
2542 ;; ::
2543 ;; ::::::::::::::::::::
2544
2545 (define_insn "addsf3"
2546   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2547         (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2548                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2549   ""
2550   "fadd.s %0 = %1, %F2"
2551   [(set_attr "itanium_class" "fmac")])
2552
2553 (define_insn "subsf3"
2554   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2555         (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2556                   (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2557   ""
2558   "fsub.s %0 = %F1, %F2"
2559   [(set_attr "itanium_class" "fmac")])
2560
2561 (define_insn "mulsf3"
2562   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2563         (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2564                  (match_operand:SF 2 "fr_register_operand" "f")))]
2565   ""
2566   "fmpy.s %0 = %1, %2"
2567   [(set_attr "itanium_class" "fmac")])
2568
2569 (define_insn "abssf2"
2570   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2571         (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2572   ""
2573   "fabs %0 = %1"
2574   [(set_attr "itanium_class" "fmisc")])
2575
2576 (define_insn "negsf2"
2577   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2578         (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2579   ""
2580   "fneg %0 = %1"
2581   [(set_attr "itanium_class" "fmisc")])
2582
2583 (define_insn "*nabssf2"
2584   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2585         (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
2586   ""
2587   "fnegabs %0 = %1"
2588   [(set_attr "itanium_class" "fmisc")])
2589
2590 (define_insn "copysignsf3"
2591   [(set (match_operand:SF 0 "register_operand" "=f")
2592         (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2593                     (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2594                    UNSPEC_COPYSIGN))]
2595   ""
2596   "fmerge.s %0 = %F2, %F1"
2597   [(set_attr "itanium_class" "fmisc")])
2598
2599 (define_insn "*ncopysignsf3"
2600   [(set (match_operand:SF 0 "register_operand" "=f")
2601         (neg:SF (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2602                             (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2603                            UNSPEC_COPYSIGN)))]
2604   ""
2605   "fmerge.ns %0 = %F2, %F1"
2606   [(set_attr "itanium_class" "fmisc")])
2607
2608 (define_insn "sminsf3"
2609   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2610         (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2611                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2612   ""
2613   "fmin %0 = %1, %F2"
2614   [(set_attr "itanium_class" "fmisc")])
2615
2616 (define_insn "smaxsf3"
2617   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2618         (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2619                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2620   ""
2621   "fmax %0 = %1, %F2"
2622   [(set_attr "itanium_class" "fmisc")])
2623
2624 (define_insn "*maddsf4"
2625   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2626         (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2627                           (match_operand:SF 2 "fr_register_operand" "f"))
2628                  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2629   ""
2630   "fma.s %0 = %1, %2, %F3"
2631   [(set_attr "itanium_class" "fmac")])
2632
2633 (define_insn "*msubsf4"
2634   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2635         (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2636                            (match_operand:SF 2 "fr_register_operand" "f"))
2637                   (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2638   ""
2639   "fms.s %0 = %1, %2, %F3"
2640   [(set_attr "itanium_class" "fmac")])
2641
2642 (define_insn "*nmulsf3"
2643   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2644         (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2645                          (match_operand:SF 2 "fr_register_operand" "f"))))]
2646   ""
2647   "fnmpy.s %0 = %1, %2"
2648   [(set_attr "itanium_class" "fmac")])
2649
2650 (define_insn "*nmaddsf4"
2651   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2652         (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
2653                   (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2654                            (match_operand:SF 2 "fr_register_operand" "f"))))]
2655   ""
2656   "fnma.s %0 = %1, %2, %F3"
2657   [(set_attr "itanium_class" "fmac")])
2658
2659 (define_insn "*nmaddsf4_alts"
2660   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2661         (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
2662                   (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2663                            (match_operand:SF 2 "fr_register_operand" "f"))))
2664    (use (match_operand:SI 4 "const_int_operand" ""))]
2665   ""
2666   "fnma.s.s%4 %0 = %1, %2, %F3"
2667   [(set_attr "itanium_class" "fmac")])
2668
2669 (define_expand "divsf3"
2670   [(set (match_operand:SF 0 "fr_register_operand" "")
2671         (div:SF (match_operand:SF 1 "fr_register_operand" "")
2672                 (match_operand:SF 2 "fr_register_operand" "")))]
2673   "TARGET_INLINE_FLOAT_DIV"
2674 {
2675   rtx insn;
2676   if (TARGET_INLINE_FLOAT_DIV_LAT)
2677     insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
2678   else
2679     insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
2680   emit_insn (insn);
2681   DONE;
2682 })
2683
2684 (define_insn_and_split "divsf3_internal_lat"
2685   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2686         (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2687                 (match_operand:SF 2 "fr_register_operand" "f")))
2688    (clobber (match_scratch:XF 3 "=&f"))
2689    (clobber (match_scratch:XF 4 "=f"))
2690    (clobber (match_scratch:BI 5 "=c"))]
2691   "TARGET_INLINE_FLOAT_DIV_LAT"
2692   "#"
2693   "&& reload_completed"
2694   [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2695               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2696                                             UNSPEC_FR_RECIP_APPROX))
2697               (use (const_int 1))])
2698    (cond_exec (ne (match_dup 5) (const_int 0))
2699      (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
2700                 (use (const_int 1))]))
2701    (cond_exec (ne (match_dup 5) (const_int 0))
2702      (parallel [(set (match_dup 4)
2703                      (minus:XF (match_dup 10)
2704                                (mult:XF (match_dup 8) (match_dup 6))))
2705                 (use (const_int 1))]))
2706    (cond_exec (ne (match_dup 5) (const_int 0))
2707      (parallel [(set (match_dup 3)
2708                      (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2709                               (match_dup 3)))
2710                 (use (const_int 1))]))
2711    (cond_exec (ne (match_dup 5) (const_int 0))
2712      (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
2713                 (use (const_int 1))]))
2714    (cond_exec (ne (match_dup 5) (const_int 0))
2715      (parallel [(set (match_dup 3)
2716                      (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2717                               (match_dup 3)))
2718                 (use (const_int 1))]))
2719    (cond_exec (ne (match_dup 5) (const_int 0))
2720      (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
2721                 (use (const_int 1))]))
2722    (cond_exec (ne (match_dup 5) (const_int 0))
2723      (parallel [(set (match_dup 9)
2724                      (float_truncate:DF
2725                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2726                               (match_dup 3))))
2727                 (use (const_int 1))]))
2728    (cond_exec (ne (match_dup 5) (const_int 0))
2729      (set (match_dup 0)
2730           (float_truncate:SF (match_dup 6))))
2731   ] 
2732 {
2733   operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2734   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2735   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2736   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2737   operands[10] = CONST1_RTX (XFmode);
2738 }
2739   [(set_attr "predicable" "no")])
2740
2741 (define_insn_and_split "divsf3_internal_thr"
2742   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2743         (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2744                 (match_operand:SF 2 "fr_register_operand" "f")))
2745    (clobber (match_scratch:XF 3 "=&f"))
2746    (clobber (match_scratch:XF 4 "=f"))
2747    (clobber (match_scratch:BI 5 "=c"))]
2748   "TARGET_INLINE_FLOAT_DIV_THR"
2749   "#"
2750   "&& reload_completed"
2751   [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2752               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2753                                             UNSPEC_FR_RECIP_APPROX))
2754               (use (const_int 1))])
2755    (cond_exec (ne (match_dup 5) (const_int 0))
2756      (parallel [(set (match_dup 3)
2757                      (minus:XF (match_dup 10)
2758                                (mult:XF (match_dup 8) (match_dup 6))))
2759                 (use (const_int 1))]))
2760    (cond_exec (ne (match_dup 5) (const_int 0))
2761      (parallel [(set (match_dup 3)
2762                      (plus:XF (mult:XF (match_dup 3) (match_dup 3))
2763                               (match_dup 3)))
2764                 (use (const_int 1))]))
2765    (cond_exec (ne (match_dup 5) (const_int 0))
2766      (parallel [(set (match_dup 6)
2767                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
2768                               (match_dup 6)))
2769                 (use (const_int 1))]))
2770    (cond_exec (ne (match_dup 5) (const_int 0))
2771      (parallel [(set (match_dup 9)
2772                      (float_truncate:SF
2773                        (mult:XF (match_dup 7) (match_dup 6))))
2774                 (use (const_int 1))]))
2775    (cond_exec (ne (match_dup 5) (const_int 0))
2776      (parallel [(set (match_dup 4)
2777                      (minus:XF (match_dup 7)
2778                                (mult:XF (match_dup 8) (match_dup 3))))
2779                 (use (const_int 1))]))
2780    (cond_exec (ne (match_dup 5) (const_int 0))
2781      (set (match_dup 0)
2782           (float_truncate:SF
2783             (plus:XF (mult:XF (match_dup 4) (match_dup 6))
2784                               (match_dup 3)))))
2785   ] 
2786 {
2787   operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2788   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2789   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2790   operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
2791   operands[10] = CONST1_RTX (XFmode);
2792 }
2793   [(set_attr "predicable" "no")])
2794
2795 ;; Inline square root.
2796
2797 (define_insn "*sqrt_approx"
2798   [(set (match_operand:XF 0 "fr_register_operand" "=f")
2799         (div:XF (const_int 1)
2800                 (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
2801    (set (match_operand:BI 1 "register_operand" "=c")
2802         (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
2803    (use (match_operand:SI 3 "const_int_operand" "")) ]
2804   ""
2805   "frsqrta.s%3 %0, %1 = %2"
2806   [(set_attr "itanium_class" "fmisc")
2807    (set_attr "predicable" "no")])
2808
2809 (define_insn "setf_exp_xf"
2810   [(set (match_operand:XF 0 "fr_register_operand" "=f")
2811         (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
2812                   UNSPEC_SETF_EXP))]
2813   ""
2814   "setf.exp %0 = %1"
2815   [(set_attr "itanium_class" "frfr")])
2816
2817 (define_expand "sqrtsf2"
2818   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2819         (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2820   "TARGET_INLINE_SQRT"
2821 {
2822   rtx insn;
2823   if (TARGET_INLINE_SQRT_LAT)
2824 #if 0
2825     insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
2826 #else
2827     abort ();
2828 #endif
2829   else
2830     insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
2831   emit_insn (insn);
2832   DONE;
2833 })
2834
2835 ;; Latency-optimized square root.
2836 ;; FIXME: Implement.
2837
2838 ;; Throughput-optimized square root.
2839
2840 (define_insn_and_split "sqrtsf2_internal_thr"
2841   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2842         (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))
2843    ;; Register r2 in optimization guide.
2844    (clobber (match_scratch:DI 2 "=r"))
2845    ;; Register f8 in optimization guide
2846    (clobber (match_scratch:XF 3 "=&f"))
2847    ;; Register f9 in optimization guide
2848    (clobber (match_scratch:XF 4 "=&f"))
2849    ;; Register f10 in optimization guide
2850    (clobber (match_scratch:XF 5 "=&f"))
2851    ;; Register p6 in optimization guide.
2852    (clobber (match_scratch:BI 6 "=c"))]
2853   "TARGET_INLINE_SQRT_THR"
2854   "#"
2855   "&& reload_completed"
2856   [ ;; exponent of +1/2 in r2
2857     (set (match_dup 2) (const_int 65534))
2858     ;; +1/2 in f8
2859     (set (match_dup 3) 
2860          (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
2861     ;; Step 1
2862     ;; y0 = 1/sqrt(a) in f7
2863     (parallel [(set (match_dup 7)
2864                     (div:XF (const_int 1)
2865                             (sqrt:XF (match_dup 8))))
2866                (set (match_dup 6)
2867                     (unspec:BI [(match_dup 8)]
2868                                  UNSPEC_FR_SQRT_RECIP_APPROX))
2869                (use (const_int 0))])
2870     ;; Step 2
2871     ;; H0 = 1/2 * y0 in f9
2872     (cond_exec (ne (match_dup 6) (const_int 0))
2873       (parallel [(set (match_dup 4)
2874                       (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2875                                (match_dup 9)))
2876                  (use (const_int 1))]))
2877     ;; Step 3
2878     ;; S0 = a * y0 in f7
2879     (cond_exec (ne (match_dup 6) (const_int 0))
2880       (parallel [(set (match_dup 7)
2881                       (plus:XF (mult:XF (match_dup 8) (match_dup 7))
2882                                (match_dup 9)))
2883                  (use (const_int 1))]))
2884     ;; Step 4
2885     ;; d = 1/2 - S0 * H0 in f10
2886     (cond_exec (ne (match_dup 6) (const_int 0))
2887       (parallel [(set (match_dup 5)
2888                       (minus:XF (match_dup 3)
2889                                 (mult:XF (match_dup 7) (match_dup 4))))
2890                  (use (const_int 1))]))
2891     ;; Step 5
2892     ;; d' = d + 1/2 * d in f8
2893     (cond_exec (ne (match_dup 6) (const_int 0))
2894        (parallel [(set (match_dup 3)
2895                        (plus:XF (mult:XF (match_dup 3) (match_dup 5))
2896                                 (match_dup 5)))
2897                   (use (const_int 1))]))
2898     ;; Step 6
2899     ;; e = d + d * d' in f8
2900     (cond_exec (ne (match_dup 6) (const_int 0))
2901        (parallel [(set (match_dup 3)
2902                        (plus:XF (mult:XF (match_dup 5) (match_dup 3))
2903                                 (match_dup 5)))
2904                   (use (const_int 1))]))
2905     ;; Step 7
2906     ;; S1 = S0 + e * S0 in f7
2907     (cond_exec (ne (match_dup 6) (const_int 0))
2908       (parallel [(set (match_dup 0)
2909                       (float_truncate:SF
2910                         (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2911                                  (match_dup 7))))
2912                  (use (const_int 1))]))
2913     ;; Step 8
2914     ;; H1 = H0 + e * H0 in f8
2915     (cond_exec (ne (match_dup 6) (const_int 0))
2916        (parallel [(set (match_dup 3)
2917                        (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2918                                 (match_dup 4)))
2919                   (use (const_int 1))]))
2920     ;; Step 9 
2921     ;; d1 = a - S1 * S1 in f9
2922     (cond_exec (ne (match_dup 6) (const_int 0))
2923        (parallel [(set (match_dup 4)
2924                        (minus:XF (match_dup 8)
2925                                  (mult:XF (match_dup 7) (match_dup 7))))
2926                   (use (const_int 1))]))
2927     ;; Step 10
2928     ;; S = S1 + d1 * H1 in f7
2929     (cond_exec (ne (match_dup 6) (const_int 0))
2930        (parallel [(set (match_dup 0)
2931                        (float_truncate:SF
2932                          (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2933                                   (match_dup 7))))
2934                   (use (const_int 0))]))]
2935 {
2936   /* Generate 82-bit versions of the input and output operands.  */
2937   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2938   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2939   /* Generate required floating-point constants.  */
2940   operands[9] = CONST0_RTX (XFmode);
2941 }
2942   [(set_attr "predicable" "no")])
2943 \f
2944 ;; ::::::::::::::::::::
2945 ;; ::
2946 ;; :: 64 bit floating point arithmetic
2947 ;; ::
2948 ;; ::::::::::::::::::::
2949
2950 (define_insn "adddf3"
2951   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2952         (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2953                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2954   ""
2955   "fadd.d %0 = %1, %F2"
2956   [(set_attr "itanium_class" "fmac")])
2957
2958 (define_insn "*adddf3_trunc"
2959   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2960         (float_truncate:SF
2961           (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2962                    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2963   ""
2964   "fadd.s %0 = %1, %F2"
2965   [(set_attr "itanium_class" "fmac")])
2966
2967 (define_insn "subdf3"
2968   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2969         (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2970                   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2971   ""
2972   "fsub.d %0 = %F1, %F2"
2973   [(set_attr "itanium_class" "fmac")])
2974
2975 (define_insn "*subdf3_trunc"
2976   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2977         (float_truncate:SF
2978           (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2979                     (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2980   ""
2981   "fsub.s %0 = %F1, %F2"
2982   [(set_attr "itanium_class" "fmac")])
2983
2984 (define_insn "muldf3"
2985   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2986         (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2987                  (match_operand:DF 2 "fr_register_operand" "f")))]
2988   ""
2989   "fmpy.d %0 = %1, %2"
2990   [(set_attr "itanium_class" "fmac")])
2991
2992 (define_insn "*muldf3_trunc"
2993   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2994         (float_truncate:SF
2995           (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2996                    (match_operand:DF 2 "fr_register_operand" "f"))))]
2997   ""
2998   "fmpy.s %0 = %1, %2"
2999   [(set_attr "itanium_class" "fmac")])
3000
3001 (define_insn "absdf2"
3002   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3003         (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3004   ""
3005   "fabs %0 = %1"
3006   [(set_attr "itanium_class" "fmisc")])
3007
3008 (define_insn "negdf2"
3009   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3010         (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3011   ""
3012   "fneg %0 = %1"
3013   [(set_attr "itanium_class" "fmisc")])
3014
3015 (define_insn "*nabsdf2"
3016   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3017         (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
3018   ""
3019   "fnegabs %0 = %1"
3020   [(set_attr "itanium_class" "fmisc")])
3021
3022 (define_insn "copysigndf3"
3023   [(set (match_operand:DF 0 "register_operand" "=f")
3024         (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3025                     (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
3026                    UNSPEC_COPYSIGN))]
3027   ""
3028   "fmerge.s %0 = %F2, %F1"
3029   [(set_attr "itanium_class" "fmisc")])
3030
3031 (define_insn "*ncopysigndf3"
3032   [(set (match_operand:DF 0 "register_operand" "=f")
3033         (neg:DF (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3034                             (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
3035                            UNSPEC_COPYSIGN)))]
3036   ""
3037   "fmerge.ns %0 = %F2, %F1"
3038   [(set_attr "itanium_class" "fmisc")])
3039
3040 (define_insn "smindf3"
3041   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3042         (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
3043                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
3044   ""
3045   "fmin %0 = %1, %F2"
3046   [(set_attr "itanium_class" "fmisc")])
3047
3048 (define_insn "smaxdf3"
3049   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3050         (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
3051                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
3052   ""
3053   "fmax %0 = %1, %F2"
3054   [(set_attr "itanium_class" "fmisc")])
3055
3056 (define_insn "*madddf4"
3057   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3058         (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3059                           (match_operand:DF 2 "fr_register_operand" "f"))
3060                  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3061   ""
3062   "fma.d %0 = %1, %2, %F3"
3063   [(set_attr "itanium_class" "fmac")])
3064
3065 (define_insn "*madddf4_trunc"
3066   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3067         (float_truncate:SF
3068           (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3069                             (match_operand:DF 2 "fr_register_operand" "f"))
3070                    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3071   ""
3072   "fma.s %0 = %1, %2, %F3"
3073   [(set_attr "itanium_class" "fmac")])
3074
3075 (define_insn "*msubdf4"
3076   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3077         (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3078                            (match_operand:DF 2 "fr_register_operand" "f"))
3079                   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3080   ""
3081   "fms.d %0 = %1, %2, %F3"
3082   [(set_attr "itanium_class" "fmac")])
3083
3084 (define_insn "*msubdf4_trunc"
3085   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3086         (float_truncate:SF
3087           (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3088                              (match_operand:DF 2 "fr_register_operand" "f"))
3089                     (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3090   ""
3091   "fms.s %0 = %1, %2, %F3"
3092   [(set_attr "itanium_class" "fmac")])
3093
3094 (define_insn "*nmuldf3"
3095   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3096         (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3097                          (match_operand:DF 2 "fr_register_operand" "f"))))]
3098   ""
3099   "fnmpy.d %0 = %1, %2"
3100   [(set_attr "itanium_class" "fmac")])
3101
3102 (define_insn "*nmuldf3_trunc"
3103   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3104         (float_truncate:SF
3105           (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3106                            (match_operand:DF 2 "fr_register_operand" "f")))))]
3107   ""
3108   "fnmpy.s %0 = %1, %2"
3109   [(set_attr "itanium_class" "fmac")])
3110
3111 (define_insn "*nmadddf4"
3112   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3113         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3114                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3115                            (match_operand:DF 2 "fr_register_operand" "f"))))]
3116   ""
3117   "fnma.d %0 = %1, %2, %F3"
3118   [(set_attr "itanium_class" "fmac")])
3119
3120 (define_insn "*nmadddf4_alts"
3121   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3122         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3123                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3124                            (match_operand:DF 2 "fr_register_operand" "f"))))
3125    (use (match_operand:SI 4 "const_int_operand" ""))]
3126   ""
3127   "fnma.d.s%4 %0 = %1, %2, %F3"
3128   [(set_attr "itanium_class" "fmac")])
3129
3130 (define_insn "*nmadddf4_truncsf"
3131   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3132         (float_truncate:SF
3133         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3134                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3135                            (match_operand:DF 2 "fr_register_operand" "f")))))]
3136   ""
3137   "fnma.s %0 = %1, %2, %F3"
3138   [(set_attr "itanium_class" "fmac")])
3139
3140 (define_insn "*nmadddf4_truncsf_alts"
3141   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3142         (float_truncate:SF
3143         (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3144                   (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3145                            (match_operand:DF 2 "fr_register_operand" "f")))))
3146    (use (match_operand:SI 4 "const_int_operand" ""))]
3147   ""
3148   "fnma.s.s%4 %0 = %1, %2, %F3"
3149   [(set_attr "itanium_class" "fmac")])
3150
3151 (define_expand "divdf3"
3152   [(set (match_operand:DF 0 "fr_register_operand" "")
3153         (div:DF (match_operand:DF 1 "fr_register_operand" "")
3154                 (match_operand:DF 2 "fr_register_operand" "")))]
3155   "TARGET_INLINE_FLOAT_DIV"
3156 {
3157   rtx insn;
3158   if (TARGET_INLINE_FLOAT_DIV_LAT)
3159     insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
3160   else
3161     insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
3162   emit_insn (insn);
3163   DONE;
3164 })
3165
3166 (define_insn_and_split "divdf3_internal_lat"
3167   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3168         (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3169                 (match_operand:DF 2 "fr_register_operand" "f")))
3170    (clobber (match_scratch:XF 3 "=&f"))
3171    (clobber (match_scratch:XF 4 "=&f"))
3172    (clobber (match_scratch:XF 5 "=&f"))
3173    (clobber (match_scratch:BI 6 "=c"))]
3174   "TARGET_INLINE_FLOAT_DIV_LAT"
3175   "#"
3176   "&& reload_completed"
3177   [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
3178               (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3179                                             UNSPEC_FR_RECIP_APPROX))
3180               (use (const_int 1))])
3181    (cond_exec (ne (match_dup 6) (const_int 0))
3182      (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
3183                 (use (const_int 1))]))
3184    (cond_exec (ne (match_dup 6) (const_int 0))
3185      (parallel [(set (match_dup 4)
3186                      (minus:XF (match_dup 12)
3187                                (mult:XF (match_dup 9) (match_dup 7))))
3188                 (use (const_int 1))]))
3189    (cond_exec (ne (match_dup 6) (const_int 0))
3190      (parallel [(set (match_dup 3)
3191                      (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3192                               (match_dup 3)))
3193                 (use (const_int 1))]))
3194    (cond_exec (ne (match_dup 6) (const_int 0))
3195      (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
3196                 (use (const_int 1))]))
3197    (cond_exec (ne (match_dup 6) (const_int 0))
3198      (parallel [(set (match_dup 7)
3199                      (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3200                               (match_dup 7)))
3201                 (use (const_int 1))]))
3202    (cond_exec (ne (match_dup 6) (const_int 0))
3203      (parallel [(set (match_dup 3)
3204                      (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3205                               (match_dup 3)))
3206                 (use (const_int 1))]))
3207    (cond_exec (ne (match_dup 6) (const_int 0))
3208      (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
3209                 (use (const_int 1))]))
3210    (cond_exec (ne (match_dup 6) (const_int 0))
3211      (parallel [(set (match_dup 7)
3212                      (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3213                               (match_dup 7)))
3214                 (use (const_int 1))]))
3215    (cond_exec (ne (match_dup 6) (const_int 0))
3216      (parallel [(set (match_dup 10)
3217                      (float_truncate:DF
3218                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3219                               (match_dup 3))))
3220                 (use (const_int 1))]))
3221    (cond_exec (ne (match_dup 6) (const_int 0))
3222      (parallel [(set (match_dup 7)
3223                      (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3224                               (match_dup 7)))
3225                 (use (const_int 1))]))
3226    (cond_exec (ne (match_dup 6) (const_int 0))
3227      (parallel [(set (match_dup 11)
3228                      (float_truncate:DF
3229                        (minus:XF (match_dup 8)
3230                                  (mult:XF (match_dup 9) (match_dup 3)))))
3231                 (use (const_int 1))]))
3232    (cond_exec (ne (match_dup 6) (const_int 0))
3233      (set (match_dup 0)
3234           (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3235                               (match_dup 3)))))
3236   ] 
3237 {
3238   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3239   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3240   operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3241   operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3242   operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3243   operands[12] = CONST1_RTX (XFmode);
3244 }
3245   [(set_attr "predicable" "no")])
3246
3247 (define_insn_and_split "divdf3_internal_thr"
3248   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3249         (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3250                 (match_operand:DF 2 "fr_register_operand" "f")))
3251    (clobber (match_scratch:XF 3 "=&f"))
3252    (clobber (match_scratch:DF 4 "=f"))
3253    (clobber (match_scratch:BI 5 "=c"))]
3254   "TARGET_INLINE_FLOAT_DIV_THR"
3255   "#"
3256   "&& reload_completed"
3257   [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3258               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3259                                             UNSPEC_FR_RECIP_APPROX))
3260               (use (const_int 1))])
3261    (cond_exec (ne (match_dup 5) (const_int 0))
3262      (parallel [(set (match_dup 3)
3263                      (minus:XF (match_dup 10)
3264                                (mult:XF (match_dup 8) (match_dup 6))))
3265                 (use (const_int 1))]))
3266    (cond_exec (ne (match_dup 5) (const_int 0))
3267      (parallel [(set (match_dup 6)
3268                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3269                               (match_dup 6)))
3270                 (use (const_int 1))]))
3271    (cond_exec (ne (match_dup 5) (const_int 0))
3272      (parallel [(set (match_dup 3)
3273                      (mult:XF (match_dup 3) (match_dup 3)))
3274                 (use (const_int 1))]))
3275    (cond_exec (ne (match_dup 5) (const_int 0))
3276      (parallel [(set (match_dup 6)
3277                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3278                               (match_dup 6)))
3279                 (use (const_int 1))]))
3280    (cond_exec (ne (match_dup 5) (const_int 0))
3281      (parallel [(set (match_dup 3)
3282                      (mult:XF (match_dup 3) (match_dup 3)))
3283                 (use (const_int 1))]))
3284    (cond_exec (ne (match_dup 5) (const_int 0))
3285      (parallel [(set (match_dup 6)
3286                      (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3287                               (match_dup 6)))
3288                 (use (const_int 1))]))
3289    (cond_exec (ne (match_dup 5) (const_int 0))
3290      (parallel [(set (match_dup 9)
3291                      (float_truncate:DF
3292                        (mult:XF (match_dup 7) (match_dup 6))))
3293                 (use (const_int 1))]))
3294    (cond_exec (ne (match_dup 5) (const_int 0))
3295      (parallel [(set (match_dup 4)
3296                      (minus:DF (match_dup 1)
3297                                (mult:DF (match_dup 2) (match_dup 9))))
3298                 (use (const_int 1))]))
3299    (cond_exec (ne (match_dup 5) (const_int 0))
3300      (set (match_dup 0)
3301           (plus:DF (mult:DF (match_dup 4) (match_dup 0))
3302                             (match_dup 9))))
3303   ] 
3304 {
3305   operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3306   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3307   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3308   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3309   operands[10] = CONST1_RTX (XFmode);
3310 }
3311   [(set_attr "predicable" "no")])
3312
3313 ;; Inline square root.
3314
3315 (define_expand "sqrtdf2"
3316   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3317         (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3318   "TARGET_INLINE_SQRT"
3319 {
3320   rtx insn;
3321   if (TARGET_INLINE_SQRT_LAT)
3322 #if 0
3323     insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
3324 #else
3325     abort ();
3326 #endif
3327   else
3328     insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
3329   emit_insn (insn);
3330   DONE;
3331 })
3332
3333 ;; Latency-optimized square root.
3334 ;; FIXME: Implement.
3335
3336 ;; Throughput-optimized square root.
3337
3338 (define_insn_and_split "sqrtdf2_internal_thr"
3339   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3340         (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))
3341    ;; Register r2 in optimization guide.
3342    (clobber (match_scratch:DI 2 "=r"))
3343    ;; Register f8 in optimization guide
3344    (clobber (match_scratch:XF 3 "=&f"))
3345    ;; Register f9 in optimization guide
3346    (clobber (match_scratch:XF 4 "=&f"))
3347    ;; Register f10 in optimization guide
3348    (clobber (match_scratch:XF 5 "=&f"))
3349    ;; Register p6 in optimization guide.
3350    (clobber (match_scratch:BI 6 "=c"))]
3351   "TARGET_INLINE_SQRT_THR"
3352   "#"
3353   "&& reload_completed"
3354   [ ;; exponent of +1/2 in r2
3355     (set (match_dup 2) (const_int 65534))
3356     ;; +1/2 in f10
3357     (set (match_dup 5) 
3358          (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3359     ;; Step 1
3360     ;; y0 = 1/sqrt(a) in f7
3361     (parallel [(set (match_dup 7)
3362                     (div:XF (const_int 1)
3363                             (sqrt:XF (match_dup 8))))
3364                (set (match_dup 6)
3365                     (unspec:BI [(match_dup 8)]
3366                                  UNSPEC_FR_SQRT_RECIP_APPROX))
3367                (use (const_int 0))])
3368     ;; Step 2
3369     ;; H0 = 1/2 * y0 in f8
3370     (cond_exec (ne (match_dup 6) (const_int 0))
3371       (parallel [(set (match_dup 3)
3372                       (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3373                                (match_dup 9)))
3374                  (use (const_int 1))]))
3375     ;; Step 3
3376     ;; G0 = a * y0 in f7
3377     (cond_exec (ne (match_dup 6) (const_int 0))
3378       (parallel [(set (match_dup 7)
3379                       (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3380                                (match_dup 9)))
3381                  (use (const_int 1))]))
3382     ;; Step 4
3383     ;; r0 = 1/2 - G0 * H0 in f9
3384     (cond_exec (ne (match_dup 6) (const_int 0))
3385       (parallel [(set (match_dup 4)
3386                       (minus:XF (match_dup 5)
3387                                 (mult:XF (match_dup 7) (match_dup 3))))
3388                  (use (const_int 1))]))
3389     ;; Step 5
3390     ;; H1 = H0 + r0 * H0 in f8
3391     (cond_exec (ne (match_dup 6) (const_int 0))
3392        (parallel [(set (match_dup 3)
3393                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3394                                 (match_dup 3)))
3395                   (use (const_int 1))]))
3396     ;; Step 6
3397     ;; G1 = G0 + r0 * G0 in f7
3398     (cond_exec (ne (match_dup 6) (const_int 0))
3399        (parallel [(set (match_dup 7)
3400                        (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3401                                 (match_dup 7)))
3402                   (use (const_int 1))]))
3403     ;; Step 7
3404     ;; r1 = 1/2 - G1 * H1 in f9
3405     (cond_exec (ne (match_dup 6) (const_int 0))
3406       (parallel [(set (match_dup 4)
3407                       (minus:XF (match_dup 5)
3408                                 (mult:XF (match_dup 7) (match_dup 3))))
3409                  (use (const_int 1))]))
3410     ;; Step 8
3411     ;; H2 = H1 + r1 * H1 in f8
3412     (cond_exec (ne (match_dup 6) (const_int 0))
3413        (parallel [(set (match_dup 3)
3414                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3415                                 (match_dup 3)))
3416                   (use (const_int 1))]))
3417     ;; Step 9 
3418     ;; G2 = G1 + r1 * G1 in f7
3419     (cond_exec (ne (match_dup 6) (const_int 0))
3420        (parallel [(set (match_dup 7)
3421                        (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3422                                 (match_dup 7)))
3423                   (use (const_int 1))]))
3424     ;; Step 10
3425     ;; d2 = a - G2 * G2 in f9
3426     (cond_exec (ne (match_dup 6) (const_int 0))
3427        (parallel [(set (match_dup 4)
3428                        (minus:XF (match_dup 8)
3429                                  (mult:XF (match_dup 7) (match_dup 7))))
3430                   (use (const_int 1))]))
3431     ;; Step 11
3432     ;; G3 = G2 + d2 * H2 in f7
3433     (cond_exec (ne (match_dup 6) (const_int 0))
3434        (parallel [(set (match_dup 7)
3435                        (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3436                                 (match_dup 7)))
3437                   (use (const_int 1))]))
3438     ;; Step 12
3439     ;; d3 = a - G3 * G3 in f9
3440     (cond_exec (ne (match_dup 6) (const_int 0))
3441        (parallel [(set (match_dup 4)
3442                        (minus:XF (match_dup 8)
3443                                  (mult:XF (match_dup 7) (match_dup 7))))
3444                   (use (const_int 1))]))
3445     ;; Step 13
3446     ;; S = G3 + d3 * H2 in f7
3447     (cond_exec (ne (match_dup 6) (const_int 0))
3448        (parallel [(set (match_dup 0)
3449                        (float_truncate:DF
3450                          (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3451                                   (match_dup 7))))
3452                   (use (const_int 0))]))]
3453 {
3454   /* Generate 82-bit versions of the input and output operands.  */
3455   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3456   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3457   /* Generate required floating-point constants.  */
3458   operands[9] = CONST0_RTX (XFmode);
3459 }
3460   [(set_attr "predicable" "no")])
3461 \f
3462 ;; ::::::::::::::::::::
3463 ;; ::
3464 ;; :: 80 bit floating point arithmetic
3465 ;; ::
3466 ;; ::::::::::::::::::::
3467
3468 (define_insn "addxf3"
3469   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3470         (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3471                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3472   ""
3473   "fadd %0 = %F1, %F2"
3474   [(set_attr "itanium_class" "fmac")])
3475
3476 (define_insn "*addxf3_truncsf"
3477   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3478         (float_truncate:SF
3479           (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3480                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3481   ""
3482   "fadd.s %0 = %F1, %F2"
3483   [(set_attr "itanium_class" "fmac")])
3484
3485 (define_insn "*addxf3_truncdf"
3486   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3487         (float_truncate:DF
3488           (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3489                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3490   ""
3491   "fadd.d %0 = %F1, %F2"
3492   [(set_attr "itanium_class" "fmac")])
3493
3494 (define_insn "subxf3"
3495   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3496         (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3497                   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3498   ""
3499   "fsub %0 = %F1, %F2"
3500   [(set_attr "itanium_class" "fmac")])
3501
3502 (define_insn "*subxf3_truncsf"
3503   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3504         (float_truncate:SF
3505           (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3506                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3507   ""
3508   "fsub.s %0 = %F1, %F2"
3509   [(set_attr "itanium_class" "fmac")])
3510
3511 (define_insn "*subxf3_truncdf"
3512   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3513         (float_truncate:DF
3514           (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3515                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3516   ""
3517   "fsub.d %0 = %F1, %F2"
3518   [(set_attr "itanium_class" "fmac")])
3519
3520 (define_insn "mulxf3"
3521   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3522         (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3523                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3524   ""
3525   "fmpy %0 = %F1, %F2"
3526   [(set_attr "itanium_class" "fmac")])
3527
3528 (define_insn "*mulxf3_truncsf"
3529   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3530         (float_truncate:SF
3531           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3532                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3533   ""
3534   "fmpy.s %0 = %F1, %F2"
3535   [(set_attr "itanium_class" "fmac")])
3536
3537 (define_insn "*mulxf3_truncdf"
3538   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3539         (float_truncate:DF
3540           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3541                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3542   ""
3543   "fmpy.d %0 = %F1, %F2"
3544   [(set_attr "itanium_class" "fmac")])
3545
3546 (define_insn "*mulxf3_alts"
3547   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3548         (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3549                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3550    (use (match_operand:SI 3 "const_int_operand" ""))]
3551   ""
3552   "fmpy.s%3 %0 = %F1, %F2"
3553   [(set_attr "itanium_class" "fmac")])
3554
3555 (define_insn "*mulxf3_truncsf_alts"
3556   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3557         (float_truncate:SF
3558           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3559                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3560    (use (match_operand:SI 3 "const_int_operand" ""))]
3561   ""
3562   "fmpy.s.s%3 %0 = %F1, %F2"
3563   [(set_attr "itanium_class" "fmac")])
3564
3565 (define_insn "*mulxf3_truncdf_alts"
3566   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3567         (float_truncate:DF
3568           (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3569                    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3570    (use (match_operand:SI 3 "const_int_operand" ""))]
3571   ""
3572   "fmpy.d.s%3 %0 = %F1, %F2"
3573   [(set_attr "itanium_class" "fmac")])
3574
3575 (define_insn "absxf2"
3576   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3577         (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3578   ""
3579   "fabs %0 = %F1"
3580   [(set_attr "itanium_class" "fmisc")])
3581
3582 (define_insn "negxf2"
3583   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3584         (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3585   ""
3586   "fneg %0 = %F1"
3587   [(set_attr "itanium_class" "fmisc")])
3588
3589 (define_insn "*nabsxf2"
3590   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3591         (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
3592   ""
3593   "fnegabs %0 = %F1"
3594   [(set_attr "itanium_class" "fmisc")])
3595
3596 (define_insn "copysignxf3"
3597   [(set (match_operand:XF 0 "register_operand" "=f")
3598         (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3599                     (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3600                    UNSPEC_COPYSIGN))]
3601   ""
3602   "fmerge.s %0 = %F2, %F1"
3603   [(set_attr "itanium_class" "fmisc")])
3604
3605 (define_insn "*ncopysignxf3"
3606   [(set (match_operand:XF 0 "register_operand" "=f")
3607         (neg:XF (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3608                             (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3609                            UNSPEC_COPYSIGN)))]
3610   ""
3611   "fmerge.ns %0 = %F2, %F1"
3612   [(set_attr "itanium_class" "fmisc")])
3613
3614 (define_insn "sminxf3"
3615   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3616         (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3617                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3618   ""
3619   "fmin %0 = %F1, %F2"
3620   [(set_attr "itanium_class" "fmisc")])
3621
3622 (define_insn "smaxxf3"
3623   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3624         (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3625                  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3626   ""
3627   "fmax %0 = %F1, %F2"
3628   [(set_attr "itanium_class" "fmisc")])
3629
3630 (define_insn "*maddxf4"
3631   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3632         (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3633                           (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3634                  (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3635   ""
3636   "fma %0 = %F1, %F2, %F3"
3637   [(set_attr "itanium_class" "fmac")])
3638
3639 (define_insn "*maddxf4_truncsf"
3640   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3641         (float_truncate:SF
3642           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3643                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3644                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3645   ""
3646   "fma.s %0 = %F1, %F2, %F3"
3647   [(set_attr "itanium_class" "fmac")])
3648
3649 (define_insn "*maddxf4_truncdf"
3650   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3651         (float_truncate:DF
3652           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3653                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3654                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3655   ""
3656   "fma.d %0 = %F1, %F2, %F3"
3657   [(set_attr "itanium_class" "fmac")])
3658
3659 (define_insn "*maddxf4_alts"
3660   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3661         (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3662                           (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3663                  (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
3664    (use (match_operand:SI 4 "const_int_operand" ""))]
3665   ""
3666   "fma.s%4 %0 = %F1, %F2, %F3"
3667   [(set_attr "itanium_class" "fmac")])
3668
3669 (define_insn "*maddxf4_alts_truncsf"
3670   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3671         (float_truncate:SF
3672           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3673                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3674                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3675    (use (match_operand:SI 4 "const_int_operand" ""))]
3676   ""
3677   "fma.s.s%4 %0 = %F1, %F2, %F3"
3678   [(set_attr "itanium_class" "fmac")])
3679
3680 (define_insn "*maddxf4_alts_truncdf"
3681   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3682         (float_truncate:DF
3683           (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3684                             (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3685                    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3686    (use (match_operand:SI 4 "const_int_operand" ""))]
3687   ""
3688   "fma.d.s%4 %0 = %F1, %F2, %F3"
3689   [(set_attr "itanium_class" "fmac")])
3690
3691 (define_insn "*msubxf4"
3692   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3693         (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3694                            (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3695                   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3696   ""
3697   "fms %0 = %F1, %F2, %F3"
3698   [(set_attr "itanium_class" "fmac")])
3699
3700 (define_insn "*msubxf4_truncsf"
3701   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3702         (float_truncate:SF
3703           (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3704                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3705                     (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3706   ""
3707   "fms.s %0 = %F1, %F2, %F3"
3708   [(set_attr "itanium_class" "fmac")])
3709
3710 (define_insn "*msubxf4_truncdf"
3711   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3712         (float_truncate:DF
3713           (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3714                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3715                     (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3716   ""
3717   "fms.d %0 = %F1, %F2, %F3"
3718   [(set_attr "itanium_class" "fmac")])
3719
3720 (define_insn "*nmulxf3"
3721   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3722         (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3723                          (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3724   ""
3725   "fnmpy %0 = %F1, %F2"
3726   [(set_attr "itanium_class" "fmac")])
3727
3728 (define_insn "*nmulxf3_truncsf"
3729   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3730         (float_truncate:SF
3731           (neg:XF (mult:XF
3732                     (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3733                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3734   ""
3735   "fnmpy.s %0 = %F1, %F2"
3736   [(set_attr "itanium_class" "fmac")])
3737
3738 (define_insn "*nmulxf3_truncdf"
3739   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3740         (float_truncate:DF
3741           (neg:XF (mult:XF
3742                     (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3743                     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3744   ""
3745   "fnmpy.d %0 = %F1, %F2"
3746   [(set_attr "itanium_class" "fmac")])
3747
3748 (define_insn "*nmaddxf4"
3749   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3750         (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
3751                   (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3752                            (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3753    )))]
3754   ""
3755   "fnma %0 = %F1, %F2, %F3"
3756   [(set_attr "itanium_class" "fmac")])
3757
3758 (define_insn "*nmaddxf4_truncsf"
3759   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3760         (float_truncate:SF
3761           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
3762                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3763                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3764    ))))]
3765   ""
3766   "fnma.s %0 = %F1, %F2, %F3"
3767   [(set_attr "itanium_class" "fmac")])
3768
3769 (define_insn "*nmaddxf4_truncdf"
3770   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3771         (float_truncate:DF
3772           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
3773                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3774                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3775    ))))]
3776   ""
3777   "fnma.d %0 = %F1, %F2, %F3"
3778   [(set_attr "itanium_class" "fmac")])
3779
3780 (define_insn "*nmaddxf4_alts"
3781   [(set (match_operand:XF 0 "fr_register_operand" "=f")
3782         (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
3783                   (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3784                            (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3785    )))
3786    (use (match_operand:SI 4 "const_int_operand" ""))]
3787   ""
3788   "fnma.s%4 %0 = %F1, %F2, %F3"
3789   [(set_attr "itanium_class" "fmac")])
3790
3791 (define_insn "*nmaddxf4_truncsf_alts"
3792   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3793         (float_truncate:SF
3794           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
3795                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3796                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3797    ))))
3798    (use (match_operand:SI 4 "const_int_operand" ""))]
3799   ""
3800   "fnma.s.s%4 %0 = %F1, %F2, %F3"
3801   [(set_attr "itanium_class" "fmac")])
3802
3803 (define_insn "*nmaddxf4_truncdf_alts"
3804   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3805         (float_truncate:DF
3806           (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
3807                     (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3808                              (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
3809    ))))
3810    (use (match_operand:SI 4 "const_int_operand" ""))]
3811   ""
3812   "fnma.d.s%4 %0 = %F1, %F2, %F3"
3813   [(set_attr "itanium_class" "fmac")])
3814
3815 (define_expand "divxf3"
3816   [(set (match_operand:XF 0 "fr_register_operand" "")
3817         (div:XF (match_operand:XF 1 "fr_register_operand" "")
3818                 (match_operand:XF 2 "fr_register_operand" "")))]
3819   "TARGET_INLINE_FLOAT_DIV"
3820 {
3821   rtx insn;
3822   if (TARGET_INLINE_FLOAT_DIV_LAT)
3823     insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
3824   else
3825     insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
3826   emit_insn (insn);
3827   DONE;
3828 })
3829
3830 (define_insn_and_split "divxf3_internal_lat"
3831   [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3832         (div:XF (match_operand:XF 1 "fr_register_operand" "f")
3833                 (match_operand:XF 2 "fr_register_operand" "f")))
3834    (clobber (match_scratch:XF 3 "=&f"))
3835    (clobber (match_scratch:XF 4 "=&f"))
3836    (clobber (match_scratch:XF 5 "=&f"))
3837    (clobber (match_scratch:XF 6 "=&f"))
3838    (clobber (match_scratch:BI 7 "=c"))]
3839   "TARGET_INLINE_FLOAT_DIV_LAT"
3840   "#"
3841   "&& reload_completed"
3842   [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
3843               (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
3844                                             UNSPEC_FR_RECIP_APPROX))
3845               (use (const_int 1))])
3846    (cond_exec (ne (match_dup 7) (const_int 0))
3847      (parallel [(set (match_dup 3)
3848                      (minus:XF (match_dup 8)
3849                                (mult:XF (match_dup 2) (match_dup 0))))
3850                 (use (const_int 1))]))
3851    (cond_exec (ne (match_dup 7) (const_int 0))
3852      (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
3853                 (use (const_int 1))]))
3854    (cond_exec (ne (match_dup 7) (const_int 0))
3855      (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
3856                 (use (const_int 1))]))
3857    (cond_exec (ne (match_dup 7) (const_int 0))
3858      (parallel [(set (match_dup 6)
3859                      (plus:XF (mult:XF (match_dup 3) (match_dup 3))
3860                               (match_dup 3)))