190075Sobrien;; IA-64 Machine description template
2169689Skan;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
3132718Skan;; Free Software Foundation, Inc.
490075Sobrien;; Contributed by James E. Wilson <wilson@cygnus.com> and
590075Sobrien;;		  David Mosberger <davidm@hpl.hp.com>.
690075Sobrien
7132718Skan;; This file is part of GCC.
890075Sobrien
9132718Skan;; GCC is free software; you can redistribute it and/or modify
1090075Sobrien;; it under the terms of the GNU General Public License as published by
1190075Sobrien;; the Free Software Foundation; either version 2, or (at your option)
1290075Sobrien;; any later version.
1390075Sobrien
14132718Skan;; GCC is distributed in the hope that it will be useful,
1590075Sobrien;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1690075Sobrien;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1790075Sobrien;; GNU General Public License for more details.
1890075Sobrien
1990075Sobrien;; You should have received a copy of the GNU General Public License
20132718Skan;; along with GCC; see the file COPYING.  If not, write to
21169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22169689Skan;; Boston, MA 02110-1301, USA.
2390075Sobrien
2490075Sobrien;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
2590075Sobrien
2690075Sobrien;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
2790075Sobrien;; reload.  This will be fixed once scheduling support is turned on.
2890075Sobrien
2990075Sobrien;; ??? Optimize for post-increment addressing modes.
3090075Sobrien
3190075Sobrien;; ??? fselect is not supported, because there is no integer register
3290075Sobrien;; equivalent.
3390075Sobrien
3490075Sobrien;; ??? fp abs/min/max instructions may also work for integer values.
3590075Sobrien
3690075Sobrien;; ??? Would a predicate_reg_operand predicate be useful?  The HP one is buggy,
3790075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking.
3890075Sobrien
3990075Sobrien;; ??? Would a branch_reg_operand predicate be useful?  The HP one is buggy,
4090075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking.
4190075Sobrien
4290075Sobrien;; ??? Go through list of documented named patterns and look for more to
4390075Sobrien;; implement.
4490075Sobrien
4590075Sobrien;; ??? Go through instruction manual and look for more instructions that
4690075Sobrien;; can be emitted.
4790075Sobrien
4890075Sobrien;; ??? Add function unit scheduling info for Itanium (TM) processor.
4990075Sobrien
5090075Sobrien;; ??? Need a better way to describe alternate fp status registers.
5190075Sobrien
52117395Skan(define_constants
53117395Skan  [; Relocations
54117395Skan   (UNSPEC_LTOFF_DTPMOD		0)
55117395Skan   (UNSPEC_LTOFF_DTPREL		1)
56117395Skan   (UNSPEC_DTPREL		2)
57117395Skan   (UNSPEC_LTOFF_TPREL		3)
58117395Skan   (UNSPEC_TPREL		4)
59169689Skan   (UNSPEC_DTPMOD		5)
60117395Skan
61117395Skan   (UNSPEC_LD_BASE		9)
62117395Skan   (UNSPEC_GR_SPILL		10)
63117395Skan   (UNSPEC_GR_RESTORE		11)
64117395Skan   (UNSPEC_FR_SPILL		12)
65117395Skan   (UNSPEC_FR_RESTORE		13)
66117395Skan   (UNSPEC_FR_RECIP_APPROX	14)
67117395Skan   (UNSPEC_PRED_REL_MUTEX	15)
68132718Skan   (UNSPEC_GETF_EXP		16)
69117395Skan   (UNSPEC_PIC_CALL		17)
70117395Skan   (UNSPEC_MF			18)
71117395Skan   (UNSPEC_CMPXCHG_ACQ		19)
72117395Skan   (UNSPEC_FETCHADD_ACQ		20)
73117395Skan   (UNSPEC_BSP_VALUE		21)
74117395Skan   (UNSPEC_FLUSHRS		22)
75117395Skan   (UNSPEC_BUNDLE_SELECTOR	23)
76117395Skan   (UNSPEC_ADDP4		24)
77117395Skan   (UNSPEC_PROLOGUE_USE		25)
78122180Skan   (UNSPEC_RET_ADDR		26)
79132718Skan   (UNSPEC_SETF_EXP             27)
80132718Skan   (UNSPEC_FR_SQRT_RECIP_APPROX 28)
81169689Skan   (UNSPEC_SHRP			29)
82169689Skan   (UNSPEC_COPYSIGN		30)
83169689Skan   (UNSPEC_VECT_EXTR		31)
84169689Skan   (UNSPEC_LDA                  40)
85169689Skan   (UNSPEC_LDS                  41)
86169689Skan   (UNSPEC_LDSA                 42)
87169689Skan   (UNSPEC_LDCCLR               43)
88169689Skan   (UNSPEC_CHKACLR              45)
89169689Skan   (UNSPEC_CHKS                 47)	
90117395Skan  ])
91117395Skan
92117395Skan(define_constants
93117395Skan  [(UNSPECV_ALLOC		0)
94117395Skan   (UNSPECV_BLOCKAGE		1)
95117395Skan   (UNSPECV_INSN_GROUP_BARRIER	2)
96117395Skan   (UNSPECV_BREAK		3)
97117395Skan   (UNSPECV_SET_BSP		4)
98117395Skan   (UNSPECV_PSAC_ALL		5)	; pred.safe_across_calls
99117395Skan   (UNSPECV_PSAC_NORMAL		6)
100117395Skan   (UNSPECV_SETJMP_RECEIVER	7)
101117395Skan  ])
102169689Skan
103169689Skan(include "predicates.md")
10490075Sobrien
10590075Sobrien;; ::::::::::::::::::::
10690075Sobrien;; ::
10790075Sobrien;; :: Attributes
10890075Sobrien;; ::
10990075Sobrien;; ::::::::::::::::::::
11090075Sobrien
111132718Skan;; Processor type.  This attribute must exactly match the processor_type
112132718Skan;; enumeration in ia64.h.
113132718Skan(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
114132718Skan
11590075Sobrien;; Instruction type.  This primarily determines how instructions can be
11690075Sobrien;; packed in bundles, and secondarily affects scheduling to function units.
11790075Sobrien
11890075Sobrien;; A alu, can go in I or M syllable of a bundle
11990075Sobrien;; I integer
12090075Sobrien;; M memory
12190075Sobrien;; F floating-point
12290075Sobrien;; B branch
12390075Sobrien;; L long immediate, takes two syllables
12490075Sobrien;; S stop bit
12590075Sobrien
12690075Sobrien;; ??? Should not have any pattern with type unknown.  Perhaps add code to
12790075Sobrien;; check this in md_reorg?  Currently use unknown for patterns which emit
12890075Sobrien;; multiple instructions, patterns which emit 0 instructions, and patterns
12990075Sobrien;; which emit instruction that can go in any slot (e.g. nop).
13090075Sobrien
131117395Skan(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
132169689Skan	fldp,fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,
133169689Skan	ld,chk_s_i,chk_s_f,chk_a,long_i,mmalua,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,
134169689Skan        st,syst_m0, syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,
135169689Skan        nop_b,nop_f,nop_i,nop_m,nop_x,lfetch,pre_cycle"
136117395Skan  (const_string "unknown"))
13790075Sobrien
138169689Skan;; chk_s_i has an I and an M form; use type A for convenience.
13990075Sobrien(define_attr "type" "unknown,A,I,M,F,B,L,X,S"
140169689Skan  (cond [(eq_attr "itanium_class" "ld,st,fld,fldp,stf,sem,nop_m") (const_string "M")
14190075Sobrien	 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
14290075Sobrien	 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
14390075Sobrien	 (eq_attr "itanium_class" "lfetch") (const_string "M")
144169689Skan         (eq_attr "itanium_class" "chk_s_f,chk_a") (const_string "M")
145169689Skan	 (eq_attr "itanium_class" "chk_s_i,ialu,icmp,ilog,mmalua")
146169689Skan	   (const_string "A")
14790075Sobrien	 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
14890075Sobrien	 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
14990075Sobrien	 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
15090075Sobrien	 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
15190075Sobrien	 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
15290075Sobrien	 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
15390075Sobrien	 (eq_attr "itanium_class" "stop_bit") (const_string "S")
15490075Sobrien	 (eq_attr "itanium_class" "nop_x") (const_string "X")
15590075Sobrien	 (eq_attr "itanium_class" "long_i") (const_string "L")]
15690075Sobrien	(const_string "unknown")))
15790075Sobrien
15890075Sobrien(define_attr "itanium_requires_unit0" "no,yes"
15990075Sobrien  (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
16090075Sobrien	 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
16190075Sobrien	 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
16290075Sobrien	 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
16390075Sobrien	 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
16490075Sobrien	 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
16590075Sobrien	(const_string "no")))
16690075Sobrien
16790075Sobrien;; Predication.  True iff this instruction can be predicated.
16890075Sobrien
16990075Sobrien(define_attr "predicable" "no,yes" (const_string "yes"))
17090075Sobrien
171132718Skan;; Empty.  True iff this insn does not generate any code.
172132718Skan
173132718Skan(define_attr "empty" "no,yes" (const_string "no"))
174132718Skan
175169689Skan;; True iff this insn must be the first insn of an instruction group.
176169689Skan;; This is true for the alloc instruction, and will also be true of others
177169689Skan;; when we have full intrinsics support.
178169689Skan
179169689Skan(define_attr "first_insn" "no,yes" (const_string "no"))
180169689Skan
181169689Skan(define_attr "data_speculative" "no,yes" (const_string "no"))
182169689Skan
183169689Skan(define_attr "control_speculative" "no,yes" (const_string "no"))
184169689Skan
185169689Skan(define_attr "check_load" "no,yes" (const_string "no"))
18690075Sobrien
187132718Skan;; DFA descriptions of ia64 processors used for insn scheduling and
188132718Skan;; bundling.
18990075Sobrien
190132718Skan(automata_option "ndfa")
19190075Sobrien
192132718Skan;; Uncomment the following line to output automata for debugging.
193132718Skan;; (automata_option "v")
19490075Sobrien
195132718Skan(automata_option "w")
19690075Sobrien
197132718Skan(include "itanium1.md")
198132718Skan(include "itanium2.md")
19990075Sobrien
20090075Sobrien
20190075Sobrien;; ::::::::::::::::::::
20290075Sobrien;; ::
20390075Sobrien;; :: Moves
20490075Sobrien;; ::
20590075Sobrien;; ::::::::::::::::::::
20690075Sobrien
20790075Sobrien;; Set of a single predicate register.  This is only used to implement
20890075Sobrien;; pr-to-pr move and complement.
20990075Sobrien
21090075Sobrien(define_insn "*movcci"
21190075Sobrien  [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
21290075Sobrien	(match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
21390075Sobrien  ""
21490075Sobrien  "@
21590075Sobrien   cmp.ne %0, p0 = r0, r0
21690075Sobrien   cmp.eq %0, p0 = r0, r0
21790075Sobrien   (%1) cmp.eq.unc %0, p0 = r0, r0"
21890075Sobrien  [(set_attr "itanium_class" "icmp")
21990075Sobrien   (set_attr "predicable" "no")])
22090075Sobrien
22190075Sobrien(define_insn "movbi"
222169689Skan  [(set (match_operand:BI 0 "destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
223169689Skan	(match_operand:BI 1 "move_operand"        " O,n, c,  c,*r, n,*m,*r,*r"))]
22490075Sobrien  ""
22590075Sobrien  "@
22690075Sobrien   cmp.ne %0, %I0 = r0, r0
22790075Sobrien   cmp.eq %0, %I0 = r0, r0
22890075Sobrien   #
22990075Sobrien   #
23090075Sobrien   tbit.nz %0, %I0 = %1, 0
23190075Sobrien   adds %0 = %1, r0
23290075Sobrien   ld1%O1 %0 = %1%P1
23390075Sobrien   st1%Q0 %0 = %1%P0
23490075Sobrien   mov %0 = %1"
23590075Sobrien  [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
23690075Sobrien
23790075Sobrien(define_split
23890075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
23990075Sobrien	(match_operand:BI 1 "register_operand" ""))]
24090075Sobrien  "reload_completed
24190075Sobrien   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
24290075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
24390075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
24490075Sobrien     (set (match_dup 0) (const_int 1)))
24590075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
24690075Sobrien     (set (match_dup 0) (const_int 0)))]
24790075Sobrien  "")
24890075Sobrien
24990075Sobrien(define_split
25090075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
25190075Sobrien	(match_operand:BI 1 "register_operand" ""))]
25290075Sobrien  "reload_completed
25390075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
25490075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
25590075Sobrien  [(set (match_dup 2) (match_dup 4))
25690075Sobrien   (set (match_dup 3) (match_dup 5))
257117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
25890075Sobrien  "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
25990075Sobrien   operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
26090075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
26190075Sobrien   operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
26290075Sobrien
26390075Sobrien(define_expand "movqi"
26490075Sobrien  [(set (match_operand:QI 0 "general_operand" "")
26590075Sobrien	(match_operand:QI 1 "general_operand" ""))]
26690075Sobrien  ""
26790075Sobrien{
268117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
269117395Skan  if (!op1)
270117395Skan    DONE;
271117395Skan  operands[1] = op1;
272117395Skan})
27390075Sobrien
27490075Sobrien(define_insn "*movqi_internal"
27590075Sobrien  [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
27690075Sobrien	(match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
27790075Sobrien  "ia64_move_ok (operands[0], operands[1])"
27890075Sobrien  "@
27990075Sobrien   mov %0 = %r1
28090075Sobrien   addl %0 = %1, r0
28190075Sobrien   ld1%O1 %0 = %1%P1
28290075Sobrien   st1%Q0 %0 = %r1%P0
28390075Sobrien   getf.sig %0 = %1
28490075Sobrien   setf.sig %0 = %r1
28590075Sobrien   mov %0 = %1"
28690075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
28790075Sobrien
28890075Sobrien(define_expand "movhi"
28990075Sobrien  [(set (match_operand:HI 0 "general_operand" "")
29090075Sobrien	(match_operand:HI 1 "general_operand" ""))]
29190075Sobrien  ""
29290075Sobrien{
293117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
294117395Skan  if (!op1)
295117395Skan    DONE;
296117395Skan  operands[1] = op1;
297117395Skan})
29890075Sobrien
29990075Sobrien(define_insn "*movhi_internal"
30090075Sobrien  [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
30190075Sobrien	(match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
30290075Sobrien  "ia64_move_ok (operands[0], operands[1])"
30390075Sobrien  "@
30490075Sobrien   mov %0 = %r1
30590075Sobrien   addl %0 = %1, r0
30690075Sobrien   ld2%O1 %0 = %1%P1
30790075Sobrien   st2%Q0 %0 = %r1%P0
30890075Sobrien   getf.sig %0 = %1
30990075Sobrien   setf.sig %0 = %r1
31090075Sobrien   mov %0 = %1"
31190075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
31290075Sobrien
31390075Sobrien(define_expand "movsi"
31490075Sobrien  [(set (match_operand:SI 0 "general_operand" "")
31590075Sobrien	(match_operand:SI 1 "general_operand" ""))]
31690075Sobrien  ""
31790075Sobrien{
318117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
319117395Skan  if (!op1)
320117395Skan    DONE;
321117395Skan  operands[1] = op1;
322117395Skan})
32390075Sobrien
32490075Sobrien(define_insn "*movsi_internal"
32590075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
32690075Sobrien	(match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
32790075Sobrien  "ia64_move_ok (operands[0], operands[1])"
32890075Sobrien  "@
32990075Sobrien  mov %0 = %r1
33090075Sobrien  addl %0 = %1, r0
33190075Sobrien  movl %0 = %1
33290075Sobrien  ld4%O1 %0 = %1%P1
33390075Sobrien  st4%Q0 %0 = %r1%P0
33490075Sobrien  getf.sig %0 = %1
33590075Sobrien  setf.sig %0 = %r1
33690075Sobrien  mov %0 = %1
33790075Sobrien  mov %0 = %1
33890075Sobrien  mov %0 = %r1"
339117395Skan  ;; frar_m, toar_m ??? why not frar_i and toar_i
34090075Sobrien  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
34190075Sobrien
34290075Sobrien(define_expand "movdi"
34390075Sobrien  [(set (match_operand:DI 0 "general_operand" "")
34490075Sobrien	(match_operand:DI 1 "general_operand" ""))]
34590075Sobrien  ""
34690075Sobrien{
347117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
348117395Skan  if (!op1)
349117395Skan    DONE;
350117395Skan  operands[1] = op1;
351117395Skan})
35290075Sobrien
35390075Sobrien(define_insn "*movdi_internal"
35490075Sobrien  [(set (match_operand:DI 0 "destination_operand"
35590075Sobrien		    "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
35690075Sobrien	(match_operand:DI 1 "move_operand"
357132718Skan		    "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
35890075Sobrien  "ia64_move_ok (operands[0], operands[1])"
35990075Sobrien{
36090075Sobrien  static const char * const alt[] = {
361117395Skan    "%,mov %0 = %r1",
362117395Skan    "%,addl %0 = %1, r0",
363117395Skan    "%,movl %0 = %1",
364117395Skan    "%,ld8%O1 %0 = %1%P1",
365117395Skan    "%,st8%Q0 %0 = %r1%P0",
366117395Skan    "%,getf.sig %0 = %1",
367117395Skan    "%,setf.sig %0 = %r1",
368117395Skan    "%,mov %0 = %1",
369117395Skan    "%,ldf8 %0 = %1%P1",
370117395Skan    "%,stf8 %0 = %1%P0",
371117395Skan    "%,mov %0 = %1",
372117395Skan    "%,mov %0 = %r1",
373117395Skan    "%,mov %0 = %1",
374117395Skan    "%,mov %0 = %1",
375117395Skan    "%,mov %0 = %1",
376117395Skan    "%,mov %0 = %1",
377117395Skan    "mov %0 = pr",
378117395Skan    "mov pr = %1, -1"
37990075Sobrien  };
38090075Sobrien
381169689Skan  gcc_assert (which_alternative != 2 || TARGET_NO_PIC
382169689Skan              || !symbolic_operand (operands[1], VOIDmode));
38390075Sobrien
38490075Sobrien  return alt[which_alternative];
385117395Skan}
38690075Sobrien  [(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")])
38790075Sobrien
388169689Skan(define_mode_macro MODE [BI QI HI SI DI SF DF XF TI])
389169689Skan(define_mode_macro MODE_FOR_EXTEND [QI HI SI])
390169689Skan
391169689Skan(define_mode_attr output_a [
392169689Skan  (BI "ld1.a %0 = %1%P1")
393169689Skan  (QI "ld1.a %0 = %1%P1")
394169689Skan  (HI "ld2.a %0 = %1%P1")
395169689Skan  (SI "ld4.a %0 = %1%P1")
396169689Skan  (DI
397169689Skan   "@
398169689Skan    ld8.a %0 = %1%P1
399169689Skan    ldf8.a %0 = %1%P1")
400169689Skan  (SF
401169689Skan   "@
402169689Skan    ldfs.a %0 = %1%P1
403169689Skan    ld4.a %0 = %1%P1")
404169689Skan  (DF
405169689Skan   "@
406169689Skan    ldfd.a %0 = %1%P1
407169689Skan    ld8.a %0 = %1%P1")
408169689Skan  (XF "ldfe.a %0 = %1%P1")
409169689Skan  (TI "ldfp8.a %X0 = %1%P1")])
410169689Skan
411169689Skan(define_mode_attr output_s [
412169689Skan  (BI "ld1.s %0 = %1%P1")
413169689Skan  (QI "ld1.s %0 = %1%P1")
414169689Skan  (HI "ld2.s %0 = %1%P1")
415169689Skan  (SI "ld4.s %0 = %1%P1")
416169689Skan  (DI
417169689Skan   "@
418169689Skan    ld8.s %0 = %1%P1
419169689Skan    ldf8.s %0 = %1%P1")
420169689Skan  (SF
421169689Skan   "@
422169689Skan    ldfs.s %0 = %1%P1
423169689Skan    ld4.s %0 = %1%P1")
424169689Skan  (DF
425169689Skan   "@
426169689Skan    ldfd.s %0 = %1%P1
427169689Skan    ld8.s %0 = %1%P1")
428169689Skan  (XF "ldfe.s %0 = %1%P1")
429169689Skan  (TI "ldfp8.s %X0 = %1%P1")])
430169689Skan
431169689Skan(define_mode_attr output_sa [
432169689Skan  (BI "ld1.sa %0 = %1%P1")
433169689Skan  (QI "ld1.sa %0 = %1%P1")
434169689Skan  (HI "ld2.sa %0 = %1%P1")
435169689Skan  (SI "ld4.sa %0 = %1%P1")
436169689Skan  (DI
437169689Skan   "@
438169689Skan    ld8.sa %0 = %1%P1
439169689Skan    ldf8.sa %0 = %1%P1")
440169689Skan  (SF
441169689Skan   "@
442169689Skan    ldfs.sa %0 = %1%P1
443169689Skan    ld4.sa %0 = %1%P1")
444169689Skan  (DF
445169689Skan   "@
446169689Skan    ldfd.sa %0 = %1%P1
447169689Skan    ld8.sa %0 = %1%P1")
448169689Skan  (XF "ldfe.sa %0 = %1%P1")
449169689Skan  (TI "ldfp8.sa %X0 = %1%P1")])
450169689Skan
451169689Skan(define_mode_attr output_c_clr [
452169689Skan  (BI "ld1.c.clr%O1 %0 = %1%P1")
453169689Skan  (QI "ld1.c.clr%O1 %0 = %1%P1")
454169689Skan  (HI "ld2.c.clr%O1 %0 = %1%P1")
455169689Skan  (SI "ld4.c.clr%O1 %0 = %1%P1")
456169689Skan  (DI
457169689Skan   "@
458169689Skan    ld8.c.clr%O1 %0 = %1%P1
459169689Skan    ldf8.c.clr %0 = %1%P1")
460169689Skan  (SF
461169689Skan   "@
462169689Skan    ldfs.c.clr %0 = %1%P1
463169689Skan    ld4.c.clr%O1 %0 = %1%P1")
464169689Skan  (DF
465169689Skan   "@
466169689Skan    ldfd.c.clr %0 = %1%P1
467169689Skan    ld8.c.clr%O1 %0 = %1%P1")
468169689Skan  (XF "ldfe.c.clr %0 = %1%P1")
469169689Skan  (TI "ldfp8.c.clr %X0 = %1%P1")])
470169689Skan
471169689Skan(define_mode_attr ld_reg_constr [(BI "=*r") (QI "=r") (HI "=r") (SI "=r") (DI "=r,*f") (SF "=f,*r") (DF "=f,*r") (XF "=f") (TI "=*x")])
472169689Skan(define_mode_attr ldc_reg_constr [(BI "+*r") (QI "+r") (HI "+r") (SI "+r") (DI "+r,*f") (SF "+f,*r") (DF "+f,*r") (XF "+f") (TI "+*x")])
473169689Skan(define_mode_attr chk_reg_constr [(BI "*r") (QI "r") (HI "r") (SI "r") (DI "r,*f") (SF "f,*r") (DF "f,*r") (XF "f") (TI "*x")])
474169689Skan
475169689Skan(define_mode_attr mem_constr [(BI "*m") (QI "m") (HI "m") (SI "m") (DI "m,Q") (SF "Q,m") (DF "Q,m") (XF "m") (TI "Q")])
476169689Skan
477169689Skan;; Define register predicate prefix.
478169689Skan;; We can generate speculative loads only for general and fp registers - this
479169689Skan;; is constrainted in ia64.c: ia64_speculate_insn ().
480169689Skan(define_mode_attr reg_pred_prefix [(BI "gr") (QI "gr") (HI "gr") (SI "gr") (DI "grfr") (SF "grfr") (DF "grfr") (XF "fr") (TI "fr")])
481169689Skan
482169689Skan(define_mode_attr ld_class [(BI "ld") (QI "ld") (HI "ld") (SI "ld") (DI "ld,fld") (SF "fld,ld") (DF "fld,ld") (XF "fld") (TI "fldp")])
483169689Skan(define_mode_attr chka_class [(BI "chk_a") (QI "chk_a") (HI "chk_a") (SI "chk_a") (DI "chk_a,chk_a") (SF "chk_a,chk_a") (DF "chk_a,chk_a") (XF "chk_a") (TI "chk_a")])
484169689Skan(define_mode_attr chks_class [(BI "chk_s_i") (QI "chk_s_i") (HI "chk_s_i") (SI "chk_s_i") (DI "chk_s_i,chk_s_f") (SF "chk_s_f,chk_s_i") (DF "chk_s_f,chk_s_i") (XF "chk_s_f") (TI "chk_s_i")])
485169689Skan
486169689Skan(define_mode_attr attr_yes [(BI "yes") (QI "yes") (HI "yes") (SI "yes") (DI "yes,yes") (SF "yes,yes") (DF "yes,yes") (XF "yes") (TI "yes")])
487169689Skan
488169689Skan(define_insn "mov<mode>_advanced"
489169689Skan  [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>")
490169689Skan	(unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDA))]
491169689Skan  "ia64_move_ok (operands[0], operands[1])"
492169689Skan  "<output_a>"
493169689Skan  [(set_attr "itanium_class" "<ld_class>")
494169689Skan   (set_attr "data_speculative" "<attr_yes>")])
495169689Skan
496169689Skan(define_insn "zero_extend<mode>di2_advanced"
497169689Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
498169689Skan	(zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDA)))]
499169689Skan  ""
500169689Skan  "<output_a>"
501169689Skan  [(set_attr "itanium_class" "<ld_class>")
502169689Skan   (set_attr "data_speculative" "<attr_yes>")])
503169689Skan
504169689Skan(define_insn "mov<mode>_speculative"
505169689Skan  [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>")
506169689Skan	(unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS))]
507169689Skan  "ia64_move_ok (operands[0], operands[1])"
508169689Skan  "<output_s>"
509169689Skan  [(set_attr "itanium_class" "<ld_class>")
510169689Skan   (set_attr "control_speculative" "<attr_yes>")])
511169689Skan
512169689Skan(define_insn "zero_extend<mode>di2_speculative"
513169689Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
514169689Skan	(zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS)))]
515169689Skan  ""
516169689Skan  "<output_s>"
517169689Skan  [(set_attr "itanium_class" "<ld_class>")
518169689Skan   (set_attr "control_speculative" "<attr_yes>")])
519169689Skan
520169689Skan(define_insn "mov<mode>_speculative_advanced"
521169689Skan  [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>")
522169689Skan	(unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDSA))]
523169689Skan  "ia64_move_ok (operands[0], operands[1])"
524169689Skan  "<output_sa>"
525169689Skan  [(set_attr "itanium_class" "<ld_class>")
526169689Skan   (set_attr "data_speculative" "<attr_yes>")
527169689Skan   (set_attr "control_speculative" "<attr_yes>")])
528169689Skan
529169689Skan(define_insn "zero_extend<mode>di2_speculative_advanced"
530169689Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
531169689Skan	(zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDSA)))]
532169689Skan  ""
533169689Skan  "<output_sa>"
534169689Skan  [(set_attr "itanium_class" "<ld_class>")
535169689Skan   (set_attr "data_speculative" "<attr_yes>")
536169689Skan   (set_attr "control_speculative" "<attr_yes>")])
537169689Skan
538169689Skan(define_insn "mov<mode>_clr"
539169689Skan  [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ldc_reg_constr>")
540169689Skan	(if_then_else:MODE (ne (unspec [(match_dup 0)] UNSPEC_LDCCLR) (const_int 0))
541169689Skan			   (match_operand:MODE 1 "memory_operand" "<mem_constr>")
542169689Skan			   (match_dup 0)))]
543169689Skan  "ia64_move_ok (operands[0], operands[1])"
544169689Skan  "<output_c_clr>"
545169689Skan  [(set_attr "itanium_class" "<ld_class>")
546169689Skan   (set_attr "check_load" "<attr_yes>")])
547169689Skan
548169689Skan(define_insn "zero_extend<mode>di2_clr"
549169689Skan  [(set (match_operand:DI 0 "gr_register_operand" "+r")
550169689Skan	(if_then_else:DI (ne (unspec [(match_dup 0)] UNSPEC_LDCCLR) (const_int 0))
551169689Skan			 (zero_extend:DI (match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>"))
552169689Skan			 (match_dup 0)))]
553169689Skan  ""
554169689Skan  "<output_c_clr>"
555169689Skan  [(set_attr "itanium_class" "<ld_class>")
556169689Skan   (set_attr "check_load" "<attr_yes>")])
557169689Skan
558169689Skan(define_insn "advanced_load_check_clr_<mode>"
559169689Skan  [(set (pc)
560169689Skan        (if_then_else (ne (unspec [(match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<chk_reg_constr>")] UNSPEC_CHKACLR) (const_int 0))
561169689Skan                      (pc)
562169689Skan                      (label_ref (match_operand 1 "" ""))))]
563169689Skan  ""
564169689Skan  "chk.a.clr %0, %l1"
565169689Skan  [(set_attr "itanium_class" "<chka_class>")])
566169689Skan
567169689Skan(define_insn "speculation_check_<mode>"
568169689Skan  [(set (pc) 
569169689Skan        (if_then_else (ne (unspec [(match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<chk_reg_constr>")] UNSPEC_CHKS) (const_int 0))
570169689Skan                      (pc)
571169689Skan                      (label_ref (match_operand 1 "" ""))))]
572169689Skan  ""
573169689Skan  "chk.s %0, %l1"
574169689Skan  [(set_attr "itanium_class" "<chks_class>")])
575169689Skan
57690075Sobrien(define_split
577132718Skan  [(set (match_operand 0 "register_operand" "")
578132718Skan	(match_operand 1 "symbolic_operand" ""))]
579169689Skan  "reload_completed"
58090075Sobrien  [(const_int 0)]
58190075Sobrien{
582169689Skan  if (ia64_expand_load_address (operands[0], operands[1]))
583169689Skan    DONE;
584169689Skan  else
585169689Skan    FAIL;
586117395Skan})
58790075Sobrien
58890075Sobrien(define_expand "load_fptr"
589169689Skan  [(set (match_operand:DI 0 "register_operand" "")
590169689Skan	(plus:DI (match_dup 2) (match_operand 1 "function_operand" "")))
591169689Skan   (set (match_dup 0) (match_dup 3))]
592169689Skan  "reload_completed"
59390075Sobrien{
594169689Skan  operands[2] = pic_offset_table_rtx;
595169689Skan  operands[3] = gen_const_mem (DImode, operands[0]);
596117395Skan})
59790075Sobrien
59890075Sobrien(define_insn "*load_fptr_internal1"
59990075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
600117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
601169689Skan  "reload_completed"
60290075Sobrien  "addl %0 = @ltoff(@fptr(%1)), gp"
60390075Sobrien  [(set_attr "itanium_class" "ialu")])
60490075Sobrien
60590075Sobrien(define_insn "load_gprel"
60690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
607117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
608169689Skan  "reload_completed"
60990075Sobrien  "addl %0 = @gprel(%1), gp"
61090075Sobrien  [(set_attr "itanium_class" "ialu")])
61190075Sobrien
612169689Skan(define_insn "*gprel64_offset"
61390075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
61490075Sobrien	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
615169689Skan  "reload_completed"
61690075Sobrien  "movl %0 = @gprel(%1)"
61790075Sobrien  [(set_attr "itanium_class" "long_i")])
61890075Sobrien
61990075Sobrien(define_expand "load_gprel64"
620169689Skan  [(set (match_operand:DI 0 "register_operand" "")
621169689Skan	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 2)))
622169689Skan   (set (match_dup 0)
623169689Skan	(plus:DI (match_dup 2) (match_dup 0)))]
624169689Skan  "reload_completed"
62590075Sobrien{
626169689Skan  operands[2] = pic_offset_table_rtx;
627117395Skan})
62890075Sobrien
629132718Skan;; This is used as a placeholder for the return address during early
630132718Skan;; compilation.  We won't know where we've placed this until during
631132718Skan;; reload, at which point it can wind up in b0, a general register,
632132718Skan;; or memory.  The only safe destination under these conditions is a
633132718Skan;; general register.
634132718Skan
635132718Skan(define_insn_and_split "*movdi_ret_addr"
636132718Skan  [(set (match_operand:DI 0 "register_operand" "=r")
637132718Skan	(unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
63890075Sobrien  ""
639132718Skan  "#"
640132718Skan  "reload_completed"
641132718Skan  [(const_int 0)]
64290075Sobrien{
643132718Skan  ia64_split_return_addr_rtx (operands[0]);
644132718Skan  DONE;
645132718Skan}
646132718Skan  [(set_attr "itanium_class" "ialu")])
64790075Sobrien
648117395Skan(define_insn "*load_symptr_high"
64990075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
650117395Skan	(plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
651117395Skan		 (match_operand:DI 2 "register_operand" "a")))]
652169689Skan  "reload_completed"
653117395Skan{
654117395Skan  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
655117395Skan    return "%,addl %0 = @ltoffx(%1), %2";
656117395Skan  else
657117395Skan    return "%,addl %0 = @ltoff(%1), %2";
658117395Skan}
65990075Sobrien  [(set_attr "itanium_class" "ialu")])
66090075Sobrien
661117395Skan(define_insn "*load_symptr_low"
662117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
663117395Skan	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
664117395Skan		   (match_operand 2 "got_symbolic_operand" "s")))]
665169689Skan  "reload_completed"
666117395Skan{
667117395Skan  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
668117395Skan    return "%,ld8.mov %0 = [%1], %2";
669117395Skan  else
670117395Skan    return "%,ld8 %0 = [%1]";
671117395Skan}
672117395Skan  [(set_attr "itanium_class" "ld")])
673117395Skan
674169689Skan(define_insn_and_split "load_dtpmod"
675117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
676169689Skan	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
677169689Skan		   UNSPEC_DTPMOD))]
678117395Skan  ""
679169689Skan  "#"
680169689Skan  "reload_completed"
681169689Skan  [(set (match_dup 0)
682169689Skan	(plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPMOD)
683169689Skan		 (match_dup 2)))
684169689Skan   (set (match_dup 0) (match_dup 3))]
685169689Skan{
686169689Skan  operands[2] = pic_offset_table_rtx;
687169689Skan  operands[3] = gen_const_mem (DImode, operands[0]);
688169689Skan})
689117395Skan
690169689Skan(define_insn "*load_ltoff_dtpmod"
691117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
692169689Skan	(plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
693169689Skan			    UNSPEC_LTOFF_DTPMOD)
694169689Skan		 (match_operand:DI 2 "register_operand" "a")))]
695169689Skan  "reload_completed"
696169689Skan  "addl %0 = @ltoff(@dtpmod(%1)), %2"
697117395Skan  [(set_attr "itanium_class" "ialu")])
698117395Skan
699117395Skan(define_expand "load_dtprel"
700117395Skan  [(set (match_operand:DI 0 "register_operand" "")
701169689Skan	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
702117395Skan		   UNSPEC_DTPREL))]
703117395Skan  ""
704117395Skan  "")
705117395Skan
706117395Skan(define_insn "*load_dtprel64"
707117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
708169689Skan	(unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
709117395Skan		   UNSPEC_DTPREL))]
710117395Skan  "TARGET_TLS64"
711117395Skan  "movl %0 = @dtprel(%1)"
712117395Skan  [(set_attr "itanium_class" "long_i")])
713117395Skan
714117395Skan(define_insn "*load_dtprel22"
715117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
716169689Skan	(unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
717117395Skan		   UNSPEC_DTPREL))]
718117395Skan  ""
719117395Skan  "addl %0 = @dtprel(%1), r0"
720117395Skan  [(set_attr "itanium_class" "ialu")])
721117395Skan
722169689Skan(define_insn_and_split "*load_dtprel_gd"
723169689Skan  [(set (match_operand:DI 0 "register_operand" "=r")
724169689Skan	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
725169689Skan		   UNSPEC_DTPREL))]
726169689Skan  ""
727169689Skan  "#"
728169689Skan  "reload_completed"
729169689Skan  [(set (match_dup 0)
730169689Skan	(plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPREL)
731169689Skan		 (match_dup 2)))
732169689Skan   (set (match_dup 0) (match_dup 3))]
733169689Skan{
734169689Skan  operands[2] = pic_offset_table_rtx;
735169689Skan  operands[3] = gen_const_mem (DImode, operands[0]);
736169689Skan})
737169689Skan
738169689Skan(define_insn "*load_ltoff_dtprel"
739169689Skan  [(set (match_operand:DI 0 "register_operand" "=r")
740169689Skan	(plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
741169689Skan			    UNSPEC_LTOFF_DTPREL)
742169689Skan		 (match_operand:DI 2 "register_operand" "a")))]
743169689Skan  ""
744169689Skan  "addl %0 = @ltoff(@dtprel(%1)), %2"
745169689Skan  [(set_attr "itanium_class" "ialu")])
746169689Skan
747117395Skan(define_expand "add_dtprel"
748117395Skan  [(set (match_operand:DI 0 "register_operand" "")
749169689Skan	(plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
750169689Skan			    UNSPEC_DTPREL)
751169689Skan		 (match_operand:DI 2 "register_operand" "")))]
752117395Skan  "!TARGET_TLS64"
753117395Skan  "")
754117395Skan
755117395Skan(define_insn "*add_dtprel14"
756117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
757169689Skan	(plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
758169689Skan			    UNSPEC_DTPREL)
759169689Skan		 (match_operand:DI 2 "register_operand" "r")))]
760117395Skan  "TARGET_TLS14"
761169689Skan  "adds %0 = @dtprel(%1), %2"
762117395Skan  [(set_attr "itanium_class" "ialu")])
763117395Skan
764117395Skan(define_insn "*add_dtprel22"
765117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
766169689Skan	(plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")]
767169689Skan			    UNSPEC_DTPREL)
768169689Skan		 (match_operand:DI 2 "register_operand" "a")))]
769117395Skan  "TARGET_TLS22"
770169689Skan  "addl %0 = @dtprel(%1), %2"
771117395Skan  [(set_attr "itanium_class" "ialu")])
772117395Skan
773117395Skan(define_expand "load_tprel"
774117395Skan  [(set (match_operand:DI 0 "register_operand" "")
775169689Skan	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
776117395Skan		   UNSPEC_TPREL))]
777117395Skan  ""
778117395Skan  "")
779117395Skan
780117395Skan(define_insn "*load_tprel64"
781117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
782169689Skan	(unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
783117395Skan		   UNSPEC_TPREL))]
784117395Skan  "TARGET_TLS64"
785117395Skan  "movl %0 = @tprel(%1)"
786117395Skan  [(set_attr "itanium_class" "long_i")])
787117395Skan
788117395Skan(define_insn "*load_tprel22"
789117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
790169689Skan	(unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
791117395Skan		   UNSPEC_TPREL))]
792117395Skan  ""
793117395Skan  "addl %0 = @tprel(%1), r0"
794117395Skan  [(set_attr "itanium_class" "ialu")])
795117395Skan
796169689Skan(define_insn_and_split "*load_tprel_ie"
797169689Skan  [(set (match_operand:DI 0 "register_operand" "=r")
798169689Skan	(unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")]
799169689Skan		   UNSPEC_TPREL))]
800169689Skan  ""
801169689Skan  "#"
802169689Skan  "reload_completed"
803169689Skan  [(set (match_dup 0)
804169689Skan	(plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_TPREL)
805169689Skan		 (match_dup 2)))
806169689Skan   (set (match_dup 0) (match_dup 3))]
807169689Skan{
808169689Skan  operands[2] = pic_offset_table_rtx;
809169689Skan  operands[3] = gen_const_mem (DImode, operands[0]);
810169689Skan})
811169689Skan
812169689Skan(define_insn "*load_ltoff_tprel"
813169689Skan  [(set (match_operand:DI 0 "register_operand" "=r")
814169689Skan	(plus:DI (unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")]
815169689Skan			    UNSPEC_LTOFF_TPREL)
816169689Skan		 (match_operand:DI 2 "register_operand" "a")))]
817169689Skan  ""
818169689Skan  "addl %0 = @ltoff(@tprel(%1)), %2"
819169689Skan  [(set_attr "itanium_class" "ialu")])
820169689Skan
821117395Skan(define_expand "add_tprel"
822117395Skan  [(set (match_operand:DI 0 "register_operand" "")
823169689Skan	(plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
824169689Skan			    UNSPEC_TPREL)
825169689Skan		 (match_operand:DI 2 "register_operand" "")))]
826117395Skan  "!TARGET_TLS64"
827117395Skan  "")
828117395Skan
829117395Skan(define_insn "*add_tprel14"
830117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
831169689Skan	(plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
832169689Skan			    UNSPEC_TPREL)
833169689Skan		 (match_operand:DI 2 "register_operand" "r")))]
834117395Skan  "TARGET_TLS14"
835169689Skan  "adds %0 = @tprel(%1), %2"
836117395Skan  [(set_attr "itanium_class" "ialu")])
837117395Skan
838117395Skan(define_insn "*add_tprel22"
839117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
840169689Skan	(plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")]
841169689Skan			    UNSPEC_TPREL)
842169689Skan		 (match_operand:DI 2 "register_operand" "a")))]
843117395Skan  "TARGET_TLS22"
844169689Skan  "addl %0 = @tprel(%1), %2"
845117395Skan  [(set_attr "itanium_class" "ialu")])
846117395Skan
84790075Sobrien;; With no offsettable memory references, we've got to have a scratch
848132718Skan;; around to play with the second word.  However, in order to avoid a
849132718Skan;; reload nightmare we lie, claim we don't need one, and fix it up
850132718Skan;; in ia64_split_tmode_move.
85190075Sobrien(define_expand "movti"
852132718Skan  [(set (match_operand:TI 0 "general_operand" "")
853132718Skan	(match_operand:TI 1 "general_operand" ""))]
85490075Sobrien  ""
85590075Sobrien{
856117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
857117395Skan  if (!op1)
858117395Skan    DONE;
859117395Skan  operands[1] = op1;
860117395Skan})
86190075Sobrien
86290075Sobrien(define_insn_and_split "*movti_internal"
863169689Skan  [(set (match_operand:TI 0 "destination_operand" "=r,   *fm,*x,*f,  Q")
864169689Skan	(match_operand:TI 1 "general_operand"     "r*fim,r,  Q, *fOQ,*f"))]
86590075Sobrien  "ia64_move_ok (operands[0], operands[1])"
866169689Skan  "@
867169689Skan   #
868169689Skan   #
869169689Skan   ldfp8 %X0 = %1%P1
870169689Skan   #
871169689Skan   #"
872169689Skan  "reload_completed && !ia64_load_pair_ok(operands[0], operands[1])"
87390075Sobrien  [(const_int 0)]
87490075Sobrien{
875132718Skan  ia64_split_tmode_move (operands);
87690075Sobrien  DONE;
877117395Skan}
878169689Skan  [(set_attr "itanium_class" "unknown,unknown,fldp,unknown,unknown")])
87990075Sobrien
88090075Sobrien;; Floating Point Moves
88190075Sobrien;;
88290075Sobrien;; Note - Patterns for SF mode moves are compulsory, but
883117395Skan;; patterns for DF are optional, as GCC can synthesize them.
88490075Sobrien
88590075Sobrien(define_expand "movsf"
88690075Sobrien  [(set (match_operand:SF 0 "general_operand" "")
88790075Sobrien	(match_operand:SF 1 "general_operand" ""))]
88890075Sobrien  ""
88990075Sobrien{
890117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
891117395Skan  if (!op1)
892117395Skan    DONE;
893117395Skan  operands[1] = op1;
894117395Skan})
89590075Sobrien
89690075Sobrien(define_insn "*movsf_internal"
89790075Sobrien  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
89890075Sobrien	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
89990075Sobrien  "ia64_move_ok (operands[0], operands[1])"
90090075Sobrien  "@
901117395Skan   mov %0 = %F1
902117395Skan   ldfs %0 = %1%P1
903117395Skan   stfs %0 = %F1%P0
904117395Skan   getf.s %0 = %F1
905117395Skan   setf.s %0 = %1
906117395Skan   mov %0 = %1
907117395Skan   ld4%O1 %0 = %1%P1
908117395Skan   st4%Q0 %0 = %1%P0"
90990075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
91090075Sobrien
91190075Sobrien(define_expand "movdf"
91290075Sobrien  [(set (match_operand:DF 0 "general_operand" "")
91390075Sobrien	(match_operand:DF 1 "general_operand" ""))]
91490075Sobrien  ""
91590075Sobrien{
916117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
917117395Skan  if (!op1)
918117395Skan    DONE;
919117395Skan  operands[1] = op1;
920117395Skan})
92190075Sobrien
92290075Sobrien(define_insn "*movdf_internal"
92390075Sobrien  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
92490075Sobrien	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
92590075Sobrien  "ia64_move_ok (operands[0], operands[1])"
92690075Sobrien  "@
927117395Skan   mov %0 = %F1
928117395Skan   ldfd %0 = %1%P1
929117395Skan   stfd %0 = %F1%P0
930117395Skan   getf.d %0 = %F1
931117395Skan   setf.d %0 = %1
932117395Skan   mov %0 = %1
933117395Skan   ld8%O1 %0 = %1%P1
934117395Skan   st8%Q0 %0 = %1%P0"
93590075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
93690075Sobrien
93790075Sobrien;; With no offsettable memory references, we've got to have a scratch
93890075Sobrien;; around to play with the second word if the variable winds up in GRs.
939132718Skan(define_expand "movxf"
940132718Skan  [(set (match_operand:XF 0 "general_operand" "")
941132718Skan	(match_operand:XF 1 "general_operand" ""))]
942132718Skan  ""
94390075Sobrien{
944169689Skan  if (ia64_expand_movxf_movrf (XFmode, operands))
945169689Skan    DONE;
946117395Skan})
94790075Sobrien
94890075Sobrien;; ??? There's no easy way to mind volatile acquire/release semantics.
94990075Sobrien
950132718Skan(define_insn "*movxf_internal"
951169689Skan  [(set (match_operand:XF 0 "destination_operand" "=f,f, m")
952169689Skan	(match_operand:XF 1 "general_operand"     "fG,m,fG"))]
953132718Skan  "ia64_move_ok (operands[0], operands[1])"
95490075Sobrien  "@
955117395Skan   mov %0 = %F1
956117395Skan   ldfe %0 = %1%P1
957117395Skan   stfe %0 = %F1%P0"
95890075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf")])
959132718Skan
960169689Skan;; Same as for movxf, but for RFmode.
961169689Skan(define_expand "movrf"
962169689Skan  [(set (match_operand:RF 0 "general_operand" "")
963169689Skan	(match_operand:RF 1 "general_operand" ""))]
964169689Skan  ""
965169689Skan{
966169689Skan  if (ia64_expand_movxf_movrf (RFmode, operands))
967169689Skan    DONE;
968169689Skan})
969169689Skan
970169689Skan(define_insn "*movrf_internal"
971169689Skan  [(set (match_operand:RF 0 "destination_operand" "=f,f, m")
972169689Skan	(match_operand:RF 1 "general_operand"     "fG,m,fG"))]
973169689Skan  "ia64_move_ok (operands[0], operands[1])"
974169689Skan  "@
975169689Skan   mov %0 = %F1
976169689Skan   ldf.fill %0 = %1%P1
977169689Skan   stf.spill %0 = %F1%P0"
978169689Skan  [(set_attr "itanium_class" "fmisc,fld,stf")])
979169689Skan
980132718Skan;; Better code generation via insns that deal with TFmode register pairs
981132718Skan;; directly.  Same concerns apply as for TImode.
982132718Skan(define_expand "movtf"
983132718Skan  [(set (match_operand:TF 0 "general_operand" "")
984132718Skan	(match_operand:TF 1 "general_operand" ""))]
985132718Skan  ""
986132718Skan{
987132718Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
988132718Skan  if (!op1)
989132718Skan    DONE;
990132718Skan  operands[1] = op1;
991132718Skan})
992132718Skan
993132718Skan(define_insn_and_split "*movtf_internal"
994169689Skan  [(set (match_operand:TF 0 "destination_operand"  "=r,r,m")
995132718Skan	(match_operand:TF 1 "general_operand"      "ri,m,r"))]
996132718Skan  "ia64_move_ok (operands[0], operands[1])"
997132718Skan  "#"
998132718Skan  "reload_completed"
999132718Skan  [(const_int 0)]
1000132718Skan{
1001132718Skan  ia64_split_tmode_move (operands);
1002132718Skan  DONE;
1003132718Skan}
1004132718Skan  [(set_attr "itanium_class" "unknown")
1005132718Skan   (set_attr "predicable" "no")])
1006132718Skan
100790075Sobrien
100890075Sobrien;; ::::::::::::::::::::
100990075Sobrien;; ::
101090075Sobrien;; :: Conversions
101190075Sobrien;; ::
101290075Sobrien;; ::::::::::::::::::::
101390075Sobrien
101490075Sobrien;; Signed conversions from a smaller integer to a larger integer
101590075Sobrien
101690075Sobrien(define_insn "extendqidi2"
101790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
101890075Sobrien	(sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
101990075Sobrien  ""
102090075Sobrien  "sxt1 %0 = %1"
102190075Sobrien  [(set_attr "itanium_class" "xtd")])
102290075Sobrien
102390075Sobrien(define_insn "extendhidi2"
102490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
102590075Sobrien	(sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
102690075Sobrien  ""
102790075Sobrien  "sxt2 %0 = %1"
102890075Sobrien  [(set_attr "itanium_class" "xtd")])
102990075Sobrien
103090075Sobrien(define_insn "extendsidi2"
103190075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
103290075Sobrien	(sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
103390075Sobrien  ""
103490075Sobrien  "@
103590075Sobrien   sxt4 %0 = %1
103690075Sobrien   fsxt.r %0 = %1, %1"
103790075Sobrien  [(set_attr "itanium_class" "xtd,fmisc")])
103890075Sobrien
103990075Sobrien;; Unsigned conversions from a smaller integer to a larger integer
104090075Sobrien
104190075Sobrien(define_insn "zero_extendqidi2"
104290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
104390075Sobrien	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
104490075Sobrien  ""
104590075Sobrien  "@
104690075Sobrien   zxt1 %0 = %1
104790075Sobrien   ld1%O1 %0 = %1%P1"
104890075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
104990075Sobrien
105090075Sobrien(define_insn "zero_extendhidi2"
105190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
105290075Sobrien	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
105390075Sobrien  ""
105490075Sobrien  "@
105590075Sobrien   zxt2 %0 = %1
105690075Sobrien   ld2%O1 %0 = %1%P1"
105790075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
105890075Sobrien
105990075Sobrien(define_insn "zero_extendsidi2"
106090075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
106190075Sobrien	(zero_extend:DI
106290075Sobrien	  (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
106390075Sobrien  ""
106490075Sobrien  "@
1065169689Skan   addp4 %0 = %1, r0
106690075Sobrien   ld4%O1 %0 = %1%P1
106790075Sobrien   fmix.r %0 = f0, %1"
1068169689Skan  [(set_attr "itanium_class" "ialu,ld,fmisc")])
106990075Sobrien
107090075Sobrien;; Convert between floating point types of different sizes.
107190075Sobrien
107290075Sobrien;; At first glance, it would appear that emitting fnorm for an extending
107390075Sobrien;; conversion is unnecessary.  However, the stf and getf instructions work
107490075Sobrien;; correctly only if the input is properly rounded for its type.  In
107590075Sobrien;; particular, we get the wrong result for getf.d/stfd if the input is a
107690075Sobrien;; denorm single.  Since we don't know what the next instruction will be, we
107790075Sobrien;; have to emit an fnorm.
107890075Sobrien
107990075Sobrien;; ??? Optimization opportunity here.  Get rid of the insn altogether
108090075Sobrien;; when we can.  Should probably use a scheme like has been proposed
108190075Sobrien;; for ia32 in dealing with operands that match unary operators.  This
108290075Sobrien;; would let combine merge the thing into adjacent insns.  See also how the
108390075Sobrien;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
108490075Sobrien;; se_register_operand.
108590075Sobrien
108690075Sobrien(define_insn "extendsfdf2"
108790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
108890075Sobrien	(float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
108990075Sobrien  ""
109090075Sobrien  "fnorm.d %0 = %1"
109190075Sobrien  [(set_attr "itanium_class" "fmac")])
109290075Sobrien
1093132718Skan(define_insn "extendsfxf2"
1094132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
1095132718Skan	(float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]
1096132718Skan  ""
109790075Sobrien  "fnorm %0 = %1"
109890075Sobrien  [(set_attr "itanium_class" "fmac")])
109990075Sobrien
1100132718Skan(define_insn "extenddfxf2"
1101132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
1102132718Skan	(float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]
1103132718Skan  ""
110490075Sobrien  "fnorm %0 = %1"
110590075Sobrien  [(set_attr "itanium_class" "fmac")])
110690075Sobrien
110790075Sobrien(define_insn "truncdfsf2"
110890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
110990075Sobrien	(float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
111090075Sobrien  ""
111190075Sobrien  "fnorm.s %0 = %1"
111290075Sobrien  [(set_attr "itanium_class" "fmac")])
111390075Sobrien
1114132718Skan(define_insn "truncxfsf2"
111590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
1116132718Skan	(float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]
1117132718Skan  ""
111890075Sobrien  "fnorm.s %0 = %1"
111990075Sobrien  [(set_attr "itanium_class" "fmac")])
112090075Sobrien
1121132718Skan(define_insn "truncxfdf2"
112290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
1123132718Skan	(float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]
1124132718Skan  ""
112590075Sobrien  "fnorm.d %0 = %1"
112690075Sobrien  [(set_attr "itanium_class" "fmac")])
112790075Sobrien
112890075Sobrien;; Convert between signed integer types and floating point.
112990075Sobrien
1130132718Skan(define_insn "floatdixf2"
1131132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
1132132718Skan	(float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
1133132718Skan  ""
113490075Sobrien  "fcvt.xf %0 = %1"
113590075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
113690075Sobrien
113790075Sobrien(define_insn "fix_truncsfdi2"
113890075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
113990075Sobrien	(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
114090075Sobrien  ""
114190075Sobrien  "fcvt.fx.trunc %0 = %1"
114290075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
114390075Sobrien
114490075Sobrien(define_insn "fix_truncdfdi2"
114590075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
114690075Sobrien	(fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
114790075Sobrien  ""
114890075Sobrien  "fcvt.fx.trunc %0 = %1"
114990075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
115090075Sobrien
1151132718Skan(define_insn "fix_truncxfdi2"
115290075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1153132718Skan	(fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
1154132718Skan  ""
115590075Sobrien  "fcvt.fx.trunc %0 = %1"
115690075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
115790075Sobrien
1158132718Skan(define_insn "fix_truncxfdi2_alts"
115990075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1160132718Skan	(fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
116190075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
1162132718Skan  ""
116390075Sobrien  "fcvt.fx.trunc.s%2 %0 = %1"
116490075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
116590075Sobrien
116690075Sobrien;; Convert between unsigned integer types and floating point.
116790075Sobrien
116890075Sobrien(define_insn "floatunsdisf2"
116990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
117090075Sobrien	(unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
117190075Sobrien  ""
117290075Sobrien  "fcvt.xuf.s %0 = %1"
117390075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
117490075Sobrien
117590075Sobrien(define_insn "floatunsdidf2"
117690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
117790075Sobrien	(unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
117890075Sobrien  ""
117990075Sobrien  "fcvt.xuf.d %0 = %1"
118090075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
118190075Sobrien
1182132718Skan(define_insn "floatunsdixf2"
1183132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
1184132718Skan	(unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
1185132718Skan  ""
118690075Sobrien  "fcvt.xuf %0 = %1"
118790075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
118890075Sobrien
118990075Sobrien(define_insn "fixuns_truncsfdi2"
119090075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
119190075Sobrien	(unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
119290075Sobrien  ""
119390075Sobrien  "fcvt.fxu.trunc %0 = %1"
119490075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
119590075Sobrien
119690075Sobrien(define_insn "fixuns_truncdfdi2"
119790075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
119890075Sobrien	(unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
119990075Sobrien  ""
120090075Sobrien  "fcvt.fxu.trunc %0 = %1"
120190075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
120290075Sobrien
1203132718Skan(define_insn "fixuns_truncxfdi2"
120490075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1205132718Skan	(unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
1206132718Skan  ""
120790075Sobrien  "fcvt.fxu.trunc %0 = %1"
120890075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
120990075Sobrien
1210132718Skan(define_insn "fixuns_truncxfdi2_alts"
121190075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
1212132718Skan	(unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
121390075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
1214132718Skan  ""
121590075Sobrien  "fcvt.fxu.trunc.s%2 %0 = %1"
121690075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
121790075Sobrien
121890075Sobrien;; ::::::::::::::::::::
121990075Sobrien;; ::
122090075Sobrien;; :: Bit field extraction
122190075Sobrien;; ::
122290075Sobrien;; ::::::::::::::::::::
122390075Sobrien
122490075Sobrien(define_insn "extv"
122590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
122690075Sobrien	(sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1227169689Skan			 (match_operand:DI 2 "extr_len_operand" "n")
1228169689Skan			 (match_operand:DI 3 "shift_count_operand" "M")))]
122990075Sobrien  ""
123090075Sobrien  "extr %0 = %1, %3, %2"
123190075Sobrien  [(set_attr "itanium_class" "ishf")])
123290075Sobrien
123390075Sobrien(define_insn "extzv"
123490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
123590075Sobrien	(zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1236169689Skan			 (match_operand:DI 2 "extr_len_operand" "n")
1237169689Skan			 (match_operand:DI 3 "shift_count_operand" "M")))]
123890075Sobrien  ""
123990075Sobrien  "extr.u %0 = %1, %3, %2"
124090075Sobrien  [(set_attr "itanium_class" "ishf")])
124190075Sobrien
124290075Sobrien;; Insert a bit field.
124390075Sobrien;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
124490075Sobrien;; Source1 can be 0 or -1.
124590075Sobrien;; Source2 can be 0.
124690075Sobrien
124790075Sobrien;; ??? Actual dep instruction is more powerful than what these insv
124890075Sobrien;; patterns support.  Unfortunately, combine is unable to create patterns
124990075Sobrien;; where source2 != dest.
125090075Sobrien
125190075Sobrien(define_expand "insv"
125290075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
125390075Sobrien			 (match_operand:DI 1 "const_int_operand" "")
125490075Sobrien			 (match_operand:DI 2 "const_int_operand" ""))
125590075Sobrien	(match_operand:DI 3 "nonmemory_operand" ""))]
125690075Sobrien  ""
125790075Sobrien{
125890075Sobrien  int width = INTVAL (operands[1]);
125990075Sobrien  int shift = INTVAL (operands[2]);
126090075Sobrien
126190075Sobrien  /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
126290075Sobrien     pseudo.  */
126390075Sobrien  if (! register_operand (operands[3], DImode)
126490075Sobrien      && operands[3] != const0_rtx && operands[3] != constm1_rtx)
126590075Sobrien    operands[3] = force_reg (DImode, operands[3]);
126690075Sobrien
126790075Sobrien  /* If this is a single dep instruction, we have nothing to do.  */
126890075Sobrien  if (! ((register_operand (operands[3], DImode) && width <= 16)
126990075Sobrien	 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
127090075Sobrien    {
127190075Sobrien      /* Check for cases that can be implemented with a mix instruction.  */
127290075Sobrien      if (width == 32 && shift == 0)
127390075Sobrien	{
127490075Sobrien	  /* Directly generating the mix4left instruction confuses
127590075Sobrien	     optimize_bit_field in function.c.  Since this is performing
127690075Sobrien	     a useful optimization, we defer generation of the complicated
127790075Sobrien	     mix4left RTL to the first splitting phase.  */
127890075Sobrien	  rtx tmp = gen_reg_rtx (DImode);
127990075Sobrien	  emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
128090075Sobrien	  DONE;
128190075Sobrien	}
128290075Sobrien      else if (width == 32 && shift == 32)
128390075Sobrien	{
128490075Sobrien	  emit_insn (gen_mix4right (operands[0], operands[3]));
128590075Sobrien	  DONE;
128690075Sobrien	}
128790075Sobrien
128890075Sobrien      /* We could handle remaining cases by emitting multiple dep
128990075Sobrien	 instructions.
129090075Sobrien
129190075Sobrien	 If we need more than two dep instructions then we lose.  A 6
129290075Sobrien	 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
129390075Sobrien	 mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,
129490075Sobrien	 the latter is 6 cycles on an Itanium (TM) processor, because there is
129590075Sobrien	 only one function unit that can execute dep and shr immed.
129690075Sobrien
129790075Sobrien	 If we only need two dep instruction, then we still lose.
129890075Sobrien	 mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away
129990075Sobrien	 the unnecessary mov, this is still undesirable because it will be
130090075Sobrien	 hard to optimize, and it creates unnecessary pressure on the I0
130190075Sobrien	 function unit.  */
130290075Sobrien
130390075Sobrien      FAIL;
130490075Sobrien
130590075Sobrien#if 0
130690075Sobrien      /* This code may be useful for other IA-64 processors, so we leave it in
130790075Sobrien	 for now.  */
130890075Sobrien      while (width > 16)
130990075Sobrien	{
131090075Sobrien	  rtx tmp;
131190075Sobrien
131290075Sobrien	  emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
131390075Sobrien			       operands[3]));
131490075Sobrien	  shift += 16;
131590075Sobrien	  width -= 16;
131690075Sobrien	  tmp = gen_reg_rtx (DImode);
131790075Sobrien	  emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
131890075Sobrien	  operands[3] = tmp;
131990075Sobrien	}
132090075Sobrien      operands[1] = GEN_INT (width);
132190075Sobrien      operands[2] = GEN_INT (shift);
132290075Sobrien#endif
132390075Sobrien    }
1324117395Skan})
132590075Sobrien
132690075Sobrien(define_insn "*insv_internal"
132790075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
132890075Sobrien			 (match_operand:DI 1 "const_int_operand" "n")
132990075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
133090075Sobrien	(match_operand:DI 3 "nonmemory_operand" "rP"))]
133190075Sobrien  "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
133290075Sobrien   || operands[3] == const0_rtx || operands[3] == constm1_rtx"
133390075Sobrien  "dep %0 = %3, %0, %2, %1"
133490075Sobrien  [(set_attr "itanium_class" "ishf")])
133590075Sobrien
1336117395Skan;; Combine doesn't like to create bit-field insertions into zero.
1337169689Skan(define_insn "*shladdp4_internal"
1338169689Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
1339169689Skan	(and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1340169689Skan			   (match_operand:DI 2 "shladd_log2_operand" "n"))
1341169689Skan		(match_operand:DI 3 "const_int_operand" "n")))]
1342169689Skan  "ia64_depz_field_mask (operands[3], operands[2]) + INTVAL (operands[2]) == 32"
1343169689Skan  "shladdp4 %0 = %1, %2, r0"
1344169689Skan  [(set_attr "itanium_class" "ialu")])
1345169689Skan
134690075Sobrien(define_insn "*depz_internal"
134790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
134890075Sobrien	(and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
134990075Sobrien			   (match_operand:DI 2 "const_int_operand" "n"))
135090075Sobrien		(match_operand:DI 3 "const_int_operand" "n")))]
135190075Sobrien  "CONST_OK_FOR_M (INTVAL (operands[2]))
135290075Sobrien   && ia64_depz_field_mask (operands[3], operands[2]) > 0"
135390075Sobrien{
135490075Sobrien  operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1355117395Skan  return "%,dep.z %0 = %1, %2, %3";
1356117395Skan}
135790075Sobrien  [(set_attr "itanium_class" "ishf")])
135890075Sobrien
135990075Sobrien(define_insn "shift_mix4left"
136090075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
136190075Sobrien			 (const_int 32) (const_int 0))
136290075Sobrien	(match_operand:DI 1 "gr_register_operand" "r"))
136390075Sobrien   (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
136490075Sobrien  ""
136590075Sobrien  "#"
136690075Sobrien  [(set_attr "itanium_class" "unknown")])
136790075Sobrien
136890075Sobrien(define_split
136990075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
137090075Sobrien			 (const_int 32) (const_int 0))
137190075Sobrien	(match_operand:DI 1 "register_operand" ""))
137290075Sobrien   (clobber (match_operand:DI 2 "register_operand" ""))]
1373169689Skan  ""
137490075Sobrien  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
137590075Sobrien   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
137690075Sobrien	(lshiftrt:DI (match_dup 3) (const_int 32)))]
137790075Sobrien  "operands[3] = operands[2];")
137890075Sobrien
137990075Sobrien(define_insn "*mix4left"
138090075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
138190075Sobrien			 (const_int 32) (const_int 0))
138290075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
138390075Sobrien		     (const_int 32)))]
138490075Sobrien  ""
138590075Sobrien  "mix4.l %0 = %0, %r1"
138690075Sobrien  [(set_attr "itanium_class" "mmshf")])
138790075Sobrien
138890075Sobrien(define_insn "mix4right"
138990075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
139090075Sobrien			 (const_int 32) (const_int 32))
139190075Sobrien	(match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
139290075Sobrien  ""
139390075Sobrien  "mix4.r %0 = %r1, %0"
139490075Sobrien  [(set_attr "itanium_class" "mmshf")])
139590075Sobrien
139690075Sobrien;; This is used by the rotrsi3 pattern.
139790075Sobrien
139890075Sobrien(define_insn "*mix4right_3op"
139990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
140090075Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
140190075Sobrien		(ashift:DI (zero_extend:DI
140290075Sobrien			     (match_operand:SI 2 "gr_register_operand" "r"))
140390075Sobrien			   (const_int 32))))]
140490075Sobrien  ""
140590075Sobrien  "mix4.r %0 = %2, %1"
140690075Sobrien  [(set_attr "itanium_class" "mmshf")])
140790075Sobrien
140890075Sobrien
140990075Sobrien;; ::::::::::::::::::::
141090075Sobrien;; ::
141190075Sobrien;; :: 1 bit Integer arithmetic
141290075Sobrien;; ::
141390075Sobrien;; ::::::::::::::::::::
141490075Sobrien
141590075Sobrien(define_insn_and_split "andbi3"
141690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
141790075Sobrien	(and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
141890075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
141990075Sobrien  ""
142090075Sobrien  "@
142190075Sobrien   #
142290075Sobrien   tbit.nz.and.orcm %0, %I0 = %2, 0
142390075Sobrien   and %0 = %2, %1"
142490075Sobrien  "reload_completed
142590075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
142690075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
142790075Sobrien  [(cond_exec (eq (match_dup 2) (const_int 0))
142890075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
142990075Sobrien				(match_dup 0))))]
143090075Sobrien  ""
143190075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
143290075Sobrien
143390075Sobrien(define_insn_and_split "*andcmbi3"
143490075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
143590075Sobrien	(and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
143690075Sobrien		(match_operand:BI 2 "register_operand" "0,0,r")))]
143790075Sobrien  ""
143890075Sobrien  "@
143990075Sobrien   #
144090075Sobrien   tbit.z.and.orcm %0, %I0 = %1, 0
144190075Sobrien   andcm %0 = %2, %1"
144290075Sobrien  "reload_completed
144390075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
144490075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
144590075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
144690075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
144790075Sobrien				(match_dup 0))))]
144890075Sobrien  ""
144990075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
145090075Sobrien
145190075Sobrien(define_insn_and_split "iorbi3"
145290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
145390075Sobrien	(ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
145490075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
145590075Sobrien  ""
145690075Sobrien  "@
145790075Sobrien   #
145890075Sobrien   tbit.nz.or.andcm %0, %I0 = %2, 0
145990075Sobrien   or %0 = %2, %1"
146090075Sobrien  "reload_completed
146190075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
146290075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
146390075Sobrien  [(cond_exec (ne (match_dup 2) (const_int 0))
146490075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
146590075Sobrien				(match_dup 0))))]
146690075Sobrien  ""
146790075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
146890075Sobrien
146990075Sobrien(define_insn_and_split "*iorcmbi3"
147090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c")
147190075Sobrien	(ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
147290075Sobrien		(match_operand:BI 2 "register_operand" "0,0")))]
147390075Sobrien  ""
147490075Sobrien  "@
147590075Sobrien   #
147690075Sobrien   tbit.z.or.andcm %0, %I0 = %1, 0"
147790075Sobrien  "reload_completed
147890075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
147990075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
148090075Sobrien  [(cond_exec (eq (match_dup 1) (const_int 0))
148190075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
148290075Sobrien				(match_dup 0))))]
148390075Sobrien  ""
148490075Sobrien  [(set_attr "itanium_class" "unknown,tbit")])
148590075Sobrien
148690075Sobrien(define_insn "one_cmplbi2"
148790075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
148890075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
148990075Sobrien   (clobber (match_scratch:BI 2 "=X,X,c,X"))]
149090075Sobrien  ""
149190075Sobrien  "@
149290075Sobrien   tbit.z %0, %I0 = %1, 0
149390075Sobrien   xor %0 = 1, %1
149490075Sobrien   #
149590075Sobrien   #"
149690075Sobrien  [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
149790075Sobrien
149890075Sobrien(define_split
149990075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
150090075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
150190075Sobrien   (clobber (match_scratch:BI 2 ""))]
150290075Sobrien  "reload_completed
150390075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
150490075Sobrien   && rtx_equal_p (operands[0], operands[1])"
150590075Sobrien  [(set (match_dup 4) (match_dup 3))
150690075Sobrien   (set (match_dup 0) (const_int 1))
150790075Sobrien   (cond_exec (ne (match_dup 2) (const_int 0))
150890075Sobrien     (set (match_dup 0) (const_int 0)))
1509117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
151090075Sobrien  "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
151190075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
151290075Sobrien
151390075Sobrien(define_split
151490075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
151590075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
151690075Sobrien   (clobber (match_scratch:BI 2 ""))]
151790075Sobrien  "reload_completed
151890075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
151990075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
152090075Sobrien   && ! rtx_equal_p (operands[0], operands[1])"
152190075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
152290075Sobrien     (set (match_dup 0) (const_int 0)))
152390075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
152490075Sobrien     (set (match_dup 0) (const_int 1)))
1525117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
152690075Sobrien  "")
152790075Sobrien
152890075Sobrien(define_insn "*cmpsi_and_0"
152990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
153090075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
153190075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
153290075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
153390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
153490075Sobrien  ""
153590075Sobrien  "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
153690075Sobrien  [(set_attr "itanium_class" "icmp")])
153790075Sobrien
153890075Sobrien(define_insn "*cmpsi_and_1"
153990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
154090075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
154190075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
154290075Sobrien		   (const_int 0)])
154390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
154490075Sobrien  ""
154590075Sobrien  "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
154690075Sobrien  [(set_attr "itanium_class" "icmp")])
154790075Sobrien
154890075Sobrien(define_insn "*cmpsi_andnot_0"
154990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
155090075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
155190075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
155290075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
155390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
155490075Sobrien  ""
155590075Sobrien  "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
155690075Sobrien  [(set_attr "itanium_class" "icmp")])
155790075Sobrien
155890075Sobrien(define_insn "*cmpsi_andnot_1"
155990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
156090075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
156190075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
156290075Sobrien			   (const_int 0)]))
156390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
156490075Sobrien  ""
156590075Sobrien  "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
156690075Sobrien  [(set_attr "itanium_class" "icmp")])
156790075Sobrien
156890075Sobrien(define_insn "*cmpdi_and_0"
156990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
157090075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
157190075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
157290075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
157390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
157490075Sobrien  ""
157590075Sobrien  "cmp.%C4.and.orcm %0, %I0 = %3, %2"
157690075Sobrien  [(set_attr "itanium_class" "icmp")])
157790075Sobrien
157890075Sobrien(define_insn "*cmpdi_and_1"
157990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
158090075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
158190075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
158290075Sobrien		   (const_int 0)])
158390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
158490075Sobrien  ""
158590075Sobrien  "cmp.%C3.and.orcm %0, %I0 = r0, %2"
158690075Sobrien  [(set_attr "itanium_class" "icmp")])
158790075Sobrien
158890075Sobrien(define_insn "*cmpdi_andnot_0"
158990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
159090075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
159190075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
159290075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
159390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
159490075Sobrien  ""
159590075Sobrien  "cmp.%C4.or.andcm %I0, %0 = %3, %2"
159690075Sobrien  [(set_attr "itanium_class" "icmp")])
159790075Sobrien
159890075Sobrien(define_insn "*cmpdi_andnot_1"
159990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
160090075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
160190075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
160290075Sobrien			   (const_int 0)]))
160390075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
160490075Sobrien  ""
160590075Sobrien  "cmp.%C3.or.andcm %I0, %0 = r0, %2"
160690075Sobrien  [(set_attr "itanium_class" "icmp")])
160790075Sobrien
160890075Sobrien(define_insn "*tbit_and_0"
160990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
161090075Sobrien	(and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
161190075Sobrien			       (const_int 1))
161290075Sobrien		       (const_int 0))
161390075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
161490075Sobrien  ""
161590075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, 0"
161690075Sobrien  [(set_attr "itanium_class" "tbit")])
161790075Sobrien
161890075Sobrien(define_insn "*tbit_and_1"
161990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
162090075Sobrien	(and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
162190075Sobrien			       (const_int 1))
162290075Sobrien		       (const_int 0))
162390075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
162490075Sobrien  ""
162590075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, 0"
162690075Sobrien  [(set_attr "itanium_class" "tbit")])
162790075Sobrien
162890075Sobrien(define_insn "*tbit_and_2"
162990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
163090075Sobrien	(and:BI (ne:BI (zero_extract:DI
163190075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
163290075Sobrien			 (const_int 1)
1633169689Skan			 (match_operand:DI 2 "shift_count_operand" "M"))
163490075Sobrien		       (const_int 0))
163590075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
163690075Sobrien  ""
163790075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, %2"
163890075Sobrien  [(set_attr "itanium_class" "tbit")])
163990075Sobrien
164090075Sobrien(define_insn "*tbit_and_3"
164190075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
164290075Sobrien	(and:BI (eq:BI (zero_extract:DI
164390075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
164490075Sobrien			 (const_int 1)
1645169689Skan			 (match_operand:DI 2 "shift_count_operand" "M"))
164690075Sobrien		       (const_int 0))
164790075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
164890075Sobrien  ""
164990075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, %2"
165090075Sobrien  [(set_attr "itanium_class" "tbit")])
165190075Sobrien
165290075Sobrien(define_insn "*cmpsi_or_0"
165390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
165490075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
165590075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
165690075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
165790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
165890075Sobrien  ""
165990075Sobrien  "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
166090075Sobrien  [(set_attr "itanium_class" "icmp")])
166190075Sobrien
166290075Sobrien(define_insn "*cmpsi_or_1"
166390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
166490075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
166590075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
166690075Sobrien		   (const_int 0)])
166790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
166890075Sobrien  ""
166990075Sobrien  "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
167090075Sobrien  [(set_attr "itanium_class" "icmp")])
167190075Sobrien
167290075Sobrien(define_insn "*cmpsi_orcm_0"
167390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
167490075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
167590075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
167690075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
167790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
167890075Sobrien  ""
167990075Sobrien  "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
168090075Sobrien  [(set_attr "itanium_class" "icmp")])
168190075Sobrien
168290075Sobrien(define_insn "*cmpsi_orcm_1"
168390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
168490075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
168590075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
168690075Sobrien			   (const_int 0)]))
168790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
168890075Sobrien  ""
168990075Sobrien  "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
169090075Sobrien  [(set_attr "itanium_class" "icmp")])
169190075Sobrien
169290075Sobrien(define_insn "*cmpdi_or_0"
169390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
169490075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
169590075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
169690075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
169790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
169890075Sobrien  ""
169990075Sobrien  "cmp.%C4.or.andcm %0, %I0 = %3, %2"
170090075Sobrien  [(set_attr "itanium_class" "icmp")])
170190075Sobrien
170290075Sobrien(define_insn "*cmpdi_or_1"
170390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
170490075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
170590075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
170690075Sobrien		   (const_int 0)])
170790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
170890075Sobrien  ""
170990075Sobrien  "cmp.%C3.or.andcm %0, %I0 = r0, %2"
171090075Sobrien  [(set_attr "itanium_class" "icmp")])
171190075Sobrien
171290075Sobrien(define_insn "*cmpdi_orcm_0"
171390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
171490075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
171590075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
171690075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
171790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
171890075Sobrien  ""
171990075Sobrien  "cmp.%C4.and.orcm %I0, %0 = %3, %2"
172090075Sobrien  [(set_attr "itanium_class" "icmp")])
172190075Sobrien
172290075Sobrien(define_insn "*cmpdi_orcm_1"
172390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
172490075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
172590075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
172690075Sobrien			   (const_int 0)]))
172790075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
172890075Sobrien  ""
172990075Sobrien  "cmp.%C3.and.orcm %I0, %0 = r0, %2"
173090075Sobrien  [(set_attr "itanium_class" "icmp")])
173190075Sobrien
173290075Sobrien(define_insn "*tbit_or_0"
173390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
173490075Sobrien	(ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
173590075Sobrien			       (const_int 1))
173690075Sobrien		       (const_int 0))
173790075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
173890075Sobrien  ""
173990075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, 0"
174090075Sobrien  [(set_attr "itanium_class" "tbit")])
174190075Sobrien
174290075Sobrien(define_insn "*tbit_or_1"
174390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
174490075Sobrien	(ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
174590075Sobrien			       (const_int 1))
174690075Sobrien		       (const_int 0))
174790075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
174890075Sobrien  ""
174990075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, 0"
175090075Sobrien  [(set_attr "itanium_class" "tbit")])
175190075Sobrien
175290075Sobrien(define_insn "*tbit_or_2"
175390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
175490075Sobrien	(ior:BI (ne:BI (zero_extract:DI
175590075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
175690075Sobrien			 (const_int 1)
1757169689Skan			 (match_operand:DI 2 "shift_count_operand" "M"))
175890075Sobrien		       (const_int 0))
175990075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
176090075Sobrien  ""
176190075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, %2"
176290075Sobrien  [(set_attr "itanium_class" "tbit")])
176390075Sobrien
176490075Sobrien(define_insn "*tbit_or_3"
176590075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
176690075Sobrien	(ior:BI (eq:BI (zero_extract:DI
176790075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
176890075Sobrien			 (const_int 1)
1769169689Skan			 (match_operand:DI 2 "shift_count_operand" "M"))
177090075Sobrien		       (const_int 0))
177190075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
177290075Sobrien  ""
177390075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, %2"
177490075Sobrien  [(set_attr "itanium_class" "tbit")])
177590075Sobrien
177690075Sobrien;; Transform test of and/or of setcc into parallel comparisons.
177790075Sobrien
177890075Sobrien(define_split
177990075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
178090075Sobrien	(ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
178190075Sobrien			      (const_int 0))
178290075Sobrien		       (match_operand:DI 3 "register_operand" ""))
178390075Sobrien	       (const_int 0)))]
178490075Sobrien  ""
178590075Sobrien  [(set (match_dup 0)
178690075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
178790075Sobrien		(match_dup 2)))]
178890075Sobrien  "")
178990075Sobrien
179090075Sobrien(define_split
179190075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
179290075Sobrien	(eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
179390075Sobrien			      (const_int 0))
179490075Sobrien		       (match_operand:DI 3 "register_operand" ""))
179590075Sobrien	       (const_int 0)))]
179690075Sobrien  ""
179790075Sobrien  [(set (match_dup 0)
179890075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
179990075Sobrien		(match_dup 2)))
180090075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
180190075Sobrien	      (clobber (scratch))])]
180290075Sobrien  "")
180390075Sobrien
180490075Sobrien(define_split
180590075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
180690075Sobrien	(ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
180790075Sobrien			      (const_int 0))
180890075Sobrien		       (match_operand:DI 3 "register_operand" ""))
180990075Sobrien	       (const_int 0)))]
181090075Sobrien  ""
181190075Sobrien  [(set (match_dup 0) 
181290075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
181390075Sobrien		(match_dup 2)))]
181490075Sobrien  "")
181590075Sobrien
181690075Sobrien(define_split
181790075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
181890075Sobrien	(eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
181990075Sobrien			      (const_int 0))
182090075Sobrien		       (match_operand:DI 3 "register_operand" ""))
182190075Sobrien	       (const_int 0)))]
182290075Sobrien  ""
182390075Sobrien  [(set (match_dup 0) 
182490075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
182590075Sobrien		(match_dup 2)))
182690075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
182790075Sobrien	      (clobber (scratch))])]
182890075Sobrien  "")
182990075Sobrien
183090075Sobrien;; ??? Incredibly hackish.  Either need four proper patterns with all
183190075Sobrien;; the alternatives, or rely on sched1 to split the insn and hope that
183290075Sobrien;; nothing bad happens to the comparisons in the meantime.
183390075Sobrien;;
183490075Sobrien;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
183590075Sobrien;; that we're doing height reduction.
183690075Sobrien;
183790075Sobrien;(define_insn_and_split ""
183890075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
183990075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
184090075Sobrien;			  [(match_operand 2 "" "")
184190075Sobrien;			   (match_operand 3 "" "")])
184290075Sobrien;			(match_operator:BI 4 "comparison_operator"
184390075Sobrien;			  [(match_operand 5 "" "")
184490075Sobrien;			   (match_operand 6 "" "")]))
184590075Sobrien;		(match_dup 0)))]
184690075Sobrien;  "flag_schedule_insns"
184790075Sobrien;  "#"
184890075Sobrien;  ""
184990075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
185090075Sobrien;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
185190075Sobrien;  "")
185290075Sobrien;
185390075Sobrien;(define_insn_and_split ""
185490075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
185590075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
185690075Sobrien;			  [(match_operand 2 "" "")
185790075Sobrien;			   (match_operand 3 "" "")])
185890075Sobrien;			(match_operator:BI 4 "comparison_operator"
185990075Sobrien;			  [(match_operand 5 "" "")
186090075Sobrien;			   (match_operand 6 "" "")]))
186190075Sobrien;		(match_dup 0)))]
186290075Sobrien;  "flag_schedule_insns"
186390075Sobrien;  "#"
186490075Sobrien;  ""
186590075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
186690075Sobrien;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
186790075Sobrien;  "")
186890075Sobrien;
186990075Sobrien;(define_split
187090075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
187190075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
187290075Sobrien;			  [(match_operand 2 "" "")
187390075Sobrien;			   (match_operand 3 "" "")])
187490075Sobrien;			(match_operand:BI 7 "register_operand" ""))
187590075Sobrien;		(and:BI (match_operator:BI 4 "comparison_operator"
187690075Sobrien;			  [(match_operand 5 "" "")
187790075Sobrien;			   (match_operand 6 "" "")])
187890075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
187990075Sobrien;  ""
188090075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
188190075Sobrien;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
188290075Sobrien;			      (match_dup 0)))]
188390075Sobrien;  "")
188490075Sobrien;
188590075Sobrien;(define_split
188690075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
188790075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
188890075Sobrien;			  [(match_operand 2 "" "")
188990075Sobrien;			   (match_operand 3 "" "")])
189090075Sobrien;			(match_operand:BI 7 "register_operand" ""))
189190075Sobrien;		(ior:BI (match_operator:BI 4 "comparison_operator"
189290075Sobrien;			  [(match_operand 5 "" "")
189390075Sobrien;			   (match_operand 6 "" "")])
189490075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
189590075Sobrien;  ""
189690075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
189790075Sobrien;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
189890075Sobrien;			      (match_dup 0)))]
189990075Sobrien;  "")
190090075Sobrien
190190075Sobrien;; Try harder to avoid predicate copies by duplicating compares.
190290075Sobrien;; Note that we'll have already split the predicate copy, which
190390075Sobrien;; is kind of a pain, but oh well.
190490075Sobrien
190590075Sobrien(define_peephole2
190690075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
190790075Sobrien	(match_operand:BI 1 "comparison_operator" ""))
190890075Sobrien   (set (match_operand:CCI 2 "register_operand" "")
190990075Sobrien	(match_operand:CCI 3 "register_operand" ""))
191090075Sobrien   (set (match_operand:CCI 4 "register_operand" "")
191190075Sobrien	(match_operand:CCI 5 "register_operand" ""))
191290075Sobrien   (set (match_operand:BI 6 "register_operand" "")
1913117395Skan	(unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
191490075Sobrien  "REGNO (operands[3]) == REGNO (operands[0])
191590075Sobrien   && REGNO (operands[4]) == REGNO (operands[0]) + 1
191690075Sobrien   && REGNO (operands[4]) == REGNO (operands[2]) + 1
191790075Sobrien   && REGNO (operands[6]) == REGNO (operands[2])"
191890075Sobrien  [(set (match_dup 0) (match_dup 1))
191990075Sobrien   (set (match_dup 6) (match_dup 7))]
192090075Sobrien  "operands[7] = copy_rtx (operands[1]);")
192190075Sobrien
192290075Sobrien;; ::::::::::::::::::::
192390075Sobrien;; ::
192490075Sobrien;; :: 16 bit Integer arithmetic
192590075Sobrien;; ::
192690075Sobrien;; ::::::::::::::::::::
192790075Sobrien
192890075Sobrien(define_insn "mulhi3"
192990075Sobrien  [(set (match_operand:HI 0 "gr_register_operand" "=r")
193090075Sobrien	(mult:HI (match_operand:HI 1 "gr_register_operand" "r")
193190075Sobrien		 (match_operand:HI 2 "gr_register_operand" "r")))]
193290075Sobrien  ""
193390075Sobrien  "pmpy2.r %0 = %1, %2"
193490075Sobrien  [(set_attr "itanium_class" "mmmul")])
193590075Sobrien
193690075Sobrien
193790075Sobrien;; ::::::::::::::::::::
193890075Sobrien;; ::
193990075Sobrien;; :: 32 bit Integer arithmetic
194090075Sobrien;; ::
194190075Sobrien;; ::::::::::::::::::::
194290075Sobrien
194390075Sobrien(define_insn "addsi3"
194490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
194590075Sobrien	(plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
194690075Sobrien		 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
194790075Sobrien  ""
194890075Sobrien  "@
1949117395Skan   add %0 = %1, %2
1950117395Skan   adds %0 = %2, %1
1951117395Skan   addl %0 = %2, %1"
195290075Sobrien  [(set_attr "itanium_class" "ialu")])
195390075Sobrien
195490075Sobrien(define_insn "*addsi3_plus1"
195590075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
195690075Sobrien	(plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
195790075Sobrien			  (match_operand:SI 2 "gr_register_operand" "r"))
195890075Sobrien		 (const_int 1)))]
195990075Sobrien  ""
196090075Sobrien  "add %0 = %1, %2, 1"
196190075Sobrien  [(set_attr "itanium_class" "ialu")])
196290075Sobrien
196390075Sobrien(define_insn "*addsi3_plus1_alt"
196490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
196590075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
196690075Sobrien			  (const_int 2))
196790075Sobrien		 (const_int 1)))]
196890075Sobrien  ""
196990075Sobrien  "add %0 = %1, %1, 1"
197090075Sobrien  [(set_attr "itanium_class" "ialu")])
197190075Sobrien
197290075Sobrien(define_insn "*addsi3_shladd"
197390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
197490075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
197590075Sobrien			  (match_operand:SI 2 "shladd_operand" "n"))
197690075Sobrien		 (match_operand:SI 3 "gr_register_operand" "r")))]
197790075Sobrien  ""
197890075Sobrien  "shladd %0 = %1, %S2, %3"
197990075Sobrien  [(set_attr "itanium_class" "ialu")])
198090075Sobrien
198190075Sobrien(define_insn "subsi3"
198290075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
198390075Sobrien	(minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
198490075Sobrien		  (match_operand:SI 2 "gr_register_operand" "r")))]
198590075Sobrien  ""
198690075Sobrien  "sub %0 = %1, %2"
198790075Sobrien  [(set_attr "itanium_class" "ialu")])
198890075Sobrien
198990075Sobrien(define_insn "*subsi3_minus1"
199090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
199190075Sobrien	(plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
199290075Sobrien		 (match_operand:SI 2 "gr_register_operand" "r")))]
199390075Sobrien  ""
199490075Sobrien  "sub %0 = %2, %1, 1"
199590075Sobrien  [(set_attr "itanium_class" "ialu")])
199690075Sobrien
199790075Sobrien;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
199890075Sobrien
199990075Sobrien(define_insn "mulsi3"
200090075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
200190075Sobrien	(mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
200290075Sobrien		 (match_operand:SI 2 "grfr_register_operand" "f")))]
200390075Sobrien  ""
200490075Sobrien  "xmpy.l %0 = %1, %2"
200590075Sobrien  [(set_attr "itanium_class" "xmpy")])
200690075Sobrien
200790075Sobrien(define_insn "maddsi4"
200890075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
200990075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
201090075Sobrien			  (match_operand:SI 2 "grfr_register_operand" "f"))
201190075Sobrien		 (match_operand:SI 3 "grfr_register_operand" "f")))]
201290075Sobrien  ""
201390075Sobrien  "xma.l %0 = %1, %2, %3"
201490075Sobrien  [(set_attr "itanium_class" "xmpy")])
201590075Sobrien
201690075Sobrien(define_insn "negsi2"
201790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
201890075Sobrien	(neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
201990075Sobrien  ""
202090075Sobrien  "sub %0 = r0, %1"
202190075Sobrien  [(set_attr "itanium_class" "ialu")])
202290075Sobrien
202390075Sobrien(define_expand "abssi2"
202490075Sobrien  [(set (match_dup 2)
202590075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
202690075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
202790075Sobrien	(if_then_else:SI (eq (match_dup 2) (const_int 0))
202890075Sobrien			 (neg:SI (match_dup 1))
202990075Sobrien			 (match_dup 1)))]
203090075Sobrien  ""
2031117395Skan  { operands[2] = gen_reg_rtx (BImode); })
203290075Sobrien
203390075Sobrien(define_expand "sminsi3"
203490075Sobrien  [(set (match_dup 3)
203590075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
203690075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
203790075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
203890075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
203990075Sobrien			 (match_dup 2) (match_dup 1)))]
204090075Sobrien  ""
2041117395Skan  { operands[3] = gen_reg_rtx (BImode); })
204290075Sobrien
204390075Sobrien(define_expand "smaxsi3"
204490075Sobrien  [(set (match_dup 3)
204590075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
204690075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
204790075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
204890075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
204990075Sobrien			 (match_dup 1) (match_dup 2)))]
205090075Sobrien  ""
2051117395Skan  { operands[3] = gen_reg_rtx (BImode); })
205290075Sobrien
205390075Sobrien(define_expand "uminsi3"
205490075Sobrien  [(set (match_dup 3)
205590075Sobrien	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
205690075Sobrien		(match_operand:SI 2 "gr_register_operand" "")))
205790075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
205890075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
205990075Sobrien			 (match_dup 2) (match_dup 1)))]
206090075Sobrien  ""
2061117395Skan  { operands[3] = gen_reg_rtx (BImode); })
206290075Sobrien
206390075Sobrien(define_expand "umaxsi3"
206490075Sobrien  [(set (match_dup 3)
206590075Sobrien	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
206690075Sobrien		(match_operand:SI 2 "gr_register_operand" "")))
206790075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
206890075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
206990075Sobrien			 (match_dup 1) (match_dup 2)))]
207090075Sobrien  ""
2071117395Skan  { operands[3] = gen_reg_rtx (BImode); })
207290075Sobrien
207390075Sobrien(define_expand "divsi3"
207490075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
207590075Sobrien	(div:SI (match_operand:SI 1 "general_operand" "")
207690075Sobrien		(match_operand:SI 2 "general_operand" "")))]
2077132718Skan  "TARGET_INLINE_INT_DIV"
207890075Sobrien{
2079169689Skan  rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
208090075Sobrien
2081132718Skan  op0_xf = gen_reg_rtx (XFmode);
208290075Sobrien  op0_di = gen_reg_rtx (DImode);
208390075Sobrien
208490075Sobrien  if (CONSTANT_P (operands[1]))
208590075Sobrien    operands[1] = force_reg (SImode, operands[1]);
2086132718Skan  op1_xf = gen_reg_rtx (XFmode);
2087132718Skan  expand_float (op1_xf, operands[1], 0);
208890075Sobrien
208990075Sobrien  if (CONSTANT_P (operands[2]))
209090075Sobrien    operands[2] = force_reg (SImode, operands[2]);
2091132718Skan  op2_xf = gen_reg_rtx (XFmode);
2092132718Skan  expand_float (op2_xf, operands[2], 0);
209390075Sobrien
209490075Sobrien  /* 2^-34 */
2095169689Skan  twon34_exp = gen_reg_rtx (DImode);
2096169689Skan  emit_move_insn (twon34_exp, GEN_INT (65501));
2097169689Skan  twon34 = gen_reg_rtx (XFmode);
2098169689Skan  emit_insn (gen_setf_exp_xf (twon34, twon34_exp));
209990075Sobrien
2100169689Skan  emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
2101169689Skan			    CONST1_RTX (SImode)));
2102169689Skan  
2103132718Skan  emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
210490075Sobrien
2105132718Skan  emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
210690075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
210790075Sobrien  DONE;
2108117395Skan})
210990075Sobrien
211090075Sobrien(define_expand "modsi3"
211190075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
211290075Sobrien	(mod:SI (match_operand:SI 1 "general_operand" "")
211390075Sobrien		(match_operand:SI 2 "general_operand" "")))]
2114132718Skan  "TARGET_INLINE_INT_DIV"
211590075Sobrien{
211690075Sobrien  rtx op2_neg, op1_di, div;
211790075Sobrien
211890075Sobrien  div = gen_reg_rtx (SImode);
211990075Sobrien  emit_insn (gen_divsi3 (div, operands[1], operands[2]));
212090075Sobrien
212190075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
212290075Sobrien
212390075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
212490075Sobrien     have already copied to the FP regs.  */
212590075Sobrien  op1_di = gen_reg_rtx (DImode);
212690075Sobrien  convert_move (op1_di, operands[1], 0);
212790075Sobrien
212890075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
212990075Sobrien			  gen_lowpart (SImode, op1_di)));
213090075Sobrien  DONE;
2131117395Skan})
213290075Sobrien
213390075Sobrien(define_expand "udivsi3"
213490075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
213590075Sobrien	(udiv:SI (match_operand:SI 1 "general_operand" "")
213690075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
2137132718Skan  "TARGET_INLINE_INT_DIV"
213890075Sobrien{
2139169689Skan  rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
214090075Sobrien
2141132718Skan  op0_xf = gen_reg_rtx (XFmode);
214290075Sobrien  op0_di = gen_reg_rtx (DImode);
214390075Sobrien
214490075Sobrien  if (CONSTANT_P (operands[1]))
214590075Sobrien    operands[1] = force_reg (SImode, operands[1]);
2146132718Skan  op1_xf = gen_reg_rtx (XFmode);
2147132718Skan  expand_float (op1_xf, operands[1], 1);
214890075Sobrien
214990075Sobrien  if (CONSTANT_P (operands[2]))
215090075Sobrien    operands[2] = force_reg (SImode, operands[2]);
2151132718Skan  op2_xf = gen_reg_rtx (XFmode);
2152132718Skan  expand_float (op2_xf, operands[2], 1);
215390075Sobrien
215490075Sobrien  /* 2^-34 */
2155169689Skan  twon34_exp = gen_reg_rtx (DImode);
2156169689Skan  emit_move_insn (twon34_exp, GEN_INT (65501));
2157169689Skan  twon34 = gen_reg_rtx (XFmode);
2158169689Skan  emit_insn (gen_setf_exp_xf (twon34, twon34_exp));
215990075Sobrien
2160169689Skan  emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
2161169689Skan			    CONST1_RTX (SImode)));
2162169689Skan  
2163132718Skan  emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
216490075Sobrien
2165132718Skan  emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
216690075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
216790075Sobrien  DONE;
2168117395Skan})
216990075Sobrien
217090075Sobrien(define_expand "umodsi3"
217190075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
217290075Sobrien	(umod:SI (match_operand:SI 1 "general_operand" "")
217390075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
2174132718Skan  "TARGET_INLINE_INT_DIV"
217590075Sobrien{
217690075Sobrien  rtx op2_neg, op1_di, div;
217790075Sobrien
217890075Sobrien  div = gen_reg_rtx (SImode);
217990075Sobrien  emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
218090075Sobrien
218190075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
218290075Sobrien
218390075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
218490075Sobrien     have already copied to the FP regs.  */
218590075Sobrien  op1_di = gen_reg_rtx (DImode);
218690075Sobrien  convert_move (op1_di, operands[1], 1);
218790075Sobrien
218890075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
218990075Sobrien			  gen_lowpart (SImode, op1_di)));
219090075Sobrien  DONE;
2191117395Skan})
219290075Sobrien
219390075Sobrien(define_insn_and_split "divsi3_internal"
2194132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2195132718Skan	(float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2196132718Skan			  (match_operand:XF 2 "fr_register_operand" "f"))))
2197132718Skan   (clobber (match_scratch:XF 4 "=&f"))
2198132718Skan   (clobber (match_scratch:XF 5 "=&f"))
219990075Sobrien   (clobber (match_scratch:BI 6 "=c"))
2200132718Skan   (use (match_operand:XF 3 "fr_register_operand" "f"))]
2201132718Skan  "TARGET_INLINE_INT_DIV"
220290075Sobrien  "#"
220390075Sobrien  "&& reload_completed"
2204132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2205117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2206117395Skan					    UNSPEC_FR_RECIP_APPROX))
220790075Sobrien	      (use (const_int 1))])
220890075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
2209132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
221090075Sobrien		(use (const_int 1))]))
221190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
221290075Sobrien     (parallel [(set (match_dup 5)
2213169689Skan		     (minus:XF (match_dup 7)
2214169689Skan			       (mult:XF (match_dup 2) (match_dup 0))))
221590075Sobrien		(use (const_int 1))]))
221690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
221790075Sobrien     (parallel [(set (match_dup 4)
2218132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 4))
221990075Sobrien			      (match_dup 4)))
222090075Sobrien		(use (const_int 1))]))
222190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
222290075Sobrien     (parallel [(set (match_dup 5)
2223132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 5))
222490075Sobrien			      (match_dup 3)))
222590075Sobrien		(use (const_int 1))]))
222690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
222790075Sobrien     (parallel [(set (match_dup 0)
2228132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 4))
222990075Sobrien			      (match_dup 4)))
223090075Sobrien		(use (const_int 1))]))
223190075Sobrien  ] 
2232132718Skan  "operands[7] = CONST1_RTX (XFmode);"
223390075Sobrien  [(set_attr "predicable" "no")])
223490075Sobrien
223590075Sobrien;; ::::::::::::::::::::
223690075Sobrien;; ::
223790075Sobrien;; :: 64 bit Integer arithmetic
223890075Sobrien;; ::
223990075Sobrien;; ::::::::::::::::::::
224090075Sobrien
224190075Sobrien(define_insn "adddi3"
224290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
224390075Sobrien	(plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
224490075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
224590075Sobrien  ""
224690075Sobrien  "@
2247117395Skan   add %0 = %1, %2
2248117395Skan   adds %0 = %2, %1
2249117395Skan   addl %0 = %2, %1"
225090075Sobrien  [(set_attr "itanium_class" "ialu")])
225190075Sobrien
225290075Sobrien(define_insn "*adddi3_plus1"
225390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
225490075Sobrien	(plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
225590075Sobrien			  (match_operand:DI 2 "gr_register_operand" "r"))
225690075Sobrien		 (const_int 1)))]
225790075Sobrien  ""
225890075Sobrien  "add %0 = %1, %2, 1"
225990075Sobrien  [(set_attr "itanium_class" "ialu")])
226090075Sobrien
226190075Sobrien;; This has some of the same problems as shladd.  We let the shladd
226290075Sobrien;; eliminator hack handle it, which results in the 1 being forced into
226390075Sobrien;; a register, but not more ugliness here.
226490075Sobrien(define_insn "*adddi3_plus1_alt"
226590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
226690075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
226790075Sobrien			  (const_int 2))
226890075Sobrien		 (const_int 1)))]
226990075Sobrien  ""
227090075Sobrien  "add %0 = %1, %1, 1"
227190075Sobrien  [(set_attr "itanium_class" "ialu")])
227290075Sobrien
227390075Sobrien(define_insn "subdi3"
227490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
227590075Sobrien	(minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
227690075Sobrien		  (match_operand:DI 2 "gr_register_operand" "r")))]
227790075Sobrien  ""
227890075Sobrien  "sub %0 = %1, %2"
227990075Sobrien  [(set_attr "itanium_class" "ialu")])
228090075Sobrien
228190075Sobrien(define_insn "*subdi3_minus1"
228290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
228390075Sobrien	(plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
228490075Sobrien		 (match_operand:DI 2 "gr_register_operand" "r")))]
228590075Sobrien  ""
228690075Sobrien  "sub %0 = %2, %1, 1"
228790075Sobrien  [(set_attr "itanium_class" "ialu")])
228890075Sobrien
228990075Sobrien;; ??? Use grfr instead of fr because of virtual register elimination
229090075Sobrien;; and silly test cases multiplying by the frame pointer.
229190075Sobrien(define_insn "muldi3"
229290075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
229390075Sobrien	(mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
229490075Sobrien		 (match_operand:DI 2 "grfr_register_operand" "f")))]
229590075Sobrien  ""
229690075Sobrien  "xmpy.l %0 = %1, %2"
229790075Sobrien  [(set_attr "itanium_class" "xmpy")])
229890075Sobrien
229990075Sobrien;; ??? If operand 3 is an eliminable reg, then register elimination causes the
230090075Sobrien;; same problem that we have with shladd below.  Unfortunately, this case is
230190075Sobrien;; much harder to fix because the multiply puts the result in an FP register,
230290075Sobrien;; but the add needs inputs from a general register.  We add a spurious clobber
230390075Sobrien;; here so that it will be present just in case register elimination gives us
230490075Sobrien;; the funny result.
230590075Sobrien
230690075Sobrien;; ??? Maybe validate_changes should try adding match_scratch clobbers?
230790075Sobrien
230890075Sobrien;; ??? Maybe we should change how adds are canonicalized.
230990075Sobrien
231090075Sobrien(define_insn "madddi4"
231190075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
231290075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
231390075Sobrien			  (match_operand:DI 2 "grfr_register_operand" "f"))
231490075Sobrien		 (match_operand:DI 3 "grfr_register_operand" "f")))
231590075Sobrien   (clobber (match_scratch:DI 4 "=X"))]
231690075Sobrien  ""
231790075Sobrien  "xma.l %0 = %1, %2, %3"
231890075Sobrien  [(set_attr "itanium_class" "xmpy")])
231990075Sobrien
232090075Sobrien;; This can be created by register elimination if operand3 of shladd is an
232190075Sobrien;; eliminable register or has reg_equiv_constant set.
232290075Sobrien
232390075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
232490075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
232590075Sobrien;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
232690075Sobrien;; incorrectly.
232790075Sobrien
232890075Sobrien(define_insn "*madddi4_elim"
232990075Sobrien  [(set (match_operand:DI 0 "register_operand" "=&r")
233090075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
233190075Sobrien				   (match_operand:DI 2 "register_operand" "f"))
233290075Sobrien			  (match_operand:DI 3 "register_operand" "f"))
233390075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))
233490075Sobrien   (clobber (match_scratch:DI 5 "=f"))]
233590075Sobrien  "reload_in_progress"
233690075Sobrien  "#"
233790075Sobrien  [(set_attr "itanium_class" "unknown")])
233890075Sobrien
233990075Sobrien(define_split
234090075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
234190075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
234290075Sobrien				   (match_operand:DI 2 "register_operand" ""))
234390075Sobrien			  (match_operand:DI 3 "register_operand" ""))
234490075Sobrien		 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
234590075Sobrien   (clobber (match_scratch:DI 5 ""))]
234690075Sobrien  "reload_completed"
234790075Sobrien  [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
234890075Sobrien					  (match_dup 3)))
234990075Sobrien	      (clobber (match_dup 0))])
235090075Sobrien   (set (match_dup 0) (match_dup 5))
235190075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
235290075Sobrien  "")
235390075Sobrien
235490075Sobrien(define_insn "smuldi3_highpart"
235590075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
235690075Sobrien	(truncate:DI
235790075Sobrien	 (lshiftrt:TI
235890075Sobrien	  (mult:TI (sign_extend:TI
235990075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
236090075Sobrien		   (sign_extend:TI
236190075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
236290075Sobrien	  (const_int 64))))]
236390075Sobrien  ""
236490075Sobrien  "xmpy.h %0 = %1, %2"
236590075Sobrien  [(set_attr "itanium_class" "xmpy")])
236690075Sobrien
236790075Sobrien(define_insn "umuldi3_highpart"
236890075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
236990075Sobrien	(truncate:DI
237090075Sobrien	 (lshiftrt:TI
237190075Sobrien	  (mult:TI (zero_extend:TI
237290075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
237390075Sobrien		   (zero_extend:TI
237490075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
237590075Sobrien	  (const_int 64))))]
237690075Sobrien  ""
237790075Sobrien  "xmpy.hu %0 = %1, %2"
237890075Sobrien  [(set_attr "itanium_class" "xmpy")])
237990075Sobrien
238090075Sobrien(define_insn "negdi2"
238190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
238290075Sobrien	(neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
238390075Sobrien  ""
238490075Sobrien  "sub %0 = r0, %1"
238590075Sobrien  [(set_attr "itanium_class" "ialu")])
238690075Sobrien
238790075Sobrien(define_expand "absdi2"
238890075Sobrien  [(set (match_dup 2)
238990075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
239090075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
239190075Sobrien	(if_then_else:DI (eq (match_dup 2) (const_int 0))
239290075Sobrien			 (neg:DI (match_dup 1))
239390075Sobrien			 (match_dup 1)))]
239490075Sobrien  ""
2395117395Skan  { operands[2] = gen_reg_rtx (BImode); })
239690075Sobrien
239790075Sobrien(define_expand "smindi3"
239890075Sobrien  [(set (match_dup 3)
239990075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
240090075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
240190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
240290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
240390075Sobrien			 (match_dup 2) (match_dup 1)))]
240490075Sobrien  ""
2405117395Skan  { operands[3] = gen_reg_rtx (BImode); })
240690075Sobrien
240790075Sobrien(define_expand "smaxdi3"
240890075Sobrien  [(set (match_dup 3)
240990075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
241090075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
241190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
241290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
241390075Sobrien			 (match_dup 1) (match_dup 2)))]
241490075Sobrien  ""
2415117395Skan  { operands[3] = gen_reg_rtx (BImode); })
241690075Sobrien
241790075Sobrien(define_expand "umindi3"
241890075Sobrien  [(set (match_dup 3)
241990075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
242090075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
242190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
242290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
242390075Sobrien			 (match_dup 2) (match_dup 1)))]
242490075Sobrien  ""
2425117395Skan  { operands[3] = gen_reg_rtx (BImode); })
242690075Sobrien
242790075Sobrien(define_expand "umaxdi3"
242890075Sobrien  [(set (match_dup 3)
242990075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
243090075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
243190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
243290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
243390075Sobrien			 (match_dup 1) (match_dup 2)))]
243490075Sobrien  ""
2435117395Skan  { operands[3] = gen_reg_rtx (BImode); })
243690075Sobrien
243790075Sobrien(define_expand "ffsdi2"
243890075Sobrien  [(set (match_dup 6)
243990075Sobrien	(eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
244090075Sobrien   (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
244190075Sobrien   (set (match_dup 5) (const_int 0))
244290075Sobrien   (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2443132718Skan   (set (match_dup 4) (popcount:DI (match_dup 3)))
244490075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
244590075Sobrien	(if_then_else:DI (ne (match_dup 6) (const_int 0))
244690075Sobrien			 (match_dup 5) (match_dup 4)))]
244790075Sobrien  ""
244890075Sobrien{
244990075Sobrien  operands[2] = gen_reg_rtx (DImode);
245090075Sobrien  operands[3] = gen_reg_rtx (DImode);
245190075Sobrien  operands[4] = gen_reg_rtx (DImode);
245290075Sobrien  operands[5] = gen_reg_rtx (DImode);
245390075Sobrien  operands[6] = gen_reg_rtx (BImode);
2454117395Skan})
245590075Sobrien
2456132718Skan(define_expand "ctzdi2"
2457132718Skan  [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
2458132718Skan			       (const_int -1)))
2459132718Skan   (set (match_dup 3) (not:DI (match_dup 1)))
2460132718Skan   (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
2461132718Skan   (set (match_operand:DI 0 "gr_register_operand" "")
2462132718Skan	(popcount:DI (match_dup 4)))]
2463132718Skan  ""
2464132718Skan{
2465132718Skan  operands[2] = gen_reg_rtx (DImode);
2466132718Skan  operands[3] = gen_reg_rtx (DImode);
2467132718Skan  operands[4] = gen_reg_rtx (DImode);
2468132718Skan})
2469132718Skan
2470132718Skan;; Note the computation here is op0 = 63 - (exp - 0xffff).
2471132718Skan(define_expand "clzdi2"
2472132718Skan  [(set (match_dup 2)
2473132718Skan	(unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "")))
2474132718Skan   (set (match_dup 3)
2475132718Skan	(unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
2476132718Skan   (set (match_dup 4) (const_int 65598))
2477132718Skan   (set (match_operand:DI 0 "gr_register_operand" "")
2478132718Skan	(minus:DI (match_dup 4) (match_dup 3)))]
2479132718Skan  ""
2480132718Skan{
2481132718Skan  operands[2] = gen_reg_rtx (XFmode);
2482132718Skan  operands[3] = gen_reg_rtx (DImode);
2483132718Skan  operands[4] = gen_reg_rtx (DImode);
2484132718Skan})
2485132718Skan
2486132718Skan(define_insn "popcountdi2"
248790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2488132718Skan	(popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
248990075Sobrien  ""
249090075Sobrien  "popcnt %0 = %1"
249190075Sobrien  [(set_attr "itanium_class" "mmmul")])
249290075Sobrien
2493132718Skan(define_insn "*getf_exp_xf"
2494132718Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2495132718Skan	(unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
2496132718Skan		   UNSPEC_GETF_EXP))]
2497132718Skan  ""
2498132718Skan  "getf.exp %0 = %1"
2499132718Skan  [(set_attr "itanium_class" "frfr")])
2500132718Skan
250190075Sobrien(define_expand "divdi3"
250290075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
250390075Sobrien	(div:DI (match_operand:DI 1 "general_operand" "")
250490075Sobrien		(match_operand:DI 2 "general_operand" "")))]
2505132718Skan  "TARGET_INLINE_INT_DIV"
250690075Sobrien{
2507132718Skan  rtx op1_xf, op2_xf, op0_xf;
250890075Sobrien
2509132718Skan  op0_xf = gen_reg_rtx (XFmode);
251090075Sobrien
251190075Sobrien  if (CONSTANT_P (operands[1]))
251290075Sobrien    operands[1] = force_reg (DImode, operands[1]);
2513132718Skan  op1_xf = gen_reg_rtx (XFmode);
2514132718Skan  expand_float (op1_xf, operands[1], 0);
251590075Sobrien
251690075Sobrien  if (CONSTANT_P (operands[2]))
251790075Sobrien    operands[2] = force_reg (DImode, operands[2]);
2518132718Skan  op2_xf = gen_reg_rtx (XFmode);
2519132718Skan  expand_float (op2_xf, operands[2], 0);
252090075Sobrien
2521169689Skan  emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
2522169689Skan			    CONST1_RTX (DImode)));
2523169689Skan
2524169689Skan  if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
2525132718Skan    emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
252690075Sobrien  else
2527132718Skan    emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
252890075Sobrien
2529132718Skan  emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
253090075Sobrien  DONE;
2531117395Skan})
253290075Sobrien
253390075Sobrien(define_expand "moddi3"
253490075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
253590075Sobrien	(mod:SI (match_operand:DI 1 "general_operand" "")
253690075Sobrien		(match_operand:DI 2 "general_operand" "")))]
2537132718Skan  "TARGET_INLINE_INT_DIV"
253890075Sobrien{
253990075Sobrien  rtx op2_neg, div;
254090075Sobrien
254190075Sobrien  div = gen_reg_rtx (DImode);
254290075Sobrien  emit_insn (gen_divdi3 (div, operands[1], operands[2]));
254390075Sobrien
254490075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
254590075Sobrien
254690075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
254790075Sobrien  DONE;
2548117395Skan})
254990075Sobrien
255090075Sobrien(define_expand "udivdi3"
255190075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
255290075Sobrien	(udiv:DI (match_operand:DI 1 "general_operand" "")
255390075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
2554132718Skan  "TARGET_INLINE_INT_DIV"
255590075Sobrien{
2556132718Skan  rtx op1_xf, op2_xf, op0_xf;
255790075Sobrien
2558132718Skan  op0_xf = gen_reg_rtx (XFmode);
255990075Sobrien
256090075Sobrien  if (CONSTANT_P (operands[1]))
256190075Sobrien    operands[1] = force_reg (DImode, operands[1]);
2562132718Skan  op1_xf = gen_reg_rtx (XFmode);
2563132718Skan  expand_float (op1_xf, operands[1], 1);
256490075Sobrien
256590075Sobrien  if (CONSTANT_P (operands[2]))
256690075Sobrien    operands[2] = force_reg (DImode, operands[2]);
2567132718Skan  op2_xf = gen_reg_rtx (XFmode);
2568132718Skan  expand_float (op2_xf, operands[2], 1);
256990075Sobrien
2570169689Skan  emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
2571169689Skan			    CONST1_RTX (DImode)));
2572169689Skan
2573169689Skan  if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
2574132718Skan    emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
257590075Sobrien  else
2576132718Skan    emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
257790075Sobrien
2578132718Skan  emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
257990075Sobrien  DONE;
2580117395Skan})
258190075Sobrien
258290075Sobrien(define_expand "umoddi3"
258390075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
258490075Sobrien	(umod:DI (match_operand:DI 1 "general_operand" "")
258590075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
2586132718Skan  "TARGET_INLINE_INT_DIV"
258790075Sobrien{
258890075Sobrien  rtx op2_neg, div;
258990075Sobrien
259090075Sobrien  div = gen_reg_rtx (DImode);
259190075Sobrien  emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
259290075Sobrien
259390075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
259490075Sobrien
259590075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
259690075Sobrien  DONE;
2597117395Skan})
259890075Sobrien
259990075Sobrien(define_insn_and_split "divdi3_internal_lat"
2600132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2601132718Skan	(float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2602132718Skan			  (match_operand:XF 2 "fr_register_operand" "f"))))
2603132718Skan   (clobber (match_scratch:XF 3 "=&f"))
2604132718Skan   (clobber (match_scratch:XF 4 "=&f"))
2605132718Skan   (clobber (match_scratch:XF 5 "=&f"))
260690075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
2607169689Skan  "TARGET_INLINE_INT_DIV == INL_MIN_LAT"
260890075Sobrien  "#"
260990075Sobrien  "&& reload_completed"
2610132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2611117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2612117395Skan					    UNSPEC_FR_RECIP_APPROX))
261390075Sobrien	      (use (const_int 1))])
261490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
261590075Sobrien     (parallel [(set (match_dup 3)
2616169689Skan		     (minus:XF (match_dup 7)
2617169689Skan			       (mult:XF (match_dup 2) (match_dup 0))))
261890075Sobrien		(use (const_int 1))]))
261990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
2620132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
262190075Sobrien		(use (const_int 1))]))
262290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
2623132718Skan     (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
262490075Sobrien		(use (const_int 1))]))
262590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
262690075Sobrien     (parallel [(set (match_dup 4)
2627132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 4))
262890075Sobrien			      (match_dup 4)))
262990075Sobrien		(use (const_int 1))]))
263090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
263190075Sobrien     (parallel [(set (match_dup 0)
2632132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
263390075Sobrien			      (match_dup 0)))
263490075Sobrien		(use (const_int 1))]))
263590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
263690075Sobrien     (parallel [(set (match_dup 3)
2637132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 4))
263890075Sobrien			      (match_dup 4)))
263990075Sobrien		(use (const_int 1))]))
264090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
264190075Sobrien     (parallel [(set (match_dup 0)
2642132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 0))
264390075Sobrien			      (match_dup 0)))
264490075Sobrien		(use (const_int 1))]))
264590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
264690075Sobrien     (parallel [(set (match_dup 4)
2647169689Skan		     (minus:XF (match_dup 1)
2648169689Skan			       (mult:XF (match_dup 2) (match_dup 3))))
264990075Sobrien		(use (const_int 1))]))
265090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
265190075Sobrien     (parallel [(set (match_dup 0)
2652132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
265390075Sobrien			      (match_dup 3)))
265490075Sobrien		(use (const_int 1))]))
265590075Sobrien  ] 
2656132718Skan  "operands[7] = CONST1_RTX (XFmode);"
265790075Sobrien  [(set_attr "predicable" "no")])
265890075Sobrien
265990075Sobrien(define_insn_and_split "divdi3_internal_thr"
2660132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2661132718Skan	(float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2662132718Skan			  (match_operand:XF 2 "fr_register_operand" "f"))))
2663132718Skan   (clobber (match_scratch:XF 3 "=&f"))
2664132718Skan   (clobber (match_scratch:XF 4 "=f"))
266590075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
2666169689Skan  "TARGET_INLINE_INT_DIV == INL_MAX_THR"
266790075Sobrien  "#"
266890075Sobrien  "&& reload_completed"
2669132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2670117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 
2671117395Skan					    UNSPEC_FR_RECIP_APPROX))
267290075Sobrien	      (use (const_int 1))])
267390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
267490075Sobrien     (parallel [(set (match_dup 3)
2675169689Skan		     (minus:XF (match_dup 6)
2676169689Skan			       (mult:XF (match_dup 2) (match_dup 0))))
267790075Sobrien		(use (const_int 1))]))
267890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
267990075Sobrien     (parallel [(set (match_dup 0)
2680132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
268190075Sobrien			      (match_dup 0)))
268290075Sobrien		(use (const_int 1))]))
268390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
2684132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
268590075Sobrien		(use (const_int 1))]))
268690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
268790075Sobrien     (parallel [(set (match_dup 0)
2688132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
268990075Sobrien			      (match_dup 0)))
269090075Sobrien		(use (const_int 1))]))
269190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
2692132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
269390075Sobrien		(use (const_int 1))]))
269490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
269590075Sobrien     (parallel [(set (match_dup 4)
2696169689Skan		     (minus:XF (match_dup 1)
2697169689Skan			       (mult:XF (match_dup 2) (match_dup 3))))
269890075Sobrien		(use (const_int 1))]))
269990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
270090075Sobrien     (parallel [(set (match_dup 0)
2701132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
270290075Sobrien			      (match_dup 3)))
270390075Sobrien		(use (const_int 1))]))
270490075Sobrien  ] 
2705132718Skan  "operands[6] = CONST1_RTX (XFmode);"
270690075Sobrien  [(set_attr "predicable" "no")])
270790075Sobrien
270890075Sobrien;; ::::::::::::::::::::
270990075Sobrien;; ::
2710169689Skan;; :: 128 bit Integer arithmetic
2711169689Skan;; ::
2712169689Skan;; ::::::::::::::::::::
2713169689Skan
2714169689Skan(define_insn "addti3"
2715169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2716169689Skan	(plus:TI (match_operand:TI 1 "gr_register_operand" "%r")
2717169689Skan		 (match_operand:TI 2 "gr_reg_or_14bit_operand" "rI")))
2718169689Skan   (clobber (match_scratch:BI 3 "=&c"))]
2719169689Skan  ""
2720169689Skan  "#"
2721169689Skan  [(set_attr "itanium_class" "unknown")])
2722169689Skan
2723169689Skan(define_split
2724169689Skan  [(set (match_operand:TI 0 "register_operand" "")
2725169689Skan	(plus:TI (match_operand:TI 1 "register_operand" "")
2726169689Skan		 (match_operand:TI 2 "register_operand" "")))
2727169689Skan   (clobber (match_scratch:BI 3 ""))]
2728169689Skan  "reload_completed"
2729169689Skan  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
2730169689Skan   (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
2731169689Skan   (cond_exec (eq (match_dup 3) (const_int 0))
2732169689Skan	      (set (match_dup 4) (plus:DI (match_dup 5) (match_dup 6))))
2733169689Skan   (cond_exec (ne (match_dup 3) (const_int 0))
2734169689Skan	      (set (match_dup 4)
2735169689Skan		   (plus:DI (plus:DI (match_dup 5) (match_dup 6))
2736169689Skan			    (const_int 1))))]
2737169689Skan{
2738169689Skan  operands[4] = gen_highpart (DImode, operands[0]);
2739169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
2740169689Skan  operands[5] = gen_highpart (DImode, operands[1]);
2741169689Skan  operands[1] = gen_lowpart (DImode, operands[1]);
2742169689Skan  operands[6] = gen_highpart (DImode, operands[2]);
2743169689Skan  operands[2] = gen_lowpart (DImode, operands[2]);
2744169689Skan})
2745169689Skan
2746169689Skan(define_split
2747169689Skan  [(set (match_operand:TI 0 "register_operand" "")
2748169689Skan	(plus:TI (match_operand:TI 1 "register_operand" "")
2749169689Skan		 (match_operand:TI 2 "immediate_operand" "")))
2750169689Skan   (clobber (match_scratch:BI 3 ""))]
2751169689Skan  "reload_completed"
2752169689Skan  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
2753169689Skan   (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1)))
2754169689Skan   (cond_exec (eq (match_dup 3) (const_int 0))
2755169689Skan	      (set (match_dup 4)
2756169689Skan		   (plus:DI (match_dup 5) (match_dup 6))))
2757169689Skan   (cond_exec (ne (match_dup 3) (const_int 0))
2758169689Skan	      (set (match_dup 4)
2759169689Skan		   (plus:DI (match_dup 5) (match_dup 7))))]
2760169689Skan{
2761169689Skan  operands[4] = gen_highpart (DImode, operands[0]);
2762169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
2763169689Skan  operands[5] = gen_highpart (DImode, operands[1]);
2764169689Skan  operands[1] = gen_lowpart (DImode, operands[1]);
2765169689Skan  operands[6] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
2766169689Skan  operands[7] = INTVAL (operands[2]) < 0 ? const0_rtx : const1_rtx;
2767169689Skan})
2768169689Skan
2769169689Skan(define_insn "subti3"
2770169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2771169689Skan	(minus:TI (match_operand:TI 1 "gr_reg_or_8bit_operand" "rK")
2772169689Skan		  (match_operand:TI 2 "gr_register_operand" "r")))
2773169689Skan   (clobber (match_scratch:BI 3 "=&c"))]
2774169689Skan  ""
2775169689Skan  "#"
2776169689Skan  [(set_attr "itanium_class" "unknown")])
2777169689Skan
2778169689Skan(define_split
2779169689Skan  [(set (match_operand:TI 0 "register_operand" "")
2780169689Skan	(minus:TI (match_operand:TI 1 "register_operand" "")
2781169689Skan		  (match_operand:TI 2 "register_operand" "")))
2782169689Skan   (clobber (match_scratch:BI 3 "=&c"))]
2783169689Skan  "reload_completed"
2784169689Skan  [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
2785169689Skan   (set (match_dup 3) (ltu:BI (match_dup 1) (match_dup 0)))
2786169689Skan   (cond_exec (eq (match_dup 3) (const_int 0))
2787169689Skan	      (set (match_dup 4) (minus:DI (match_dup 5) (match_dup 6))))
2788169689Skan   (cond_exec (ne (match_dup 3) (const_int 0))
2789169689Skan	      (set (match_dup 4)
2790169689Skan		   (plus:DI (not:DI (match_dup 6)) (match_dup 5))))]
2791169689Skan{
2792169689Skan  operands[4] = gen_highpart (DImode, operands[0]);
2793169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
2794169689Skan  operands[5] = gen_highpart (DImode, operands[1]);
2795169689Skan  operands[1] = gen_lowpart (DImode, operands[1]);
2796169689Skan  operands[6] = gen_highpart (DImode, operands[2]);
2797169689Skan  operands[2] = gen_lowpart (DImode, operands[2]);
2798169689Skan})
2799169689Skan
2800169689Skan(define_split
2801169689Skan  [(set (match_operand:TI 0 "register_operand" "")
2802169689Skan	(minus:TI (match_operand:TI 1 "immediate_operand" "")
2803169689Skan		  (match_operand:TI 2 "register_operand" "")))
2804169689Skan   (clobber (match_scratch:BI 3 "=&c"))]
2805169689Skan  "reload_completed && CONST_OK_FOR_K (INTVAL (operands[1]))"
2806169689Skan  [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))
2807169689Skan   (set (match_dup 3) (gtu:BI (match_dup 0) (match_dup 1)))
2808169689Skan   (cond_exec (ne (match_dup 3) (const_int 0))
2809169689Skan	      (set (match_dup 4) (minus:DI (match_dup 6) (match_dup 5))))
2810169689Skan   (cond_exec (eq (match_dup 3) (const_int 0))
2811169689Skan	      (set (match_dup 4) (minus:DI (match_dup 7) (match_dup 5))))]
2812169689Skan{
2813169689Skan  operands[4] = gen_highpart (DImode, operands[0]);
2814169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
2815169689Skan  operands[5] = gen_highpart (DImode, operands[2]);
2816169689Skan  operands[2] = gen_lowpart (DImode, operands[2]);
2817169689Skan  operands[6] = INTVAL (operands[1]) < 0 ? GEN_INT (-2) : constm1_rtx;
2818169689Skan  operands[7] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
2819169689Skan})
2820169689Skan
2821169689Skan(define_expand "mulditi3"
2822169689Skan  [(set (match_operand:TI 0 "fr_register_operand" "")
2823169689Skan	(mult:TI (sign_extend:TI
2824169689Skan		   (match_operand:DI 1 "fr_register_operand" ""))
2825169689Skan		 (sign_extend:TI
2826169689Skan		   (match_operand:DI 2 "fr_register_operand" ""))))]
2827169689Skan  ""
2828169689Skan  "")
2829169689Skan
2830169689Skan(define_insn_and_split "*mulditi3_internal"
2831169689Skan  [(set (match_operand:TI 0 "fr_register_operand" "=&f")
2832169689Skan	(mult:TI (sign_extend:TI
2833169689Skan		   (match_operand:DI 1 "fr_register_operand" "%f"))
2834169689Skan		 (sign_extend:TI
2835169689Skan		   (match_operand:DI 2 "fr_register_operand" "f"))))]
2836169689Skan  ""
2837169689Skan  "#"
2838169689Skan  "reload_completed"
2839169689Skan  [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
2840169689Skan   (set (match_dup 3) (truncate:DI
2841169689Skan			(lshiftrt:TI
2842169689Skan			  (mult:TI (sign_extend:TI (match_dup 1))
2843169689Skan				   (sign_extend:TI (match_dup 2)))
2844169689Skan			  (const_int 64))))]
2845169689Skan{
2846169689Skan  operands[3] = gen_highpart (DImode, operands[0]);
2847169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
2848169689Skan}
2849169689Skan  [(set_attr "itanium_class" "unknown")])
2850169689Skan
2851169689Skan(define_expand "umulditi3"
2852169689Skan  [(set (match_operand:TI 0 "fr_register_operand" "")
2853169689Skan	(mult:TI (zero_extend:TI
2854169689Skan		   (match_operand:DI 1 "fr_register_operand" ""))
2855169689Skan		 (zero_extend:TI
2856169689Skan		   (match_operand:DI 2 "fr_register_operand" ""))))]
2857169689Skan  ""
2858169689Skan  "")
2859169689Skan
2860169689Skan(define_insn_and_split "*umulditi3_internal"
2861169689Skan  [(set (match_operand:TI 0 "fr_register_operand" "=&f")
2862169689Skan	(mult:TI (zero_extend:TI
2863169689Skan		   (match_operand:DI 1 "fr_register_operand" "%f"))
2864169689Skan		 (zero_extend:TI
2865169689Skan		   (match_operand:DI 2 "fr_register_operand" "f"))))]
2866169689Skan  ""
2867169689Skan  "#"
2868169689Skan  "reload_completed"
2869169689Skan  [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2)))
2870169689Skan   (set (match_dup 3) (truncate:DI
2871169689Skan			(lshiftrt:TI
2872169689Skan			  (mult:TI (zero_extend:TI (match_dup 1))
2873169689Skan				   (zero_extend:TI (match_dup 2)))
2874169689Skan			  (const_int 64))))]
2875169689Skan{
2876169689Skan  operands[3] = gen_highpart (DImode, operands[0]);
2877169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
2878169689Skan}
2879169689Skan  [(set_attr "itanium_class" "unknown")])
2880169689Skan
2881169689Skan(define_insn_and_split "negti2"
2882169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
2883169689Skan	(neg:TI (match_operand:TI 1 "gr_register_operand" "r")))
2884169689Skan   (clobber (match_scratch:BI 2 "=&c"))]
2885169689Skan  ""
2886169689Skan  "#"
2887169689Skan  "reload_completed"
2888169689Skan  [(set (match_dup 2) (eq:BI (match_dup 1) (const_int 0)))
2889169689Skan   (set (match_dup 0) (minus:DI (const_int 0) (match_dup 1)))
2890169689Skan   (cond_exec (eq (match_dup 2) (const_int 0))
2891169689Skan	      (set (match_dup 3) (minus:DI (const_int -1) (match_dup 4))))
2892169689Skan   (cond_exec (ne (match_dup 2) (const_int 0))
2893169689Skan	      (set (match_dup 3) (minus:DI (const_int 0) (match_dup 4))))]
2894169689Skan{
2895169689Skan  operands[3] = gen_highpart (DImode, operands[0]);
2896169689Skan  operands[0] = gen_lowpart (DImode, operands[0]);
2897169689Skan  operands[4] = gen_highpart (DImode, operands[1]);
2898169689Skan  operands[1] = gen_lowpart (DImode, operands[1]);
2899169689Skan}
2900169689Skan  [(set_attr "itanium_class" "unknown")])
2901169689Skan
2902169689Skan;; ::::::::::::::::::::
2903169689Skan;; ::
290490075Sobrien;; :: 32 bit floating point arithmetic
290590075Sobrien;; ::
290690075Sobrien;; ::::::::::::::::::::
290790075Sobrien
290890075Sobrien(define_insn "addsf3"
290990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
291090075Sobrien	(plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
291190075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
291290075Sobrien  ""
291390075Sobrien  "fadd.s %0 = %1, %F2"
291490075Sobrien  [(set_attr "itanium_class" "fmac")])
291590075Sobrien
291690075Sobrien(define_insn "subsf3"
291790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
291890075Sobrien	(minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
291990075Sobrien		  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
292090075Sobrien  ""
292190075Sobrien  "fsub.s %0 = %F1, %F2"
292290075Sobrien  [(set_attr "itanium_class" "fmac")])
292390075Sobrien
292490075Sobrien(define_insn "mulsf3"
292590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
292690075Sobrien	(mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
292790075Sobrien		 (match_operand:SF 2 "fr_register_operand" "f")))]
292890075Sobrien  ""
292990075Sobrien  "fmpy.s %0 = %1, %2"
293090075Sobrien  [(set_attr "itanium_class" "fmac")])
293190075Sobrien
293290075Sobrien(define_insn "abssf2"
293390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
293490075Sobrien	(abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
293590075Sobrien  ""
293690075Sobrien  "fabs %0 = %1"
293790075Sobrien  [(set_attr "itanium_class" "fmisc")])
293890075Sobrien
293990075Sobrien(define_insn "negsf2"
294090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
294190075Sobrien	(neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
294290075Sobrien  ""
294390075Sobrien  "fneg %0 = %1"
294490075Sobrien  [(set_attr "itanium_class" "fmisc")])
294590075Sobrien
294690075Sobrien(define_insn "*nabssf2"
294790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
294890075Sobrien	(neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
294990075Sobrien  ""
295090075Sobrien  "fnegabs %0 = %1"
295190075Sobrien  [(set_attr "itanium_class" "fmisc")])
295290075Sobrien
2953169689Skan(define_insn "copysignsf3"
2954169689Skan  [(set (match_operand:SF 0 "register_operand" "=f")
2955169689Skan	(unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2956169689Skan		    (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2957169689Skan		   UNSPEC_COPYSIGN))]
2958169689Skan  ""
2959169689Skan  "fmerge.s %0 = %F2, %F1"
2960169689Skan  [(set_attr "itanium_class" "fmisc")])
2961169689Skan
2962169689Skan(define_insn "*ncopysignsf3"
2963169689Skan  [(set (match_operand:SF 0 "register_operand" "=f")
2964169689Skan	(neg:SF (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2965169689Skan			    (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")]
2966169689Skan			   UNSPEC_COPYSIGN)))]
2967169689Skan  ""
2968169689Skan  "fmerge.ns %0 = %F2, %F1"
2969169689Skan  [(set_attr "itanium_class" "fmisc")])
2970169689Skan
2971169689Skan(define_insn "sminsf3"
297290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
297390075Sobrien	(smin:SF (match_operand:SF 1 "fr_register_operand" "f")
297490075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
297590075Sobrien  ""
297690075Sobrien  "fmin %0 = %1, %F2"
297790075Sobrien  [(set_attr "itanium_class" "fmisc")])
297890075Sobrien
2979169689Skan(define_insn "smaxsf3"
298090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
298190075Sobrien	(smax:SF (match_operand:SF 1 "fr_register_operand" "f")
298290075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
298390075Sobrien  ""
298490075Sobrien  "fmax %0 = %1, %F2"
298590075Sobrien  [(set_attr "itanium_class" "fmisc")])
298690075Sobrien
298790075Sobrien(define_insn "*maddsf4"
298890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
298990075Sobrien	(plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
299090075Sobrien			  (match_operand:SF 2 "fr_register_operand" "f"))
299190075Sobrien		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
299290075Sobrien  ""
299390075Sobrien  "fma.s %0 = %1, %2, %F3"
299490075Sobrien  [(set_attr "itanium_class" "fmac")])
299590075Sobrien
299690075Sobrien(define_insn "*msubsf4"
299790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
299890075Sobrien	(minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
299990075Sobrien			   (match_operand:SF 2 "fr_register_operand" "f"))
300090075Sobrien		  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
300190075Sobrien  ""
300290075Sobrien  "fms.s %0 = %1, %2, %F3"
300390075Sobrien  [(set_attr "itanium_class" "fmac")])
300490075Sobrien
300590075Sobrien(define_insn "*nmulsf3"
300690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
300790075Sobrien	(neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
300890075Sobrien			 (match_operand:SF 2 "fr_register_operand" "f"))))]
300990075Sobrien  ""
301090075Sobrien  "fnmpy.s %0 = %1, %2"
301190075Sobrien  [(set_attr "itanium_class" "fmac")])
301290075Sobrien
301390075Sobrien(define_insn "*nmaddsf4"
301490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3015169689Skan	(minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
3016169689Skan		  (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
3017169689Skan			   (match_operand:SF 2 "fr_register_operand" "f"))))]
301890075Sobrien  ""
301990075Sobrien  "fnma.s %0 = %1, %2, %F3"
302090075Sobrien  [(set_attr "itanium_class" "fmac")])
302190075Sobrien
3022169689Skan(define_insn "*nmaddsf4_alts"
3023169689Skan  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3024169689Skan	(minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
3025169689Skan		  (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
3026169689Skan			   (match_operand:SF 2 "fr_register_operand" "f"))))
3027169689Skan   (use (match_operand:SI 4 "const_int_operand" ""))]
3028169689Skan  ""
3029169689Skan  "fnma.s.s%4 %0 = %1, %2, %F3"
3030169689Skan  [(set_attr "itanium_class" "fmac")])
3031169689Skan
303290075Sobrien(define_expand "divsf3"
303390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "")
303490075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "")
303590075Sobrien		(match_operand:SF 2 "fr_register_operand" "")))]
3036132718Skan  "TARGET_INLINE_FLOAT_DIV"
303790075Sobrien{
303890075Sobrien  rtx insn;
3039169689Skan  if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
304090075Sobrien    insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
304190075Sobrien  else
304290075Sobrien    insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
304390075Sobrien  emit_insn (insn);
304490075Sobrien  DONE;
3045117395Skan})
304690075Sobrien
304790075Sobrien(define_insn_and_split "divsf3_internal_lat"
304890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
304990075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
305090075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
3051132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3052132718Skan   (clobber (match_scratch:XF 4 "=f"))
305390075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
3054169689Skan  "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT"
305590075Sobrien  "#"
305690075Sobrien  "&& reload_completed"
3057132718Skan  [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3058117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3059117395Skan					    UNSPEC_FR_RECIP_APPROX))
3060169689Skan	      (use (const_int 0))])
306190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
3062132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
306390075Sobrien		(use (const_int 1))]))
306490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
306590075Sobrien     (parallel [(set (match_dup 4)
3066169689Skan		     (minus:XF (match_dup 10)
3067169689Skan			       (mult:XF (match_dup 8) (match_dup 6))))
306890075Sobrien		(use (const_int 1))]))
306990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
307090075Sobrien     (parallel [(set (match_dup 3)
3071132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 3))
307290075Sobrien			      (match_dup 3)))
307390075Sobrien		(use (const_int 1))]))
307490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
3075132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
307690075Sobrien		(use (const_int 1))]))
307790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
307890075Sobrien     (parallel [(set (match_dup 3)
3079132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 3))
308090075Sobrien			      (match_dup 3)))
308190075Sobrien		(use (const_int 1))]))
308290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
3083132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
308490075Sobrien		(use (const_int 1))]))
308590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
308690075Sobrien     (parallel [(set (match_dup 9)
308790075Sobrien		     (float_truncate:DF
3088132718Skan		       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
308990075Sobrien			      (match_dup 3))))
309090075Sobrien		(use (const_int 1))]))
309190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
309290075Sobrien     (set (match_dup 0)
309390075Sobrien	  (float_truncate:SF (match_dup 6))))
309490075Sobrien  ] 
3095117395Skan{
3096132718Skan  operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3097132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3098132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3099117395Skan  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
3100132718Skan  operands[10] = CONST1_RTX (XFmode);
3101117395Skan}
310290075Sobrien  [(set_attr "predicable" "no")])
310390075Sobrien
310490075Sobrien(define_insn_and_split "divsf3_internal_thr"
310590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
310690075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
310790075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
3108132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3109132718Skan   (clobber (match_scratch:XF 4 "=f"))
311090075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
3111169689Skan  "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR"
311290075Sobrien  "#"
311390075Sobrien  "&& reload_completed"
3114132718Skan  [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3115117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3116117395Skan					    UNSPEC_FR_RECIP_APPROX))
3117169689Skan	      (use (const_int 0))])
311890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
311990075Sobrien     (parallel [(set (match_dup 3)
3120169689Skan		     (minus:XF (match_dup 10)
3121169689Skan			       (mult:XF (match_dup 8) (match_dup 6))))
312290075Sobrien		(use (const_int 1))]))
312390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
312490075Sobrien     (parallel [(set (match_dup 3)
3125132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 3))
312690075Sobrien			      (match_dup 3)))
312790075Sobrien		(use (const_int 1))]))
312890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
312990075Sobrien     (parallel [(set (match_dup 6)
3130132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
313190075Sobrien			      (match_dup 6)))
313290075Sobrien		(use (const_int 1))]))
313390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
313490075Sobrien     (parallel [(set (match_dup 9)
313590075Sobrien		     (float_truncate:SF
3136132718Skan		       (mult:XF (match_dup 7) (match_dup 6))))
313790075Sobrien		(use (const_int 1))]))
313890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
313990075Sobrien     (parallel [(set (match_dup 4)
3140169689Skan		     (minus:XF (match_dup 7)
3141169689Skan			       (mult:XF (match_dup 8) (match_dup 3))))
314290075Sobrien		(use (const_int 1))]))
314390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
314490075Sobrien     (set (match_dup 0)
314590075Sobrien	  (float_truncate:SF
3146132718Skan	    (plus:XF (mult:XF (match_dup 4) (match_dup 6))
314790075Sobrien			      (match_dup 3)))))
314890075Sobrien  ] 
3149117395Skan{
3150132718Skan  operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3151132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3152132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3153117395Skan  operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
3154132718Skan  operands[10] = CONST1_RTX (XFmode);
3155117395Skan}
315690075Sobrien  [(set_attr "predicable" "no")])
3157132718Skan
3158132718Skan;; Inline square root.
3159132718Skan
3160132718Skan(define_insn "*sqrt_approx"
3161132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3162132718Skan        (div:XF (const_int 1)
3163132718Skan                (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
3164132718Skan   (set (match_operand:BI 1 "register_operand" "=c")
3165132718Skan        (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
3166132718Skan   (use (match_operand:SI 3 "const_int_operand" "")) ]
3167132718Skan  ""
3168132718Skan  "frsqrta.s%3 %0, %1 = %2"
3169132718Skan  [(set_attr "itanium_class" "fmisc")
3170132718Skan   (set_attr "predicable" "no")])
3171132718Skan
3172169689Skan(define_insn "setf_exp_xf"
3173132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3174132718Skan        (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
3175132718Skan                  UNSPEC_SETF_EXP))]
3176132718Skan  ""
3177132718Skan  "setf.exp %0 = %1"
3178132718Skan  [(set_attr "itanium_class" "frfr")])
3179132718Skan
3180132718Skan(define_expand "sqrtsf2"
3181132718Skan  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
3182132718Skan	(sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))]
3183132718Skan  "TARGET_INLINE_SQRT"
3184132718Skan{
3185132718Skan  rtx insn;
3186132718Skan#if 0
3187169689Skan  if (TARGET_INLINE_SQRT == INL_MIN_LAT)
3188132718Skan    insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
3189169689Skan  else
3190132718Skan#else
3191169689Skan  gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
3192132718Skan#endif
3193169689Skan  insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
3194132718Skan  emit_insn (insn);
3195132718Skan  DONE;
3196132718Skan})
3197132718Skan
3198132718Skan;; Latency-optimized square root.
3199132718Skan;; FIXME: Implement.
3200132718Skan
3201132718Skan;; Throughput-optimized square root.
3202132718Skan
3203132718Skan(define_insn_and_split "sqrtsf2_internal_thr"
3204132718Skan  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
3205132718Skan	(sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))
3206132718Skan   ;; Register r2 in optimization guide.
3207132718Skan   (clobber (match_scratch:DI 2 "=r"))
3208132718Skan   ;; Register f8 in optimization guide
3209132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3210132718Skan   ;; Register f9 in optimization guide
3211132718Skan   (clobber (match_scratch:XF 4 "=&f"))
3212132718Skan   ;; Register f10 in optimization guide
3213132718Skan   (clobber (match_scratch:XF 5 "=&f"))
3214132718Skan   ;; Register p6 in optimization guide.
3215132718Skan   (clobber (match_scratch:BI 6 "=c"))]
3216169689Skan  "TARGET_INLINE_SQRT == INL_MAX_THR"
3217132718Skan  "#"
3218132718Skan  "&& reload_completed"
3219132718Skan  [ ;; exponent of +1/2 in r2
3220132718Skan    (set (match_dup 2) (const_int 65534))
3221132718Skan    ;; +1/2 in f8
3222132718Skan    (set (match_dup 3) 
3223132718Skan         (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3224132718Skan    ;; Step 1
3225132718Skan    ;; y0 = 1/sqrt(a) in f7
3226132718Skan    (parallel [(set (match_dup 7)
3227132718Skan                    (div:XF (const_int 1)
3228132718Skan                            (sqrt:XF (match_dup 8))))
3229132718Skan               (set (match_dup 6)
3230132718Skan                    (unspec:BI [(match_dup 8)]
3231132718Skan                                 UNSPEC_FR_SQRT_RECIP_APPROX))
3232132718Skan               (use (const_int 0))])
3233132718Skan    ;; Step 2
3234132718Skan    ;; H0 = 1/2 * y0 in f9
3235132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3236132718Skan      (parallel [(set (match_dup 4)
3237132718Skan                      (plus:XF (mult:XF (match_dup 3) (match_dup 7))
3238132718Skan                               (match_dup 9)))
3239132718Skan                 (use (const_int 1))]))
3240132718Skan    ;; Step 3
3241132718Skan    ;; S0 = a * y0 in f7
3242132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3243132718Skan      (parallel [(set (match_dup 7)
3244132718Skan                      (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3245132718Skan                               (match_dup 9)))
3246132718Skan                 (use (const_int 1))]))
3247132718Skan    ;; Step 4
3248132718Skan    ;; d = 1/2 - S0 * H0 in f10
3249132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3250132718Skan      (parallel [(set (match_dup 5)
3251169689Skan                      (minus:XF (match_dup 3)
3252169689Skan				(mult:XF (match_dup 7) (match_dup 4))))
3253132718Skan                 (use (const_int 1))]))
3254132718Skan    ;; Step 5
3255132718Skan    ;; d' = d + 1/2 * d in f8
3256132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3257132718Skan       (parallel [(set (match_dup 3)
3258132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 5))
3259132718Skan                                (match_dup 5)))
3260132718Skan                  (use (const_int 1))]))
3261132718Skan    ;; Step 6
3262132718Skan    ;; e = d + d * d' in f8
3263132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3264132718Skan       (parallel [(set (match_dup 3)
3265132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3266132718Skan                                (match_dup 5)))
3267132718Skan                  (use (const_int 1))]))
3268132718Skan    ;; Step 7
3269132718Skan    ;; S1 = S0 + e * S0 in f7
3270132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3271132718Skan      (parallel [(set (match_dup 0)
3272132718Skan		      (float_truncate:SF
3273132718Skan                        (plus:XF (mult:XF (match_dup 3) (match_dup 7))
3274132718Skan                                 (match_dup 7))))
3275132718Skan                 (use (const_int 1))]))
3276132718Skan    ;; Step 8
3277132718Skan    ;; H1 = H0 + e * H0 in f8
3278132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3279132718Skan       (parallel [(set (match_dup 3)
3280132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 4))
3281132718Skan                                (match_dup 4)))
3282132718Skan                  (use (const_int 1))]))
3283132718Skan    ;; Step 9 
3284132718Skan    ;; d1 = a - S1 * S1 in f9
3285132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3286132718Skan       (parallel [(set (match_dup 4)
3287169689Skan                       (minus:XF (match_dup 8)
3288169689Skan				 (mult:XF (match_dup 7) (match_dup 7))))
3289132718Skan                  (use (const_int 1))]))
3290132718Skan    ;; Step 10
3291132718Skan    ;; S = S1 + d1 * H1 in f7
3292132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3293132718Skan       (parallel [(set (match_dup 0)
3294132718Skan                       (float_truncate:SF
3295132718Skan                         (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3296132718Skan                                  (match_dup 7))))
3297132718Skan                  (use (const_int 0))]))]
3298132718Skan{
3299132718Skan  /* Generate 82-bit versions of the input and output operands.  */
3300132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3301132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3302132718Skan  /* Generate required floating-point constants.  */
3303132718Skan  operands[9] = CONST0_RTX (XFmode);
3304132718Skan}
3305132718Skan  [(set_attr "predicable" "no")])
330690075Sobrien
330790075Sobrien;; ::::::::::::::::::::
330890075Sobrien;; ::
330990075Sobrien;; :: 64 bit floating point arithmetic
331090075Sobrien;; ::
331190075Sobrien;; ::::::::::::::::::::
331290075Sobrien
331390075Sobrien(define_insn "adddf3"
331490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
331590075Sobrien	(plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
331690075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
331790075Sobrien  ""
331890075Sobrien  "fadd.d %0 = %1, %F2"
331990075Sobrien  [(set_attr "itanium_class" "fmac")])
332090075Sobrien
332190075Sobrien(define_insn "*adddf3_trunc"
332290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
332390075Sobrien	(float_truncate:SF
332490075Sobrien	  (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
332590075Sobrien		   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
332690075Sobrien  ""
332790075Sobrien  "fadd.s %0 = %1, %F2"
332890075Sobrien  [(set_attr "itanium_class" "fmac")])
332990075Sobrien
333090075Sobrien(define_insn "subdf3"
333190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
333290075Sobrien	(minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
333390075Sobrien		  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
333490075Sobrien  ""
333590075Sobrien  "fsub.d %0 = %F1, %F2"
333690075Sobrien  [(set_attr "itanium_class" "fmac")])
333790075Sobrien
333890075Sobrien(define_insn "*subdf3_trunc"
333990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
334090075Sobrien	(float_truncate:SF
334190075Sobrien	  (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
334290075Sobrien		    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
334390075Sobrien  ""
334490075Sobrien  "fsub.s %0 = %F1, %F2"
334590075Sobrien  [(set_attr "itanium_class" "fmac")])
334690075Sobrien
334790075Sobrien(define_insn "muldf3"
334890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
334990075Sobrien	(mult:DF (match_operand:DF 1 "fr_register_operand" "f")
335090075Sobrien		 (match_operand:DF 2 "fr_register_operand" "f")))]
335190075Sobrien  ""
335290075Sobrien  "fmpy.d %0 = %1, %2"
335390075Sobrien  [(set_attr "itanium_class" "fmac")])
335490075Sobrien
335590075Sobrien(define_insn "*muldf3_trunc"
335690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
335790075Sobrien	(float_truncate:SF
335890075Sobrien	  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
335990075Sobrien		   (match_operand:DF 2 "fr_register_operand" "f"))))]
336090075Sobrien  ""
336190075Sobrien  "fmpy.s %0 = %1, %2"
336290075Sobrien  [(set_attr "itanium_class" "fmac")])
336390075Sobrien
336490075Sobrien(define_insn "absdf2"
336590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
336690075Sobrien	(abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
336790075Sobrien  ""
336890075Sobrien  "fabs %0 = %1"
336990075Sobrien  [(set_attr "itanium_class" "fmisc")])
337090075Sobrien
337190075Sobrien(define_insn "negdf2"
337290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
337390075Sobrien	(neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
337490075Sobrien  ""
337590075Sobrien  "fneg %0 = %1"
337690075Sobrien  [(set_attr "itanium_class" "fmisc")])
337790075Sobrien
337890075Sobrien(define_insn "*nabsdf2"
337990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
338090075Sobrien	(neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
338190075Sobrien  ""
338290075Sobrien  "fnegabs %0 = %1"
338390075Sobrien  [(set_attr "itanium_class" "fmisc")])
338490075Sobrien
3385169689Skan(define_insn "copysigndf3"
3386169689Skan  [(set (match_operand:DF 0 "register_operand" "=f")
3387169689Skan	(unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3388169689Skan		    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
3389169689Skan		   UNSPEC_COPYSIGN))]
3390169689Skan  ""
3391169689Skan  "fmerge.s %0 = %F2, %F1"
3392169689Skan  [(set_attr "itanium_class" "fmisc")])
3393169689Skan
3394169689Skan(define_insn "*ncopysigndf3"
3395169689Skan  [(set (match_operand:DF 0 "register_operand" "=f")
3396169689Skan	(neg:DF (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
3397169689Skan			    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")]
3398169689Skan			   UNSPEC_COPYSIGN)))]
3399169689Skan  ""
3400169689Skan  "fmerge.ns %0 = %F2, %F1"
3401169689Skan  [(set_attr "itanium_class" "fmisc")])
3402169689Skan
3403169689Skan(define_insn "smindf3"
340490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
340590075Sobrien	(smin:DF (match_operand:DF 1 "fr_register_operand" "f")
340690075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
340790075Sobrien  ""
340890075Sobrien  "fmin %0 = %1, %F2"
340990075Sobrien  [(set_attr "itanium_class" "fmisc")])
341090075Sobrien
3411169689Skan(define_insn "smaxdf3"
341290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
341390075Sobrien	(smax:DF (match_operand:DF 1 "fr_register_operand" "f")
341490075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
341590075Sobrien  ""
341690075Sobrien  "fmax %0 = %1, %F2"
341790075Sobrien  [(set_attr "itanium_class" "fmisc")])
341890075Sobrien
341990075Sobrien(define_insn "*madddf4"
342090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
342190075Sobrien	(plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
342290075Sobrien			  (match_operand:DF 2 "fr_register_operand" "f"))
342390075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
342490075Sobrien  ""
342590075Sobrien  "fma.d %0 = %1, %2, %F3"
342690075Sobrien  [(set_attr "itanium_class" "fmac")])
342790075Sobrien
342890075Sobrien(define_insn "*madddf4_trunc"
342990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
343090075Sobrien	(float_truncate:SF
343190075Sobrien	  (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
343290075Sobrien			    (match_operand:DF 2 "fr_register_operand" "f"))
343390075Sobrien		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
343490075Sobrien  ""
343590075Sobrien  "fma.s %0 = %1, %2, %F3"
343690075Sobrien  [(set_attr "itanium_class" "fmac")])
343790075Sobrien
343890075Sobrien(define_insn "*msubdf4"
343990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
344090075Sobrien	(minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
344190075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f"))
344290075Sobrien		  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
344390075Sobrien  ""
344490075Sobrien  "fms.d %0 = %1, %2, %F3"
344590075Sobrien  [(set_attr "itanium_class" "fmac")])
344690075Sobrien
344790075Sobrien(define_insn "*msubdf4_trunc"
344890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
344990075Sobrien	(float_truncate:SF
345090075Sobrien	  (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
345190075Sobrien			     (match_operand:DF 2 "fr_register_operand" "f"))
345290075Sobrien		    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
345390075Sobrien  ""
345490075Sobrien  "fms.s %0 = %1, %2, %F3"
345590075Sobrien  [(set_attr "itanium_class" "fmac")])
345690075Sobrien
345790075Sobrien(define_insn "*nmuldf3"
345890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
345990075Sobrien	(neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
346090075Sobrien			 (match_operand:DF 2 "fr_register_operand" "f"))))]
346190075Sobrien  ""
346290075Sobrien  "fnmpy.d %0 = %1, %2"
346390075Sobrien  [(set_attr "itanium_class" "fmac")])
346490075Sobrien
346590075Sobrien(define_insn "*nmuldf3_trunc"
346690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
346790075Sobrien	(float_truncate:SF
346890075Sobrien	  (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
346990075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))))]
347090075Sobrien  ""
347190075Sobrien  "fnmpy.s %0 = %1, %2"
347290075Sobrien  [(set_attr "itanium_class" "fmac")])
347390075Sobrien
347490075Sobrien(define_insn "*nmadddf4"
347590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3476169689Skan	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3477169689Skan		  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3478169689Skan			   (match_operand:DF 2 "fr_register_operand" "f"))))]
347990075Sobrien  ""
348090075Sobrien  "fnma.d %0 = %1, %2, %F3"
348190075Sobrien  [(set_attr "itanium_class" "fmac")])
348290075Sobrien
348390075Sobrien(define_insn "*nmadddf4_alts"
348490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
3485169689Skan	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3486169689Skan		  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3487169689Skan			   (match_operand:DF 2 "fr_register_operand" "f"))))
348890075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
348990075Sobrien  ""
349090075Sobrien  "fnma.d.s%4 %0 = %1, %2, %F3"
349190075Sobrien  [(set_attr "itanium_class" "fmac")])
349290075Sobrien
3493169689Skan(define_insn "*nmadddf4_truncsf"
349490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
349590075Sobrien	(float_truncate:SF
3496169689Skan	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3497169689Skan		  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3498169689Skan			   (match_operand:DF 2 "fr_register_operand" "f")))))]
349990075Sobrien  ""
350090075Sobrien  "fnma.s %0 = %1, %2, %F3"
350190075Sobrien  [(set_attr "itanium_class" "fmac")])
350290075Sobrien
3503169689Skan(define_insn "*nmadddf4_truncsf_alts"
3504169689Skan  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3505169689Skan	(float_truncate:SF
3506169689Skan	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
3507169689Skan		  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3508169689Skan			   (match_operand:DF 2 "fr_register_operand" "f")))))
3509169689Skan   (use (match_operand:SI 4 "const_int_operand" ""))]
3510169689Skan  ""
3511169689Skan  "fnma.s.s%4 %0 = %1, %2, %F3"
3512169689Skan  [(set_attr "itanium_class" "fmac")])
3513169689Skan
351490075Sobrien(define_expand "divdf3"
351590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "")
351690075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "")
351790075Sobrien		(match_operand:DF 2 "fr_register_operand" "")))]
3518132718Skan  "TARGET_INLINE_FLOAT_DIV"
351990075Sobrien{
352090075Sobrien  rtx insn;
3521169689Skan  if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
352290075Sobrien    insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
352390075Sobrien  else
352490075Sobrien    insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
352590075Sobrien  emit_insn (insn);
352690075Sobrien  DONE;
3527117395Skan})
352890075Sobrien
352990075Sobrien(define_insn_and_split "divdf3_internal_lat"
353090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
353190075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
353290075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
3533132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3534132718Skan   (clobber (match_scratch:XF 4 "=&f"))
3535132718Skan   (clobber (match_scratch:XF 5 "=&f"))
353690075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
3537169689Skan  "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT"
353890075Sobrien  "#"
353990075Sobrien  "&& reload_completed"
3540132718Skan  [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
3541117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3542117395Skan					    UNSPEC_FR_RECIP_APPROX))
3543169689Skan	      (use (const_int 0))])
354490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
3545132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
354690075Sobrien		(use (const_int 1))]))
354790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
354890075Sobrien     (parallel [(set (match_dup 4)
3549169689Skan		     (minus:XF (match_dup 12)
3550169689Skan			       (mult:XF (match_dup 9) (match_dup 7))))
355190075Sobrien		(use (const_int 1))]))
355290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
355390075Sobrien     (parallel [(set (match_dup 3)
3554132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 3))
355590075Sobrien			      (match_dup 3)))
355690075Sobrien		(use (const_int 1))]))
355790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
3558132718Skan     (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
355990075Sobrien		(use (const_int 1))]))
356090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
356190075Sobrien     (parallel [(set (match_dup 7)
3562132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 7))
356390075Sobrien			      (match_dup 7)))
356490075Sobrien		(use (const_int 1))]))
356590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
356690075Sobrien     (parallel [(set (match_dup 3)
3567132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 3))
356890075Sobrien			      (match_dup 3)))
356990075Sobrien		(use (const_int 1))]))
357090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
3571132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
357290075Sobrien		(use (const_int 1))]))
357390075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
357490075Sobrien     (parallel [(set (match_dup 7)
3575132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 7))
357690075Sobrien			      (match_dup 7)))
357790075Sobrien		(use (const_int 1))]))
357890075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
357990075Sobrien     (parallel [(set (match_dup 10)
358090075Sobrien		     (float_truncate:DF
3581132718Skan		       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
358290075Sobrien			      (match_dup 3))))
358390075Sobrien		(use (const_int 1))]))
358490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
358590075Sobrien     (parallel [(set (match_dup 7)
3586132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 7))
358790075Sobrien			      (match_dup 7)))
358890075Sobrien		(use (const_int 1))]))
358990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
359090075Sobrien     (parallel [(set (match_dup 11)
359190075Sobrien		     (float_truncate:DF
3592169689Skan		       (minus:XF (match_dup 8)
3593169689Skan				 (mult:XF (match_dup 9) (match_dup 3)))))
359490075Sobrien		(use (const_int 1))]))
359590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
359690075Sobrien     (set (match_dup 0)
3597132718Skan	  (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
359890075Sobrien			      (match_dup 3)))))
359990075Sobrien  ] 
3600117395Skan{
3601132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3602132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3603132718Skan  operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3604117395Skan  operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3605117395Skan  operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3606132718Skan  operands[12] = CONST1_RTX (XFmode);
3607117395Skan}
360890075Sobrien  [(set_attr "predicable" "no")])
360990075Sobrien
361090075Sobrien(define_insn_and_split "divdf3_internal_thr"
361190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
361290075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
361390075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
3614132718Skan   (clobber (match_scratch:XF 3 "=&f"))
361590075Sobrien   (clobber (match_scratch:DF 4 "=f"))
361690075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
3617169689Skan  "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR"
361890075Sobrien  "#"
361990075Sobrien  "&& reload_completed"
3620132718Skan  [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3621117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3622117395Skan					    UNSPEC_FR_RECIP_APPROX))
3623169689Skan	      (use (const_int 0))])
362490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
362590075Sobrien     (parallel [(set (match_dup 3)
3626169689Skan		     (minus:XF (match_dup 10)
3627169689Skan			       (mult:XF (match_dup 8) (match_dup 6))))
362890075Sobrien		(use (const_int 1))]))
362990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
363090075Sobrien     (parallel [(set (match_dup 6)
3631132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
363290075Sobrien			      (match_dup 6)))
363390075Sobrien		(use (const_int 1))]))
363490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
363590075Sobrien     (parallel [(set (match_dup 3)
3636132718Skan		     (mult:XF (match_dup 3) (match_dup 3)))
363790075Sobrien		(use (const_int 1))]))
363890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
363990075Sobrien     (parallel [(set (match_dup 6)
3640132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
364190075Sobrien			      (match_dup 6)))
364290075Sobrien		(use (const_int 1))]))
364390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
364490075Sobrien     (parallel [(set (match_dup 3)
3645132718Skan		     (mult:XF (match_dup 3) (match_dup 3)))
364690075Sobrien		(use (const_int 1))]))
364790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
364890075Sobrien     (parallel [(set (match_dup 6)
3649132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
365090075Sobrien			      (match_dup 6)))
365190075Sobrien		(use (const_int 1))]))
365290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
365390075Sobrien     (parallel [(set (match_dup 9)
365490075Sobrien		     (float_truncate:DF
3655169689Skan		       (mult:XF (match_dup 7) (match_dup 6))))
365690075Sobrien		(use (const_int 1))]))
365790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
365890075Sobrien     (parallel [(set (match_dup 4)
3659169689Skan		     (minus:DF (match_dup 1)
3660169689Skan			       (mult:DF (match_dup 2) (match_dup 9))))
366190075Sobrien		(use (const_int 1))]))
366290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
366390075Sobrien     (set (match_dup 0)
366490075Sobrien	  (plus:DF (mult:DF (match_dup 4) (match_dup 0))
366590075Sobrien			    (match_dup 9))))
366690075Sobrien  ] 
3667117395Skan{
3668132718Skan  operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3669132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3670132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3671117395Skan  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3672132718Skan  operands[10] = CONST1_RTX (XFmode);
3673117395Skan}
367490075Sobrien  [(set_attr "predicable" "no")])
3675132718Skan
3676132718Skan;; Inline square root.
3677132718Skan
3678132718Skan(define_expand "sqrtdf2"
3679132718Skan  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3680132718Skan	(sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3681132718Skan  "TARGET_INLINE_SQRT"
3682132718Skan{
3683132718Skan  rtx insn;
3684132718Skan#if 0
3685169689Skan  if (TARGET_INLINE_SQRT == INL_MIN_LAT)
3686132718Skan    insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
3687169689Skan  else
3688132718Skan#else
3689169689Skan  gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
3690132718Skan#endif
3691169689Skan  insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
3692132718Skan  emit_insn (insn);
3693132718Skan  DONE;
3694132718Skan})
3695132718Skan
3696132718Skan;; Latency-optimized square root.
3697132718Skan;; FIXME: Implement.
3698132718Skan
3699132718Skan;; Throughput-optimized square root.
3700132718Skan
3701132718Skan(define_insn_and_split "sqrtdf2_internal_thr"
3702132718Skan  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3703132718Skan	(sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))
3704132718Skan   ;; Register r2 in optimization guide.
3705132718Skan   (clobber (match_scratch:DI 2 "=r"))
3706132718Skan   ;; Register f8 in optimization guide
3707132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3708132718Skan   ;; Register f9 in optimization guide
3709132718Skan   (clobber (match_scratch:XF 4 "=&f"))
3710132718Skan   ;; Register f10 in optimization guide
3711132718Skan   (clobber (match_scratch:XF 5 "=&f"))
3712132718Skan   ;; Register p6 in optimization guide.
3713132718Skan   (clobber (match_scratch:BI 6 "=c"))]
3714169689Skan  "TARGET_INLINE_SQRT == INL_MAX_THR"
3715132718Skan  "#"
3716132718Skan  "&& reload_completed"
3717132718Skan  [ ;; exponent of +1/2 in r2
3718132718Skan    (set (match_dup 2) (const_int 65534))
3719132718Skan    ;; +1/2 in f10
3720132718Skan    (set (match_dup 5) 
3721132718Skan         (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3722132718Skan    ;; Step 1
3723132718Skan    ;; y0 = 1/sqrt(a) in f7
3724132718Skan    (parallel [(set (match_dup 7)
3725132718Skan                    (div:XF (const_int 1)
3726132718Skan                            (sqrt:XF (match_dup 8))))
3727132718Skan               (set (match_dup 6)
3728132718Skan                    (unspec:BI [(match_dup 8)]
3729132718Skan                                 UNSPEC_FR_SQRT_RECIP_APPROX))
3730132718Skan               (use (const_int 0))])
3731132718Skan    ;; Step 2
3732132718Skan    ;; H0 = 1/2 * y0 in f8
3733132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3734132718Skan      (parallel [(set (match_dup 3)
3735132718Skan                      (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3736132718Skan                               (match_dup 9)))
3737132718Skan                 (use (const_int 1))]))
3738132718Skan    ;; Step 3
3739132718Skan    ;; G0 = a * y0 in f7
3740132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3741132718Skan      (parallel [(set (match_dup 7)
3742132718Skan                      (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3743132718Skan                               (match_dup 9)))
3744132718Skan                 (use (const_int 1))]))
3745132718Skan    ;; Step 4
3746132718Skan    ;; r0 = 1/2 - G0 * H0 in f9
3747132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3748132718Skan      (parallel [(set (match_dup 4)
3749169689Skan                      (minus:XF (match_dup 5)
3750169689Skan				(mult:XF (match_dup 7) (match_dup 3))))
3751132718Skan                 (use (const_int 1))]))
3752132718Skan    ;; Step 5
3753132718Skan    ;; H1 = H0 + r0 * H0 in f8
3754132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3755132718Skan       (parallel [(set (match_dup 3)
3756132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3757132718Skan                                (match_dup 3)))
3758132718Skan                  (use (const_int 1))]))
3759132718Skan    ;; Step 6
3760132718Skan    ;; G1 = G0 + r0 * G0 in f7
3761132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3762132718Skan       (parallel [(set (match_dup 7)
3763132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3764132718Skan                                (match_dup 7)))
3765132718Skan                  (use (const_int 1))]))
3766132718Skan    ;; Step 7
3767132718Skan    ;; r1 = 1/2 - G1 * H1 in f9
3768132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3769132718Skan      (parallel [(set (match_dup 4)
3770169689Skan                      (minus:XF (match_dup 5)
3771169689Skan				(mult:XF (match_dup 7) (match_dup 3))))
3772132718Skan                 (use (const_int 1))]))
3773132718Skan    ;; Step 8
3774132718Skan    ;; H2 = H1 + r1 * H1 in f8
3775132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3776132718Skan       (parallel [(set (match_dup 3)
3777132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3778132718Skan                                (match_dup 3)))
3779132718Skan                  (use (const_int 1))]))
3780132718Skan    ;; Step 9 
3781132718Skan    ;; G2 = G1 + r1 * G1 in f7
3782132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3783132718Skan       (parallel [(set (match_dup 7)
3784132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3785132718Skan                                (match_dup 7)))
3786132718Skan                  (use (const_int 1))]))
3787132718Skan    ;; Step 10
3788132718Skan    ;; d2 = a - G2 * G2 in f9
3789132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3790132718Skan       (parallel [(set (match_dup 4)
3791169689Skan                       (minus:XF (match_dup 8)
3792169689Skan				 (mult:XF (match_dup 7) (match_dup 7))))
3793132718Skan                  (use (const_int 1))]))
3794132718Skan    ;; Step 11
3795132718Skan    ;; G3 = G2 + d2 * H2 in f7
3796132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3797132718Skan       (parallel [(set (match_dup 7)
3798132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3799132718Skan                                (match_dup 7)))
3800132718Skan                  (use (const_int 1))]))
3801132718Skan    ;; Step 12
3802132718Skan    ;; d3 = a - G3 * G3 in f9
3803132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3804132718Skan       (parallel [(set (match_dup 4)
3805169689Skan                       (minus:XF (match_dup 8)
3806169689Skan				 (mult:XF (match_dup 7) (match_dup 7))))
3807132718Skan                  (use (const_int 1))]))
3808132718Skan    ;; Step 13
3809132718Skan    ;; S = G3 + d3 * H2 in f7
3810132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3811132718Skan       (parallel [(set (match_dup 0)
3812132718Skan                       (float_truncate:DF
3813132718Skan                         (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3814132718Skan                                  (match_dup 7))))
3815132718Skan                  (use (const_int 0))]))]
3816132718Skan{
3817132718Skan  /* Generate 82-bit versions of the input and output operands.  */
3818132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3819132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3820132718Skan  /* Generate required floating-point constants.  */
3821132718Skan  operands[9] = CONST0_RTX (XFmode);
3822132718Skan}
3823132718Skan  [(set_attr "predicable" "no")])
382490075Sobrien
382590075Sobrien;; ::::::::::::::::::::
382690075Sobrien;; ::
382790075Sobrien;; :: 80 bit floating point arithmetic
382890075Sobrien;; ::
382990075Sobrien;; ::::::::::::::::::::
383090075Sobrien
3831132718Skan(define_insn "addxf3"
3832132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3833132718Skan	(plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3834132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3835132718Skan  ""
383690075Sobrien  "fadd %0 = %F1, %F2"
383790075Sobrien  [(set_attr "itanium_class" "fmac")])
383890075Sobrien
3839132718Skan(define_insn "*addxf3_truncsf"
384090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
384190075Sobrien	(float_truncate:SF
3842132718Skan	  (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3843132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3844132718Skan  ""
384590075Sobrien  "fadd.s %0 = %F1, %F2"
384690075Sobrien  [(set_attr "itanium_class" "fmac")])
384790075Sobrien
3848132718Skan(define_insn "*addxf3_truncdf"
384990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
385090075Sobrien	(float_truncate:DF
3851132718Skan	  (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3852132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3853132718Skan  ""
385490075Sobrien  "fadd.d %0 = %F1, %F2"
385590075Sobrien  [(set_attr "itanium_class" "fmac")])
385690075Sobrien
3857132718Skan(define_insn "subxf3"
3858132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3859132718Skan	(minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3860132718Skan		  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3861132718Skan  ""
386290075Sobrien  "fsub %0 = %F1, %F2"
386390075Sobrien  [(set_attr "itanium_class" "fmac")])
386490075Sobrien
3865132718Skan(define_insn "*subxf3_truncsf"
386690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
386790075Sobrien	(float_truncate:SF
3868132718Skan	  (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3869132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3870132718Skan  ""
387190075Sobrien  "fsub.s %0 = %F1, %F2"
387290075Sobrien  [(set_attr "itanium_class" "fmac")])
387390075Sobrien
3874132718Skan(define_insn "*subxf3_truncdf"
387590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
387690075Sobrien	(float_truncate:DF
3877132718Skan	  (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3878132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3879132718Skan  ""
388090075Sobrien  "fsub.d %0 = %F1, %F2"
388190075Sobrien  [(set_attr "itanium_class" "fmac")])
388290075Sobrien
3883132718Skan(define_insn "mulxf3"
3884132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3885132718Skan	(mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3886132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3887132718Skan  ""
388890075Sobrien  "fmpy %0 = %F1, %F2"
388990075Sobrien  [(set_attr "itanium_class" "fmac")])
389090075Sobrien
3891132718Skan(define_insn "*mulxf3_truncsf"
389290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
389390075Sobrien	(float_truncate:SF
3894132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3895132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3896132718Skan  ""
389790075Sobrien  "fmpy.s %0 = %F1, %F2"
389890075Sobrien  [(set_attr "itanium_class" "fmac")])
389990075Sobrien
3900132718Skan(define_insn "*mulxf3_truncdf"
390190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
390290075Sobrien	(float_truncate:DF
3903132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3904132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3905132718Skan  ""
390690075Sobrien  "fmpy.d %0 = %F1, %F2"
390790075Sobrien  [(set_attr "itanium_class" "fmac")])
390890075Sobrien
3909132718Skan(define_insn "*mulxf3_alts"
3910132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3911132718Skan	(mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3912132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
391390075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
3914132718Skan  ""
391590075Sobrien  "fmpy.s%3 %0 = %F1, %F2"
391690075Sobrien  [(set_attr "itanium_class" "fmac")])
391790075Sobrien
3918132718Skan(define_insn "*mulxf3_truncsf_alts"
391990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
392090075Sobrien	(float_truncate:SF
3921132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3922132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
392390075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
3924132718Skan  ""
392590075Sobrien  "fmpy.s.s%3 %0 = %F1, %F2"
392690075Sobrien  [(set_attr "itanium_class" "fmac")])
392790075Sobrien
3928132718Skan(define_insn "*mulxf3_truncdf_alts"
392990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
393090075Sobrien	(float_truncate:DF
3931132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3932132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
393390075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
3934132718Skan  ""
393590075Sobrien  "fmpy.d.s%3 %0 = %F1, %F2"
393690075Sobrien  [(set_attr "itanium_class" "fmac")])
393790075Sobrien
3938132718Skan(define_insn "absxf2"
3939132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3940132718Skan	(abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3941132718Skan  ""
394290075Sobrien  "fabs %0 = %F1"
394390075Sobrien  [(set_attr "itanium_class" "fmisc")])
394490075Sobrien
3945132718Skan(define_insn "negxf2"
3946132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3947132718Skan	(neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3948132718Skan  ""
394990075Sobrien  "fneg %0 = %F1"
395090075Sobrien  [(set_attr "itanium_class" "fmisc")])
395190075Sobrien
3952132718Skan(define_insn "*nabsxf2"
3953132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3954132718Skan	(neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
3955132718Skan  ""
395690075Sobrien  "fnegabs %0 = %F1"
395790075Sobrien  [(set_attr "itanium_class" "fmisc")])
395890075Sobrien
3959169689Skan(define_insn "copysignxf3"
3960169689Skan  [(set (match_operand:XF 0 "register_operand" "=f")
3961169689Skan	(unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3962169689Skan		    (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3963169689Skan		   UNSPEC_COPYSIGN))]
3964169689Skan  ""
3965169689Skan  "fmerge.s %0 = %F2, %F1"
3966169689Skan  [(set_attr "itanium_class" "fmisc")])
3967169689Skan
3968169689Skan(define_insn "*ncopysignxf3"
3969169689Skan  [(set (match_operand:XF 0 "register_operand" "=f")
3970169689Skan	(neg:XF (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
3971169689Skan			    (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
3972169689Skan			   UNSPEC_COPYSIGN)))]
3973169689Skan  ""
3974169689Skan  "fmerge.ns %0 = %F2, %F1"
3975169689Skan  [(set_attr "itanium_class" "fmisc")])
3976169689Skan
3977169689Skan(define_insn "sminxf3"
3978132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3979132718Skan	(smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3980132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3981132718Skan  ""
398290075Sobrien  "fmin %0 = %F1, %F2"
398390075Sobrien  [(set_attr "itanium_class" "fmisc")])
398490075Sobrien
3985169689Skan(define_insn "smaxxf3"
3986132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3987132718Skan	(smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3988132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3989132718Skan  ""
399090075Sobrien  "fmax %0 = %F1, %F2"
399190075Sobrien  [(set_attr "itanium_class" "fmisc")])
399290075Sobrien
3993132718Skan(define_insn "*maddxf4"
3994132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3995132718Skan	(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3996132718Skan			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3997132718Skan		 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3998132718Skan  ""
399990075Sobrien  "fma %0 = %F1, %F2, %F3"
400090075Sobrien  [(set_attr "itanium_class" "fmac")])
400190075Sobrien
4002132718Skan(define_insn "*maddxf4_truncsf"
400390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
400490075Sobrien	(float_truncate:SF
4005132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4006132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4007132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4008132718Skan  ""
400990075Sobrien  "fma.s %0 = %F1, %F2, %F3"
401090075Sobrien  [(set_attr "itanium_class" "fmac")])
401190075Sobrien
4012132718Skan(define_insn "*maddxf4_truncdf"
401390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
401490075Sobrien	(float_truncate:DF
4015132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4016132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4017132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4018132718Skan  ""
401990075Sobrien  "fma.d %0 = %F1, %F2, %F3"
402090075Sobrien  [(set_attr "itanium_class" "fmac")])
402190075Sobrien
4022132718Skan(define_insn "*maddxf4_alts"
4023132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
4024132718Skan	(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4025132718Skan			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4026132718Skan		 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
402790075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
4028132718Skan  ""
402990075Sobrien  "fma.s%4 %0 = %F1, %F2, %F3"
403090075Sobrien  [(set_attr "itanium_class" "fmac")])
403190075Sobrien
4032132718Skan(define_insn "*maddxf4_alts_truncsf"
4033132718Skan  [(set (match_operand:SF 0 "fr_register_operand" "=f")
4034132718Skan	(float_truncate:SF
4035132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4036132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4037132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
4038132718Skan   (use (match_operand:SI 4 "const_int_operand" ""))]
4039132718Skan  ""
4040132718Skan  "fma.s.s%4 %0 = %F1, %F2, %F3"
4041132718Skan  [(set_attr "itanium_class" "fmac")])
4042132718Skan
4043132718Skan(define_insn "*maddxf4_alts_truncdf"
404490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
404590075Sobrien	(float_truncate:DF
4046132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4047132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4048132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
404990075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
4050132718Skan  ""
405190075Sobrien  "fma.d.s%4 %0 = %F1, %F2, %F3"
405290075Sobrien  [(set_attr "itanium_class" "fmac")])
405390075Sobrien
4054132718Skan(define_insn "*msubxf4"
4055132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
4056132718Skan	(minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4057132718Skan			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4058132718Skan		  (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
4059132718Skan  ""
406090075Sobrien  "fms %0 = %F1, %F2, %F3"
406190075Sobrien  [(set_attr "itanium_class" "fmac")])
406290075Sobrien
4063132718Skan(define_insn "*msubxf4_truncsf"
406490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
406590075Sobrien	(float_truncate:SF
4066132718Skan	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4067132718Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4068132718Skan		    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4069132718Skan  ""
407090075Sobrien  "fms.s %0 = %F1, %F2, %F3"
407190075Sobrien  [(set_attr "itanium_class" "fmac")])
407290075Sobrien
4073132718Skan(define_insn "*msubxf4_truncdf"
407490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
407590075Sobrien	(float_truncate:DF
4076132718Skan	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4077132718Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
4078132718Skan		    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
4079132718Skan  ""
408090075Sobrien  "fms.d %0 = %F1, %F2, %F3"
408190075Sobrien  [(set_attr "itanium_class" "fmac")])
408290075Sobrien
4083132718Skan(define_insn "*nmulxf3"
4084132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
4085132718Skan	(neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4086132718Skan			 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
4087132718Skan  ""
408890075Sobrien  "fnmpy %0 = %F1, %F2"
408990075Sobrien  [(set_attr "itanium_class" "fmac")])
409090075Sobrien
4091132718Skan(define_insn "*nmulxf3_truncsf"
409290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
409390075Sobrien	(float_truncate:SF
4094132718Skan	  (neg:XF (mult:XF
4095132718Skan		    (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4096132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
4097132718Skan  ""
409890075Sobrien  "fnmpy.s %0 = %F1, %F2"
409990075Sobrien  [(set_attr "itanium_class" "fmac")])
410090075Sobrien
4101132718Skan(define_insn "*nmulxf3_truncdf"
410290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
410390075Sobrien	(float_truncate:DF
4104132718Skan	  (neg:XF (mult:XF
4105132718Skan		    (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4106132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
4107132718Skan  ""
410890075Sobrien  "fnmpy.d %0 = %F1, %F2"
410990075Sobrien  [(set_attr "itanium_class" "fmac")])
411090075Sobrien
4111132718Skan(define_insn "*nmaddxf4"
4112132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
4113169689Skan	(minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
4114169689Skan		  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4115169689Skan			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4116169689Skan   )))]
4117132718Skan  ""
411890075Sobrien  "fnma %0 = %F1, %F2, %F3"
411990075Sobrien  [(set_attr "itanium_class" "fmac")])
412090075Sobrien
4121132718Skan(define_insn "*nmaddxf4_truncsf"
412290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
412390075Sobrien	(float_truncate:SF
4124169689Skan	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4125169689Skan		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4126169689Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4127169689Skan   ))))]
4128132718Skan  ""
412990075Sobrien  "fnma.s %0 = %F1, %F2, %F3"
413090075Sobrien  [(set_attr "itanium_class" "fmac")])
413190075Sobrien
4132132718Skan(define_insn "*nmaddxf4_truncdf"
413390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
413490075Sobrien	(float_truncate:DF
4135169689Skan	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4136169689Skan		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4137169689Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4138169689Skan   ))))]
4139132718Skan  ""
414090075Sobrien  "fnma.d %0 = %F1, %F2, %F3"
414190075Sobrien  [(set_attr "itanium_class" "fmac")])
414290075Sobrien
4143132718Skan(define_insn "*nmaddxf4_alts"
4144132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
4145169689Skan	(minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
4146169689Skan		  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4147169689Skan			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4148169689Skan   )))
414990075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
4150132718Skan  ""
415190075Sobrien  "fnma.s%4 %0 = %F1, %F2, %F3"
415290075Sobrien  [(set_attr "itanium_class" "fmac")])
415390075Sobrien
4154169689Skan(define_insn "*nmaddxf4_truncsf_alts"
4155169689Skan  [(set (match_operand:SF 0 "fr_register_operand" "=f")
4156169689Skan	(float_truncate:SF
4157169689Skan	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4158169689Skan		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4159169689Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4160169689Skan   ))))
4161169689Skan   (use (match_operand:SI 4 "const_int_operand" ""))]
4162169689Skan  ""
4163169689Skan  "fnma.s.s%4 %0 = %F1, %F2, %F3"
4164169689Skan  [(set_attr "itanium_class" "fmac")])
4165169689Skan
4166132718Skan(define_insn "*nmaddxf4_truncdf_alts"
416790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
416890075Sobrien	(float_truncate:DF
4169169689Skan	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
4170169689Skan		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
4171169689Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4172169689Skan   ))))
417390075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
4174132718Skan  ""
417590075Sobrien  "fnma.d.s%4 %0 = %F1, %F2, %F3"
417690075Sobrien  [(set_attr "itanium_class" "fmac")])
417790075Sobrien
4178132718Skan(define_expand "divxf3"
4179132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "")
4180132718Skan	(div:XF (match_operand:XF 1 "fr_register_operand" "")
4181132718Skan		(match_operand:XF 2 "fr_register_operand" "")))]
4182132718Skan  "TARGET_INLINE_FLOAT_DIV"
418390075Sobrien{
418490075Sobrien  rtx insn;
4185169689Skan  if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
4186132718Skan    insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
418790075Sobrien  else
4188132718Skan    insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
418990075Sobrien  emit_insn (insn);
419090075Sobrien  DONE;
4191117395Skan})
419290075Sobrien
4193132718Skan(define_insn_and_split "divxf3_internal_lat"
4194132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4195132718Skan	(div:XF (match_operand:XF 1 "fr_register_operand" "f")
4196132718Skan		(match_operand:XF 2 "fr_register_operand" "f")))
4197132718Skan   (clobber (match_scratch:XF 3 "=&f"))
4198132718Skan   (clobber (match_scratch:XF 4 "=&f"))
4199132718Skan   (clobber (match_scratch:XF 5 "=&f"))
4200132718Skan   (clobber (match_scratch:XF 6 "=&f"))
420190075Sobrien   (clobber (match_scratch:BI 7 "=c"))]
4202169689Skan  "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT"
420390075Sobrien  "#"
420490075Sobrien  "&& reload_completed"
4205132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
4206117395Skan	      (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
4207117395Skan					    UNSPEC_FR_RECIP_APPROX))
4208169689Skan	      (use (const_int 0))])
420990075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
421090075Sobrien     (parallel [(set (match_dup 3)
4211169689Skan		     (minus:XF (match_dup 8)
4212169689Skan			       (mult:XF (match_dup 2) (match_dup 0))))
421390075Sobrien		(use (const_int 1))]))
421490075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
4215132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
421690075Sobrien		(use (const_int 1))]))
421790075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
4218132718Skan     (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
421990075Sobrien		(use (const_int 1))]))
422090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
422190075Sobrien     (parallel [(set (match_dup 6)
4222132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 3))
422390075Sobrien			      (match_dup 3)))
422490075Sobrien		(use (const_int 1))]))
422590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
422690075Sobrien     (parallel [(set (match_dup 3)
4227132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 5))
422890075Sobrien			      (match_dup 3)))
422990075Sobrien		(use (const_int 1))]))
423090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
423190075Sobrien     (parallel [(set (match_dup 5)
4232132718Skan		     (plus:XF (mult:XF (match_dup 6) (match_dup 0))
423390075Sobrien			      (match_dup 0)))
423490075Sobrien		(use (const_int 1))]))
423590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
423690075Sobrien     (parallel [(set (match_dup 0)
4237132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 3))
423890075Sobrien			      (match_dup 0)))
423990075Sobrien		(use (const_int 1))]))
424090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
424190075Sobrien     (parallel [(set (match_dup 4)
4242169689Skan		     (minus:XF (match_dup 1)
4243169689Skan			       (mult:XF (match_dup 2) (match_dup 4))))
424490075Sobrien		(use (const_int 1))]))
424590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
424690075Sobrien     (parallel [(set (match_dup 3)
4247132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
424890075Sobrien			      (match_dup 4)))
424990075Sobrien		(use (const_int 1))]))
425090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
425190075Sobrien     (parallel [(set (match_dup 5)
4252169689Skan		     (minus:XF (match_dup 8)
4253169689Skan			       (mult:XF (match_dup 2) (match_dup 0))))
425490075Sobrien		(use (const_int 1))]))
425590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
425690075Sobrien     (parallel [(set (match_dup 0)
4257132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
425890075Sobrien			      (match_dup 0)))
425990075Sobrien		(use (const_int 1))]))
426090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
426190075Sobrien     (parallel [(set (match_dup 4)
4262169689Skan		     (minus:XF (match_dup 1)
4263169689Skan			       (mult:XF (match_dup 2) (match_dup 3))))
426490075Sobrien		(use (const_int 1))]))
426590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
426690075Sobrien     (set (match_dup 0)
4267132718Skan	  (plus:XF (mult:XF (match_dup 4) (match_dup 0))
426890075Sobrien		   (match_dup 3))))
426990075Sobrien  ] 
4270132718Skan  "operands[8] = CONST1_RTX (XFmode);"
427190075Sobrien  [(set_attr "predicable" "no")])
427290075Sobrien
4273132718Skan(define_insn_and_split "divxf3_internal_thr"
4274132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4275132718Skan	(div:XF (match_operand:XF 1 "fr_register_operand" "f")
4276132718Skan		(match_operand:XF 2 "fr_register_operand" "f")))
4277132718Skan   (clobber (match_scratch:XF 3 "=&f"))
4278132718Skan   (clobber (match_scratch:XF 4 "=&f"))
427990075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
4280169689Skan  "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR"
428190075Sobrien  "#"
428290075Sobrien  "&& reload_completed"
4283132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
4284117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
4285117395Skan					    UNSPEC_FR_RECIP_APPROX))
4286169689Skan	      (use (const_int 0))])
428790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
428890075Sobrien     (parallel [(set (match_dup 3)
4289169689Skan		     (minus:XF (match_dup 6)
4290169689Skan			       (mult:XF (match_dup 2) (match_dup 0))))
429190075Sobrien		(use (const_int 1))]))
429290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
429390075Sobrien     (parallel [(set (match_dup 4)
4294132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
429590075Sobrien			      (match_dup 0)))
429690075Sobrien		(use (const_int 1))]))
429790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
4298132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
429990075Sobrien		(use (const_int 1))]))
430090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
430190075Sobrien     (parallel [(set (match_dup 3)
4302132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 4))
430390075Sobrien			      (match_dup 4)))
430490075Sobrien		(use (const_int 1))]))
430590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
4306132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
430790075Sobrien		(use (const_int 1))]))
430890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
430990075Sobrien     (parallel [(set (match_dup 0)
4310169689Skan		     (minus:XF (match_dup 6)
4311169689Skan			       (mult:XF (match_dup 2) (match_dup 3))))
431290075Sobrien		(use (const_int 1))]))
431390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
431490075Sobrien     (parallel [(set (match_dup 0)
4315132718Skan		     (plus:XF (mult:XF (match_dup 0) (match_dup 3))
431690075Sobrien			      (match_dup 3)))
431790075Sobrien		(use (const_int 1))]))
431890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
431990075Sobrien     (parallel [(set (match_dup 3)
4320169689Skan		     (minus:XF (match_dup 1)
4321169689Skan			       (mult:XF (match_dup 2) (match_dup 4))))
432290075Sobrien		(use (const_int 1))]))
432390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
432490075Sobrien     (parallel [(set (match_dup 3)
4325132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
432690075Sobrien			      (match_dup 4)))
432790075Sobrien		(use (const_int 1))]))
432890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
432990075Sobrien     (parallel [(set (match_dup 4)
4330169689Skan		     (minus:XF (match_dup 6)
4331169689Skan			       (mult:XF (match_dup 2) (match_dup 0))))
433290075Sobrien		(use (const_int 1))]))
433390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
433490075Sobrien     (parallel [(set (match_dup 0)
4335132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
433690075Sobrien			      (match_dup 0)))
433790075Sobrien		(use (const_int 1))]))
433890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
433990075Sobrien     (parallel [(set (match_dup 4)
4340169689Skan		     (minus:XF (match_dup 1)
4341169689Skan			       (mult:XF (match_dup 2) (match_dup 3))))
434290075Sobrien		(use (const_int 1))]))
434390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
434490075Sobrien     (set (match_dup 0)
4345132718Skan	  (plus:XF (mult:XF (match_dup 4) (match_dup 0))
434690075Sobrien		   (match_dup 3))))
434790075Sobrien  ] 
4348132718Skan  "operands[6] = CONST1_RTX (XFmode);"
434990075Sobrien  [(set_attr "predicable" "no")])
435090075Sobrien
4351132718Skan;; Inline square root.
4352132718Skan
4353132718Skan(define_expand "sqrtxf2"
4354132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4355132718Skan	(sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))]
4356132718Skan  "TARGET_INLINE_SQRT"
4357132718Skan{
4358132718Skan  rtx insn;
4359132718Skan#if 0
4360169689Skan  if (TARGET_INLINE_SQRT == INL_MIN_LAT)
4361132718Skan    insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
4362169689Skan  else
4363132718Skan#else
4364169689Skan  gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
4365132718Skan#endif
4366169689Skan  insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]);
4367132718Skan  emit_insn (insn);
4368132718Skan  DONE;
4369132718Skan})
4370132718Skan
4371132718Skan;; Latency-optimized square root.
4372132718Skan;; FIXME: Implement.
4373132718Skan
4374132718Skan;; Throughput-optimized square root.
4375132718Skan
4376132718Skan(define_insn_and_split "sqrtxf2_internal_thr"
4377132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
4378132718Skan	(sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))
4379132718Skan   ;; Register r2 in optimization guide.
4380132718Skan   (clobber (match_scratch:DI 2 "=r"))
4381132718Skan   ;; Register f8 in optimization guide
4382132718Skan   (clobber (match_scratch:XF 3 "=&f"))
4383132718Skan   ;; Register f9 in optimization guide
4384132718Skan   (clobber (match_scratch:XF 4 "=&f"))
4385132718Skan   ;; Register f10 in optimization guide
4386132718Skan   (clobber (match_scratch:XF 5 "=&f"))
4387132718Skan   ;; Register f11 in optimization guide
4388132718Skan   (clobber (match_scratch:XF 6 "=&f"))
4389132718Skan   ;; Register p6 in optimization guide.
4390132718Skan   (clobber (match_scratch:BI 7 "=c"))]
4391169689Skan  "TARGET_INLINE_SQRT == INL_MAX_THR"
4392132718Skan  "#"
4393132718Skan  "&& reload_completed"
4394132718Skan  [ ;; exponent of +1/2 in r2
4395132718Skan    (set (match_dup 2) (const_int 65534))
4396132718Skan    ;; +1/2 in f8.  The Intel manual mistakenly specifies f10.
4397132718Skan    (set (match_dup 3) 
4398132718Skan         (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
4399132718Skan    ;; Step 1
4400132718Skan    ;; y0 = 1/sqrt(a) in f7
4401132718Skan    (parallel [(set (match_dup 8)
4402132718Skan                    (div:XF (const_int 1)
4403132718Skan                            (sqrt:XF (match_dup 9))))
4404132718Skan               (set (match_dup 7)
4405132718Skan                    (unspec:BI [(match_dup 9)]
4406132718Skan                                 UNSPEC_FR_SQRT_RECIP_APPROX))
4407132718Skan               (use (const_int 0))])
4408132718Skan    ;; Step 2
4409132718Skan    ;; H0 = 1/2 * y0 in f9
4410132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4411132718Skan      (parallel [(set (match_dup 4)
4412132718Skan                      (plus:XF (mult:XF (match_dup 3) (match_dup 8))
4413132718Skan                               (match_dup 10)))
4414132718Skan                 (use (const_int 1))]))
4415132718Skan    ;; Step 3
4416132718Skan    ;; S0 = a * y0 in f7
4417132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4418132718Skan      (parallel [(set (match_dup 8)
4419132718Skan                      (plus:XF (mult:XF (match_dup 9) (match_dup 8))
4420132718Skan                               (match_dup 10)))
4421132718Skan                 (use (const_int 1))]))
4422132718Skan    ;; Step 4
4423132718Skan    ;; d0 = 1/2 - S0 * H0 in f10
4424132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4425132718Skan      (parallel [(set (match_dup 5)
4426169689Skan                      (minus:XF (match_dup 3)
4427169689Skan				(mult:XF (match_dup 8) (match_dup 4))))
4428132718Skan                 (use (const_int 1))]))
4429132718Skan    ;; Step 5
4430132718Skan    ;; H1 = H0 + d0 * H0 in f9
4431132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4432132718Skan       (parallel [(set (match_dup 4)
4433132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4434132718Skan                                (match_dup 4)))
4435132718Skan                  (use (const_int 1))]))
4436132718Skan    ;; Step 6
4437132718Skan    ;; S1 = S0 + d0 * S0 in f7
4438132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4439132718Skan       (parallel [(set (match_dup 8)
4440132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 8))
4441132718Skan                                (match_dup 8)))
4442132718Skan                  (use (const_int 1))]))
4443132718Skan    ;; Step 7
4444132718Skan    ;; d1 = 1/2 - S1 * H1 in f10
4445132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4446132718Skan      (parallel [(set (match_dup 5)
4447169689Skan                      (minus:XF (match_dup 3)
4448169689Skan				(mult:XF (match_dup 8) (match_dup 4))))
4449132718Skan                 (use (const_int 1))]))
4450132718Skan    ;; Step 8
4451132718Skan    ;; H2 = H1 + d1 * H1 in f9
4452132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4453132718Skan       (parallel [(set (match_dup 4)
4454132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4455132718Skan                                (match_dup 4)))
4456132718Skan                  (use (const_int 1))]))
4457132718Skan    ;; Step 9 
4458132718Skan    ;; S2 = S1 + d1 * S1 in f7
4459132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4460132718Skan       (parallel [(set (match_dup 8)
4461132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 8))
4462132718Skan                                (match_dup 8)))
4463132718Skan                  (use (const_int 1))]))
4464132718Skan    ;; Step 10
4465132718Skan    ;; d2 = 1/2 - S2 * H2 in f10
4466132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4467132718Skan       (parallel [(set (match_dup 5)
4468169689Skan                       (minus:XF (match_dup 3)
4469169689Skan				 (mult:XF (match_dup 8) (match_dup 4))))
4470132718Skan                  (use (const_int 1))]))
4471132718Skan    ;; Step 11
4472132718Skan    ;; e2 = a - S2 * S2 in f8
4473132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4474132718Skan       (parallel [(set (match_dup 3)
4475169689Skan                       (minus:XF (match_dup 9)
4476169689Skan				 (mult:XF (match_dup 8) (match_dup 8))))
4477132718Skan                  (use (const_int 1))]))
4478132718Skan    ;; Step 12
4479132718Skan    ;; S3 = S2 + e2 * H2 in f7
4480132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4481132718Skan       (parallel [(set (match_dup 8)
4482132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4483132718Skan                                (match_dup 8)))
4484132718Skan                  (use (const_int 1))]))
4485132718Skan    ;; Step 13
4486132718Skan    ;; H3 = H2 + d2 * H2 in f9
4487132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4488132718Skan       (parallel [(set (match_dup 4)
4489132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4490132718Skan                                (match_dup 4)))
4491132718Skan                  (use (const_int 1))]))
4492132718Skan    ;; Step 14
4493132718Skan    ;; e3 = a - S3 * S3 in f8
4494132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4495132718Skan       (parallel [(set (match_dup 3)
4496169689Skan                       (minus:XF (match_dup 9)
4497169689Skan				 (mult:XF (match_dup 8) (match_dup 8))))
4498132718Skan                  (use (const_int 1))]))
4499132718Skan    ;; Step 15
4500132718Skan    ;; S = S3 + e3 * H3 in f7
4501132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4502132718Skan       (parallel [(set (match_dup 0)
4503132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4504132718Skan                                (match_dup 8)))
4505132718Skan                  (use (const_int 0))]))]
4506132718Skan{
4507132718Skan  /* Generate 82-bit versions of the input and output operands.  */
4508132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0]));
4509132718Skan  operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1]));
4510132718Skan  /* Generate required floating-point constants.  */
4511132718Skan  operands[10] = CONST0_RTX (XFmode);
4512132718Skan}
4513132718Skan  [(set_attr "predicable" "no")])
4514132718Skan
451590075Sobrien;; ??? frcpa works like cmp.foo.unc.
451690075Sobrien
451790075Sobrien(define_insn "*recip_approx"
4518132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
4519132718Skan	(div:XF (const_int 1)
4520132718Skan		(match_operand:XF 3 "fr_register_operand" "f")))
452190075Sobrien   (set (match_operand:BI 1 "register_operand" "=c")
4522132718Skan	(unspec:BI [(match_operand:XF 2 "fr_register_operand" "f")
4523117395Skan		    (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
452490075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
4525132718Skan  ""
452690075Sobrien  "frcpa.s%4 %0, %1 = %2, %3"
452790075Sobrien  [(set_attr "itanium_class" "fmisc")
452890075Sobrien   (set_attr "predicable" "no")])
452990075Sobrien
453090075Sobrien;; ::::::::::::::::::::
453190075Sobrien;; ::
453290075Sobrien;; :: 32 bit Integer Shifts and Rotates
453390075Sobrien;; ::
453490075Sobrien;; ::::::::::::::::::::
453590075Sobrien
453690075Sobrien(define_expand "ashlsi3"
453790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
453890075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "")
453990075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
454090075Sobrien  ""
454190075Sobrien{
454290075Sobrien  if (GET_CODE (operands[2]) != CONST_INT)
454390075Sobrien    {
454490075Sobrien      /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
454590075Sobrien	 we've got to get rid of stray bits outside the SImode register.  */
454690075Sobrien      rtx subshift = gen_reg_rtx (DImode);
454790075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
454890075Sobrien      operands[2] = subshift;
454990075Sobrien    }
4550117395Skan})
455190075Sobrien
455290075Sobrien(define_insn "*ashlsi3_internal"
455390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
455490075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
455590075Sobrien		   (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
455690075Sobrien  ""
455790075Sobrien  "@
455890075Sobrien   shladd %0 = %1, %2, r0
455990075Sobrien   dep.z %0 = %1, %2, %E2
456090075Sobrien   shl %0 = %1, %2"
456190075Sobrien  [(set_attr "itanium_class" "ialu,ishf,mmshf")])
456290075Sobrien
456390075Sobrien(define_expand "ashrsi3"
456490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
456590075Sobrien	(ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
456690075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
456790075Sobrien  ""
456890075Sobrien{
456990075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
457090075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
457190075Sobrien    emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
457290075Sobrien			 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
457390075Sobrien  else
457490075Sobrien    {
457590075Sobrien      rtx subshift = gen_reg_rtx (DImode);
457690075Sobrien      emit_insn (gen_extendsidi2 (subtarget, operands[1]));
457790075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
457890075Sobrien      emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
457990075Sobrien    }
458090075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
458190075Sobrien  DONE;
4582117395Skan})
458390075Sobrien
458490075Sobrien(define_expand "lshrsi3"
458590075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
458690075Sobrien	(lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
458790075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
458890075Sobrien  ""
458990075Sobrien{
459090075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
459190075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
459290075Sobrien    emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
459390075Sobrien			  GEN_INT (32 - INTVAL (operands[2])), operands[2]));
459490075Sobrien  else
459590075Sobrien    {
459690075Sobrien      rtx subshift = gen_reg_rtx (DImode);
459790075Sobrien      emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
459890075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
459990075Sobrien      emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
460090075Sobrien    }
460190075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
460290075Sobrien  DONE;
4603117395Skan})
460490075Sobrien
460590075Sobrien;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
460690075Sobrien;; here, instead of 64 like the patterns above.  Keep the pattern together
460790075Sobrien;; until after combine; otherwise it won't get matched often.
460890075Sobrien
460990075Sobrien(define_expand "rotrsi3"
461090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
461190075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
461290075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
461390075Sobrien  ""
461490075Sobrien{
461590075Sobrien  if (GET_MODE (operands[2]) != VOIDmode)
461690075Sobrien    {
461790075Sobrien      rtx tmp = gen_reg_rtx (DImode);
461890075Sobrien      emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
461990075Sobrien      operands[2] = tmp;
462090075Sobrien    }
4621117395Skan})
462290075Sobrien
462390075Sobrien(define_insn_and_split "*rotrsi3_internal"
462490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=&r")
462590075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
462690075Sobrien		     (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
462790075Sobrien  ""
462890075Sobrien  "#"
462990075Sobrien  "reload_completed"
463090075Sobrien  [(set (match_dup 3)
463190075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
463290075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
463390075Sobrien   (set (match_dup 3)
463490075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
463590075Sobrien  "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
463690075Sobrien
463790075Sobrien(define_expand "rotlsi3"
463890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
463990075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "")
464090075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
464190075Sobrien  ""
464290075Sobrien{
464390075Sobrien  if (! shift_32bit_count_operand (operands[2], SImode))
464490075Sobrien    {
464590075Sobrien      rtx tmp = gen_reg_rtx (SImode);
464690075Sobrien      emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
464790075Sobrien      emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
464890075Sobrien      DONE;
464990075Sobrien    }
4650117395Skan})
465190075Sobrien
465290075Sobrien(define_insn_and_split "*rotlsi3_internal"
465390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
465490075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
465590075Sobrien		   (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
465690075Sobrien  ""
4657169689Skan  "mux2 %0 = %1, 0xe1"
4658169689Skan  "reload_completed && INTVAL (operands[2]) != 16"
465990075Sobrien  [(set (match_dup 3)
466090075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
466190075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
466290075Sobrien   (set (match_dup 3)
466390075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
4664117395Skan{
4665117395Skan  operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
4666117395Skan  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4667169689Skan}
4668169689Skan  [(set_attr "itanium_class" "mmshf")])
466990075Sobrien
467090075Sobrien;; ::::::::::::::::::::
467190075Sobrien;; ::
467290075Sobrien;; :: 64 bit Integer Shifts and Rotates
467390075Sobrien;; ::
467490075Sobrien;; ::::::::::::::::::::
467590075Sobrien
467690075Sobrien(define_insn "ashldi3"
467790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
467890075Sobrien	(ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
467990075Sobrien		   (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
468090075Sobrien  ""
468190075Sobrien  "@
468290075Sobrien   shladd %0 = %1, %2, r0
468390075Sobrien   shl %0 = %1, %2
468490075Sobrien   shl %0 = %1, %2"
468590075Sobrien  [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
468690075Sobrien
468790075Sobrien;; ??? Maybe combine this with the multiply and add instruction?
468890075Sobrien
468990075Sobrien(define_insn "*shladd"
469090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
469190075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
469290075Sobrien			  (match_operand:DI 2 "shladd_operand" "n"))
469390075Sobrien		 (match_operand:DI 3 "gr_register_operand" "r")))]
469490075Sobrien  ""
469590075Sobrien  "shladd %0 = %1, %S2, %3"
469690075Sobrien  [(set_attr "itanium_class" "ialu")])
469790075Sobrien
469890075Sobrien;; This can be created by register elimination if operand3 of shladd is an
469990075Sobrien;; eliminable register or has reg_equiv_constant set.
470090075Sobrien
470190075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
470290075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
470390075Sobrien;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
470490075Sobrien;; incorrectly.
470590075Sobrien
470690075Sobrien(define_insn_and_split "*shladd_elim"
470790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=&r")
470890075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
470990075Sobrien				   (match_operand:DI 2 "shladd_operand" "n"))
471090075Sobrien			  (match_operand:DI 3 "nonmemory_operand" "r"))
471190075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))]
471290075Sobrien  "reload_in_progress"
4713169689Skan  "* gcc_unreachable ();"
471490075Sobrien  "reload_completed"
471590075Sobrien  [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
471690075Sobrien			       (match_dup 3)))
471790075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
471890075Sobrien  ""
471990075Sobrien  [(set_attr "itanium_class" "unknown")])
472090075Sobrien
472190075Sobrien(define_insn "ashrdi3"
472290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
472390075Sobrien	(ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
472490075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
472590075Sobrien  ""
472690075Sobrien  "@
472790075Sobrien   shr %0 = %1, %2
472890075Sobrien   shr %0 = %1, %2"
472990075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
473090075Sobrien
473190075Sobrien(define_insn "lshrdi3"
473290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
473390075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
473490075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
473590075Sobrien  ""
473690075Sobrien  "@
473790075Sobrien   shr.u %0 = %1, %2
473890075Sobrien   shr.u %0 = %1, %2"
473990075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
474090075Sobrien
474190075Sobrien;; Using a predicate that accepts only constants doesn't work, because optabs
474290075Sobrien;; will load the operand into a register and call the pattern if the predicate
474390075Sobrien;; did not accept it on the first try.  So we use nonmemory_operand and then
474490075Sobrien;; verify that we have an appropriate constant in the expander.
474590075Sobrien
474690075Sobrien(define_expand "rotrdi3"
474790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
474890075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
474990075Sobrien		     (match_operand:DI 2 "nonmemory_operand" "")))]
475090075Sobrien  ""
475190075Sobrien{
475290075Sobrien  if (! shift_count_operand (operands[2], DImode))
475390075Sobrien    FAIL;
4754117395Skan})
475590075Sobrien
475690075Sobrien(define_insn "*rotrdi3_internal"
475790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
475890075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
475990075Sobrien		     (match_operand:DI 2 "shift_count_operand" "M")))]
476090075Sobrien  ""
476190075Sobrien  "shrp %0 = %1, %1, %2"
476290075Sobrien  [(set_attr "itanium_class" "ishf")])
476390075Sobrien
476490075Sobrien(define_expand "rotldi3"
476590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
476690075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "")
476790075Sobrien		   (match_operand:DI 2 "nonmemory_operand" "")))]
476890075Sobrien  ""
476990075Sobrien{
477090075Sobrien  if (! shift_count_operand (operands[2], DImode))
477190075Sobrien    FAIL;
4772117395Skan})
477390075Sobrien
477490075Sobrien(define_insn "*rotldi3_internal"
477590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
477690075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
477790075Sobrien		   (match_operand:DI 2 "shift_count_operand" "M")))]
477890075Sobrien  ""
477990075Sobrien  "shrp %0 = %1, %1, %e2"
478090075Sobrien  [(set_attr "itanium_class" "ishf")])
478190075Sobrien
478290075Sobrien;; ::::::::::::::::::::
478390075Sobrien;; ::
4784169689Skan;; :: 128 bit Integer Shifts and Rotates
4785169689Skan;; ::
4786169689Skan;; ::::::::::::::::::::
4787169689Skan
4788169689Skan(define_expand "ashlti3"
4789169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "")
4790169689Skan	(ashift:TI (match_operand:TI 1 "gr_register_operand" "")
4791169689Skan		   (match_operand:DI 2 "nonmemory_operand" "")))]
4792169689Skan  ""
4793169689Skan{
4794169689Skan  if (!dshift_count_operand (operands[2], DImode))
4795169689Skan    FAIL;
4796169689Skan})
4797169689Skan
4798169689Skan(define_insn_and_split "*ashlti3_internal"
4799169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4800169689Skan	(ashift:TI (match_operand:TI 1 "gr_register_operand" "r")
4801169689Skan		   (match_operand:DI 2 "dshift_count_operand" "n")))]
4802169689Skan  ""
4803169689Skan  "#"
4804169689Skan  "reload_completed"
4805169689Skan  [(const_int 0)]
4806169689Skan{
4807169689Skan  HOST_WIDE_INT shift = INTVAL (operands[2]);
4808169689Skan  rtx rl = gen_lowpart (DImode, operands[0]);
4809169689Skan  rtx rh = gen_highpart (DImode, operands[0]);
4810169689Skan  rtx lo = gen_lowpart (DImode, operands[1]);
4811169689Skan  rtx shiftlo = GEN_INT (shift & 63);
4812169689Skan
4813169689Skan  if (shift & 64)
4814169689Skan    {
4815169689Skan      emit_move_insn (rl, const0_rtx);
4816169689Skan      if (shift & 63)
4817169689Skan	emit_insn (gen_ashldi3 (rh, lo, shiftlo));
4818169689Skan      else
4819169689Skan	emit_move_insn (rh, lo);
4820169689Skan    }
4821169689Skan  else
4822169689Skan    {
4823169689Skan      rtx hi = gen_highpart (DImode, operands[1]);
4824169689Skan
4825169689Skan      emit_insn (gen_shrp (rh, hi, lo, GEN_INT (-shift & 63)));
4826169689Skan      emit_insn (gen_ashldi3 (rl, lo, shiftlo));
4827169689Skan    }
4828169689Skan  DONE;
4829169689Skan})
4830169689Skan
4831169689Skan(define_expand "ashrti3"
4832169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "")
4833169689Skan	(ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
4834169689Skan		     (match_operand:DI 2 "nonmemory_operand" "")))]
4835169689Skan  ""
4836169689Skan{
4837169689Skan  if (!dshift_count_operand (operands[2], DImode))
4838169689Skan    FAIL;
4839169689Skan})
4840169689Skan
4841169689Skan(define_insn_and_split "*ashrti3_internal"
4842169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4843169689Skan	(ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
4844169689Skan		     (match_operand:DI 2 "dshift_count_operand" "n")))]
4845169689Skan  ""
4846169689Skan  "#"
4847169689Skan  "reload_completed"
4848169689Skan  [(const_int 0)]
4849169689Skan{
4850169689Skan  HOST_WIDE_INT shift = INTVAL (operands[2]);
4851169689Skan  rtx rl = gen_lowpart (DImode, operands[0]);
4852169689Skan  rtx rh = gen_highpart (DImode, operands[0]);
4853169689Skan  rtx hi = gen_highpart (DImode, operands[1]);
4854169689Skan  rtx shiftlo = GEN_INT (shift & 63);
4855169689Skan
4856169689Skan  if (shift & 64)
4857169689Skan    {
4858169689Skan      if (shift & 63)
4859169689Skan	emit_insn (gen_ashrdi3 (rl, hi, shiftlo));
4860169689Skan      else
4861169689Skan	emit_move_insn (rl, hi);
4862169689Skan      emit_insn (gen_ashrdi3 (rh, hi, GEN_INT (63)));
4863169689Skan    }
4864169689Skan  else
4865169689Skan    {
4866169689Skan      rtx lo = gen_lowpart (DImode, operands[1]);
4867169689Skan
4868169689Skan      emit_insn (gen_shrp (rl, hi, lo, shiftlo));
4869169689Skan      emit_insn (gen_ashrdi3 (rh, hi, shiftlo));
4870169689Skan    }
4871169689Skan  DONE;
4872169689Skan})
4873169689Skan
4874169689Skan(define_expand "lshrti3"
4875169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "")
4876169689Skan        (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "")
4877169689Skan                     (match_operand:DI 2 "nonmemory_operand" "")))]
4878169689Skan  ""
4879169689Skan{ 
4880169689Skan  if (!dshift_count_operand (operands[2], DImode))
4881169689Skan    FAIL;
4882169689Skan}) 
4883169689Skan
4884169689Skan(define_insn_and_split "*lshrti3_internal"
4885169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4886169689Skan	(lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "r")
4887169689Skan		     (match_operand:DI 2 "dshift_count_operand" "n")))]
4888169689Skan  ""
4889169689Skan  "#"
4890169689Skan  "reload_completed"
4891169689Skan  [(const_int 0)]
4892169689Skan{
4893169689Skan  HOST_WIDE_INT shift = INTVAL (operands[2]);
4894169689Skan  rtx rl = gen_lowpart (DImode, operands[0]);
4895169689Skan  rtx rh = gen_highpart (DImode, operands[0]);
4896169689Skan  rtx hi = gen_highpart (DImode, operands[1]);
4897169689Skan  rtx shiftlo = GEN_INT (shift & 63);
4898169689Skan
4899169689Skan  if (shift & 64)
4900169689Skan    {
4901169689Skan      if (shift & 63)
4902169689Skan	emit_insn (gen_lshrdi3 (rl, hi, shiftlo));
4903169689Skan      else
4904169689Skan	emit_move_insn (rl, hi);
4905169689Skan      emit_move_insn (rh, const0_rtx);
4906169689Skan    }
4907169689Skan  else
4908169689Skan    {
4909169689Skan      rtx lo = gen_lowpart (DImode, operands[1]);
4910169689Skan
4911169689Skan      emit_insn (gen_shrp (rl, hi, lo, shiftlo));
4912169689Skan      emit_insn (gen_lshrdi3 (rh, hi, shiftlo));
4913169689Skan    }
4914169689Skan  DONE;
4915169689Skan})
4916169689Skan
4917169689Skan(define_expand "rotlti3"
4918169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "")
4919169689Skan	(rotate:TI (match_operand:TI 1 "gr_register_operand" "")
4920169689Skan		   (match_operand:DI 2 "nonmemory_operand" "")))]
4921169689Skan  ""
4922169689Skan{
4923169689Skan  if (! dshift_count_operand (operands[2], DImode))
4924169689Skan    FAIL;
4925169689Skan})
4926169689Skan
4927169689Skan(define_insn_and_split "*rotlti3_internal"
4928169689Skan  [(set (match_operand:TI 0 "gr_register_operand" "=&r")
4929169689Skan	(rotate:TI (match_operand:TI 1 "gr_register_operand" "r")
4930169689Skan		   (match_operand:DI 2 "dshift_count_operand" "n")))]
4931169689Skan  ""
4932169689Skan  "#"
4933169689Skan  "reload_completed"
4934169689Skan  [(const_int 0)]
4935169689Skan{
4936169689Skan  HOST_WIDE_INT count = INTVAL (operands[2]);
4937169689Skan  rtx rl = gen_lowpart (DImode, operands[0]);
4938169689Skan  rtx rh = gen_highpart (DImode, operands[0]);
4939169689Skan  rtx lo = gen_lowpart (DImode, operands[1]);
4940169689Skan  rtx hi = gen_highpart (DImode, operands[1]);
4941169689Skan  rtx countlo = GEN_INT (-count & 63);
4942169689Skan
4943169689Skan  if (count & 64)
4944169689Skan    {
4945169689Skan      if (count & 63)
4946169689Skan	{
4947169689Skan	  emit_insn (gen_shrp (rl, hi, lo, countlo));
4948169689Skan	  emit_insn (gen_shrp (rh, lo, hi, countlo));
4949169689Skan	}
4950169689Skan      else
4951169689Skan	{
4952169689Skan	  emit_move_insn (rl, hi);
4953169689Skan	  emit_move_insn (rh, lo);
4954169689Skan	}
4955169689Skan    }
4956169689Skan  else
4957169689Skan    {
4958169689Skan      emit_insn (gen_shrp (rl, lo, hi, countlo));
4959169689Skan      emit_insn (gen_shrp (rh, hi, lo, countlo));
4960169689Skan    }
4961169689Skan  DONE;
4962169689Skan}
4963169689Skan  [(set_attr "itanium_class" "unknown")])
4964169689Skan
4965169689Skan(define_insn "shrp"
4966169689Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
4967169689Skan	(unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")
4968169689Skan		    (match_operand:DI 2 "gr_register_operand" "r")
4969169689Skan		    (match_operand:DI 3 "shift_count_operand" "M")]
4970169689Skan		   UNSPEC_SHRP))]
4971169689Skan  ""
4972169689Skan  "shrp %0 = %1, %2, %3"
4973169689Skan  [(set_attr "itanium_class" "ishf")])
4974169689Skan
4975169689Skan;; ::::::::::::::::::::
4976169689Skan;; ::
497790075Sobrien;; :: 32 bit Integer Logical operations
497890075Sobrien;; ::
497990075Sobrien;; ::::::::::::::::::::
498090075Sobrien
498190075Sobrien;; We don't seem to need any other 32-bit logical operations, because gcc
498290075Sobrien;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
498390075Sobrien;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
498490075Sobrien;; This doesn't work for unary logical operations, because we don't call
498590075Sobrien;; apply_distributive_law for them.
498690075Sobrien
498790075Sobrien;; ??? Likewise, this doesn't work for andnot, which isn't handled by
498890075Sobrien;; apply_distributive_law.  We get inefficient code for
498990075Sobrien;; int sub4 (int i, int j) { return i & ~j; }
499090075Sobrien;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
499190075Sobrien;; (zero_extend (and (not A) B)) in combine.
499290075Sobrien;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
499390075Sobrien;; one_cmplsi2 pattern.
499490075Sobrien
499590075Sobrien(define_insn "one_cmplsi2"
499690075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
499790075Sobrien	(not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
499890075Sobrien  ""
499990075Sobrien  "andcm %0 = -1, %1"
500090075Sobrien  [(set_attr "itanium_class" "ilog")])
500190075Sobrien
500290075Sobrien;; ::::::::::::::::::::
500390075Sobrien;; ::
500490075Sobrien;; :: 64 bit Integer Logical operations
500590075Sobrien;; ::
500690075Sobrien;; ::::::::::::::::::::
500790075Sobrien
500890075Sobrien(define_insn "anddi3"
500990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
501090075Sobrien	(and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
501190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
501290075Sobrien  ""
501390075Sobrien  "@
501490075Sobrien   and %0 = %2, %1
501590075Sobrien   fand %0 = %2, %1"
501690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
501790075Sobrien
501890075Sobrien(define_insn "*andnot"
501990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
502090075Sobrien	(and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
502190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
502290075Sobrien  ""
502390075Sobrien  "@
502490075Sobrien   andcm %0 = %2, %1
502590075Sobrien   fandcm %0 = %2, %1"
502690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
502790075Sobrien
502890075Sobrien(define_insn "iordi3"
502990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
503090075Sobrien	(ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
503190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
503290075Sobrien  ""
503390075Sobrien  "@
503490075Sobrien   or %0 = %2, %1
503590075Sobrien   for %0 = %2, %1"
503690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
503790075Sobrien
503890075Sobrien(define_insn "xordi3"
503990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
504090075Sobrien	(xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
504190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
504290075Sobrien  ""
504390075Sobrien  "@
504490075Sobrien   xor %0 = %2, %1
504590075Sobrien   fxor %0 = %2, %1"
504690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
504790075Sobrien
504890075Sobrien(define_insn "one_cmpldi2"
504990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
505090075Sobrien	(not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
505190075Sobrien  ""
505290075Sobrien  "andcm %0 = -1, %1"
505390075Sobrien  [(set_attr "itanium_class" "ilog")])
505490075Sobrien
505590075Sobrien;; ::::::::::::::::::::
505690075Sobrien;; ::
505790075Sobrien;; :: Comparisons
505890075Sobrien;; ::
505990075Sobrien;; ::::::::::::::::::::
506090075Sobrien
506190075Sobrien(define_expand "cmpbi"
506290075Sobrien  [(set (cc0)
506390075Sobrien        (compare (match_operand:BI 0 "register_operand" "")
506490075Sobrien  		 (match_operand:BI 1 "const_int_operand" "")))]
506590075Sobrien  ""
506690075Sobrien{
506790075Sobrien  ia64_compare_op0 = operands[0];
506890075Sobrien  ia64_compare_op1 = operands[1];
506990075Sobrien  DONE;
5070117395Skan})
507190075Sobrien
507290075Sobrien(define_expand "cmpsi"
507390075Sobrien  [(set (cc0)
507490075Sobrien        (compare (match_operand:SI 0 "gr_register_operand" "")
507590075Sobrien  		 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
507690075Sobrien  ""
507790075Sobrien{
507890075Sobrien  ia64_compare_op0 = operands[0];
507990075Sobrien  ia64_compare_op1 = operands[1];
508090075Sobrien  DONE;
5081117395Skan})
508290075Sobrien
508390075Sobrien(define_expand "cmpdi"
508490075Sobrien  [(set (cc0)
508590075Sobrien        (compare (match_operand:DI 0 "gr_register_operand" "")
508690075Sobrien  		 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
508790075Sobrien  ""
508890075Sobrien{
508990075Sobrien  ia64_compare_op0 = operands[0];
509090075Sobrien  ia64_compare_op1 = operands[1];
509190075Sobrien  DONE;
5092117395Skan})
509390075Sobrien
509490075Sobrien(define_expand "cmpsf"
509590075Sobrien  [(set (cc0)
509690075Sobrien        (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
509790075Sobrien  		 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
509890075Sobrien  ""
509990075Sobrien{
510090075Sobrien  ia64_compare_op0 = operands[0];
510190075Sobrien  ia64_compare_op1 = operands[1];
510290075Sobrien  DONE;
5103117395Skan})
510490075Sobrien
510590075Sobrien(define_expand "cmpdf"
510690075Sobrien  [(set (cc0)
510790075Sobrien        (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
510890075Sobrien  		 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
510990075Sobrien  ""
511090075Sobrien{
511190075Sobrien  ia64_compare_op0 = operands[0];
511290075Sobrien  ia64_compare_op1 = operands[1];
511390075Sobrien  DONE;
5114117395Skan})
511590075Sobrien
5116132718Skan(define_expand "cmpxf"
5117132718Skan  [(set (cc0)
5118132718Skan        (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
5119132718Skan  		 (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
5120132718Skan  ""
5121132718Skan{
5122132718Skan  ia64_compare_op0 = operands[0];
5123132718Skan  ia64_compare_op1 = operands[1];
5124132718Skan  DONE;
5125132718Skan})
5126132718Skan
512790075Sobrien(define_expand "cmptf"
512890075Sobrien  [(set (cc0)
5129132718Skan        (compare (match_operand:TF 0 "gr_register_operand" "")
5130132718Skan  		 (match_operand:TF 1 "gr_register_operand" "")))]
5131132718Skan  "TARGET_HPUX"
513290075Sobrien{
513390075Sobrien  ia64_compare_op0 = operands[0];
513490075Sobrien  ia64_compare_op1 = operands[1];
513590075Sobrien  DONE;
5136117395Skan})
513790075Sobrien
513890075Sobrien(define_insn "*cmpsi_normal"
513990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
514090075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
514190075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
514290075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
514390075Sobrien  ""
514490075Sobrien  "cmp4.%C1 %0, %I0 = %3, %2"
514590075Sobrien  [(set_attr "itanium_class" "icmp")])
514690075Sobrien
514790075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
514890075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
514990075Sobrien
515090075Sobrien(define_insn "*cmpsi_adjusted"
515190075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
515290075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
515390075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
515490075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
515590075Sobrien  ""
515690075Sobrien  "cmp4.%C1 %0, %I0 = %r3, %2"
515790075Sobrien  [(set_attr "itanium_class" "icmp")])
515890075Sobrien
515990075Sobrien(define_insn "*cmpdi_normal"
516090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
516190075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
516290075Sobrien	   [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
516390075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
516490075Sobrien  ""
516590075Sobrien  "cmp.%C1 %0, %I0 = %3, %r2"
516690075Sobrien  [(set_attr "itanium_class" "icmp")])
516790075Sobrien
516890075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
516990075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
517090075Sobrien
517190075Sobrien(define_insn "*cmpdi_adjusted"
517290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
517390075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
517490075Sobrien	   [(match_operand:DI 2 "gr_register_operand" "r")
517590075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
517690075Sobrien  ""
517790075Sobrien  "cmp.%C1 %0, %I0 = %r3, %2"
517890075Sobrien  [(set_attr "itanium_class" "icmp")])
517990075Sobrien
518090075Sobrien(define_insn "*cmpsf_internal"
518190075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
518290075Sobrien	(match_operator:BI 1 "comparison_operator"
518390075Sobrien	   [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
518490075Sobrien	    (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
518590075Sobrien  ""
518690075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
518790075Sobrien  [(set_attr "itanium_class" "fcmp")])
518890075Sobrien
518990075Sobrien(define_insn "*cmpdf_internal"
519090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
519190075Sobrien	(match_operator:BI 1 "comparison_operator"
519290075Sobrien	   [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
519390075Sobrien	    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
519490075Sobrien  ""
519590075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
519690075Sobrien  [(set_attr "itanium_class" "fcmp")])
519790075Sobrien
5198132718Skan(define_insn "*cmpxf_internal"
519990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
520090075Sobrien	(match_operator:BI 1 "comparison_operator"
5201132718Skan		   [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
5202132718Skan		    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
5203132718Skan  ""
520490075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
520590075Sobrien  [(set_attr "itanium_class" "fcmp")])
520690075Sobrien
520790075Sobrien;; ??? Can this pattern be generated?
520890075Sobrien
520990075Sobrien(define_insn "*bit_zero"
521090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
521190075Sobrien	(eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
521290075Sobrien				(const_int 1)
5213169689Skan				(match_operand:DI 2 "shift_count_operand" "M"))
521490075Sobrien	       (const_int 0)))]
521590075Sobrien  ""
521690075Sobrien  "tbit.z %0, %I0 = %1, %2"
521790075Sobrien  [(set_attr "itanium_class" "tbit")])
521890075Sobrien
521990075Sobrien(define_insn "*bit_one"
522090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
522190075Sobrien	(ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
522290075Sobrien				(const_int 1)
5223169689Skan				(match_operand:DI 2 "shift_count_operand" "M"))
522490075Sobrien	       (const_int 0)))]
522590075Sobrien  ""
522690075Sobrien  "tbit.nz %0, %I0 = %1, %2"
522790075Sobrien  [(set_attr "itanium_class" "tbit")])
522890075Sobrien
522990075Sobrien;; ::::::::::::::::::::
523090075Sobrien;; ::
523190075Sobrien;; :: Branches
523290075Sobrien;; ::
523390075Sobrien;; ::::::::::::::::::::
523490075Sobrien
523590075Sobrien(define_expand "beq"
523690075Sobrien  [(set (pc)
523790075Sobrien	(if_then_else (match_dup 1)
523890075Sobrien		      (label_ref (match_operand 0 "" ""))
523990075Sobrien		      (pc)))]
524090075Sobrien  ""
524190075Sobrien  "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
524290075Sobrien
524390075Sobrien(define_expand "bne"
524490075Sobrien  [(set (pc)
524590075Sobrien	(if_then_else (match_dup 1)
524690075Sobrien		      (label_ref (match_operand 0 "" ""))
524790075Sobrien		      (pc)))]
524890075Sobrien  ""
524990075Sobrien  "operands[1] = ia64_expand_compare (NE, VOIDmode);")
525090075Sobrien
525190075Sobrien(define_expand "blt"
525290075Sobrien  [(set (pc)
525390075Sobrien	(if_then_else (match_dup 1)
525490075Sobrien		      (label_ref (match_operand 0 "" ""))
525590075Sobrien		      (pc)))]
525690075Sobrien  ""
525790075Sobrien  "operands[1] = ia64_expand_compare (LT, VOIDmode);")
525890075Sobrien
525990075Sobrien(define_expand "ble"
526090075Sobrien  [(set (pc)
526190075Sobrien	(if_then_else (match_dup 1)
526290075Sobrien		      (label_ref (match_operand 0 "" ""))
526390075Sobrien		      (pc)))]
526490075Sobrien  ""
526590075Sobrien  "operands[1] = ia64_expand_compare (LE, VOIDmode);")
526690075Sobrien
526790075Sobrien(define_expand "bgt"
526890075Sobrien  [(set (pc)
526990075Sobrien	(if_then_else (match_dup 1)
527090075Sobrien		      (label_ref (match_operand 0 "" ""))
527190075Sobrien		      (pc)))]
527290075Sobrien  ""
527390075Sobrien  "operands[1] = ia64_expand_compare (GT, VOIDmode);")
527490075Sobrien
527590075Sobrien(define_expand "bge"
527690075Sobrien  [(set (pc)
527790075Sobrien	(if_then_else (match_dup 1)
527890075Sobrien		      (label_ref (match_operand 0 "" ""))
527990075Sobrien		      (pc)))]
528090075Sobrien  ""
528190075Sobrien  "operands[1] = ia64_expand_compare (GE, VOIDmode);")
528290075Sobrien
528390075Sobrien(define_expand "bltu"
528490075Sobrien  [(set (pc)
528590075Sobrien	(if_then_else (match_dup 1)
528690075Sobrien		      (label_ref (match_operand 0 "" ""))
528790075Sobrien		      (pc)))]
528890075Sobrien  ""
528990075Sobrien  "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
529090075Sobrien
529190075Sobrien(define_expand "bleu"
529290075Sobrien  [(set (pc)
529390075Sobrien	(if_then_else (match_dup 1)
529490075Sobrien		      (label_ref (match_operand 0 "" ""))
529590075Sobrien		      (pc)))]
529690075Sobrien  ""
529790075Sobrien  "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
529890075Sobrien
529990075Sobrien(define_expand "bgtu"
530090075Sobrien  [(set (pc)
530190075Sobrien	(if_then_else (match_dup 1)
530290075Sobrien		      (label_ref (match_operand 0 "" ""))
530390075Sobrien		      (pc)))]
530490075Sobrien  ""
530590075Sobrien  "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
530690075Sobrien
530790075Sobrien(define_expand "bgeu"
530890075Sobrien  [(set (pc)
530990075Sobrien	(if_then_else (match_dup 1)
531090075Sobrien		      (label_ref (match_operand 0 "" ""))
531190075Sobrien		      (pc)))]
531290075Sobrien  ""
531390075Sobrien  "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
531490075Sobrien
531590075Sobrien(define_expand "bunordered"
531690075Sobrien  [(set (pc)
531790075Sobrien	(if_then_else (match_dup 1)
531890075Sobrien		      (label_ref (match_operand 0 "" ""))
531990075Sobrien		      (pc)))]
532090075Sobrien  ""
532190075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
532290075Sobrien
532390075Sobrien(define_expand "bordered"
532490075Sobrien  [(set (pc)
532590075Sobrien	(if_then_else (match_dup 1)
532690075Sobrien		      (label_ref (match_operand 0 "" ""))
532790075Sobrien		      (pc)))]
532890075Sobrien  ""
532990075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
533090075Sobrien
533190075Sobrien(define_insn "*br_true"
533290075Sobrien  [(set (pc)
533390075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
533490075Sobrien			[(match_operand:BI 1 "register_operand" "c")
533590075Sobrien			 (const_int 0)])
533690075Sobrien		      (label_ref (match_operand 2 "" ""))
533790075Sobrien		      (pc)))]
533890075Sobrien  ""
533990075Sobrien  "(%J0) br.cond%+ %l2"
534090075Sobrien  [(set_attr "itanium_class" "br")
534190075Sobrien   (set_attr "predicable" "no")])
534290075Sobrien
534390075Sobrien(define_insn "*br_false"
534490075Sobrien  [(set (pc)
534590075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
534690075Sobrien			[(match_operand:BI 1 "register_operand" "c")
534790075Sobrien			 (const_int 0)])
534890075Sobrien		      (pc)
534990075Sobrien		      (label_ref (match_operand 2 "" ""))))]
535090075Sobrien  ""
535190075Sobrien  "(%j0) br.cond%+ %l2"
535290075Sobrien  [(set_attr "itanium_class" "br")
535390075Sobrien   (set_attr "predicable" "no")])
535490075Sobrien
535590075Sobrien;; ::::::::::::::::::::
535690075Sobrien;; ::
535790075Sobrien;; :: Counted loop operations
535890075Sobrien;; ::
535990075Sobrien;; ::::::::::::::::::::
536090075Sobrien
536190075Sobrien(define_expand "doloop_end"
536290075Sobrien  [(use (match_operand 0 "" ""))	; loop pseudo
536390075Sobrien   (use (match_operand 1 "" ""))	; iterations; zero if unknown
536490075Sobrien   (use (match_operand 2 "" ""))	; max iterations
536590075Sobrien   (use (match_operand 3 "" ""))	; loop level
536690075Sobrien   (use (match_operand 4 "" ""))]	; label
536790075Sobrien  ""
536890075Sobrien{
536990075Sobrien  /* Only use cloop on innermost loops.  */
537090075Sobrien  if (INTVAL (operands[3]) > 1)
537190075Sobrien    FAIL;
537290075Sobrien  emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
537390075Sobrien					   operands[4]));
537490075Sobrien  DONE;
5375117395Skan})
537690075Sobrien
537790075Sobrien(define_insn "doloop_end_internal"
537890075Sobrien  [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
537990075Sobrien			       (const_int 0))
538090075Sobrien		(label_ref (match_operand 1 "" ""))
538190075Sobrien		(pc)))
538290075Sobrien   (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
5383117395Skan			 (plus:DI (match_dup 0) (const_int -1))
5384117395Skan			 (match_dup 0)))]
538590075Sobrien  ""
538690075Sobrien  "br.cloop.sptk.few %l1"
538790075Sobrien  [(set_attr "itanium_class" "br")
538890075Sobrien   (set_attr "predicable" "no")])
538990075Sobrien
539090075Sobrien;; ::::::::::::::::::::
539190075Sobrien;; ::
539290075Sobrien;; :: Set flag operations
539390075Sobrien;; ::
539490075Sobrien;; ::::::::::::::::::::
539590075Sobrien
539690075Sobrien(define_expand "seq"
539790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
539890075Sobrien  ""
539990075Sobrien  "operands[1] = ia64_expand_compare (EQ, DImode);")
540090075Sobrien
540190075Sobrien(define_expand "sne"
540290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
540390075Sobrien  ""
540490075Sobrien  "operands[1] = ia64_expand_compare (NE, DImode);")
540590075Sobrien
540690075Sobrien(define_expand "slt"
540790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
540890075Sobrien  ""
540990075Sobrien  "operands[1] = ia64_expand_compare (LT, DImode);")
541090075Sobrien
541190075Sobrien(define_expand "sle"
541290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
541390075Sobrien  ""
541490075Sobrien  "operands[1] = ia64_expand_compare (LE, DImode);")
541590075Sobrien
541690075Sobrien(define_expand "sgt"
541790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
541890075Sobrien  ""
541990075Sobrien  "operands[1] = ia64_expand_compare (GT, DImode);")
542090075Sobrien
542190075Sobrien(define_expand "sge"
542290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
542390075Sobrien  ""
542490075Sobrien  "operands[1] = ia64_expand_compare (GE, DImode);")
542590075Sobrien
542690075Sobrien(define_expand "sltu"
542790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
542890075Sobrien  ""
542990075Sobrien  "operands[1] = ia64_expand_compare (LTU, DImode);")
543090075Sobrien
543190075Sobrien(define_expand "sleu"
543290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
543390075Sobrien  ""
543490075Sobrien  "operands[1] = ia64_expand_compare (LEU, DImode);")
543590075Sobrien
543690075Sobrien(define_expand "sgtu"
543790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
543890075Sobrien  ""
543990075Sobrien  "operands[1] = ia64_expand_compare (GTU, DImode);")
544090075Sobrien
544190075Sobrien(define_expand "sgeu"
544290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
544390075Sobrien  ""
544490075Sobrien  "operands[1] = ia64_expand_compare (GEU, DImode);")
544590075Sobrien
544690075Sobrien(define_expand "sunordered"
544790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
544890075Sobrien  ""
544990075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
545090075Sobrien
545190075Sobrien(define_expand "sordered"
545290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
545390075Sobrien  ""
545490075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, DImode);")
545590075Sobrien
545690075Sobrien;; Don't allow memory as destination here, because cmov/cmov/st is more
545790075Sobrien;; efficient than mov/mov/cst/cst.
545890075Sobrien
545990075Sobrien(define_insn_and_split "*sne_internal"
546090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
546190075Sobrien	(ne:DI (match_operand:BI 1 "register_operand" "c")
546290075Sobrien	       (const_int 0)))]
546390075Sobrien  ""
546490075Sobrien  "#"
546590075Sobrien  "reload_completed"
546690075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
546790075Sobrien     (set (match_dup 0) (const_int 1)))
546890075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
546990075Sobrien     (set (match_dup 0) (const_int 0)))]
547090075Sobrien  ""
547190075Sobrien  [(set_attr "itanium_class" "unknown")])
547290075Sobrien
547390075Sobrien(define_insn_and_split "*seq_internal"
547490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
547590075Sobrien	(eq:DI (match_operand:BI 1 "register_operand" "c")
547690075Sobrien	       (const_int 0)))]
547790075Sobrien  ""
547890075Sobrien  "#"
547990075Sobrien  "reload_completed"
548090075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
548190075Sobrien     (set (match_dup 0) (const_int 0)))
548290075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
548390075Sobrien     (set (match_dup 0) (const_int 1)))]
548490075Sobrien  ""
548590075Sobrien  [(set_attr "itanium_class" "unknown")])
548690075Sobrien
548790075Sobrien;; ::::::::::::::::::::
548890075Sobrien;; ::
548990075Sobrien;; :: Conditional move instructions.
549090075Sobrien;; ::
549190075Sobrien;; ::::::::::::::::::::
549290075Sobrien
549390075Sobrien;; ??? Add movXXcc patterns?
549490075Sobrien
549590075Sobrien;;
549690075Sobrien;; DImode if_then_else patterns.
549790075Sobrien;;
549890075Sobrien
549990075Sobrien(define_insn "*cmovdi_internal"
550090075Sobrien  [(set (match_operand:DI 0 "destination_operand"
550190075Sobrien	   "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
550290075Sobrien	(if_then_else:DI
550390075Sobrien	  (match_operator 4 "predicate_operator"
550490075Sobrien	    [(match_operand:BI 1 "register_operand"
550590075Sobrien		"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
550690075Sobrien	     (const_int 0)])
550790075Sobrien	  (match_operand:DI 2 "move_operand"
5508132718Skan	   "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
550990075Sobrien	  (match_operand:DI 3 "move_operand"
5510132718Skan	   "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
551190075Sobrien  "ia64_move_ok (operands[0], operands[2])
551290075Sobrien   && ia64_move_ok (operands[0], operands[3])"
5513169689Skan  { gcc_unreachable (); }
551490075Sobrien  [(set_attr "predicable" "no")])
551590075Sobrien
551690075Sobrien(define_split
551790075Sobrien  [(set (match_operand 0 "destination_operand" "")
551890075Sobrien	(if_then_else
551990075Sobrien	  (match_operator 4 "predicate_operator"
552090075Sobrien	    [(match_operand:BI 1 "register_operand" "")
552190075Sobrien	     (const_int 0)])
552290075Sobrien	  (match_operand 2 "move_operand" "")
552390075Sobrien	  (match_operand 3 "move_operand" "")))]
552490075Sobrien  "reload_completed"
552590075Sobrien  [(const_int 0)]
552690075Sobrien{
5527132718Skan  bool emitted_something = false;
5528132718Skan  rtx dest = operands[0];
5529132718Skan  rtx srct = operands[2];
5530132718Skan  rtx srcf = operands[3];
5531132718Skan  rtx cond = operands[4];
5532117395Skan
5533132718Skan  if (! rtx_equal_p (dest, srct))
553490075Sobrien    {
5535132718Skan      ia64_emit_cond_move (dest, srct, cond);
5536132718Skan      emitted_something = true;
553790075Sobrien    }
5538132718Skan  if (! rtx_equal_p (dest, srcf))
553990075Sobrien    {
5540132718Skan      cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
5541132718Skan 			     VOIDmode, operands[1], const0_rtx);
5542132718Skan      ia64_emit_cond_move (dest, srcf, cond);
5543132718Skan      emitted_something = true;
554490075Sobrien    }
5545117395Skan  if (! emitted_something)
5546132718Skan    emit_note (NOTE_INSN_DELETED);
554790075Sobrien  DONE;
5548117395Skan})
554990075Sobrien
555090075Sobrien;; Absolute value pattern.
555190075Sobrien
555290075Sobrien(define_insn "*absdi2_internal"
555390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
555490075Sobrien	(if_then_else:DI
555590075Sobrien	  (match_operator 4 "predicate_operator"
555690075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
555790075Sobrien	     (const_int 0)])
555890075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
555990075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
556090075Sobrien  ""
556190075Sobrien  "#"
556290075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
556390075Sobrien   (set_attr "predicable" "no")])
556490075Sobrien
556590075Sobrien(define_split
556690075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
556790075Sobrien	(if_then_else:DI
556890075Sobrien	  (match_operator 4 "predicate_operator"
556990075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
557090075Sobrien	     (const_int 0)])
557190075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
557290075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
557390075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
557490075Sobrien  [(cond_exec
557590075Sobrien     (match_dup 4)
557690075Sobrien     (set (match_dup 0)
557790075Sobrien	  (neg:DI (match_dup 2))))]
557890075Sobrien  "")
557990075Sobrien
558090075Sobrien(define_split
558190075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
558290075Sobrien	(if_then_else:DI
558390075Sobrien	  (match_operator 4 "predicate_operator"
558490075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
558590075Sobrien	     (const_int 0)])
558690075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
558790075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
558890075Sobrien  "reload_completed"
558990075Sobrien  [(cond_exec
559090075Sobrien     (match_dup 4)
559190075Sobrien     (set (match_dup 0) (neg:DI (match_dup 2))))
559290075Sobrien   (cond_exec
559390075Sobrien     (match_dup 5)
559490075Sobrien     (set (match_dup 0) (match_dup 3)))]
559590075Sobrien{
559690075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
559790075Sobrien				VOIDmode, operands[1], const0_rtx);
5598117395Skan})
559990075Sobrien
560090075Sobrien;;
560190075Sobrien;; SImode if_then_else patterns.
560290075Sobrien;;
560390075Sobrien
560490075Sobrien(define_insn "*cmovsi_internal"
560590075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
560690075Sobrien	(if_then_else:SI
560790075Sobrien	  (match_operator 4 "predicate_operator"
560890075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
560990075Sobrien	     (const_int 0)])
561090075Sobrien	  (match_operand:SI 2 "move_operand"
5611132718Skan		    "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
561290075Sobrien	  (match_operand:SI 3 "move_operand"
5613132718Skan		    "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
561490075Sobrien  "ia64_move_ok (operands[0], operands[2])
561590075Sobrien   && ia64_move_ok (operands[0], operands[3])"
5616169689Skan  { gcc_unreachable (); }
561790075Sobrien  [(set_attr "predicable" "no")])
561890075Sobrien
561990075Sobrien(define_insn "*abssi2_internal"
562090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
562190075Sobrien	(if_then_else:SI
562290075Sobrien	  (match_operator 4 "predicate_operator"
562390075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
562490075Sobrien	     (const_int 0)])
562590075Sobrien	  (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
562690075Sobrien	  (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
562790075Sobrien  ""
562890075Sobrien  "#"
562990075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
563090075Sobrien   (set_attr "predicable" "no")])
563190075Sobrien
563290075Sobrien(define_split
563390075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
563490075Sobrien	(if_then_else:SI
563590075Sobrien	  (match_operator 4 "predicate_operator"
563690075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
563790075Sobrien	     (const_int 0)])
563890075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
563990075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
564090075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
564190075Sobrien  [(cond_exec
564290075Sobrien     (match_dup 4)
564390075Sobrien     (set (match_dup 0)
564490075Sobrien	  (neg:SI (match_dup 2))))]
564590075Sobrien  "")
564690075Sobrien
564790075Sobrien(define_split
564890075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
564990075Sobrien	(if_then_else:SI
565090075Sobrien	  (match_operator 4 "predicate_operator"
565190075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
565290075Sobrien	     (const_int 0)])
565390075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
565490075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
565590075Sobrien  "reload_completed"
565690075Sobrien  [(cond_exec
565790075Sobrien     (match_dup 4)
565890075Sobrien     (set (match_dup 0) (neg:SI (match_dup 2))))
565990075Sobrien   (cond_exec
566090075Sobrien     (match_dup 5)
566190075Sobrien     (set (match_dup 0) (match_dup 3)))]
566290075Sobrien{
566390075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
566490075Sobrien				VOIDmode, operands[1], const0_rtx);
5665117395Skan})
566690075Sobrien
566790075Sobrien(define_insn_and_split "*cond_opsi2_internal"
566890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
566990075Sobrien	(match_operator:SI 5 "condop_operator"
567090075Sobrien	  [(if_then_else:SI
567190075Sobrien	     (match_operator 6 "predicate_operator"
567290075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
567390075Sobrien	        (const_int 0)])
567490075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
567590075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))
567690075Sobrien	   (match_operand:SI 4 "gr_register_operand" "r")]))]
567790075Sobrien  ""
567890075Sobrien  "#"
567990075Sobrien  "reload_completed"
568090075Sobrien  [(cond_exec
568190075Sobrien     (match_dup 6)
568290075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
568390075Sobrien   (cond_exec
568490075Sobrien     (match_dup 7)
568590075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
568690075Sobrien{
568790075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
568890075Sobrien				VOIDmode, operands[1], const0_rtx);
5689117395Skan}
569090075Sobrien  [(set_attr "itanium_class" "ialu")
569190075Sobrien   (set_attr "predicable" "no")])
569290075Sobrien
569390075Sobrien
569490075Sobrien(define_insn_and_split "*cond_opsi2_internal_b"
569590075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
569690075Sobrien	(match_operator:SI 5 "condop_operator"
569790075Sobrien	  [(match_operand:SI 4 "gr_register_operand" "r")
569890075Sobrien	   (if_then_else:SI
569990075Sobrien	     (match_operator 6 "predicate_operator"
570090075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
570190075Sobrien	        (const_int 0)])
570290075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
570390075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))]))]
570490075Sobrien  ""
570590075Sobrien  "#"
570690075Sobrien  "reload_completed"
570790075Sobrien  [(cond_exec
570890075Sobrien     (match_dup 6)
570990075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
571090075Sobrien   (cond_exec
571190075Sobrien     (match_dup 7)
571290075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
571390075Sobrien{
571490075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
571590075Sobrien				VOIDmode, operands[1], const0_rtx);
5716117395Skan}
571790075Sobrien  [(set_attr "itanium_class" "ialu")
571890075Sobrien   (set_attr "predicable" "no")])
571990075Sobrien
572090075Sobrien
572190075Sobrien;; ::::::::::::::::::::
572290075Sobrien;; ::
572390075Sobrien;; :: Call and branch instructions
572490075Sobrien;; ::
572590075Sobrien;; ::::::::::::::::::::
572690075Sobrien
572790075Sobrien;; Subroutine call instruction returning no value.  Operand 0 is the function
572890075Sobrien;; to call; operand 1 is the number of bytes of arguments pushed (in mode
572990075Sobrien;; `SImode', except it is normally a `const_int'); operand 2 is the number of
573090075Sobrien;; registers used as operands.
573190075Sobrien
573290075Sobrien;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
573390075Sobrien;; is supplied for the sake of some RISC machines which need to put this
573490075Sobrien;; information into the assembler code; they can put it in the RTL instead of
573590075Sobrien;; operand 1.
573690075Sobrien
573790075Sobrien(define_expand "call"
573890075Sobrien  [(use (match_operand:DI 0 "" ""))
573990075Sobrien   (use (match_operand 1 "" ""))
574090075Sobrien   (use (match_operand 2 "" ""))
574190075Sobrien   (use (match_operand 3 "" ""))]
574290075Sobrien  ""
574390075Sobrien{
5744117395Skan  ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
574590075Sobrien  DONE;
5746117395Skan})
574790075Sobrien
574890075Sobrien(define_expand "sibcall"
574990075Sobrien  [(use (match_operand:DI 0 "" ""))
575090075Sobrien   (use (match_operand 1 "" ""))
575190075Sobrien   (use (match_operand 2 "" ""))
575290075Sobrien   (use (match_operand 3 "" ""))]
575390075Sobrien  ""
575490075Sobrien{
5755117395Skan  ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
575690075Sobrien  DONE;
5757117395Skan})
575890075Sobrien
575990075Sobrien;; Subroutine call instruction returning a value.  Operand 0 is the hard
576090075Sobrien;; register in which the value is returned.  There are three more operands,
576190075Sobrien;; the same as the three operands of the `call' instruction (but with numbers
576290075Sobrien;; increased by one).
576390075Sobrien;;
576490075Sobrien;; Subroutines that return `BLKmode' objects use the `call' insn.
576590075Sobrien
576690075Sobrien(define_expand "call_value"
576790075Sobrien  [(use (match_operand 0 "" ""))
576890075Sobrien   (use (match_operand:DI 1 "" ""))
576990075Sobrien   (use (match_operand 2 "" ""))
577090075Sobrien   (use (match_operand 3 "" ""))
577190075Sobrien   (use (match_operand 4 "" ""))]
577290075Sobrien  ""
577390075Sobrien{
5774117395Skan  ia64_expand_call (operands[0], operands[1], operands[3], false);
577590075Sobrien  DONE;
5776117395Skan})
577790075Sobrien
577890075Sobrien(define_expand "sibcall_value"
577990075Sobrien  [(use (match_operand 0 "" ""))
578090075Sobrien   (use (match_operand:DI 1 "" ""))
578190075Sobrien   (use (match_operand 2 "" ""))
578290075Sobrien   (use (match_operand 3 "" ""))
578390075Sobrien   (use (match_operand 4 "" ""))]
578490075Sobrien  ""
578590075Sobrien{
5786117395Skan  ia64_expand_call (operands[0], operands[1], operands[3], true);
578790075Sobrien  DONE;
5788117395Skan})
578990075Sobrien
579090075Sobrien;; Call subroutine returning any type.
579190075Sobrien
579290075Sobrien(define_expand "untyped_call"
579390075Sobrien  [(parallel [(call (match_operand 0 "" "")
579490075Sobrien		    (const_int 0))
579590075Sobrien	      (match_operand 1 "" "")
579690075Sobrien	      (match_operand 2 "" "")])]
579790075Sobrien  ""
579890075Sobrien{
579990075Sobrien  int i;
580090075Sobrien
580190075Sobrien  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
580290075Sobrien
580390075Sobrien  for (i = 0; i < XVECLEN (operands[2], 0); i++)
580490075Sobrien    {
580590075Sobrien      rtx set = XVECEXP (operands[2], 0, i);
580690075Sobrien      emit_move_insn (SET_DEST (set), SET_SRC (set));
580790075Sobrien    }
580890075Sobrien
580990075Sobrien  /* The optimizer does not know that the call sets the function value
581090075Sobrien     registers we stored in the result block.  We avoid problems by
581190075Sobrien     claiming that all hard registers are used and clobbered at this
581290075Sobrien     point.  */
581390075Sobrien  emit_insn (gen_blockage ());
581490075Sobrien
581590075Sobrien  DONE;
5816117395Skan})
581790075Sobrien
5818117395Skan(define_insn "call_nogp"
5819117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5820117395Skan	 (const_int 0))
5821117395Skan   (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
582290075Sobrien  ""
5823117395Skan  "br.call%+.many %1 = %0"
582490075Sobrien  [(set_attr "itanium_class" "br,scall")])
582590075Sobrien
5826117395Skan(define_insn "call_value_nogp"
5827132718Skan  [(set (match_operand 0 "" "=X,X")
5828117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
5829117395Skan	      (const_int 0)))
5830117395Skan   (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
583190075Sobrien  ""
5832117395Skan  "br.call%+.many %2 = %1"
583390075Sobrien  [(set_attr "itanium_class" "br,scall")])
583490075Sobrien
5835117395Skan(define_insn "sibcall_nogp"
5836117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5837117395Skan	 (const_int 0))]
583890075Sobrien  ""
583990075Sobrien  "br%+.many %0"
584090075Sobrien  [(set_attr "itanium_class" "br,scall")])
584190075Sobrien
5842117395Skan(define_insn "call_gp"
5843132718Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5844117395Skan	 (const_int 1))
5845117395Skan   (clobber (match_operand:DI 1 "register_operand" "=b,b"))
5846117395Skan   (clobber (match_scratch:DI 2 "=&r,X"))
5847117395Skan   (clobber (match_scratch:DI 3 "=b,X"))]
584890075Sobrien  ""
5849117395Skan  "#"
585090075Sobrien  [(set_attr "itanium_class" "br,scall")])
585190075Sobrien
5852117395Skan;; Irritatingly, we don't have access to INSN within the split body.
5853117395Skan;; See commentary in ia64_split_call as to why these aren't peep2.
5854117395Skan(define_split
5855117395Skan  [(call (mem (match_operand 0 "call_operand" ""))
5856117395Skan	 (const_int 1))
5857117395Skan   (clobber (match_operand:DI 1 "register_operand" ""))
5858117395Skan   (clobber (match_scratch:DI 2 ""))
5859117395Skan   (clobber (match_scratch:DI 3 ""))]
5860117395Skan  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5861117395Skan  [(const_int 0)]
5862117395Skan{
5863117395Skan  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5864117395Skan		   operands[3], true, false);
5865117395Skan  DONE;
5866117395Skan})
5867117395Skan
5868117395Skan(define_split
5869117395Skan  [(call (mem (match_operand 0 "call_operand" ""))
5870117395Skan	 (const_int 1))
5871117395Skan   (clobber (match_operand:DI 1 "register_operand" ""))
5872117395Skan   (clobber (match_scratch:DI 2 ""))
5873117395Skan   (clobber (match_scratch:DI 3 ""))]
5874117395Skan  "reload_completed"
5875117395Skan  [(const_int 0)]
5876117395Skan{
5877117395Skan  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5878117395Skan		   operands[3], false, false);
5879117395Skan  DONE;
5880117395Skan})
5881117395Skan
5882117395Skan(define_insn "call_value_gp"
5883132718Skan  [(set (match_operand 0 "" "=X,X")
5884117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
5885117395Skan	      (const_int 1)))
5886117395Skan   (clobber (match_operand:DI 2 "register_operand" "=b,b"))
5887117395Skan   (clobber (match_scratch:DI 3 "=&r,X"))
5888117395Skan   (clobber (match_scratch:DI 4 "=b,X"))]
588990075Sobrien  ""
5890117395Skan  "#"
589190075Sobrien  [(set_attr "itanium_class" "br,scall")])
589290075Sobrien
5893117395Skan(define_split
5894117395Skan  [(set (match_operand 0 "" "")
5895117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
5896117395Skan	      (const_int 1)))
5897117395Skan   (clobber (match_operand:DI 2 "register_operand" ""))
5898117395Skan   (clobber (match_scratch:DI 3 ""))
5899117395Skan   (clobber (match_scratch:DI 4 ""))]
5900117395Skan  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5901117395Skan  [(const_int 0)]
5902117395Skan{
5903117395Skan  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5904117395Skan		   operands[4], true, false);
5905117395Skan  DONE;
5906117395Skan})
5907117395Skan
5908117395Skan(define_split
5909117395Skan  [(set (match_operand 0 "" "")
5910117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
5911117395Skan	      (const_int 1)))
5912117395Skan   (clobber (match_operand:DI 2 "register_operand" ""))
5913117395Skan   (clobber (match_scratch:DI 3 ""))
5914117395Skan   (clobber (match_scratch:DI 4 ""))]
5915117395Skan  "reload_completed"
5916117395Skan  [(const_int 0)]
5917117395Skan{
5918117395Skan  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5919117395Skan		   operands[4], false, false);
5920117395Skan  DONE;
5921117395Skan})
5922117395Skan
5923117395Skan(define_insn_and_split "sibcall_gp"
5924117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5925117395Skan	 (const_int 1))
5926117395Skan   (clobber (match_scratch:DI 1 "=&r,X"))
5927117395Skan   (clobber (match_scratch:DI 2 "=b,X"))]
592890075Sobrien  ""
5929117395Skan  "#"
5930117395Skan  "reload_completed"
5931117395Skan  [(const_int 0)]
5932117395Skan{
5933117395Skan  ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
5934117395Skan		   operands[2], true, true);
5935117395Skan  DONE;
5936117395Skan}
593790075Sobrien  [(set_attr "itanium_class" "br")])
593890075Sobrien
593990075Sobrien(define_insn "return_internal"
594090075Sobrien  [(return)
594190075Sobrien   (use (match_operand:DI 0 "register_operand" "b"))]
594290075Sobrien  ""
594390075Sobrien  "br.ret.sptk.many %0"
594490075Sobrien  [(set_attr "itanium_class" "br")])
594590075Sobrien
594690075Sobrien(define_insn "return"
594790075Sobrien  [(return)]
594890075Sobrien  "ia64_direct_return ()"
594990075Sobrien  "br.ret.sptk.many rp"
595090075Sobrien  [(set_attr "itanium_class" "br")])
595190075Sobrien
595290075Sobrien(define_insn "*return_true"
595390075Sobrien  [(set (pc)
595490075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
595590075Sobrien			[(match_operand:BI 1 "register_operand" "c")
595690075Sobrien			 (const_int 0)])
595790075Sobrien		      (return)
595890075Sobrien		      (pc)))]
595990075Sobrien  "ia64_direct_return ()"
596090075Sobrien  "(%J0) br.ret%+.many rp"
596190075Sobrien  [(set_attr "itanium_class" "br")
596290075Sobrien   (set_attr "predicable" "no")])
596390075Sobrien
596490075Sobrien(define_insn "*return_false"
596590075Sobrien  [(set (pc)
596690075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
596790075Sobrien			[(match_operand:BI 1 "register_operand" "c")
596890075Sobrien			 (const_int 0)])
596990075Sobrien		      (pc)
597090075Sobrien		      (return)))]
597190075Sobrien  "ia64_direct_return ()"
597290075Sobrien  "(%j0) br.ret%+.many rp"
597390075Sobrien  [(set_attr "itanium_class" "br")
597490075Sobrien   (set_attr "predicable" "no")])
597590075Sobrien
597690075Sobrien(define_insn "jump"
597790075Sobrien  [(set (pc) (label_ref (match_operand 0 "" "")))]
597890075Sobrien  ""
597990075Sobrien  "br %l0"
598090075Sobrien  [(set_attr "itanium_class" "br")])
598190075Sobrien
598290075Sobrien(define_insn "indirect_jump"
598390075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
598490075Sobrien  ""
598590075Sobrien  "br %0"
598690075Sobrien  [(set_attr "itanium_class" "br")])
598790075Sobrien
598890075Sobrien(define_expand "tablejump"
598990075Sobrien  [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
599090075Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
599190075Sobrien  ""
599290075Sobrien{
599390075Sobrien  rtx op0 = operands[0];
599490075Sobrien  rtx addr;
599590075Sobrien
599690075Sobrien  /* ??? Bother -- do_tablejump is "helpful" and pulls the table
599790075Sobrien     element into a register without bothering to see whether that
599890075Sobrien     is necessary given the operand predicate.  Check for MEM just
599990075Sobrien     in case someone fixes this.  */
600090075Sobrien  if (GET_CODE (op0) == MEM)
600190075Sobrien    addr = XEXP (op0, 0);
600290075Sobrien  else
600390075Sobrien    {
600490075Sobrien      /* Otherwise, cheat and guess that the previous insn in the
600590075Sobrien	 stream was the memory load.  Grab the address from that.
600690075Sobrien	 Note we have to momentarily pop out of the sequence started
600790075Sobrien	 by the insn-emit wrapper in order to grab the last insn.  */
600890075Sobrien      rtx last, set;
600990075Sobrien
601090075Sobrien      end_sequence ();
601190075Sobrien      last = get_last_insn ();
601290075Sobrien      start_sequence ();
601390075Sobrien      set = single_set (last);
601490075Sobrien
6015169689Skan      gcc_assert (rtx_equal_p (SET_DEST (set), op0)
6016169689Skan		  && GET_CODE (SET_SRC (set)) == MEM);
601790075Sobrien      addr = XEXP (SET_SRC (set), 0);
6018169689Skan      gcc_assert (!rtx_equal_p (addr, op0));
601990075Sobrien    }
602090075Sobrien
602190075Sobrien  /* Jump table elements are stored pc-relative.  That is, a displacement
602290075Sobrien     from the entry to the label.  Thus to convert to an absolute address
602390075Sobrien     we add the address of the memory from which the value is loaded.  */
602490075Sobrien  operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
602590075Sobrien				     NULL_RTX, 1, OPTAB_DIRECT);
602690075Sobrien})
602790075Sobrien
602890075Sobrien(define_insn "*tablejump_internal"
602990075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))
603090075Sobrien   (use (label_ref (match_operand 1 "" "")))]
603190075Sobrien  ""
603290075Sobrien  "br %0"
603390075Sobrien  [(set_attr "itanium_class" "br")])
603490075Sobrien
603590075Sobrien
603690075Sobrien;; ::::::::::::::::::::
603790075Sobrien;; ::
603890075Sobrien;; :: Prologue and Epilogue instructions
603990075Sobrien;; ::
604090075Sobrien;; ::::::::::::::::::::
604190075Sobrien
604290075Sobrien(define_expand "prologue"
604390075Sobrien  [(const_int 1)]
604490075Sobrien  ""
604590075Sobrien{
604690075Sobrien  ia64_expand_prologue ();
604790075Sobrien  DONE;
6048117395Skan})
604990075Sobrien
605090075Sobrien(define_expand "epilogue"
605190075Sobrien  [(return)]
605290075Sobrien  ""
605390075Sobrien{
605490075Sobrien  ia64_expand_epilogue (0);
605590075Sobrien  DONE;
6056117395Skan})
605790075Sobrien
605890075Sobrien(define_expand "sibcall_epilogue"
605990075Sobrien  [(return)]
606090075Sobrien  ""
606190075Sobrien{
606290075Sobrien  ia64_expand_epilogue (1);
606390075Sobrien  DONE;
6064117395Skan})
606590075Sobrien
606690075Sobrien;; This prevents the scheduler from moving the SP decrement past FP-relative
606790075Sobrien;; stack accesses.  This is the same as adddi3 plus the extra set.
606890075Sobrien
606990075Sobrien(define_insn "prologue_allocate_stack"
607090075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
607190075Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
607290075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
607396263Sobrien   (set (match_operand:DI 3 "register_operand" "+r,r,r")
607490075Sobrien	(match_dup 3))]
607590075Sobrien  ""
607690075Sobrien  "@
6077117395Skan   add %0 = %1, %2
6078117395Skan   adds %0 = %2, %1
6079117395Skan   addl %0 = %2, %1"
608090075Sobrien  [(set_attr "itanium_class" "ialu")])
608190075Sobrien
608290075Sobrien;; This prevents the scheduler from moving the SP restore past FP-relative
608390075Sobrien;; stack accesses.  This is similar to movdi plus the extra set.
608490075Sobrien
608590075Sobrien(define_insn "epilogue_deallocate_stack"
608690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
608790075Sobrien	(match_operand:DI 1 "register_operand" "+r"))
608890075Sobrien   (set (match_dup 1) (match_dup 1))]
608990075Sobrien  ""
609090075Sobrien  "mov %0 = %1"
609190075Sobrien  [(set_attr "itanium_class" "ialu")])
609290075Sobrien
6093117395Skan;; As USE insns aren't meaningful after reload, this is used instead
6094117395Skan;; to prevent deleting instructions setting registers for EH handling
6095117395Skan(define_insn "prologue_use"
6096117395Skan  [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
6097117395Skan	      UNSPEC_PROLOGUE_USE)]
6098117395Skan  ""
6099117395Skan  ""
6100117395Skan  [(set_attr "itanium_class" "ignore")
6101132718Skan   (set_attr "predicable" "no")
6102132718Skan   (set_attr "empty" "yes")])
6103117395Skan
610490075Sobrien;; Allocate a new register frame.
610590075Sobrien
610690075Sobrien(define_insn "alloc"
610790075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
6108117395Skan	(unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
610990075Sobrien   (use (match_operand:DI 1 "const_int_operand" "i"))
611090075Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
611190075Sobrien   (use (match_operand:DI 3 "const_int_operand" "i"))
611290075Sobrien   (use (match_operand:DI 4 "const_int_operand" "i"))]
611390075Sobrien  ""
611490075Sobrien  "alloc %0 = ar.pfs, %1, %2, %3, %4"
611590075Sobrien  [(set_attr "itanium_class" "syst_m0")
6116169689Skan   (set_attr "predicable" "no")
6117169689Skan   (set_attr "first_insn" "yes")])
611890075Sobrien
611990075Sobrien;; Modifies ar.unat
612090075Sobrien(define_expand "gr_spill"
612190075Sobrien  [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
612290075Sobrien		   (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6123117395Skan			       (match_operand:DI 2 "const_int_operand" "")]
6124117395Skan			      UNSPEC_GR_SPILL))
612590075Sobrien	      (clobber (match_dup 3))])]
612690075Sobrien  ""
612790075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
612890075Sobrien
612990075Sobrien(define_insn "gr_spill_internal"
6130169689Skan  [(set (match_operand:DI 0 "destination_operand" "=m")
613190075Sobrien	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
6132117395Skan		    (match_operand:DI 2 "const_int_operand" "")]
6133117395Skan		   UNSPEC_GR_SPILL))
613490075Sobrien   (clobber (match_operand:DI 3 "register_operand" ""))]
613590075Sobrien  ""
613690075Sobrien{
6137117395Skan  /* Note that we use a C output pattern here to avoid the predicate
6138117395Skan     being automatically added before the .mem.offset directive.  */
6139117395Skan  return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
6140117395Skan}
614190075Sobrien  [(set_attr "itanium_class" "st")])
614290075Sobrien
614390075Sobrien;; Reads ar.unat
614490075Sobrien(define_expand "gr_restore"
614590075Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
614690075Sobrien		   (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
6147117395Skan			       (match_operand:DI 2 "const_int_operand" "")]
6148117395Skan			      UNSPEC_GR_RESTORE))
614990075Sobrien	      (use (match_dup 3))])]
615090075Sobrien  ""
615190075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
615290075Sobrien
615390075Sobrien(define_insn "gr_restore_internal"
615490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
615590075Sobrien	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
6156117395Skan		    (match_operand:DI 2 "const_int_operand" "")]
6157117395Skan		   UNSPEC_GR_RESTORE))
615890075Sobrien   (use (match_operand:DI 3 "register_operand" ""))]
615990075Sobrien  ""
6160117395Skan  { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
616190075Sobrien  [(set_attr "itanium_class" "ld")])
616290075Sobrien
616390075Sobrien(define_insn "fr_spill"
6164169689Skan  [(set (match_operand:XF 0 "destination_operand" "=m")
6165132718Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "f")]
6166117395Skan		   UNSPEC_FR_SPILL))]
616790075Sobrien  ""
616890075Sobrien  "stf.spill %0 = %1%P0"
616990075Sobrien  [(set_attr "itanium_class" "stf")])
617090075Sobrien
617190075Sobrien(define_insn "fr_restore"
6172132718Skan  [(set (match_operand:XF 0 "register_operand" "=f")
6173132718Skan	(unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
6174117395Skan		   UNSPEC_FR_RESTORE))]
617590075Sobrien  ""
617690075Sobrien  "ldf.fill %0 = %1%P1"
617790075Sobrien  [(set_attr "itanium_class" "fld")])
617890075Sobrien
617990075Sobrien;; ??? The explicit stop is not ideal.  It would be better if
618090075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
618190075Sobrien;; fixed later.  This avoids an RSE DV.
618290075Sobrien
618390075Sobrien(define_insn "bsp_value"
618490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
6185117395Skan	(unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
618690075Sobrien  ""
6187117395Skan  "*
6188117395Skan{
6189117395Skan  return \";;\;%,mov %0 = ar.bsp\";
6190117395Skan}"
619190075Sobrien  [(set_attr "itanium_class" "frar_i")])
619290075Sobrien
619390075Sobrien(define_insn "set_bsp"
6194117395Skan  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
6195117395Skan		    UNSPECV_SET_BSP)]
619690075Sobrien  ""
6197117395Skan  "flushrs
6198117395Skan	mov r19=ar.rsc
6199117395Skan	;;
6200117395Skan	and r19=0x1c,r19
6201117395Skan	;;
6202117395Skan	mov ar.rsc=r19
6203117395Skan	;;
6204117395Skan	mov ar.bspstore=%0
6205117395Skan	;;
6206117395Skan	or r19=0x3,r19
6207117395Skan	;;
6208117395Skan	loadrs
6209117395Skan	invala
6210117395Skan	;;
6211117395Skan	mov ar.rsc=r19"
621290075Sobrien  [(set_attr "itanium_class" "unknown")
621390075Sobrien   (set_attr "predicable" "no")])
621490075Sobrien
621590075Sobrien;; ??? The explicit stops are not ideal.  It would be better if
621690075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
621790075Sobrien;; fixed later.  This avoids an RSE DV.
621890075Sobrien
621990075Sobrien(define_insn "flushrs"
6220117395Skan  [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
622190075Sobrien  ""
622290075Sobrien  ";;\;flushrs\;;;"
6223117395Skan  [(set_attr "itanium_class" "rse_m")
6224117395Skan   (set_attr "predicable" "no")])
622590075Sobrien
622690075Sobrien;; ::::::::::::::::::::
622790075Sobrien;; ::
622890075Sobrien;; :: Miscellaneous instructions
622990075Sobrien;; ::
623090075Sobrien;; ::::::::::::::::::::
623190075Sobrien
6232132718Skan;; ??? Emitting a NOP instruction isn't very useful.  This should probably
623390075Sobrien;; be emitting ";;" to force a break in the instruction packing.
623490075Sobrien
623590075Sobrien;; No operation, needed in case the user uses -g but not -O.
623690075Sobrien(define_insn "nop"
623790075Sobrien  [(const_int 0)]
623890075Sobrien  ""
623990075Sobrien  "nop 0"
6240132718Skan  [(set_attr "itanium_class" "nop")])
624190075Sobrien
624290075Sobrien(define_insn "nop_m"
624390075Sobrien  [(const_int 1)]
624490075Sobrien  ""
624590075Sobrien  "nop.m 0"
624690075Sobrien  [(set_attr "itanium_class" "nop_m")])
624790075Sobrien
624890075Sobrien(define_insn "nop_i"
624990075Sobrien  [(const_int 2)]
625090075Sobrien  ""
625190075Sobrien  "nop.i 0"
625290075Sobrien  [(set_attr "itanium_class" "nop_i")])
625390075Sobrien
625490075Sobrien(define_insn "nop_f"
625590075Sobrien  [(const_int 3)]
625690075Sobrien  ""
625790075Sobrien  "nop.f 0"
625890075Sobrien  [(set_attr "itanium_class" "nop_f")])
625990075Sobrien
626090075Sobrien(define_insn "nop_b"
626190075Sobrien  [(const_int 4)]
626290075Sobrien  ""
626390075Sobrien  "nop.b 0"
626490075Sobrien  [(set_attr "itanium_class" "nop_b")])
626590075Sobrien
626690075Sobrien(define_insn "nop_x"
626790075Sobrien  [(const_int 5)]
626890075Sobrien  ""
626990075Sobrien  ""
6270132718Skan  [(set_attr "itanium_class" "nop_x")
6271132718Skan   (set_attr "empty" "yes")])
627290075Sobrien
6273132718Skan;; The following insn will be never generated.  It is used only by
6274132718Skan;; insn scheduler to change state before advancing cycle.
6275132718Skan(define_insn "pre_cycle"
6276132718Skan  [(const_int 6)]
6277132718Skan  ""
6278132718Skan  ""
6279132718Skan  [(set_attr "itanium_class" "pre_cycle")])
6280132718Skan
628190075Sobrien(define_insn "bundle_selector"
6282117395Skan  [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
628390075Sobrien  ""
6284117395Skan  { return get_bundle_name (INTVAL (operands[0])); }
628590075Sobrien  [(set_attr "itanium_class" "ignore")
628690075Sobrien   (set_attr "predicable" "no")])
628790075Sobrien
628890075Sobrien;; Pseudo instruction that prevents the scheduler from moving code above this
628990075Sobrien;; point.
629090075Sobrien(define_insn "blockage"
6291117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
629290075Sobrien  ""
629390075Sobrien  ""
629490075Sobrien  [(set_attr "itanium_class" "ignore")
629590075Sobrien   (set_attr "predicable" "no")])
629690075Sobrien
629790075Sobrien(define_insn "insn_group_barrier"
6298117395Skan  [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
6299117395Skan		    UNSPECV_INSN_GROUP_BARRIER)]
630090075Sobrien  ""
630190075Sobrien  ";;"
630290075Sobrien  [(set_attr "itanium_class" "stop_bit")
6303132718Skan   (set_attr "predicable" "no")
6304132718Skan   (set_attr "empty" "yes")])
630590075Sobrien
630696263Sobrien(define_expand "trap"
630796263Sobrien  [(trap_if (const_int 1) (const_int 0))]
630896263Sobrien  ""
630996263Sobrien  "")
631096263Sobrien
631196263Sobrien;; ??? We don't have a match-any slot type.  Setting the type to unknown
631296263Sobrien;; produces worse code that setting the slot type to A.
631396263Sobrien
631496263Sobrien(define_insn "*trap"
631596263Sobrien  [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
631696263Sobrien  ""
631796263Sobrien  "break %0"
6318169689Skan  [(set_attr "itanium_class" "chk_s_i")])
631996263Sobrien
632096263Sobrien(define_expand "conditional_trap"
632196263Sobrien  [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
632296263Sobrien  ""
632396263Sobrien{
632496263Sobrien  operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
632596263Sobrien})
632696263Sobrien
632796263Sobrien(define_insn "*conditional_trap"
632896263Sobrien  [(trap_if (match_operator 0 "predicate_operator"
632996263Sobrien	      [(match_operand:BI 1 "register_operand" "c")
633096263Sobrien	       (const_int 0)])  
633196263Sobrien	    (match_operand 2 "const_int_operand" ""))]
633296263Sobrien  ""
633396263Sobrien  "(%J0) break %2"
6334169689Skan  [(set_attr "itanium_class" "chk_s_i")
633596263Sobrien   (set_attr "predicable" "no")])
633696263Sobrien
633790075Sobrien(define_insn "break_f"
6338117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
633990075Sobrien  ""
634090075Sobrien  "break.f 0"
634190075Sobrien  [(set_attr "itanium_class" "nop_f")])
634290075Sobrien
634390075Sobrien(define_insn "prefetch"
634490075Sobrien  [(prefetch (match_operand:DI 0 "address_operand" "p")
634590075Sobrien	     (match_operand:DI 1 "const_int_operand" "n")
634690075Sobrien	     (match_operand:DI 2 "const_int_operand" "n"))]
634790075Sobrien  ""
634890075Sobrien{
634990075Sobrien  static const char * const alt[2][4] = {
635090075Sobrien    {
6351119256Skan      "%,lfetch.nta [%0]",
6352119256Skan      "%,lfetch.nt1 [%0]",
6353119256Skan      "%,lfetch.nt2 [%0]",
6354119256Skan      "%,lfetch [%0]"
635590075Sobrien    },
635690075Sobrien    {
6357119256Skan      "%,lfetch.excl.nta [%0]",
6358119256Skan      "%,lfetch.excl.nt1 [%0]",
6359119256Skan      "%,lfetch.excl.nt2 [%0]",
6360119256Skan      "%,lfetch.excl [%0]"
636190075Sobrien    }
636290075Sobrien  };
636390075Sobrien  int i = (INTVAL (operands[1]));
636490075Sobrien  int j = (INTVAL (operands[2]));
636590075Sobrien
6366169689Skan  gcc_assert (i == 0 || i == 1);
6367169689Skan  gcc_assert (j >= 0 && j <= 3);
636890075Sobrien  return alt[i][j];
636990075Sobrien}
637090075Sobrien  [(set_attr "itanium_class" "lfetch")])
637190075Sobrien
637290075Sobrien;; Non-local goto support.
637390075Sobrien
637490075Sobrien(define_expand "save_stack_nonlocal"
637590075Sobrien  [(use (match_operand:OI 0 "memory_operand" ""))
637690075Sobrien   (use (match_operand:DI 1 "register_operand" ""))]
637790075Sobrien  ""
637890075Sobrien{
637990075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
638090075Sobrien					 \"__ia64_save_stack_nonlocal\"),
638190075Sobrien		     0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
638290075Sobrien		     operands[1], Pmode);
638390075Sobrien  DONE;
6384117395Skan})
638590075Sobrien
638690075Sobrien(define_expand "nonlocal_goto"
638790075Sobrien  [(use (match_operand 0 "general_operand" ""))
638890075Sobrien   (use (match_operand 1 "general_operand" ""))
638990075Sobrien   (use (match_operand 2 "general_operand" ""))
639090075Sobrien   (use (match_operand 3 "general_operand" ""))]
639190075Sobrien  ""
639290075Sobrien{
639390075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
639490075Sobrien		     LCT_NORETURN, VOIDmode, 3,
639590075Sobrien		     operands[1], Pmode,
639690075Sobrien		     copy_to_reg (XEXP (operands[2], 0)), Pmode,
639790075Sobrien		     operands[3], Pmode);
639890075Sobrien  emit_barrier ();
639990075Sobrien  DONE;
6400117395Skan})
640190075Sobrien
6402117395Skan(define_insn_and_split "builtin_setjmp_receiver"
6403117395Skan  [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
640490075Sobrien  ""
6405117395Skan  "#"
6406117395Skan  "reload_completed"
6407117395Skan  [(const_int 0)]
640890075Sobrien{
6409117395Skan  ia64_reload_gp ();
641090075Sobrien  DONE;
6411117395Skan})
641290075Sobrien
641390075Sobrien(define_expand "eh_epilogue"
641490075Sobrien  [(use (match_operand:DI 0 "register_operand" "r"))
641590075Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
641690075Sobrien   (use (match_operand:DI 2 "register_operand" "r"))]
641790075Sobrien  ""
641890075Sobrien{
641990075Sobrien  rtx bsp = gen_rtx_REG (Pmode, 10);
642090075Sobrien  rtx sp = gen_rtx_REG (Pmode, 9);
642190075Sobrien
642290075Sobrien  if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
642390075Sobrien    {
642490075Sobrien      emit_move_insn (bsp, operands[0]);
642590075Sobrien      operands[0] = bsp;
642690075Sobrien    }
642790075Sobrien  if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
642890075Sobrien    {
642990075Sobrien      emit_move_insn (sp, operands[2]);
643090075Sobrien      operands[2] = sp;
643190075Sobrien    }
643290075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, sp));
643390075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, bsp));
643490075Sobrien
643590075Sobrien  cfun->machine->ia64_eh_epilogue_sp = sp;
643690075Sobrien  cfun->machine->ia64_eh_epilogue_bsp = bsp;
6437117395Skan})
643890075Sobrien
643990075Sobrien;; Builtin apply support.
644090075Sobrien
644190075Sobrien(define_expand "restore_stack_nonlocal"
644290075Sobrien  [(use (match_operand:DI 0 "register_operand" ""))
644390075Sobrien   (use (match_operand:OI 1 "memory_operand" ""))]
644490075Sobrien  ""
644590075Sobrien{
644690075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
6447117395Skan					 "__ia64_restore_stack_nonlocal"),
644890075Sobrien		     0, VOIDmode, 1,
644990075Sobrien		     copy_to_reg (XEXP (operands[1], 0)), Pmode);
645090075Sobrien  DONE;
6451117395Skan})
645290075Sobrien
645390075Sobrien
645490075Sobrien;; Predication.
645590075Sobrien
645690075Sobrien(define_cond_exec
645790075Sobrien  [(match_operator 0 "predicate_operator"
645890075Sobrien     [(match_operand:BI 1 "register_operand" "c")
645990075Sobrien      (const_int 0)])]
646090075Sobrien  ""
646190075Sobrien  "(%J0)")
646290075Sobrien
646390075Sobrien(define_insn "pred_rel_mutex"
646490075Sobrien  [(set (match_operand:BI 0 "register_operand" "+c")
6465117395Skan       (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
646690075Sobrien  ""
646790075Sobrien  ".pred.rel.mutex %0, %I0"
646890075Sobrien  [(set_attr "itanium_class" "ignore")
646990075Sobrien   (set_attr "predicable" "no")])
647090075Sobrien
647190075Sobrien(define_insn "safe_across_calls_all"
6472117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
647390075Sobrien  ""
647490075Sobrien  ".pred.safe_across_calls p1-p63"
647590075Sobrien  [(set_attr "itanium_class" "ignore")
647690075Sobrien   (set_attr "predicable" "no")])
647790075Sobrien
647890075Sobrien(define_insn "safe_across_calls_normal"
6479117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
648090075Sobrien  ""
648190075Sobrien{
6482132718Skan  emit_safe_across_calls ();
6483117395Skan  return "";
6484117395Skan}
648590075Sobrien  [(set_attr "itanium_class" "ignore")
648690075Sobrien   (set_attr "predicable" "no")])
648790075Sobrien
648890075Sobrien;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
648990075Sobrien;; pointer.  This is used by the HP-UX 32 bit mode.
649090075Sobrien
649190075Sobrien(define_insn "ptr_extend"
649290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
6493117395Skan        (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
6494117395Skan		   UNSPEC_ADDP4))]
649590075Sobrien  ""
649690075Sobrien  "addp4 %0 = 0,%1"
649790075Sobrien  [(set_attr "itanium_class" "ialu")])
649890075Sobrien
649990075Sobrien;;
6500117395Skan;; Optimizations for ptr_extend
6501117395Skan
6502132718Skan(define_insn "ptr_extend_plus_imm"
6503117395Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
6504117395Skan        (unspec:DI
6505117395Skan         [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
6506117395Skan                   (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
6507117395Skan         UNSPEC_ADDP4))]
6508117395Skan  "addp4_optimize_ok (operands[1], operands[2])"
6509117395Skan  "addp4 %0 = %2, %1"
6510117395Skan  [(set_attr "itanium_class" "ialu")])
6511117395Skan
6512117395Skan(define_insn "*ptr_extend_plus_2"
6513117395Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
6514117395Skan        (unspec:DI
6515117395Skan         [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
6516117395Skan                   (match_operand:SI 2 "basereg_operand" "r"))]
6517117395Skan         UNSPEC_ADDP4))]
6518117395Skan  "addp4_optimize_ok (operands[1], operands[2])"
6519117395Skan  "addp4 %0 = %1, %2"
6520117395Skan  [(set_attr "itanium_class" "ialu")])
6521169689Skan
6522169689Skan;;
6523169689Skan;; Get instruction pointer
6524169689Skan
6525169689Skan(define_insn "ip_value"
6526169689Skan  [(set (match_operand:DI 0 "register_operand" "=r")
6527169689Skan        (pc))]
6528169689Skan ""
6529169689Skan "mov %0 = ip"
6530169689Skan  [(set_attr "itanium_class" "ialu")])
6531169689Skan
6532169689Skan;; Vector operations
6533169689Skan(include "vect.md")
6534169689Skan;; Atomic operations
6535169689Skan(include "sync.md")
6536