* target.h (asm_out.file_start, file_start_app_off,
[official-gcc.git] / gcc / config / ia64 / ia64.md
blobd0c65de1a210971d62eb05624347f23200ff96f9
1 ;; IA-64 Machine description template
2 ;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 ;; Contributed by James E. Wilson <wilson@cygnus.com> and
4 ;;                David Mosberger <davidm@hpl.hp.com>.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING.  If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
26 ;; reload.  This will be fixed once scheduling support is turned on.
28 ;; ??? Optimize for post-increment addressing modes.
30 ;; ??? fselect is not supported, because there is no integer register
31 ;; equivalent.
33 ;; ??? fp abs/min/max instructions may also work for integer values.
35 ;; ??? Would a predicate_reg_operand predicate be useful?  The HP one is buggy,
36 ;; it assumes the operand is a register and takes REGNO of it without checking.
38 ;; ??? Would a branch_reg_operand predicate be useful?  The HP one is buggy,
39 ;; it assumes the operand is a register and takes REGNO of it without checking.
41 ;; ??? Go through list of documented named patterns and look for more to
42 ;; implement.
44 ;; ??? Go through instruction manual and look for more instructions that
45 ;; can be emitted.
47 ;; ??? Add function unit scheduling info for Itanium (TM) processor.
49 ;; ??? Need a better way to describe alternate fp status registers.
51 (define_constants
52   [; Relocations
53    (UNSPEC_LTOFF_DTPMOD         0)
54    (UNSPEC_LTOFF_DTPREL         1)
55    (UNSPEC_DTPREL               2)
56    (UNSPEC_LTOFF_TPREL          3)
57    (UNSPEC_TPREL                4)
59    (UNSPEC_LD_BASE              9)
60    (UNSPEC_GR_SPILL             10)
61    (UNSPEC_GR_RESTORE           11)
62    (UNSPEC_FR_SPILL             12)
63    (UNSPEC_FR_RESTORE           13)
64    (UNSPEC_FR_RECIP_APPROX      14)
65    (UNSPEC_PRED_REL_MUTEX       15)
66    (UNSPEC_GETF_EXP             16)
67    (UNSPEC_PIC_CALL             17)
68    (UNSPEC_MF                   18)
69    (UNSPEC_CMPXCHG_ACQ          19)
70    (UNSPEC_FETCHADD_ACQ         20)
71    (UNSPEC_BSP_VALUE            21)
72    (UNSPEC_FLUSHRS              22)
73    (UNSPEC_BUNDLE_SELECTOR      23)
74    (UNSPEC_ADDP4                24)
75    (UNSPEC_PROLOGUE_USE         25)
76   ])
78 (define_constants
79   [(UNSPECV_ALLOC               0)
80    (UNSPECV_BLOCKAGE            1)
81    (UNSPECV_INSN_GROUP_BARRIER  2)
82    (UNSPECV_BREAK               3)
83    (UNSPECV_SET_BSP             4)
84    (UNSPECV_PSAC_ALL            5)      ; pred.safe_across_calls
85    (UNSPECV_PSAC_NORMAL         6)
86    (UNSPECV_SETJMP_RECEIVER     7)
87   ])
89 ;; ::::::::::::::::::::
90 ;; ::
91 ;; :: Attributes
92 ;; ::
93 ;; ::::::::::::::::::::
95 ;; Processor type.  This attribute must exactly match the processor_type
96 ;; enumeration in ia64.h.
97 (define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
99 ;; Instruction type.  This primarily determines how instructions can be
100 ;; packed in bundles, and secondarily affects scheduling to function units.
102 ;; A alu, can go in I or M syllable of a bundle
103 ;; I integer
104 ;; M memory
105 ;; F floating-point
106 ;; B branch
107 ;; L long immediate, takes two syllables
108 ;; S stop bit
110 ;; ??? Should not have any pattern with type unknown.  Perhaps add code to
111 ;; check this in md_reorg?  Currently use unknown for patterns which emit
112 ;; multiple instructions, patterns which emit 0 instructions, and patterns
113 ;; which emit instruction that can go in any slot (e.g. nop).
115 (define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
116         fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
117         chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
118         syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
119         nop_i,nop_m,nop_x,lfetch,pre_cycle"
120   (const_string "unknown"))
122 ;; chk_s has an I and an M form; use type A for convenience.
123 (define_attr "type" "unknown,A,I,M,F,B,L,X,S"
124   (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
125          (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
126          (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
127          (eq_attr "itanium_class" "lfetch") (const_string "M")
128          (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A")
129          (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
130          (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
131          (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
132          (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
133          (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
134          (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
135          (eq_attr "itanium_class" "stop_bit") (const_string "S")
136          (eq_attr "itanium_class" "nop_x") (const_string "X")
137          (eq_attr "itanium_class" "long_i") (const_string "L")]
138         (const_string "unknown")))
140 (define_attr "itanium_requires_unit0" "no,yes"
141   (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
142          (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
143          (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
144          (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
145          (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
146          (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
147         (const_string "no")))
149 ;; Predication.  True iff this instruction can be predicated.
151 (define_attr "predicable" "no,yes" (const_string "yes"))
155 ;; DFA descriptions of ia64 processors used for insn scheduling and
156 ;; bundling.
158 (automata_option "ndfa")
160 ;; Uncomment the following line to output automata for debugging.
161 ;; (automata_option "v")
163 (automata_option "w")
165 ;;(automata_option "no-minimization")
168 (include "itanium1.md")
169 (include "itanium2.md")
172 ;; ::::::::::::::::::::
173 ;; ::
174 ;; :: Moves
175 ;; ::
176 ;; ::::::::::::::::::::
178 ;; Set of a single predicate register.  This is only used to implement
179 ;; pr-to-pr move and complement.
181 (define_insn "*movcci"
182   [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
183         (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
184   ""
185   "@
186    cmp.ne %0, p0 = r0, r0
187    cmp.eq %0, p0 = r0, r0
188    (%1) cmp.eq.unc %0, p0 = r0, r0"
189   [(set_attr "itanium_class" "icmp")
190    (set_attr "predicable" "no")])
192 (define_insn "movbi"
193   [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
194         (match_operand:BI 1 "move_operand"         " O,n, c,  c,*r, n,*m,*r,*r"))]
195   ""
196   "@
197    cmp.ne %0, %I0 = r0, r0
198    cmp.eq %0, %I0 = r0, r0
199    #
200    #
201    tbit.nz %0, %I0 = %1, 0
202    adds %0 = %1, r0
203    ld1%O1 %0 = %1%P1
204    st1%Q0 %0 = %1%P0
205    mov %0 = %1"
206   [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
208 (define_split
209   [(set (match_operand:BI 0 "register_operand" "")
210         (match_operand:BI 1 "register_operand" ""))]
211   "reload_completed
212    && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
213    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
214   [(cond_exec (ne (match_dup 1) (const_int 0))
215      (set (match_dup 0) (const_int 1)))
216    (cond_exec (eq (match_dup 1) (const_int 0))
217      (set (match_dup 0) (const_int 0)))]
218   "")
220 (define_split
221   [(set (match_operand:BI 0 "register_operand" "")
222         (match_operand:BI 1 "register_operand" ""))]
223   "reload_completed
224    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
225    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
226   [(set (match_dup 2) (match_dup 4))
227    (set (match_dup 3) (match_dup 5))
228    (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
229   "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
230    operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
231    operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
232    operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
234 (define_expand "movqi"
235   [(set (match_operand:QI 0 "general_operand" "")
236         (match_operand:QI 1 "general_operand" ""))]
237   ""
239   rtx op1 = ia64_expand_move (operands[0], operands[1]);
240   if (!op1)
241     DONE;
242   operands[1] = op1;
245 (define_insn "*movqi_internal"
246   [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
247         (match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
248   "ia64_move_ok (operands[0], operands[1])"
249   "@
250    mov %0 = %r1
251    addl %0 = %1, r0
252    ld1%O1 %0 = %1%P1
253    st1%Q0 %0 = %r1%P0
254    getf.sig %0 = %1
255    setf.sig %0 = %r1
256    mov %0 = %1"
257   [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
259 (define_expand "movhi"
260   [(set (match_operand:HI 0 "general_operand" "")
261         (match_operand:HI 1 "general_operand" ""))]
262   ""
264   rtx op1 = ia64_expand_move (operands[0], operands[1]);
265   if (!op1)
266     DONE;
267   operands[1] = op1;
270 (define_insn "*movhi_internal"
271   [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
272         (match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
273   "ia64_move_ok (operands[0], operands[1])"
274   "@
275    mov %0 = %r1
276    addl %0 = %1, r0
277    ld2%O1 %0 = %1%P1
278    st2%Q0 %0 = %r1%P0
279    getf.sig %0 = %1
280    setf.sig %0 = %r1
281    mov %0 = %1"
282   [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
284 (define_expand "movsi"
285   [(set (match_operand:SI 0 "general_operand" "")
286         (match_operand:SI 1 "general_operand" ""))]
287   ""
289   rtx op1 = ia64_expand_move (operands[0], operands[1]);
290   if (!op1)
291     DONE;
292   operands[1] = op1;
295 (define_insn "*movsi_internal"
296   [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
297         (match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
298   "ia64_move_ok (operands[0], operands[1])"
299   "@
300   mov %0 = %r1
301   addl %0 = %1, r0
302   movl %0 = %1
303   ld4%O1 %0 = %1%P1
304   st4%Q0 %0 = %r1%P0
305   getf.sig %0 = %1
306   setf.sig %0 = %r1
307   mov %0 = %1
308   mov %0 = %1
309   mov %0 = %r1"
310   ;; frar_m, toar_m ??? why not frar_i and toar_i
311   [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
313 (define_expand "movdi"
314   [(set (match_operand:DI 0 "general_operand" "")
315         (match_operand:DI 1 "general_operand" ""))]
316   ""
318   rtx op1 = ia64_expand_move (operands[0], operands[1]);
319   if (!op1)
320     DONE;
321   operands[1] = op1;
324 (define_insn "*movdi_internal"
325   [(set (match_operand:DI 0 "destination_operand"
326                     "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
327         (match_operand:DI 1 "move_operand"
328                     "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
329   "ia64_move_ok (operands[0], operands[1])"
331   static const char * const alt[] = {
332     "%,mov %0 = %r1",
333     "%,addl %0 = %1, r0",
334     "%,movl %0 = %1",
335     "%,ld8%O1 %0 = %1%P1",
336     "%,st8%Q0 %0 = %r1%P0",
337     "%,getf.sig %0 = %1",
338     "%,setf.sig %0 = %r1",
339     "%,mov %0 = %1",
340     "%,ldf8 %0 = %1%P1",
341     "%,stf8 %0 = %1%P0",
342     "%,mov %0 = %1",
343     "%,mov %0 = %r1",
344     "%,mov %0 = %1",
345     "%,mov %0 = %1",
346     "%,mov %0 = %1",
347     "%,mov %0 = %1",
348     "mov %0 = pr",
349     "mov pr = %1, -1"
350   };
352   if (which_alternative == 2 && ! TARGET_NO_PIC
353       && symbolic_operand (operands[1], VOIDmode))
354     abort ();
356   return alt[which_alternative];
358   [(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")])
360 (define_split
361   [(set (match_operand 0 "register_operand" "")
362         (match_operand 1 "symbolic_operand" ""))]
363   "reload_completed && ! TARGET_NO_PIC"
364   [(const_int 0)]
366   ia64_expand_load_address (operands[0], operands[1]);
367   DONE;
370 (define_expand "load_fptr"
371   [(set (match_dup 2)
372         (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
373    (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
374   ""
376   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
377   operands[3] = gen_rtx_MEM (DImode, operands[2]);
378   RTX_UNCHANGING_P (operands[3]) = 1;
381 (define_insn "*load_fptr_internal1"
382   [(set (match_operand:DI 0 "register_operand" "=r")
383         (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
384   ""
385   "addl %0 = @ltoff(@fptr(%1)), gp"
386   [(set_attr "itanium_class" "ialu")])
388 (define_insn "load_gprel"
389   [(set (match_operand:DI 0 "register_operand" "=r")
390         (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
391   ""
392   "addl %0 = @gprel(%1), gp"
393   [(set_attr "itanium_class" "ialu")])
395 (define_insn "gprel64_offset"
396   [(set (match_operand:DI 0 "register_operand" "=r")
397         (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
398   ""
399   "movl %0 = @gprel(%1)"
400   [(set_attr "itanium_class" "long_i")])
402 (define_expand "load_gprel64"
403   [(set (match_dup 2)
404         (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
405    (set (match_operand:DI 0 "register_operand" "")
406         (plus:DI (match_dup 3) (match_dup 2)))]
407   ""
409   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
410   operands[3] = pic_offset_table_rtx;
413 (define_insn "*load_symptr_high"
414   [(set (match_operand:DI 0 "register_operand" "=r")
415         (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
416                  (match_operand:DI 2 "register_operand" "a")))]
417   ""
419   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
420     return "%,addl %0 = @ltoffx(%1), %2";
421   else
422     return "%,addl %0 = @ltoff(%1), %2";
424   [(set_attr "itanium_class" "ialu")])
426 (define_insn "*load_symptr_low"
427   [(set (match_operand:DI 0 "register_operand" "=r")
428         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
429                    (match_operand 2 "got_symbolic_operand" "s")))]
430   ""
432   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
433     return "%,ld8.mov %0 = [%1], %2";
434   else
435     return "%,ld8 %0 = [%1]";
437   [(set_attr "itanium_class" "ld")])
439 (define_insn "load_ltoff_dtpmod"
440   [(set (match_operand:DI 0 "register_operand" "=r")
441         (plus:DI (reg:DI 1)
442                  (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
443                             UNSPEC_LTOFF_DTPMOD)))]
444   ""
445   "addl %0 = @ltoff(@dtpmod(%1)), gp"
446   [(set_attr "itanium_class" "ialu")])
448 (define_insn "load_ltoff_dtprel"
449   [(set (match_operand:DI 0 "register_operand" "=r")
450         (plus:DI (reg:DI 1)
451                  (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
452                             UNSPEC_LTOFF_DTPREL)))]
453   ""
454   "addl %0 = @ltoff(@dtprel(%1)), gp"
455   [(set_attr "itanium_class" "ialu")])
457 (define_expand "load_dtprel"
458   [(set (match_operand:DI 0 "register_operand" "")
459         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
460                    UNSPEC_DTPREL))]
461   ""
462   "")
464 (define_insn "*load_dtprel64"
465   [(set (match_operand:DI 0 "register_operand" "=r")
466         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
467                    UNSPEC_DTPREL))]
468   "TARGET_TLS64"
469   "movl %0 = @dtprel(%1)"
470   [(set_attr "itanium_class" "long_i")])
472 (define_insn "*load_dtprel22"
473   [(set (match_operand:DI 0 "register_operand" "=r")
474         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
475                    UNSPEC_DTPREL))]
476   ""
477   "addl %0 = @dtprel(%1), r0"
478   [(set_attr "itanium_class" "ialu")])
480 (define_expand "add_dtprel"
481   [(set (match_operand:DI 0 "register_operand" "")
482         (plus:DI (match_operand:DI 1 "register_operand" "")
483                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
484                             UNSPEC_DTPREL)))]
485   "!TARGET_TLS64"
486   "")
488 (define_insn "*add_dtprel14"
489   [(set (match_operand:DI 0 "register_operand" "=r")
490         (plus:DI (match_operand:DI 1 "register_operand" "r")
491                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
492                             UNSPEC_DTPREL)))]
493   "TARGET_TLS14"
494   "adds %0 = @dtprel(%2), %1"
495   [(set_attr "itanium_class" "ialu")])
497 (define_insn "*add_dtprel22"
498   [(set (match_operand:DI 0 "register_operand" "=r")
499         (plus:DI (match_operand:DI 1 "register_operand" "a")
500                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
501                             UNSPEC_DTPREL)))]
502   "TARGET_TLS22"
503   "addl %0 = @dtprel(%2), %1"
504   [(set_attr "itanium_class" "ialu")])
506 (define_insn "load_ltoff_tprel"
507   [(set (match_operand:DI 0 "register_operand" "=r")
508         (plus:DI (reg:DI 1)
509                  (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
510                             UNSPEC_LTOFF_TPREL)))]
511   ""
512   "addl %0 = @ltoff(@tprel(%1)), gp"
513   [(set_attr "itanium_class" "ialu")])
515 (define_expand "load_tprel"
516   [(set (match_operand:DI 0 "register_operand" "")
517         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
518                    UNSPEC_TPREL))]
519   ""
520   "")
522 (define_insn "*load_tprel64"
523   [(set (match_operand:DI 0 "register_operand" "=r")
524         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
525                    UNSPEC_TPREL))]
526   "TARGET_TLS64"
527   "movl %0 = @tprel(%1)"
528   [(set_attr "itanium_class" "long_i")])
530 (define_insn "*load_tprel22"
531   [(set (match_operand:DI 0 "register_operand" "=r")
532         (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
533                    UNSPEC_TPREL))]
534   ""
535   "addl %0 = @tprel(%1), r0"
536   [(set_attr "itanium_class" "ialu")])
538 (define_expand "add_tprel"
539   [(set (match_operand:DI 0 "register_operand" "")
540         (plus:DI (match_operand:DI 1 "register_operand" "")
541                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
542                             UNSPEC_TPREL)))]
543   "!TARGET_TLS64"
544   "")
546 (define_insn "*add_tprel14"
547   [(set (match_operand:DI 0 "register_operand" "=r")
548         (plus:DI (match_operand:DI 1 "register_operand" "r")
549                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
550                             UNSPEC_TPREL)))]
551   "TARGET_TLS14"
552   "adds %0 = @tprel(%2), %1"
553   [(set_attr "itanium_class" "ialu")])
555 (define_insn "*add_tprel22"
556   [(set (match_operand:DI 0 "register_operand" "=r")
557         (plus:DI (match_operand:DI 1 "register_operand" "a")
558                  (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
559                             UNSPEC_TPREL)))]
560   "TARGET_TLS22"
561   "addl %0 = @tprel(%2), %1"
562   [(set_attr "itanium_class" "ialu")])
564 ;; With no offsettable memory references, we've got to have a scratch
565 ;; around to play with the second word.
566 (define_expand "movti"
567   [(parallel [(set (match_operand:TI 0 "general_operand" "")
568                    (match_operand:TI 1 "general_operand" ""))
569               (clobber (match_scratch:DI 2 ""))])]
570   ""
572   rtx op1 = ia64_expand_move (operands[0], operands[1]);
573   if (!op1)
574     DONE;
575   operands[1] = op1;
578 (define_insn_and_split "*movti_internal"
579   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
580         (match_operand:TI 1 "general_operand"      "ri,m,r"))
581    (clobber (match_scratch:DI 2 "=X,&r,&r"))]
582   "ia64_move_ok (operands[0], operands[1])"
583   "#"
584   "reload_completed"
585   [(const_int 0)]
587   rtx adj1, adj2, in[2], out[2], insn;
588   int first;
590   adj1 = ia64_split_timode (in, operands[1], operands[2]);
591   adj2 = ia64_split_timode (out, operands[0], operands[2]);
593   first = 0;
594   if (reg_overlap_mentioned_p (out[0], in[1]))
595     {
596       if (reg_overlap_mentioned_p (out[1], in[0]))
597         abort ();
598       first = 1;
599     }
601   if (adj1 && adj2)
602     abort ();
603   if (adj1)
604     emit_insn (adj1);
605   if (adj2)
606     emit_insn (adj2);
607   insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
608   if (GET_CODE (out[first]) == MEM
609       && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
610     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
611                                           XEXP (XEXP (out[first], 0), 0),
612                                           REG_NOTES (insn));
613   insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
614   if (GET_CODE (out[!first]) == MEM
615       && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
616     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
617                                           XEXP (XEXP (out[!first], 0), 0),
618                                           REG_NOTES (insn));
619   DONE;
621   [(set_attr "itanium_class" "unknown")
622    (set_attr "predicable" "no")])
624 ;; ??? SSA creates these.  Can't allow memories since we don't have
625 ;; the scratch register.  Fortunately combine will know how to add
626 ;; the clobber and scratch.
627 (define_insn_and_split "*movti_internal_reg"
628   [(set (match_operand:TI 0 "register_operand"  "=r")
629         (match_operand:TI 1 "nonmemory_operand" "ri"))]
630   ""
631   "#"
632   "reload_completed"
633   [(const_int 0)]
635   rtx in[2], out[2];
636   int first;
638   ia64_split_timode (in, operands[1], NULL_RTX);
639   ia64_split_timode (out, operands[0], NULL_RTX);
641   first = 0;
642   if (reg_overlap_mentioned_p (out[0], in[1]))
643     {
644       if (reg_overlap_mentioned_p (out[1], in[0]))
645         abort ();
646       first = 1;
647     }
649   emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
650   emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
651   DONE;
653   [(set_attr "itanium_class" "unknown")
654    (set_attr "predicable" "no")])
656 (define_expand "reload_inti"
657   [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
658                    (match_operand:TI 1 "" "m"))
659               (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
660   ""
662   unsigned int s_regno = REGNO (operands[2]);
663   if (s_regno == REGNO (operands[0]))
664     s_regno += 1;
665   operands[2] = gen_rtx_REG (DImode, s_regno);
668 (define_expand "reload_outti"
669   [(parallel [(set (match_operand:TI 0 "" "=m")
670                    (match_operand:TI 1 "register_operand" "r"))
671               (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
672   ""
674   unsigned int s_regno = REGNO (operands[2]);
675   if (s_regno == REGNO (operands[1]))
676     s_regno += 1;
677   operands[2] = gen_rtx_REG (DImode, s_regno);
680 ;; Floating Point Moves
682 ;; Note - Patterns for SF mode moves are compulsory, but
683 ;; patterns for DF are optional, as GCC can synthesize them.
685 (define_expand "movsf"
686   [(set (match_operand:SF 0 "general_operand" "")
687         (match_operand:SF 1 "general_operand" ""))]
688   ""
690   rtx op1 = ia64_expand_move (operands[0], operands[1]);
691   if (!op1)
692     DONE;
693   operands[1] = op1;
696 (define_insn "*movsf_internal"
697   [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
698         (match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
699   "ia64_move_ok (operands[0], operands[1])"
700   "@
701    mov %0 = %F1
702    ldfs %0 = %1%P1
703    stfs %0 = %F1%P0
704    getf.s %0 = %F1
705    setf.s %0 = %1
706    mov %0 = %1
707    ld4%O1 %0 = %1%P1
708    st4%Q0 %0 = %1%P0"
709   [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
711 (define_expand "movdf"
712   [(set (match_operand:DF 0 "general_operand" "")
713         (match_operand:DF 1 "general_operand" ""))]
714   ""
716   rtx op1 = ia64_expand_move (operands[0], operands[1]);
717   if (!op1)
718     DONE;
719   operands[1] = op1;
722 (define_insn "*movdf_internal"
723   [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
724         (match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
725   "ia64_move_ok (operands[0], operands[1])"
726   "@
727    mov %0 = %F1
728    ldfd %0 = %1%P1
729    stfd %0 = %F1%P0
730    getf.d %0 = %F1
731    setf.d %0 = %1
732    mov %0 = %1
733    ld8%O1 %0 = %1%P1
734    st8%Q0 %0 = %1%P0"
735   [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
737 ;; With no offsettable memory references, we've got to have a scratch
738 ;; around to play with the second word if the variable winds up in GRs.
739 (define_expand "movtf"
740   [(set (match_operand:TF 0 "general_operand" "")
741         (match_operand:TF 1 "general_operand" ""))]
742   "INTEL_EXTENDED_IEEE_FORMAT"
744   /* We must support TFmode loads into general registers for stdarg/vararg
745      and unprototyped calls.  We split them into DImode loads for convenience.
746      We don't need TFmode stores from general regs, because a stdarg/vararg
747      routine does a block store to memory of unnamed arguments.  */
748   if (GET_CODE (operands[0]) == REG
749       && GR_REGNO_P (REGNO (operands[0])))
750     {
751       /* We're hoping to transform everything that deals with TFmode
752          quantities and GR registers early in the compiler.  */
753       if (no_new_pseudos)
754         abort ();
756       /* Struct to register can just use TImode instead.  */
757       if ((GET_CODE (operands[1]) == SUBREG
758            && GET_MODE (SUBREG_REG (operands[1])) == TImode)
759           || (GET_CODE (operands[1]) == REG
760               && GR_REGNO_P (REGNO (operands[1]))))
761         {
762           emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
763                           SUBREG_REG (operands[1]));
764           DONE;
765         }
767       if (GET_CODE (operands[1]) == CONST_DOUBLE)
768         {
769           emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
770                           operand_subword (operands[1], 0, 0, TFmode));
771           emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
772                           operand_subword (operands[1], 1, 0, TFmode));
773           DONE;
774         }
776       /* If the quantity is in a register not known to be GR, spill it.  */
777       if (register_operand (operands[1], TFmode))
778         operands[1] = spill_tfmode_operand (operands[1], 1);
780       if (GET_CODE (operands[1]) == MEM)
781         {
782           rtx out[2];
784           out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
785           out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
787           emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
788           emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
789           DONE;
790         }
792       abort ();
793     }
795   if (! reload_in_progress && ! reload_completed)
796     {
797       operands[0] = spill_tfmode_operand (operands[0], 0);
798       operands[1] = spill_tfmode_operand (operands[1], 0);
800       if (! ia64_move_ok (operands[0], operands[1]))
801         operands[1] = force_reg (TFmode, operands[1]);
802     }
805 ;; ??? There's no easy way to mind volatile acquire/release semantics.
807 (define_insn "*movtf_internal"
808   [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
809         (match_operand:TF 1 "general_tfmode_operand"     "fG,m,fG"))]
810   "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])"
811   "@
812    mov %0 = %F1
813    ldfe %0 = %1%P1
814    stfe %0 = %F1%P0"
815   [(set_attr "itanium_class" "fmisc,fld,stf")])
817 ;; ::::::::::::::::::::
818 ;; ::
819 ;; :: Conversions
820 ;; ::
821 ;; ::::::::::::::::::::
823 ;; Signed conversions from a smaller integer to a larger integer
825 (define_insn "extendqidi2"
826   [(set (match_operand:DI 0 "gr_register_operand" "=r")
827         (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
828   ""
829   "sxt1 %0 = %1"
830   [(set_attr "itanium_class" "xtd")])
832 (define_insn "extendhidi2"
833   [(set (match_operand:DI 0 "gr_register_operand" "=r")
834         (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
835   ""
836   "sxt2 %0 = %1"
837   [(set_attr "itanium_class" "xtd")])
839 (define_insn "extendsidi2"
840   [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
841         (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
842   ""
843   "@
844    sxt4 %0 = %1
845    fsxt.r %0 = %1, %1"
846   [(set_attr "itanium_class" "xtd,fmisc")])
848 ;; Unsigned conversions from a smaller integer to a larger integer
850 (define_insn "zero_extendqidi2"
851   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
852         (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
853   ""
854   "@
855    zxt1 %0 = %1
856    ld1%O1 %0 = %1%P1"
857   [(set_attr "itanium_class" "xtd,ld")])
859 (define_insn "zero_extendhidi2"
860   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
861         (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
862   ""
863   "@
864    zxt2 %0 = %1
865    ld2%O1 %0 = %1%P1"
866   [(set_attr "itanium_class" "xtd,ld")])
868 (define_insn "zero_extendsidi2"
869   [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
870         (zero_extend:DI
871           (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
872   ""
873   "@
874    zxt4 %0 = %1
875    ld4%O1 %0 = %1%P1
876    fmix.r %0 = f0, %1"
877   [(set_attr "itanium_class" "xtd,ld,fmisc")])
879 ;; Convert between floating point types of different sizes.
881 ;; At first glance, it would appear that emitting fnorm for an extending
882 ;; conversion is unnecessary.  However, the stf and getf instructions work
883 ;; correctly only if the input is properly rounded for its type.  In
884 ;; particular, we get the wrong result for getf.d/stfd if the input is a
885 ;; denorm single.  Since we don't know what the next instruction will be, we
886 ;; have to emit an fnorm.
888 ;; ??? Optimization opportunity here.  Get rid of the insn altogether
889 ;; when we can.  Should probably use a scheme like has been proposed
890 ;; for ia32 in dealing with operands that match unary operators.  This
891 ;; would let combine merge the thing into adjacent insns.  See also how the
892 ;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
893 ;; se_register_operand.
895 (define_insn "extendsfdf2"
896   [(set (match_operand:DF 0 "fr_register_operand" "=f")
897         (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
898   ""
899   "fnorm.d %0 = %1"
900   [(set_attr "itanium_class" "fmac")])
902 (define_insn "extendsftf2"
903   [(set (match_operand:TF 0 "fr_register_operand" "=f")
904         (float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))]
905   "INTEL_EXTENDED_IEEE_FORMAT"
906   "fnorm %0 = %1"
907   [(set_attr "itanium_class" "fmac")])
909 (define_insn "extenddftf2"
910   [(set (match_operand:TF 0 "fr_register_operand" "=f")
911         (float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))]
912   "INTEL_EXTENDED_IEEE_FORMAT"
913   "fnorm %0 = %1"
914   [(set_attr "itanium_class" "fmac")])
916 (define_insn "truncdfsf2"
917   [(set (match_operand:SF 0 "fr_register_operand" "=f")
918         (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
919   ""
920   "fnorm.s %0 = %1"
921   [(set_attr "itanium_class" "fmac")])
923 (define_insn "trunctfsf2"
924   [(set (match_operand:SF 0 "fr_register_operand" "=f")
925         (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
926   "INTEL_EXTENDED_IEEE_FORMAT"
927   "fnorm.s %0 = %1"
928   [(set_attr "itanium_class" "fmac")])
930 (define_insn "trunctfdf2"
931   [(set (match_operand:DF 0 "fr_register_operand" "=f")
932         (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
933   "INTEL_EXTENDED_IEEE_FORMAT"
934   "fnorm.d %0 = %1"
935   [(set_attr "itanium_class" "fmac")])
937 ;; Convert between signed integer types and floating point.
939 (define_insn "floatditf2"
940   [(set (match_operand:TF 0 "fr_register_operand" "=f")
941         (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
942   "INTEL_EXTENDED_IEEE_FORMAT"
943   "fcvt.xf %0 = %1"
944   [(set_attr "itanium_class" "fcvtfx")])
946 ;; ??? Suboptimal.  This should be split somehow.
947 (define_insn "floatdidf2"
948   [(set (match_operand:DF 0 "register_operand" "=f")
949         (float:DF (match_operand:DI 1 "register_operand" "f")))]
950   "!INTEL_EXTENDED_IEEE_FORMAT"
951   "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0"
952   [(set_attr "itanium_class" "fcvtfx")])
954 ;; ??? Suboptimal.  This should be split somehow.
955 (define_insn "floatdisf2"
956   [(set (match_operand:SF 0 "register_operand" "=f")
957         (float:SF (match_operand:DI 1 "register_operand" "f")))]
958   "!INTEL_EXTENDED_IEEE_FORMAT"
959   "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0"
960   [(set_attr "itanium_class" "fcvtfx")])
962 (define_insn "fix_truncsfdi2"
963   [(set (match_operand:DI 0 "fr_register_operand" "=f")
964         (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
965   ""
966   "fcvt.fx.trunc %0 = %1"
967   [(set_attr "itanium_class" "fcvtfx")])
969 (define_insn "fix_truncdfdi2"
970   [(set (match_operand:DI 0 "fr_register_operand" "=f")
971         (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
972   ""
973   "fcvt.fx.trunc %0 = %1"
974   [(set_attr "itanium_class" "fcvtfx")])
976 (define_insn "fix_trunctfdi2"
977   [(set (match_operand:DI 0 "fr_register_operand" "=f")
978         (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
979   "INTEL_EXTENDED_IEEE_FORMAT"
980   "fcvt.fx.trunc %0 = %1"
981   [(set_attr "itanium_class" "fcvtfx")])
983 (define_insn "fix_trunctfdi2_alts"
984   [(set (match_operand:DI 0 "fr_register_operand" "=f")
985         (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
986    (use (match_operand:SI 2 "const_int_operand" ""))]
987   "INTEL_EXTENDED_IEEE_FORMAT"
988   "fcvt.fx.trunc.s%2 %0 = %1"
989   [(set_attr "itanium_class" "fcvtfx")])
991 ;; Convert between unsigned integer types and floating point.
993 (define_insn "floatunsdisf2"
994   [(set (match_operand:SF 0 "fr_register_operand" "=f")
995         (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
996   ""
997   "fcvt.xuf.s %0 = %1"
998   [(set_attr "itanium_class" "fcvtfx")])
1000 (define_insn "floatunsdidf2"
1001   [(set (match_operand:DF 0 "fr_register_operand" "=f")
1002         (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
1003   ""
1004   "fcvt.xuf.d %0 = %1"
1005   [(set_attr "itanium_class" "fcvtfx")])
1007 (define_insn "floatunsditf2"
1008   [(set (match_operand:TF 0 "fr_register_operand" "=f")
1009         (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
1010   "INTEL_EXTENDED_IEEE_FORMAT"
1011   "fcvt.xuf %0 = %1"
1012   [(set_attr "itanium_class" "fcvtfx")])
1014 (define_insn "fixuns_truncsfdi2"
1015   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1016         (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1017   ""
1018   "fcvt.fxu.trunc %0 = %1"
1019   [(set_attr "itanium_class" "fcvtfx")])
1021 (define_insn "fixuns_truncdfdi2"
1022   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1023         (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1024   ""
1025   "fcvt.fxu.trunc %0 = %1"
1026   [(set_attr "itanium_class" "fcvtfx")])
1028 (define_insn "fixuns_trunctfdi2"
1029   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1030         (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
1031   "INTEL_EXTENDED_IEEE_FORMAT"
1032   "fcvt.fxu.trunc %0 = %1"
1033   [(set_attr "itanium_class" "fcvtfx")])
1035 (define_insn "fixuns_trunctfdi2_alts"
1036   [(set (match_operand:DI 0 "fr_register_operand" "=f")
1037         (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
1038    (use (match_operand:SI 2 "const_int_operand" ""))]
1039   "INTEL_EXTENDED_IEEE_FORMAT"
1040   "fcvt.fxu.trunc.s%2 %0 = %1"
1041   [(set_attr "itanium_class" "fcvtfx")])
1043 ;; ::::::::::::::::::::
1044 ;; ::
1045 ;; :: Bit field extraction
1046 ;; ::
1047 ;; ::::::::::::::::::::
1049 (define_insn "extv"
1050   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1051         (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1052                          (match_operand:DI 2 "const_int_operand" "n")
1053                          (match_operand:DI 3 "const_int_operand" "n")))]
1054   ""
1055   "extr %0 = %1, %3, %2"
1056   [(set_attr "itanium_class" "ishf")])
1058 (define_insn "extzv"
1059   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1060         (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1061                          (match_operand:DI 2 "const_int_operand" "n")
1062                          (match_operand:DI 3 "const_int_operand" "n")))]
1063   ""
1064   "extr.u %0 = %1, %3, %2"
1065   [(set_attr "itanium_class" "ishf")])
1067 ;; Insert a bit field.
1068 ;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1069 ;; Source1 can be 0 or -1.
1070 ;; Source2 can be 0.
1072 ;; ??? Actual dep instruction is more powerful than what these insv
1073 ;; patterns support.  Unfortunately, combine is unable to create patterns
1074 ;; where source2 != dest.
1076 (define_expand "insv"
1077   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1078                          (match_operand:DI 1 "const_int_operand" "")
1079                          (match_operand:DI 2 "const_int_operand" ""))
1080         (match_operand:DI 3 "nonmemory_operand" ""))]
1081   ""
1083   int width = INTVAL (operands[1]);
1084   int shift = INTVAL (operands[2]);
1086   /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1087      pseudo.  */
1088   if (! register_operand (operands[3], DImode)
1089       && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1090     operands[3] = force_reg (DImode, operands[3]);
1092   /* If this is a single dep instruction, we have nothing to do.  */
1093   if (! ((register_operand (operands[3], DImode) && width <= 16)
1094          || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1095     {
1096       /* Check for cases that can be implemented with a mix instruction.  */
1097       if (width == 32 && shift == 0)
1098         {
1099           /* Directly generating the mix4left instruction confuses
1100              optimize_bit_field in function.c.  Since this is performing
1101              a useful optimization, we defer generation of the complicated
1102              mix4left RTL to the first splitting phase.  */
1103           rtx tmp = gen_reg_rtx (DImode);
1104           emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1105           DONE;
1106         }
1107       else if (width == 32 && shift == 32)
1108         {
1109           emit_insn (gen_mix4right (operands[0], operands[3]));
1110           DONE;
1111         }
1113       /* We could handle remaining cases by emitting multiple dep
1114          instructions.
1116          If we need more than two dep instructions then we lose.  A 6
1117          insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1118          mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,
1119          the latter is 6 cycles on an Itanium (TM) processor, because there is
1120          only one function unit that can execute dep and shr immed.
1122          If we only need two dep instruction, then we still lose.
1123          mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away
1124          the unnecessary mov, this is still undesirable because it will be
1125          hard to optimize, and it creates unnecessary pressure on the I0
1126          function unit.  */
1128       FAIL;
1130 #if 0
1131       /* This code may be useful for other IA-64 processors, so we leave it in
1132          for now.  */
1133       while (width > 16)
1134         {
1135           rtx tmp;
1137           emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1138                                operands[3]));
1139           shift += 16;
1140           width -= 16;
1141           tmp = gen_reg_rtx (DImode);
1142           emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1143           operands[3] = tmp;
1144         }
1145       operands[1] = GEN_INT (width);
1146       operands[2] = GEN_INT (shift);
1147 #endif
1148     }
1151 (define_insn "*insv_internal"
1152   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1153                          (match_operand:DI 1 "const_int_operand" "n")
1154                          (match_operand:DI 2 "const_int_operand" "n"))
1155         (match_operand:DI 3 "nonmemory_operand" "rP"))]
1156   "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1157    || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1158   "dep %0 = %3, %0, %2, %1"
1159   [(set_attr "itanium_class" "ishf")])
1161 ;; Combine doesn't like to create bit-field insertions into zero.
1162 (define_insn "*depz_internal"
1163   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1164         (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1165                            (match_operand:DI 2 "const_int_operand" "n"))
1166                 (match_operand:DI 3 "const_int_operand" "n")))]
1167   "CONST_OK_FOR_M (INTVAL (operands[2]))
1168    && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1170   operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1171   return "%,dep.z %0 = %1, %2, %3";
1173   [(set_attr "itanium_class" "ishf")])
1175 (define_insn "shift_mix4left"
1176   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1177                          (const_int 32) (const_int 0))
1178         (match_operand:DI 1 "gr_register_operand" "r"))
1179    (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1180   ""
1181   "#"
1182   [(set_attr "itanium_class" "unknown")])
1184 (define_split
1185   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1186                          (const_int 32) (const_int 0))
1187         (match_operand:DI 1 "register_operand" ""))
1188    (clobber (match_operand:DI 2 "register_operand" ""))]
1189   "reload_completed"
1190   [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1191    (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1192         (lshiftrt:DI (match_dup 3) (const_int 32)))]
1193   "operands[3] = operands[2];")
1195 (define_split
1196   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1197                          (const_int 32) (const_int 0))
1198         (match_operand:DI 1 "register_operand" ""))
1199    (clobber (match_operand:DI 2 "register_operand" ""))]
1200   "! reload_completed"
1201   [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1202    (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1203         (lshiftrt:DI (match_dup 3) (const_int 32)))]
1204   "operands[3] = operands[2];")
1206 (define_insn "*mix4left"
1207   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1208                          (const_int 32) (const_int 0))
1209         (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1210                      (const_int 32)))]
1211   ""
1212   "mix4.l %0 = %0, %r1"
1213   [(set_attr "itanium_class" "mmshf")])
1215 (define_insn "mix4right"
1216   [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1217                          (const_int 32) (const_int 32))
1218         (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1219   ""
1220   "mix4.r %0 = %r1, %0"
1221   [(set_attr "itanium_class" "mmshf")])
1223 ;; This is used by the rotrsi3 pattern.
1225 (define_insn "*mix4right_3op"
1226   [(set (match_operand:DI 0 "gr_register_operand" "=r")
1227         (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1228                 (ashift:DI (zero_extend:DI
1229                              (match_operand:SI 2 "gr_register_operand" "r"))
1230                            (const_int 32))))]
1231   ""
1232   "mix4.r %0 = %2, %1"
1233   [(set_attr "itanium_class" "mmshf")])
1236 ;; ::::::::::::::::::::
1237 ;; ::
1238 ;; :: 1 bit Integer arithmetic
1239 ;; ::
1240 ;; ::::::::::::::::::::
1242 (define_insn_and_split "andbi3"
1243   [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1244         (and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1245                 (match_operand:BI 2 "register_operand" "c,r,r")))]
1246   ""
1247   "@
1248    #
1249    tbit.nz.and.orcm %0, %I0 = %2, 0
1250    and %0 = %2, %1"
1251   "reload_completed
1252    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1253    && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1254   [(cond_exec (eq (match_dup 2) (const_int 0))
1255      (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1256                                 (match_dup 0))))]
1257   ""
1258   [(set_attr "itanium_class" "unknown,tbit,ilog")])
1260 (define_insn_and_split "*andcmbi3"
1261   [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1262         (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
1263                 (match_operand:BI 2 "register_operand" "0,0,r")))]
1264   ""
1265   "@
1266    #
1267    tbit.z.and.orcm %0, %I0 = %1, 0
1268    andcm %0 = %2, %1"
1269   "reload_completed
1270    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1271    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1272   [(cond_exec (ne (match_dup 1) (const_int 0))
1273      (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1274                                 (match_dup 0))))]
1275   ""
1276   [(set_attr "itanium_class" "unknown,tbit,ilog")])
1278 (define_insn_and_split "iorbi3"
1279   [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1280         (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1281                 (match_operand:BI 2 "register_operand" "c,r,r")))]
1282   ""
1283   "@
1284    #
1285    tbit.nz.or.andcm %0, %I0 = %2, 0
1286    or %0 = %2, %1"
1287   "reload_completed
1288    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1289    && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1290   [(cond_exec (ne (match_dup 2) (const_int 0))
1291      (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1292                                 (match_dup 0))))]
1293   ""
1294   [(set_attr "itanium_class" "unknown,tbit,ilog")])
1296 (define_insn_and_split "*iorcmbi3"
1297   [(set (match_operand:BI 0 "register_operand" "=c,c")
1298         (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
1299                 (match_operand:BI 2 "register_operand" "0,0")))]
1300   ""
1301   "@
1302    #
1303    tbit.z.or.andcm %0, %I0 = %1, 0"
1304   "reload_completed
1305    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1306    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1307   [(cond_exec (eq (match_dup 1) (const_int 0))
1308      (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1309                                 (match_dup 0))))]
1310   ""
1311   [(set_attr "itanium_class" "unknown,tbit")])
1313 (define_insn "one_cmplbi2"
1314   [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
1315         (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
1316    (clobber (match_scratch:BI 2 "=X,X,c,X"))]
1317   ""
1318   "@
1319    tbit.z %0, %I0 = %1, 0
1320    xor %0 = 1, %1
1321    #
1322    #"
1323   [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
1325 (define_split
1326   [(set (match_operand:BI 0 "register_operand" "")
1327         (not:BI (match_operand:BI 1 "register_operand" "")))
1328    (clobber (match_scratch:BI 2 ""))]
1329   "reload_completed
1330    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1331    && rtx_equal_p (operands[0], operands[1])"
1332   [(set (match_dup 4) (match_dup 3))
1333    (set (match_dup 0) (const_int 1))
1334    (cond_exec (ne (match_dup 2) (const_int 0))
1335      (set (match_dup 0) (const_int 0)))
1336    (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1337   "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
1338    operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
1340 (define_split
1341   [(set (match_operand:BI 0 "register_operand" "")
1342         (not:BI (match_operand:BI 1 "register_operand" "")))
1343    (clobber (match_scratch:BI 2 ""))]
1344   "reload_completed
1345    && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1346    && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1347    && ! rtx_equal_p (operands[0], operands[1])"
1348   [(cond_exec (ne (match_dup 1) (const_int 0))
1349      (set (match_dup 0) (const_int 0)))
1350    (cond_exec (eq (match_dup 1) (const_int 0))
1351      (set (match_dup 0) (const_int 1)))
1352    (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1353   "")
1355 (define_insn "*cmpsi_and_0"
1356   [(set (match_operand:BI 0 "register_operand" "=c")
1357         (and:BI (match_operator:BI 4 "predicate_operator"
1358                   [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1359                    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1360                 (match_operand:BI 1 "register_operand" "0")))]
1361   ""
1362   "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
1363   [(set_attr "itanium_class" "icmp")])
1365 (define_insn "*cmpsi_and_1"
1366   [(set (match_operand:BI 0 "register_operand" "=c")
1367         (and:BI (match_operator:BI 3 "signed_inequality_operator"
1368                   [(match_operand:SI 2 "gr_register_operand" "r")
1369                    (const_int 0)])
1370                 (match_operand:BI 1 "register_operand" "0")))]
1371   ""
1372   "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
1373   [(set_attr "itanium_class" "icmp")])
1375 (define_insn "*cmpsi_andnot_0"
1376   [(set (match_operand:BI 0 "register_operand" "=c")
1377         (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1378                          [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1379                           (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1380                 (match_operand:BI 1 "register_operand" "0")))]
1381   ""
1382   "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
1383   [(set_attr "itanium_class" "icmp")])
1385 (define_insn "*cmpsi_andnot_1"
1386   [(set (match_operand:BI 0 "register_operand" "=c")
1387         (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1388                           [(match_operand:SI 2 "gr_register_operand" "r")
1389                            (const_int 0)]))
1390                 (match_operand:BI 1 "register_operand" "0")))]
1391   ""
1392   "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
1393   [(set_attr "itanium_class" "icmp")])
1395 (define_insn "*cmpdi_and_0"
1396   [(set (match_operand:BI 0 "register_operand" "=c")
1397         (and:BI (match_operator:BI 4 "predicate_operator"
1398                   [(match_operand:DI 2 "gr_register_operand" "r")
1399                    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1400                 (match_operand:BI 1 "register_operand" "0")))]
1401   ""
1402   "cmp.%C4.and.orcm %0, %I0 = %3, %2"
1403   [(set_attr "itanium_class" "icmp")])
1405 (define_insn "*cmpdi_and_1"
1406   [(set (match_operand:BI 0 "register_operand" "=c")
1407         (and:BI (match_operator:BI 3 "signed_inequality_operator"
1408                   [(match_operand:DI 2 "gr_register_operand" "r")
1409                    (const_int 0)])
1410                 (match_operand:BI 1 "register_operand" "0")))]
1411   ""
1412   "cmp.%C3.and.orcm %0, %I0 = r0, %2"
1413   [(set_attr "itanium_class" "icmp")])
1415 (define_insn "*cmpdi_andnot_0"
1416   [(set (match_operand:BI 0 "register_operand" "=c")
1417         (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1418                          [(match_operand:DI 2 "gr_register_operand" "r")
1419                           (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1420                 (match_operand:BI 1 "register_operand" "0")))]
1421   ""
1422   "cmp.%C4.or.andcm %I0, %0 = %3, %2"
1423   [(set_attr "itanium_class" "icmp")])
1425 (define_insn "*cmpdi_andnot_1"
1426   [(set (match_operand:BI 0 "register_operand" "=c")
1427         (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1428                           [(match_operand:DI 2 "gr_register_operand" "r")
1429                            (const_int 0)]))
1430                 (match_operand:BI 1 "register_operand" "0")))]
1431   ""
1432   "cmp.%C3.or.andcm %I0, %0 = r0, %2"
1433   [(set_attr "itanium_class" "icmp")])
1435 (define_insn "*tbit_and_0"
1436   [(set (match_operand:BI 0 "register_operand" "=c")
1437         (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1438                                (const_int 1))
1439                        (const_int 0))
1440                 (match_operand:BI 2 "register_operand" "0")))]
1441   ""
1442   "tbit.nz.and.orcm %0, %I0 = %1, 0"
1443   [(set_attr "itanium_class" "tbit")])
1445 (define_insn "*tbit_and_1"
1446   [(set (match_operand:BI 0 "register_operand" "=c")
1447         (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1448                                (const_int 1))
1449                        (const_int 0))
1450                 (match_operand:BI 2 "register_operand" "0")))]
1451   ""
1452   "tbit.z.and.orcm %0, %I0 = %1, 0"
1453   [(set_attr "itanium_class" "tbit")])
1455 (define_insn "*tbit_and_2"
1456   [(set (match_operand:BI 0 "register_operand" "=c")
1457         (and:BI (ne:BI (zero_extract:DI
1458                          (match_operand:DI 1 "gr_register_operand" "r")
1459                          (const_int 1)
1460                          (match_operand:DI 2 "const_int_operand" "n"))
1461                        (const_int 0))
1462                 (match_operand:BI 3 "register_operand" "0")))]
1463   ""
1464   "tbit.nz.and.orcm %0, %I0 = %1, %2"
1465   [(set_attr "itanium_class" "tbit")])
1467 (define_insn "*tbit_and_3"
1468   [(set (match_operand:BI 0 "register_operand" "=c")
1469         (and:BI (eq:BI (zero_extract:DI
1470                          (match_operand:DI 1 "gr_register_operand" "r")
1471                          (const_int 1)
1472                          (match_operand:DI 2 "const_int_operand" "n"))
1473                        (const_int 0))
1474                 (match_operand:BI 3 "register_operand" "0")))]
1475   ""
1476   "tbit.z.and.orcm %0, %I0 = %1, %2"
1477   [(set_attr "itanium_class" "tbit")])
1479 (define_insn "*cmpsi_or_0"
1480   [(set (match_operand:BI 0 "register_operand" "=c")
1481         (ior:BI (match_operator:BI 4 "predicate_operator"
1482                   [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1483                    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1484                 (match_operand:BI 1 "register_operand" "0")))]
1485   ""
1486   "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
1487   [(set_attr "itanium_class" "icmp")])
1489 (define_insn "*cmpsi_or_1"
1490   [(set (match_operand:BI 0 "register_operand" "=c")
1491         (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1492                   [(match_operand:SI 2 "gr_register_operand" "r")
1493                    (const_int 0)])
1494                 (match_operand:BI 1 "register_operand" "0")))]
1495   ""
1496   "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
1497   [(set_attr "itanium_class" "icmp")])
1499 (define_insn "*cmpsi_orcm_0"
1500   [(set (match_operand:BI 0 "register_operand" "=c")
1501         (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1502                          [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1503                           (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1504                 (match_operand:BI 1 "register_operand" "0")))]
1505   ""
1506   "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
1507   [(set_attr "itanium_class" "icmp")])
1509 (define_insn "*cmpsi_orcm_1"
1510   [(set (match_operand:BI 0 "register_operand" "=c")
1511         (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1512                           [(match_operand:SI 2 "gr_register_operand" "r")
1513                            (const_int 0)]))
1514                 (match_operand:BI 1 "register_operand" "0")))]
1515   ""
1516   "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
1517   [(set_attr "itanium_class" "icmp")])
1519 (define_insn "*cmpdi_or_0"
1520   [(set (match_operand:BI 0 "register_operand" "=c")
1521         (ior:BI (match_operator:BI 4 "predicate_operator"
1522                   [(match_operand:DI 2 "gr_register_operand" "r")
1523                    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1524                 (match_operand:BI 1 "register_operand" "0")))]
1525   ""
1526   "cmp.%C4.or.andcm %0, %I0 = %3, %2"
1527   [(set_attr "itanium_class" "icmp")])
1529 (define_insn "*cmpdi_or_1"
1530   [(set (match_operand:BI 0 "register_operand" "=c")
1531         (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1532                   [(match_operand:DI 2 "gr_register_operand" "r")
1533                    (const_int 0)])
1534                 (match_operand:BI 1 "register_operand" "0")))]
1535   ""
1536   "cmp.%C3.or.andcm %0, %I0 = r0, %2"
1537   [(set_attr "itanium_class" "icmp")])
1539 (define_insn "*cmpdi_orcm_0"
1540   [(set (match_operand:BI 0 "register_operand" "=c")
1541         (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1542                          [(match_operand:DI 2 "gr_register_operand" "r")
1543                           (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1544                 (match_operand:BI 1 "register_operand" "0")))]
1545   ""
1546   "cmp.%C4.and.orcm %I0, %0 = %3, %2"
1547   [(set_attr "itanium_class" "icmp")])
1549 (define_insn "*cmpdi_orcm_1"
1550   [(set (match_operand:BI 0 "register_operand" "=c")
1551         (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1552                           [(match_operand:DI 2 "gr_register_operand" "r")
1553                            (const_int 0)]))
1554                 (match_operand:BI 1 "register_operand" "0")))]
1555   ""
1556   "cmp.%C3.and.orcm %I0, %0 = r0, %2"
1557   [(set_attr "itanium_class" "icmp")])
1559 (define_insn "*tbit_or_0"
1560   [(set (match_operand:BI 0 "register_operand" "=c")
1561         (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1562                                (const_int 1))
1563                        (const_int 0))
1564                 (match_operand:BI 2 "register_operand" "0")))]
1565   ""
1566   "tbit.nz.or.andcm %0, %I0 = %1, 0"
1567   [(set_attr "itanium_class" "tbit")])
1569 (define_insn "*tbit_or_1"
1570   [(set (match_operand:BI 0 "register_operand" "=c")
1571         (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1572                                (const_int 1))
1573                        (const_int 0))
1574                 (match_operand:BI 2 "register_operand" "0")))]
1575   ""
1576   "tbit.z.or.andcm %0, %I0 = %1, 0"
1577   [(set_attr "itanium_class" "tbit")])
1579 (define_insn "*tbit_or_2"
1580   [(set (match_operand:BI 0 "register_operand" "=c")
1581         (ior:BI (ne:BI (zero_extract:DI
1582                          (match_operand:DI 1 "gr_register_operand" "r")
1583                          (const_int 1)
1584                          (match_operand:DI 2 "const_int_operand" "n"))
1585                        (const_int 0))
1586                 (match_operand:BI 3 "register_operand" "0")))]
1587   ""
1588   "tbit.nz.or.andcm %0, %I0 = %1, %2"
1589   [(set_attr "itanium_class" "tbit")])
1591 (define_insn "*tbit_or_3"
1592   [(set (match_operand:BI 0 "register_operand" "=c")
1593         (ior:BI (eq:BI (zero_extract:DI
1594                          (match_operand:DI 1 "gr_register_operand" "r")
1595                          (const_int 1)
1596                          (match_operand:DI 2 "const_int_operand" "n"))
1597                        (const_int 0))
1598                 (match_operand:BI 3 "register_operand" "0")))]
1599   ""
1600   "tbit.z.or.andcm %0, %I0 = %1, %2"
1601   [(set_attr "itanium_class" "tbit")])
1603 ;; Transform test of and/or of setcc into parallel comparisons.
1605 (define_split
1606   [(set (match_operand:BI 0 "register_operand" "")
1607         (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1608                               (const_int 0))
1609                        (match_operand:DI 3 "register_operand" ""))
1610                (const_int 0)))]
1611   ""
1612   [(set (match_dup 0)
1613         (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1614                 (match_dup 2)))]
1615   "")
1617 (define_split
1618   [(set (match_operand:BI 0 "register_operand" "")
1619         (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1620                               (const_int 0))
1621                        (match_operand:DI 3 "register_operand" ""))
1622                (const_int 0)))]
1623   ""
1624   [(set (match_dup 0)
1625         (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1626                 (match_dup 2)))
1627    (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1628               (clobber (scratch))])]
1629   "")
1631 (define_split
1632   [(set (match_operand:BI 0 "register_operand" "")
1633         (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1634                               (const_int 0))
1635                        (match_operand:DI 3 "register_operand" ""))
1636                (const_int 0)))]
1637   ""
1638   [(set (match_dup 0) 
1639         (ior:BI (ne:BI (match_dup 3) (const_int 0))
1640                 (match_dup 2)))]
1641   "")
1643 (define_split
1644   [(set (match_operand:BI 0 "register_operand" "")
1645         (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1646                               (const_int 0))
1647                        (match_operand:DI 3 "register_operand" ""))
1648                (const_int 0)))]
1649   ""
1650   [(set (match_dup 0) 
1651         (ior:BI (ne:BI (match_dup 3) (const_int 0))
1652                 (match_dup 2)))
1653    (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1654               (clobber (scratch))])]
1655   "")
1657 ;; ??? Incredibly hackish.  Either need four proper patterns with all
1658 ;; the alternatives, or rely on sched1 to split the insn and hope that
1659 ;; nothing bad happens to the comparisons in the meantime.
1661 ;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1662 ;; that we're doing height reduction.
1664 ;(define_insn_and_split ""
1665 ;  [(set (match_operand:BI 0 "register_operand" "=c")
1666 ;       (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1667 ;                         [(match_operand 2 "" "")
1668 ;                          (match_operand 3 "" "")])
1669 ;                       (match_operator:BI 4 "comparison_operator"
1670 ;                         [(match_operand 5 "" "")
1671 ;                          (match_operand 6 "" "")]))
1672 ;               (match_dup 0)))]
1673 ;  "flag_schedule_insns"
1674 ;  "#"
1675 ;  ""
1676 ;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
1677 ;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
1678 ;  "")
1680 ;(define_insn_and_split ""
1681 ;  [(set (match_operand:BI 0 "register_operand" "=c")
1682 ;       (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1683 ;                         [(match_operand 2 "" "")
1684 ;                          (match_operand 3 "" "")])
1685 ;                       (match_operator:BI 4 "comparison_operator"
1686 ;                         [(match_operand 5 "" "")
1687 ;                          (match_operand 6 "" "")]))
1688 ;               (match_dup 0)))]
1689 ;  "flag_schedule_insns"
1690 ;  "#"
1691 ;  ""
1692 ;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
1693 ;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
1694 ;  "")
1696 ;(define_split
1697 ;  [(set (match_operand:BI 0 "register_operand" "")
1698 ;       (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1699 ;                         [(match_operand 2 "" "")
1700 ;                          (match_operand 3 "" "")])
1701 ;                       (match_operand:BI 7 "register_operand" ""))
1702 ;               (and:BI (match_operator:BI 4 "comparison_operator"
1703 ;                         [(match_operand 5 "" "")
1704 ;                          (match_operand 6 "" "")])
1705 ;                       (match_operand:BI 8 "register_operand" ""))))]
1706 ;  ""
1707 ;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
1708 ;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
1709 ;                             (match_dup 0)))]
1710 ;  "")
1712 ;(define_split
1713 ;  [(set (match_operand:BI 0 "register_operand" "")
1714 ;       (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1715 ;                         [(match_operand 2 "" "")
1716 ;                          (match_operand 3 "" "")])
1717 ;                       (match_operand:BI 7 "register_operand" ""))
1718 ;               (ior:BI (match_operator:BI 4 "comparison_operator"
1719 ;                         [(match_operand 5 "" "")
1720 ;                          (match_operand 6 "" "")])
1721 ;                       (match_operand:BI 8 "register_operand" ""))))]
1722 ;  ""
1723 ;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
1724 ;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
1725 ;                             (match_dup 0)))]
1726 ;  "")
1728 ;; Try harder to avoid predicate copies by duplicating compares.
1729 ;; Note that we'll have already split the predicate copy, which
1730 ;; is kind of a pain, but oh well.
1732 (define_peephole2
1733   [(set (match_operand:BI 0 "register_operand" "")
1734         (match_operand:BI 1 "comparison_operator" ""))
1735    (set (match_operand:CCI 2 "register_operand" "")
1736         (match_operand:CCI 3 "register_operand" ""))
1737    (set (match_operand:CCI 4 "register_operand" "")
1738         (match_operand:CCI 5 "register_operand" ""))
1739    (set (match_operand:BI 6 "register_operand" "")
1740         (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
1741   "REGNO (operands[3]) == REGNO (operands[0])
1742    && REGNO (operands[4]) == REGNO (operands[0]) + 1
1743    && REGNO (operands[4]) == REGNO (operands[2]) + 1
1744    && REGNO (operands[6]) == REGNO (operands[2])"
1745   [(set (match_dup 0) (match_dup 1))
1746    (set (match_dup 6) (match_dup 7))]
1747   "operands[7] = copy_rtx (operands[1]);")
1749 ;; ::::::::::::::::::::
1750 ;; ::
1751 ;; :: 16 bit Integer arithmetic
1752 ;; ::
1753 ;; ::::::::::::::::::::
1755 (define_insn "mulhi3"
1756   [(set (match_operand:HI 0 "gr_register_operand" "=r")
1757         (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1758                  (match_operand:HI 2 "gr_register_operand" "r")))]
1759   ""
1760   "pmpy2.r %0 = %1, %2"
1761   [(set_attr "itanium_class" "mmmul")])
1764 ;; ::::::::::::::::::::
1765 ;; ::
1766 ;; :: 32 bit Integer arithmetic
1767 ;; ::
1768 ;; ::::::::::::::::::::
1770 (define_insn "addsi3"
1771   [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1772         (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1773                  (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1774   ""
1775   "@
1776    add %0 = %1, %2
1777    adds %0 = %2, %1
1778    addl %0 = %2, %1"
1779   [(set_attr "itanium_class" "ialu")])
1781 (define_insn "*addsi3_plus1"
1782   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1783         (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1784                           (match_operand:SI 2 "gr_register_operand" "r"))
1785                  (const_int 1)))]
1786   ""
1787   "add %0 = %1, %2, 1"
1788   [(set_attr "itanium_class" "ialu")])
1790 (define_insn "*addsi3_plus1_alt"
1791   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1792         (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1793                           (const_int 2))
1794                  (const_int 1)))]
1795   ""
1796   "add %0 = %1, %1, 1"
1797   [(set_attr "itanium_class" "ialu")])
1799 (define_insn "*addsi3_shladd"
1800   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1801         (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1802                           (match_operand:SI 2 "shladd_operand" "n"))
1803                  (match_operand:SI 3 "gr_register_operand" "r")))]
1804   ""
1805   "shladd %0 = %1, %S2, %3"
1806   [(set_attr "itanium_class" "ialu")])
1808 (define_insn "subsi3"
1809   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1810         (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1811                   (match_operand:SI 2 "gr_register_operand" "r")))]
1812   ""
1813   "sub %0 = %1, %2"
1814   [(set_attr "itanium_class" "ialu")])
1816 (define_insn "*subsi3_minus1"
1817   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1818         (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1819                  (match_operand:SI 2 "gr_register_operand" "r")))]
1820   ""
1821   "sub %0 = %2, %1, 1"
1822   [(set_attr "itanium_class" "ialu")])
1824 ;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
1826 (define_insn "mulsi3"
1827   [(set (match_operand:SI 0 "fr_register_operand" "=f")
1828         (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1829                  (match_operand:SI 2 "grfr_register_operand" "f")))]
1830   ""
1831   "xmpy.l %0 = %1, %2"
1832   [(set_attr "itanium_class" "xmpy")])
1834 (define_insn "maddsi4"
1835   [(set (match_operand:SI 0 "fr_register_operand" "=f")
1836         (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1837                           (match_operand:SI 2 "grfr_register_operand" "f"))
1838                  (match_operand:SI 3 "grfr_register_operand" "f")))]
1839   ""
1840   "xma.l %0 = %1, %2, %3"
1841   [(set_attr "itanium_class" "xmpy")])
1843 (define_insn "negsi2"
1844   [(set (match_operand:SI 0 "gr_register_operand" "=r")
1845         (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
1846   ""
1847   "sub %0 = r0, %1"
1848   [(set_attr "itanium_class" "ialu")])
1850 (define_expand "abssi2"
1851   [(set (match_dup 2)
1852         (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1853    (set (match_operand:SI 0 "gr_register_operand" "")
1854         (if_then_else:SI (eq (match_dup 2) (const_int 0))
1855                          (neg:SI (match_dup 1))
1856                          (match_dup 1)))]
1857   ""
1858   { operands[2] = gen_reg_rtx (BImode); })
1860 (define_expand "sminsi3"
1861   [(set (match_dup 3)
1862         (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1863                (match_operand:SI 2 "gr_register_operand" "")))
1864    (set (match_operand:SI 0 "gr_register_operand" "")
1865         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1866                          (match_dup 2) (match_dup 1)))]
1867   ""
1868   { operands[3] = gen_reg_rtx (BImode); })
1870 (define_expand "smaxsi3"
1871   [(set (match_dup 3)
1872         (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1873                (match_operand:SI 2 "gr_register_operand" "")))
1874    (set (match_operand:SI 0 "gr_register_operand" "")
1875         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1876                          (match_dup 1) (match_dup 2)))]
1877   ""
1878   { operands[3] = gen_reg_rtx (BImode); })
1880 (define_expand "uminsi3"
1881   [(set (match_dup 3)
1882         (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1883                 (match_operand:SI 2 "gr_register_operand" "")))
1884    (set (match_operand:SI 0 "gr_register_operand" "")
1885         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1886                          (match_dup 2) (match_dup 1)))]
1887   ""
1888   { operands[3] = gen_reg_rtx (BImode); })
1890 (define_expand "umaxsi3"
1891   [(set (match_dup 3)
1892         (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1893                 (match_operand:SI 2 "gr_register_operand" "")))
1894    (set (match_operand:SI 0 "gr_register_operand" "")
1895         (if_then_else:SI (ne (match_dup 3) (const_int 0))
1896                          (match_dup 1) (match_dup 2)))]
1897   ""
1898   { operands[3] = gen_reg_rtx (BImode); })
1900 (define_expand "divsi3"
1901   [(set (match_operand:SI 0 "register_operand" "")
1902         (div:SI (match_operand:SI 1 "general_operand" "")
1903                 (match_operand:SI 2 "general_operand" "")))]
1904   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
1906   rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
1907   REAL_VALUE_TYPE twon34_r;
1909   op0_tf = gen_reg_rtx (TFmode);
1910   op0_di = gen_reg_rtx (DImode);
1912   if (CONSTANT_P (operands[1]))
1913     operands[1] = force_reg (SImode, operands[1]);
1914   op1_tf = gen_reg_rtx (TFmode);
1915   expand_float (op1_tf, operands[1], 0);
1917   if (CONSTANT_P (operands[2]))
1918     operands[2] = force_reg (SImode, operands[2]);
1919   op2_tf = gen_reg_rtx (TFmode);
1920   expand_float (op2_tf, operands[2], 0);
1922   /* 2^-34 */
1923   real_2expN (&twon34_r, -34);
1924   twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
1925   twon34 = force_reg (TFmode, twon34);
1927   emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
1929   emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
1930   emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1931   DONE;
1934 (define_expand "modsi3"
1935   [(set (match_operand:SI 0 "register_operand" "")
1936         (mod:SI (match_operand:SI 1 "general_operand" "")
1937                 (match_operand:SI 2 "general_operand" "")))]
1938   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
1940   rtx op2_neg, op1_di, div;
1942   div = gen_reg_rtx (SImode);
1943   emit_insn (gen_divsi3 (div, operands[1], operands[2]));
1945   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1947   /* This is a trick to get us to reuse the value that we're sure to
1948      have already copied to the FP regs.  */
1949   op1_di = gen_reg_rtx (DImode);
1950   convert_move (op1_di, operands[1], 0);
1952   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1953                           gen_lowpart (SImode, op1_di)));
1954   DONE;
1957 (define_expand "udivsi3"
1958   [(set (match_operand:SI 0 "register_operand" "")
1959         (udiv:SI (match_operand:SI 1 "general_operand" "")
1960                  (match_operand:SI 2 "general_operand" "")))]
1961   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
1963   rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
1964   REAL_VALUE_TYPE twon34_r;
1966   op0_tf = gen_reg_rtx (TFmode);
1967   op0_di = gen_reg_rtx (DImode);
1969   if (CONSTANT_P (operands[1]))
1970     operands[1] = force_reg (SImode, operands[1]);
1971   op1_tf = gen_reg_rtx (TFmode);
1972   expand_float (op1_tf, operands[1], 1);
1974   if (CONSTANT_P (operands[2]))
1975     operands[2] = force_reg (SImode, operands[2]);
1976   op2_tf = gen_reg_rtx (TFmode);
1977   expand_float (op2_tf, operands[2], 1);
1979   /* 2^-34 */
1980   real_2expN (&twon34_r, -34);
1981   twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
1982   twon34 = force_reg (TFmode, twon34);
1984   emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
1986   emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
1987   emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1988   DONE;
1991 (define_expand "umodsi3"
1992   [(set (match_operand:SI 0 "register_operand" "")
1993         (umod:SI (match_operand:SI 1 "general_operand" "")
1994                  (match_operand:SI 2 "general_operand" "")))]
1995   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
1997   rtx op2_neg, op1_di, div;
1999   div = gen_reg_rtx (SImode);
2000   emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
2002   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2004   /* This is a trick to get us to reuse the value that we're sure to
2005      have already copied to the FP regs.  */
2006   op1_di = gen_reg_rtx (DImode);
2007   convert_move (op1_di, operands[1], 1);
2009   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2010                           gen_lowpart (SImode, op1_di)));
2011   DONE;
2014 (define_insn_and_split "divsi3_internal"
2015   [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2016         (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2017                           (match_operand:TF 2 "fr_register_operand" "f"))))
2018    (clobber (match_scratch:TF 4 "=&f"))
2019    (clobber (match_scratch:TF 5 "=&f"))
2020    (clobber (match_scratch:BI 6 "=c"))
2021    (use (match_operand:TF 3 "fr_register_operand" "f"))]
2022   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2023   "#"
2024   "&& reload_completed"
2025   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2026               (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2027                                             UNSPEC_FR_RECIP_APPROX))
2028               (use (const_int 1))])
2029    (cond_exec (ne (match_dup 6) (const_int 0))
2030      (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
2031                 (use (const_int 1))]))
2032    (cond_exec (ne (match_dup 6) (const_int 0))
2033      (parallel [(set (match_dup 5)
2034                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2035                               (match_dup 7)))
2036                 (use (const_int 1))]))
2037    (cond_exec (ne (match_dup 6) (const_int 0))
2038      (parallel [(set (match_dup 4)
2039                      (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2040                               (match_dup 4)))
2041                 (use (const_int 1))]))
2042    (cond_exec (ne (match_dup 6) (const_int 0))
2043      (parallel [(set (match_dup 5)
2044                      (plus:TF (mult:TF (match_dup 5) (match_dup 5))
2045                               (match_dup 3)))
2046                 (use (const_int 1))]))
2047    (cond_exec (ne (match_dup 6) (const_int 0))
2048      (parallel [(set (match_dup 0)
2049                      (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2050                               (match_dup 4)))
2051                 (use (const_int 1))]))
2052   ] 
2053   "operands[7] = CONST1_RTX (TFmode);"
2054   [(set_attr "predicable" "no")])
2056 ;; ::::::::::::::::::::
2057 ;; ::
2058 ;; :: 64 bit Integer arithmetic
2059 ;; ::
2060 ;; ::::::::::::::::::::
2062 (define_insn "adddi3"
2063   [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
2064         (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
2065                  (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
2066   ""
2067   "@
2068    add %0 = %1, %2
2069    adds %0 = %2, %1
2070    addl %0 = %2, %1"
2071   [(set_attr "itanium_class" "ialu")])
2073 (define_insn "*adddi3_plus1"
2074   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2075         (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
2076                           (match_operand:DI 2 "gr_register_operand" "r"))
2077                  (const_int 1)))]
2078   ""
2079   "add %0 = %1, %2, 1"
2080   [(set_attr "itanium_class" "ialu")])
2082 ;; This has some of the same problems as shladd.  We let the shladd
2083 ;; eliminator hack handle it, which results in the 1 being forced into
2084 ;; a register, but not more ugliness here.
2085 (define_insn "*adddi3_plus1_alt"
2086   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2087         (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2088                           (const_int 2))
2089                  (const_int 1)))]
2090   ""
2091   "add %0 = %1, %1, 1"
2092   [(set_attr "itanium_class" "ialu")])
2094 (define_insn "subdi3"
2095   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2096         (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
2097                   (match_operand:DI 2 "gr_register_operand" "r")))]
2098   ""
2099   "sub %0 = %1, %2"
2100   [(set_attr "itanium_class" "ialu")])
2102 (define_insn "*subdi3_minus1"
2103   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2104         (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
2105                  (match_operand:DI 2 "gr_register_operand" "r")))]
2106   ""
2107   "sub %0 = %2, %1, 1"
2108   [(set_attr "itanium_class" "ialu")])
2110 ;; ??? Use grfr instead of fr because of virtual register elimination
2111 ;; and silly test cases multiplying by the frame pointer.
2112 (define_insn "muldi3"
2113   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2114         (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2115                  (match_operand:DI 2 "grfr_register_operand" "f")))]
2116   ""
2117   "xmpy.l %0 = %1, %2"
2118   [(set_attr "itanium_class" "xmpy")])
2120 ;; ??? If operand 3 is an eliminable reg, then register elimination causes the
2121 ;; same problem that we have with shladd below.  Unfortunately, this case is
2122 ;; much harder to fix because the multiply puts the result in an FP register,
2123 ;; but the add needs inputs from a general register.  We add a spurious clobber
2124 ;; here so that it will be present just in case register elimination gives us
2125 ;; the funny result.
2127 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2129 ;; ??? Maybe we should change how adds are canonicalized.
2131 (define_insn "madddi4"
2132   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2133         (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2134                           (match_operand:DI 2 "grfr_register_operand" "f"))
2135                  (match_operand:DI 3 "grfr_register_operand" "f")))
2136    (clobber (match_scratch:DI 4 "=X"))]
2137   ""
2138   "xma.l %0 = %1, %2, %3"
2139   [(set_attr "itanium_class" "xmpy")])
2141 ;; This can be created by register elimination if operand3 of shladd is an
2142 ;; eliminable register or has reg_equiv_constant set.
2144 ;; We have to use nonmemory_operand for operand 4, to ensure that the
2145 ;; validate_changes call inside eliminate_regs will always succeed.  If it
2146 ;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
2147 ;; incorrectly.
2149 (define_insn "*madddi4_elim"
2150   [(set (match_operand:DI 0 "register_operand" "=&r")
2151         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
2152                                    (match_operand:DI 2 "register_operand" "f"))
2153                           (match_operand:DI 3 "register_operand" "f"))
2154                  (match_operand:DI 4 "nonmemory_operand" "rI")))
2155    (clobber (match_scratch:DI 5 "=f"))]
2156   "reload_in_progress"
2157   "#"
2158   [(set_attr "itanium_class" "unknown")])
2160 (define_split
2161   [(set (match_operand:DI 0 "register_operand" "")
2162         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2163                                    (match_operand:DI 2 "register_operand" ""))
2164                           (match_operand:DI 3 "register_operand" ""))
2165                  (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
2166    (clobber (match_scratch:DI 5 ""))]
2167   "reload_completed"
2168   [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2169                                           (match_dup 3)))
2170               (clobber (match_dup 0))])
2171    (set (match_dup 0) (match_dup 5))
2172    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2173   "")
2175 ;; ??? There are highpart multiply and add instructions, but we have no way
2176 ;; to generate them.
2178 (define_insn "smuldi3_highpart"
2179   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2180         (truncate:DI
2181          (lshiftrt:TI
2182           (mult:TI (sign_extend:TI
2183                      (match_operand:DI 1 "fr_register_operand" "f"))
2184                    (sign_extend:TI
2185                      (match_operand:DI 2 "fr_register_operand" "f")))
2186           (const_int 64))))]
2187   ""
2188   "xmpy.h %0 = %1, %2"
2189   [(set_attr "itanium_class" "xmpy")])
2191 (define_insn "umuldi3_highpart"
2192   [(set (match_operand:DI 0 "fr_register_operand" "=f")
2193         (truncate:DI
2194          (lshiftrt:TI
2195           (mult:TI (zero_extend:TI
2196                      (match_operand:DI 1 "fr_register_operand" "f"))
2197                    (zero_extend:TI
2198                      (match_operand:DI 2 "fr_register_operand" "f")))
2199           (const_int 64))))]
2200   ""
2201   "xmpy.hu %0 = %1, %2"
2202   [(set_attr "itanium_class" "xmpy")])
2204 (define_insn "negdi2"
2205   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2206         (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2207   ""
2208   "sub %0 = r0, %1"
2209   [(set_attr "itanium_class" "ialu")])
2211 (define_expand "absdi2"
2212   [(set (match_dup 2)
2213         (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2214    (set (match_operand:DI 0 "gr_register_operand" "")
2215         (if_then_else:DI (eq (match_dup 2) (const_int 0))
2216                          (neg:DI (match_dup 1))
2217                          (match_dup 1)))]
2218   ""
2219   { operands[2] = gen_reg_rtx (BImode); })
2221 (define_expand "smindi3"
2222   [(set (match_dup 3)
2223         (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2224                (match_operand:DI 2 "gr_register_operand" "")))
2225    (set (match_operand:DI 0 "gr_register_operand" "")
2226         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2227                          (match_dup 2) (match_dup 1)))]
2228   ""
2229   { operands[3] = gen_reg_rtx (BImode); })
2231 (define_expand "smaxdi3"
2232   [(set (match_dup 3)
2233         (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2234                (match_operand:DI 2 "gr_register_operand" "")))
2235    (set (match_operand:DI 0 "gr_register_operand" "")
2236         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2237                          (match_dup 1) (match_dup 2)))]
2238   ""
2239   { operands[3] = gen_reg_rtx (BImode); })
2241 (define_expand "umindi3"
2242   [(set (match_dup 3)
2243         (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2244                 (match_operand:DI 2 "gr_register_operand" "")))
2245    (set (match_operand:DI 0 "gr_register_operand" "")
2246         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2247                          (match_dup 2) (match_dup 1)))]
2248   ""
2249   { operands[3] = gen_reg_rtx (BImode); })
2251 (define_expand "umaxdi3"
2252   [(set (match_dup 3)
2253         (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2254                 (match_operand:DI 2 "gr_register_operand" "")))
2255    (set (match_operand:DI 0 "gr_register_operand" "")
2256         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2257                          (match_dup 1) (match_dup 2)))]
2258   ""
2259   { operands[3] = gen_reg_rtx (BImode); })
2261 (define_expand "ffsdi2"
2262   [(set (match_dup 6)
2263         (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2264    (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
2265    (set (match_dup 5) (const_int 0))
2266    (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2267    (set (match_dup 4) (popcount:DI (match_dup 3)))
2268    (set (match_operand:DI 0 "gr_register_operand" "")
2269         (if_then_else:DI (ne (match_dup 6) (const_int 0))
2270                          (match_dup 5) (match_dup 4)))]
2271   ""
2273   operands[2] = gen_reg_rtx (DImode);
2274   operands[3] = gen_reg_rtx (DImode);
2275   operands[4] = gen_reg_rtx (DImode);
2276   operands[5] = gen_reg_rtx (DImode);
2277   operands[6] = gen_reg_rtx (BImode);
2280 (define_expand "ctzdi2"
2281   [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
2282                                (const_int -1)))
2283    (set (match_dup 3) (not:DI (match_dup 1)))
2284    (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
2285    (set (match_operand:DI 0 "gr_register_operand" "")
2286         (popcount:DI (match_dup 4)))]
2287   ""
2289   operands[2] = gen_reg_rtx (DImode);
2290   operands[3] = gen_reg_rtx (DImode);
2291   operands[4] = gen_reg_rtx (DImode);
2294 ;; ??? Ought to invent some unspecs for !INTEL_EXTENDED_IEEE_FORMAT.
2295 ;; Note the computation here is op0 = 63 - (exp - 0xffff).
2296 (define_expand "clzdi2"
2297   [(set (match_dup 2)
2298         (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "")))
2299    (set (match_dup 3)
2300         (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
2301    (set (match_dup 4) (const_int 65598))
2302    (set (match_operand:DI 0 "gr_register_operand" "")
2303         (minus:DI (match_dup 4) (match_dup 3)))]
2304   "INTEL_EXTENDED_IEEE_FORMAT"
2306   operands[2] = gen_reg_rtx (TFmode);
2307   operands[3] = gen_reg_rtx (DImode);
2308   operands[4] = gen_reg_rtx (DImode);
2311 (define_insn "popcountdi2"
2312   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2313         (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2314   ""
2315   "popcnt %0 = %1"
2316   [(set_attr "itanium_class" "mmmul")])
2318 (define_insn "*getf_exp_tf"
2319   [(set (match_operand:DI 0 "gr_register_operand" "=r")
2320         (unspec:DI [(match_operand:TF 1 "fr_register_operand" "f")]
2321                    UNSPEC_GETF_EXP))]
2322   "INTEL_EXTENDED_IEEE_FORMAT"
2323   "getf.exp %0 = %1"
2324   [(set_attr "itanium_class" "frfr")])
2326 (define_expand "divdi3"
2327   [(set (match_operand:DI 0 "register_operand" "")
2328         (div:DI (match_operand:DI 1 "general_operand" "")
2329                 (match_operand:DI 2 "general_operand" "")))]
2330   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2332   rtx op1_tf, op2_tf, op0_tf;
2334   op0_tf = gen_reg_rtx (TFmode);
2336   if (CONSTANT_P (operands[1]))
2337     operands[1] = force_reg (DImode, operands[1]);
2338   op1_tf = gen_reg_rtx (TFmode);
2339   expand_float (op1_tf, operands[1], 0);
2341   if (CONSTANT_P (operands[2]))
2342     operands[2] = force_reg (DImode, operands[2]);
2343   op2_tf = gen_reg_rtx (TFmode);
2344   expand_float (op2_tf, operands[2], 0);
2346   if (TARGET_INLINE_INT_DIV_LAT)
2347     emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
2348   else
2349     emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
2351   emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
2352   DONE;
2355 (define_expand "moddi3"
2356   [(set (match_operand:DI 0 "register_operand" "")
2357         (mod:SI (match_operand:DI 1 "general_operand" "")
2358                 (match_operand:DI 2 "general_operand" "")))]
2359   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2361   rtx op2_neg, div;
2363   div = gen_reg_rtx (DImode);
2364   emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2366   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2368   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2369   DONE;
2372 (define_expand "udivdi3"
2373   [(set (match_operand:DI 0 "register_operand" "")
2374         (udiv:DI (match_operand:DI 1 "general_operand" "")
2375                  (match_operand:DI 2 "general_operand" "")))]
2376   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2378   rtx op1_tf, op2_tf, op0_tf;
2380   op0_tf = gen_reg_rtx (TFmode);
2382   if (CONSTANT_P (operands[1]))
2383     operands[1] = force_reg (DImode, operands[1]);
2384   op1_tf = gen_reg_rtx (TFmode);
2385   expand_float (op1_tf, operands[1], 1);
2387   if (CONSTANT_P (operands[2]))
2388     operands[2] = force_reg (DImode, operands[2]);
2389   op2_tf = gen_reg_rtx (TFmode);
2390   expand_float (op2_tf, operands[2], 1);
2392   if (TARGET_INLINE_INT_DIV_LAT)
2393     emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
2394   else
2395     emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
2397   emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
2398   DONE;
2401 (define_expand "umoddi3"
2402   [(set (match_operand:DI 0 "register_operand" "")
2403         (umod:DI (match_operand:DI 1 "general_operand" "")
2404                  (match_operand:DI 2 "general_operand" "")))]
2405   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
2407   rtx op2_neg, div;
2409   div = gen_reg_rtx (DImode);
2410   emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2412   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2414   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2415   DONE;
2418 (define_insn_and_split "divdi3_internal_lat"
2419   [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2420         (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2421                           (match_operand:TF 2 "fr_register_operand" "f"))))
2422    (clobber (match_scratch:TF 3 "=&f"))
2423    (clobber (match_scratch:TF 4 "=&f"))
2424    (clobber (match_scratch:TF 5 "=&f"))
2425    (clobber (match_scratch:BI 6 "=c"))]
2426   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_LAT"
2427   "#"
2428   "&& reload_completed"
2429   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2430               (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2431                                             UNSPEC_FR_RECIP_APPROX))
2432               (use (const_int 1))])
2433    (cond_exec (ne (match_dup 6) (const_int 0))
2434      (parallel [(set (match_dup 3)
2435                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2436                               (match_dup 7)))
2437                 (use (const_int 1))]))
2438    (cond_exec (ne (match_dup 6) (const_int 0))
2439      (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
2440                 (use (const_int 1))]))
2441    (cond_exec (ne (match_dup 6) (const_int 0))
2442      (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
2443                 (use (const_int 1))]))
2444    (cond_exec (ne (match_dup 6) (const_int 0))
2445      (parallel [(set (match_dup 4)
2446                      (plus:TF (mult:TF (match_dup 3) (match_dup 4))
2447                               (match_dup 4)))
2448                 (use (const_int 1))]))
2449    (cond_exec (ne (match_dup 6) (const_int 0))
2450      (parallel [(set (match_dup 0)
2451                      (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2452                               (match_dup 0)))
2453                 (use (const_int 1))]))
2454    (cond_exec (ne (match_dup 6) (const_int 0))
2455      (parallel [(set (match_dup 3)
2456                      (plus:TF (mult:TF (match_dup 5) (match_dup 4))
2457                               (match_dup 4)))
2458                 (use (const_int 1))]))
2459    (cond_exec (ne (match_dup 6) (const_int 0))
2460      (parallel [(set (match_dup 0)
2461                      (plus:TF (mult:TF (match_dup 5) (match_dup 0))
2462                               (match_dup 0)))
2463                 (use (const_int 1))]))
2464    (cond_exec (ne (match_dup 6) (const_int 0))
2465      (parallel [(set (match_dup 4)
2466                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2467                               (match_dup 1)))
2468                 (use (const_int 1))]))
2469    (cond_exec (ne (match_dup 6) (const_int 0))
2470      (parallel [(set (match_dup 0)
2471                      (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2472                               (match_dup 3)))
2473                 (use (const_int 1))]))
2474   ] 
2475   "operands[7] = CONST1_RTX (TFmode);"
2476   [(set_attr "predicable" "no")])
2478 (define_insn_and_split "divdi3_internal_thr"
2479   [(set (match_operand:TF 0 "fr_register_operand" "=&f")
2480         (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
2481                           (match_operand:TF 2 "fr_register_operand" "f"))))
2482    (clobber (match_scratch:TF 3 "=&f"))
2483    (clobber (match_scratch:TF 4 "=f"))
2484    (clobber (match_scratch:BI 5 "=c"))]
2485   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_THR"
2486   "#"
2487   "&& reload_completed"
2488   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2489               (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 
2490                                             UNSPEC_FR_RECIP_APPROX))
2491               (use (const_int 1))])
2492    (cond_exec (ne (match_dup 5) (const_int 0))
2493      (parallel [(set (match_dup 3)
2494                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
2495                               (match_dup 6)))
2496                 (use (const_int 1))]))
2497    (cond_exec (ne (match_dup 5) (const_int 0))
2498      (parallel [(set (match_dup 0)
2499                      (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2500                               (match_dup 0)))
2501                 (use (const_int 1))]))
2502    (cond_exec (ne (match_dup 5) (const_int 0))
2503      (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
2504                 (use (const_int 1))]))
2505    (cond_exec (ne (match_dup 5) (const_int 0))
2506      (parallel [(set (match_dup 0)
2507                      (plus:TF (mult:TF (match_dup 3) (match_dup 0))
2508                               (match_dup 0)))
2509                 (use (const_int 1))]))
2510    (cond_exec (ne (match_dup 5) (const_int 0))
2511      (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
2512                 (use (const_int 1))]))
2513    (cond_exec (ne (match_dup 5) (const_int 0))
2514      (parallel [(set (match_dup 4)
2515                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
2516                               (match_dup 1)))
2517                 (use (const_int 1))]))
2518    (cond_exec (ne (match_dup 5) (const_int 0))
2519      (parallel [(set (match_dup 0)
2520                      (plus:TF (mult:TF (match_dup 4) (match_dup 0))
2521                               (match_dup 3)))
2522                 (use (const_int 1))]))
2523   ] 
2524   "operands[6] = CONST1_RTX (TFmode);"
2525   [(set_attr "predicable" "no")])
2527 ;; ::::::::::::::::::::
2528 ;; ::
2529 ;; :: 32 bit floating point arithmetic
2530 ;; ::
2531 ;; ::::::::::::::::::::
2533 (define_insn "addsf3"
2534   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2535         (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2536                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2537   ""
2538   "fadd.s %0 = %1, %F2"
2539   [(set_attr "itanium_class" "fmac")])
2541 (define_insn "subsf3"
2542   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2543         (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2544                   (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2545   ""
2546   "fsub.s %0 = %F1, %F2"
2547   [(set_attr "itanium_class" "fmac")])
2549 (define_insn "mulsf3"
2550   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2551         (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2552                  (match_operand:SF 2 "fr_register_operand" "f")))]
2553   ""
2554   "fmpy.s %0 = %1, %2"
2555   [(set_attr "itanium_class" "fmac")])
2557 (define_insn "abssf2"
2558   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2559         (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2560   ""
2561   "fabs %0 = %1"
2562   [(set_attr "itanium_class" "fmisc")])
2564 (define_insn "negsf2"
2565   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2566         (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2567   ""
2568   "fneg %0 = %1"
2569   [(set_attr "itanium_class" "fmisc")])
2571 (define_insn "*nabssf2"
2572   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2573         (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
2574   ""
2575   "fnegabs %0 = %1"
2576   [(set_attr "itanium_class" "fmisc")])
2578 (define_insn "minsf3"
2579   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2580         (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2581                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2582   ""
2583   "fmin %0 = %1, %F2"
2584   [(set_attr "itanium_class" "fmisc")])
2586 (define_insn "maxsf3"
2587   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2588         (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2589                  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2590   ""
2591   "fmax %0 = %1, %F2"
2592   [(set_attr "itanium_class" "fmisc")])
2594 (define_insn "*maddsf4"
2595   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2596         (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2597                           (match_operand:SF 2 "fr_register_operand" "f"))
2598                  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2599   ""
2600   "fma.s %0 = %1, %2, %F3"
2601   [(set_attr "itanium_class" "fmac")])
2603 (define_insn "*msubsf4"
2604   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2605         (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2606                            (match_operand:SF 2 "fr_register_operand" "f"))
2607                   (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2608   ""
2609   "fms.s %0 = %1, %2, %F3"
2610   [(set_attr "itanium_class" "fmac")])
2612 (define_insn "*nmulsf3"
2613   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2614         (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2615                          (match_operand:SF 2 "fr_register_operand" "f"))))]
2616   ""
2617   "fnmpy.s %0 = %1, %2"
2618   [(set_attr "itanium_class" "fmac")])
2620 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2622 (define_insn "*nmaddsf4"
2623   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2624         (plus:SF (neg:SF (mult:SF
2625                            (match_operand:SF 1 "fr_register_operand" "f")
2626                            (match_operand:SF 2 "fr_register_operand" "f")))
2627                  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2628   ""
2629   "fnma.s %0 = %1, %2, %F3"
2630   [(set_attr "itanium_class" "fmac")])
2632 (define_expand "divsf3"
2633   [(set (match_operand:SF 0 "fr_register_operand" "")
2634         (div:SF (match_operand:SF 1 "fr_register_operand" "")
2635                 (match_operand:SF 2 "fr_register_operand" "")))]
2636   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
2638   rtx insn;
2639   if (TARGET_INLINE_FLOAT_DIV_LAT)
2640     insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
2641   else
2642     insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
2643   emit_insn (insn);
2644   DONE;
2647 (define_insn_and_split "divsf3_internal_lat"
2648   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2649         (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2650                 (match_operand:SF 2 "fr_register_operand" "f")))
2651    (clobber (match_scratch:TF 3 "=&f"))
2652    (clobber (match_scratch:TF 4 "=f"))
2653    (clobber (match_scratch:BI 5 "=c"))]
2654   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
2655   "#"
2656   "&& reload_completed"
2657   [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
2658               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2659                                             UNSPEC_FR_RECIP_APPROX))
2660               (use (const_int 1))])
2661    (cond_exec (ne (match_dup 5) (const_int 0))
2662      (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
2663                 (use (const_int 1))]))
2664    (cond_exec (ne (match_dup 5) (const_int 0))
2665      (parallel [(set (match_dup 4)
2666                      (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
2667                               (match_dup 10)))
2668                 (use (const_int 1))]))
2669    (cond_exec (ne (match_dup 5) (const_int 0))
2670      (parallel [(set (match_dup 3)
2671                      (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2672                               (match_dup 3)))
2673                 (use (const_int 1))]))
2674    (cond_exec (ne (match_dup 5) (const_int 0))
2675      (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
2676                 (use (const_int 1))]))
2677    (cond_exec (ne (match_dup 5) (const_int 0))
2678      (parallel [(set (match_dup 3)
2679                      (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2680                               (match_dup 3)))
2681                 (use (const_int 1))]))
2682    (cond_exec (ne (match_dup 5) (const_int 0))
2683      (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
2684                 (use (const_int 1))]))
2685    (cond_exec (ne (match_dup 5) (const_int 0))
2686      (parallel [(set (match_dup 9)
2687                      (float_truncate:DF
2688                        (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2689                               (match_dup 3))))
2690                 (use (const_int 1))]))
2691    (cond_exec (ne (match_dup 5) (const_int 0))
2692      (set (match_dup 0)
2693           (float_truncate:SF (match_dup 6))))
2694   ] 
2696   operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2697   operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2698   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2699   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2700   operands[10] = CONST1_RTX (TFmode);
2702   [(set_attr "predicable" "no")])
2704 (define_insn_and_split "divsf3_internal_thr"
2705   [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2706         (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2707                 (match_operand:SF 2 "fr_register_operand" "f")))
2708    (clobber (match_scratch:TF 3 "=&f"))
2709    (clobber (match_scratch:TF 4 "=f"))
2710    (clobber (match_scratch:BI 5 "=c"))]
2711   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
2712   "#"
2713   "&& reload_completed"
2714   [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
2715               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2716                                             UNSPEC_FR_RECIP_APPROX))
2717               (use (const_int 1))])
2718    (cond_exec (ne (match_dup 5) (const_int 0))
2719      (parallel [(set (match_dup 3)
2720                      (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
2721                               (match_dup 10)))
2722                 (use (const_int 1))]))
2723    (cond_exec (ne (match_dup 5) (const_int 0))
2724      (parallel [(set (match_dup 3)
2725                      (plus:TF (mult:TF (match_dup 3) (match_dup 3))
2726                               (match_dup 3)))
2727                 (use (const_int 1))]))
2728    (cond_exec (ne (match_dup 5) (const_int 0))
2729      (parallel [(set (match_dup 6)
2730                      (plus:TF (mult:TF (match_dup 3) (match_dup 6))
2731                               (match_dup 6)))
2732                 (use (const_int 1))]))
2733    (cond_exec (ne (match_dup 5) (const_int 0))
2734      (parallel [(set (match_dup 9)
2735                      (float_truncate:SF
2736                        (mult:TF (match_dup 7) (match_dup 6))))
2737                 (use (const_int 1))]))
2738    (cond_exec (ne (match_dup 5) (const_int 0))
2739      (parallel [(set (match_dup 4)
2740                      (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3)))
2741                               (match_dup 7)))
2742                 (use (const_int 1))]))
2743    (cond_exec (ne (match_dup 5) (const_int 0))
2744      (set (match_dup 0)
2745           (float_truncate:SF
2746             (plus:TF (mult:TF (match_dup 4) (match_dup 6))
2747                               (match_dup 3)))))
2748   ] 
2750   operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2751   operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2752   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2753   operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
2754   operands[10] = CONST1_RTX (TFmode);
2756   [(set_attr "predicable" "no")])
2758 ;; ::::::::::::::::::::
2759 ;; ::
2760 ;; :: 64 bit floating point arithmetic
2761 ;; ::
2762 ;; ::::::::::::::::::::
2764 (define_insn "adddf3"
2765   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2766         (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2767                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2768   ""
2769   "fadd.d %0 = %1, %F2"
2770   [(set_attr "itanium_class" "fmac")])
2772 (define_insn "*adddf3_trunc"
2773   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2774         (float_truncate:SF
2775           (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2776                    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2777   ""
2778   "fadd.s %0 = %1, %F2"
2779   [(set_attr "itanium_class" "fmac")])
2781 (define_insn "subdf3"
2782   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2783         (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2784                   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2785   ""
2786   "fsub.d %0 = %F1, %F2"
2787   [(set_attr "itanium_class" "fmac")])
2789 (define_insn "*subdf3_trunc"
2790   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2791         (float_truncate:SF
2792           (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2793                     (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2794   ""
2795   "fsub.s %0 = %F1, %F2"
2796   [(set_attr "itanium_class" "fmac")])
2798 (define_insn "muldf3"
2799   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2800         (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2801                  (match_operand:DF 2 "fr_register_operand" "f")))]
2802   ""
2803   "fmpy.d %0 = %1, %2"
2804   [(set_attr "itanium_class" "fmac")])
2806 (define_insn "*muldf3_trunc"
2807   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2808         (float_truncate:SF
2809           (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2810                    (match_operand:DF 2 "fr_register_operand" "f"))))]
2811   ""
2812   "fmpy.s %0 = %1, %2"
2813   [(set_attr "itanium_class" "fmac")])
2815 (define_insn "absdf2"
2816   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2817         (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2818   ""
2819   "fabs %0 = %1"
2820   [(set_attr "itanium_class" "fmisc")])
2822 (define_insn "negdf2"
2823   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2824         (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2825   ""
2826   "fneg %0 = %1"
2827   [(set_attr "itanium_class" "fmisc")])
2829 (define_insn "*nabsdf2"
2830   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2831         (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
2832   ""
2833   "fnegabs %0 = %1"
2834   [(set_attr "itanium_class" "fmisc")])
2836 (define_insn "mindf3"
2837   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2838         (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
2839                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2840   ""
2841   "fmin %0 = %1, %F2"
2842   [(set_attr "itanium_class" "fmisc")])
2844 (define_insn "maxdf3"
2845   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2846         (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
2847                  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2848   ""
2849   "fmax %0 = %1, %F2"
2850   [(set_attr "itanium_class" "fmisc")])
2852 (define_insn "*madddf4"
2853   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2854         (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2855                           (match_operand:DF 2 "fr_register_operand" "f"))
2856                  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2857   ""
2858   "fma.d %0 = %1, %2, %F3"
2859   [(set_attr "itanium_class" "fmac")])
2861 (define_insn "*madddf4_trunc"
2862   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2863         (float_truncate:SF
2864           (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2865                             (match_operand:DF 2 "fr_register_operand" "f"))
2866                    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
2867   ""
2868   "fma.s %0 = %1, %2, %F3"
2869   [(set_attr "itanium_class" "fmac")])
2871 (define_insn "*msubdf4"
2872   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2873         (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2874                            (match_operand:DF 2 "fr_register_operand" "f"))
2875                   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2876   ""
2877   "fms.d %0 = %1, %2, %F3"
2878   [(set_attr "itanium_class" "fmac")])
2880 (define_insn "*msubdf4_trunc"
2881   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2882         (float_truncate:SF
2883           (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2884                              (match_operand:DF 2 "fr_register_operand" "f"))
2885                     (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
2886   ""
2887   "fms.s %0 = %1, %2, %F3"
2888   [(set_attr "itanium_class" "fmac")])
2890 (define_insn "*nmuldf3"
2891   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2892         (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2893                          (match_operand:DF 2 "fr_register_operand" "f"))))]
2894   ""
2895   "fnmpy.d %0 = %1, %2"
2896   [(set_attr "itanium_class" "fmac")])
2898 (define_insn "*nmuldf3_trunc"
2899   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2900         (float_truncate:SF
2901           (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2902                            (match_operand:DF 2 "fr_register_operand" "f")))))]
2903   ""
2904   "fnmpy.s %0 = %1, %2"
2905   [(set_attr "itanium_class" "fmac")])
2907 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2909 (define_insn "*nmadddf4"
2910   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2911         (plus:DF (neg:DF (mult:DF
2912                            (match_operand:DF 1 "fr_register_operand" "f")
2913                            (match_operand:DF 2 "fr_register_operand" "f")))
2914                  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2915   ""
2916   "fnma.d %0 = %1, %2, %F3"
2917   [(set_attr "itanium_class" "fmac")])
2919 (define_insn "*nmadddf4_alts"
2920   [(set (match_operand:DF 0 "fr_register_operand" "=f")
2921         (plus:DF (neg:DF (mult:DF
2922                            (match_operand:DF 1 "fr_register_operand" "f")
2923                            (match_operand:DF 2 "fr_register_operand" "f")))
2924                  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
2925    (use (match_operand:SI 4 "const_int_operand" ""))]
2926   ""
2927   "fnma.d.s%4 %0 = %1, %2, %F3"
2928   [(set_attr "itanium_class" "fmac")])
2930 (define_insn "*nmadddf4_trunc"
2931   [(set (match_operand:SF 0 "fr_register_operand" "=f")
2932         (float_truncate:SF
2933           (plus:DF (neg:DF (mult:DF
2934                              (match_operand:DF 1 "fr_register_operand" "f")
2935                              (match_operand:DF 2 "fr_register_operand" "f")))
2936                    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
2937   ""
2938   "fnma.s %0 = %1, %2, %F3"
2939   [(set_attr "itanium_class" "fmac")])
2941 (define_expand "divdf3"
2942   [(set (match_operand:DF 0 "fr_register_operand" "")
2943         (div:DF (match_operand:DF 1 "fr_register_operand" "")
2944                 (match_operand:DF 2 "fr_register_operand" "")))]
2945   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
2947   rtx insn;
2948   if (TARGET_INLINE_FLOAT_DIV_LAT)
2949     insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
2950   else
2951     insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
2952   emit_insn (insn);
2953   DONE;
2956 (define_insn_and_split "divdf3_internal_lat"
2957   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
2958         (div:DF (match_operand:DF 1 "fr_register_operand" "f")
2959                 (match_operand:DF 2 "fr_register_operand" "f")))
2960    (clobber (match_scratch:TF 3 "=&f"))
2961    (clobber (match_scratch:TF 4 "=&f"))
2962    (clobber (match_scratch:TF 5 "=&f"))
2963    (clobber (match_scratch:BI 6 "=c"))]
2964   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
2965   "#"
2966   "&& reload_completed"
2967   [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
2968               (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
2969                                             UNSPEC_FR_RECIP_APPROX))
2970               (use (const_int 1))])
2971    (cond_exec (ne (match_dup 6) (const_int 0))
2972      (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
2973                 (use (const_int 1))]))
2974    (cond_exec (ne (match_dup 6) (const_int 0))
2975      (parallel [(set (match_dup 4)
2976                      (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7)))
2977                               (match_dup 12)))
2978                 (use (const_int 1))]))
2979    (cond_exec (ne (match_dup 6) (const_int 0))
2980      (parallel [(set (match_dup 3)
2981                      (plus:TF (mult:TF (match_dup 4) (match_dup 3))
2982                               (match_dup 3)))
2983                 (use (const_int 1))]))
2984    (cond_exec (ne (match_dup 6) (const_int 0))
2985      (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4)))
2986                 (use (const_int 1))]))
2987    (cond_exec (ne (match_dup 6) (const_int 0))
2988      (parallel [(set (match_dup 7)
2989                      (plus:TF (mult:TF (match_dup 4) (match_dup 7))
2990                               (match_dup 7)))
2991                 (use (const_int 1))]))
2992    (cond_exec (ne (match_dup 6) (const_int 0))
2993      (parallel [(set (match_dup 3)
2994                      (plus:TF (mult:TF (match_dup 5) (match_dup 3))
2995                               (match_dup 3)))
2996                 (use (const_int 1))]))
2997    (cond_exec (ne (match_dup 6) (const_int 0))
2998      (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5)))
2999                 (use (const_int 1))]))
3000    (cond_exec (ne (match_dup 6) (const_int 0))
3001      (parallel [(set (match_dup 7)
3002                      (plus:TF (mult:TF (match_dup 5) (match_dup 7))
3003                               (match_dup 7)))
3004                 (use (const_int 1))]))
3005    (cond_exec (ne (match_dup 6) (const_int 0))
3006      (parallel [(set (match_dup 10)
3007                      (float_truncate:DF
3008                        (plus:TF (mult:TF (match_dup 4) (match_dup 3))
3009                               (match_dup 3))))
3010                 (use (const_int 1))]))
3011    (cond_exec (ne (match_dup 6) (const_int 0))
3012      (parallel [(set (match_dup 7)
3013                      (plus:TF (mult:TF (match_dup 4) (match_dup 7))
3014                               (match_dup 7)))
3015                 (use (const_int 1))]))
3016    (cond_exec (ne (match_dup 6) (const_int 0))
3017      (parallel [(set (match_dup 11)
3018                      (float_truncate:DF
3019                        (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3)))
3020                                 (match_dup 8))))
3021                 (use (const_int 1))]))
3022    (cond_exec (ne (match_dup 6) (const_int 0))
3023      (set (match_dup 0)
3024           (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7))
3025                               (match_dup 3)))))
3026   ] 
3028   operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3029   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3030   operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3031   operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3032   operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3033   operands[12] = CONST1_RTX (TFmode);
3035   [(set_attr "predicable" "no")])
3037 (define_insn_and_split "divdf3_internal_thr"
3038   [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3039         (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3040                 (match_operand:DF 2 "fr_register_operand" "f")))
3041    (clobber (match_scratch:TF 3 "=&f"))
3042    (clobber (match_scratch:DF 4 "=f"))
3043    (clobber (match_scratch:BI 5 "=c"))]
3044   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
3045   "#"
3046   "&& reload_completed"
3047   [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
3048               (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3049                                             UNSPEC_FR_RECIP_APPROX))
3050               (use (const_int 1))])
3051    (cond_exec (ne (match_dup 5) (const_int 0))
3052      (parallel [(set (match_dup 3)
3053                      (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
3054                               (match_dup 10)))
3055                 (use (const_int 1))]))
3056    (cond_exec (ne (match_dup 5) (const_int 0))
3057      (parallel [(set (match_dup 6)
3058                      (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3059                               (match_dup 6)))
3060                 (use (const_int 1))]))
3061    (cond_exec (ne (match_dup 5) (const_int 0))
3062      (parallel [(set (match_dup 3)
3063                      (mult:TF (match_dup 3) (match_dup 3)))
3064                 (use (const_int 1))]))
3065    (cond_exec (ne (match_dup 5) (const_int 0))
3066      (parallel [(set (match_dup 6)
3067                      (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3068                               (match_dup 6)))
3069                 (use (const_int 1))]))
3070    (cond_exec (ne (match_dup 5) (const_int 0))
3071      (parallel [(set (match_dup 3)
3072                      (mult:TF (match_dup 3) (match_dup 3)))
3073                 (use (const_int 1))]))
3074    (cond_exec (ne (match_dup 5) (const_int 0))
3075      (parallel [(set (match_dup 6)
3076                      (plus:TF (mult:TF (match_dup 3) (match_dup 6))
3077                               (match_dup 6)))
3078                 (use (const_int 1))]))
3079    (cond_exec (ne (match_dup 5) (const_int 0))
3080      (parallel [(set (match_dup 9)
3081                      (float_truncate:DF
3082                        (mult:TF (match_dup 7) (match_dup 3))))
3083                 (use (const_int 1))]))
3084    (cond_exec (ne (match_dup 5) (const_int 0))
3085      (parallel [(set (match_dup 4)
3086                      (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
3087                               (match_dup 1)))
3088                 (use (const_int 1))]))
3089    (cond_exec (ne (match_dup 5) (const_int 0))
3090      (set (match_dup 0)
3091           (plus:DF (mult:DF (match_dup 4) (match_dup 0))
3092                             (match_dup 9))))
3093   ] 
3095   operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3096   operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3097   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3098   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3099   operands[10] = CONST1_RTX (TFmode);
3101   [(set_attr "predicable" "no")])
3103 ;; ::::::::::::::::::::
3104 ;; ::
3105 ;; :: 80 bit floating point arithmetic
3106 ;; ::
3107 ;; ::::::::::::::::::::
3109 (define_insn "addtf3"
3110   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3111         (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3112                  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3113   "INTEL_EXTENDED_IEEE_FORMAT"
3114   "fadd %0 = %F1, %F2"
3115   [(set_attr "itanium_class" "fmac")])
3117 (define_insn "*addtf3_truncsf"
3118   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3119         (float_truncate:SF
3120           (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3121                    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3122   "INTEL_EXTENDED_IEEE_FORMAT"
3123   "fadd.s %0 = %F1, %F2"
3124   [(set_attr "itanium_class" "fmac")])
3126 (define_insn "*addtf3_truncdf"
3127   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3128         (float_truncate:DF
3129           (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3130                    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3131   "INTEL_EXTENDED_IEEE_FORMAT"
3132   "fadd.d %0 = %F1, %F2"
3133   [(set_attr "itanium_class" "fmac")])
3135 (define_insn "subtf3"
3136   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3137         (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3138                   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3139   "INTEL_EXTENDED_IEEE_FORMAT"
3140   "fsub %0 = %F1, %F2"
3141   [(set_attr "itanium_class" "fmac")])
3143 (define_insn "*subtf3_truncsf"
3144   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3145         (float_truncate:SF
3146           (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3147                     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3148   "INTEL_EXTENDED_IEEE_FORMAT"
3149   "fsub.s %0 = %F1, %F2"
3150   [(set_attr "itanium_class" "fmac")])
3152 (define_insn "*subtf3_truncdf"
3153   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3154         (float_truncate:DF
3155           (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3156                     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3157   "INTEL_EXTENDED_IEEE_FORMAT"
3158   "fsub.d %0 = %F1, %F2"
3159   [(set_attr "itanium_class" "fmac")])
3161 (define_insn "multf3"
3162   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3163         (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3164                  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3165   "INTEL_EXTENDED_IEEE_FORMAT"
3166   "fmpy %0 = %F1, %F2"
3167   [(set_attr "itanium_class" "fmac")])
3169 (define_insn "*multf3_truncsf"
3170   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3171         (float_truncate:SF
3172           (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3173                    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3174   "INTEL_EXTENDED_IEEE_FORMAT"
3175   "fmpy.s %0 = %F1, %F2"
3176   [(set_attr "itanium_class" "fmac")])
3178 (define_insn "*multf3_truncdf"
3179   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3180         (float_truncate:DF
3181           (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3182                    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3183   "INTEL_EXTENDED_IEEE_FORMAT"
3184   "fmpy.d %0 = %F1, %F2"
3185   [(set_attr "itanium_class" "fmac")])
3187 (define_insn "*multf3_alts"
3188   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3189         (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3190                  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3191    (use (match_operand:SI 3 "const_int_operand" ""))]
3192   "INTEL_EXTENDED_IEEE_FORMAT"
3193   "fmpy.s%3 %0 = %F1, %F2"
3194   [(set_attr "itanium_class" "fmac")])
3196 (define_insn "*multf3_truncsf_alts"
3197   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3198         (float_truncate:SF
3199           (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3200                    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
3201    (use (match_operand:SI 3 "const_int_operand" ""))]
3202   "INTEL_EXTENDED_IEEE_FORMAT"
3203   "fmpy.s.s%3 %0 = %F1, %F2"
3204   [(set_attr "itanium_class" "fmac")])
3206 (define_insn "*multf3_truncdf_alts"
3207   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3208         (float_truncate:DF
3209           (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3210                    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
3211    (use (match_operand:SI 3 "const_int_operand" ""))]
3212   "INTEL_EXTENDED_IEEE_FORMAT"
3213   "fmpy.d.s%3 %0 = %F1, %F2"
3214   [(set_attr "itanium_class" "fmac")])
3216 (define_insn "abstf2"
3217   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3218         (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
3219   "INTEL_EXTENDED_IEEE_FORMAT"
3220   "fabs %0 = %F1"
3221   [(set_attr "itanium_class" "fmisc")])
3223 (define_insn "negtf2"
3224   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3225         (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
3226   "INTEL_EXTENDED_IEEE_FORMAT"
3227   "fneg %0 = %F1"
3228   [(set_attr "itanium_class" "fmisc")])
3230 (define_insn "*nabstf2"
3231   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3232         (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
3233   "INTEL_EXTENDED_IEEE_FORMAT"
3234   "fnegabs %0 = %F1"
3235   [(set_attr "itanium_class" "fmisc")])
3237 (define_insn "mintf3"
3238   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3239         (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3240                  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3241   "INTEL_EXTENDED_IEEE_FORMAT"
3242   "fmin %0 = %F1, %F2"
3243   [(set_attr "itanium_class" "fmisc")])
3245 (define_insn "maxtf3"
3246   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3247         (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3248                  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
3249   "INTEL_EXTENDED_IEEE_FORMAT"
3250   "fmax %0 = %F1, %F2"
3251   [(set_attr "itanium_class" "fmisc")])
3253 (define_insn "*maddtf4"
3254   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3255         (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3256                           (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3257                  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3258   "INTEL_EXTENDED_IEEE_FORMAT"
3259   "fma %0 = %F1, %F2, %F3"
3260   [(set_attr "itanium_class" "fmac")])
3262 (define_insn "*maddtf4_truncsf"
3263   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3264         (float_truncate:SF
3265           (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3266                             (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3267                    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3268   "INTEL_EXTENDED_IEEE_FORMAT"
3269   "fma.s %0 = %F1, %F2, %F3"
3270   [(set_attr "itanium_class" "fmac")])
3272 (define_insn "*maddtf4_truncdf"
3273   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3274         (float_truncate:DF
3275           (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3276                             (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3277                    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3278   "INTEL_EXTENDED_IEEE_FORMAT"
3279   "fma.d %0 = %F1, %F2, %F3"
3280   [(set_attr "itanium_class" "fmac")])
3282 (define_insn "*maddtf4_alts"
3283   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3284         (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3285                           (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3286                  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
3287    (use (match_operand:SI 4 "const_int_operand" ""))]
3288   "INTEL_EXTENDED_IEEE_FORMAT"
3289   "fma.s%4 %0 = %F1, %F2, %F3"
3290   [(set_attr "itanium_class" "fmac")])
3292 (define_insn "*maddtf4_alts_truncdf"
3293   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3294         (float_truncate:DF
3295           (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3296                             (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3297                    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
3298    (use (match_operand:SI 4 "const_int_operand" ""))]
3299   "INTEL_EXTENDED_IEEE_FORMAT"
3300   "fma.d.s%4 %0 = %F1, %F2, %F3"
3301   [(set_attr "itanium_class" "fmac")])
3303 (define_insn "*msubtf4"
3304   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3305         (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3306                            (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3307                   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3308   "INTEL_EXTENDED_IEEE_FORMAT"
3309   "fms %0 = %F1, %F2, %F3"
3310   [(set_attr "itanium_class" "fmac")])
3312 (define_insn "*msubtf4_truncsf"
3313   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3314         (float_truncate:SF
3315           (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3316                              (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3317                     (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3318   "INTEL_EXTENDED_IEEE_FORMAT"
3319   "fms.s %0 = %F1, %F2, %F3"
3320   [(set_attr "itanium_class" "fmac")])
3322 (define_insn "*msubtf4_truncdf"
3323   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3324         (float_truncate:DF
3325           (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3326                              (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
3327                     (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3328   "INTEL_EXTENDED_IEEE_FORMAT"
3329   "fms.d %0 = %F1, %F2, %F3"
3330   [(set_attr "itanium_class" "fmac")])
3332 (define_insn "*nmultf3"
3333   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3334         (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3335                          (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
3336   "INTEL_EXTENDED_IEEE_FORMAT"
3337   "fnmpy %0 = %F1, %F2"
3338   [(set_attr "itanium_class" "fmac")])
3340 (define_insn "*nmultf3_truncsf"
3341   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3342         (float_truncate:SF
3343           (neg:TF (mult:TF
3344                     (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3345                     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
3346   "INTEL_EXTENDED_IEEE_FORMAT"
3347   "fnmpy.s %0 = %F1, %F2"
3348   [(set_attr "itanium_class" "fmac")])
3350 (define_insn "*nmultf3_truncdf"
3351   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3352         (float_truncate:DF
3353           (neg:TF (mult:TF
3354                     (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3355                     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
3356   "INTEL_EXTENDED_IEEE_FORMAT"
3357   "fnmpy.d %0 = %F1, %F2"
3358   [(set_attr "itanium_class" "fmac")])
3360 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3362 (define_insn "*nmaddtf4"
3363   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3364         (plus:TF (neg:TF (mult:TF
3365                           (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3366                           (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3367                  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
3368   "INTEL_EXTENDED_IEEE_FORMAT"
3369   "fnma %0 = %F1, %F2, %F3"
3370   [(set_attr "itanium_class" "fmac")])
3372 (define_insn "*nmaddtf4_truncsf"
3373   [(set (match_operand:SF 0 "fr_register_operand" "=f")
3374         (float_truncate:SF
3375           (plus:TF (neg:TF (mult:TF
3376                             (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3377                             (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3378                    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3379   "INTEL_EXTENDED_IEEE_FORMAT"
3380   "fnma.s %0 = %F1, %F2, %F3"
3381   [(set_attr "itanium_class" "fmac")])
3383 (define_insn "*nmaddtf4_truncdf"
3384   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3385         (float_truncate:DF
3386           (plus:TF (neg:TF (mult:TF
3387                             (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3388                             (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3389                    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
3390   "INTEL_EXTENDED_IEEE_FORMAT"
3391   "fnma.d %0 = %F1, %F2, %F3"
3392   [(set_attr "itanium_class" "fmac")])
3394 (define_insn "*nmaddtf4_alts"
3395   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3396         (plus:TF (neg:TF (mult:TF
3397                           (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3398                           (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3399                  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
3400    (use (match_operand:SI 4 "const_int_operand" ""))]
3401   "INTEL_EXTENDED_IEEE_FORMAT"
3402   "fnma.s%4 %0 = %F1, %F2, %F3"
3403   [(set_attr "itanium_class" "fmac")])
3405 (define_insn "*nmaddtf4_truncdf_alts"
3406   [(set (match_operand:DF 0 "fr_register_operand" "=f")
3407         (float_truncate:DF
3408           (plus:TF (neg:TF
3409                      (mult:TF
3410                        (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
3411                        (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
3412                  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
3413    (use (match_operand:SI 4 "const_int_operand" ""))]
3414   "INTEL_EXTENDED_IEEE_FORMAT"
3415   "fnma.d.s%4 %0 = %F1, %F2, %F3"
3416   [(set_attr "itanium_class" "fmac")])
3418 (define_expand "divtf3"
3419   [(set (match_operand:TF 0 "fr_register_operand" "")
3420         (div:TF (match_operand:TF 1 "fr_register_operand" "")
3421                 (match_operand:TF 2 "fr_register_operand" "")))]
3422   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
3424   rtx insn;
3425   if (TARGET_INLINE_FLOAT_DIV_LAT)
3426     insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]);
3427   else
3428     insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]);
3429   emit_insn (insn);
3430   DONE;
3433 (define_insn_and_split "divtf3_internal_lat"
3434   [(set (match_operand:TF 0 "fr_register_operand" "=&f")
3435         (div:TF (match_operand:TF 1 "fr_register_operand" "f")
3436                 (match_operand:TF 2 "fr_register_operand" "f")))
3437    (clobber (match_scratch:TF 3 "=&f"))
3438    (clobber (match_scratch:TF 4 "=&f"))
3439    (clobber (match_scratch:TF 5 "=&f"))
3440    (clobber (match_scratch:TF 6 "=&f"))
3441    (clobber (match_scratch:BI 7 "=c"))]
3442   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
3443   "#"
3444   "&& reload_completed"
3445   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
3446               (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
3447                                             UNSPEC_FR_RECIP_APPROX))
3448               (use (const_int 1))])
3449    (cond_exec (ne (match_dup 7) (const_int 0))
3450      (parallel [(set (match_dup 3)
3451                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3452                               (match_dup 8)))
3453                 (use (const_int 1))]))
3454    (cond_exec (ne (match_dup 7) (const_int 0))
3455      (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
3456                 (use (const_int 1))]))
3457    (cond_exec (ne (match_dup 7) (const_int 0))
3458      (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
3459                 (use (const_int 1))]))
3460    (cond_exec (ne (match_dup 7) (const_int 0))
3461      (parallel [(set (match_dup 6)
3462                      (plus:TF (mult:TF (match_dup 3) (match_dup 3))
3463                               (match_dup 3)))
3464                 (use (const_int 1))]))
3465    (cond_exec (ne (match_dup 7) (const_int 0))
3466      (parallel [(set (match_dup 3)
3467                      (plus:TF (mult:TF (match_dup 5) (match_dup 5))
3468                               (match_dup 3)))
3469                 (use (const_int 1))]))
3470    (cond_exec (ne (match_dup 7) (const_int 0))
3471      (parallel [(set (match_dup 5)
3472                      (plus:TF (mult:TF (match_dup 6) (match_dup 0))
3473                               (match_dup 0)))
3474                 (use (const_int 1))]))
3475    (cond_exec (ne (match_dup 7) (const_int 0))
3476      (parallel [(set (match_dup 0)
3477                      (plus:TF (mult:TF (match_dup 5) (match_dup 3))
3478                               (match_dup 0)))
3479                 (use (const_int 1))]))
3480    (cond_exec (ne (match_dup 7) (const_int 0))
3481      (parallel [(set (match_dup 4)
3482                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
3483                               (match_dup 1)))
3484                 (use (const_int 1))]))
3485    (cond_exec (ne (match_dup 7) (const_int 0))
3486      (parallel [(set (match_dup 3)
3487                      (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3488                               (match_dup 4)))
3489                 (use (const_int 1))]))
3490    (cond_exec (ne (match_dup 7) (const_int 0))
3491      (parallel [(set (match_dup 5)
3492                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3493                               (match_dup 8)))
3494                 (use (const_int 1))]))
3495    (cond_exec (ne (match_dup 7) (const_int 0))
3496      (parallel [(set (match_dup 0)
3497                      (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3498                               (match_dup 0)))
3499                 (use (const_int 1))]))
3500    (cond_exec (ne (match_dup 7) (const_int 0))
3501      (parallel [(set (match_dup 4)
3502                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3503                               (match_dup 1)))
3504                 (use (const_int 1))]))
3505    (cond_exec (ne (match_dup 7) (const_int 0))
3506      (set (match_dup 0)
3507           (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3508                    (match_dup 3))))
3509   ] 
3510   "operands[8] = CONST1_RTX (TFmode);"
3511   [(set_attr "predicable" "no")])
3513 (define_insn_and_split "divtf3_internal_thr"
3514   [(set (match_operand:TF 0 "fr_register_operand" "=&f")
3515         (div:TF (match_operand:TF 1 "fr_register_operand" "f")
3516                 (match_operand:TF 2 "fr_register_operand" "f")))
3517    (clobber (match_scratch:TF 3 "=&f"))
3518    (clobber (match_scratch:TF 4 "=&f"))
3519    (clobber (match_scratch:BI 5 "=c"))]
3520   "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
3521   "#"
3522   "&& reload_completed"
3523   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
3524               (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
3525                                             UNSPEC_FR_RECIP_APPROX))
3526               (use (const_int 1))])
3527    (cond_exec (ne (match_dup 5) (const_int 0))
3528      (parallel [(set (match_dup 3)
3529                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3530                               (match_dup 6)))
3531                 (use (const_int 1))]))
3532    (cond_exec (ne (match_dup 5) (const_int 0))
3533      (parallel [(set (match_dup 4)
3534                      (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3535                               (match_dup 0)))
3536                 (use (const_int 1))]))
3537    (cond_exec (ne (match_dup 5) (const_int 0))
3538      (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
3539                 (use (const_int 1))]))
3540    (cond_exec (ne (match_dup 5) (const_int 0))
3541      (parallel [(set (match_dup 3)
3542                      (plus:TF (mult:TF (match_dup 3) (match_dup 4))
3543                               (match_dup 4)))
3544                 (use (const_int 1))]))
3545    (cond_exec (ne (match_dup 5) (const_int 0))
3546      (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
3547                 (use (const_int 1))]))
3548    (cond_exec (ne (match_dup 5) (const_int 0))
3549      (parallel [(set (match_dup 0)
3550                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3551                               (match_dup 6)))
3552                 (use (const_int 1))]))
3553    (cond_exec (ne (match_dup 5) (const_int 0))
3554      (parallel [(set (match_dup 0)
3555                      (plus:TF (mult:TF (match_dup 0) (match_dup 3))
3556                               (match_dup 3)))
3557                 (use (const_int 1))]))
3558    (cond_exec (ne (match_dup 5) (const_int 0))
3559      (parallel [(set (match_dup 3)
3560                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
3561                               (match_dup 1)))
3562                 (use (const_int 1))]))
3563    (cond_exec (ne (match_dup 5) (const_int 0))
3564      (parallel [(set (match_dup 3)
3565                      (plus:TF (mult:TF (match_dup 3) (match_dup 0))
3566                               (match_dup 4)))
3567                 (use (const_int 1))]))
3568    (cond_exec (ne (match_dup 5) (const_int 0))
3569      (parallel [(set (match_dup 4)
3570                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
3571                               (match_dup 6)))
3572                 (use (const_int 1))]))
3573    (cond_exec (ne (match_dup 5) (const_int 0))
3574      (parallel [(set (match_dup 0)
3575                      (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3576                               (match_dup 0)))
3577                 (use (const_int 1))]))
3578    (cond_exec (ne (match_dup 5) (const_int 0))
3579      (parallel [(set (match_dup 4)
3580                      (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
3581                               (match_dup 1)))
3582                 (use (const_int 1))]))
3583    (cond_exec (ne (match_dup 5) (const_int 0))
3584      (set (match_dup 0)
3585           (plus:TF (mult:TF (match_dup 4) (match_dup 0))
3586                    (match_dup 3))))
3587   ] 
3588   "operands[6] = CONST1_RTX (TFmode);"
3589   [(set_attr "predicable" "no")])
3591 ;; ??? frcpa works like cmp.foo.unc.
3593 (define_insn "*recip_approx"
3594   [(set (match_operand:TF 0 "fr_register_operand" "=f")
3595         (div:TF (const_int 1)
3596                 (match_operand:TF 3 "fr_register_operand" "f")))
3597    (set (match_operand:BI 1 "register_operand" "=c")
3598         (unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
3599                     (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
3600    (use (match_operand:SI 4 "const_int_operand" ""))]
3601   "INTEL_EXTENDED_IEEE_FORMAT"
3602   "frcpa.s%4 %0, %1 = %2, %3"
3603   [(set_attr "itanium_class" "fmisc")
3604    (set_attr "predicable" "no")])
3606 ;; ::::::::::::::::::::
3607 ;; ::
3608 ;; :: 32 bit Integer Shifts and Rotates
3609 ;; ::
3610 ;; ::::::::::::::::::::
3612 (define_expand "ashlsi3"
3613   [(set (match_operand:SI 0 "gr_register_operand" "")
3614         (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
3615                    (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3616   ""
3618   if (GET_CODE (operands[2]) != CONST_INT)
3619     {
3620       /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
3621          we've got to get rid of stray bits outside the SImode register.  */
3622       rtx subshift = gen_reg_rtx (DImode);
3623       emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3624       operands[2] = subshift;
3625     }
3628 (define_insn "*ashlsi3_internal"
3629   [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
3630         (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
3631                    (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
3632   ""
3633   "@
3634    shladd %0 = %1, %2, r0
3635    dep.z %0 = %1, %2, %E2
3636    shl %0 = %1, %2"
3637   [(set_attr "itanium_class" "ialu,ishf,mmshf")])
3639 (define_expand "ashrsi3"
3640   [(set (match_operand:SI 0 "gr_register_operand" "")
3641         (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3642                      (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3643   ""
3645   rtx subtarget = gen_reg_rtx (DImode);
3646   if (GET_CODE (operands[2]) == CONST_INT)
3647     emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
3648                          GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3649   else
3650     {
3651       rtx subshift = gen_reg_rtx (DImode);
3652       emit_insn (gen_extendsidi2 (subtarget, operands[1]));
3653       emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3654       emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
3655     }
3656   emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3657   DONE;
3660 (define_expand "lshrsi3"
3661   [(set (match_operand:SI 0 "gr_register_operand" "")
3662         (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
3663                      (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3664   ""
3666   rtx subtarget = gen_reg_rtx (DImode);
3667   if (GET_CODE (operands[2]) == CONST_INT)
3668     emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
3669                           GEN_INT (32 - INTVAL (operands[2])), operands[2]));
3670   else
3671     {
3672       rtx subshift = gen_reg_rtx (DImode);
3673       emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
3674       emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
3675       emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
3676     }
3677   emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
3678   DONE;
3681 ;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
3682 ;; here, instead of 64 like the patterns above.  Keep the pattern together
3683 ;; until after combine; otherwise it won't get matched often.
3685 (define_expand "rotrsi3"
3686   [(set (match_operand:SI 0 "gr_register_operand" "")
3687         (rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
3688                      (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3689   ""
3691   if (GET_MODE (operands[2]) != VOIDmode)
3692     {
3693       rtx tmp = gen_reg_rtx (DImode);
3694       emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
3695       operands[2] = tmp;
3696     }
3699 (define_insn_and_split "*rotrsi3_internal"
3700   [(set (match_operand:SI 0 "gr_register_operand" "=&r")
3701         (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
3702                      (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
3703   ""
3704   "#"
3705   "reload_completed"
3706   [(set (match_dup 3)
3707         (ior:DI (zero_extend:DI (match_dup 1))
3708                 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
3709    (set (match_dup 3)
3710         (lshiftrt:DI (match_dup 3) (match_dup 2)))]
3711   "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
3713 (define_expand "rotlsi3"
3714   [(set (match_operand:SI 0 "gr_register_operand" "")
3715         (rotate:SI (match_operand:SI 1 "gr_register_operand" "")
3716                    (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
3717   ""
3719   if (! shift_32bit_count_operand (operands[2], SImode))
3720     {
3721       rtx tmp = gen_reg_rtx (SImode);
3722       emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
3723       emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
3724       DONE;
3725     }
3728 (define_insn_and_split "*rotlsi3_internal"
3729   [(set (match_operand:SI 0 "gr_register_operand" "=r")
3730         (rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
3731                    (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
3732   ""
3733   "#"
3734   "reload_completed"
3735   [(set (match_dup 3)
3736         (ior:DI (zero_extend:DI (match_dup 1))
3737                 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
3738    (set (match_dup 3)
3739         (lshiftrt:DI (match_dup 3) (match_dup 2)))]
3741   operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
3742   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
3745 ;; ::::::::::::::::::::
3746 ;; ::
3747 ;; :: 64 bit Integer Shifts and Rotates
3748 ;; ::
3749 ;; ::::::::::::::::::::
3751 (define_insn "ashldi3"
3752   [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
3753         (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
3754                    (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
3755   ""
3756   "@
3757    shladd %0 = %1, %2, r0
3758    shl %0 = %1, %2
3759    shl %0 = %1, %2"
3760   [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
3762 ;; ??? Maybe combine this with the multiply and add instruction?
3764 (define_insn "*shladd"
3765   [(set (match_operand:DI 0 "gr_register_operand" "=r")
3766         (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
3767                           (match_operand:DI 2 "shladd_operand" "n"))
3768                  (match_operand:DI 3 "gr_register_operand" "r")))]
3769   ""
3770   "shladd %0 = %1, %S2, %3"
3771   [(set_attr "itanium_class" "ialu")])
3773 ;; This can be created by register elimination if operand3 of shladd is an
3774 ;; eliminable register or has reg_equiv_constant set.
3776 ;; We have to use nonmemory_operand for operand 4, to ensure that the
3777 ;; validate_changes call inside eliminate_regs will always succeed.  If it
3778 ;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
3779 ;; incorrectly.
3781 (define_insn_and_split "*shladd_elim"
3782   [(set (match_operand:DI 0 "gr_register_operand" "=&r")
3783         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
3784                                    (match_operand:DI 2 "shladd_operand" "n"))
3785                           (match_operand:DI 3 "nonmemory_operand" "r"))
3786                  (match_operand:DI 4 "nonmemory_operand" "rI")))]
3787   "reload_in_progress"
3788   "* abort ();"
3789   "reload_completed"
3790   [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
3791                                (match_dup 3)))
3792    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
3793   ""
3794   [(set_attr "itanium_class" "unknown")])
3796 (define_insn "ashrdi3"
3797   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3798         (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
3799                      (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
3800   ""
3801   "@
3802    shr %0 = %1, %2
3803    shr %0 = %1, %2"
3804   [(set_attr "itanium_class" "mmshf,mmshfi")])
3806 (define_insn "lshrdi3"
3807   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
3808         (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
3809                      (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
3810   ""
3811   "@
3812    shr.u %0 = %1, %2
3813    shr.u %0 = %1, %2"
3814   [(set_attr "itanium_class" "mmshf,mmshfi")])
3816 ;; Using a predicate that accepts only constants doesn't work, because optabs
3817 ;; will load the operand into a register and call the pattern if the predicate
3818 ;; did not accept it on the first try.  So we use nonmemory_operand and then
3819 ;; verify that we have an appropriate constant in the expander.
3821 (define_expand "rotrdi3"
3822   [(set (match_operand:DI 0 "gr_register_operand" "")
3823         (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
3824                      (match_operand:DI 2 "nonmemory_operand" "")))]
3825   ""
3827   if (! shift_count_operand (operands[2], DImode))
3828     FAIL;
3831 (define_insn "*rotrdi3_internal"
3832   [(set (match_operand:DI 0 "gr_register_operand" "=r")
3833         (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
3834                      (match_operand:DI 2 "shift_count_operand" "M")))]
3835   ""
3836   "shrp %0 = %1, %1, %2"
3837   [(set_attr "itanium_class" "ishf")])
3839 (define_expand "rotldi3"
3840   [(set (match_operand:DI 0 "gr_register_operand" "")
3841         (rotate:DI (match_operand:DI 1 "gr_register_operand" "")
3842                    (match_operand:DI 2 "nonmemory_operand" "")))]
3843   ""
3845   if (! shift_count_operand (operands[2], DImode))
3846     FAIL;
3849 (define_insn "*rotldi3_internal"
3850   [(set (match_operand:DI 0 "gr_register_operand" "=r")
3851         (rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
3852                    (match_operand:DI 2 "shift_count_operand" "M")))]
3853   ""
3854   "shrp %0 = %1, %1, %e2"
3855   [(set_attr "itanium_class" "ishf")])
3857 ;; ::::::::::::::::::::
3858 ;; ::
3859 ;; :: 32 bit Integer Logical operations
3860 ;; ::
3861 ;; ::::::::::::::::::::
3863 ;; We don't seem to need any other 32-bit logical operations, because gcc
3864 ;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
3865 ;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
3866 ;; This doesn't work for unary logical operations, because we don't call
3867 ;; apply_distributive_law for them.
3869 ;; ??? Likewise, this doesn't work for andnot, which isn't handled by
3870 ;; apply_distributive_law.  We get inefficient code for
3871 ;; int sub4 (int i, int j) { return i & ~j; }
3872 ;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
3873 ;; (zero_extend (and (not A) B)) in combine.
3874 ;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
3875 ;; one_cmplsi2 pattern.
3877 (define_insn "one_cmplsi2"
3878   [(set (match_operand:SI 0 "gr_register_operand" "=r")
3879         (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
3880   ""
3881   "andcm %0 = -1, %1"
3882   [(set_attr "itanium_class" "ilog")])
3884 ;; ::::::::::::::::::::
3885 ;; ::
3886 ;; :: 64 bit Integer Logical operations
3887 ;; ::
3888 ;; ::::::::::::::::::::
3890 (define_insn "anddi3"
3891   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3892         (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3893                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3894   ""
3895   "@
3896    and %0 = %2, %1
3897    fand %0 = %2, %1"
3898   [(set_attr "itanium_class" "ilog,fmisc")])
3900 (define_insn "*andnot"
3901   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3902         (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
3903                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3904   ""
3905   "@
3906    andcm %0 = %2, %1
3907    fandcm %0 = %2, %1"
3908   [(set_attr "itanium_class" "ilog,fmisc")])
3910 (define_insn "iordi3"
3911   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3912         (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3913                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3914   ""
3915   "@
3916    or %0 = %2, %1
3917    for %0 = %2, %1"
3918   [(set_attr "itanium_class" "ilog,fmisc")])
3920 (define_insn "xordi3"
3921   [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
3922         (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
3923                 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
3924   ""
3925   "@
3926    xor %0 = %2, %1
3927    fxor %0 = %2, %1"
3928   [(set_attr "itanium_class" "ilog,fmisc")])
3930 (define_insn "one_cmpldi2"
3931   [(set (match_operand:DI 0 "gr_register_operand" "=r")
3932         (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
3933   ""
3934   "andcm %0 = -1, %1"
3935   [(set_attr "itanium_class" "ilog")])
3937 ;; ::::::::::::::::::::
3938 ;; ::
3939 ;; :: Comparisons
3940 ;; ::
3941 ;; ::::::::::::::::::::
3943 (define_expand "cmpbi"
3944   [(set (cc0)
3945         (compare (match_operand:BI 0 "register_operand" "")
3946                  (match_operand:BI 1 "const_int_operand" "")))]
3947   ""
3949   ia64_compare_op0 = operands[0];
3950   ia64_compare_op1 = operands[1];
3951   DONE;
3954 (define_expand "cmpsi"
3955   [(set (cc0)
3956         (compare (match_operand:SI 0 "gr_register_operand" "")
3957                  (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
3958   ""
3960   ia64_compare_op0 = operands[0];
3961   ia64_compare_op1 = operands[1];
3962   DONE;
3965 (define_expand "cmpdi"
3966   [(set (cc0)
3967         (compare (match_operand:DI 0 "gr_register_operand" "")
3968                  (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
3969   ""
3971   ia64_compare_op0 = operands[0];
3972   ia64_compare_op1 = operands[1];
3973   DONE;
3976 (define_expand "cmpsf"
3977   [(set (cc0)
3978         (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
3979                  (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
3980   ""
3982   ia64_compare_op0 = operands[0];
3983   ia64_compare_op1 = operands[1];
3984   DONE;
3987 (define_expand "cmpdf"
3988   [(set (cc0)
3989         (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
3990                  (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
3991   ""
3993   ia64_compare_op0 = operands[0];
3994   ia64_compare_op1 = operands[1];
3995   DONE;
3998 (define_expand "cmptf"
3999   [(set (cc0)
4000         (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
4001                  (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
4002   "INTEL_EXTENDED_IEEE_FORMAT"
4004   ia64_compare_op0 = operands[0];
4005   ia64_compare_op1 = operands[1];
4006   DONE;
4009 (define_insn "*cmpsi_normal"
4010   [(set (match_operand:BI 0 "register_operand" "=c")
4011         (match_operator:BI 1 "normal_comparison_operator"
4012            [(match_operand:SI 2 "gr_register_operand" "r")
4013             (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
4014   ""
4015   "cmp4.%C1 %0, %I0 = %3, %2"
4016   [(set_attr "itanium_class" "icmp")])
4018 ;; We use %r3 because it is possible for us to match a 0, and two of the
4019 ;; unsigned comparisons don't accept immediate operands of zero.
4021 (define_insn "*cmpsi_adjusted"
4022   [(set (match_operand:BI 0 "register_operand" "=c")
4023         (match_operator:BI 1 "adjusted_comparison_operator"
4024            [(match_operand:SI 2 "gr_register_operand" "r")
4025             (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4026   ""
4027   "cmp4.%C1 %0, %I0 = %r3, %2"
4028   [(set_attr "itanium_class" "icmp")])
4030 (define_insn "*cmpdi_normal"
4031   [(set (match_operand:BI 0 "register_operand" "=c")
4032         (match_operator:BI 1 "normal_comparison_operator"
4033            [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
4034             (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
4035   ""
4036   "cmp.%C1 %0, %I0 = %3, %r2"
4037   [(set_attr "itanium_class" "icmp")])
4039 ;; We use %r3 because it is possible for us to match a 0, and two of the
4040 ;; unsigned comparisons don't accept immediate operands of zero.
4042 (define_insn "*cmpdi_adjusted"
4043   [(set (match_operand:BI 0 "register_operand" "=c")
4044         (match_operator:BI 1 "adjusted_comparison_operator"
4045            [(match_operand:DI 2 "gr_register_operand" "r")
4046             (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4047   ""
4048   "cmp.%C1 %0, %I0 = %r3, %2"
4049   [(set_attr "itanium_class" "icmp")])
4051 (define_insn "*cmpsf_internal"
4052   [(set (match_operand:BI 0 "register_operand" "=c")
4053         (match_operator:BI 1 "comparison_operator"
4054            [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
4055             (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
4056   ""
4057   "fcmp.%D1 %0, %I0 = %F2, %F3"
4058   [(set_attr "itanium_class" "fcmp")])
4060 (define_insn "*cmpdf_internal"
4061   [(set (match_operand:BI 0 "register_operand" "=c")
4062         (match_operator:BI 1 "comparison_operator"
4063            [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
4064             (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
4065   ""
4066   "fcmp.%D1 %0, %I0 = %F2, %F3"
4067   [(set_attr "itanium_class" "fcmp")])
4069 (define_insn "*cmptf_internal"
4070   [(set (match_operand:BI 0 "register_operand" "=c")
4071         (match_operator:BI 1 "comparison_operator"
4072                    [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
4073                     (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
4074   "INTEL_EXTENDED_IEEE_FORMAT"
4075   "fcmp.%D1 %0, %I0 = %F2, %F3"
4076   [(set_attr "itanium_class" "fcmp")])
4078 ;; ??? Can this pattern be generated?
4080 (define_insn "*bit_zero"
4081   [(set (match_operand:BI 0 "register_operand" "=c")
4082         (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4083                                 (const_int 1)
4084                                 (match_operand:DI 2 "immediate_operand" "n"))
4085                (const_int 0)))]
4086   ""
4087   "tbit.z %0, %I0 = %1, %2"
4088   [(set_attr "itanium_class" "tbit")])
4090 (define_insn "*bit_one"
4091   [(set (match_operand:BI 0 "register_operand" "=c")
4092         (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4093                                 (const_int 1)
4094                                 (match_operand:DI 2 "immediate_operand" "n"))
4095                (const_int 0)))]
4096   ""
4097   "tbit.nz %0, %I0 = %1, %2"
4098   [(set_attr "itanium_class" "tbit")])
4100 ;; ::::::::::::::::::::
4101 ;; ::
4102 ;; :: Branches
4103 ;; ::
4104 ;; ::::::::::::::::::::
4106 (define_expand "beq"
4107   [(set (pc)
4108         (if_then_else (match_dup 1)
4109                       (label_ref (match_operand 0 "" ""))
4110                       (pc)))]
4111   ""
4112   "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
4114 (define_expand "bne"
4115   [(set (pc)
4116         (if_then_else (match_dup 1)
4117                       (label_ref (match_operand 0 "" ""))
4118                       (pc)))]
4119   ""
4120   "operands[1] = ia64_expand_compare (NE, VOIDmode);")
4122 (define_expand "blt"
4123   [(set (pc)
4124         (if_then_else (match_dup 1)
4125                       (label_ref (match_operand 0 "" ""))
4126                       (pc)))]
4127   ""
4128   "operands[1] = ia64_expand_compare (LT, VOIDmode);")
4130 (define_expand "ble"
4131   [(set (pc)
4132         (if_then_else (match_dup 1)
4133                       (label_ref (match_operand 0 "" ""))
4134                       (pc)))]
4135   ""
4136   "operands[1] = ia64_expand_compare (LE, VOIDmode);")
4138 (define_expand "bgt"
4139   [(set (pc)
4140         (if_then_else (match_dup 1)
4141                       (label_ref (match_operand 0 "" ""))
4142                       (pc)))]
4143   ""
4144   "operands[1] = ia64_expand_compare (GT, VOIDmode);")
4146 (define_expand "bge"
4147   [(set (pc)
4148         (if_then_else (match_dup 1)
4149                       (label_ref (match_operand 0 "" ""))
4150                       (pc)))]
4151   ""
4152   "operands[1] = ia64_expand_compare (GE, VOIDmode);")
4154 (define_expand "bltu"
4155   [(set (pc)
4156         (if_then_else (match_dup 1)
4157                       (label_ref (match_operand 0 "" ""))
4158                       (pc)))]
4159   ""
4160   "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
4162 (define_expand "bleu"
4163   [(set (pc)
4164         (if_then_else (match_dup 1)
4165                       (label_ref (match_operand 0 "" ""))
4166                       (pc)))]
4167   ""
4168   "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
4170 (define_expand "bgtu"
4171   [(set (pc)
4172         (if_then_else (match_dup 1)
4173                       (label_ref (match_operand 0 "" ""))
4174                       (pc)))]
4175   ""
4176   "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
4178 (define_expand "bgeu"
4179   [(set (pc)
4180         (if_then_else (match_dup 1)
4181                       (label_ref (match_operand 0 "" ""))
4182                       (pc)))]
4183   ""
4184   "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
4186 (define_expand "bunordered"
4187   [(set (pc)
4188         (if_then_else (match_dup 1)
4189                       (label_ref (match_operand 0 "" ""))
4190                       (pc)))]
4191   ""
4192   "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
4194 (define_expand "bordered"
4195   [(set (pc)
4196         (if_then_else (match_dup 1)
4197                       (label_ref (match_operand 0 "" ""))
4198                       (pc)))]
4199   ""
4200   "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
4202 (define_insn "*br_true"
4203   [(set (pc)
4204         (if_then_else (match_operator 0 "predicate_operator"
4205                         [(match_operand:BI 1 "register_operand" "c")
4206                          (const_int 0)])
4207                       (label_ref (match_operand 2 "" ""))
4208                       (pc)))]
4209   ""
4210   "(%J0) br.cond%+ %l2"
4211   [(set_attr "itanium_class" "br")
4212    (set_attr "predicable" "no")])
4214 (define_insn "*br_false"
4215   [(set (pc)
4216         (if_then_else (match_operator 0 "predicate_operator"
4217                         [(match_operand:BI 1 "register_operand" "c")
4218                          (const_int 0)])
4219                       (pc)
4220                       (label_ref (match_operand 2 "" ""))))]
4221   ""
4222   "(%j0) br.cond%+ %l2"
4223   [(set_attr "itanium_class" "br")
4224    (set_attr "predicable" "no")])
4226 ;; ::::::::::::::::::::
4227 ;; ::
4228 ;; :: Counted loop operations
4229 ;; ::
4230 ;; ::::::::::::::::::::
4232 (define_expand "doloop_end"
4233   [(use (match_operand 0 "" ""))        ; loop pseudo
4234    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
4235    (use (match_operand 2 "" ""))        ; max iterations
4236    (use (match_operand 3 "" ""))        ; loop level
4237    (use (match_operand 4 "" ""))]       ; label
4238   ""
4240   /* Only use cloop on innermost loops.  */
4241   if (INTVAL (operands[3]) > 1)
4242     FAIL;
4243   emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
4244                                            operands[4]));
4245   DONE;
4248 (define_insn "doloop_end_internal"
4249   [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
4250                                (const_int 0))
4251                 (label_ref (match_operand 1 "" ""))
4252                 (pc)))
4253    (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
4254                          (plus:DI (match_dup 0) (const_int -1))
4255                          (match_dup 0)))]
4256   ""
4257   "br.cloop.sptk.few %l1"
4258   [(set_attr "itanium_class" "br")
4259    (set_attr "predicable" "no")])
4261 ;; ::::::::::::::::::::
4262 ;; ::
4263 ;; :: Set flag operations
4264 ;; ::
4265 ;; ::::::::::::::::::::
4267 (define_expand "seq"
4268   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4269   ""
4270   "operands[1] = ia64_expand_compare (EQ, DImode);")
4272 (define_expand "sne"
4273   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4274   ""
4275   "operands[1] = ia64_expand_compare (NE, DImode);")
4277 (define_expand "slt"
4278   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4279   ""
4280   "operands[1] = ia64_expand_compare (LT, DImode);")
4282 (define_expand "sle"
4283   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4284   ""
4285   "operands[1] = ia64_expand_compare (LE, DImode);")
4287 (define_expand "sgt"
4288   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4289   ""
4290   "operands[1] = ia64_expand_compare (GT, DImode);")
4292 (define_expand "sge"
4293   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4294   ""
4295   "operands[1] = ia64_expand_compare (GE, DImode);")
4297 (define_expand "sltu"
4298   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4299   ""
4300   "operands[1] = ia64_expand_compare (LTU, DImode);")
4302 (define_expand "sleu"
4303   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4304   ""
4305   "operands[1] = ia64_expand_compare (LEU, DImode);")
4307 (define_expand "sgtu"
4308   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4309   ""
4310   "operands[1] = ia64_expand_compare (GTU, DImode);")
4312 (define_expand "sgeu"
4313   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4314   ""
4315   "operands[1] = ia64_expand_compare (GEU, DImode);")
4317 (define_expand "sunordered"
4318   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4319   ""
4320   "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
4322 (define_expand "sordered"
4323   [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4324   ""
4325   "operands[1] = ia64_expand_compare (ORDERED, DImode);")
4327 ;; Don't allow memory as destination here, because cmov/cmov/st is more
4328 ;; efficient than mov/mov/cst/cst.
4330 (define_insn_and_split "*sne_internal"
4331   [(set (match_operand:DI 0 "gr_register_operand" "=r")
4332         (ne:DI (match_operand:BI 1 "register_operand" "c")
4333                (const_int 0)))]
4334   ""
4335   "#"
4336   "reload_completed"
4337   [(cond_exec (ne (match_dup 1) (const_int 0))
4338      (set (match_dup 0) (const_int 1)))
4339    (cond_exec (eq (match_dup 1) (const_int 0))
4340      (set (match_dup 0) (const_int 0)))]
4341   ""
4342   [(set_attr "itanium_class" "unknown")])
4344 (define_insn_and_split "*seq_internal"
4345   [(set (match_operand:DI 0 "gr_register_operand" "=r")
4346         (eq:DI (match_operand:BI 1 "register_operand" "c")
4347                (const_int 0)))]
4348   ""
4349   "#"
4350   "reload_completed"
4351   [(cond_exec (ne (match_dup 1) (const_int 0))
4352      (set (match_dup 0) (const_int 0)))
4353    (cond_exec (eq (match_dup 1) (const_int 0))
4354      (set (match_dup 0) (const_int 1)))]
4355   ""
4356   [(set_attr "itanium_class" "unknown")])
4358 ;; ::::::::::::::::::::
4359 ;; ::
4360 ;; :: Conditional move instructions.
4361 ;; ::
4362 ;; ::::::::::::::::::::
4364 ;; ??? Add movXXcc patterns?
4367 ;; DImode if_then_else patterns.
4370 (define_insn "*cmovdi_internal"
4371   [(set (match_operand:DI 0 "destination_operand"
4372            "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
4373         (if_then_else:DI
4374           (match_operator 4 "predicate_operator"
4375             [(match_operand:BI 1 "register_operand"
4376                 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
4377              (const_int 0)])
4378           (match_operand:DI 2 "move_operand"
4379            "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
4380           (match_operand:DI 3 "move_operand"
4381            "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
4382   "ia64_move_ok (operands[0], operands[2])
4383    && ia64_move_ok (operands[0], operands[3])"
4384   { abort (); }
4385   [(set_attr "predicable" "no")])
4387 (define_split
4388   [(set (match_operand 0 "destination_operand" "")
4389         (if_then_else
4390           (match_operator 4 "predicate_operator"
4391             [(match_operand:BI 1 "register_operand" "")
4392              (const_int 0)])
4393           (match_operand 2 "move_operand" "")
4394           (match_operand 3 "move_operand" "")))]
4395   "reload_completed"
4396   [(const_int 0)]
4398   bool emitted_something = false;
4399   rtx dest = operands[0];
4400   rtx srct = operands[2];
4401   rtx srcf = operands[3];
4402   rtx cond = operands[4];
4404   if (! rtx_equal_p (dest, srct))
4405     {
4406       ia64_emit_cond_move (dest, srct, cond);
4407       emitted_something = true;
4408     }
4409   if (! rtx_equal_p (dest, srcf))
4410     {
4411       cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
4412                              VOIDmode, operands[1], const0_rtx);
4413       ia64_emit_cond_move (dest, srcf, cond);
4414       emitted_something = true;
4415     }
4416   if (! emitted_something)
4417     emit_note (NULL, NOTE_INSN_DELETED);
4418   DONE;
4421 ;; Absolute value pattern.
4423 (define_insn "*absdi2_internal"
4424   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4425         (if_then_else:DI
4426           (match_operator 4 "predicate_operator"
4427             [(match_operand:BI 1 "register_operand" "c,c")
4428              (const_int 0)])
4429           (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
4430           (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
4431   ""
4432   "#"
4433   [(set_attr "itanium_class" "ialu,unknown")
4434    (set_attr "predicable" "no")])
4436 (define_split
4437   [(set (match_operand:DI 0 "register_operand" "")
4438         (if_then_else:DI
4439           (match_operator 4 "predicate_operator"
4440             [(match_operand:BI 1 "register_operand" "c,c")
4441              (const_int 0)])
4442           (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4443           (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4444   "reload_completed && rtx_equal_p (operands[0], operands[3])"
4445   [(cond_exec
4446      (match_dup 4)
4447      (set (match_dup 0)
4448           (neg:DI (match_dup 2))))]
4449   "")
4451 (define_split
4452   [(set (match_operand:DI 0 "register_operand" "")
4453         (if_then_else:DI
4454           (match_operator 4 "predicate_operator"
4455             [(match_operand:BI 1 "register_operand" "c,c")
4456              (const_int 0)])
4457           (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4458           (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4459   "reload_completed"
4460   [(cond_exec
4461      (match_dup 4)
4462      (set (match_dup 0) (neg:DI (match_dup 2))))
4463    (cond_exec
4464      (match_dup 5)
4465      (set (match_dup 0) (match_dup 3)))]
4467   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4468                                 VOIDmode, operands[1], const0_rtx);
4472 ;; SImode if_then_else patterns.
4475 (define_insn "*cmovsi_internal"
4476   [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
4477         (if_then_else:SI
4478           (match_operator 4 "predicate_operator"
4479             [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
4480              (const_int 0)])
4481           (match_operand:SI 2 "move_operand"
4482                     "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
4483           (match_operand:SI 3 "move_operand"
4484                     "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
4485   "ia64_move_ok (operands[0], operands[2])
4486    && ia64_move_ok (operands[0], operands[3])"
4487   { abort (); }
4488   [(set_attr "predicable" "no")])
4490 (define_insn "*abssi2_internal"
4491   [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
4492         (if_then_else:SI
4493           (match_operator 4 "predicate_operator"
4494             [(match_operand:BI 1 "register_operand" "c,c")
4495              (const_int 0)])
4496           (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
4497           (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
4498   ""
4499   "#"
4500   [(set_attr "itanium_class" "ialu,unknown")
4501    (set_attr "predicable" "no")])
4503 (define_split
4504   [(set (match_operand:SI 0 "register_operand" "")
4505         (if_then_else:SI
4506           (match_operator 4 "predicate_operator"
4507             [(match_operand:BI 1 "register_operand" "c,c")
4508              (const_int 0)])
4509           (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4510           (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4511   "reload_completed && rtx_equal_p (operands[0], operands[3])"
4512   [(cond_exec
4513      (match_dup 4)
4514      (set (match_dup 0)
4515           (neg:SI (match_dup 2))))]
4516   "")
4518 (define_split
4519   [(set (match_operand:SI 0 "register_operand" "")
4520         (if_then_else:SI
4521           (match_operator 4 "predicate_operator"
4522             [(match_operand:BI 1 "register_operand" "c,c")
4523              (const_int 0)])
4524           (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4525           (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4526   "reload_completed"
4527   [(cond_exec
4528      (match_dup 4)
4529      (set (match_dup 0) (neg:SI (match_dup 2))))
4530    (cond_exec
4531      (match_dup 5)
4532      (set (match_dup 0) (match_dup 3)))]
4534   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4535                                 VOIDmode, operands[1], const0_rtx);
4538 (define_insn_and_split "*cond_opsi2_internal"
4539   [(set (match_operand:SI 0 "gr_register_operand" "=r")
4540         (match_operator:SI 5 "condop_operator"
4541           [(if_then_else:SI
4542              (match_operator 6 "predicate_operator"
4543                [(match_operand:BI 1 "register_operand" "c")
4544                 (const_int 0)])
4545              (match_operand:SI 2 "gr_register_operand" "r")
4546              (match_operand:SI 3 "gr_register_operand" "r"))
4547            (match_operand:SI 4 "gr_register_operand" "r")]))]
4548   ""
4549   "#"
4550   "reload_completed"
4551   [(cond_exec
4552      (match_dup 6)
4553      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
4554    (cond_exec
4555      (match_dup 7)
4556      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
4558   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
4559                                 VOIDmode, operands[1], const0_rtx);
4561   [(set_attr "itanium_class" "ialu")
4562    (set_attr "predicable" "no")])
4565 (define_insn_and_split "*cond_opsi2_internal_b"
4566   [(set (match_operand:SI 0 "gr_register_operand" "=r")
4567         (match_operator:SI 5 "condop_operator"
4568           [(match_operand:SI 4 "gr_register_operand" "r")
4569            (if_then_else:SI
4570              (match_operator 6 "predicate_operator"
4571                [(match_operand:BI 1 "register_operand" "c")
4572                 (const_int 0)])
4573              (match_operand:SI 2 "gr_register_operand" "r")
4574              (match_operand:SI 3 "gr_register_operand" "r"))]))]
4575   ""
4576   "#"
4577   "reload_completed"
4578   [(cond_exec
4579      (match_dup 6)
4580      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
4581    (cond_exec
4582      (match_dup 7)
4583      (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
4585   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
4586                                 VOIDmode, operands[1], const0_rtx);
4588   [(set_attr "itanium_class" "ialu")
4589    (set_attr "predicable" "no")])
4592 ;; ::::::::::::::::::::
4593 ;; ::
4594 ;; :: Call and branch instructions
4595 ;; ::
4596 ;; ::::::::::::::::::::
4598 ;; Subroutine call instruction returning no value.  Operand 0 is the function
4599 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
4600 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
4601 ;; registers used as operands.
4603 ;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
4604 ;; is supplied for the sake of some RISC machines which need to put this
4605 ;; information into the assembler code; they can put it in the RTL instead of
4606 ;; operand 1.
4608 (define_expand "call"
4609   [(use (match_operand:DI 0 "" ""))
4610    (use (match_operand 1 "" ""))
4611    (use (match_operand 2 "" ""))
4612    (use (match_operand 3 "" ""))]
4613   ""
4615   ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
4616   DONE;
4619 (define_expand "sibcall"
4620   [(use (match_operand:DI 0 "" ""))
4621    (use (match_operand 1 "" ""))
4622    (use (match_operand 2 "" ""))
4623    (use (match_operand 3 "" ""))]
4624   ""
4626   ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
4627   DONE;
4630 ;; Subroutine call instruction returning a value.  Operand 0 is the hard
4631 ;; register in which the value is returned.  There are three more operands,
4632 ;; the same as the three operands of the `call' instruction (but with numbers
4633 ;; increased by one).
4635 ;; Subroutines that return `BLKmode' objects use the `call' insn.
4637 (define_expand "call_value"
4638   [(use (match_operand 0 "" ""))
4639    (use (match_operand:DI 1 "" ""))
4640    (use (match_operand 2 "" ""))
4641    (use (match_operand 3 "" ""))
4642    (use (match_operand 4 "" ""))]
4643   ""
4645   ia64_expand_call (operands[0], operands[1], operands[3], false);
4646   DONE;
4649 (define_expand "sibcall_value"
4650   [(use (match_operand 0 "" ""))
4651    (use (match_operand:DI 1 "" ""))
4652    (use (match_operand 2 "" ""))
4653    (use (match_operand 3 "" ""))
4654    (use (match_operand 4 "" ""))]
4655   ""
4657   ia64_expand_call (operands[0], operands[1], operands[3], true);
4658   DONE;
4661 ;; Call subroutine returning any type.
4663 (define_expand "untyped_call"
4664   [(parallel [(call (match_operand 0 "" "")
4665                     (const_int 0))
4666               (match_operand 1 "" "")
4667               (match_operand 2 "" "")])]
4668   ""
4670   int i;
4672   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
4674   for (i = 0; i < XVECLEN (operands[2], 0); i++)
4675     {
4676       rtx set = XVECEXP (operands[2], 0, i);
4677       emit_move_insn (SET_DEST (set), SET_SRC (set));
4678     }
4680   /* The optimizer does not know that the call sets the function value
4681      registers we stored in the result block.  We avoid problems by
4682      claiming that all hard registers are used and clobbered at this
4683      point.  */
4684   emit_insn (gen_blockage ());
4686   DONE;
4689 (define_insn "call_nogp"
4690   [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
4691          (const_int 0))
4692    (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
4693   ""
4694   "br.call%+.many %1 = %0"
4695   [(set_attr "itanium_class" "br,scall")])
4697 (define_insn "call_value_nogp"
4698   [(set (match_operand 0 "" "")
4699         (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
4700               (const_int 0)))
4701    (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
4702   ""
4703   "br.call%+.many %2 = %1"
4704   [(set_attr "itanium_class" "br,scall")])
4706 (define_insn "sibcall_nogp"
4707   [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
4708          (const_int 0))]
4709   ""
4710   "br%+.many %0"
4711   [(set_attr "itanium_class" "br,scall")])
4713 (define_insn "call_gp"
4714   [(call (mem:DI (match_operand 0 "call_operand" "?r,i"))
4715          (const_int 1))
4716    (clobber (match_operand:DI 1 "register_operand" "=b,b"))
4717    (clobber (match_scratch:DI 2 "=&r,X"))
4718    (clobber (match_scratch:DI 3 "=b,X"))]
4719   ""
4720   "#"
4721   [(set_attr "itanium_class" "br,scall")])
4723 ;; Irritatingly, we don't have access to INSN within the split body.
4724 ;; See commentary in ia64_split_call as to why these aren't peep2.
4725 (define_split
4726   [(call (mem (match_operand 0 "call_operand" ""))
4727          (const_int 1))
4728    (clobber (match_operand:DI 1 "register_operand" ""))
4729    (clobber (match_scratch:DI 2 ""))
4730    (clobber (match_scratch:DI 3 ""))]
4731   "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4732   [(const_int 0)]
4734   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4735                    operands[3], true, false);
4736   DONE;
4739 (define_split
4740   [(call (mem (match_operand 0 "call_operand" ""))
4741          (const_int 1))
4742    (clobber (match_operand:DI 1 "register_operand" ""))
4743    (clobber (match_scratch:DI 2 ""))
4744    (clobber (match_scratch:DI 3 ""))]
4745   "reload_completed"
4746   [(const_int 0)]
4748   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4749                    operands[3], false, false);
4750   DONE;
4753 (define_insn "call_value_gp"
4754   [(set (match_operand 0 "" "")
4755         (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
4756               (const_int 1)))
4757    (clobber (match_operand:DI 2 "register_operand" "=b,b"))
4758    (clobber (match_scratch:DI 3 "=&r,X"))
4759    (clobber (match_scratch:DI 4 "=b,X"))]
4760   ""
4761   "#"
4762   [(set_attr "itanium_class" "br,scall")])
4764 (define_split
4765   [(set (match_operand 0 "" "")
4766         (call (mem:DI (match_operand:DI 1 "call_operand" ""))
4767               (const_int 1)))
4768    (clobber (match_operand:DI 2 "register_operand" ""))
4769    (clobber (match_scratch:DI 3 ""))
4770    (clobber (match_scratch:DI 4 ""))]
4771   "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4772   [(const_int 0)]
4774   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4775                    operands[4], true, false);
4776   DONE;
4779 (define_split
4780   [(set (match_operand 0 "" "")
4781         (call (mem:DI (match_operand:DI 1 "call_operand" ""))
4782               (const_int 1)))
4783    (clobber (match_operand:DI 2 "register_operand" ""))
4784    (clobber (match_scratch:DI 3 ""))
4785    (clobber (match_scratch:DI 4 ""))]
4786   "reload_completed"
4787   [(const_int 0)]
4789   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4790                    operands[4], false, false);
4791   DONE;
4794 (define_insn_and_split "sibcall_gp"
4795   [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
4796          (const_int 1))
4797    (clobber (match_scratch:DI 1 "=&r,X"))
4798    (clobber (match_scratch:DI 2 "=b,X"))]
4799   ""
4800   "#"
4801   "reload_completed"
4802   [(const_int 0)]
4804   ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
4805                    operands[2], true, true);
4806   DONE;
4808   [(set_attr "itanium_class" "br")])
4810 (define_insn "return_internal"
4811   [(return)
4812    (use (match_operand:DI 0 "register_operand" "b"))]
4813   ""
4814   "br.ret.sptk.many %0"
4815   [(set_attr "itanium_class" "br")])
4817 (define_insn "return"
4818   [(return)]
4819   "ia64_direct_return ()"
4820   "br.ret.sptk.many rp"
4821   [(set_attr "itanium_class" "br")])
4823 (define_insn "*return_true"
4824   [(set (pc)
4825         (if_then_else (match_operator 0 "predicate_operator"
4826                         [(match_operand:BI 1 "register_operand" "c")
4827                          (const_int 0)])
4828                       (return)
4829                       (pc)))]
4830   "ia64_direct_return ()"
4831   "(%J0) br.ret%+.many rp"
4832   [(set_attr "itanium_class" "br")
4833    (set_attr "predicable" "no")])
4835 (define_insn "*return_false"
4836   [(set (pc)
4837         (if_then_else (match_operator 0 "predicate_operator"
4838                         [(match_operand:BI 1 "register_operand" "c")
4839                          (const_int 0)])
4840                       (pc)
4841                       (return)))]
4842   "ia64_direct_return ()"
4843   "(%j0) br.ret%+.many rp"
4844   [(set_attr "itanium_class" "br")
4845    (set_attr "predicable" "no")])
4847 (define_insn "jump"
4848   [(set (pc) (label_ref (match_operand 0 "" "")))]
4849   ""
4850   "br %l0"
4851   [(set_attr "itanium_class" "br")])
4853 (define_insn "indirect_jump"
4854   [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
4855   ""
4856   "br %0"
4857   [(set_attr "itanium_class" "br")])
4859 (define_expand "tablejump"
4860   [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
4861               (use (label_ref (match_operand 1 "" "")))])]
4862   ""
4864   rtx op0 = operands[0];
4865   rtx addr;
4867   /* ??? Bother -- do_tablejump is "helpful" and pulls the table
4868      element into a register without bothering to see whether that
4869      is necessary given the operand predicate.  Check for MEM just
4870      in case someone fixes this.  */
4871   if (GET_CODE (op0) == MEM)
4872     addr = XEXP (op0, 0);
4873   else
4874     {
4875       /* Otherwise, cheat and guess that the previous insn in the
4876          stream was the memory load.  Grab the address from that.
4877          Note we have to momentarily pop out of the sequence started
4878          by the insn-emit wrapper in order to grab the last insn.  */
4879       rtx last, set;
4881       end_sequence ();
4882       last = get_last_insn ();
4883       start_sequence ();
4884       set = single_set (last);
4886       if (! rtx_equal_p (SET_DEST (set), op0)
4887           || GET_CODE (SET_SRC (set)) != MEM)
4888         abort ();
4889       addr = XEXP (SET_SRC (set), 0);
4890       if (rtx_equal_p (addr, op0))
4891         abort ();
4892     }
4894   /* Jump table elements are stored pc-relative.  That is, a displacement
4895      from the entry to the label.  Thus to convert to an absolute address
4896      we add the address of the memory from which the value is loaded.  */
4897   operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
4898                                      NULL_RTX, 1, OPTAB_DIRECT);
4901 (define_insn "*tablejump_internal"
4902   [(set (pc) (match_operand:DI 0 "register_operand" "b"))
4903    (use (label_ref (match_operand 1 "" "")))]
4904   ""
4905   "br %0"
4906   [(set_attr "itanium_class" "br")])
4909 ;; ::::::::::::::::::::
4910 ;; ::
4911 ;; :: Prologue and Epilogue instructions
4912 ;; ::
4913 ;; ::::::::::::::::::::
4915 (define_expand "prologue"
4916   [(const_int 1)]
4917   ""
4919   ia64_expand_prologue ();
4920   DONE;
4923 (define_expand "epilogue"
4924   [(return)]
4925   ""
4927   ia64_expand_epilogue (0);
4928   DONE;
4931 (define_expand "sibcall_epilogue"
4932   [(return)]
4933   ""
4935   ia64_expand_epilogue (1);
4936   DONE;
4939 ;; This prevents the scheduler from moving the SP decrement past FP-relative
4940 ;; stack accesses.  This is the same as adddi3 plus the extra set.
4942 (define_insn "prologue_allocate_stack"
4943   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4944         (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
4945                  (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
4946    (set (match_operand:DI 3 "register_operand" "+r,r,r")
4947         (match_dup 3))]
4948   ""
4949   "@
4950    add %0 = %1, %2
4951    adds %0 = %2, %1
4952    addl %0 = %2, %1"
4953   [(set_attr "itanium_class" "ialu")])
4955 ;; This prevents the scheduler from moving the SP restore past FP-relative
4956 ;; stack accesses.  This is similar to movdi plus the extra set.
4958 (define_insn "epilogue_deallocate_stack"
4959   [(set (match_operand:DI 0 "register_operand" "=r")
4960         (match_operand:DI 1 "register_operand" "+r"))
4961    (set (match_dup 1) (match_dup 1))]
4962   ""
4963   "mov %0 = %1"
4964   [(set_attr "itanium_class" "ialu")])
4966 ;; As USE insns aren't meaningful after reload, this is used instead
4967 ;; to prevent deleting instructions setting registers for EH handling
4968 (define_insn "prologue_use"
4969   [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
4970               UNSPEC_PROLOGUE_USE)]
4971   ""
4972   ""
4973   [(set_attr "itanium_class" "ignore")
4974    (set_attr "predicable" "no")])
4976 ;; Allocate a new register frame.
4978 (define_insn "alloc"
4979   [(set (match_operand:DI 0 "register_operand" "=r")
4980         (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
4981    (use (match_operand:DI 1 "const_int_operand" "i"))
4982    (use (match_operand:DI 2 "const_int_operand" "i"))
4983    (use (match_operand:DI 3 "const_int_operand" "i"))
4984    (use (match_operand:DI 4 "const_int_operand" "i"))]
4985   ""
4986   "alloc %0 = ar.pfs, %1, %2, %3, %4"
4987   [(set_attr "itanium_class" "syst_m0")
4988    (set_attr "predicable" "no")])
4990 ;; Modifies ar.unat
4991 (define_expand "gr_spill"
4992   [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
4993                    (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4994                                (match_operand:DI 2 "const_int_operand" "")]
4995                               UNSPEC_GR_SPILL))
4996               (clobber (match_dup 3))])]
4997   ""
4998   "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5000 (define_insn "gr_spill_internal"
5001   [(set (match_operand:DI 0 "memory_operand" "=m")
5002         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5003                     (match_operand:DI 2 "const_int_operand" "")]
5004                    UNSPEC_GR_SPILL))
5005    (clobber (match_operand:DI 3 "register_operand" ""))]
5006   ""
5008   /* Note that we use a C output pattern here to avoid the predicate
5009      being automatically added before the .mem.offset directive.  */
5010   return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
5012   [(set_attr "itanium_class" "st")])
5014 ;; Reads ar.unat
5015 (define_expand "gr_restore"
5016   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5017                    (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5018                                (match_operand:DI 2 "const_int_operand" "")]
5019                               UNSPEC_GR_RESTORE))
5020               (use (match_dup 3))])]
5021   ""
5022   "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5024 (define_insn "gr_restore_internal"
5025   [(set (match_operand:DI 0 "register_operand" "=r")
5026         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5027                     (match_operand:DI 2 "const_int_operand" "")]
5028                    UNSPEC_GR_RESTORE))
5029    (use (match_operand:DI 3 "register_operand" ""))]
5030   ""
5031   { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
5032   [(set_attr "itanium_class" "ld")])
5034 (define_insn "fr_spill"
5035   [(set (match_operand:TF 0 "memory_operand" "=m")
5036         (unspec:TF [(match_operand:TF 1 "register_operand" "f")]
5037                    UNSPEC_FR_SPILL))]
5038   ""
5039   "stf.spill %0 = %1%P0"
5040   [(set_attr "itanium_class" "stf")])
5042 (define_insn "fr_restore"
5043   [(set (match_operand:TF 0 "register_operand" "=f")
5044         (unspec:TF [(match_operand:TF 1 "memory_operand" "m")]
5045                    UNSPEC_FR_RESTORE))]
5046   ""
5047   "ldf.fill %0 = %1%P1"
5048   [(set_attr "itanium_class" "fld")])
5050 ;; ??? The explicit stop is not ideal.  It would be better if
5051 ;; rtx_needs_barrier took care of this, but this is something that can be
5052 ;; fixed later.  This avoids an RSE DV.
5054 (define_insn "bsp_value"
5055   [(set (match_operand:DI 0 "register_operand" "=r")
5056         (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
5057   ""
5058   "*
5060   return \";;\;%,mov %0 = ar.bsp\";
5062   [(set_attr "itanium_class" "frar_i")])
5064 (define_insn "set_bsp"
5065   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
5066                     UNSPECV_SET_BSP)]
5067   ""
5068   "flushrs
5069         mov r19=ar.rsc
5070         ;;
5071         and r19=0x1c,r19
5072         ;;
5073         mov ar.rsc=r19
5074         ;;
5075         mov ar.bspstore=%0
5076         ;;
5077         or r19=0x3,r19
5078         ;;
5079         loadrs
5080         invala
5081         ;;
5082         mov ar.rsc=r19"
5083   [(set_attr "itanium_class" "unknown")
5084    (set_attr "predicable" "no")])
5086 ;; ??? The explicit stops are not ideal.  It would be better if
5087 ;; rtx_needs_barrier took care of this, but this is something that can be
5088 ;; fixed later.  This avoids an RSE DV.
5090 (define_insn "flushrs"
5091   [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
5092   ""
5093   ";;\;flushrs\;;;"
5094   [(set_attr "itanium_class" "rse_m")
5095    (set_attr "predicable" "no")])
5097 ;; ::::::::::::::::::::
5098 ;; ::
5099 ;; :: Miscellaneous instructions
5100 ;; ::
5101 ;; ::::::::::::::::::::
5103 ;; ??? Emiting a NOP instruction isn't very useful.  This should probably
5104 ;; be emitting ";;" to force a break in the instruction packing.
5106 ;; No operation, needed in case the user uses -g but not -O.
5107 (define_insn "nop"
5108   [(const_int 0)]
5109   ""
5110   "nop 0"
5111   [(set_attr "itanium_class" "nop")])
5113 (define_insn "nop_m"
5114   [(const_int 1)]
5115   ""
5116   "nop.m 0"
5117   [(set_attr "itanium_class" "nop_m")])
5119 (define_insn "nop_i"
5120   [(const_int 2)]
5121   ""
5122   "nop.i 0"
5123   [(set_attr "itanium_class" "nop_i")])
5125 (define_insn "nop_f"
5126   [(const_int 3)]
5127   ""
5128   "nop.f 0"
5129   [(set_attr "itanium_class" "nop_f")])
5131 (define_insn "nop_b"
5132   [(const_int 4)]
5133   ""
5134   "nop.b 0"
5135   [(set_attr "itanium_class" "nop_b")])
5137 (define_insn "nop_x"
5138   [(const_int 5)]
5139   ""
5140   ""
5141   [(set_attr "itanium_class" "nop_x")])
5143 ;; The following insn will be never generated.  It is used only by
5144 ;; insn scheduler to change state before advancing cycle.
5145 (define_insn "pre_cycle"
5146   [(const_int 6)]
5147   ""
5148   ""
5149   [(set_attr "itanium_class" "pre_cycle")])
5151 (define_insn "bundle_selector"
5152   [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
5153   ""
5154   { return get_bundle_name (INTVAL (operands[0])); }
5155   [(set_attr "itanium_class" "ignore")
5156    (set_attr "predicable" "no")])
5158 ;; Pseudo instruction that prevents the scheduler from moving code above this
5159 ;; point.
5160 (define_insn "blockage"
5161   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
5162   ""
5163   ""
5164   [(set_attr "itanium_class" "ignore")
5165    (set_attr "predicable" "no")])
5167 (define_insn "insn_group_barrier"
5168   [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5169                     UNSPECV_INSN_GROUP_BARRIER)]
5170   ""
5171   ";;"
5172   [(set_attr "itanium_class" "stop_bit")
5173    (set_attr "predicable" "no")])
5175 (define_expand "trap"
5176   [(trap_if (const_int 1) (const_int 0))]
5177   ""
5178   "")
5180 ;; ??? We don't have a match-any slot type.  Setting the type to unknown
5181 ;; produces worse code that setting the slot type to A.
5183 (define_insn "*trap"
5184   [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
5185   ""
5186   "break %0"
5187   [(set_attr "itanium_class" "chk_s")])
5189 (define_expand "conditional_trap"
5190   [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
5191   ""
5193   operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
5196 (define_insn "*conditional_trap"
5197   [(trap_if (match_operator 0 "predicate_operator"
5198               [(match_operand:BI 1 "register_operand" "c")
5199                (const_int 0)])  
5200             (match_operand 2 "const_int_operand" ""))]
5201   ""
5202   "(%J0) break %2"
5203   [(set_attr "itanium_class" "chk_s")
5204    (set_attr "predicable" "no")])
5206 (define_insn "break_f"
5207   [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
5208   ""
5209   "break.f 0"
5210   [(set_attr "itanium_class" "nop_f")])
5212 (define_insn "prefetch"
5213   [(prefetch (match_operand:DI 0 "address_operand" "p")
5214              (match_operand:DI 1 "const_int_operand" "n")
5215              (match_operand:DI 2 "const_int_operand" "n"))]
5216   ""
5218   static const char * const alt[2][4] = {
5219     {
5220       "lfetch.nta [%0]",
5221       "lfetch.nt1 [%0]",
5222       "lfetch.nt2 [%0]",
5223       "lfetch [%0]"
5224     },
5225     {
5226       "lfetch.excl.nta [%0]",
5227       "lfetch.excl.nt1 [%0]",
5228       "lfetch.excl.nt2 [%0]",
5229       "lfetch.excl [%0]"
5230     }
5231   };
5232   int i = (INTVAL (operands[1]));
5233   int j = (INTVAL (operands[2]));
5235   if (i != 0 && i != 1)
5236     abort ();
5237   if (j < 0 || j > 3)
5238     abort ();
5239   return alt[i][j];
5241   [(set_attr "itanium_class" "lfetch")])
5243 ;; Non-local goto support.
5245 (define_expand "save_stack_nonlocal"
5246   [(use (match_operand:OI 0 "memory_operand" ""))
5247    (use (match_operand:DI 1 "register_operand" ""))]
5248   ""
5250   emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5251                                          \"__ia64_save_stack_nonlocal\"),
5252                      0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
5253                      operands[1], Pmode);
5254   DONE;
5257 (define_expand "nonlocal_goto"
5258   [(use (match_operand 0 "general_operand" ""))
5259    (use (match_operand 1 "general_operand" ""))
5260    (use (match_operand 2 "general_operand" ""))
5261    (use (match_operand 3 "general_operand" ""))]
5262   ""
5264   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
5265                      LCT_NORETURN, VOIDmode, 3,
5266                      operands[1], Pmode,
5267                      copy_to_reg (XEXP (operands[2], 0)), Pmode,
5268                      operands[3], Pmode);
5269   emit_barrier ();
5270   DONE;
5273 (define_insn_and_split "builtin_setjmp_receiver"
5274   [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
5275   ""
5276   "#"
5277   "reload_completed"
5278   [(const_int 0)]
5280   ia64_reload_gp ();
5281   DONE;
5284 (define_expand "eh_epilogue"
5285   [(use (match_operand:DI 0 "register_operand" "r"))
5286    (use (match_operand:DI 1 "register_operand" "r"))
5287    (use (match_operand:DI 2 "register_operand" "r"))]
5288   ""
5290   rtx bsp = gen_rtx_REG (Pmode, 10);
5291   rtx sp = gen_rtx_REG (Pmode, 9);
5293   if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
5294     {
5295       emit_move_insn (bsp, operands[0]);
5296       operands[0] = bsp;
5297     }
5298   if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
5299     {
5300       emit_move_insn (sp, operands[2]);
5301       operands[2] = sp;
5302     }
5303   emit_insn (gen_rtx_USE (VOIDmode, sp));
5304   emit_insn (gen_rtx_USE (VOIDmode, bsp));
5306   cfun->machine->ia64_eh_epilogue_sp = sp;
5307   cfun->machine->ia64_eh_epilogue_bsp = bsp;
5310 ;; Builtin apply support.
5312 (define_expand "restore_stack_nonlocal"
5313   [(use (match_operand:DI 0 "register_operand" ""))
5314    (use (match_operand:OI 1 "memory_operand" ""))]
5315   ""
5317   emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5318                                          "__ia64_restore_stack_nonlocal"),
5319                      0, VOIDmode, 1,
5320                      copy_to_reg (XEXP (operands[1], 0)), Pmode);
5321   DONE;
5325 ;;; Intrinsics support.
5327 (define_expand "mf"
5328   [(set (mem:BLK (match_dup 0))
5329         (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
5330   ""
5332   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
5333   MEM_VOLATILE_P (operands[0]) = 1;
5336 (define_insn "*mf_internal"
5337   [(set (match_operand:BLK 0 "" "")
5338         (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
5339   ""
5340   "mf"
5341   [(set_attr "itanium_class" "syst_m")])
5343 (define_insn "fetchadd_acq_si"
5344   [(set (match_operand:SI 0 "gr_register_operand" "=r")
5345         (match_dup 1))
5346    (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5347         (unspec:SI [(match_dup 1)
5348                     (match_operand:SI 2 "fetchadd_operand" "n")]
5349                    UNSPEC_FETCHADD_ACQ))]
5350   ""
5351   "fetchadd4.acq %0 = %1, %2"
5352   [(set_attr "itanium_class" "sem")])
5354 (define_insn "fetchadd_acq_di"
5355   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5356         (match_dup 1))
5357    (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5358         (unspec:DI [(match_dup 1)
5359                     (match_operand:DI 2 "fetchadd_operand" "n")]
5360                    UNSPEC_FETCHADD_ACQ))]
5361   ""
5362   "fetchadd8.acq %0 = %1, %2"
5363   [(set_attr "itanium_class" "sem")])
5365 (define_insn "cmpxchg_acq_si"
5366   [(set (match_operand:SI 0 "gr_register_operand" "=r")
5367         (match_dup 1))
5368    (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5369         (unspec:SI [(match_dup 1)
5370                     (match_operand:SI 2 "gr_register_operand" "r")
5371                     (match_operand 3 "ar_ccv_reg_operand" "")]
5372                    UNSPEC_CMPXCHG_ACQ))]
5373   ""
5374   "cmpxchg4.acq %0 = %1, %2, %3"
5375   [(set_attr "itanium_class" "sem")])
5377 (define_insn "cmpxchg_acq_di"
5378   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5379         (match_dup 1))
5380    (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5381         (unspec:DI [(match_dup 1)
5382                     (match_operand:DI 2 "gr_register_operand" "r")
5383                     (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5384                    UNSPEC_CMPXCHG_ACQ))]
5385   ""
5386   "cmpxchg8.acq %0 = %1, %2, %3"
5387   [(set_attr "itanium_class" "sem")])
5389 (define_insn "xchgsi"
5390   [(set (match_operand:SI 0 "gr_register_operand" "=r")
5391         (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5392    (set (match_dup 1)
5393         (match_operand:SI 2 "gr_register_operand" "r"))]
5394   ""
5395   "xchg4 %0 = %1, %2"
5396   [(set_attr "itanium_class" "sem")])
5398 (define_insn "xchgdi"
5399   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5400         (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5401    (set (match_dup 1)
5402         (match_operand:DI 2 "gr_register_operand" "r"))]
5403   ""
5404   "xchg8 %0 = %1, %2"
5405   [(set_attr "itanium_class" "sem")])
5407 ;; Predication.
5409 (define_cond_exec
5410   [(match_operator 0 "predicate_operator"
5411      [(match_operand:BI 1 "register_operand" "c")
5412       (const_int 0)])]
5413   ""
5414   "(%J0)")
5416 (define_insn "pred_rel_mutex"
5417   [(set (match_operand:BI 0 "register_operand" "+c")
5418        (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
5419   ""
5420   ".pred.rel.mutex %0, %I0"
5421   [(set_attr "itanium_class" "ignore")
5422    (set_attr "predicable" "no")])
5424 (define_insn "safe_across_calls_all"
5425   [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
5426   ""
5427   ".pred.safe_across_calls p1-p63"
5428   [(set_attr "itanium_class" "ignore")
5429    (set_attr "predicable" "no")])
5431 (define_insn "safe_across_calls_normal"
5432   [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
5433   ""
5435   emit_safe_across_calls ();
5436   return "";
5438   [(set_attr "itanium_class" "ignore")
5439    (set_attr "predicable" "no")])
5441 ;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
5442 ;; pointer.  This is used by the HP-UX 32 bit mode.
5444 (define_insn "ptr_extend"
5445   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5446         (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
5447                    UNSPEC_ADDP4))]
5448   ""
5449   "addp4 %0 = 0,%1"
5450   [(set_attr "itanium_class" "ialu")])
5453 ;; Optimizations for ptr_extend
5455 (define_insn "*ptr_extend_plus_1"
5456   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5457         (unspec:DI
5458          [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
5459                    (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
5460          UNSPEC_ADDP4))]
5461   "addp4_optimize_ok (operands[1], operands[2])"
5462   "addp4 %0 = %2, %1"
5463   [(set_attr "itanium_class" "ialu")])
5465 (define_insn "*ptr_extend_plus_2"
5466   [(set (match_operand:DI 0 "gr_register_operand" "=r")
5467         (unspec:DI
5468          [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
5469                    (match_operand:SI 2 "basereg_operand" "r"))]
5470          UNSPEC_ADDP4))]
5471   "addp4_optimize_ok (operands[1], operands[2])"
5472   "addp4 %0 = %1, %2"
5473   [(set_attr "itanium_class" "ialu")])