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