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