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