OSDN Git Service

* config/ia64/hpux.h (TARGET_OS_CPP_BUILTINS): Define _ILP32
[pf3gnuchains/gcc-fork.git] / gcc / config / ia64 / ia64.md
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>.
5
6 ;; This file is part of GCC.
7
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.
12
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.
17
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.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
26 ;; reload.  This will be fixed once scheduling support is turned on.
27
28 ;; ??? Optimize for post-increment addressing modes.
29
30 ;; ??? fselect is not supported, because there is no integer register
31 ;; equivalent.
32
33 ;; ??? fp abs/min/max instructions may also work for integer values.
34
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.
37
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.
40
41 ;; ??? Go through list of documented named patterns and look for more to
42 ;; implement.
43
44 ;; ??? Go through instruction manual and look for more instructions that
45 ;; can be emitted.
46
47 ;; ??? Add function unit scheduling info for Itanium (TM) processor.
48
49 ;; ??? Need a better way to describe alternate fp status registers.
50
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)
58
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   ])
80
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   ])
91 \f
92 ;; ::::::::::::::::::::
93 ;; ::
94 ;; :: Attributes
95 ;; ::
96 ;; ::::::::::::::::::::
97
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")))
101
102 ;; Instruction type.  This primarily determines how instructions can be
103 ;; packed in bundles, and secondarily affects scheduling to function units.
104
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
112
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).
117
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"))
124
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")))
142
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")))
151
152 ;; Predication.  True iff this instruction can be predicated.
153
154 (define_attr "predicable" "no,yes" (const_string "yes"))
155
156 \f
157
158 ;; DFA descriptions of ia64 processors used for insn scheduling and
159 ;; bundling.
160
161 (automata_option "ndfa")
162
163 ;; Uncomment the following line to output automata for debugging.
164 ;; (automata_option "v")
165
166 (automata_option "w")
167
168 ;;(automata_option "no-minimization")
169
170
171 (include "itanium1.md")
172 (include "itanium2.md")
173
174 \f
175 ;; ::::::::::::::::::::
176 ;; ::
177 ;; :: Moves
178 ;; ::
179 ;; ::::::::::::::::::::
180
181 ;; Set of a single predicate register.  This is only used to implement
182 ;; pr-to-pr move and complement.
183
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")])
194
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")])
210
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   "")
222
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);")
236
237 (define_expand "movqi"
238   [(set (match_operand:QI 0 "general_operand" "")
239         (match_operand:QI 1 "general_operand" ""))]
240   ""
241 {
242   rtx op1 = ia64_expand_move (operands[0], operands[1]);
243   if (!op1)
244     DONE;
245   operands[1] = op1;
246 })
247
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")])
261
262 (define_expand "movhi"
263   [(set (match_operand:HI 0 "general_operand" "")
264         (match_operand:HI 1 "general_operand" ""))]
265   ""
266 {
267   rtx op1 = ia64_expand_move (operands[0], operands[1]);
268   if (!op1)
269     DONE;
270   operands[1] = op1;
271 })
272
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")])
286
287 (define_expand "movsi"
288   [(set (match_operand:SI 0 "general_operand" "")
289         (match_operand:SI 1 "general_operand" ""))]
290   ""
291 {
292   rtx op1 = ia64_expand_move (operands[0], operands[1]);
293   if (!op1)
294     DONE;
295   operands[1] = op1;
296 })
297
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")])
315
316 (define_expand "movdi"
317   [(set (match_operand:DI 0 "general_operand" "")
318         (match_operand:DI 1 "general_operand" ""))]
319   ""
320 {
321   rtx op1 = ia64_expand_move (operands[0], operands[1]);
322   if (!op1)
323     DONE;
324   operands[1] = op1;
325 })
326
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])"
333 {
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   };
354
355   if (which_alternative == 2 && ! TARGET_NO_PIC
356       && symbolic_operand (operands[1], VOIDmode))
357     abort ();
358
359   return alt[which_alternative];
360 }
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")])
362
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)]
368 {
369   ia64_expand_load_address (operands[0], operands[1]);
370   DONE;
371 })
372
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   ""
378 {
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;
382 })
383
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")])
390
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")])
397
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")])
404
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   ""
411 {
412   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
413   operands[3] = pic_offset_table_rtx;
414 })
415
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.
421
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)]
429 {
430   ia64_split_return_addr_rtx (operands[0]);
431   DONE;
432 }
433   [(set_attr "itanium_class" "ialu")])
434
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   ""
440 {
441   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
442     return "%,addl %0 = @ltoffx(%1), %2";
443   else
444     return "%,addl %0 = @ltoff(%1), %2";
445 }
446   [(set_attr "itanium_class" "ialu")])
447
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   ""
453 {
454   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
455     return "%,ld8.mov %0 = [%1], %2";
456   else
457     return "%,ld8 %0 = [%1]";
458 }
459   [(set_attr "itanium_class" "ld")])
460
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")])
469
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")])
478
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   "")
485
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")])
493
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")])
501
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   "")
509
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")])
518
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")])
527
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")])
536
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   "")
543
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")])
551
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")])
559
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   "")
567
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")])
576
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")])
585
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   ""
593 {
594   rtx op1 = ia64_expand_move (operands[0], operands[1]);
595   if (!op1)
596     DONE;
597   operands[1] = op1;
598 })
599
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)]
608 {
609   rtx adj1, adj2, in[2], out[2], insn;
610   int first;
611
612   adj1 = ia64_split_timode (in, operands[1], operands[2]);
613   adj2 = ia64_split_timode (out, operands[0], operands[2]);
614
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     }
622
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;
642 }
643   [(set_attr "itanium_class" "unknown")
644    (set_attr "predicable" "no")])
645
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)]
656 {
657   rtx in[2], out[2];
658   int first;
659
660   ia64_split_timode (in, operands[1], NULL_RTX);
661   ia64_split_timode (out, operands[0], NULL_RTX);
662
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     }
670
671   emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
672   emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
673   DONE;
674 }
675   [(set_attr "itanium_class" "unknown")
676    (set_attr "predicable" "no")])
677
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   ""
683 {
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);
688 })
689
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   ""
695 {
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);
700 })
701
702 ;; Floating Point Moves
703 ;;
704 ;; Note - Patterns for SF mode moves are compulsory, but
705 ;; patterns for DF are optional, as GCC can synthesize them.
706
707 (define_expand "movsf"
708   [(set (match_operand:SF 0 "general_operand" "")
709         (match_operand:SF 1 "general_operand" ""))]
710   ""
711 {
712   rtx op1 = ia64_expand_move (operands[0], operands[1]);
713   if (!op1)
714     DONE;
715   operands[1] = op1;
716 })
717
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")])
732
733 (define_expand "movdf"
734   [(set (match_operand:DF 0 "general_operand" "")
735         (match_operand:DF 1 "general_operand" ""))]
736   ""
737 {
738   rtx op1 = ia64_expand_move (operands[0], operands[1]);
739   if (!op1)
740     DONE;
741   operands[1] = op1;
742 })
743
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")])
758
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   ""
765 {
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 ();
777
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         }
788
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         }
797
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);
801
802       if (GET_CODE (operands[1]) == MEM)
803         {
804           rtx out[2];
805
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);
808
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         }
813
814       abort ();
815     }
816
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);
821
822       if (! ia64_move_ok (operands[0], operands[1]))
823         operands[1] = force_reg (XFmode, operands[1]);
824     }
825 })
826
827 ;; ??? There's no easy way to mind volatile acquire/release semantics.
828
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")])
838 \f
839 ;; ::::::::::::::::::::
840 ;; ::
841 ;; :: Conversions
842 ;; ::
843 ;; ::::::::::::::::::::
844
845 ;; Signed conversions from a smaller integer to a larger integer
846
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")])
853
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")])
860
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")])
869
870 ;; Unsigned conversions from a smaller integer to a larger integer
871
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")])
880
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")])
889
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")])
900
901 ;; Convert between floating point types of different sizes.
902
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.
909
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.
916
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")])
923
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")])
930
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")])
937
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")])
944
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")])
951
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")])
958
959 ;; Convert between signed integer types and floating point.
960
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")])
967
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")])
974
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")])
981
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")])
988
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")])
996
997 ;; Convert between unsigned integer types and floating point.
998
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")])
1005
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")])
1012
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")])
1019
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")])
1026
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")])
1033
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")])
1040
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")])
1048 \f
1049 ;; ::::::::::::::::::::
1050 ;; ::
1051 ;; :: Bit field extraction
1052 ;; ::
1053 ;; ::::::::::::::::::::
1054
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")])
1063
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")])
1072
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.
1077
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.
1081
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   ""
1088 {
1089   int width = INTVAL (operands[1]);
1090   int shift = INTVAL (operands[2]);
1091
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]);
1097
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         }
1118
1119       /* We could handle remaining cases by emitting multiple dep
1120          instructions.
1121
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.
1127
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.  */
1133
1134       FAIL;
1135
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;
1142
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     }
1155 })
1156
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")])
1166
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"
1175 {
1176   operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1177   return "%,dep.z %0 = %1, %2, %3";
1178 }
1179   [(set_attr "itanium_class" "ishf")])
1180
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")])
1189
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];")
1200
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];")
1211
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")])
1220
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")])
1228
1229 ;; This is used by the rotrsi3 pattern.
1230
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")])
1240
1241 \f
1242 ;; ::::::::::::::::::::
1243 ;; ::
1244 ;; :: 1 bit Integer arithmetic
1245 ;; ::
1246 ;; ::::::::::::::::::::
1247
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")])
1265
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")])
1283
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")])
1301
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")])
1318
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")])
1330
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]));")
1345
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   "")
1360
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")])
1370
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")])
1380
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")])
1390
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")])
1400
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")])
1410
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")])
1420
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")])
1430
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")])
1440
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")])
1450
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")])
1460
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")])
1472
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")])
1484
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")])
1494
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")])
1504
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")])
1514
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")])
1524
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")])
1534
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")])
1544
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")])
1554
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")])
1564
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")])
1574
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")])
1584
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")])
1596
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")])
1608
1609 ;; Transform test of and/or of setcc into parallel comparisons.
1610
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   "")
1622
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   "")
1636
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   "")
1648
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   "")
1662
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.
1666 ;;
1667 ;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1668 ;; that we're doing height reduction.
1669 ;
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 ;  "")
1685 ;
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 ;  "")
1701 ;
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 ;  "")
1717 ;
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 ;  "")
1733
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.
1737
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]);")
1754 \f
1755 ;; ::::::::::::::::::::
1756 ;; ::
1757 ;; :: 16 bit Integer arithmetic
1758 ;; ::
1759 ;; ::::::::::::::::::::
1760
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")])
1768
1769 \f
1770 ;; ::::::::::::::::::::
1771 ;; ::
1772 ;; :: 32 bit Integer arithmetic
1773 ;; ::
1774 ;; ::::::::::::::::::::
1775
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")])
1786
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")])
1795
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")])
1804
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")])
1813
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")])
1821
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")])
1829
1830 ;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
1831
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")])
1839
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")])
1848
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")])
1855
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); })
1865
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); })
1875
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); })
1885
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); })
1895
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); })
1905
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"
1911 {
1912   rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1913   REAL_VALUE_TYPE twon34_r;
1914
1915   op0_xf = gen_reg_rtx (XFmode);
1916   op0_di = gen_reg_rtx (DImode);
1917
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);
1922
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);
1927
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);
1932
1933   emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1934
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;
1938 })
1939
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"
1945 {
1946   rtx op2_neg, op1_di, div;
1947
1948   div = gen_reg_rtx (SImode);
1949   emit_insn (gen_divsi3 (div, operands[1], operands[2]));
1950
1951   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1952
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);
1957
1958   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1959                           gen_lowpart (SImode, op1_di)));
1960   DONE;
1961 })
1962
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"
1968 {
1969   rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1970   REAL_VALUE_TYPE twon34_r;
1971
1972   op0_xf = gen_reg_rtx (XFmode);
1973   op0_di = gen_reg_rtx (DImode);
1974
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);
1979
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);
1984
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);
1989
1990   emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1991
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;
1995 })
1996
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"
2002 {
2003   rtx op2_neg, op1_di, div;
2004
2005   div = gen_reg_rtx (SImode);
2006   emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
2007
2008   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2009
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);
2014
2015   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2016                           gen_lowpart (SImode, op1_di)));
2017   DONE;
2018 })
2019
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")])
2061 \f
2062 ;; ::::::::::::::::::::
2063 ;; ::
2064 ;; :: 64 bit Integer arithmetic
2065 ;; ::
2066 ;; ::::::::::::::::::::
2067
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")])
2078
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")])
2087
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")])
2099
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")])
2107
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")])
2115
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")])
2125
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.
2132
2133 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2134
2135 ;; ??? Maybe we should change how adds are canonicalized.
2136
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")])
2146
2147 ;; This can be created by register elimination if operand3 of shladd is an
2148 ;; eliminable register or has reg_equiv_constant set.
2149
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.
2154
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")])
2165
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   "")
2180
2181 ;; ??? There are highpart multiply and add instructions, but we have no way
2182 ;; to generate them.
2183
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")])
2196
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")])
2209
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")])
2216
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); })
2226
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); })
2236
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); })
2246
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); })
2256
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); })
2266
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   ""
2278 {
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);
2284 })
2285
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   ""
2294 {
2295   operands[2] = gen_reg_rtx (DImode);
2296   operands[3] = gen_reg_rtx (DImode);
2297   operands[4] = gen_reg_rtx (DImode);
2298 })
2299
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   ""
2310 {
2311   operands[2] = gen_reg_rtx (XFmode);
2312   operands[3] = gen_reg_rtx (DImode);
2313   operands[4] = gen_reg_rtx (DImode);
2314 })
2315
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")])
2322
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")])
2330
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"
2336 {
2337   rtx op1_xf, op2_xf, op0_xf;
2338
2339   op0_xf = gen_reg_rtx (XFmode);
2340
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);
2345
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);
2350
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));
2355
2356   emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2357   DONE;
2358 })
2359
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"
2365 {
2366   rtx op2_neg, div;
2367
2368   div = gen_reg_rtx (DImode);
2369   emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2370
2371   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2372
2373   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2374   DONE;
2375 })
2376
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"
2382 {
2383   rtx op1_xf, op2_xf, op0_xf;
2384
2385   op0_xf = gen_reg_rtx (XFmode);
2386
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);
2391
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);
2396
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));
2401
2402   emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2403   DONE;
2404 })
2405
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"
2411 {
2412   rtx op2_neg, div;
2413
2414   div = gen_reg_rtx (DImode);
2415   emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2416
2417   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2418
2419   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2420   DONE;
2421 })
2422
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")])
2482
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")])
2531 \f
2532 ;; ::::::::::::::::::::
2533 ;; ::
2534 ;; :: 32 bit floating point arithmetic
2535 ;; ::
2536 ;; ::::::::::::::::::::
2537
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")])
2545
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")])
2553
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")])
2561
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")])
2568
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")])
2575
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")])
2582
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")])
2590
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")])
2598
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")])
2607
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")])
2616
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")])
2624
2625 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2626
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")])
2636
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"
2642 {
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;
2650 })
2651
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   ] 
2700 {
2701   operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2702   operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2703   operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2704   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2705   operands[10] = CONST1_RTX (XFmode);
2706 }
2707   [(set_attr "predicable" "no")])
2708
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   ] 
2754 {
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);
2760 }
2761   [(set_attr "predicable" "no")])
2762
2763 ;; Inline square root.
2764
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")])
2776
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")])
2784
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"
2789 {
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;
2801 })
2802
2803 ;; Latency-optimized square root.
2804 ;; FIXME: Implement.
2805
2806 ;; Throughput-optimized square root.
2807
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))]))]
2903 {
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);
2909 }
2910   [(set_attr "predicable" "no")])
2911 \f
2912 ;; ::::::::::::::::::::
2913 ;; ::
2914 ;; :: 64 bit floating point arithmetic
2915 ;; ::
2916 ;; ::::::::::::::::::::
2917
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")])
2925
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")])
2934
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")])
2942
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")])
2951
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")])
2959
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")])
2968
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")])
2975
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")])
2982
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")])
2989
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")])
2997
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")])
3005
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")])
3014
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")])
3024
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")])
3033
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")])
3043
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")])
3051
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")])
3060
3061 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3062
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")])
3072
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")])
3083
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")])
3094
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"
3100 {
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;
3108 })
3109
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   ] 
3181 {
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);
3188 }
3189   [(set_attr "predicable" "no")])
3190
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   ] 
3248 {
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);
3254 }
3255   [(set_attr "predicable" "no")])
3256
3257 ;; Inline square root.
3258
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"
3263 {
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;
3275 })
3276
3277 ;; Latency-optimized square root.
3278 ;; FIXME: Implement.
3279
3280 ;; Throughput-optimized square root.
3281
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))]))]
3397 {
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);
3403 }
3404   [(set_attr "predicable" "no")])
3405 \f
3406 ;; ::::::::::::::::::::
3407 ;; ::
3408 ;; :: 80 bit floating point arithmetic
3409 ;; ::
3410 ;; ::::::::::::::::::::
3411
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")])
3419
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")])
3428
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")])
3437
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")])
3445
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")])
3454
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")])
3463
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")])
3471
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")])
3480
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")])
3489
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")])
3498
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")])
3508
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")])
3518
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")])
3525
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")])
3532
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")])
3539
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")])
3547
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")])
3555
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")])
3564
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")])
3574
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")])
3584
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")])
3594
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")])
3605
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")])
3616
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")])
3625
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")])
3635
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")])
3645
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")])
3653
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")])
3663
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")])
3673
3674 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3675
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")])
3685
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")])
3696
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")])
3707
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")])
3718
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")])
3731
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"
3737 {
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;
3745 })
3746
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")])
3826
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")])
3904
3905 ;; Inline square root.
3906
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"
3911 {
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;
3923 })
3924
3925 ;; Latency-optimized square root.
3926 ;; FIXME: Implement.
3927
3928 ;; Throughput-optimized square root.
3929
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))]))]
4060 {
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);
4066 }
4067   [(set_attr "predicable" "no")])
4068
4069 ;; ??? frcpa works like cmp.foo.unc.
4070
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")])
4083 \f
4084 ;; ::::::::::::::::::::
4085 ;; ::
4086 ;; :: 32 bit Integer Shifts and Rotates
4087 ;; ::
4088 ;; ::::::::::::::::::::
4089
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   ""
4095 {
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     }
4104 })
4105
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")])
4116
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   ""
4122 {
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;
4136 })
4137
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   ""
4143 {
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;
4157 })
4158
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.
4162
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   ""
4168 {
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     }
4175 })
4176
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]));")
4190
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   ""
4196 {
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     }
4204 })
4205
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)))]
4218 {
4219   operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
4220   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4221 })
4222 \f
4223 ;; ::::::::::::::::::::
4224 ;; ::
4225 ;; :: 64 bit Integer Shifts and Rotates
4226 ;; ::
4227 ;; ::::::::::::::::::::
4228
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")])
4239
4240 ;; ??? Maybe combine this with the multiply and add instruction?
4241
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")])
4250
4251 ;; This can be created by register elimination if operand3 of shladd is an
4252 ;; eliminable register or has reg_equiv_constant set.
4253
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.
4258
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")])
4273
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")])
4283
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")])
4293
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.
4298
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   ""
4304 {
4305   if (! shift_count_operand (operands[2], DImode))
4306     FAIL;
4307 })
4308
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")])
4316
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   ""
4322 {
4323   if (! shift_count_operand (operands[2], DImode))
4324     FAIL;
4325 })
4326
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")])
4334 \f
4335 ;; ::::::::::::::::::::
4336 ;; ::
4337 ;; :: 32 bit Integer Logical operations
4338 ;; ::
4339 ;; ::::::::::::::::::::
4340
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.
4346
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.
4354
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")])
4361 \f
4362 ;; ::::::::::::::::::::
4363 ;; ::
4364 ;; :: 64 bit Integer Logical operations
4365 ;; ::
4366 ;; ::::::::::::::::::::
4367
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")])
4377
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")])
4387
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")])
4397
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")])
4407
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")])
4414 \f
4415 ;; ::::::::::::::::::::
4416 ;; ::
4417 ;; :: Comparisons
4418 ;; ::
4419 ;; ::::::::::::::::::::
4420
4421 (define_expand "cmpbi"
4422   [(set (cc0)
4423         (compare (match_operand:BI 0 "register_operand" "")
4424                  (match_operand:BI 1 "const_int_operand" "")))]
4425   ""
4426 {
4427   ia64_compare_op0 = operands[0];
4428   ia64_compare_op1 = operands[1];
4429   DONE;
4430 })
4431
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   ""
4437 {
4438   ia64_compare_op0 = operands[0];
4439   ia64_compare_op1 = operands[1];
4440   DONE;
4441 })
4442
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   ""
4448 {
4449   ia64_compare_op0 = operands[0];
4450   ia64_compare_op1 = operands[1];
4451   DONE;
4452 })
4453
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   ""
4459 {
4460   ia64_compare_op0 = operands[0];
4461   ia64_compare_op1 = operands[1];
4462   DONE;
4463 })
4464
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   ""
4470 {
4471   ia64_compare_op0 = operands[0];
4472   ia64_compare_op1 = operands[1];
4473   DONE;
4474 })
4475
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   ""
4481 {
4482   ia64_compare_op0 = operands[0];
4483   ia64_compare_op1 = operands[1];
4484   DONE;
4485 })
4486
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"
4492 {
4493   ia64_compare_op0 = operands[0];
4494   ia64_compare_op1 = operands[1];
4495   DONE;
4496 })
4497
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")])
4506
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.
4509
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")])
4518
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")])
4527
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.
4530
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")])
4539
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")])
4548
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")])
4557
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")])
4566
4567 ;; ??? Can this pattern be generated?
4568
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")])
4578
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")])
4588 \f
4589 ;; ::::::::::::::::::::
4590 ;; ::
4591 ;; :: Branches
4592 ;; ::
4593 ;; ::::::::::::::::::::
4594
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);")
4602
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);")
4610
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);")
4618
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);")
4626
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);")
4634
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);")
4642
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);")
4650
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);")
4658
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);")
4666
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);")
4674
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);")
4682
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);")
4690
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")])
4702
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")])
4714 \f
4715 ;; ::::::::::::::::::::
4716 ;; ::
4717 ;; :: Counted loop operations
4718 ;; ::
4719 ;; ::::::::::::::::::::
4720
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   ""
4728 {
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;
4735 })
4736
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")])
4749 \f
4750 ;; ::::::::::::::::::::
4751 ;; ::
4752 ;; :: Set flag operations
4753 ;; ::
4754 ;; ::::::::::::::::::::
4755
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);")
4760
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);")
4765
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);")
4770
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);")
4775
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);")
4780
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);")
4785
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);")
4790
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);")
4795
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);")
4800
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);")
4805
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);")
4810
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);")
4815
4816 ;; Don't allow memory as destination here, because cmov/cmov/st is more
4817 ;; efficient than mov/mov/cst/cst.
4818
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")])
4832
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")])
4846 \f
4847 ;; ::::::::::::::::::::
4848 ;; ::
4849 ;; :: Conditional move instructions.
4850 ;; ::
4851 ;; ::::::::::::::::::::
4852
4853 ;; ??? Add movXXcc patterns?
4854
4855 ;;
4856 ;; DImode if_then_else patterns.
4857 ;;
4858
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")])
4875
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)]
4886 {
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];
4892
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;
4908 })
4909
4910 ;; Absolute value pattern.
4911
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")])
4924
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   "")
4939
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)))]
4955 {
4956   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4957                                 VOIDmode, operands[1], const0_rtx);
4958 })
4959
4960 ;;
4961 ;; SImode if_then_else patterns.
4962 ;;
4963
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")])
4978
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")])
4991
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   "")
5006
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)))]
5022 {
5023   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
5024                                 VOIDmode, operands[1], const0_rtx);
5025 })
5026
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)])))]
5046 {
5047   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5048                                 VOIDmode, operands[1], const0_rtx);
5049 }
5050   [(set_attr "itanium_class" "ialu")
5051    (set_attr "predicable" "no")])
5052
5053
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)])))]
5073 {
5074   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5075                                 VOIDmode, operands[1], const0_rtx);
5076 }
5077   [(set_attr "itanium_class" "ialu")
5078    (set_attr "predicable" "no")])
5079
5080 \f
5081 ;; ::::::::::::::::::::
5082 ;; ::
5083 ;; :: Call and branch instructions
5084 ;; ::
5085 ;; ::::::::::::::::::::
5086
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.
5091
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.
5096
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   ""
5103 {
5104   ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
5105   DONE;
5106 })
5107
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   ""
5114 {
5115   ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
5116   DONE;
5117 })
5118
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).
5123 ;;
5124 ;; Subroutines that return `BLKmode' objects use the `call' insn.
5125
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   ""
5133 {
5134   ia64_expand_call (operands[0], operands[1], operands[3], false);
5135   DONE;
5136 })
5137
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   ""
5145 {
5146   ia64_expand_call (operands[0], operands[1], operands[3], true);
5147   DONE;
5148 })
5149
5150 ;; Call subroutine returning any type.
5151
5152 (define_expand "untyped_call"
5153   [(parallel [(call (match_operand 0 "" "")
5154                     (const_int 0))
5155               (match_operand 1 "" "")
5156               (match_operand 2 "" "")])]
5157   ""
5158 {
5159   int i;
5160
5161   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
5162
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     }
5168
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 ());
5174
5175   DONE;
5176 })
5177
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")])
5185
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")])
5194
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")])
5201
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")])
5211
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)]
5222 {
5223   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5224                    operands[3], true, false);
5225   DONE;
5226 })
5227
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)]
5236 {
5237   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5238                    operands[3], false, false);
5239   DONE;
5240 })
5241
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")])
5252
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)]
5262 {
5263   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5264                    operands[4], true, false);
5265   DONE;
5266 })
5267
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)]
5277 {
5278   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5279                    operands[4], false, false);
5280   DONE;
5281 })
5282
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)]
5292 {
5293   ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
5294                    operands[2], true, true);
5295   DONE;
5296 }
5297   [(set_attr "itanium_class" "br")])
5298
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")])
5305
5306 (define_insn "return"
5307   [(return)]
5308   "ia64_direct_return ()"
5309   "br.ret.sptk.many rp"
5310   [(set_attr "itanium_class" "br")])
5311
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")])
5323
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")])
5335
5336 (define_insn "jump"
5337   [(set (pc) (label_ref (match_operand 0 "" "")))]
5338   ""
5339   "br %l0"
5340   [(set_attr "itanium_class" "br")])
5341
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")])
5347
5348 (define_expand "tablejump"
5349   [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
5350               (use (label_ref (match_operand 1 "" "")))])]
5351   ""
5352 {
5353   rtx op0 = operands[0];
5354   rtx addr;
5355
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;
5369
5370       end_sequence ();
5371       last = get_last_insn ();
5372       start_sequence ();
5373       set = single_set (last);
5374
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     }
5382
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);
5388 })
5389
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")])
5396
5397 \f
5398 ;; ::::::::::::::::::::
5399 ;; ::
5400 ;; :: Prologue and Epilogue instructions
5401 ;; ::
5402 ;; ::::::::::::::::::::
5403
5404 (define_expand "prologue"
5405   [(const_int 1)]
5406   ""
5407 {
5408   ia64_expand_prologue ();
5409   DONE;
5410 })
5411
5412 (define_expand "epilogue"
5413   [(return)]
5414   ""
5415 {
5416   ia64_expand_epilogue (0);
5417   DONE;
5418 })
5419
5420 (define_expand "sibcall_epilogue"
5421   [(return)]
5422   ""
5423 {
5424   ia64_expand_epilogue (1);
5425   DONE;
5426 })
5427
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.
5430
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")])
5443
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.
5446
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")])
5454
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")])
5464
5465 ;; Allocate a new register frame.
5466
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")])
5478
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);")
5488
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   ""
5496 {
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";
5500 }
5501   [(set_attr "itanium_class" "st")])
5502
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);")
5512
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")])
5522
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")])
5530
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")])
5538
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.
5542
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   "*
5548 {
5549   return \";;\;%,mov %0 = ar.bsp\";
5550 }"
5551   [(set_attr "itanium_class" "frar_i")])
5552
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")])
5574
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.
5578
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")])
5585 \f
5586 ;; ::::::::::::::::::::
5587 ;; ::
5588 ;; :: Miscellaneous instructions
5589 ;; ::
5590 ;; ::::::::::::::::::::
5591
5592 ;; ??? Emitting a NOP instruction isn't very useful.  This should probably
5593 ;; be emitting ";;" to force a break in the instruction packing.
5594
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")])
5601
5602 (define_insn "nop_m"
5603   [(const_int 1)]
5604   ""
5605   "nop.m 0"
5606   [(set_attr "itanium_class" "nop_m")])
5607
5608 (define_insn "nop_i"
5609   [(const_int 2)]
5610   ""
5611   "nop.i 0"
5612   [(set_attr "itanium_class" "nop_i")])
5613
5614 (define_insn "nop_f"
5615   [(const_int 3)]
5616   ""
5617   "nop.f 0"
5618   [(set_attr "itanium_class" "nop_f")])
5619
5620 (define_insn "nop_b"
5621   [(const_int 4)]
5622   ""
5623   "nop.b 0"
5624   [(set_attr "itanium_class" "nop_b")])
5625
5626 (define_insn "nop_x"
5627   [(const_int 5)]
5628   ""
5629   ""
5630   [(set_attr "itanium_class" "nop_x")])
5631
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")])
5639
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")])
5646
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")])
5655
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")])
5663
5664 (define_expand "trap"
5665   [(trap_if (const_int 1) (const_int 0))]
5666   ""
5667   "")
5668
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.
5671
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")])
5677
5678 (define_expand "conditional_trap"
5679   [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
5680   ""
5681 {
5682   operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
5683 })
5684
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")])
5694
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")])
5700
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   ""
5706 {
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]));
5723
5724   if (i != 0 && i != 1)
5725     abort ();
5726   if (j < 0 || j > 3)
5727     abort ();
5728   return alt[i][j];
5729 }
5730   [(set_attr "itanium_class" "lfetch")])
5731 \f
5732 ;; Non-local goto support.
5733
5734 (define_expand "save_stack_nonlocal"
5735   [(use (match_operand:OI 0 "memory_operand" ""))
5736    (use (match_operand:DI 1 "register_operand" ""))]
5737   ""
5738 {
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;
5744 })
5745
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   ""
5752 {
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;
5760 })
5761
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)]
5768 {
5769   ia64_reload_gp ();
5770   DONE;
5771 })
5772
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   ""
5778 {
5779   rtx bsp = gen_rtx_REG (Pmode, 10);
5780   rtx sp = gen_rtx_REG (Pmode, 9);
5781
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));
5794
5795   cfun->machine->ia64_eh_epilogue_sp = sp;
5796   cfun->machine->ia64_eh_epilogue_bsp = bsp;
5797 })
5798 \f
5799 ;; Builtin apply support.
5800
5801 (define_expand "restore_stack_nonlocal"
5802   [(use (match_operand:DI 0 "register_operand" ""))
5803    (use (match_operand:OI 1 "memory_operand" ""))]
5804   ""
5805 {
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;
5811 })
5812
5813 \f
5814 ;;; Intrinsics support.
5815
5816 (define_expand "mf"
5817   [(set (mem:BLK (match_dup 0))
5818         (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
5819   ""
5820 {
5821   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
5822   MEM_VOLATILE_P (operands[0]) = 1;
5823 })
5824
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")])
5831
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")])
5842
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")])
5853
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")])
5865
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")])
5877
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")])
5886
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")])
5895 \f
5896 ;; Predication.
5897
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)")
5904
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")])
5912
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")])
5919
5920 (define_insn "safe_across_calls_normal"
5921   [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
5922   ""
5923 {
5924   emit_safe_across_calls ();
5925   return "";
5926 }
5927   [(set_attr "itanium_class" "ignore")
5928    (set_attr "predicable" "no")])
5929
5930 ;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
5931 ;; pointer.  This is used by the HP-UX 32 bit mode.
5932
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")])
5940
5941 ;;
5942 ;; Optimizations for ptr_extend
5943
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")])
5953
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")])