ia64.md revision 119256
190075Sobrien;; IA-64 Machine description template
2117395Skan;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
390075Sobrien;; Contributed by James E. Wilson <wilson@cygnus.com> and
490075Sobrien;;		  David Mosberger <davidm@hpl.hp.com>.
590075Sobrien
690075Sobrien;; This file is part of GNU CC.
790075Sobrien
890075Sobrien;; GNU CC is free software; you can redistribute it and/or modify
990075Sobrien;; it under the terms of the GNU General Public License as published by
1090075Sobrien;; the Free Software Foundation; either version 2, or (at your option)
1190075Sobrien;; any later version.
1290075Sobrien
1390075Sobrien;; GNU CC is distributed in the hope that it will be useful,
1490075Sobrien;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1590075Sobrien;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1690075Sobrien;; GNU General Public License for more details.
1790075Sobrien
1890075Sobrien;; You should have received a copy of the GNU General Public License
1990075Sobrien;; along with GNU CC; see the file COPYING.  If not, write to
2090075Sobrien;; the Free Software Foundation, 59 Temple Place - Suite 330,
2190075Sobrien;; Boston, MA 02111-1307, USA.
2290075Sobrien
2390075Sobrien;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
2490075Sobrien
2590075Sobrien;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
2690075Sobrien;; reload.  This will be fixed once scheduling support is turned on.
2790075Sobrien
2890075Sobrien;; ??? Optimize for post-increment addressing modes.
2990075Sobrien
3090075Sobrien;; ??? fselect is not supported, because there is no integer register
3190075Sobrien;; equivalent.
3290075Sobrien
3390075Sobrien;; ??? fp abs/min/max instructions may also work for integer values.
3490075Sobrien
3590075Sobrien;; ??? Would a predicate_reg_operand predicate be useful?  The HP one is buggy,
3690075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking.
3790075Sobrien
3890075Sobrien;; ??? Would a branch_reg_operand predicate be useful?  The HP one is buggy,
3990075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking.
4090075Sobrien
4190075Sobrien;; ??? Go through list of documented named patterns and look for more to
4290075Sobrien;; implement.
4390075Sobrien
4490075Sobrien;; ??? Go through instruction manual and look for more instructions that
4590075Sobrien;; can be emitted.
4690075Sobrien
4790075Sobrien;; ??? Add function unit scheduling info for Itanium (TM) processor.
4890075Sobrien
4990075Sobrien;; ??? Need a better way to describe alternate fp status registers.
5090075Sobrien
51117395Skan(define_constants
52117395Skan  [; Relocations
53117395Skan   (UNSPEC_LTOFF_DTPMOD		0)
54117395Skan   (UNSPEC_LTOFF_DTPREL		1)
55117395Skan   (UNSPEC_DTPREL		2)
56117395Skan   (UNSPEC_LTOFF_TPREL		3)
57117395Skan   (UNSPEC_TPREL		4)
58117395Skan
59117395Skan   (UNSPEC_LD_BASE		9)
60117395Skan   (UNSPEC_GR_SPILL		10)
61117395Skan   (UNSPEC_GR_RESTORE		11)
62117395Skan   (UNSPEC_FR_SPILL		12)
63117395Skan   (UNSPEC_FR_RESTORE		13)
64117395Skan   (UNSPEC_FR_RECIP_APPROX	14)
65117395Skan   (UNSPEC_PRED_REL_MUTEX	15)
66117395Skan   (UNSPEC_POPCNT		16)
67117395Skan   (UNSPEC_PIC_CALL		17)
68117395Skan   (UNSPEC_MF			18)
69117395Skan   (UNSPEC_CMPXCHG_ACQ		19)
70117395Skan   (UNSPEC_FETCHADD_ACQ		20)
71117395Skan   (UNSPEC_BSP_VALUE		21)
72117395Skan   (UNSPEC_FLUSHRS		22)
73117395Skan   (UNSPEC_BUNDLE_SELECTOR	23)
74117395Skan   (UNSPEC_ADDP4		24)
75117395Skan   (UNSPEC_PROLOGUE_USE		25)
76117395Skan  ])
77117395Skan
78117395Skan(define_constants
79117395Skan  [(UNSPECV_ALLOC		0)
80117395Skan   (UNSPECV_BLOCKAGE		1)
81117395Skan   (UNSPECV_INSN_GROUP_BARRIER	2)
82117395Skan   (UNSPECV_BREAK		3)
83117395Skan   (UNSPECV_SET_BSP		4)
84117395Skan   (UNSPECV_PSAC_ALL		5)	; pred.safe_across_calls
85117395Skan   (UNSPECV_PSAC_NORMAL		6)
86117395Skan   (UNSPECV_SETJMP_RECEIVER	7)
87117395Skan  ])
8890075Sobrien
8990075Sobrien;; ::::::::::::::::::::
9090075Sobrien;; ::
9190075Sobrien;; :: Attributes
9290075Sobrien;; ::
9390075Sobrien;; ::::::::::::::::::::
9490075Sobrien
9590075Sobrien;; Instruction type.  This primarily determines how instructions can be
9690075Sobrien;; packed in bundles, and secondarily affects scheduling to function units.
9790075Sobrien
9890075Sobrien;; A alu, can go in I or M syllable of a bundle
9990075Sobrien;; I integer
10090075Sobrien;; M memory
10190075Sobrien;; F floating-point
10290075Sobrien;; B branch
10390075Sobrien;; L long immediate, takes two syllables
10490075Sobrien;; S stop bit
10590075Sobrien
10690075Sobrien;; ??? Should not have any pattern with type unknown.  Perhaps add code to
10790075Sobrien;; check this in md_reorg?  Currently use unknown for patterns which emit
10890075Sobrien;; multiple instructions, patterns which emit 0 instructions, and patterns
10990075Sobrien;; which emit instruction that can go in any slot (e.g. nop).
11090075Sobrien
111117395Skan(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
112117395Skan	fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
113117395Skan	chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
114117395Skan	syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f,
115117395Skan	nop_i,nop_m,nop_x,lfetch"
116117395Skan  (const_string "unknown"))
11790075Sobrien
11890075Sobrien;; chk_s has an I and an M form; use type A for convenience.
11990075Sobrien(define_attr "type" "unknown,A,I,M,F,B,L,X,S"
12090075Sobrien  (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
12190075Sobrien	 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
12290075Sobrien	 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
12390075Sobrien	 (eq_attr "itanium_class" "lfetch") (const_string "M")
12490075Sobrien	 (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A")
12590075Sobrien	 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
12690075Sobrien	 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
12790075Sobrien	 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
12890075Sobrien	 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
12990075Sobrien	 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
13090075Sobrien	 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
13190075Sobrien	 (eq_attr "itanium_class" "stop_bit") (const_string "S")
13290075Sobrien	 (eq_attr "itanium_class" "nop_x") (const_string "X")
13390075Sobrien	 (eq_attr "itanium_class" "long_i") (const_string "L")]
13490075Sobrien	(const_string "unknown")))
13590075Sobrien
13690075Sobrien(define_attr "itanium_requires_unit0" "no,yes"
13790075Sobrien  (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
13890075Sobrien	 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
13990075Sobrien	 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
14090075Sobrien	 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
14190075Sobrien	 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
14290075Sobrien	 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
14390075Sobrien	(const_string "no")))
14490075Sobrien
14590075Sobrien;; Predication.  True iff this instruction can be predicated.
14690075Sobrien
14790075Sobrien(define_attr "predicable" "no,yes" (const_string "yes"))
14890075Sobrien
14990075Sobrien
15090075Sobrien;; ::::::::::::::::::::
15190075Sobrien;; ::
15290075Sobrien;; :: Function Units
15390075Sobrien;; ::
15490075Sobrien;; ::::::::::::::::::::
15590075Sobrien
15690075Sobrien;; We define 6 "dummy" functional units.  All the real work to decide which
15790075Sobrien;; insn uses which unit is done by our MD_SCHED_REORDER hooks.  We only
15890075Sobrien;; have to ensure here that there are enough copies of the dummy unit so
15990075Sobrien;; that the scheduler doesn't get confused by MD_SCHED_REORDER.
16090075Sobrien;; Other than the 6 dummies for normal insns, we also add a single dummy unit
16190075Sobrien;; for stop bits.
16290075Sobrien
16390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br")     0 0)
16490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall")  0 0)
16590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp")   2 0)
16690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0)
16790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld")    9 0)
16890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac")   5 0)
16990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc")  5 0)
17090075Sobrien
17190075Sobrien;; There is only one insn `mov = ar.bsp' for frar_i:
17290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0)
17390075Sobrien;; There is only ony insn `mov = ar.unat' for frar_m:
17490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0)
17590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr")   2 0)
17690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr")   2 0)
17790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr")   2 0)
17890075Sobrien
17990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu")   1 0)
18090075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp")   1 0)
18190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog")   1 0)
18290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf")   1 0)
18390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld")     2 0)
18490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0)
18590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul")  2 0)
18690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf")  2 0)
18790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi")  2 0)
18890075Sobrien
18990075Sobrien;; Now we have only one insn (flushrs) of such class.  We assume that flushrs
19090075Sobrien;; is the 1st syllable of the bundle after stop bit.
19190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m")  0 0)
19290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem")   11 0)
19390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf")    1 0)
19490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st")     1 0)
19590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0)
19690075Sobrien;; Now we use only one insn `mf'.  Therfore latency time is set up to 0.
19790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0)
19890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit")   1 0)
19990075Sobrien
20090075Sobrien;; There is only one insn `mov ar.pfs =' for toar_i therefore we use
20190075Sobrien;; latency time equal to 0:
20290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0)
20390075Sobrien;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
20490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0)
20590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr")   1 0)
20690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr")   9 0)
20790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr")   1 0)
20890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy")   7 0)
20990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd")    1 0)
21090075Sobrien
21190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m")  0 0)
21290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i")  0 0)
21390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f")  0 0)
21490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b")  0 0)
21590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x")  0 0)
21690075Sobrien
21790075Sobrien(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0)
21890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0)
21990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0)
22090075Sobrien
22190075Sobrien;; ::::::::::::::::::::
22290075Sobrien;; ::
22390075Sobrien;; :: Moves
22490075Sobrien;; ::
22590075Sobrien;; ::::::::::::::::::::
22690075Sobrien
22790075Sobrien;; Set of a single predicate register.  This is only used to implement
22890075Sobrien;; pr-to-pr move and complement.
22990075Sobrien
23090075Sobrien(define_insn "*movcci"
23190075Sobrien  [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
23290075Sobrien	(match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
23390075Sobrien  ""
23490075Sobrien  "@
23590075Sobrien   cmp.ne %0, p0 = r0, r0
23690075Sobrien   cmp.eq %0, p0 = r0, r0
23790075Sobrien   (%1) cmp.eq.unc %0, p0 = r0, r0"
23890075Sobrien  [(set_attr "itanium_class" "icmp")
23990075Sobrien   (set_attr "predicable" "no")])
24090075Sobrien
24190075Sobrien(define_insn "movbi"
24290075Sobrien  [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
24390075Sobrien	(match_operand:BI 1 "move_operand"         " O,n, c,  c,*r, n,*m,*r,*r"))]
24490075Sobrien  ""
24590075Sobrien  "@
24690075Sobrien   cmp.ne %0, %I0 = r0, r0
24790075Sobrien   cmp.eq %0, %I0 = r0, r0
24890075Sobrien   #
24990075Sobrien   #
25090075Sobrien   tbit.nz %0, %I0 = %1, 0
25190075Sobrien   adds %0 = %1, r0
25290075Sobrien   ld1%O1 %0 = %1%P1
25390075Sobrien   st1%Q0 %0 = %1%P0
25490075Sobrien   mov %0 = %1"
25590075Sobrien  [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
25690075Sobrien
25790075Sobrien(define_split
25890075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
25990075Sobrien	(match_operand:BI 1 "register_operand" ""))]
26090075Sobrien  "reload_completed
26190075Sobrien   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
26290075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
26390075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
26490075Sobrien     (set (match_dup 0) (const_int 1)))
26590075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
26690075Sobrien     (set (match_dup 0) (const_int 0)))]
26790075Sobrien  "")
26890075Sobrien
26990075Sobrien(define_split
27090075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
27190075Sobrien	(match_operand:BI 1 "register_operand" ""))]
27290075Sobrien  "reload_completed
27390075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
27490075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
27590075Sobrien  [(set (match_dup 2) (match_dup 4))
27690075Sobrien   (set (match_dup 3) (match_dup 5))
277117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
27890075Sobrien  "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
27990075Sobrien   operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
28090075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
28190075Sobrien   operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
28290075Sobrien
28390075Sobrien(define_expand "movqi"
28490075Sobrien  [(set (match_operand:QI 0 "general_operand" "")
28590075Sobrien	(match_operand:QI 1 "general_operand" ""))]
28690075Sobrien  ""
28790075Sobrien{
288117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
289117395Skan  if (!op1)
290117395Skan    DONE;
291117395Skan  operands[1] = op1;
292117395Skan})
29390075Sobrien
29490075Sobrien(define_insn "*movqi_internal"
29590075Sobrien  [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
29690075Sobrien	(match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
29790075Sobrien  "ia64_move_ok (operands[0], operands[1])"
29890075Sobrien  "@
29990075Sobrien   mov %0 = %r1
30090075Sobrien   addl %0 = %1, r0
30190075Sobrien   ld1%O1 %0 = %1%P1
30290075Sobrien   st1%Q0 %0 = %r1%P0
30390075Sobrien   getf.sig %0 = %1
30490075Sobrien   setf.sig %0 = %r1
30590075Sobrien   mov %0 = %1"
30690075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
30790075Sobrien
30890075Sobrien(define_expand "movhi"
30990075Sobrien  [(set (match_operand:HI 0 "general_operand" "")
31090075Sobrien	(match_operand:HI 1 "general_operand" ""))]
31190075Sobrien  ""
31290075Sobrien{
313117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
314117395Skan  if (!op1)
315117395Skan    DONE;
316117395Skan  operands[1] = op1;
317117395Skan})
31890075Sobrien
31990075Sobrien(define_insn "*movhi_internal"
32090075Sobrien  [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
32190075Sobrien	(match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
32290075Sobrien  "ia64_move_ok (operands[0], operands[1])"
32390075Sobrien  "@
32490075Sobrien   mov %0 = %r1
32590075Sobrien   addl %0 = %1, r0
32690075Sobrien   ld2%O1 %0 = %1%P1
32790075Sobrien   st2%Q0 %0 = %r1%P0
32890075Sobrien   getf.sig %0 = %1
32990075Sobrien   setf.sig %0 = %r1
33090075Sobrien   mov %0 = %1"
33190075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
33290075Sobrien
33390075Sobrien(define_expand "movsi"
33490075Sobrien  [(set (match_operand:SI 0 "general_operand" "")
33590075Sobrien	(match_operand:SI 1 "general_operand" ""))]
33690075Sobrien  ""
33790075Sobrien{
338117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
339117395Skan  if (!op1)
340117395Skan    DONE;
341117395Skan  operands[1] = op1;
342117395Skan})
34390075Sobrien
344117395Skan;; This is used during early compilation to delay the decision on
345117395Skan;; how to refer to a variable as long as possible.  This is especially
346117395Skan;; important between initial rtl generation and optimization for
347117395Skan;; deferred functions, since we may acquire additional information
348117395Skan;; on the variables used in the meantime.
349117395Skan
350117395Skan(define_insn_and_split "movsi_symbolic"
351117395Skan  [(set (match_operand:SI 0 "register_operand" "=r")
352117395Skan	(match_operand:SI 1 "symbolic_operand" "s"))
353117395Skan   (clobber (match_scratch:DI 2 "=r"))
354117395Skan   (use (reg:DI 1))]
355117395Skan  ""
356117395Skan  "* abort ();"
357117395Skan  "!no_new_pseudos || reload_completed"
358117395Skan  [(const_int 0)]
359117395Skan{
360117395Skan  rtx scratch = operands[2];
361117395Skan  if (!reload_completed)
362117395Skan    scratch = gen_reg_rtx (Pmode);
363117395Skan  ia64_expand_load_address (operands[0], operands[1], scratch); 
364117395Skan  DONE;
365117395Skan})
366117395Skan
36790075Sobrien(define_insn "*movsi_internal"
36890075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
36990075Sobrien	(match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
37090075Sobrien  "ia64_move_ok (operands[0], operands[1])"
37190075Sobrien  "@
37290075Sobrien  mov %0 = %r1
37390075Sobrien  addl %0 = %1, r0
37490075Sobrien  movl %0 = %1
37590075Sobrien  ld4%O1 %0 = %1%P1
37690075Sobrien  st4%Q0 %0 = %r1%P0
37790075Sobrien  getf.sig %0 = %1
37890075Sobrien  setf.sig %0 = %r1
37990075Sobrien  mov %0 = %1
38090075Sobrien  mov %0 = %1
38190075Sobrien  mov %0 = %r1"
382117395Skan  ;; frar_m, toar_m ??? why not frar_i and toar_i
38390075Sobrien  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
38490075Sobrien
38590075Sobrien(define_expand "movdi"
38690075Sobrien  [(set (match_operand:DI 0 "general_operand" "")
38790075Sobrien	(match_operand:DI 1 "general_operand" ""))]
38890075Sobrien  ""
38990075Sobrien{
390117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
391117395Skan  if (!op1)
392117395Skan    DONE;
393117395Skan  operands[1] = op1;
394117395Skan})
39590075Sobrien
39690075Sobrien;; This is used during early compilation to delay the decision on
39790075Sobrien;; how to refer to a variable as long as possible.  This is especially
39890075Sobrien;; important between initial rtl generation and optimization for
39990075Sobrien;; deferred functions, since we may acquire additional information
40090075Sobrien;; on the variables used in the meantime.
40190075Sobrien
40290075Sobrien(define_insn_and_split "movdi_symbolic"
40390075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
40490075Sobrien	(match_operand:DI 1 "symbolic_operand" "s"))
405117395Skan   (clobber (match_scratch:DI 2 "=r"))
40690075Sobrien   (use (reg:DI 1))]
40790075Sobrien  ""
40890075Sobrien  "* abort ();"
409117395Skan  "!no_new_pseudos || reload_completed"
41090075Sobrien  [(const_int 0)]
411117395Skan{
412117395Skan  rtx scratch = operands[2];
413117395Skan  if (!reload_completed)
414117395Skan    scratch = gen_reg_rtx (Pmode);
415117395Skan  ia64_expand_load_address (operands[0], operands[1], scratch); 
416117395Skan  DONE;
417117395Skan})
41890075Sobrien
41990075Sobrien(define_insn "*movdi_internal"
42090075Sobrien  [(set (match_operand:DI 0 "destination_operand"
42190075Sobrien		    "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
42290075Sobrien	(match_operand:DI 1 "move_operand"
42390075Sobrien		    "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
42490075Sobrien  "ia64_move_ok (operands[0], operands[1])"
42590075Sobrien{
42690075Sobrien  static const char * const alt[] = {
427117395Skan    "%,mov %0 = %r1",
428117395Skan    "%,addl %0 = %1, r0",
429117395Skan    "%,movl %0 = %1",
430117395Skan    "%,ld8%O1 %0 = %1%P1",
431117395Skan    "%,st8%Q0 %0 = %r1%P0",
432117395Skan    "%,getf.sig %0 = %1",
433117395Skan    "%,setf.sig %0 = %r1",
434117395Skan    "%,mov %0 = %1",
435117395Skan    "%,ldf8 %0 = %1%P1",
436117395Skan    "%,stf8 %0 = %1%P0",
437117395Skan    "%,mov %0 = %1",
438117395Skan    "%,mov %0 = %r1",
439117395Skan    "%,mov %0 = %1",
440117395Skan    "%,mov %0 = %1",
441117395Skan    "%,mov %0 = %1",
442117395Skan    "%,mov %0 = %1",
443117395Skan    "mov %0 = pr",
444117395Skan    "mov pr = %1, -1"
44590075Sobrien  };
44690075Sobrien
44790075Sobrien  if (which_alternative == 2 && ! TARGET_NO_PIC
44890075Sobrien      && symbolic_operand (operands[1], VOIDmode))
44990075Sobrien    abort ();
45090075Sobrien
45190075Sobrien  return alt[which_alternative];
452117395Skan}
45390075Sobrien  [(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")])
45490075Sobrien
45590075Sobrien(define_split
45690075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
45790075Sobrien	(match_operand:DI 1 "symbolic_operand" ""))]
45890075Sobrien  "reload_completed && ! TARGET_NO_PIC"
45990075Sobrien  [(const_int 0)]
46090075Sobrien{
46190075Sobrien  ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
46290075Sobrien  DONE;
463117395Skan})
46490075Sobrien
46590075Sobrien(define_expand "load_fptr"
46690075Sobrien  [(set (match_dup 2)
467117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
46890075Sobrien   (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
46990075Sobrien  ""
47090075Sobrien{
47190075Sobrien  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
47290075Sobrien  operands[3] = gen_rtx_MEM (DImode, operands[2]);
47390075Sobrien  RTX_UNCHANGING_P (operands[3]) = 1;
474117395Skan})
47590075Sobrien
47690075Sobrien(define_insn "*load_fptr_internal1"
47790075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
478117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
47990075Sobrien  ""
48090075Sobrien  "addl %0 = @ltoff(@fptr(%1)), gp"
48190075Sobrien  [(set_attr "itanium_class" "ialu")])
48290075Sobrien
48390075Sobrien(define_insn "load_gprel"
48490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
485117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
48690075Sobrien  ""
48790075Sobrien  "addl %0 = @gprel(%1), gp"
48890075Sobrien  [(set_attr "itanium_class" "ialu")])
48990075Sobrien
49090075Sobrien(define_insn "gprel64_offset"
49190075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
49290075Sobrien	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
49390075Sobrien  ""
49490075Sobrien  "movl %0 = @gprel(%1)"
49590075Sobrien  [(set_attr "itanium_class" "long_i")])
49690075Sobrien
49790075Sobrien(define_expand "load_gprel64"
49890075Sobrien  [(set (match_dup 2)
49990075Sobrien	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
50090075Sobrien   (set (match_operand:DI 0 "register_operand" "")
50190075Sobrien	(plus:DI (match_dup 3) (match_dup 2)))]
50290075Sobrien  ""
50390075Sobrien{
50490075Sobrien  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
50590075Sobrien  operands[3] = pic_offset_table_rtx;
506117395Skan})
50790075Sobrien
50890075Sobrien(define_expand "load_symptr"
50990075Sobrien  [(set (match_operand:DI 2 "register_operand" "")
510117395Skan	(plus:DI (high:DI (match_operand:DI 1 "got_symbolic_operand" ""))
511117395Skan		 (match_dup 3)))
512117395Skan   (set (match_operand:DI 0 "register_operand" "")
513117395Skan	(lo_sum:DI (match_dup 2) (match_dup 1)))]
51490075Sobrien  ""
51590075Sobrien{
516117395Skan  operands[3] = pic_offset_table_rtx;
517117395Skan})
51890075Sobrien
519117395Skan(define_insn "*load_symptr_high"
52090075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
521117395Skan	(plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
522117395Skan		 (match_operand:DI 2 "register_operand" "a")))]
52390075Sobrien  ""
524117395Skan{
525117395Skan  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
526117395Skan    return "%,addl %0 = @ltoffx(%1), %2";
527117395Skan  else
528117395Skan    return "%,addl %0 = @ltoff(%1), %2";
529117395Skan}
53090075Sobrien  [(set_attr "itanium_class" "ialu")])
53190075Sobrien
532117395Skan(define_insn "*load_symptr_low"
533117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
534117395Skan	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
535117395Skan		   (match_operand 2 "got_symbolic_operand" "s")))]
536117395Skan  ""
537117395Skan{
538117395Skan  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
539117395Skan    return "%,ld8.mov %0 = [%1], %2";
540117395Skan  else
541117395Skan    return "%,ld8 %0 = [%1]";
542117395Skan}
543117395Skan  [(set_attr "itanium_class" "ld")])
544117395Skan
545117395Skan(define_insn "load_ltoff_dtpmod"
546117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
547117395Skan	(plus:DI (reg:DI 1)
548117395Skan		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
549117395Skan			    UNSPEC_LTOFF_DTPMOD)))]
550117395Skan  ""
551117395Skan  "addl %0 = @ltoff(@dtpmod(%1)), gp"
552117395Skan  [(set_attr "itanium_class" "ialu")])
553117395Skan
554117395Skan(define_insn "load_ltoff_dtprel"
555117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
556117395Skan	(plus:DI (reg:DI 1)
557117395Skan		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
558117395Skan			    UNSPEC_LTOFF_DTPREL)))]
559117395Skan  ""
560117395Skan  "addl %0 = @ltoff(@dtprel(%1)), gp"
561117395Skan  [(set_attr "itanium_class" "ialu")])
562117395Skan
563117395Skan(define_expand "load_dtprel"
564117395Skan  [(set (match_operand:DI 0 "register_operand" "")
565117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
566117395Skan		   UNSPEC_DTPREL))]
567117395Skan  ""
568117395Skan  "")
569117395Skan
570117395Skan(define_insn "*load_dtprel64"
571117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
572117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
573117395Skan		   UNSPEC_DTPREL))]
574117395Skan  "TARGET_TLS64"
575117395Skan  "movl %0 = @dtprel(%1)"
576117395Skan  [(set_attr "itanium_class" "long_i")])
577117395Skan
578117395Skan(define_insn "*load_dtprel22"
579117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
580117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
581117395Skan		   UNSPEC_DTPREL))]
582117395Skan  ""
583117395Skan  "addl %0 = @dtprel(%1), r0"
584117395Skan  [(set_attr "itanium_class" "ialu")])
585117395Skan
586117395Skan(define_expand "add_dtprel"
587117395Skan  [(set (match_operand:DI 0 "register_operand" "")
588117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "")
589117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
590117395Skan			    UNSPEC_DTPREL)))]
591117395Skan  "!TARGET_TLS64"
592117395Skan  "")
593117395Skan
594117395Skan(define_insn "*add_dtprel14"
595117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
596117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "r")
597117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
598117395Skan			    UNSPEC_DTPREL)))]
599117395Skan  "TARGET_TLS14"
600117395Skan  "adds %0 = @dtprel(%2), %1"
601117395Skan  [(set_attr "itanium_class" "ialu")])
602117395Skan
603117395Skan(define_insn "*add_dtprel22"
604117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
605117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "a")
606117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
607117395Skan			    UNSPEC_DTPREL)))]
608117395Skan  "TARGET_TLS22"
609117395Skan  "addl %0 = @dtprel(%2), %1"
610117395Skan  [(set_attr "itanium_class" "ialu")])
611117395Skan
612117395Skan(define_insn "load_ltoff_tprel"
613117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
614117395Skan	(plus:DI (reg:DI 1)
615117395Skan		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
616117395Skan			    UNSPEC_LTOFF_TPREL)))]
617117395Skan  ""
618117395Skan  "addl %0 = @ltoff(@tprel(%1)), gp"
619117395Skan  [(set_attr "itanium_class" "ialu")])
620117395Skan
621117395Skan(define_expand "load_tprel"
622117395Skan  [(set (match_operand:DI 0 "register_operand" "")
623117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
624117395Skan		   UNSPEC_TPREL))]
625117395Skan  ""
626117395Skan  "")
627117395Skan
628117395Skan(define_insn "*load_tprel64"
629117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
630117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
631117395Skan		   UNSPEC_TPREL))]
632117395Skan  "TARGET_TLS64"
633117395Skan  "movl %0 = @tprel(%1)"
634117395Skan  [(set_attr "itanium_class" "long_i")])
635117395Skan
636117395Skan(define_insn "*load_tprel22"
637117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
638117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
639117395Skan		   UNSPEC_TPREL))]
640117395Skan  ""
641117395Skan  "addl %0 = @tprel(%1), r0"
642117395Skan  [(set_attr "itanium_class" "ialu")])
643117395Skan
644117395Skan(define_expand "add_tprel"
645117395Skan  [(set (match_operand:DI 0 "register_operand" "")
646117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "")
647117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
648117395Skan			    UNSPEC_TPREL)))]
649117395Skan  "!TARGET_TLS64"
650117395Skan  "")
651117395Skan
652117395Skan(define_insn "*add_tprel14"
653117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
654117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "r")
655117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
656117395Skan			    UNSPEC_TPREL)))]
657117395Skan  "TARGET_TLS14"
658117395Skan  "adds %0 = @tprel(%2), %1"
659117395Skan  [(set_attr "itanium_class" "ialu")])
660117395Skan
661117395Skan(define_insn "*add_tprel22"
662117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
663117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "a")
664117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
665117395Skan			    UNSPEC_TPREL)))]
666117395Skan  "TARGET_TLS22"
667117395Skan  "addl %0 = @tprel(%2), %1"
668117395Skan  [(set_attr "itanium_class" "ialu")])
669117395Skan
67090075Sobrien;; With no offsettable memory references, we've got to have a scratch
67190075Sobrien;; around to play with the second word.
67290075Sobrien(define_expand "movti"
67390075Sobrien  [(parallel [(set (match_operand:TI 0 "general_operand" "")
67490075Sobrien		   (match_operand:TI 1 "general_operand" ""))
67590075Sobrien	      (clobber (match_scratch:DI 2 ""))])]
67690075Sobrien  ""
67790075Sobrien{
678117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
679117395Skan  if (!op1)
680117395Skan    DONE;
681117395Skan  operands[1] = op1;
682117395Skan})
68390075Sobrien
68490075Sobrien(define_insn_and_split "*movti_internal"
68590075Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
68690075Sobrien	(match_operand:TI 1 "general_operand"      "ri,m,r"))
68790075Sobrien   (clobber (match_scratch:DI 2 "=X,&r,&r"))]
68890075Sobrien  "ia64_move_ok (operands[0], operands[1])"
68990075Sobrien  "#"
69090075Sobrien  "reload_completed"
69190075Sobrien  [(const_int 0)]
69290075Sobrien{
69390075Sobrien  rtx adj1, adj2, in[2], out[2], insn;
69490075Sobrien  int first;
69590075Sobrien
69690075Sobrien  adj1 = ia64_split_timode (in, operands[1], operands[2]);
69790075Sobrien  adj2 = ia64_split_timode (out, operands[0], operands[2]);
69890075Sobrien
69990075Sobrien  first = 0;
70090075Sobrien  if (reg_overlap_mentioned_p (out[0], in[1]))
70190075Sobrien    {
70290075Sobrien      if (reg_overlap_mentioned_p (out[1], in[0]))
70390075Sobrien	abort ();
70490075Sobrien      first = 1;
70590075Sobrien    }
70690075Sobrien
70790075Sobrien  if (adj1 && adj2)
70890075Sobrien    abort ();
70990075Sobrien  if (adj1)
71090075Sobrien    emit_insn (adj1);
71190075Sobrien  if (adj2)
71290075Sobrien    emit_insn (adj2);
71390075Sobrien  insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
71490075Sobrien  if (GET_CODE (out[first]) == MEM
71590075Sobrien      && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
71690075Sobrien    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
71790075Sobrien					  XEXP (XEXP (out[first], 0), 0),
71890075Sobrien					  REG_NOTES (insn));
71990075Sobrien  insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
72090075Sobrien  if (GET_CODE (out[!first]) == MEM
72190075Sobrien      && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
72290075Sobrien    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
72390075Sobrien					  XEXP (XEXP (out[!first], 0), 0),
72490075Sobrien					  REG_NOTES (insn));
72590075Sobrien  DONE;
726117395Skan}
72790075Sobrien  [(set_attr "itanium_class" "unknown")
72890075Sobrien   (set_attr "predicable" "no")])
72990075Sobrien
73090075Sobrien;; ??? SSA creates these.  Can't allow memories since we don't have
73190075Sobrien;; the scratch register.  Fortunately combine will know how to add
73290075Sobrien;; the clobber and scratch.
73390075Sobrien(define_insn_and_split "*movti_internal_reg"
73490075Sobrien  [(set (match_operand:TI 0 "register_operand"  "=r")
73590075Sobrien	(match_operand:TI 1 "nonmemory_operand" "ri"))]
73690075Sobrien  ""
73790075Sobrien  "#"
73890075Sobrien  "reload_completed"
73990075Sobrien  [(const_int 0)]
74090075Sobrien{
74190075Sobrien  rtx in[2], out[2];
74290075Sobrien  int first;
74390075Sobrien
74490075Sobrien  ia64_split_timode (in, operands[1], NULL_RTX);
74590075Sobrien  ia64_split_timode (out, operands[0], NULL_RTX);
74690075Sobrien
74790075Sobrien  first = 0;
74890075Sobrien  if (reg_overlap_mentioned_p (out[0], in[1]))
74990075Sobrien    {
75090075Sobrien      if (reg_overlap_mentioned_p (out[1], in[0]))
75190075Sobrien	abort ();
75290075Sobrien      first = 1;
75390075Sobrien    }
75490075Sobrien
75590075Sobrien  emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
75690075Sobrien  emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
75790075Sobrien  DONE;
758117395Skan}
75990075Sobrien  [(set_attr "itanium_class" "unknown")
76090075Sobrien   (set_attr "predicable" "no")])
76190075Sobrien
76290075Sobrien(define_expand "reload_inti"
76390075Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
76490075Sobrien		   (match_operand:TI 1 "" "m"))
76590075Sobrien	      (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
76690075Sobrien  ""
76790075Sobrien{
76890075Sobrien  unsigned int s_regno = REGNO (operands[2]);
76990075Sobrien  if (s_regno == REGNO (operands[0]))
77090075Sobrien    s_regno += 1;
77190075Sobrien  operands[2] = gen_rtx_REG (DImode, s_regno);
772117395Skan})
77390075Sobrien
77490075Sobrien(define_expand "reload_outti"
77590075Sobrien  [(parallel [(set (match_operand:TI 0 "" "=m")
77690075Sobrien		   (match_operand:TI 1 "register_operand" "r"))
77790075Sobrien	      (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
77890075Sobrien  ""
77990075Sobrien{
78090075Sobrien  unsigned int s_regno = REGNO (operands[2]);
78190075Sobrien  if (s_regno == REGNO (operands[1]))
78290075Sobrien    s_regno += 1;
78390075Sobrien  operands[2] = gen_rtx_REG (DImode, s_regno);
784117395Skan})
78590075Sobrien
78690075Sobrien;; Floating Point Moves
78790075Sobrien;;
78890075Sobrien;; Note - Patterns for SF mode moves are compulsory, but
789117395Skan;; patterns for DF are optional, as GCC can synthesize them.
79090075Sobrien
79190075Sobrien(define_expand "movsf"
79290075Sobrien  [(set (match_operand:SF 0 "general_operand" "")
79390075Sobrien	(match_operand:SF 1 "general_operand" ""))]
79490075Sobrien  ""
79590075Sobrien{
796117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
797117395Skan  if (!op1)
798117395Skan    DONE;
799117395Skan  operands[1] = op1;
800117395Skan})
80190075Sobrien
80290075Sobrien(define_insn "*movsf_internal"
80390075Sobrien  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
80490075Sobrien	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
80590075Sobrien  "ia64_move_ok (operands[0], operands[1])"
80690075Sobrien  "@
807117395Skan   mov %0 = %F1
808117395Skan   ldfs %0 = %1%P1
809117395Skan   stfs %0 = %F1%P0
810117395Skan   getf.s %0 = %F1
811117395Skan   setf.s %0 = %1
812117395Skan   mov %0 = %1
813117395Skan   ld4%O1 %0 = %1%P1
814117395Skan   st4%Q0 %0 = %1%P0"
81590075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
81690075Sobrien
81790075Sobrien(define_expand "movdf"
81890075Sobrien  [(set (match_operand:DF 0 "general_operand" "")
81990075Sobrien	(match_operand:DF 1 "general_operand" ""))]
82090075Sobrien  ""
82190075Sobrien{
822117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
823117395Skan  if (!op1)
824117395Skan    DONE;
825117395Skan  operands[1] = op1;
826117395Skan})
82790075Sobrien
82890075Sobrien(define_insn "*movdf_internal"
82990075Sobrien  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
83090075Sobrien	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
83190075Sobrien  "ia64_move_ok (operands[0], operands[1])"
83290075Sobrien  "@
833117395Skan   mov %0 = %F1
834117395Skan   ldfd %0 = %1%P1
835117395Skan   stfd %0 = %F1%P0
836117395Skan   getf.d %0 = %F1
837117395Skan   setf.d %0 = %1
838117395Skan   mov %0 = %1
839117395Skan   ld8%O1 %0 = %1%P1
840117395Skan   st8%Q0 %0 = %1%P0"
84190075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
84290075Sobrien
84390075Sobrien;; With no offsettable memory references, we've got to have a scratch
84490075Sobrien;; around to play with the second word if the variable winds up in GRs.
84590075Sobrien(define_expand "movtf"
84690075Sobrien  [(set (match_operand:TF 0 "general_operand" "")
84790075Sobrien	(match_operand:TF 1 "general_operand" ""))]
84890075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
84990075Sobrien{
85090075Sobrien  /* We must support TFmode loads into general registers for stdarg/vararg
85190075Sobrien     and unprototyped calls.  We split them into DImode loads for convenience.
85290075Sobrien     We don't need TFmode stores from general regs, because a stdarg/vararg
85390075Sobrien     routine does a block store to memory of unnamed arguments.  */
85490075Sobrien  if (GET_CODE (operands[0]) == REG
85590075Sobrien      && GR_REGNO_P (REGNO (operands[0])))
85690075Sobrien    {
85790075Sobrien      /* We're hoping to transform everything that deals with TFmode
85890075Sobrien	 quantities and GR registers early in the compiler.  */
85990075Sobrien      if (no_new_pseudos)
86090075Sobrien	abort ();
86190075Sobrien
86290075Sobrien      /* Struct to register can just use TImode instead.  */
86390075Sobrien      if ((GET_CODE (operands[1]) == SUBREG
86490075Sobrien	   && GET_MODE (SUBREG_REG (operands[1])) == TImode)
86590075Sobrien	  || (GET_CODE (operands[1]) == REG
86690075Sobrien	      && GR_REGNO_P (REGNO (operands[1]))))
86790075Sobrien	{
86890075Sobrien	  emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
86990075Sobrien			  SUBREG_REG (operands[1]));
87090075Sobrien	  DONE;
87190075Sobrien	}
87290075Sobrien
87390075Sobrien      if (GET_CODE (operands[1]) == CONST_DOUBLE)
87490075Sobrien	{
87590075Sobrien	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
87690075Sobrien			  operand_subword (operands[1], 0, 0, TFmode));
87790075Sobrien	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
87890075Sobrien			  operand_subword (operands[1], 1, 0, TFmode));
87990075Sobrien	  DONE;
88090075Sobrien	}
88190075Sobrien
88290075Sobrien      /* If the quantity is in a register not known to be GR, spill it.  */
88390075Sobrien      if (register_operand (operands[1], TFmode))
88490075Sobrien	operands[1] = spill_tfmode_operand (operands[1], 1);
88590075Sobrien
88690075Sobrien      if (GET_CODE (operands[1]) == MEM)
88790075Sobrien	{
88890075Sobrien	  rtx out[2];
88990075Sobrien
89090075Sobrien	  out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
89190075Sobrien	  out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
89290075Sobrien
89390075Sobrien	  emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
89490075Sobrien	  emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
89590075Sobrien	  DONE;
89690075Sobrien	}
89790075Sobrien
89890075Sobrien      abort ();
89990075Sobrien    }
90090075Sobrien
90190075Sobrien  if (! reload_in_progress && ! reload_completed)
90290075Sobrien    {
90390075Sobrien      operands[0] = spill_tfmode_operand (operands[0], 0);
90490075Sobrien      operands[1] = spill_tfmode_operand (operands[1], 0);
90590075Sobrien
90690075Sobrien      if (! ia64_move_ok (operands[0], operands[1]))
90790075Sobrien	operands[1] = force_reg (TFmode, operands[1]);
90890075Sobrien    }
909117395Skan})
91090075Sobrien
91190075Sobrien;; ??? There's no easy way to mind volatile acquire/release semantics.
91290075Sobrien
91390075Sobrien(define_insn "*movtf_internal"
91490075Sobrien  [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
91590075Sobrien	(match_operand:TF 1 "general_tfmode_operand"     "fG,m,fG"))]
91690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])"
91790075Sobrien  "@
918117395Skan   mov %0 = %F1
919117395Skan   ldfe %0 = %1%P1
920117395Skan   stfe %0 = %F1%P0"
92190075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf")])
92290075Sobrien
92390075Sobrien;; ::::::::::::::::::::
92490075Sobrien;; ::
92590075Sobrien;; :: Conversions
92690075Sobrien;; ::
92790075Sobrien;; ::::::::::::::::::::
92890075Sobrien
92990075Sobrien;; Signed conversions from a smaller integer to a larger integer
93090075Sobrien
93190075Sobrien(define_insn "extendqidi2"
93290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
93390075Sobrien	(sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
93490075Sobrien  ""
93590075Sobrien  "sxt1 %0 = %1"
93690075Sobrien  [(set_attr "itanium_class" "xtd")])
93790075Sobrien
93890075Sobrien(define_insn "extendhidi2"
93990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
94090075Sobrien	(sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
94190075Sobrien  ""
94290075Sobrien  "sxt2 %0 = %1"
94390075Sobrien  [(set_attr "itanium_class" "xtd")])
94490075Sobrien
94590075Sobrien(define_insn "extendsidi2"
94690075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
94790075Sobrien	(sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
94890075Sobrien  ""
94990075Sobrien  "@
95090075Sobrien   sxt4 %0 = %1
95190075Sobrien   fsxt.r %0 = %1, %1"
95290075Sobrien  [(set_attr "itanium_class" "xtd,fmisc")])
95390075Sobrien
95490075Sobrien;; Unsigned conversions from a smaller integer to a larger integer
95590075Sobrien
95690075Sobrien(define_insn "zero_extendqidi2"
95790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
95890075Sobrien	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
95990075Sobrien  ""
96090075Sobrien  "@
96190075Sobrien   zxt1 %0 = %1
96290075Sobrien   ld1%O1 %0 = %1%P1"
96390075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
96490075Sobrien
96590075Sobrien(define_insn "zero_extendhidi2"
96690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
96790075Sobrien	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
96890075Sobrien  ""
96990075Sobrien  "@
97090075Sobrien   zxt2 %0 = %1
97190075Sobrien   ld2%O1 %0 = %1%P1"
97290075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
97390075Sobrien
97490075Sobrien(define_insn "zero_extendsidi2"
97590075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
97690075Sobrien	(zero_extend:DI
97790075Sobrien	  (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
97890075Sobrien  ""
97990075Sobrien  "@
98090075Sobrien   zxt4 %0 = %1
98190075Sobrien   ld4%O1 %0 = %1%P1
98290075Sobrien   fmix.r %0 = f0, %1"
98390075Sobrien  [(set_attr "itanium_class" "xtd,ld,fmisc")])
98490075Sobrien
98590075Sobrien;; Convert between floating point types of different sizes.
98690075Sobrien
98790075Sobrien;; At first glance, it would appear that emitting fnorm for an extending
98890075Sobrien;; conversion is unnecessary.  However, the stf and getf instructions work
98990075Sobrien;; correctly only if the input is properly rounded for its type.  In
99090075Sobrien;; particular, we get the wrong result for getf.d/stfd if the input is a
99190075Sobrien;; denorm single.  Since we don't know what the next instruction will be, we
99290075Sobrien;; have to emit an fnorm.
99390075Sobrien
99490075Sobrien;; ??? Optimization opportunity here.  Get rid of the insn altogether
99590075Sobrien;; when we can.  Should probably use a scheme like has been proposed
99690075Sobrien;; for ia32 in dealing with operands that match unary operators.  This
99790075Sobrien;; would let combine merge the thing into adjacent insns.  See also how the
99890075Sobrien;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
99990075Sobrien;; se_register_operand.
100090075Sobrien
100190075Sobrien(define_insn "extendsfdf2"
100290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
100390075Sobrien	(float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
100490075Sobrien  ""
100590075Sobrien  "fnorm.d %0 = %1"
100690075Sobrien  [(set_attr "itanium_class" "fmac")])
100790075Sobrien
100890075Sobrien(define_insn "extendsftf2"
100990075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
101090075Sobrien	(float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))]
101190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
101290075Sobrien  "fnorm %0 = %1"
101390075Sobrien  [(set_attr "itanium_class" "fmac")])
101490075Sobrien
101590075Sobrien(define_insn "extenddftf2"
101690075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
101790075Sobrien	(float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))]
101890075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
101990075Sobrien  "fnorm %0 = %1"
102090075Sobrien  [(set_attr "itanium_class" "fmac")])
102190075Sobrien
102290075Sobrien(define_insn "truncdfsf2"
102390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
102490075Sobrien	(float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
102590075Sobrien  ""
102690075Sobrien  "fnorm.s %0 = %1"
102790075Sobrien  [(set_attr "itanium_class" "fmac")])
102890075Sobrien
102990075Sobrien(define_insn "trunctfsf2"
103090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
103190075Sobrien	(float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
103290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
103390075Sobrien  "fnorm.s %0 = %1"
103490075Sobrien  [(set_attr "itanium_class" "fmac")])
103590075Sobrien
103690075Sobrien(define_insn "trunctfdf2"
103790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
103890075Sobrien	(float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
103990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
104090075Sobrien  "fnorm.d %0 = %1"
104190075Sobrien  [(set_attr "itanium_class" "fmac")])
104290075Sobrien
104390075Sobrien;; Convert between signed integer types and floating point.
104490075Sobrien
104590075Sobrien(define_insn "floatditf2"
104690075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
104790075Sobrien	(float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
104890075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
104990075Sobrien  "fcvt.xf %0 = %1"
105090075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
105190075Sobrien
105290075Sobrien;; ??? Suboptimal.  This should be split somehow.
105390075Sobrien(define_insn "floatdidf2"
105490075Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
105590075Sobrien        (float:DF (match_operand:DI 1 "register_operand" "f")))]
105690075Sobrien  "!INTEL_EXTENDED_IEEE_FORMAT"
1057117395Skan  "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0"
105890075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
105990075Sobrien
106090075Sobrien;; ??? Suboptimal.  This should be split somehow.
106190075Sobrien(define_insn "floatdisf2"
106290075Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
106390075Sobrien        (float:SF (match_operand:DI 1 "register_operand" "f")))]
106490075Sobrien  "!INTEL_EXTENDED_IEEE_FORMAT"
1065117395Skan  "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0"
106690075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
106790075Sobrien
106890075Sobrien(define_insn "fix_truncsfdi2"
106990075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
107090075Sobrien	(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
107190075Sobrien  ""
107290075Sobrien  "fcvt.fx.trunc %0 = %1"
107390075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
107490075Sobrien
107590075Sobrien(define_insn "fix_truncdfdi2"
107690075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
107790075Sobrien	(fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
107890075Sobrien  ""
107990075Sobrien  "fcvt.fx.trunc %0 = %1"
108090075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
108190075Sobrien
108290075Sobrien(define_insn "fix_trunctfdi2"
108390075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
108490075Sobrien	(fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
108590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
108690075Sobrien  "fcvt.fx.trunc %0 = %1"
108790075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
108890075Sobrien
108990075Sobrien(define_insn "fix_trunctfdi2_alts"
109090075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
109190075Sobrien	(fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
109290075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
109390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
109490075Sobrien  "fcvt.fx.trunc.s%2 %0 = %1"
109590075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
109690075Sobrien
109790075Sobrien;; Convert between unsigned integer types and floating point.
109890075Sobrien
109990075Sobrien(define_insn "floatunsdisf2"
110090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
110190075Sobrien	(unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
110290075Sobrien  ""
110390075Sobrien  "fcvt.xuf.s %0 = %1"
110490075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
110590075Sobrien
110690075Sobrien(define_insn "floatunsdidf2"
110790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
110890075Sobrien	(unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
110990075Sobrien  ""
111090075Sobrien  "fcvt.xuf.d %0 = %1"
111190075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
111290075Sobrien
111390075Sobrien(define_insn "floatunsditf2"
111490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
111590075Sobrien	(unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
111690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
111790075Sobrien  "fcvt.xuf %0 = %1"
111890075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
111990075Sobrien
112090075Sobrien(define_insn "fixuns_truncsfdi2"
112190075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
112290075Sobrien	(unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
112390075Sobrien  ""
112490075Sobrien  "fcvt.fxu.trunc %0 = %1"
112590075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
112690075Sobrien
112790075Sobrien(define_insn "fixuns_truncdfdi2"
112890075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
112990075Sobrien	(unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
113090075Sobrien  ""
113190075Sobrien  "fcvt.fxu.trunc %0 = %1"
113290075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
113390075Sobrien
113490075Sobrien(define_insn "fixuns_trunctfdi2"
113590075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
113690075Sobrien	(unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
113790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
113890075Sobrien  "fcvt.fxu.trunc %0 = %1"
113990075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
114090075Sobrien
114190075Sobrien(define_insn "fixuns_trunctfdi2_alts"
114290075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
114390075Sobrien	(unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
114490075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
114590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
114690075Sobrien  "fcvt.fxu.trunc.s%2 %0 = %1"
114790075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
114890075Sobrien
114990075Sobrien;; ::::::::::::::::::::
115090075Sobrien;; ::
115190075Sobrien;; :: Bit field extraction
115290075Sobrien;; ::
115390075Sobrien;; ::::::::::::::::::::
115490075Sobrien
115590075Sobrien(define_insn "extv"
115690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
115790075Sobrien	(sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
115890075Sobrien			 (match_operand:DI 2 "const_int_operand" "n")
115990075Sobrien			 (match_operand:DI 3 "const_int_operand" "n")))]
116090075Sobrien  ""
116190075Sobrien  "extr %0 = %1, %3, %2"
116290075Sobrien  [(set_attr "itanium_class" "ishf")])
116390075Sobrien
116490075Sobrien(define_insn "extzv"
116590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
116690075Sobrien	(zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
116790075Sobrien			 (match_operand:DI 2 "const_int_operand" "n")
116890075Sobrien			 (match_operand:DI 3 "const_int_operand" "n")))]
116990075Sobrien  ""
117090075Sobrien  "extr.u %0 = %1, %3, %2"
117190075Sobrien  [(set_attr "itanium_class" "ishf")])
117290075Sobrien
117390075Sobrien;; Insert a bit field.
117490075Sobrien;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
117590075Sobrien;; Source1 can be 0 or -1.
117690075Sobrien;; Source2 can be 0.
117790075Sobrien
117890075Sobrien;; ??? Actual dep instruction is more powerful than what these insv
117990075Sobrien;; patterns support.  Unfortunately, combine is unable to create patterns
118090075Sobrien;; where source2 != dest.
118190075Sobrien
118290075Sobrien(define_expand "insv"
118390075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
118490075Sobrien			 (match_operand:DI 1 "const_int_operand" "")
118590075Sobrien			 (match_operand:DI 2 "const_int_operand" ""))
118690075Sobrien	(match_operand:DI 3 "nonmemory_operand" ""))]
118790075Sobrien  ""
118890075Sobrien{
118990075Sobrien  int width = INTVAL (operands[1]);
119090075Sobrien  int shift = INTVAL (operands[2]);
119190075Sobrien
119290075Sobrien  /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
119390075Sobrien     pseudo.  */
119490075Sobrien  if (! register_operand (operands[3], DImode)
119590075Sobrien      && operands[3] != const0_rtx && operands[3] != constm1_rtx)
119690075Sobrien    operands[3] = force_reg (DImode, operands[3]);
119790075Sobrien
119890075Sobrien  /* If this is a single dep instruction, we have nothing to do.  */
119990075Sobrien  if (! ((register_operand (operands[3], DImode) && width <= 16)
120090075Sobrien	 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
120190075Sobrien    {
120290075Sobrien      /* Check for cases that can be implemented with a mix instruction.  */
120390075Sobrien      if (width == 32 && shift == 0)
120490075Sobrien	{
120590075Sobrien	  /* Directly generating the mix4left instruction confuses
120690075Sobrien	     optimize_bit_field in function.c.  Since this is performing
120790075Sobrien	     a useful optimization, we defer generation of the complicated
120890075Sobrien	     mix4left RTL to the first splitting phase.  */
120990075Sobrien	  rtx tmp = gen_reg_rtx (DImode);
121090075Sobrien	  emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
121190075Sobrien	  DONE;
121290075Sobrien	}
121390075Sobrien      else if (width == 32 && shift == 32)
121490075Sobrien	{
121590075Sobrien	  emit_insn (gen_mix4right (operands[0], operands[3]));
121690075Sobrien	  DONE;
121790075Sobrien	}
121890075Sobrien
121990075Sobrien      /* We could handle remaining cases by emitting multiple dep
122090075Sobrien	 instructions.
122190075Sobrien
122290075Sobrien	 If we need more than two dep instructions then we lose.  A 6
122390075Sobrien	 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
122490075Sobrien	 mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,
122590075Sobrien	 the latter is 6 cycles on an Itanium (TM) processor, because there is
122690075Sobrien	 only one function unit that can execute dep and shr immed.
122790075Sobrien
122890075Sobrien	 If we only need two dep instruction, then we still lose.
122990075Sobrien	 mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away
123090075Sobrien	 the unnecessary mov, this is still undesirable because it will be
123190075Sobrien	 hard to optimize, and it creates unnecessary pressure on the I0
123290075Sobrien	 function unit.  */
123390075Sobrien
123490075Sobrien      FAIL;
123590075Sobrien
123690075Sobrien#if 0
123790075Sobrien      /* This code may be useful for other IA-64 processors, so we leave it in
123890075Sobrien	 for now.  */
123990075Sobrien      while (width > 16)
124090075Sobrien	{
124190075Sobrien	  rtx tmp;
124290075Sobrien
124390075Sobrien	  emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
124490075Sobrien			       operands[3]));
124590075Sobrien	  shift += 16;
124690075Sobrien	  width -= 16;
124790075Sobrien	  tmp = gen_reg_rtx (DImode);
124890075Sobrien	  emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
124990075Sobrien	  operands[3] = tmp;
125090075Sobrien	}
125190075Sobrien      operands[1] = GEN_INT (width);
125290075Sobrien      operands[2] = GEN_INT (shift);
125390075Sobrien#endif
125490075Sobrien    }
1255117395Skan})
125690075Sobrien
125790075Sobrien(define_insn "*insv_internal"
125890075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
125990075Sobrien			 (match_operand:DI 1 "const_int_operand" "n")
126090075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
126190075Sobrien	(match_operand:DI 3 "nonmemory_operand" "rP"))]
126290075Sobrien  "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
126390075Sobrien   || operands[3] == const0_rtx || operands[3] == constm1_rtx"
126490075Sobrien  "dep %0 = %3, %0, %2, %1"
126590075Sobrien  [(set_attr "itanium_class" "ishf")])
126690075Sobrien
1267117395Skan;; Combine doesn't like to create bit-field insertions into zero.
126890075Sobrien(define_insn "*depz_internal"
126990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
127090075Sobrien	(and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
127190075Sobrien			   (match_operand:DI 2 "const_int_operand" "n"))
127290075Sobrien		(match_operand:DI 3 "const_int_operand" "n")))]
127390075Sobrien  "CONST_OK_FOR_M (INTVAL (operands[2]))
127490075Sobrien   && ia64_depz_field_mask (operands[3], operands[2]) > 0"
127590075Sobrien{
127690075Sobrien  operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1277117395Skan  return "%,dep.z %0 = %1, %2, %3";
1278117395Skan}
127990075Sobrien  [(set_attr "itanium_class" "ishf")])
128090075Sobrien
128190075Sobrien(define_insn "shift_mix4left"
128290075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
128390075Sobrien			 (const_int 32) (const_int 0))
128490075Sobrien	(match_operand:DI 1 "gr_register_operand" "r"))
128590075Sobrien   (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
128690075Sobrien  ""
128790075Sobrien  "#"
128890075Sobrien  [(set_attr "itanium_class" "unknown")])
128990075Sobrien
129090075Sobrien(define_split
129190075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
129290075Sobrien			 (const_int 32) (const_int 0))
129390075Sobrien	(match_operand:DI 1 "register_operand" ""))
129490075Sobrien   (clobber (match_operand:DI 2 "register_operand" ""))]
129590075Sobrien  "reload_completed"
129690075Sobrien  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
129790075Sobrien   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
129890075Sobrien	(lshiftrt:DI (match_dup 3) (const_int 32)))]
129990075Sobrien  "operands[3] = operands[2];")
130090075Sobrien
130190075Sobrien(define_split
130290075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
130390075Sobrien			 (const_int 32) (const_int 0))
130490075Sobrien	(match_operand:DI 1 "register_operand" ""))
130590075Sobrien   (clobber (match_operand:DI 2 "register_operand" ""))]
130690075Sobrien  "! reload_completed"
130790075Sobrien  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
130890075Sobrien   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
130990075Sobrien	(lshiftrt:DI (match_dup 3) (const_int 32)))]
131090075Sobrien  "operands[3] = operands[2];")
131190075Sobrien
131290075Sobrien(define_insn "*mix4left"
131390075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
131490075Sobrien			 (const_int 32) (const_int 0))
131590075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
131690075Sobrien		     (const_int 32)))]
131790075Sobrien  ""
131890075Sobrien  "mix4.l %0 = %0, %r1"
131990075Sobrien  [(set_attr "itanium_class" "mmshf")])
132090075Sobrien
132190075Sobrien(define_insn "mix4right"
132290075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
132390075Sobrien			 (const_int 32) (const_int 32))
132490075Sobrien	(match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
132590075Sobrien  ""
132690075Sobrien  "mix4.r %0 = %r1, %0"
132790075Sobrien  [(set_attr "itanium_class" "mmshf")])
132890075Sobrien
132990075Sobrien;; This is used by the rotrsi3 pattern.
133090075Sobrien
133190075Sobrien(define_insn "*mix4right_3op"
133290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
133390075Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
133490075Sobrien		(ashift:DI (zero_extend:DI
133590075Sobrien			     (match_operand:SI 2 "gr_register_operand" "r"))
133690075Sobrien			   (const_int 32))))]
133790075Sobrien  ""
133890075Sobrien  "mix4.r %0 = %2, %1"
133990075Sobrien  [(set_attr "itanium_class" "mmshf")])
134090075Sobrien
134190075Sobrien
134290075Sobrien;; ::::::::::::::::::::
134390075Sobrien;; ::
134490075Sobrien;; :: 1 bit Integer arithmetic
134590075Sobrien;; ::
134690075Sobrien;; ::::::::::::::::::::
134790075Sobrien
134890075Sobrien(define_insn_and_split "andbi3"
134990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
135090075Sobrien	(and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
135190075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
135290075Sobrien  ""
135390075Sobrien  "@
135490075Sobrien   #
135590075Sobrien   tbit.nz.and.orcm %0, %I0 = %2, 0
135690075Sobrien   and %0 = %2, %1"
135790075Sobrien  "reload_completed
135890075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
135990075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
136090075Sobrien  [(cond_exec (eq (match_dup 2) (const_int 0))
136190075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
136290075Sobrien				(match_dup 0))))]
136390075Sobrien  ""
136490075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
136590075Sobrien
136690075Sobrien(define_insn_and_split "*andcmbi3"
136790075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
136890075Sobrien	(and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
136990075Sobrien		(match_operand:BI 2 "register_operand" "0,0,r")))]
137090075Sobrien  ""
137190075Sobrien  "@
137290075Sobrien   #
137390075Sobrien   tbit.z.and.orcm %0, %I0 = %1, 0
137490075Sobrien   andcm %0 = %2, %1"
137590075Sobrien  "reload_completed
137690075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
137790075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
137890075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
137990075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
138090075Sobrien				(match_dup 0))))]
138190075Sobrien  ""
138290075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
138390075Sobrien
138490075Sobrien(define_insn_and_split "iorbi3"
138590075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
138690075Sobrien	(ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
138790075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
138890075Sobrien  ""
138990075Sobrien  "@
139090075Sobrien   #
139190075Sobrien   tbit.nz.or.andcm %0, %I0 = %2, 0
139290075Sobrien   or %0 = %2, %1"
139390075Sobrien  "reload_completed
139490075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
139590075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
139690075Sobrien  [(cond_exec (ne (match_dup 2) (const_int 0))
139790075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
139890075Sobrien				(match_dup 0))))]
139990075Sobrien  ""
140090075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
140190075Sobrien
140290075Sobrien(define_insn_and_split "*iorcmbi3"
140390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c")
140490075Sobrien	(ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
140590075Sobrien		(match_operand:BI 2 "register_operand" "0,0")))]
140690075Sobrien  ""
140790075Sobrien  "@
140890075Sobrien   #
140990075Sobrien   tbit.z.or.andcm %0, %I0 = %1, 0"
141090075Sobrien  "reload_completed
141190075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
141290075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
141390075Sobrien  [(cond_exec (eq (match_dup 1) (const_int 0))
141490075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
141590075Sobrien				(match_dup 0))))]
141690075Sobrien  ""
141790075Sobrien  [(set_attr "itanium_class" "unknown,tbit")])
141890075Sobrien
141990075Sobrien(define_insn "one_cmplbi2"
142090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
142190075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
142290075Sobrien   (clobber (match_scratch:BI 2 "=X,X,c,X"))]
142390075Sobrien  ""
142490075Sobrien  "@
142590075Sobrien   tbit.z %0, %I0 = %1, 0
142690075Sobrien   xor %0 = 1, %1
142790075Sobrien   #
142890075Sobrien   #"
142990075Sobrien  [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
143090075Sobrien
143190075Sobrien(define_split
143290075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
143390075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
143490075Sobrien   (clobber (match_scratch:BI 2 ""))]
143590075Sobrien  "reload_completed
143690075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
143790075Sobrien   && rtx_equal_p (operands[0], operands[1])"
143890075Sobrien  [(set (match_dup 4) (match_dup 3))
143990075Sobrien   (set (match_dup 0) (const_int 1))
144090075Sobrien   (cond_exec (ne (match_dup 2) (const_int 0))
144190075Sobrien     (set (match_dup 0) (const_int 0)))
1442117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
144390075Sobrien  "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
144490075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
144590075Sobrien
144690075Sobrien(define_split
144790075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
144890075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
144990075Sobrien   (clobber (match_scratch:BI 2 ""))]
145090075Sobrien  "reload_completed
145190075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
145290075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
145390075Sobrien   && ! rtx_equal_p (operands[0], operands[1])"
145490075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
145590075Sobrien     (set (match_dup 0) (const_int 0)))
145690075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
145790075Sobrien     (set (match_dup 0) (const_int 1)))
1458117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
145990075Sobrien  "")
146090075Sobrien
146190075Sobrien(define_insn "*cmpsi_and_0"
146290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
146390075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
146490075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
146590075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
146690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
146790075Sobrien  ""
146890075Sobrien  "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
146990075Sobrien  [(set_attr "itanium_class" "icmp")])
147090075Sobrien
147190075Sobrien(define_insn "*cmpsi_and_1"
147290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
147390075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
147490075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
147590075Sobrien		   (const_int 0)])
147690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
147790075Sobrien  ""
147890075Sobrien  "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
147990075Sobrien  [(set_attr "itanium_class" "icmp")])
148090075Sobrien
148190075Sobrien(define_insn "*cmpsi_andnot_0"
148290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
148390075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
148490075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
148590075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
148690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
148790075Sobrien  ""
148890075Sobrien  "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
148990075Sobrien  [(set_attr "itanium_class" "icmp")])
149090075Sobrien
149190075Sobrien(define_insn "*cmpsi_andnot_1"
149290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
149390075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
149490075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
149590075Sobrien			   (const_int 0)]))
149690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
149790075Sobrien  ""
149890075Sobrien  "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
149990075Sobrien  [(set_attr "itanium_class" "icmp")])
150090075Sobrien
150190075Sobrien(define_insn "*cmpdi_and_0"
150290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
150390075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
150490075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
150590075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
150690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
150790075Sobrien  ""
150890075Sobrien  "cmp.%C4.and.orcm %0, %I0 = %3, %2"
150990075Sobrien  [(set_attr "itanium_class" "icmp")])
151090075Sobrien
151190075Sobrien(define_insn "*cmpdi_and_1"
151290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
151390075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
151490075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
151590075Sobrien		   (const_int 0)])
151690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
151790075Sobrien  ""
151890075Sobrien  "cmp.%C3.and.orcm %0, %I0 = r0, %2"
151990075Sobrien  [(set_attr "itanium_class" "icmp")])
152090075Sobrien
152190075Sobrien(define_insn "*cmpdi_andnot_0"
152290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
152390075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
152490075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
152590075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
152690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
152790075Sobrien  ""
152890075Sobrien  "cmp.%C4.or.andcm %I0, %0 = %3, %2"
152990075Sobrien  [(set_attr "itanium_class" "icmp")])
153090075Sobrien
153190075Sobrien(define_insn "*cmpdi_andnot_1"
153290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
153390075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
153490075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
153590075Sobrien			   (const_int 0)]))
153690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
153790075Sobrien  ""
153890075Sobrien  "cmp.%C3.or.andcm %I0, %0 = r0, %2"
153990075Sobrien  [(set_attr "itanium_class" "icmp")])
154090075Sobrien
154190075Sobrien(define_insn "*tbit_and_0"
154290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
154390075Sobrien	(and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
154490075Sobrien			       (const_int 1))
154590075Sobrien		       (const_int 0))
154690075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
154790075Sobrien  ""
154890075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, 0"
154990075Sobrien  [(set_attr "itanium_class" "tbit")])
155090075Sobrien
155190075Sobrien(define_insn "*tbit_and_1"
155290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
155390075Sobrien	(and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
155490075Sobrien			       (const_int 1))
155590075Sobrien		       (const_int 0))
155690075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
155790075Sobrien  ""
155890075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, 0"
155990075Sobrien  [(set_attr "itanium_class" "tbit")])
156090075Sobrien
156190075Sobrien(define_insn "*tbit_and_2"
156290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
156390075Sobrien	(and:BI (ne:BI (zero_extract:DI
156490075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
156590075Sobrien			 (const_int 1)
156690075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
156790075Sobrien		       (const_int 0))
156890075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
156990075Sobrien  ""
157090075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, %2"
157190075Sobrien  [(set_attr "itanium_class" "tbit")])
157290075Sobrien
157390075Sobrien(define_insn "*tbit_and_3"
157490075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
157590075Sobrien	(and:BI (eq:BI (zero_extract:DI
157690075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
157790075Sobrien			 (const_int 1)
157890075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
157990075Sobrien		       (const_int 0))
158090075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
158190075Sobrien  ""
158290075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, %2"
158390075Sobrien  [(set_attr "itanium_class" "tbit")])
158490075Sobrien
158590075Sobrien(define_insn "*cmpsi_or_0"
158690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
158790075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
158890075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
158990075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
159090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
159190075Sobrien  ""
159290075Sobrien  "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
159390075Sobrien  [(set_attr "itanium_class" "icmp")])
159490075Sobrien
159590075Sobrien(define_insn "*cmpsi_or_1"
159690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
159790075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
159890075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
159990075Sobrien		   (const_int 0)])
160090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
160190075Sobrien  ""
160290075Sobrien  "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
160390075Sobrien  [(set_attr "itanium_class" "icmp")])
160490075Sobrien
160590075Sobrien(define_insn "*cmpsi_orcm_0"
160690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
160790075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
160890075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
160990075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
161090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
161190075Sobrien  ""
161290075Sobrien  "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
161390075Sobrien  [(set_attr "itanium_class" "icmp")])
161490075Sobrien
161590075Sobrien(define_insn "*cmpsi_orcm_1"
161690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
161790075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
161890075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
161990075Sobrien			   (const_int 0)]))
162090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
162190075Sobrien  ""
162290075Sobrien  "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
162390075Sobrien  [(set_attr "itanium_class" "icmp")])
162490075Sobrien
162590075Sobrien(define_insn "*cmpdi_or_0"
162690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
162790075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
162890075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
162990075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
163090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
163190075Sobrien  ""
163290075Sobrien  "cmp.%C4.or.andcm %0, %I0 = %3, %2"
163390075Sobrien  [(set_attr "itanium_class" "icmp")])
163490075Sobrien
163590075Sobrien(define_insn "*cmpdi_or_1"
163690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
163790075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
163890075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
163990075Sobrien		   (const_int 0)])
164090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
164190075Sobrien  ""
164290075Sobrien  "cmp.%C3.or.andcm %0, %I0 = r0, %2"
164390075Sobrien  [(set_attr "itanium_class" "icmp")])
164490075Sobrien
164590075Sobrien(define_insn "*cmpdi_orcm_0"
164690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
164790075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
164890075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
164990075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
165090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
165190075Sobrien  ""
165290075Sobrien  "cmp.%C4.and.orcm %I0, %0 = %3, %2"
165390075Sobrien  [(set_attr "itanium_class" "icmp")])
165490075Sobrien
165590075Sobrien(define_insn "*cmpdi_orcm_1"
165690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
165790075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
165890075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
165990075Sobrien			   (const_int 0)]))
166090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
166190075Sobrien  ""
166290075Sobrien  "cmp.%C3.and.orcm %I0, %0 = r0, %2"
166390075Sobrien  [(set_attr "itanium_class" "icmp")])
166490075Sobrien
166590075Sobrien(define_insn "*tbit_or_0"
166690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
166790075Sobrien	(ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
166890075Sobrien			       (const_int 1))
166990075Sobrien		       (const_int 0))
167090075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
167190075Sobrien  ""
167290075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, 0"
167390075Sobrien  [(set_attr "itanium_class" "tbit")])
167490075Sobrien
167590075Sobrien(define_insn "*tbit_or_1"
167690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
167790075Sobrien	(ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
167890075Sobrien			       (const_int 1))
167990075Sobrien		       (const_int 0))
168090075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
168190075Sobrien  ""
168290075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, 0"
168390075Sobrien  [(set_attr "itanium_class" "tbit")])
168490075Sobrien
168590075Sobrien(define_insn "*tbit_or_2"
168690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
168790075Sobrien	(ior:BI (ne:BI (zero_extract:DI
168890075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
168990075Sobrien			 (const_int 1)
169090075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
169190075Sobrien		       (const_int 0))
169290075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
169390075Sobrien  ""
169490075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, %2"
169590075Sobrien  [(set_attr "itanium_class" "tbit")])
169690075Sobrien
169790075Sobrien(define_insn "*tbit_or_3"
169890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
169990075Sobrien	(ior:BI (eq:BI (zero_extract:DI
170090075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
170190075Sobrien			 (const_int 1)
170290075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
170390075Sobrien		       (const_int 0))
170490075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
170590075Sobrien  ""
170690075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, %2"
170790075Sobrien  [(set_attr "itanium_class" "tbit")])
170890075Sobrien
170990075Sobrien;; Transform test of and/or of setcc into parallel comparisons.
171090075Sobrien
171190075Sobrien(define_split
171290075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
171390075Sobrien	(ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
171490075Sobrien			      (const_int 0))
171590075Sobrien		       (match_operand:DI 3 "register_operand" ""))
171690075Sobrien	       (const_int 0)))]
171790075Sobrien  ""
171890075Sobrien  [(set (match_dup 0)
171990075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
172090075Sobrien		(match_dup 2)))]
172190075Sobrien  "")
172290075Sobrien
172390075Sobrien(define_split
172490075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
172590075Sobrien	(eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
172690075Sobrien			      (const_int 0))
172790075Sobrien		       (match_operand:DI 3 "register_operand" ""))
172890075Sobrien	       (const_int 0)))]
172990075Sobrien  ""
173090075Sobrien  [(set (match_dup 0)
173190075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
173290075Sobrien		(match_dup 2)))
173390075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
173490075Sobrien	      (clobber (scratch))])]
173590075Sobrien  "")
173690075Sobrien
173790075Sobrien(define_split
173890075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
173990075Sobrien	(ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
174090075Sobrien			      (const_int 0))
174190075Sobrien		       (match_operand:DI 3 "register_operand" ""))
174290075Sobrien	       (const_int 0)))]
174390075Sobrien  ""
174490075Sobrien  [(set (match_dup 0) 
174590075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
174690075Sobrien		(match_dup 2)))]
174790075Sobrien  "")
174890075Sobrien
174990075Sobrien(define_split
175090075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
175190075Sobrien	(eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
175290075Sobrien			      (const_int 0))
175390075Sobrien		       (match_operand:DI 3 "register_operand" ""))
175490075Sobrien	       (const_int 0)))]
175590075Sobrien  ""
175690075Sobrien  [(set (match_dup 0) 
175790075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
175890075Sobrien		(match_dup 2)))
175990075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
176090075Sobrien	      (clobber (scratch))])]
176190075Sobrien  "")
176290075Sobrien
176390075Sobrien;; ??? Incredibly hackish.  Either need four proper patterns with all
176490075Sobrien;; the alternatives, or rely on sched1 to split the insn and hope that
176590075Sobrien;; nothing bad happens to the comparisons in the meantime.
176690075Sobrien;;
176790075Sobrien;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
176890075Sobrien;; that we're doing height reduction.
176990075Sobrien;
177090075Sobrien;(define_insn_and_split ""
177190075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
177290075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
177390075Sobrien;			  [(match_operand 2 "" "")
177490075Sobrien;			   (match_operand 3 "" "")])
177590075Sobrien;			(match_operator:BI 4 "comparison_operator"
177690075Sobrien;			  [(match_operand 5 "" "")
177790075Sobrien;			   (match_operand 6 "" "")]))
177890075Sobrien;		(match_dup 0)))]
177990075Sobrien;  "flag_schedule_insns"
178090075Sobrien;  "#"
178190075Sobrien;  ""
178290075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
178390075Sobrien;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
178490075Sobrien;  "")
178590075Sobrien;
178690075Sobrien;(define_insn_and_split ""
178790075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
178890075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
178990075Sobrien;			  [(match_operand 2 "" "")
179090075Sobrien;			   (match_operand 3 "" "")])
179190075Sobrien;			(match_operator:BI 4 "comparison_operator"
179290075Sobrien;			  [(match_operand 5 "" "")
179390075Sobrien;			   (match_operand 6 "" "")]))
179490075Sobrien;		(match_dup 0)))]
179590075Sobrien;  "flag_schedule_insns"
179690075Sobrien;  "#"
179790075Sobrien;  ""
179890075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
179990075Sobrien;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
180090075Sobrien;  "")
180190075Sobrien;
180290075Sobrien;(define_split
180390075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
180490075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
180590075Sobrien;			  [(match_operand 2 "" "")
180690075Sobrien;			   (match_operand 3 "" "")])
180790075Sobrien;			(match_operand:BI 7 "register_operand" ""))
180890075Sobrien;		(and:BI (match_operator:BI 4 "comparison_operator"
180990075Sobrien;			  [(match_operand 5 "" "")
181090075Sobrien;			   (match_operand 6 "" "")])
181190075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
181290075Sobrien;  ""
181390075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
181490075Sobrien;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
181590075Sobrien;			      (match_dup 0)))]
181690075Sobrien;  "")
181790075Sobrien;
181890075Sobrien;(define_split
181990075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
182090075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
182190075Sobrien;			  [(match_operand 2 "" "")
182290075Sobrien;			   (match_operand 3 "" "")])
182390075Sobrien;			(match_operand:BI 7 "register_operand" ""))
182490075Sobrien;		(ior:BI (match_operator:BI 4 "comparison_operator"
182590075Sobrien;			  [(match_operand 5 "" "")
182690075Sobrien;			   (match_operand 6 "" "")])
182790075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
182890075Sobrien;  ""
182990075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
183090075Sobrien;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
183190075Sobrien;			      (match_dup 0)))]
183290075Sobrien;  "")
183390075Sobrien
183490075Sobrien;; Try harder to avoid predicate copies by duplicating compares.
183590075Sobrien;; Note that we'll have already split the predicate copy, which
183690075Sobrien;; is kind of a pain, but oh well.
183790075Sobrien
183890075Sobrien(define_peephole2
183990075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
184090075Sobrien	(match_operand:BI 1 "comparison_operator" ""))
184190075Sobrien   (set (match_operand:CCI 2 "register_operand" "")
184290075Sobrien	(match_operand:CCI 3 "register_operand" ""))
184390075Sobrien   (set (match_operand:CCI 4 "register_operand" "")
184490075Sobrien	(match_operand:CCI 5 "register_operand" ""))
184590075Sobrien   (set (match_operand:BI 6 "register_operand" "")
1846117395Skan	(unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
184790075Sobrien  "REGNO (operands[3]) == REGNO (operands[0])
184890075Sobrien   && REGNO (operands[4]) == REGNO (operands[0]) + 1
184990075Sobrien   && REGNO (operands[4]) == REGNO (operands[2]) + 1
185090075Sobrien   && REGNO (operands[6]) == REGNO (operands[2])"
185190075Sobrien  [(set (match_dup 0) (match_dup 1))
185290075Sobrien   (set (match_dup 6) (match_dup 7))]
185390075Sobrien  "operands[7] = copy_rtx (operands[1]);")
185490075Sobrien
185590075Sobrien;; ::::::::::::::::::::
185690075Sobrien;; ::
185790075Sobrien;; :: 16 bit Integer arithmetic
185890075Sobrien;; ::
185990075Sobrien;; ::::::::::::::::::::
186090075Sobrien
186190075Sobrien(define_insn "mulhi3"
186290075Sobrien  [(set (match_operand:HI 0 "gr_register_operand" "=r")
186390075Sobrien	(mult:HI (match_operand:HI 1 "gr_register_operand" "r")
186490075Sobrien		 (match_operand:HI 2 "gr_register_operand" "r")))]
186590075Sobrien  ""
186690075Sobrien  "pmpy2.r %0 = %1, %2"
186790075Sobrien  [(set_attr "itanium_class" "mmmul")])
186890075Sobrien
186990075Sobrien
187090075Sobrien;; ::::::::::::::::::::
187190075Sobrien;; ::
187290075Sobrien;; :: 32 bit Integer arithmetic
187390075Sobrien;; ::
187490075Sobrien;; ::::::::::::::::::::
187590075Sobrien
187690075Sobrien(define_insn "addsi3"
187790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
187890075Sobrien	(plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
187990075Sobrien		 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
188090075Sobrien  ""
188190075Sobrien  "@
1882117395Skan   add %0 = %1, %2
1883117395Skan   adds %0 = %2, %1
1884117395Skan   addl %0 = %2, %1"
188590075Sobrien  [(set_attr "itanium_class" "ialu")])
188690075Sobrien
188790075Sobrien(define_insn "*addsi3_plus1"
188890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
188990075Sobrien	(plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
189090075Sobrien			  (match_operand:SI 2 "gr_register_operand" "r"))
189190075Sobrien		 (const_int 1)))]
189290075Sobrien  ""
189390075Sobrien  "add %0 = %1, %2, 1"
189490075Sobrien  [(set_attr "itanium_class" "ialu")])
189590075Sobrien
189690075Sobrien(define_insn "*addsi3_plus1_alt"
189790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
189890075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
189990075Sobrien			  (const_int 2))
190090075Sobrien		 (const_int 1)))]
190190075Sobrien  ""
190290075Sobrien  "add %0 = %1, %1, 1"
190390075Sobrien  [(set_attr "itanium_class" "ialu")])
190490075Sobrien
190590075Sobrien(define_insn "*addsi3_shladd"
190690075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
190790075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
190890075Sobrien			  (match_operand:SI 2 "shladd_operand" "n"))
190990075Sobrien		 (match_operand:SI 3 "gr_register_operand" "r")))]
191090075Sobrien  ""
191190075Sobrien  "shladd %0 = %1, %S2, %3"
191290075Sobrien  [(set_attr "itanium_class" "ialu")])
191390075Sobrien
191490075Sobrien(define_insn "subsi3"
191590075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
191690075Sobrien	(minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
191790075Sobrien		  (match_operand:SI 2 "gr_register_operand" "r")))]
191890075Sobrien  ""
191990075Sobrien  "sub %0 = %1, %2"
192090075Sobrien  [(set_attr "itanium_class" "ialu")])
192190075Sobrien
192290075Sobrien(define_insn "*subsi3_minus1"
192390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
192490075Sobrien	(plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
192590075Sobrien		 (match_operand:SI 2 "gr_register_operand" "r")))]
192690075Sobrien  ""
192790075Sobrien  "sub %0 = %2, %1, 1"
192890075Sobrien  [(set_attr "itanium_class" "ialu")])
192990075Sobrien
193090075Sobrien;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
193190075Sobrien
193290075Sobrien(define_insn "mulsi3"
193390075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
193490075Sobrien	(mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
193590075Sobrien		 (match_operand:SI 2 "grfr_register_operand" "f")))]
193690075Sobrien  ""
193790075Sobrien  "xmpy.l %0 = %1, %2"
193890075Sobrien  [(set_attr "itanium_class" "xmpy")])
193990075Sobrien
194090075Sobrien(define_insn "maddsi4"
194190075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
194290075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
194390075Sobrien			  (match_operand:SI 2 "grfr_register_operand" "f"))
194490075Sobrien		 (match_operand:SI 3 "grfr_register_operand" "f")))]
194590075Sobrien  ""
194690075Sobrien  "xma.l %0 = %1, %2, %3"
194790075Sobrien  [(set_attr "itanium_class" "xmpy")])
194890075Sobrien
194990075Sobrien(define_insn "negsi2"
195090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
195190075Sobrien	(neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
195290075Sobrien  ""
195390075Sobrien  "sub %0 = r0, %1"
195490075Sobrien  [(set_attr "itanium_class" "ialu")])
195590075Sobrien
195690075Sobrien(define_expand "abssi2"
195790075Sobrien  [(set (match_dup 2)
195890075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
195990075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
196090075Sobrien	(if_then_else:SI (eq (match_dup 2) (const_int 0))
196190075Sobrien			 (neg:SI (match_dup 1))
196290075Sobrien			 (match_dup 1)))]
196390075Sobrien  ""
1964117395Skan  { operands[2] = gen_reg_rtx (BImode); })
196590075Sobrien
196690075Sobrien(define_expand "sminsi3"
196790075Sobrien  [(set (match_dup 3)
196890075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
196990075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
197090075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
197190075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
197290075Sobrien			 (match_dup 2) (match_dup 1)))]
197390075Sobrien  ""
1974117395Skan  { operands[3] = gen_reg_rtx (BImode); })
197590075Sobrien
197690075Sobrien(define_expand "smaxsi3"
197790075Sobrien  [(set (match_dup 3)
197890075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
197990075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
198090075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
198190075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
198290075Sobrien			 (match_dup 1) (match_dup 2)))]
198390075Sobrien  ""
1984117395Skan  { operands[3] = gen_reg_rtx (BImode); })
198590075Sobrien
198690075Sobrien(define_expand "uminsi3"
198790075Sobrien  [(set (match_dup 3)
198890075Sobrien	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
198990075Sobrien		(match_operand:SI 2 "gr_register_operand" "")))
199090075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
199190075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
199290075Sobrien			 (match_dup 2) (match_dup 1)))]
199390075Sobrien  ""
1994117395Skan  { operands[3] = gen_reg_rtx (BImode); })
199590075Sobrien
199690075Sobrien(define_expand "umaxsi3"
199790075Sobrien  [(set (match_dup 3)
199890075Sobrien	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
199990075Sobrien		(match_operand:SI 2 "gr_register_operand" "")))
200090075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
200190075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
200290075Sobrien			 (match_dup 1) (match_dup 2)))]
200390075Sobrien  ""
2004117395Skan  { operands[3] = gen_reg_rtx (BImode); })
200590075Sobrien
200690075Sobrien(define_expand "divsi3"
200790075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
200890075Sobrien	(div:SI (match_operand:SI 1 "general_operand" "")
200990075Sobrien		(match_operand:SI 2 "general_operand" "")))]
2010117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
201190075Sobrien{
201290075Sobrien  rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
2013117395Skan  REAL_VALUE_TYPE twon34_r;
201490075Sobrien
201590075Sobrien  op0_tf = gen_reg_rtx (TFmode);
201690075Sobrien  op0_di = gen_reg_rtx (DImode);
201790075Sobrien
201890075Sobrien  if (CONSTANT_P (operands[1]))
201990075Sobrien    operands[1] = force_reg (SImode, operands[1]);
202090075Sobrien  op1_tf = gen_reg_rtx (TFmode);
202190075Sobrien  expand_float (op1_tf, operands[1], 0);
202290075Sobrien
202390075Sobrien  if (CONSTANT_P (operands[2]))
202490075Sobrien    operands[2] = force_reg (SImode, operands[2]);
202590075Sobrien  op2_tf = gen_reg_rtx (TFmode);
202690075Sobrien  expand_float (op2_tf, operands[2], 0);
202790075Sobrien
202890075Sobrien  /* 2^-34 */
2029117395Skan  real_2expN (&twon34_r, -34);
2030117395Skan  twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
203190075Sobrien  twon34 = force_reg (TFmode, twon34);
203290075Sobrien
203390075Sobrien  emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
203490075Sobrien
203590075Sobrien  emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
203690075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
203790075Sobrien  DONE;
2038117395Skan})
203990075Sobrien
204090075Sobrien(define_expand "modsi3"
204190075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
204290075Sobrien	(mod:SI (match_operand:SI 1 "general_operand" "")
204390075Sobrien		(match_operand:SI 2 "general_operand" "")))]
2044117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
204590075Sobrien{
204690075Sobrien  rtx op2_neg, op1_di, div;
204790075Sobrien
204890075Sobrien  div = gen_reg_rtx (SImode);
204990075Sobrien  emit_insn (gen_divsi3 (div, operands[1], operands[2]));
205090075Sobrien
205190075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
205290075Sobrien
205390075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
205490075Sobrien     have already copied to the FP regs.  */
205590075Sobrien  op1_di = gen_reg_rtx (DImode);
205690075Sobrien  convert_move (op1_di, operands[1], 0);
205790075Sobrien
205890075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
205990075Sobrien			  gen_lowpart (SImode, op1_di)));
206090075Sobrien  DONE;
2061117395Skan})
206290075Sobrien
206390075Sobrien(define_expand "udivsi3"
206490075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
206590075Sobrien	(udiv:SI (match_operand:SI 1 "general_operand" "")
206690075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
2067117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
206890075Sobrien{
206990075Sobrien  rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
2070117395Skan  REAL_VALUE_TYPE twon34_r;
207190075Sobrien
207290075Sobrien  op0_tf = gen_reg_rtx (TFmode);
207390075Sobrien  op0_di = gen_reg_rtx (DImode);
207490075Sobrien
207590075Sobrien  if (CONSTANT_P (operands[1]))
207690075Sobrien    operands[1] = force_reg (SImode, operands[1]);
207790075Sobrien  op1_tf = gen_reg_rtx (TFmode);
207890075Sobrien  expand_float (op1_tf, operands[1], 1);
207990075Sobrien
208090075Sobrien  if (CONSTANT_P (operands[2]))
208190075Sobrien    operands[2] = force_reg (SImode, operands[2]);
208290075Sobrien  op2_tf = gen_reg_rtx (TFmode);
208390075Sobrien  expand_float (op2_tf, operands[2], 1);
208490075Sobrien
208590075Sobrien  /* 2^-34 */
2086117395Skan  real_2expN (&twon34_r, -34);
2087117395Skan  twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
208890075Sobrien  twon34 = force_reg (TFmode, twon34);
208990075Sobrien
209090075Sobrien  emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
209190075Sobrien
209290075Sobrien  emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
209390075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
209490075Sobrien  DONE;
2095117395Skan})
209690075Sobrien
209790075Sobrien(define_expand "umodsi3"
209890075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
209990075Sobrien	(umod:SI (match_operand:SI 1 "general_operand" "")
210090075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
2101117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
210290075Sobrien{
210390075Sobrien  rtx op2_neg, op1_di, div;
210490075Sobrien
210590075Sobrien  div = gen_reg_rtx (SImode);
210690075Sobrien  emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
210790075Sobrien
210890075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
210990075Sobrien
211090075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
211190075Sobrien     have already copied to the FP regs.  */
211290075Sobrien  op1_di = gen_reg_rtx (DImode);
211390075Sobrien  convert_move (op1_di, operands[1], 1);
211490075Sobrien
211590075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
211690075Sobrien			  gen_lowpart (SImode, op1_di)));
211790075Sobrien  DONE;
2118117395Skan})
211990075Sobrien
212090075Sobrien(define_insn_and_split "divsi3_internal"
212190075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
212290075Sobrien	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
212390075Sobrien			  (match_operand:TF 2 "fr_register_operand" "f"))))
212490075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
212590075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
212690075Sobrien   (clobber (match_scratch:BI 6 "=c"))
212790075Sobrien   (use (match_operand:TF 3 "fr_register_operand" "f"))]
2128117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
212990075Sobrien  "#"
213090075Sobrien  "&& reload_completed"
213190075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2132117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2133117395Skan					    UNSPEC_FR_RECIP_APPROX))
213490075Sobrien	      (use (const_int 1))])
213590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
213690075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
213790075Sobrien		(use (const_int 1))]))
213890075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
213990075Sobrien     (parallel [(set (match_dup 5)
214090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
214190075Sobrien			      (match_dup 7)))
214290075Sobrien		(use (const_int 1))]))
214390075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
214490075Sobrien     (parallel [(set (match_dup 4)
214590075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
214690075Sobrien			      (match_dup 4)))
214790075Sobrien		(use (const_int 1))]))
214890075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
214990075Sobrien     (parallel [(set (match_dup 5)
215090075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 5))
215190075Sobrien			      (match_dup 3)))
215290075Sobrien		(use (const_int 1))]))
215390075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
215490075Sobrien     (parallel [(set (match_dup 0)
215590075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
215690075Sobrien			      (match_dup 4)))
215790075Sobrien		(use (const_int 1))]))
215890075Sobrien  ] 
215990075Sobrien  "operands[7] = CONST1_RTX (TFmode);"
216090075Sobrien  [(set_attr "predicable" "no")])
216190075Sobrien
216290075Sobrien;; ::::::::::::::::::::
216390075Sobrien;; ::
216490075Sobrien;; :: 64 bit Integer arithmetic
216590075Sobrien;; ::
216690075Sobrien;; ::::::::::::::::::::
216790075Sobrien
216890075Sobrien(define_insn "adddi3"
216990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
217090075Sobrien	(plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
217190075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
217290075Sobrien  ""
217390075Sobrien  "@
2174117395Skan   add %0 = %1, %2
2175117395Skan   adds %0 = %2, %1
2176117395Skan   addl %0 = %2, %1"
217790075Sobrien  [(set_attr "itanium_class" "ialu")])
217890075Sobrien
217990075Sobrien(define_insn "*adddi3_plus1"
218090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
218190075Sobrien	(plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
218290075Sobrien			  (match_operand:DI 2 "gr_register_operand" "r"))
218390075Sobrien		 (const_int 1)))]
218490075Sobrien  ""
218590075Sobrien  "add %0 = %1, %2, 1"
218690075Sobrien  [(set_attr "itanium_class" "ialu")])
218790075Sobrien
218890075Sobrien;; This has some of the same problems as shladd.  We let the shladd
218990075Sobrien;; eliminator hack handle it, which results in the 1 being forced into
219090075Sobrien;; a register, but not more ugliness here.
219190075Sobrien(define_insn "*adddi3_plus1_alt"
219290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
219390075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
219490075Sobrien			  (const_int 2))
219590075Sobrien		 (const_int 1)))]
219690075Sobrien  ""
219790075Sobrien  "add %0 = %1, %1, 1"
219890075Sobrien  [(set_attr "itanium_class" "ialu")])
219990075Sobrien
220090075Sobrien(define_insn "subdi3"
220190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
220290075Sobrien	(minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
220390075Sobrien		  (match_operand:DI 2 "gr_register_operand" "r")))]
220490075Sobrien  ""
220590075Sobrien  "sub %0 = %1, %2"
220690075Sobrien  [(set_attr "itanium_class" "ialu")])
220790075Sobrien
220890075Sobrien(define_insn "*subdi3_minus1"
220990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
221090075Sobrien	(plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
221190075Sobrien		 (match_operand:DI 2 "gr_register_operand" "r")))]
221290075Sobrien  ""
221390075Sobrien  "sub %0 = %2, %1, 1"
221490075Sobrien  [(set_attr "itanium_class" "ialu")])
221590075Sobrien
221690075Sobrien;; ??? Use grfr instead of fr because of virtual register elimination
221790075Sobrien;; and silly test cases multiplying by the frame pointer.
221890075Sobrien(define_insn "muldi3"
221990075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
222090075Sobrien	(mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
222190075Sobrien		 (match_operand:DI 2 "grfr_register_operand" "f")))]
222290075Sobrien  ""
222390075Sobrien  "xmpy.l %0 = %1, %2"
222490075Sobrien  [(set_attr "itanium_class" "xmpy")])
222590075Sobrien
222690075Sobrien;; ??? If operand 3 is an eliminable reg, then register elimination causes the
222790075Sobrien;; same problem that we have with shladd below.  Unfortunately, this case is
222890075Sobrien;; much harder to fix because the multiply puts the result in an FP register,
222990075Sobrien;; but the add needs inputs from a general register.  We add a spurious clobber
223090075Sobrien;; here so that it will be present just in case register elimination gives us
223190075Sobrien;; the funny result.
223290075Sobrien
223390075Sobrien;; ??? Maybe validate_changes should try adding match_scratch clobbers?
223490075Sobrien
223590075Sobrien;; ??? Maybe we should change how adds are canonicalized.
223690075Sobrien
223790075Sobrien(define_insn "madddi4"
223890075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
223990075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
224090075Sobrien			  (match_operand:DI 2 "grfr_register_operand" "f"))
224190075Sobrien		 (match_operand:DI 3 "grfr_register_operand" "f")))
224290075Sobrien   (clobber (match_scratch:DI 4 "=X"))]
224390075Sobrien  ""
224490075Sobrien  "xma.l %0 = %1, %2, %3"
224590075Sobrien  [(set_attr "itanium_class" "xmpy")])
224690075Sobrien
224790075Sobrien;; This can be created by register elimination if operand3 of shladd is an
224890075Sobrien;; eliminable register or has reg_equiv_constant set.
224990075Sobrien
225090075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
225190075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
225290075Sobrien;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
225390075Sobrien;; incorrectly.
225490075Sobrien
225590075Sobrien(define_insn "*madddi4_elim"
225690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=&r")
225790075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
225890075Sobrien				   (match_operand:DI 2 "register_operand" "f"))
225990075Sobrien			  (match_operand:DI 3 "register_operand" "f"))
226090075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))
226190075Sobrien   (clobber (match_scratch:DI 5 "=f"))]
226290075Sobrien  "reload_in_progress"
226390075Sobrien  "#"
226490075Sobrien  [(set_attr "itanium_class" "unknown")])
226590075Sobrien
226690075Sobrien(define_split
226790075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
226890075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
226990075Sobrien				   (match_operand:DI 2 "register_operand" ""))
227090075Sobrien			  (match_operand:DI 3 "register_operand" ""))
227190075Sobrien		 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
227290075Sobrien   (clobber (match_scratch:DI 5 ""))]
227390075Sobrien  "reload_completed"
227490075Sobrien  [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
227590075Sobrien					  (match_dup 3)))
227690075Sobrien	      (clobber (match_dup 0))])
227790075Sobrien   (set (match_dup 0) (match_dup 5))
227890075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
227990075Sobrien  "")
228090075Sobrien
228190075Sobrien;; ??? There are highpart multiply and add instructions, but we have no way
228290075Sobrien;; to generate them.
228390075Sobrien
228490075Sobrien(define_insn "smuldi3_highpart"
228590075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
228690075Sobrien	(truncate:DI
228790075Sobrien	 (lshiftrt:TI
228890075Sobrien	  (mult:TI (sign_extend:TI
228990075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
229090075Sobrien		   (sign_extend:TI
229190075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
229290075Sobrien	  (const_int 64))))]
229390075Sobrien  ""
229490075Sobrien  "xmpy.h %0 = %1, %2"
229590075Sobrien  [(set_attr "itanium_class" "xmpy")])
229690075Sobrien
229790075Sobrien(define_insn "umuldi3_highpart"
229890075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
229990075Sobrien	(truncate:DI
230090075Sobrien	 (lshiftrt:TI
230190075Sobrien	  (mult:TI (zero_extend:TI
230290075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
230390075Sobrien		   (zero_extend:TI
230490075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
230590075Sobrien	  (const_int 64))))]
230690075Sobrien  ""
230790075Sobrien  "xmpy.hu %0 = %1, %2"
230890075Sobrien  [(set_attr "itanium_class" "xmpy")])
230990075Sobrien
231090075Sobrien(define_insn "negdi2"
231190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
231290075Sobrien	(neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
231390075Sobrien  ""
231490075Sobrien  "sub %0 = r0, %1"
231590075Sobrien  [(set_attr "itanium_class" "ialu")])
231690075Sobrien
231790075Sobrien(define_expand "absdi2"
231890075Sobrien  [(set (match_dup 2)
231990075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
232090075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
232190075Sobrien	(if_then_else:DI (eq (match_dup 2) (const_int 0))
232290075Sobrien			 (neg:DI (match_dup 1))
232390075Sobrien			 (match_dup 1)))]
232490075Sobrien  ""
2325117395Skan  { operands[2] = gen_reg_rtx (BImode); })
232690075Sobrien
232790075Sobrien(define_expand "smindi3"
232890075Sobrien  [(set (match_dup 3)
232990075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
233090075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
233190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
233290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
233390075Sobrien			 (match_dup 2) (match_dup 1)))]
233490075Sobrien  ""
2335117395Skan  { operands[3] = gen_reg_rtx (BImode); })
233690075Sobrien
233790075Sobrien(define_expand "smaxdi3"
233890075Sobrien  [(set (match_dup 3)
233990075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
234090075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
234190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
234290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
234390075Sobrien			 (match_dup 1) (match_dup 2)))]
234490075Sobrien  ""
2345117395Skan  { operands[3] = gen_reg_rtx (BImode); })
234690075Sobrien
234790075Sobrien(define_expand "umindi3"
234890075Sobrien  [(set (match_dup 3)
234990075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
235090075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
235190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
235290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
235390075Sobrien			 (match_dup 2) (match_dup 1)))]
235490075Sobrien  ""
2355117395Skan  { operands[3] = gen_reg_rtx (BImode); })
235690075Sobrien
235790075Sobrien(define_expand "umaxdi3"
235890075Sobrien  [(set (match_dup 3)
235990075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
236090075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
236190075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
236290075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
236390075Sobrien			 (match_dup 1) (match_dup 2)))]
236490075Sobrien  ""
2365117395Skan  { operands[3] = gen_reg_rtx (BImode); })
236690075Sobrien
236790075Sobrien(define_expand "ffsdi2"
236890075Sobrien  [(set (match_dup 6)
236990075Sobrien	(eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
237090075Sobrien   (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
237190075Sobrien   (set (match_dup 5) (const_int 0))
237290075Sobrien   (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2373117395Skan   (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_POPCNT))
237490075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
237590075Sobrien	(if_then_else:DI (ne (match_dup 6) (const_int 0))
237690075Sobrien			 (match_dup 5) (match_dup 4)))]
237790075Sobrien  ""
237890075Sobrien{
237990075Sobrien  operands[2] = gen_reg_rtx (DImode);
238090075Sobrien  operands[3] = gen_reg_rtx (DImode);
238190075Sobrien  operands[4] = gen_reg_rtx (DImode);
238290075Sobrien  operands[5] = gen_reg_rtx (DImode);
238390075Sobrien  operands[6] = gen_reg_rtx (BImode);
2384117395Skan})
238590075Sobrien
238690075Sobrien(define_insn "*popcnt"
238790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2388117395Skan	(unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")]
2389117395Skan		   UNSPEC_POPCNT))]
239090075Sobrien  ""
239190075Sobrien  "popcnt %0 = %1"
239290075Sobrien  [(set_attr "itanium_class" "mmmul")])
239390075Sobrien
239490075Sobrien(define_expand "divdi3"
239590075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
239690075Sobrien	(div:DI (match_operand:DI 1 "general_operand" "")
239790075Sobrien		(match_operand:DI 2 "general_operand" "")))]
2398117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
239990075Sobrien{
240090075Sobrien  rtx op1_tf, op2_tf, op0_tf;
240190075Sobrien
240290075Sobrien  op0_tf = gen_reg_rtx (TFmode);
240390075Sobrien
240490075Sobrien  if (CONSTANT_P (operands[1]))
240590075Sobrien    operands[1] = force_reg (DImode, operands[1]);
240690075Sobrien  op1_tf = gen_reg_rtx (TFmode);
240790075Sobrien  expand_float (op1_tf, operands[1], 0);
240890075Sobrien
240990075Sobrien  if (CONSTANT_P (operands[2]))
241090075Sobrien    operands[2] = force_reg (DImode, operands[2]);
241190075Sobrien  op2_tf = gen_reg_rtx (TFmode);
241290075Sobrien  expand_float (op2_tf, operands[2], 0);
241390075Sobrien
2414117395Skan  if (TARGET_INLINE_INT_DIV_LAT)
241590075Sobrien    emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
241690075Sobrien  else
241790075Sobrien    emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
241890075Sobrien
241990075Sobrien  emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
242090075Sobrien  DONE;
2421117395Skan})
242290075Sobrien
242390075Sobrien(define_expand "moddi3"
242490075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
242590075Sobrien	(mod:SI (match_operand:DI 1 "general_operand" "")
242690075Sobrien		(match_operand:DI 2 "general_operand" "")))]
2427117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
242890075Sobrien{
242990075Sobrien  rtx op2_neg, div;
243090075Sobrien
243190075Sobrien  div = gen_reg_rtx (DImode);
243290075Sobrien  emit_insn (gen_divdi3 (div, operands[1], operands[2]));
243390075Sobrien
243490075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
243590075Sobrien
243690075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
243790075Sobrien  DONE;
2438117395Skan})
243990075Sobrien
244090075Sobrien(define_expand "udivdi3"
244190075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
244290075Sobrien	(udiv:DI (match_operand:DI 1 "general_operand" "")
244390075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
2444117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
244590075Sobrien{
244690075Sobrien  rtx op1_tf, op2_tf, op0_tf;
244790075Sobrien
244890075Sobrien  op0_tf = gen_reg_rtx (TFmode);
244990075Sobrien
245090075Sobrien  if (CONSTANT_P (operands[1]))
245190075Sobrien    operands[1] = force_reg (DImode, operands[1]);
245290075Sobrien  op1_tf = gen_reg_rtx (TFmode);
245390075Sobrien  expand_float (op1_tf, operands[1], 1);
245490075Sobrien
245590075Sobrien  if (CONSTANT_P (operands[2]))
245690075Sobrien    operands[2] = force_reg (DImode, operands[2]);
245790075Sobrien  op2_tf = gen_reg_rtx (TFmode);
245890075Sobrien  expand_float (op2_tf, operands[2], 1);
245990075Sobrien
2460117395Skan  if (TARGET_INLINE_INT_DIV_LAT)
246190075Sobrien    emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
246290075Sobrien  else
246390075Sobrien    emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
246490075Sobrien
246590075Sobrien  emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
246690075Sobrien  DONE;
2467117395Skan})
246890075Sobrien
246990075Sobrien(define_expand "umoddi3"
247090075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
247190075Sobrien	(umod:DI (match_operand:DI 1 "general_operand" "")
247290075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
2473117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
247490075Sobrien{
247590075Sobrien  rtx op2_neg, div;
247690075Sobrien
247790075Sobrien  div = gen_reg_rtx (DImode);
247890075Sobrien  emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
247990075Sobrien
248090075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
248190075Sobrien
248290075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
248390075Sobrien  DONE;
2484117395Skan})
248590075Sobrien
248690075Sobrien(define_insn_and_split "divdi3_internal_lat"
248790075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
248890075Sobrien	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
248990075Sobrien			  (match_operand:TF 2 "fr_register_operand" "f"))))
249090075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
249190075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
249290075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
249390075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
2494117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_LAT"
249590075Sobrien  "#"
249690075Sobrien  "&& reload_completed"
249790075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2498117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2499117395Skan					    UNSPEC_FR_RECIP_APPROX))
250090075Sobrien	      (use (const_int 1))])
250190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
250290075Sobrien     (parallel [(set (match_dup 3)
250390075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
250490075Sobrien			      (match_dup 7)))
250590075Sobrien		(use (const_int 1))]))
250690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
250790075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
250890075Sobrien		(use (const_int 1))]))
250990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
251090075Sobrien     (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
251190075Sobrien		(use (const_int 1))]))
251290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
251390075Sobrien     (parallel [(set (match_dup 4)
251490075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 4))
251590075Sobrien			      (match_dup 4)))
251690075Sobrien		(use (const_int 1))]))
251790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
251890075Sobrien     (parallel [(set (match_dup 0)
251990075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
252090075Sobrien			      (match_dup 0)))
252190075Sobrien		(use (const_int 1))]))
252290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
252390075Sobrien     (parallel [(set (match_dup 3)
252490075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
252590075Sobrien			      (match_dup 4)))
252690075Sobrien		(use (const_int 1))]))
252790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
252890075Sobrien     (parallel [(set (match_dup 0)
252990075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 0))
253090075Sobrien			      (match_dup 0)))
253190075Sobrien		(use (const_int 1))]))
253290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
253390075Sobrien     (parallel [(set (match_dup 4)
253490075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
253590075Sobrien			      (match_dup 1)))
253690075Sobrien		(use (const_int 1))]))
253790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
253890075Sobrien     (parallel [(set (match_dup 0)
253990075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
254090075Sobrien			      (match_dup 3)))
254190075Sobrien		(use (const_int 1))]))
254290075Sobrien  ] 
254390075Sobrien  "operands[7] = CONST1_RTX (TFmode);"
254490075Sobrien  [(set_attr "predicable" "no")])
254590075Sobrien
254690075Sobrien(define_insn_and_split "divdi3_internal_thr"
254790075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
254890075Sobrien	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
254990075Sobrien			  (match_operand:TF 2 "fr_register_operand" "f"))))
255090075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
255190075Sobrien   (clobber (match_scratch:TF 4 "=f"))
255290075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
2553117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_THR"
255490075Sobrien  "#"
255590075Sobrien  "&& reload_completed"
255690075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
2557117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 
2558117395Skan					    UNSPEC_FR_RECIP_APPROX))
255990075Sobrien	      (use (const_int 1))])
256090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
256190075Sobrien     (parallel [(set (match_dup 3)
256290075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
256390075Sobrien			      (match_dup 6)))
256490075Sobrien		(use (const_int 1))]))
256590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
256690075Sobrien     (parallel [(set (match_dup 0)
256790075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
256890075Sobrien			      (match_dup 0)))
256990075Sobrien		(use (const_int 1))]))
257090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
257190075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
257290075Sobrien		(use (const_int 1))]))
257390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
257490075Sobrien     (parallel [(set (match_dup 0)
257590075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
257690075Sobrien			      (match_dup 0)))
257790075Sobrien		(use (const_int 1))]))
257890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
257990075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
258090075Sobrien		(use (const_int 1))]))
258190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
258290075Sobrien     (parallel [(set (match_dup 4)
258390075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
258490075Sobrien			      (match_dup 1)))
258590075Sobrien		(use (const_int 1))]))
258690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
258790075Sobrien     (parallel [(set (match_dup 0)
258890075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
258990075Sobrien			      (match_dup 3)))
259090075Sobrien		(use (const_int 1))]))
259190075Sobrien  ] 
259290075Sobrien  "operands[6] = CONST1_RTX (TFmode);"
259390075Sobrien  [(set_attr "predicable" "no")])
259490075Sobrien
259590075Sobrien;; ::::::::::::::::::::
259690075Sobrien;; ::
259790075Sobrien;; :: 32 bit floating point arithmetic
259890075Sobrien;; ::
259990075Sobrien;; ::::::::::::::::::::
260090075Sobrien
260190075Sobrien(define_insn "addsf3"
260290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
260390075Sobrien	(plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
260490075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
260590075Sobrien  ""
260690075Sobrien  "fadd.s %0 = %1, %F2"
260790075Sobrien  [(set_attr "itanium_class" "fmac")])
260890075Sobrien
260990075Sobrien(define_insn "subsf3"
261090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
261190075Sobrien	(minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
261290075Sobrien		  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
261390075Sobrien  ""
261490075Sobrien  "fsub.s %0 = %F1, %F2"
261590075Sobrien  [(set_attr "itanium_class" "fmac")])
261690075Sobrien
261790075Sobrien(define_insn "mulsf3"
261890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
261990075Sobrien	(mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
262090075Sobrien		 (match_operand:SF 2 "fr_register_operand" "f")))]
262190075Sobrien  ""
262290075Sobrien  "fmpy.s %0 = %1, %2"
262390075Sobrien  [(set_attr "itanium_class" "fmac")])
262490075Sobrien
262590075Sobrien(define_insn "abssf2"
262690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
262790075Sobrien	(abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
262890075Sobrien  ""
262990075Sobrien  "fabs %0 = %1"
263090075Sobrien  [(set_attr "itanium_class" "fmisc")])
263190075Sobrien
263290075Sobrien(define_insn "negsf2"
263390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
263490075Sobrien	(neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
263590075Sobrien  ""
263690075Sobrien  "fneg %0 = %1"
263790075Sobrien  [(set_attr "itanium_class" "fmisc")])
263890075Sobrien
263990075Sobrien(define_insn "*nabssf2"
264090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
264190075Sobrien	(neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
264290075Sobrien  ""
264390075Sobrien  "fnegabs %0 = %1"
264490075Sobrien  [(set_attr "itanium_class" "fmisc")])
264590075Sobrien
264690075Sobrien(define_insn "minsf3"
264790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
264890075Sobrien	(smin:SF (match_operand:SF 1 "fr_register_operand" "f")
264990075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
265090075Sobrien  ""
265190075Sobrien  "fmin %0 = %1, %F2"
265290075Sobrien  [(set_attr "itanium_class" "fmisc")])
265390075Sobrien
265490075Sobrien(define_insn "maxsf3"
265590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
265690075Sobrien	(smax:SF (match_operand:SF 1 "fr_register_operand" "f")
265790075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
265890075Sobrien  ""
265990075Sobrien  "fmax %0 = %1, %F2"
266090075Sobrien  [(set_attr "itanium_class" "fmisc")])
266190075Sobrien
266290075Sobrien(define_insn "*maddsf4"
266390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
266490075Sobrien	(plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
266590075Sobrien			  (match_operand:SF 2 "fr_register_operand" "f"))
266690075Sobrien		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
266790075Sobrien  ""
266890075Sobrien  "fma.s %0 = %1, %2, %F3"
266990075Sobrien  [(set_attr "itanium_class" "fmac")])
267090075Sobrien
267190075Sobrien(define_insn "*msubsf4"
267290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
267390075Sobrien	(minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
267490075Sobrien			   (match_operand:SF 2 "fr_register_operand" "f"))
267590075Sobrien		  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
267690075Sobrien  ""
267790075Sobrien  "fms.s %0 = %1, %2, %F3"
267890075Sobrien  [(set_attr "itanium_class" "fmac")])
267990075Sobrien
268090075Sobrien(define_insn "*nmulsf3"
268190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
268290075Sobrien	(neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
268390075Sobrien			 (match_operand:SF 2 "fr_register_operand" "f"))))]
268490075Sobrien  ""
268590075Sobrien  "fnmpy.s %0 = %1, %2"
268690075Sobrien  [(set_attr "itanium_class" "fmac")])
268790075Sobrien
268890075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
268990075Sobrien
269090075Sobrien(define_insn "*nmaddsf4"
269190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
269290075Sobrien	(plus:SF (neg:SF (mult:SF
269390075Sobrien			   (match_operand:SF 1 "fr_register_operand" "f")
269490075Sobrien			   (match_operand:SF 2 "fr_register_operand" "f")))
269590075Sobrien		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
269690075Sobrien  ""
269790075Sobrien  "fnma.s %0 = %1, %2, %F3"
269890075Sobrien  [(set_attr "itanium_class" "fmac")])
269990075Sobrien
270090075Sobrien(define_expand "divsf3"
270190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "")
270290075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "")
270390075Sobrien		(match_operand:SF 2 "fr_register_operand" "")))]
2704117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
270590075Sobrien{
270690075Sobrien  rtx insn;
2707117395Skan  if (TARGET_INLINE_FLOAT_DIV_LAT)
270890075Sobrien    insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
270990075Sobrien  else
271090075Sobrien    insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
271190075Sobrien  emit_insn (insn);
271290075Sobrien  DONE;
2713117395Skan})
271490075Sobrien
271590075Sobrien(define_insn_and_split "divsf3_internal_lat"
271690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
271790075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
271890075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
271990075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
272090075Sobrien   (clobber (match_scratch:TF 4 "=f"))
272190075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
2722117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
272390075Sobrien  "#"
272490075Sobrien  "&& reload_completed"
272590075Sobrien  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
2726117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2727117395Skan					    UNSPEC_FR_RECIP_APPROX))
272890075Sobrien	      (use (const_int 1))])
272990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
273090075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
273190075Sobrien		(use (const_int 1))]))
273290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
273390075Sobrien     (parallel [(set (match_dup 4)
273490075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
273590075Sobrien			      (match_dup 10)))
273690075Sobrien		(use (const_int 1))]))
273790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
273890075Sobrien     (parallel [(set (match_dup 3)
273990075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
274090075Sobrien			      (match_dup 3)))
274190075Sobrien		(use (const_int 1))]))
274290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
274390075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
274490075Sobrien		(use (const_int 1))]))
274590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
274690075Sobrien     (parallel [(set (match_dup 3)
274790075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
274890075Sobrien			      (match_dup 3)))
274990075Sobrien		(use (const_int 1))]))
275090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
275190075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
275290075Sobrien		(use (const_int 1))]))
275390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
275490075Sobrien     (parallel [(set (match_dup 9)
275590075Sobrien		     (float_truncate:DF
275690075Sobrien		       (plus:TF (mult:TF (match_dup 4) (match_dup 3))
275790075Sobrien			      (match_dup 3))))
275890075Sobrien		(use (const_int 1))]))
275990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
276090075Sobrien     (set (match_dup 0)
276190075Sobrien	  (float_truncate:SF (match_dup 6))))
276290075Sobrien  ] 
2763117395Skan{
2764117395Skan  operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2765117395Skan  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2766117395Skan  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2767117395Skan  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2768117395Skan  operands[10] = CONST1_RTX (TFmode);
2769117395Skan}
277090075Sobrien  [(set_attr "predicable" "no")])
277190075Sobrien
277290075Sobrien(define_insn_and_split "divsf3_internal_thr"
277390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
277490075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
277590075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
277690075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
277790075Sobrien   (clobber (match_scratch:TF 4 "=f"))
277890075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
2779117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
278090075Sobrien  "#"
278190075Sobrien  "&& reload_completed"
278290075Sobrien  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
2783117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2784117395Skan					    UNSPEC_FR_RECIP_APPROX))
278590075Sobrien	      (use (const_int 1))])
278690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
278790075Sobrien     (parallel [(set (match_dup 3)
278890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
278990075Sobrien			      (match_dup 10)))
279090075Sobrien		(use (const_int 1))]))
279190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
279290075Sobrien     (parallel [(set (match_dup 3)
279390075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 3))
279490075Sobrien			      (match_dup 3)))
279590075Sobrien		(use (const_int 1))]))
279690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
279790075Sobrien     (parallel [(set (match_dup 6)
279890075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
279990075Sobrien			      (match_dup 6)))
280090075Sobrien		(use (const_int 1))]))
280190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
280290075Sobrien     (parallel [(set (match_dup 9)
280390075Sobrien		     (float_truncate:SF
280490075Sobrien		       (mult:TF (match_dup 7) (match_dup 6))))
280590075Sobrien		(use (const_int 1))]))
280690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
280790075Sobrien     (parallel [(set (match_dup 4)
280890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3)))
280990075Sobrien			      (match_dup 7)))
281090075Sobrien		(use (const_int 1))]))
281190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
281290075Sobrien     (set (match_dup 0)
281390075Sobrien	  (float_truncate:SF
281490075Sobrien	    (plus:TF (mult:TF (match_dup 4) (match_dup 6))
281590075Sobrien			      (match_dup 3)))))
281690075Sobrien  ] 
2817117395Skan{
2818117395Skan  operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
2819117395Skan  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
2820117395Skan  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
2821117395Skan  operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
2822117395Skan  operands[10] = CONST1_RTX (TFmode);
2823117395Skan}
282490075Sobrien  [(set_attr "predicable" "no")])
282590075Sobrien
282690075Sobrien;; ::::::::::::::::::::
282790075Sobrien;; ::
282890075Sobrien;; :: 64 bit floating point arithmetic
282990075Sobrien;; ::
283090075Sobrien;; ::::::::::::::::::::
283190075Sobrien
283290075Sobrien(define_insn "adddf3"
283390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
283490075Sobrien	(plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
283590075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
283690075Sobrien  ""
283790075Sobrien  "fadd.d %0 = %1, %F2"
283890075Sobrien  [(set_attr "itanium_class" "fmac")])
283990075Sobrien
284090075Sobrien(define_insn "*adddf3_trunc"
284190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
284290075Sobrien	(float_truncate:SF
284390075Sobrien	  (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
284490075Sobrien		   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
284590075Sobrien  ""
284690075Sobrien  "fadd.s %0 = %1, %F2"
284790075Sobrien  [(set_attr "itanium_class" "fmac")])
284890075Sobrien
284990075Sobrien(define_insn "subdf3"
285090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
285190075Sobrien	(minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
285290075Sobrien		  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
285390075Sobrien  ""
285490075Sobrien  "fsub.d %0 = %F1, %F2"
285590075Sobrien  [(set_attr "itanium_class" "fmac")])
285690075Sobrien
285790075Sobrien(define_insn "*subdf3_trunc"
285890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
285990075Sobrien	(float_truncate:SF
286090075Sobrien	  (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
286190075Sobrien		    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
286290075Sobrien  ""
286390075Sobrien  "fsub.s %0 = %F1, %F2"
286490075Sobrien  [(set_attr "itanium_class" "fmac")])
286590075Sobrien
286690075Sobrien(define_insn "muldf3"
286790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
286890075Sobrien	(mult:DF (match_operand:DF 1 "fr_register_operand" "f")
286990075Sobrien		 (match_operand:DF 2 "fr_register_operand" "f")))]
287090075Sobrien  ""
287190075Sobrien  "fmpy.d %0 = %1, %2"
287290075Sobrien  [(set_attr "itanium_class" "fmac")])
287390075Sobrien
287490075Sobrien(define_insn "*muldf3_trunc"
287590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
287690075Sobrien	(float_truncate:SF
287790075Sobrien	  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
287890075Sobrien		   (match_operand:DF 2 "fr_register_operand" "f"))))]
287990075Sobrien  ""
288090075Sobrien  "fmpy.s %0 = %1, %2"
288190075Sobrien  [(set_attr "itanium_class" "fmac")])
288290075Sobrien
288390075Sobrien(define_insn "absdf2"
288490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
288590075Sobrien	(abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
288690075Sobrien  ""
288790075Sobrien  "fabs %0 = %1"
288890075Sobrien  [(set_attr "itanium_class" "fmisc")])
288990075Sobrien
289090075Sobrien(define_insn "negdf2"
289190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
289290075Sobrien	(neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
289390075Sobrien  ""
289490075Sobrien  "fneg %0 = %1"
289590075Sobrien  [(set_attr "itanium_class" "fmisc")])
289690075Sobrien
289790075Sobrien(define_insn "*nabsdf2"
289890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
289990075Sobrien	(neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
290090075Sobrien  ""
290190075Sobrien  "fnegabs %0 = %1"
290290075Sobrien  [(set_attr "itanium_class" "fmisc")])
290390075Sobrien
290490075Sobrien(define_insn "mindf3"
290590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
290690075Sobrien	(smin:DF (match_operand:DF 1 "fr_register_operand" "f")
290790075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
290890075Sobrien  ""
290990075Sobrien  "fmin %0 = %1, %F2"
291090075Sobrien  [(set_attr "itanium_class" "fmisc")])
291190075Sobrien
291290075Sobrien(define_insn "maxdf3"
291390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
291490075Sobrien	(smax:DF (match_operand:DF 1 "fr_register_operand" "f")
291590075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
291690075Sobrien  ""
291790075Sobrien  "fmax %0 = %1, %F2"
291890075Sobrien  [(set_attr "itanium_class" "fmisc")])
291990075Sobrien
292090075Sobrien(define_insn "*madddf4"
292190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
292290075Sobrien	(plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
292390075Sobrien			  (match_operand:DF 2 "fr_register_operand" "f"))
292490075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
292590075Sobrien  ""
292690075Sobrien  "fma.d %0 = %1, %2, %F3"
292790075Sobrien  [(set_attr "itanium_class" "fmac")])
292890075Sobrien
292990075Sobrien(define_insn "*madddf4_trunc"
293090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
293190075Sobrien	(float_truncate:SF
293290075Sobrien	  (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
293390075Sobrien			    (match_operand:DF 2 "fr_register_operand" "f"))
293490075Sobrien		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
293590075Sobrien  ""
293690075Sobrien  "fma.s %0 = %1, %2, %F3"
293790075Sobrien  [(set_attr "itanium_class" "fmac")])
293890075Sobrien
293990075Sobrien(define_insn "*msubdf4"
294090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
294190075Sobrien	(minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
294290075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f"))
294390075Sobrien		  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
294490075Sobrien  ""
294590075Sobrien  "fms.d %0 = %1, %2, %F3"
294690075Sobrien  [(set_attr "itanium_class" "fmac")])
294790075Sobrien
294890075Sobrien(define_insn "*msubdf4_trunc"
294990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
295090075Sobrien	(float_truncate:SF
295190075Sobrien	  (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
295290075Sobrien			     (match_operand:DF 2 "fr_register_operand" "f"))
295390075Sobrien		    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
295490075Sobrien  ""
295590075Sobrien  "fms.s %0 = %1, %2, %F3"
295690075Sobrien  [(set_attr "itanium_class" "fmac")])
295790075Sobrien
295890075Sobrien(define_insn "*nmuldf3"
295990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
296090075Sobrien	(neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
296190075Sobrien			 (match_operand:DF 2 "fr_register_operand" "f"))))]
296290075Sobrien  ""
296390075Sobrien  "fnmpy.d %0 = %1, %2"
296490075Sobrien  [(set_attr "itanium_class" "fmac")])
296590075Sobrien
296690075Sobrien(define_insn "*nmuldf3_trunc"
296790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
296890075Sobrien	(float_truncate:SF
296990075Sobrien	  (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
297090075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))))]
297190075Sobrien  ""
297290075Sobrien  "fnmpy.s %0 = %1, %2"
297390075Sobrien  [(set_attr "itanium_class" "fmac")])
297490075Sobrien
297590075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
297690075Sobrien
297790075Sobrien(define_insn "*nmadddf4"
297890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
297990075Sobrien	(plus:DF (neg:DF (mult:DF
298090075Sobrien			   (match_operand:DF 1 "fr_register_operand" "f")
298190075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))
298290075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
298390075Sobrien  ""
298490075Sobrien  "fnma.d %0 = %1, %2, %F3"
298590075Sobrien  [(set_attr "itanium_class" "fmac")])
298690075Sobrien
298790075Sobrien(define_insn "*nmadddf4_alts"
298890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
298990075Sobrien	(plus:DF (neg:DF (mult:DF
299090075Sobrien			   (match_operand:DF 1 "fr_register_operand" "f")
299190075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))
299290075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
299390075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
299490075Sobrien  ""
299590075Sobrien  "fnma.d.s%4 %0 = %1, %2, %F3"
299690075Sobrien  [(set_attr "itanium_class" "fmac")])
299790075Sobrien
299890075Sobrien(define_insn "*nmadddf4_trunc"
299990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
300090075Sobrien	(float_truncate:SF
300190075Sobrien	  (plus:DF (neg:DF (mult:DF
300290075Sobrien			     (match_operand:DF 1 "fr_register_operand" "f")
300390075Sobrien			     (match_operand:DF 2 "fr_register_operand" "f")))
300490075Sobrien		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
300590075Sobrien  ""
300690075Sobrien  "fnma.s %0 = %1, %2, %F3"
300790075Sobrien  [(set_attr "itanium_class" "fmac")])
300890075Sobrien
300990075Sobrien(define_expand "divdf3"
301090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "")
301190075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "")
301290075Sobrien		(match_operand:DF 2 "fr_register_operand" "")))]
3013117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
301490075Sobrien{
301590075Sobrien  rtx insn;
3016117395Skan  if (TARGET_INLINE_FLOAT_DIV_LAT)
301790075Sobrien    insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
301890075Sobrien  else
301990075Sobrien    insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
302090075Sobrien  emit_insn (insn);
302190075Sobrien  DONE;
3022117395Skan})
302390075Sobrien
302490075Sobrien(define_insn_and_split "divdf3_internal_lat"
302590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
302690075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
302790075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
302890075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
302990075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
303090075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
303190075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
3032117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
303390075Sobrien  "#"
303490075Sobrien  "&& reload_completed"
303590075Sobrien  [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
3036117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3037117395Skan					    UNSPEC_FR_RECIP_APPROX))
303890075Sobrien	      (use (const_int 1))])
303990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
304090075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
304190075Sobrien		(use (const_int 1))]))
304290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
304390075Sobrien     (parallel [(set (match_dup 4)
304490075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7)))
304590075Sobrien			      (match_dup 12)))
304690075Sobrien		(use (const_int 1))]))
304790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
304890075Sobrien     (parallel [(set (match_dup 3)
304990075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
305090075Sobrien			      (match_dup 3)))
305190075Sobrien		(use (const_int 1))]))
305290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
305390075Sobrien     (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4)))
305490075Sobrien		(use (const_int 1))]))
305590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
305690075Sobrien     (parallel [(set (match_dup 7)
305790075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 7))
305890075Sobrien			      (match_dup 7)))
305990075Sobrien		(use (const_int 1))]))
306090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
306190075Sobrien     (parallel [(set (match_dup 3)
306290075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 3))
306390075Sobrien			      (match_dup 3)))
306490075Sobrien		(use (const_int 1))]))
306590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
306690075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5)))
306790075Sobrien		(use (const_int 1))]))
306890075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
306990075Sobrien     (parallel [(set (match_dup 7)
307090075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 7))
307190075Sobrien			      (match_dup 7)))
307290075Sobrien		(use (const_int 1))]))
307390075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
307490075Sobrien     (parallel [(set (match_dup 10)
307590075Sobrien		     (float_truncate:DF
307690075Sobrien		       (plus:TF (mult:TF (match_dup 4) (match_dup 3))
307790075Sobrien			      (match_dup 3))))
307890075Sobrien		(use (const_int 1))]))
307990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
308090075Sobrien     (parallel [(set (match_dup 7)
308190075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 7))
308290075Sobrien			      (match_dup 7)))
308390075Sobrien		(use (const_int 1))]))
308490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
308590075Sobrien     (parallel [(set (match_dup 11)
308690075Sobrien		     (float_truncate:DF
308790075Sobrien		       (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3)))
308890075Sobrien			        (match_dup 8))))
308990075Sobrien		(use (const_int 1))]))
309090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
309190075Sobrien     (set (match_dup 0)
309290075Sobrien	  (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7))
309390075Sobrien			      (match_dup 3)))))
309490075Sobrien  ] 
3095117395Skan{
3096117395Skan  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3097117395Skan  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3098117395Skan  operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3099117395Skan  operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3100117395Skan  operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3101117395Skan  operands[12] = CONST1_RTX (TFmode);
3102117395Skan}
310390075Sobrien  [(set_attr "predicable" "no")])
310490075Sobrien
310590075Sobrien(define_insn_and_split "divdf3_internal_thr"
310690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
310790075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
310890075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
310990075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
311090075Sobrien   (clobber (match_scratch:DF 4 "=f"))
311190075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
3112117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
311390075Sobrien  "#"
311490075Sobrien  "&& reload_completed"
311590075Sobrien  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
3116117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3117117395Skan					    UNSPEC_FR_RECIP_APPROX))
311890075Sobrien	      (use (const_int 1))])
311990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
312090075Sobrien     (parallel [(set (match_dup 3)
312190075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
312290075Sobrien			      (match_dup 10)))
312390075Sobrien		(use (const_int 1))]))
312490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
312590075Sobrien     (parallel [(set (match_dup 6)
312690075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
312790075Sobrien			      (match_dup 6)))
312890075Sobrien		(use (const_int 1))]))
312990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
313090075Sobrien     (parallel [(set (match_dup 3)
313190075Sobrien		     (mult:TF (match_dup 3) (match_dup 3)))
313290075Sobrien		(use (const_int 1))]))
313390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
313490075Sobrien     (parallel [(set (match_dup 6)
313590075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
313690075Sobrien			      (match_dup 6)))
313790075Sobrien		(use (const_int 1))]))
313890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
313990075Sobrien     (parallel [(set (match_dup 3)
314090075Sobrien		     (mult:TF (match_dup 3) (match_dup 3)))
314190075Sobrien		(use (const_int 1))]))
314290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
314390075Sobrien     (parallel [(set (match_dup 6)
314490075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
314590075Sobrien			      (match_dup 6)))
314690075Sobrien		(use (const_int 1))]))
314790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
314890075Sobrien     (parallel [(set (match_dup 9)
314990075Sobrien		     (float_truncate:DF
315090075Sobrien		       (mult:TF (match_dup 7) (match_dup 3))))
315190075Sobrien		(use (const_int 1))]))
315290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
315390075Sobrien     (parallel [(set (match_dup 4)
315490075Sobrien		     (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
315590075Sobrien			      (match_dup 1)))
315690075Sobrien		(use (const_int 1))]))
315790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
315890075Sobrien     (set (match_dup 0)
315990075Sobrien	  (plus:DF (mult:DF (match_dup 4) (match_dup 0))
316090075Sobrien			    (match_dup 9))))
316190075Sobrien  ] 
3162117395Skan{
3163117395Skan  operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
3164117395Skan  operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
3165117395Skan  operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
3166117395Skan  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3167117395Skan  operands[10] = CONST1_RTX (TFmode);
3168117395Skan}
316990075Sobrien  [(set_attr "predicable" "no")])
317090075Sobrien
317190075Sobrien;; ::::::::::::::::::::
317290075Sobrien;; ::
317390075Sobrien;; :: 80 bit floating point arithmetic
317490075Sobrien;; ::
317590075Sobrien;; ::::::::::::::::::::
317690075Sobrien
317790075Sobrien(define_insn "addtf3"
317890075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
317990075Sobrien	(plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
318090075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
318190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
318290075Sobrien  "fadd %0 = %F1, %F2"
318390075Sobrien  [(set_attr "itanium_class" "fmac")])
318490075Sobrien
318590075Sobrien(define_insn "*addtf3_truncsf"
318690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
318790075Sobrien	(float_truncate:SF
318890075Sobrien	  (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
318990075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
319090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
319190075Sobrien  "fadd.s %0 = %F1, %F2"
319290075Sobrien  [(set_attr "itanium_class" "fmac")])
319390075Sobrien
319490075Sobrien(define_insn "*addtf3_truncdf"
319590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
319690075Sobrien	(float_truncate:DF
319790075Sobrien	  (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
319890075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
319990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
320090075Sobrien  "fadd.d %0 = %F1, %F2"
320190075Sobrien  [(set_attr "itanium_class" "fmac")])
320290075Sobrien
320390075Sobrien(define_insn "subtf3"
320490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
320590075Sobrien	(minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
320690075Sobrien		  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
320790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
320890075Sobrien  "fsub %0 = %F1, %F2"
320990075Sobrien  [(set_attr "itanium_class" "fmac")])
321090075Sobrien
321190075Sobrien(define_insn "*subtf3_truncsf"
321290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
321390075Sobrien	(float_truncate:SF
321490075Sobrien	  (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
321590075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
321690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
321790075Sobrien  "fsub.s %0 = %F1, %F2"
321890075Sobrien  [(set_attr "itanium_class" "fmac")])
321990075Sobrien
322090075Sobrien(define_insn "*subtf3_truncdf"
322190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
322290075Sobrien	(float_truncate:DF
322390075Sobrien	  (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
322490075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
322590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
322690075Sobrien  "fsub.d %0 = %F1, %F2"
322790075Sobrien  [(set_attr "itanium_class" "fmac")])
322890075Sobrien
322990075Sobrien(define_insn "multf3"
323090075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
323190075Sobrien	(mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
323290075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
323390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
323490075Sobrien  "fmpy %0 = %F1, %F2"
323590075Sobrien  [(set_attr "itanium_class" "fmac")])
323690075Sobrien
323790075Sobrien(define_insn "*multf3_truncsf"
323890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
323990075Sobrien	(float_truncate:SF
324090075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
324190075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
324290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
324390075Sobrien  "fmpy.s %0 = %F1, %F2"
324490075Sobrien  [(set_attr "itanium_class" "fmac")])
324590075Sobrien
324690075Sobrien(define_insn "*multf3_truncdf"
324790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
324890075Sobrien	(float_truncate:DF
324990075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
325090075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
325190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
325290075Sobrien  "fmpy.d %0 = %F1, %F2"
325390075Sobrien  [(set_attr "itanium_class" "fmac")])
325490075Sobrien
325590075Sobrien(define_insn "*multf3_alts"
325690075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
325790075Sobrien	(mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
325890075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
325990075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
326090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
326190075Sobrien  "fmpy.s%3 %0 = %F1, %F2"
326290075Sobrien  [(set_attr "itanium_class" "fmac")])
326390075Sobrien
326490075Sobrien(define_insn "*multf3_truncsf_alts"
326590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
326690075Sobrien	(float_truncate:SF
326790075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
326890075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
326990075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
327090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
327190075Sobrien  "fmpy.s.s%3 %0 = %F1, %F2"
327290075Sobrien  [(set_attr "itanium_class" "fmac")])
327390075Sobrien
327490075Sobrien(define_insn "*multf3_truncdf_alts"
327590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
327690075Sobrien	(float_truncate:DF
327790075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
327890075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
327990075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
328090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
328190075Sobrien  "fmpy.d.s%3 %0 = %F1, %F2"
328290075Sobrien  [(set_attr "itanium_class" "fmac")])
328390075Sobrien
328490075Sobrien(define_insn "abstf2"
328590075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
328690075Sobrien	(abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
328790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
328890075Sobrien  "fabs %0 = %F1"
328990075Sobrien  [(set_attr "itanium_class" "fmisc")])
329090075Sobrien
329190075Sobrien(define_insn "negtf2"
329290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
329390075Sobrien	(neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
329490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
329590075Sobrien  "fneg %0 = %F1"
329690075Sobrien  [(set_attr "itanium_class" "fmisc")])
329790075Sobrien
329890075Sobrien(define_insn "*nabstf2"
329990075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
330090075Sobrien	(neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
330190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
330290075Sobrien  "fnegabs %0 = %F1"
330390075Sobrien  [(set_attr "itanium_class" "fmisc")])
330490075Sobrien
330590075Sobrien(define_insn "mintf3"
330690075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
330790075Sobrien	(smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
330890075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
330990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
331090075Sobrien  "fmin %0 = %F1, %F2"
331190075Sobrien  [(set_attr "itanium_class" "fmisc")])
331290075Sobrien
331390075Sobrien(define_insn "maxtf3"
331490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
331590075Sobrien	(smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
331690075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
331790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
331890075Sobrien  "fmax %0 = %F1, %F2"
331990075Sobrien  [(set_attr "itanium_class" "fmisc")])
332090075Sobrien
332190075Sobrien(define_insn "*maddtf4"
332290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
332390075Sobrien	(plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
332490075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
332590075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
332690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
332790075Sobrien  "fma %0 = %F1, %F2, %F3"
332890075Sobrien  [(set_attr "itanium_class" "fmac")])
332990075Sobrien
333090075Sobrien(define_insn "*maddtf4_truncsf"
333190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
333290075Sobrien	(float_truncate:SF
333390075Sobrien	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
333490075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
333590075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
333690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
333790075Sobrien  "fma.s %0 = %F1, %F2, %F3"
333890075Sobrien  [(set_attr "itanium_class" "fmac")])
333990075Sobrien
334090075Sobrien(define_insn "*maddtf4_truncdf"
334190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
334290075Sobrien	(float_truncate:DF
334390075Sobrien	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
334490075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
334590075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
334690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
334790075Sobrien  "fma.d %0 = %F1, %F2, %F3"
334890075Sobrien  [(set_attr "itanium_class" "fmac")])
334990075Sobrien
335090075Sobrien(define_insn "*maddtf4_alts"
335190075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
335290075Sobrien	(plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
335390075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
335490075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
335590075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
335690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
335790075Sobrien  "fma.s%4 %0 = %F1, %F2, %F3"
335890075Sobrien  [(set_attr "itanium_class" "fmac")])
335990075Sobrien
336090075Sobrien(define_insn "*maddtf4_alts_truncdf"
336190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
336290075Sobrien	(float_truncate:DF
336390075Sobrien	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
336490075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
336590075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
336690075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
336790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
336890075Sobrien  "fma.d.s%4 %0 = %F1, %F2, %F3"
336990075Sobrien  [(set_attr "itanium_class" "fmac")])
337090075Sobrien
337190075Sobrien(define_insn "*msubtf4"
337290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
337390075Sobrien	(minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
337490075Sobrien			   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
337590075Sobrien		  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
337690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
337790075Sobrien  "fms %0 = %F1, %F2, %F3"
337890075Sobrien  [(set_attr "itanium_class" "fmac")])
337990075Sobrien
338090075Sobrien(define_insn "*msubtf4_truncsf"
338190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
338290075Sobrien	(float_truncate:SF
338390075Sobrien	  (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
338490075Sobrien			     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
338590075Sobrien		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
338690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
338790075Sobrien  "fms.s %0 = %F1, %F2, %F3"
338890075Sobrien  [(set_attr "itanium_class" "fmac")])
338990075Sobrien
339090075Sobrien(define_insn "*msubtf4_truncdf"
339190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
339290075Sobrien	(float_truncate:DF
339390075Sobrien	  (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
339490075Sobrien			     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
339590075Sobrien		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
339690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
339790075Sobrien  "fms.d %0 = %F1, %F2, %F3"
339890075Sobrien  [(set_attr "itanium_class" "fmac")])
339990075Sobrien
340090075Sobrien(define_insn "*nmultf3"
340190075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
340290075Sobrien	(neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
340390075Sobrien			 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
340490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
340590075Sobrien  "fnmpy %0 = %F1, %F2"
340690075Sobrien  [(set_attr "itanium_class" "fmac")])
340790075Sobrien
340890075Sobrien(define_insn "*nmultf3_truncsf"
340990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
341090075Sobrien	(float_truncate:SF
341190075Sobrien	  (neg:TF (mult:TF
341290075Sobrien		    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
341390075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
341490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
341590075Sobrien  "fnmpy.s %0 = %F1, %F2"
341690075Sobrien  [(set_attr "itanium_class" "fmac")])
341790075Sobrien
341890075Sobrien(define_insn "*nmultf3_truncdf"
341990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
342090075Sobrien	(float_truncate:DF
342190075Sobrien	  (neg:TF (mult:TF
342290075Sobrien		    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
342390075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
342490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
342590075Sobrien  "fnmpy.d %0 = %F1, %F2"
342690075Sobrien  [(set_attr "itanium_class" "fmac")])
342790075Sobrien
342890075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
342990075Sobrien
343090075Sobrien(define_insn "*nmaddtf4"
343190075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
343290075Sobrien	(plus:TF (neg:TF (mult:TF
343390075Sobrien			  (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
343490075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
343590075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
343690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
343790075Sobrien  "fnma %0 = %F1, %F2, %F3"
343890075Sobrien  [(set_attr "itanium_class" "fmac")])
343990075Sobrien
344090075Sobrien(define_insn "*nmaddtf4_truncsf"
344190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
344290075Sobrien	(float_truncate:SF
344390075Sobrien	  (plus:TF (neg:TF (mult:TF
344490075Sobrien			    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
344590075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
344690075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
344790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
344890075Sobrien  "fnma.s %0 = %F1, %F2, %F3"
344990075Sobrien  [(set_attr "itanium_class" "fmac")])
345090075Sobrien
345190075Sobrien(define_insn "*nmaddtf4_truncdf"
345290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
345390075Sobrien	(float_truncate:DF
345490075Sobrien	  (plus:TF (neg:TF (mult:TF
345590075Sobrien			    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
345690075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
345790075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
345890075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
345990075Sobrien  "fnma.d %0 = %F1, %F2, %F3"
346090075Sobrien  [(set_attr "itanium_class" "fmac")])
346190075Sobrien
346290075Sobrien(define_insn "*nmaddtf4_alts"
346390075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
346490075Sobrien	(plus:TF (neg:TF (mult:TF
346590075Sobrien			  (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
346690075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
346790075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
346890075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
346990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
347090075Sobrien  "fnma.s%4 %0 = %F1, %F2, %F3"
347190075Sobrien  [(set_attr "itanium_class" "fmac")])
347290075Sobrien
347390075Sobrien(define_insn "*nmaddtf4_truncdf_alts"
347490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
347590075Sobrien	(float_truncate:DF
347690075Sobrien	  (plus:TF (neg:TF
347790075Sobrien		     (mult:TF
347890075Sobrien		       (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
347990075Sobrien		       (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
348090075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
348190075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
348290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
348390075Sobrien  "fnma.d.s%4 %0 = %F1, %F2, %F3"
348490075Sobrien  [(set_attr "itanium_class" "fmac")])
348590075Sobrien
348690075Sobrien(define_expand "divtf3"
348790075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "")
348890075Sobrien	(div:TF (match_operand:TF 1 "fr_register_operand" "")
348990075Sobrien		(match_operand:TF 2 "fr_register_operand" "")))]
3490117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
349190075Sobrien{
349290075Sobrien  rtx insn;
3493117395Skan  if (TARGET_INLINE_FLOAT_DIV_LAT)
349490075Sobrien    insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]);
349590075Sobrien  else
349690075Sobrien    insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]);
349790075Sobrien  emit_insn (insn);
349890075Sobrien  DONE;
3499117395Skan})
350090075Sobrien
350190075Sobrien(define_insn_and_split "divtf3_internal_lat"
350290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
350390075Sobrien	(div:TF (match_operand:TF 1 "fr_register_operand" "f")
350490075Sobrien		(match_operand:TF 2 "fr_register_operand" "f")))
350590075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
350690075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
350790075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
350890075Sobrien   (clobber (match_scratch:TF 6 "=&f"))
350990075Sobrien   (clobber (match_scratch:BI 7 "=c"))]
3510117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
351190075Sobrien  "#"
351290075Sobrien  "&& reload_completed"
351390075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
3514117395Skan	      (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
3515117395Skan					    UNSPEC_FR_RECIP_APPROX))
351690075Sobrien	      (use (const_int 1))])
351790075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
351890075Sobrien     (parallel [(set (match_dup 3)
351990075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
352090075Sobrien			      (match_dup 8)))
352190075Sobrien		(use (const_int 1))]))
352290075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
352390075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
352490075Sobrien		(use (const_int 1))]))
352590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
352690075Sobrien     (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
352790075Sobrien		(use (const_int 1))]))
352890075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
352990075Sobrien     (parallel [(set (match_dup 6)
353090075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 3))
353190075Sobrien			      (match_dup 3)))
353290075Sobrien		(use (const_int 1))]))
353390075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
353490075Sobrien     (parallel [(set (match_dup 3)
353590075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 5))
353690075Sobrien			      (match_dup 3)))
353790075Sobrien		(use (const_int 1))]))
353890075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
353990075Sobrien     (parallel [(set (match_dup 5)
354090075Sobrien		     (plus:TF (mult:TF (match_dup 6) (match_dup 0))
354190075Sobrien			      (match_dup 0)))
354290075Sobrien		(use (const_int 1))]))
354390075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
354490075Sobrien     (parallel [(set (match_dup 0)
354590075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 3))
354690075Sobrien			      (match_dup 0)))
354790075Sobrien		(use (const_int 1))]))
354890075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
354990075Sobrien     (parallel [(set (match_dup 4)
355090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
355190075Sobrien			      (match_dup 1)))
355290075Sobrien		(use (const_int 1))]))
355390075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
355490075Sobrien     (parallel [(set (match_dup 3)
355590075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
355690075Sobrien			      (match_dup 4)))
355790075Sobrien		(use (const_int 1))]))
355890075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
355990075Sobrien     (parallel [(set (match_dup 5)
356090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
356190075Sobrien			      (match_dup 8)))
356290075Sobrien		(use (const_int 1))]))
356390075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
356490075Sobrien     (parallel [(set (match_dup 0)
356590075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
356690075Sobrien			      (match_dup 0)))
356790075Sobrien		(use (const_int 1))]))
356890075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
356990075Sobrien     (parallel [(set (match_dup 4)
357090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
357190075Sobrien			      (match_dup 1)))
357290075Sobrien		(use (const_int 1))]))
357390075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
357490075Sobrien     (set (match_dup 0)
357590075Sobrien	  (plus:TF (mult:TF (match_dup 4) (match_dup 0))
357690075Sobrien		   (match_dup 3))))
357790075Sobrien  ] 
357890075Sobrien  "operands[8] = CONST1_RTX (TFmode);"
357990075Sobrien  [(set_attr "predicable" "no")])
358090075Sobrien
358190075Sobrien(define_insn_and_split "divtf3_internal_thr"
358290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
358390075Sobrien	(div:TF (match_operand:TF 1 "fr_register_operand" "f")
358490075Sobrien		(match_operand:TF 2 "fr_register_operand" "f")))
358590075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
358690075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
358790075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
3588117395Skan  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
358990075Sobrien  "#"
359090075Sobrien  "&& reload_completed"
359190075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
3592117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
3593117395Skan					    UNSPEC_FR_RECIP_APPROX))
359490075Sobrien	      (use (const_int 1))])
359590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
359690075Sobrien     (parallel [(set (match_dup 3)
359790075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
359890075Sobrien			      (match_dup 6)))
359990075Sobrien		(use (const_int 1))]))
360090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
360190075Sobrien     (parallel [(set (match_dup 4)
360290075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
360390075Sobrien			      (match_dup 0)))
360490075Sobrien		(use (const_int 1))]))
360590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
360690075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
360790075Sobrien		(use (const_int 1))]))
360890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
360990075Sobrien     (parallel [(set (match_dup 3)
361090075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 4))
361190075Sobrien			      (match_dup 4)))
361290075Sobrien		(use (const_int 1))]))
361390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
361490075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
361590075Sobrien		(use (const_int 1))]))
361690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
361790075Sobrien     (parallel [(set (match_dup 0)
361890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
361990075Sobrien			      (match_dup 6)))
362090075Sobrien		(use (const_int 1))]))
362190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
362290075Sobrien     (parallel [(set (match_dup 0)
362390075Sobrien		     (plus:TF (mult:TF (match_dup 0) (match_dup 3))
362490075Sobrien			      (match_dup 3)))
362590075Sobrien		(use (const_int 1))]))
362690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
362790075Sobrien     (parallel [(set (match_dup 3)
362890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
362990075Sobrien			      (match_dup 1)))
363090075Sobrien		(use (const_int 1))]))
363190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
363290075Sobrien     (parallel [(set (match_dup 3)
363390075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
363490075Sobrien			      (match_dup 4)))
363590075Sobrien		(use (const_int 1))]))
363690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
363790075Sobrien     (parallel [(set (match_dup 4)
363890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
363990075Sobrien			      (match_dup 6)))
364090075Sobrien		(use (const_int 1))]))
364190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
364290075Sobrien     (parallel [(set (match_dup 0)
364390075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
364490075Sobrien			      (match_dup 0)))
364590075Sobrien		(use (const_int 1))]))
364690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
364790075Sobrien     (parallel [(set (match_dup 4)
364890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
364990075Sobrien			      (match_dup 1)))
365090075Sobrien		(use (const_int 1))]))
365190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
365290075Sobrien     (set (match_dup 0)
365390075Sobrien	  (plus:TF (mult:TF (match_dup 4) (match_dup 0))
365490075Sobrien		   (match_dup 3))))
365590075Sobrien  ] 
365690075Sobrien  "operands[6] = CONST1_RTX (TFmode);"
365790075Sobrien  [(set_attr "predicable" "no")])
365890075Sobrien
365990075Sobrien;; ??? frcpa works like cmp.foo.unc.
366090075Sobrien
366190075Sobrien(define_insn "*recip_approx"
366290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
366390075Sobrien	(div:TF (const_int 1)
366490075Sobrien		(match_operand:TF 3 "fr_register_operand" "f")))
366590075Sobrien   (set (match_operand:BI 1 "register_operand" "=c")
366690075Sobrien	(unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
3667117395Skan		    (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
366890075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
366990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
367090075Sobrien  "frcpa.s%4 %0, %1 = %2, %3"
367190075Sobrien  [(set_attr "itanium_class" "fmisc")
367290075Sobrien   (set_attr "predicable" "no")])
367390075Sobrien
367490075Sobrien;; ::::::::::::::::::::
367590075Sobrien;; ::
367690075Sobrien;; :: 32 bit Integer Shifts and Rotates
367790075Sobrien;; ::
367890075Sobrien;; ::::::::::::::::::::
367990075Sobrien
368090075Sobrien(define_expand "ashlsi3"
368190075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
368290075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "")
368390075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
368490075Sobrien  ""
368590075Sobrien{
368690075Sobrien  if (GET_CODE (operands[2]) != CONST_INT)
368790075Sobrien    {
368890075Sobrien      /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
368990075Sobrien	 we've got to get rid of stray bits outside the SImode register.  */
369090075Sobrien      rtx subshift = gen_reg_rtx (DImode);
369190075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
369290075Sobrien      operands[2] = subshift;
369390075Sobrien    }
3694117395Skan})
369590075Sobrien
369690075Sobrien(define_insn "*ashlsi3_internal"
369790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
369890075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
369990075Sobrien		   (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
370090075Sobrien  ""
370190075Sobrien  "@
370290075Sobrien   shladd %0 = %1, %2, r0
370390075Sobrien   dep.z %0 = %1, %2, %E2
370490075Sobrien   shl %0 = %1, %2"
370590075Sobrien  [(set_attr "itanium_class" "ialu,ishf,mmshf")])
370690075Sobrien
370790075Sobrien(define_expand "ashrsi3"
370890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
370990075Sobrien	(ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
371090075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
371190075Sobrien  ""
371290075Sobrien{
371390075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
371490075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
371590075Sobrien    emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
371690075Sobrien			 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
371790075Sobrien  else
371890075Sobrien    {
371990075Sobrien      rtx subshift = gen_reg_rtx (DImode);
372090075Sobrien      emit_insn (gen_extendsidi2 (subtarget, operands[1]));
372190075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
372290075Sobrien      emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
372390075Sobrien    }
372490075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
372590075Sobrien  DONE;
3726117395Skan})
372790075Sobrien
372890075Sobrien(define_expand "lshrsi3"
372990075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
373090075Sobrien	(lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
373190075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
373290075Sobrien  ""
373390075Sobrien{
373490075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
373590075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
373690075Sobrien    emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
373790075Sobrien			  GEN_INT (32 - INTVAL (operands[2])), operands[2]));
373890075Sobrien  else
373990075Sobrien    {
374090075Sobrien      rtx subshift = gen_reg_rtx (DImode);
374190075Sobrien      emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
374290075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
374390075Sobrien      emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
374490075Sobrien    }
374590075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
374690075Sobrien  DONE;
3747117395Skan})
374890075Sobrien
374990075Sobrien;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
375090075Sobrien;; here, instead of 64 like the patterns above.  Keep the pattern together
375190075Sobrien;; until after combine; otherwise it won't get matched often.
375290075Sobrien
375390075Sobrien(define_expand "rotrsi3"
375490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
375590075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
375690075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
375790075Sobrien  ""
375890075Sobrien{
375990075Sobrien  if (GET_MODE (operands[2]) != VOIDmode)
376090075Sobrien    {
376190075Sobrien      rtx tmp = gen_reg_rtx (DImode);
376290075Sobrien      emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
376390075Sobrien      operands[2] = tmp;
376490075Sobrien    }
3765117395Skan})
376690075Sobrien
376790075Sobrien(define_insn_and_split "*rotrsi3_internal"
376890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=&r")
376990075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
377090075Sobrien		     (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
377190075Sobrien  ""
377290075Sobrien  "#"
377390075Sobrien  "reload_completed"
377490075Sobrien  [(set (match_dup 3)
377590075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
377690075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
377790075Sobrien   (set (match_dup 3)
377890075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
377990075Sobrien  "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
378090075Sobrien
378190075Sobrien(define_expand "rotlsi3"
378290075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
378390075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "")
378490075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
378590075Sobrien  ""
378690075Sobrien{
378790075Sobrien  if (! shift_32bit_count_operand (operands[2], SImode))
378890075Sobrien    {
378990075Sobrien      rtx tmp = gen_reg_rtx (SImode);
379090075Sobrien      emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
379190075Sobrien      emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
379290075Sobrien      DONE;
379390075Sobrien    }
3794117395Skan})
379590075Sobrien
379690075Sobrien(define_insn_and_split "*rotlsi3_internal"
379790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
379890075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
379990075Sobrien		   (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
380090075Sobrien  ""
380190075Sobrien  "#"
380290075Sobrien  "reload_completed"
380390075Sobrien  [(set (match_dup 3)
380490075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
380590075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
380690075Sobrien   (set (match_dup 3)
380790075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
3808117395Skan{
3809117395Skan  operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
3810117395Skan  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
3811117395Skan})
381290075Sobrien
381390075Sobrien;; ::::::::::::::::::::
381490075Sobrien;; ::
381590075Sobrien;; :: 64 bit Integer Shifts and Rotates
381690075Sobrien;; ::
381790075Sobrien;; ::::::::::::::::::::
381890075Sobrien
381990075Sobrien(define_insn "ashldi3"
382090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
382190075Sobrien	(ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
382290075Sobrien		   (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
382390075Sobrien  ""
382490075Sobrien  "@
382590075Sobrien   shladd %0 = %1, %2, r0
382690075Sobrien   shl %0 = %1, %2
382790075Sobrien   shl %0 = %1, %2"
382890075Sobrien  [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
382990075Sobrien
383090075Sobrien;; ??? Maybe combine this with the multiply and add instruction?
383190075Sobrien
383290075Sobrien(define_insn "*shladd"
383390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
383490075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
383590075Sobrien			  (match_operand:DI 2 "shladd_operand" "n"))
383690075Sobrien		 (match_operand:DI 3 "gr_register_operand" "r")))]
383790075Sobrien  ""
383890075Sobrien  "shladd %0 = %1, %S2, %3"
383990075Sobrien  [(set_attr "itanium_class" "ialu")])
384090075Sobrien
384190075Sobrien;; This can be created by register elimination if operand3 of shladd is an
384290075Sobrien;; eliminable register or has reg_equiv_constant set.
384390075Sobrien
384490075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
384590075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
384690075Sobrien;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
384790075Sobrien;; incorrectly.
384890075Sobrien
384990075Sobrien(define_insn_and_split "*shladd_elim"
385090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=&r")
385190075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
385290075Sobrien				   (match_operand:DI 2 "shladd_operand" "n"))
385390075Sobrien			  (match_operand:DI 3 "nonmemory_operand" "r"))
385490075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))]
385590075Sobrien  "reload_in_progress"
385690075Sobrien  "* abort ();"
385790075Sobrien  "reload_completed"
385890075Sobrien  [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
385990075Sobrien			       (match_dup 3)))
386090075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
386190075Sobrien  ""
386290075Sobrien  [(set_attr "itanium_class" "unknown")])
386390075Sobrien
386490075Sobrien(define_insn "ashrdi3"
386590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
386690075Sobrien	(ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
386790075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
386890075Sobrien  ""
386990075Sobrien  "@
387090075Sobrien   shr %0 = %1, %2
387190075Sobrien   shr %0 = %1, %2"
387290075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
387390075Sobrien
387490075Sobrien(define_insn "lshrdi3"
387590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
387690075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
387790075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
387890075Sobrien  ""
387990075Sobrien  "@
388090075Sobrien   shr.u %0 = %1, %2
388190075Sobrien   shr.u %0 = %1, %2"
388290075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
388390075Sobrien
388490075Sobrien;; Using a predicate that accepts only constants doesn't work, because optabs
388590075Sobrien;; will load the operand into a register and call the pattern if the predicate
388690075Sobrien;; did not accept it on the first try.  So we use nonmemory_operand and then
388790075Sobrien;; verify that we have an appropriate constant in the expander.
388890075Sobrien
388990075Sobrien(define_expand "rotrdi3"
389090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
389190075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
389290075Sobrien		     (match_operand:DI 2 "nonmemory_operand" "")))]
389390075Sobrien  ""
389490075Sobrien{
389590075Sobrien  if (! shift_count_operand (operands[2], DImode))
389690075Sobrien    FAIL;
3897117395Skan})
389890075Sobrien
389990075Sobrien(define_insn "*rotrdi3_internal"
390090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
390190075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
390290075Sobrien		     (match_operand:DI 2 "shift_count_operand" "M")))]
390390075Sobrien  ""
390490075Sobrien  "shrp %0 = %1, %1, %2"
390590075Sobrien  [(set_attr "itanium_class" "ishf")])
390690075Sobrien
390790075Sobrien(define_expand "rotldi3"
390890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
390990075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "")
391090075Sobrien		   (match_operand:DI 2 "nonmemory_operand" "")))]
391190075Sobrien  ""
391290075Sobrien{
391390075Sobrien  if (! shift_count_operand (operands[2], DImode))
391490075Sobrien    FAIL;
3915117395Skan})
391690075Sobrien
391790075Sobrien(define_insn "*rotldi3_internal"
391890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
391990075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
392090075Sobrien		   (match_operand:DI 2 "shift_count_operand" "M")))]
392190075Sobrien  ""
392290075Sobrien  "shrp %0 = %1, %1, %e2"
392390075Sobrien  [(set_attr "itanium_class" "ishf")])
392490075Sobrien
392590075Sobrien;; ::::::::::::::::::::
392690075Sobrien;; ::
392790075Sobrien;; :: 32 bit Integer Logical operations
392890075Sobrien;; ::
392990075Sobrien;; ::::::::::::::::::::
393090075Sobrien
393190075Sobrien;; We don't seem to need any other 32-bit logical operations, because gcc
393290075Sobrien;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
393390075Sobrien;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
393490075Sobrien;; This doesn't work for unary logical operations, because we don't call
393590075Sobrien;; apply_distributive_law for them.
393690075Sobrien
393790075Sobrien;; ??? Likewise, this doesn't work for andnot, which isn't handled by
393890075Sobrien;; apply_distributive_law.  We get inefficient code for
393990075Sobrien;; int sub4 (int i, int j) { return i & ~j; }
394090075Sobrien;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
394190075Sobrien;; (zero_extend (and (not A) B)) in combine.
394290075Sobrien;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
394390075Sobrien;; one_cmplsi2 pattern.
394490075Sobrien
394590075Sobrien(define_insn "one_cmplsi2"
394690075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
394790075Sobrien	(not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
394890075Sobrien  ""
394990075Sobrien  "andcm %0 = -1, %1"
395090075Sobrien  [(set_attr "itanium_class" "ilog")])
395190075Sobrien
395290075Sobrien;; ::::::::::::::::::::
395390075Sobrien;; ::
395490075Sobrien;; :: 64 bit Integer Logical operations
395590075Sobrien;; ::
395690075Sobrien;; ::::::::::::::::::::
395790075Sobrien
395890075Sobrien(define_insn "anddi3"
395990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
396090075Sobrien	(and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
396190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
396290075Sobrien  ""
396390075Sobrien  "@
396490075Sobrien   and %0 = %2, %1
396590075Sobrien   fand %0 = %2, %1"
396690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
396790075Sobrien
396890075Sobrien(define_insn "*andnot"
396990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
397090075Sobrien	(and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
397190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
397290075Sobrien  ""
397390075Sobrien  "@
397490075Sobrien   andcm %0 = %2, %1
397590075Sobrien   fandcm %0 = %2, %1"
397690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
397790075Sobrien
397890075Sobrien(define_insn "iordi3"
397990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
398090075Sobrien	(ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
398190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
398290075Sobrien  ""
398390075Sobrien  "@
398490075Sobrien   or %0 = %2, %1
398590075Sobrien   for %0 = %2, %1"
398690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
398790075Sobrien
398890075Sobrien(define_insn "xordi3"
398990075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
399090075Sobrien	(xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
399190075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
399290075Sobrien  ""
399390075Sobrien  "@
399490075Sobrien   xor %0 = %2, %1
399590075Sobrien   fxor %0 = %2, %1"
399690075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
399790075Sobrien
399890075Sobrien(define_insn "one_cmpldi2"
399990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
400090075Sobrien	(not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
400190075Sobrien  ""
400290075Sobrien  "andcm %0 = -1, %1"
400390075Sobrien  [(set_attr "itanium_class" "ilog")])
400490075Sobrien
400590075Sobrien;; ::::::::::::::::::::
400690075Sobrien;; ::
400790075Sobrien;; :: Comparisons
400890075Sobrien;; ::
400990075Sobrien;; ::::::::::::::::::::
401090075Sobrien
401190075Sobrien(define_expand "cmpbi"
401290075Sobrien  [(set (cc0)
401390075Sobrien        (compare (match_operand:BI 0 "register_operand" "")
401490075Sobrien  		 (match_operand:BI 1 "const_int_operand" "")))]
401590075Sobrien  ""
401690075Sobrien{
401790075Sobrien  ia64_compare_op0 = operands[0];
401890075Sobrien  ia64_compare_op1 = operands[1];
401990075Sobrien  DONE;
4020117395Skan})
402190075Sobrien
402290075Sobrien(define_expand "cmpsi"
402390075Sobrien  [(set (cc0)
402490075Sobrien        (compare (match_operand:SI 0 "gr_register_operand" "")
402590075Sobrien  		 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
402690075Sobrien  ""
402790075Sobrien{
402890075Sobrien  ia64_compare_op0 = operands[0];
402990075Sobrien  ia64_compare_op1 = operands[1];
403090075Sobrien  DONE;
4031117395Skan})
403290075Sobrien
403390075Sobrien(define_expand "cmpdi"
403490075Sobrien  [(set (cc0)
403590075Sobrien        (compare (match_operand:DI 0 "gr_register_operand" "")
403690075Sobrien  		 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
403790075Sobrien  ""
403890075Sobrien{
403990075Sobrien  ia64_compare_op0 = operands[0];
404090075Sobrien  ia64_compare_op1 = operands[1];
404190075Sobrien  DONE;
4042117395Skan})
404390075Sobrien
404490075Sobrien(define_expand "cmpsf"
404590075Sobrien  [(set (cc0)
404690075Sobrien        (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
404790075Sobrien  		 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
404890075Sobrien  ""
404990075Sobrien{
405090075Sobrien  ia64_compare_op0 = operands[0];
405190075Sobrien  ia64_compare_op1 = operands[1];
405290075Sobrien  DONE;
4053117395Skan})
405490075Sobrien
405590075Sobrien(define_expand "cmpdf"
405690075Sobrien  [(set (cc0)
405790075Sobrien        (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
405890075Sobrien  		 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
405990075Sobrien  ""
406090075Sobrien{
406190075Sobrien  ia64_compare_op0 = operands[0];
406290075Sobrien  ia64_compare_op1 = operands[1];
406390075Sobrien  DONE;
4064117395Skan})
406590075Sobrien
406690075Sobrien(define_expand "cmptf"
406790075Sobrien  [(set (cc0)
406890075Sobrien        (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
406990075Sobrien  		 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
407090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
407190075Sobrien{
407290075Sobrien  ia64_compare_op0 = operands[0];
407390075Sobrien  ia64_compare_op1 = operands[1];
407490075Sobrien  DONE;
4075117395Skan})
407690075Sobrien
407790075Sobrien(define_insn "*cmpsi_normal"
407890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
407990075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
408090075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
408190075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
408290075Sobrien  ""
408390075Sobrien  "cmp4.%C1 %0, %I0 = %3, %2"
408490075Sobrien  [(set_attr "itanium_class" "icmp")])
408590075Sobrien
408690075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
408790075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
408890075Sobrien
408990075Sobrien(define_insn "*cmpsi_adjusted"
409090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
409190075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
409290075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
409390075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
409490075Sobrien  ""
409590075Sobrien  "cmp4.%C1 %0, %I0 = %r3, %2"
409690075Sobrien  [(set_attr "itanium_class" "icmp")])
409790075Sobrien
409890075Sobrien(define_insn "*cmpdi_normal"
409990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
410090075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
410190075Sobrien	   [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
410290075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
410390075Sobrien  ""
410490075Sobrien  "cmp.%C1 %0, %I0 = %3, %r2"
410590075Sobrien  [(set_attr "itanium_class" "icmp")])
410690075Sobrien
410790075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
410890075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
410990075Sobrien
411090075Sobrien(define_insn "*cmpdi_adjusted"
411190075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
411290075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
411390075Sobrien	   [(match_operand:DI 2 "gr_register_operand" "r")
411490075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
411590075Sobrien  ""
411690075Sobrien  "cmp.%C1 %0, %I0 = %r3, %2"
411790075Sobrien  [(set_attr "itanium_class" "icmp")])
411890075Sobrien
411990075Sobrien(define_insn "*cmpsf_internal"
412090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
412190075Sobrien	(match_operator:BI 1 "comparison_operator"
412290075Sobrien	   [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
412390075Sobrien	    (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
412490075Sobrien  ""
412590075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
412690075Sobrien  [(set_attr "itanium_class" "fcmp")])
412790075Sobrien
412890075Sobrien(define_insn "*cmpdf_internal"
412990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
413090075Sobrien	(match_operator:BI 1 "comparison_operator"
413190075Sobrien	   [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
413290075Sobrien	    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
413390075Sobrien  ""
413490075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
413590075Sobrien  [(set_attr "itanium_class" "fcmp")])
413690075Sobrien
413790075Sobrien(define_insn "*cmptf_internal"
413890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
413990075Sobrien	(match_operator:BI 1 "comparison_operator"
414090075Sobrien		   [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
414190075Sobrien		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
414290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
414390075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
414490075Sobrien  [(set_attr "itanium_class" "fcmp")])
414590075Sobrien
414690075Sobrien;; ??? Can this pattern be generated?
414790075Sobrien
414890075Sobrien(define_insn "*bit_zero"
414990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
415090075Sobrien	(eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
415190075Sobrien				(const_int 1)
415290075Sobrien				(match_operand:DI 2 "immediate_operand" "n"))
415390075Sobrien	       (const_int 0)))]
415490075Sobrien  ""
415590075Sobrien  "tbit.z %0, %I0 = %1, %2"
415690075Sobrien  [(set_attr "itanium_class" "tbit")])
415790075Sobrien
415890075Sobrien(define_insn "*bit_one"
415990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
416090075Sobrien	(ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
416190075Sobrien				(const_int 1)
416290075Sobrien				(match_operand:DI 2 "immediate_operand" "n"))
416390075Sobrien	       (const_int 0)))]
416490075Sobrien  ""
416590075Sobrien  "tbit.nz %0, %I0 = %1, %2"
416690075Sobrien  [(set_attr "itanium_class" "tbit")])
416790075Sobrien
416890075Sobrien;; ::::::::::::::::::::
416990075Sobrien;; ::
417090075Sobrien;; :: Branches
417190075Sobrien;; ::
417290075Sobrien;; ::::::::::::::::::::
417390075Sobrien
417490075Sobrien(define_expand "beq"
417590075Sobrien  [(set (pc)
417690075Sobrien	(if_then_else (match_dup 1)
417790075Sobrien		      (label_ref (match_operand 0 "" ""))
417890075Sobrien		      (pc)))]
417990075Sobrien  ""
418090075Sobrien  "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
418190075Sobrien
418290075Sobrien(define_expand "bne"
418390075Sobrien  [(set (pc)
418490075Sobrien	(if_then_else (match_dup 1)
418590075Sobrien		      (label_ref (match_operand 0 "" ""))
418690075Sobrien		      (pc)))]
418790075Sobrien  ""
418890075Sobrien  "operands[1] = ia64_expand_compare (NE, VOIDmode);")
418990075Sobrien
419090075Sobrien(define_expand "blt"
419190075Sobrien  [(set (pc)
419290075Sobrien	(if_then_else (match_dup 1)
419390075Sobrien		      (label_ref (match_operand 0 "" ""))
419490075Sobrien		      (pc)))]
419590075Sobrien  ""
419690075Sobrien  "operands[1] = ia64_expand_compare (LT, VOIDmode);")
419790075Sobrien
419890075Sobrien(define_expand "ble"
419990075Sobrien  [(set (pc)
420090075Sobrien	(if_then_else (match_dup 1)
420190075Sobrien		      (label_ref (match_operand 0 "" ""))
420290075Sobrien		      (pc)))]
420390075Sobrien  ""
420490075Sobrien  "operands[1] = ia64_expand_compare (LE, VOIDmode);")
420590075Sobrien
420690075Sobrien(define_expand "bgt"
420790075Sobrien  [(set (pc)
420890075Sobrien	(if_then_else (match_dup 1)
420990075Sobrien		      (label_ref (match_operand 0 "" ""))
421090075Sobrien		      (pc)))]
421190075Sobrien  ""
421290075Sobrien  "operands[1] = ia64_expand_compare (GT, VOIDmode);")
421390075Sobrien
421490075Sobrien(define_expand "bge"
421590075Sobrien  [(set (pc)
421690075Sobrien	(if_then_else (match_dup 1)
421790075Sobrien		      (label_ref (match_operand 0 "" ""))
421890075Sobrien		      (pc)))]
421990075Sobrien  ""
422090075Sobrien  "operands[1] = ia64_expand_compare (GE, VOIDmode);")
422190075Sobrien
422290075Sobrien(define_expand "bltu"
422390075Sobrien  [(set (pc)
422490075Sobrien	(if_then_else (match_dup 1)
422590075Sobrien		      (label_ref (match_operand 0 "" ""))
422690075Sobrien		      (pc)))]
422790075Sobrien  ""
422890075Sobrien  "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
422990075Sobrien
423090075Sobrien(define_expand "bleu"
423190075Sobrien  [(set (pc)
423290075Sobrien	(if_then_else (match_dup 1)
423390075Sobrien		      (label_ref (match_operand 0 "" ""))
423490075Sobrien		      (pc)))]
423590075Sobrien  ""
423690075Sobrien  "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
423790075Sobrien
423890075Sobrien(define_expand "bgtu"
423990075Sobrien  [(set (pc)
424090075Sobrien	(if_then_else (match_dup 1)
424190075Sobrien		      (label_ref (match_operand 0 "" ""))
424290075Sobrien		      (pc)))]
424390075Sobrien  ""
424490075Sobrien  "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
424590075Sobrien
424690075Sobrien(define_expand "bgeu"
424790075Sobrien  [(set (pc)
424890075Sobrien	(if_then_else (match_dup 1)
424990075Sobrien		      (label_ref (match_operand 0 "" ""))
425090075Sobrien		      (pc)))]
425190075Sobrien  ""
425290075Sobrien  "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
425390075Sobrien
425490075Sobrien(define_expand "bunordered"
425590075Sobrien  [(set (pc)
425690075Sobrien	(if_then_else (match_dup 1)
425790075Sobrien		      (label_ref (match_operand 0 "" ""))
425890075Sobrien		      (pc)))]
425990075Sobrien  ""
426090075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
426190075Sobrien
426290075Sobrien(define_expand "bordered"
426390075Sobrien  [(set (pc)
426490075Sobrien	(if_then_else (match_dup 1)
426590075Sobrien		      (label_ref (match_operand 0 "" ""))
426690075Sobrien		      (pc)))]
426790075Sobrien  ""
426890075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
426990075Sobrien
427090075Sobrien(define_insn "*br_true"
427190075Sobrien  [(set (pc)
427290075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
427390075Sobrien			[(match_operand:BI 1 "register_operand" "c")
427490075Sobrien			 (const_int 0)])
427590075Sobrien		      (label_ref (match_operand 2 "" ""))
427690075Sobrien		      (pc)))]
427790075Sobrien  ""
427890075Sobrien  "(%J0) br.cond%+ %l2"
427990075Sobrien  [(set_attr "itanium_class" "br")
428090075Sobrien   (set_attr "predicable" "no")])
428190075Sobrien
428290075Sobrien(define_insn "*br_false"
428390075Sobrien  [(set (pc)
428490075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
428590075Sobrien			[(match_operand:BI 1 "register_operand" "c")
428690075Sobrien			 (const_int 0)])
428790075Sobrien		      (pc)
428890075Sobrien		      (label_ref (match_operand 2 "" ""))))]
428990075Sobrien  ""
429090075Sobrien  "(%j0) br.cond%+ %l2"
429190075Sobrien  [(set_attr "itanium_class" "br")
429290075Sobrien   (set_attr "predicable" "no")])
429390075Sobrien
429490075Sobrien;; ::::::::::::::::::::
429590075Sobrien;; ::
429690075Sobrien;; :: Counted loop operations
429790075Sobrien;; ::
429890075Sobrien;; ::::::::::::::::::::
429990075Sobrien
430090075Sobrien(define_expand "doloop_end"
430190075Sobrien  [(use (match_operand 0 "" ""))	; loop pseudo
430290075Sobrien   (use (match_operand 1 "" ""))	; iterations; zero if unknown
430390075Sobrien   (use (match_operand 2 "" ""))	; max iterations
430490075Sobrien   (use (match_operand 3 "" ""))	; loop level
430590075Sobrien   (use (match_operand 4 "" ""))]	; label
430690075Sobrien  ""
430790075Sobrien{
430890075Sobrien  /* Only use cloop on innermost loops.  */
430990075Sobrien  if (INTVAL (operands[3]) > 1)
431090075Sobrien    FAIL;
431190075Sobrien  emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
431290075Sobrien					   operands[4]));
431390075Sobrien  DONE;
4314117395Skan})
431590075Sobrien
431690075Sobrien(define_insn "doloop_end_internal"
431790075Sobrien  [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
431890075Sobrien			       (const_int 0))
431990075Sobrien		(label_ref (match_operand 1 "" ""))
432090075Sobrien		(pc)))
432190075Sobrien   (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
4322117395Skan			 (plus:DI (match_dup 0) (const_int -1))
4323117395Skan			 (match_dup 0)))]
432490075Sobrien  ""
432590075Sobrien  "br.cloop.sptk.few %l1"
432690075Sobrien  [(set_attr "itanium_class" "br")
432790075Sobrien   (set_attr "predicable" "no")])
432890075Sobrien
432990075Sobrien;; ::::::::::::::::::::
433090075Sobrien;; ::
433190075Sobrien;; :: Set flag operations
433290075Sobrien;; ::
433390075Sobrien;; ::::::::::::::::::::
433490075Sobrien
433590075Sobrien(define_expand "seq"
433690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
433790075Sobrien  ""
433890075Sobrien  "operands[1] = ia64_expand_compare (EQ, DImode);")
433990075Sobrien
434090075Sobrien(define_expand "sne"
434190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
434290075Sobrien  ""
434390075Sobrien  "operands[1] = ia64_expand_compare (NE, DImode);")
434490075Sobrien
434590075Sobrien(define_expand "slt"
434690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
434790075Sobrien  ""
434890075Sobrien  "operands[1] = ia64_expand_compare (LT, DImode);")
434990075Sobrien
435090075Sobrien(define_expand "sle"
435190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
435290075Sobrien  ""
435390075Sobrien  "operands[1] = ia64_expand_compare (LE, DImode);")
435490075Sobrien
435590075Sobrien(define_expand "sgt"
435690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
435790075Sobrien  ""
435890075Sobrien  "operands[1] = ia64_expand_compare (GT, DImode);")
435990075Sobrien
436090075Sobrien(define_expand "sge"
436190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
436290075Sobrien  ""
436390075Sobrien  "operands[1] = ia64_expand_compare (GE, DImode);")
436490075Sobrien
436590075Sobrien(define_expand "sltu"
436690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
436790075Sobrien  ""
436890075Sobrien  "operands[1] = ia64_expand_compare (LTU, DImode);")
436990075Sobrien
437090075Sobrien(define_expand "sleu"
437190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
437290075Sobrien  ""
437390075Sobrien  "operands[1] = ia64_expand_compare (LEU, DImode);")
437490075Sobrien
437590075Sobrien(define_expand "sgtu"
437690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
437790075Sobrien  ""
437890075Sobrien  "operands[1] = ia64_expand_compare (GTU, DImode);")
437990075Sobrien
438090075Sobrien(define_expand "sgeu"
438190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
438290075Sobrien  ""
438390075Sobrien  "operands[1] = ia64_expand_compare (GEU, DImode);")
438490075Sobrien
438590075Sobrien(define_expand "sunordered"
438690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
438790075Sobrien  ""
438890075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
438990075Sobrien
439090075Sobrien(define_expand "sordered"
439190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
439290075Sobrien  ""
439390075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, DImode);")
439490075Sobrien
439590075Sobrien;; Don't allow memory as destination here, because cmov/cmov/st is more
439690075Sobrien;; efficient than mov/mov/cst/cst.
439790075Sobrien
439890075Sobrien(define_insn_and_split "*sne_internal"
439990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
440090075Sobrien	(ne:DI (match_operand:BI 1 "register_operand" "c")
440190075Sobrien	       (const_int 0)))]
440290075Sobrien  ""
440390075Sobrien  "#"
440490075Sobrien  "reload_completed"
440590075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
440690075Sobrien     (set (match_dup 0) (const_int 1)))
440790075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
440890075Sobrien     (set (match_dup 0) (const_int 0)))]
440990075Sobrien  ""
441090075Sobrien  [(set_attr "itanium_class" "unknown")])
441190075Sobrien
441290075Sobrien(define_insn_and_split "*seq_internal"
441390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
441490075Sobrien	(eq:DI (match_operand:BI 1 "register_operand" "c")
441590075Sobrien	       (const_int 0)))]
441690075Sobrien  ""
441790075Sobrien  "#"
441890075Sobrien  "reload_completed"
441990075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
442090075Sobrien     (set (match_dup 0) (const_int 0)))
442190075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
442290075Sobrien     (set (match_dup 0) (const_int 1)))]
442390075Sobrien  ""
442490075Sobrien  [(set_attr "itanium_class" "unknown")])
442590075Sobrien
442690075Sobrien;; ::::::::::::::::::::
442790075Sobrien;; ::
442890075Sobrien;; :: Conditional move instructions.
442990075Sobrien;; ::
443090075Sobrien;; ::::::::::::::::::::
443190075Sobrien
443290075Sobrien;; ??? Add movXXcc patterns?
443390075Sobrien
443490075Sobrien;;
443590075Sobrien;; DImode if_then_else patterns.
443690075Sobrien;;
443790075Sobrien
443890075Sobrien(define_insn "*cmovdi_internal"
443990075Sobrien  [(set (match_operand:DI 0 "destination_operand"
444090075Sobrien	   "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
444190075Sobrien	(if_then_else:DI
444290075Sobrien	  (match_operator 4 "predicate_operator"
444390075Sobrien	    [(match_operand:BI 1 "register_operand"
444490075Sobrien		"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
444590075Sobrien	     (const_int 0)])
444690075Sobrien	  (match_operand:DI 2 "move_operand"
4447117395Skan	   "rnm, *f, *b,*d*e,rnm,rnm, rnm,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
444890075Sobrien	  (match_operand:DI 3 "move_operand"
4449117395Skan	   "rnm,rnm,rnm, rnm, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
445090075Sobrien  "ia64_move_ok (operands[0], operands[2])
445190075Sobrien   && ia64_move_ok (operands[0], operands[3])"
4452117395Skan  { abort (); }
445390075Sobrien  [(set_attr "predicable" "no")])
445490075Sobrien
445590075Sobrien(define_split
445690075Sobrien  [(set (match_operand 0 "destination_operand" "")
445790075Sobrien	(if_then_else
445890075Sobrien	  (match_operator 4 "predicate_operator"
445990075Sobrien	    [(match_operand:BI 1 "register_operand" "")
446090075Sobrien	     (const_int 0)])
446190075Sobrien	  (match_operand 2 "move_operand" "")
446290075Sobrien	  (match_operand 3 "move_operand" "")))]
446390075Sobrien  "reload_completed"
446490075Sobrien  [(const_int 0)]
446590075Sobrien{
446690075Sobrien  rtx tmp;
4467117395Skan  int emitted_something;
4468117395Skan
4469117395Skan  emitted_something = 0;
447090075Sobrien  if (! rtx_equal_p (operands[0], operands[2]))
447190075Sobrien    {
447290075Sobrien      tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
447390075Sobrien      tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
447490075Sobrien      emit_insn (tmp);
4475117395Skan      emitted_something = 1;
447690075Sobrien    }
447790075Sobrien  if (! rtx_equal_p (operands[0], operands[3]))
447890075Sobrien    {
447990075Sobrien      tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
448090075Sobrien			    VOIDmode, operands[1], const0_rtx);
448190075Sobrien      tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
448290075Sobrien			       gen_rtx_SET (VOIDmode, operands[0],
448390075Sobrien					    operands[3]));
448490075Sobrien      emit_insn (tmp);
4485117395Skan      emitted_something = 1;
448690075Sobrien    }
4487117395Skan  if (! emitted_something)
4488117395Skan    emit_note (NULL, NOTE_INSN_DELETED);
448990075Sobrien  DONE;
4490117395Skan})
449190075Sobrien
449290075Sobrien;; Absolute value pattern.
449390075Sobrien
449490075Sobrien(define_insn "*absdi2_internal"
449590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
449690075Sobrien	(if_then_else:DI
449790075Sobrien	  (match_operator 4 "predicate_operator"
449890075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
449990075Sobrien	     (const_int 0)])
450090075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
450190075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
450290075Sobrien  ""
450390075Sobrien  "#"
450490075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
450590075Sobrien   (set_attr "predicable" "no")])
450690075Sobrien
450790075Sobrien(define_split
450890075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
450990075Sobrien	(if_then_else:DI
451090075Sobrien	  (match_operator 4 "predicate_operator"
451190075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
451290075Sobrien	     (const_int 0)])
451390075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
451490075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
451590075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
451690075Sobrien  [(cond_exec
451790075Sobrien     (match_dup 4)
451890075Sobrien     (set (match_dup 0)
451990075Sobrien	  (neg:DI (match_dup 2))))]
452090075Sobrien  "")
452190075Sobrien
452290075Sobrien(define_split
452390075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
452490075Sobrien	(if_then_else:DI
452590075Sobrien	  (match_operator 4 "predicate_operator"
452690075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
452790075Sobrien	     (const_int 0)])
452890075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
452990075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
453090075Sobrien  "reload_completed"
453190075Sobrien  [(cond_exec
453290075Sobrien     (match_dup 4)
453390075Sobrien     (set (match_dup 0) (neg:DI (match_dup 2))))
453490075Sobrien   (cond_exec
453590075Sobrien     (match_dup 5)
453690075Sobrien     (set (match_dup 0) (match_dup 3)))]
453790075Sobrien{
453890075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
453990075Sobrien				VOIDmode, operands[1], const0_rtx);
4540117395Skan})
454190075Sobrien
454290075Sobrien;;
454390075Sobrien;; SImode if_then_else patterns.
454490075Sobrien;;
454590075Sobrien
454690075Sobrien(define_insn "*cmovsi_internal"
454790075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
454890075Sobrien	(if_then_else:SI
454990075Sobrien	  (match_operator 4 "predicate_operator"
455090075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
455190075Sobrien	     (const_int 0)])
455290075Sobrien	  (match_operand:SI 2 "move_operand"
4553117395Skan		    "0,0,0,rnm*f,rO,rO,rnm*f,rO,rO")
455490075Sobrien	  (match_operand:SI 3 "move_operand"
4555117395Skan		    "rnm*f,rO,rO,0,0,0,rnm*f,rO,rO")))]
455690075Sobrien  "ia64_move_ok (operands[0], operands[2])
455790075Sobrien   && ia64_move_ok (operands[0], operands[3])"
4558117395Skan  { abort (); }
455990075Sobrien  [(set_attr "predicable" "no")])
456090075Sobrien
456190075Sobrien(define_insn "*abssi2_internal"
456290075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
456390075Sobrien	(if_then_else:SI
456490075Sobrien	  (match_operator 4 "predicate_operator"
456590075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
456690075Sobrien	     (const_int 0)])
456790075Sobrien	  (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
456890075Sobrien	  (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
456990075Sobrien  ""
457090075Sobrien  "#"
457190075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
457290075Sobrien   (set_attr "predicable" "no")])
457390075Sobrien
457490075Sobrien(define_split
457590075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
457690075Sobrien	(if_then_else:SI
457790075Sobrien	  (match_operator 4 "predicate_operator"
457890075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
457990075Sobrien	     (const_int 0)])
458090075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
458190075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
458290075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
458390075Sobrien  [(cond_exec
458490075Sobrien     (match_dup 4)
458590075Sobrien     (set (match_dup 0)
458690075Sobrien	  (neg:SI (match_dup 2))))]
458790075Sobrien  "")
458890075Sobrien
458990075Sobrien(define_split
459090075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
459190075Sobrien	(if_then_else:SI
459290075Sobrien	  (match_operator 4 "predicate_operator"
459390075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
459490075Sobrien	     (const_int 0)])
459590075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
459690075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
459790075Sobrien  "reload_completed"
459890075Sobrien  [(cond_exec
459990075Sobrien     (match_dup 4)
460090075Sobrien     (set (match_dup 0) (neg:SI (match_dup 2))))
460190075Sobrien   (cond_exec
460290075Sobrien     (match_dup 5)
460390075Sobrien     (set (match_dup 0) (match_dup 3)))]
460490075Sobrien{
460590075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
460690075Sobrien				VOIDmode, operands[1], const0_rtx);
4607117395Skan})
460890075Sobrien
460990075Sobrien(define_insn_and_split "*cond_opsi2_internal"
461090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
461190075Sobrien	(match_operator:SI 5 "condop_operator"
461290075Sobrien	  [(if_then_else:SI
461390075Sobrien	     (match_operator 6 "predicate_operator"
461490075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
461590075Sobrien	        (const_int 0)])
461690075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
461790075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))
461890075Sobrien	   (match_operand:SI 4 "gr_register_operand" "r")]))]
461990075Sobrien  ""
462090075Sobrien  "#"
462190075Sobrien  "reload_completed"
462290075Sobrien  [(cond_exec
462390075Sobrien     (match_dup 6)
462490075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
462590075Sobrien   (cond_exec
462690075Sobrien     (match_dup 7)
462790075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
462890075Sobrien{
462990075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
463090075Sobrien				VOIDmode, operands[1], const0_rtx);
4631117395Skan}
463290075Sobrien  [(set_attr "itanium_class" "ialu")
463390075Sobrien   (set_attr "predicable" "no")])
463490075Sobrien
463590075Sobrien
463690075Sobrien(define_insn_and_split "*cond_opsi2_internal_b"
463790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
463890075Sobrien	(match_operator:SI 5 "condop_operator"
463990075Sobrien	  [(match_operand:SI 4 "gr_register_operand" "r")
464090075Sobrien	   (if_then_else:SI
464190075Sobrien	     (match_operator 6 "predicate_operator"
464290075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
464390075Sobrien	        (const_int 0)])
464490075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
464590075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))]))]
464690075Sobrien  ""
464790075Sobrien  "#"
464890075Sobrien  "reload_completed"
464990075Sobrien  [(cond_exec
465090075Sobrien     (match_dup 6)
465190075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
465290075Sobrien   (cond_exec
465390075Sobrien     (match_dup 7)
465490075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
465590075Sobrien{
465690075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
465790075Sobrien				VOIDmode, operands[1], const0_rtx);
4658117395Skan}
465990075Sobrien  [(set_attr "itanium_class" "ialu")
466090075Sobrien   (set_attr "predicable" "no")])
466190075Sobrien
466290075Sobrien
466390075Sobrien;; ::::::::::::::::::::
466490075Sobrien;; ::
466590075Sobrien;; :: Call and branch instructions
466690075Sobrien;; ::
466790075Sobrien;; ::::::::::::::::::::
466890075Sobrien
466990075Sobrien;; Subroutine call instruction returning no value.  Operand 0 is the function
467090075Sobrien;; to call; operand 1 is the number of bytes of arguments pushed (in mode
467190075Sobrien;; `SImode', except it is normally a `const_int'); operand 2 is the number of
467290075Sobrien;; registers used as operands.
467390075Sobrien
467490075Sobrien;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
467590075Sobrien;; is supplied for the sake of some RISC machines which need to put this
467690075Sobrien;; information into the assembler code; they can put it in the RTL instead of
467790075Sobrien;; operand 1.
467890075Sobrien
467990075Sobrien(define_expand "call"
468090075Sobrien  [(use (match_operand:DI 0 "" ""))
468190075Sobrien   (use (match_operand 1 "" ""))
468290075Sobrien   (use (match_operand 2 "" ""))
468390075Sobrien   (use (match_operand 3 "" ""))]
468490075Sobrien  ""
468590075Sobrien{
4686117395Skan  ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
468790075Sobrien  DONE;
4688117395Skan})
468990075Sobrien
469090075Sobrien(define_expand "sibcall"
469190075Sobrien  [(use (match_operand:DI 0 "" ""))
469290075Sobrien   (use (match_operand 1 "" ""))
469390075Sobrien   (use (match_operand 2 "" ""))
469490075Sobrien   (use (match_operand 3 "" ""))]
469590075Sobrien  ""
469690075Sobrien{
4697117395Skan  ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
469890075Sobrien  DONE;
4699117395Skan})
470090075Sobrien
470190075Sobrien;; Subroutine call instruction returning a value.  Operand 0 is the hard
470290075Sobrien;; register in which the value is returned.  There are three more operands,
470390075Sobrien;; the same as the three operands of the `call' instruction (but with numbers
470490075Sobrien;; increased by one).
470590075Sobrien;;
470690075Sobrien;; Subroutines that return `BLKmode' objects use the `call' insn.
470790075Sobrien
470890075Sobrien(define_expand "call_value"
470990075Sobrien  [(use (match_operand 0 "" ""))
471090075Sobrien   (use (match_operand:DI 1 "" ""))
471190075Sobrien   (use (match_operand 2 "" ""))
471290075Sobrien   (use (match_operand 3 "" ""))
471390075Sobrien   (use (match_operand 4 "" ""))]
471490075Sobrien  ""
471590075Sobrien{
4716117395Skan  ia64_expand_call (operands[0], operands[1], operands[3], false);
471790075Sobrien  DONE;
4718117395Skan})
471990075Sobrien
472090075Sobrien(define_expand "sibcall_value"
472190075Sobrien  [(use (match_operand 0 "" ""))
472290075Sobrien   (use (match_operand:DI 1 "" ""))
472390075Sobrien   (use (match_operand 2 "" ""))
472490075Sobrien   (use (match_operand 3 "" ""))
472590075Sobrien   (use (match_operand 4 "" ""))]
472690075Sobrien  ""
472790075Sobrien{
4728117395Skan  ia64_expand_call (operands[0], operands[1], operands[3], true);
472990075Sobrien  DONE;
4730117395Skan})
473190075Sobrien
473290075Sobrien;; Call subroutine returning any type.
473390075Sobrien
473490075Sobrien(define_expand "untyped_call"
473590075Sobrien  [(parallel [(call (match_operand 0 "" "")
473690075Sobrien		    (const_int 0))
473790075Sobrien	      (match_operand 1 "" "")
473890075Sobrien	      (match_operand 2 "" "")])]
473990075Sobrien  ""
474090075Sobrien{
474190075Sobrien  int i;
474290075Sobrien
474390075Sobrien  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
474490075Sobrien
474590075Sobrien  for (i = 0; i < XVECLEN (operands[2], 0); i++)
474690075Sobrien    {
474790075Sobrien      rtx set = XVECEXP (operands[2], 0, i);
474890075Sobrien      emit_move_insn (SET_DEST (set), SET_SRC (set));
474990075Sobrien    }
475090075Sobrien
475190075Sobrien  /* The optimizer does not know that the call sets the function value
475290075Sobrien     registers we stored in the result block.  We avoid problems by
475390075Sobrien     claiming that all hard registers are used and clobbered at this
475490075Sobrien     point.  */
475590075Sobrien  emit_insn (gen_blockage ());
475690075Sobrien
475790075Sobrien  DONE;
4758117395Skan})
475990075Sobrien
4760117395Skan(define_insn "call_nogp"
4761117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
4762117395Skan	 (const_int 0))
4763117395Skan   (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
476490075Sobrien  ""
4765117395Skan  "br.call%+.many %1 = %0"
476690075Sobrien  [(set_attr "itanium_class" "br,scall")])
476790075Sobrien
4768117395Skan(define_insn "call_value_nogp"
476990075Sobrien  [(set (match_operand 0 "" "")
4770117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
4771117395Skan	      (const_int 0)))
4772117395Skan   (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
477390075Sobrien  ""
4774117395Skan  "br.call%+.many %2 = %1"
477590075Sobrien  [(set_attr "itanium_class" "br,scall")])
477690075Sobrien
4777117395Skan(define_insn "sibcall_nogp"
4778117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
4779117395Skan	 (const_int 0))]
478090075Sobrien  ""
478190075Sobrien  "br%+.many %0"
478290075Sobrien  [(set_attr "itanium_class" "br,scall")])
478390075Sobrien
4784117395Skan(define_insn "call_gp"
4785117395Skan  [(call (mem (match_operand 0 "call_operand" "?r,i"))
4786117395Skan	 (const_int 1))
4787117395Skan   (clobber (match_operand:DI 1 "register_operand" "=b,b"))
4788117395Skan   (clobber (match_scratch:DI 2 "=&r,X"))
4789117395Skan   (clobber (match_scratch:DI 3 "=b,X"))]
479090075Sobrien  ""
4791117395Skan  "#"
479290075Sobrien  [(set_attr "itanium_class" "br,scall")])
479390075Sobrien
4794117395Skan;; Irritatingly, we don't have access to INSN within the split body.
4795117395Skan;; See commentary in ia64_split_call as to why these aren't peep2.
4796117395Skan(define_split
4797117395Skan  [(call (mem (match_operand 0 "call_operand" ""))
4798117395Skan	 (const_int 1))
4799117395Skan   (clobber (match_operand:DI 1 "register_operand" ""))
4800117395Skan   (clobber (match_scratch:DI 2 ""))
4801117395Skan   (clobber (match_scratch:DI 3 ""))]
4802117395Skan  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4803117395Skan  [(const_int 0)]
4804117395Skan{
4805117395Skan  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4806117395Skan		   operands[3], true, false);
4807117395Skan  DONE;
4808117395Skan})
4809117395Skan
4810117395Skan(define_split
4811117395Skan  [(call (mem (match_operand 0 "call_operand" ""))
4812117395Skan	 (const_int 1))
4813117395Skan   (clobber (match_operand:DI 1 "register_operand" ""))
4814117395Skan   (clobber (match_scratch:DI 2 ""))
4815117395Skan   (clobber (match_scratch:DI 3 ""))]
4816117395Skan  "reload_completed"
4817117395Skan  [(const_int 0)]
4818117395Skan{
4819117395Skan  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
4820117395Skan		   operands[3], false, false);
4821117395Skan  DONE;
4822117395Skan})
4823117395Skan
4824117395Skan(define_insn "call_value_gp"
482590075Sobrien  [(set (match_operand 0 "" "")
4826117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
4827117395Skan	      (const_int 1)))
4828117395Skan   (clobber (match_operand:DI 2 "register_operand" "=b,b"))
4829117395Skan   (clobber (match_scratch:DI 3 "=&r,X"))
4830117395Skan   (clobber (match_scratch:DI 4 "=b,X"))]
483190075Sobrien  ""
4832117395Skan  "#"
483390075Sobrien  [(set_attr "itanium_class" "br,scall")])
483490075Sobrien
4835117395Skan(define_split
4836117395Skan  [(set (match_operand 0 "" "")
4837117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
4838117395Skan	      (const_int 1)))
4839117395Skan   (clobber (match_operand:DI 2 "register_operand" ""))
4840117395Skan   (clobber (match_scratch:DI 3 ""))
4841117395Skan   (clobber (match_scratch:DI 4 ""))]
4842117395Skan  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4843117395Skan  [(const_int 0)]
4844117395Skan{
4845117395Skan  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4846117395Skan		   operands[4], true, false);
4847117395Skan  DONE;
4848117395Skan})
4849117395Skan
4850117395Skan(define_split
4851117395Skan  [(set (match_operand 0 "" "")
4852117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
4853117395Skan	      (const_int 1)))
4854117395Skan   (clobber (match_operand:DI 2 "register_operand" ""))
4855117395Skan   (clobber (match_scratch:DI 3 ""))
4856117395Skan   (clobber (match_scratch:DI 4 ""))]
4857117395Skan  "reload_completed"
4858117395Skan  [(const_int 0)]
4859117395Skan{
4860117395Skan  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
4861117395Skan		   operands[4], false, false);
4862117395Skan  DONE;
4863117395Skan})
4864117395Skan
4865117395Skan(define_insn_and_split "sibcall_gp"
4866117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
4867117395Skan	 (const_int 1))
4868117395Skan   (clobber (match_scratch:DI 1 "=&r,X"))
4869117395Skan   (clobber (match_scratch:DI 2 "=b,X"))]
487090075Sobrien  ""
4871117395Skan  "#"
4872117395Skan  "reload_completed"
4873117395Skan  [(const_int 0)]
4874117395Skan{
4875117395Skan  ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
4876117395Skan		   operands[2], true, true);
4877117395Skan  DONE;
4878117395Skan}
487990075Sobrien  [(set_attr "itanium_class" "br")])
488090075Sobrien
488190075Sobrien(define_insn "return_internal"
488290075Sobrien  [(return)
488390075Sobrien   (use (match_operand:DI 0 "register_operand" "b"))]
488490075Sobrien  ""
488590075Sobrien  "br.ret.sptk.many %0"
488690075Sobrien  [(set_attr "itanium_class" "br")])
488790075Sobrien
488890075Sobrien(define_insn "return"
488990075Sobrien  [(return)]
489090075Sobrien  "ia64_direct_return ()"
489190075Sobrien  "br.ret.sptk.many rp"
489290075Sobrien  [(set_attr "itanium_class" "br")])
489390075Sobrien
489490075Sobrien(define_insn "*return_true"
489590075Sobrien  [(set (pc)
489690075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
489790075Sobrien			[(match_operand:BI 1 "register_operand" "c")
489890075Sobrien			 (const_int 0)])
489990075Sobrien		      (return)
490090075Sobrien		      (pc)))]
490190075Sobrien  "ia64_direct_return ()"
490290075Sobrien  "(%J0) br.ret%+.many rp"
490390075Sobrien  [(set_attr "itanium_class" "br")
490490075Sobrien   (set_attr "predicable" "no")])
490590075Sobrien
490690075Sobrien(define_insn "*return_false"
490790075Sobrien  [(set (pc)
490890075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
490990075Sobrien			[(match_operand:BI 1 "register_operand" "c")
491090075Sobrien			 (const_int 0)])
491190075Sobrien		      (pc)
491290075Sobrien		      (return)))]
491390075Sobrien  "ia64_direct_return ()"
491490075Sobrien  "(%j0) br.ret%+.many rp"
491590075Sobrien  [(set_attr "itanium_class" "br")
491690075Sobrien   (set_attr "predicable" "no")])
491790075Sobrien
491890075Sobrien(define_insn "jump"
491990075Sobrien  [(set (pc) (label_ref (match_operand 0 "" "")))]
492090075Sobrien  ""
492190075Sobrien  "br %l0"
492290075Sobrien  [(set_attr "itanium_class" "br")])
492390075Sobrien
492490075Sobrien(define_insn "indirect_jump"
492590075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
492690075Sobrien  ""
492790075Sobrien  "br %0"
492890075Sobrien  [(set_attr "itanium_class" "br")])
492990075Sobrien
493090075Sobrien(define_expand "tablejump"
493190075Sobrien  [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
493290075Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
493390075Sobrien  ""
493490075Sobrien{
493590075Sobrien  rtx op0 = operands[0];
493690075Sobrien  rtx addr;
493790075Sobrien
493890075Sobrien  /* ??? Bother -- do_tablejump is "helpful" and pulls the table
493990075Sobrien     element into a register without bothering to see whether that
494090075Sobrien     is necessary given the operand predicate.  Check for MEM just
494190075Sobrien     in case someone fixes this.  */
494290075Sobrien  if (GET_CODE (op0) == MEM)
494390075Sobrien    addr = XEXP (op0, 0);
494490075Sobrien  else
494590075Sobrien    {
494690075Sobrien      /* Otherwise, cheat and guess that the previous insn in the
494790075Sobrien	 stream was the memory load.  Grab the address from that.
494890075Sobrien	 Note we have to momentarily pop out of the sequence started
494990075Sobrien	 by the insn-emit wrapper in order to grab the last insn.  */
495090075Sobrien      rtx last, set;
495190075Sobrien
495290075Sobrien      end_sequence ();
495390075Sobrien      last = get_last_insn ();
495490075Sobrien      start_sequence ();
495590075Sobrien      set = single_set (last);
495690075Sobrien
495790075Sobrien      if (! rtx_equal_p (SET_DEST (set), op0)
495890075Sobrien	  || GET_CODE (SET_SRC (set)) != MEM)
495990075Sobrien	abort ();
496090075Sobrien      addr = XEXP (SET_SRC (set), 0);
496190075Sobrien      if (rtx_equal_p (addr, op0))
496290075Sobrien	abort ();
496390075Sobrien    }
496490075Sobrien
496590075Sobrien  /* Jump table elements are stored pc-relative.  That is, a displacement
496690075Sobrien     from the entry to the label.  Thus to convert to an absolute address
496790075Sobrien     we add the address of the memory from which the value is loaded.  */
496890075Sobrien  operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
496990075Sobrien				     NULL_RTX, 1, OPTAB_DIRECT);
497090075Sobrien})
497190075Sobrien
497290075Sobrien(define_insn "*tablejump_internal"
497390075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))
497490075Sobrien   (use (label_ref (match_operand 1 "" "")))]
497590075Sobrien  ""
497690075Sobrien  "br %0"
497790075Sobrien  [(set_attr "itanium_class" "br")])
497890075Sobrien
497990075Sobrien
498090075Sobrien;; ::::::::::::::::::::
498190075Sobrien;; ::
498290075Sobrien;; :: Prologue and Epilogue instructions
498390075Sobrien;; ::
498490075Sobrien;; ::::::::::::::::::::
498590075Sobrien
498690075Sobrien(define_expand "prologue"
498790075Sobrien  [(const_int 1)]
498890075Sobrien  ""
498990075Sobrien{
499090075Sobrien  ia64_expand_prologue ();
499190075Sobrien  DONE;
4992117395Skan})
499390075Sobrien
499490075Sobrien(define_expand "epilogue"
499590075Sobrien  [(return)]
499690075Sobrien  ""
499790075Sobrien{
499890075Sobrien  ia64_expand_epilogue (0);
499990075Sobrien  DONE;
5000117395Skan})
500190075Sobrien
500290075Sobrien(define_expand "sibcall_epilogue"
500390075Sobrien  [(return)]
500490075Sobrien  ""
500590075Sobrien{
500690075Sobrien  ia64_expand_epilogue (1);
500790075Sobrien  DONE;
5008117395Skan})
500990075Sobrien
501090075Sobrien;; This prevents the scheduler from moving the SP decrement past FP-relative
501190075Sobrien;; stack accesses.  This is the same as adddi3 plus the extra set.
501290075Sobrien
501390075Sobrien(define_insn "prologue_allocate_stack"
501490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
501590075Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
501690075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
501796263Sobrien   (set (match_operand:DI 3 "register_operand" "+r,r,r")
501890075Sobrien	(match_dup 3))]
501990075Sobrien  ""
502090075Sobrien  "@
5021117395Skan   add %0 = %1, %2
5022117395Skan   adds %0 = %2, %1
5023117395Skan   addl %0 = %2, %1"
502490075Sobrien  [(set_attr "itanium_class" "ialu")])
502590075Sobrien
502690075Sobrien;; This prevents the scheduler from moving the SP restore past FP-relative
502790075Sobrien;; stack accesses.  This is similar to movdi plus the extra set.
502890075Sobrien
502990075Sobrien(define_insn "epilogue_deallocate_stack"
503090075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
503190075Sobrien	(match_operand:DI 1 "register_operand" "+r"))
503290075Sobrien   (set (match_dup 1) (match_dup 1))]
503390075Sobrien  ""
503490075Sobrien  "mov %0 = %1"
503590075Sobrien  [(set_attr "itanium_class" "ialu")])
503690075Sobrien
5037117395Skan;; As USE insns aren't meaningful after reload, this is used instead
5038117395Skan;; to prevent deleting instructions setting registers for EH handling
5039117395Skan(define_insn "prologue_use"
5040117395Skan  [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
5041117395Skan	      UNSPEC_PROLOGUE_USE)]
5042117395Skan  ""
5043117395Skan  ""
5044117395Skan  [(set_attr "itanium_class" "ignore")
5045117395Skan   (set_attr "predicable" "no")])
5046117395Skan
504790075Sobrien;; Allocate a new register frame.
504890075Sobrien
504990075Sobrien(define_insn "alloc"
505090075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
5051117395Skan	(unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
505290075Sobrien   (use (match_operand:DI 1 "const_int_operand" "i"))
505390075Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
505490075Sobrien   (use (match_operand:DI 3 "const_int_operand" "i"))
505590075Sobrien   (use (match_operand:DI 4 "const_int_operand" "i"))]
505690075Sobrien  ""
505790075Sobrien  "alloc %0 = ar.pfs, %1, %2, %3, %4"
505890075Sobrien  [(set_attr "itanium_class" "syst_m0")
505990075Sobrien   (set_attr "predicable" "no")])
506090075Sobrien
506190075Sobrien;; Modifies ar.unat
506290075Sobrien(define_expand "gr_spill"
506390075Sobrien  [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
506490075Sobrien		   (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5065117395Skan			       (match_operand:DI 2 "const_int_operand" "")]
5066117395Skan			      UNSPEC_GR_SPILL))
506790075Sobrien	      (clobber (match_dup 3))])]
506890075Sobrien  ""
506990075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
507090075Sobrien
507190075Sobrien(define_insn "gr_spill_internal"
507290075Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
507390075Sobrien	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5074117395Skan		    (match_operand:DI 2 "const_int_operand" "")]
5075117395Skan		   UNSPEC_GR_SPILL))
507690075Sobrien   (clobber (match_operand:DI 3 "register_operand" ""))]
507790075Sobrien  ""
507890075Sobrien{
5079117395Skan  /* Note that we use a C output pattern here to avoid the predicate
5080117395Skan     being automatically added before the .mem.offset directive.  */
5081117395Skan  return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
5082117395Skan}
508390075Sobrien  [(set_attr "itanium_class" "st")])
508490075Sobrien
508590075Sobrien;; Reads ar.unat
508690075Sobrien(define_expand "gr_restore"
508790075Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
508890075Sobrien		   (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5089117395Skan			       (match_operand:DI 2 "const_int_operand" "")]
5090117395Skan			      UNSPEC_GR_RESTORE))
509190075Sobrien	      (use (match_dup 3))])]
509290075Sobrien  ""
509390075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
509490075Sobrien
509590075Sobrien(define_insn "gr_restore_internal"
509690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
509790075Sobrien	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5098117395Skan		    (match_operand:DI 2 "const_int_operand" "")]
5099117395Skan		   UNSPEC_GR_RESTORE))
510090075Sobrien   (use (match_operand:DI 3 "register_operand" ""))]
510190075Sobrien  ""
5102117395Skan  { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
510390075Sobrien  [(set_attr "itanium_class" "ld")])
510490075Sobrien
510590075Sobrien(define_insn "fr_spill"
510690075Sobrien  [(set (match_operand:TF 0 "memory_operand" "=m")
5107117395Skan	(unspec:TF [(match_operand:TF 1 "register_operand" "f")]
5108117395Skan		   UNSPEC_FR_SPILL))]
510990075Sobrien  ""
511090075Sobrien  "stf.spill %0 = %1%P0"
511190075Sobrien  [(set_attr "itanium_class" "stf")])
511290075Sobrien
511390075Sobrien(define_insn "fr_restore"
511490075Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
5115117395Skan	(unspec:TF [(match_operand:TF 1 "memory_operand" "m")]
5116117395Skan		   UNSPEC_FR_RESTORE))]
511790075Sobrien  ""
511890075Sobrien  "ldf.fill %0 = %1%P1"
511990075Sobrien  [(set_attr "itanium_class" "fld")])
512090075Sobrien
512190075Sobrien;; ??? The explicit stop is not ideal.  It would be better if
512290075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
512390075Sobrien;; fixed later.  This avoids an RSE DV.
512490075Sobrien
512590075Sobrien(define_insn "bsp_value"
512690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
5127117395Skan	(unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
512890075Sobrien  ""
5129117395Skan  "*
5130117395Skan{
5131117395Skan  return \";;\;%,mov %0 = ar.bsp\";
5132117395Skan}"
513390075Sobrien  [(set_attr "itanium_class" "frar_i")])
513490075Sobrien
513590075Sobrien(define_insn "set_bsp"
5136117395Skan  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
5137117395Skan		    UNSPECV_SET_BSP)]
513890075Sobrien  ""
5139117395Skan  "flushrs
5140117395Skan	mov r19=ar.rsc
5141117395Skan	;;
5142117395Skan	and r19=0x1c,r19
5143117395Skan	;;
5144117395Skan	mov ar.rsc=r19
5145117395Skan	;;
5146117395Skan	mov ar.bspstore=%0
5147117395Skan	;;
5148117395Skan	or r19=0x3,r19
5149117395Skan	;;
5150117395Skan	loadrs
5151117395Skan	invala
5152117395Skan	;;
5153117395Skan	mov ar.rsc=r19"
515490075Sobrien  [(set_attr "itanium_class" "unknown")
515590075Sobrien   (set_attr "predicable" "no")])
515690075Sobrien
515790075Sobrien;; ??? The explicit stops are not ideal.  It would be better if
515890075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
515990075Sobrien;; fixed later.  This avoids an RSE DV.
516090075Sobrien
516190075Sobrien(define_insn "flushrs"
5162117395Skan  [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
516390075Sobrien  ""
516490075Sobrien  ";;\;flushrs\;;;"
5165117395Skan  [(set_attr "itanium_class" "rse_m")
5166117395Skan   (set_attr "predicable" "no")])
516790075Sobrien
516890075Sobrien;; ::::::::::::::::::::
516990075Sobrien;; ::
517090075Sobrien;; :: Miscellaneous instructions
517190075Sobrien;; ::
517290075Sobrien;; ::::::::::::::::::::
517390075Sobrien
517490075Sobrien;; ??? Emiting a NOP instruction isn't very useful.  This should probably
517590075Sobrien;; be emitting ";;" to force a break in the instruction packing.
517690075Sobrien
517790075Sobrien;; No operation, needed in case the user uses -g but not -O.
517890075Sobrien(define_insn "nop"
517990075Sobrien  [(const_int 0)]
518090075Sobrien  ""
518190075Sobrien  "nop 0"
518290075Sobrien  [(set_attr "itanium_class" "unknown")])
518390075Sobrien
518490075Sobrien(define_insn "nop_m"
518590075Sobrien  [(const_int 1)]
518690075Sobrien  ""
518790075Sobrien  "nop.m 0"
518890075Sobrien  [(set_attr "itanium_class" "nop_m")])
518990075Sobrien
519090075Sobrien(define_insn "nop_i"
519190075Sobrien  [(const_int 2)]
519290075Sobrien  ""
519390075Sobrien  "nop.i 0"
519490075Sobrien  [(set_attr "itanium_class" "nop_i")])
519590075Sobrien
519690075Sobrien(define_insn "nop_f"
519790075Sobrien  [(const_int 3)]
519890075Sobrien  ""
519990075Sobrien  "nop.f 0"
520090075Sobrien  [(set_attr "itanium_class" "nop_f")])
520190075Sobrien
520290075Sobrien(define_insn "nop_b"
520390075Sobrien  [(const_int 4)]
520490075Sobrien  ""
520590075Sobrien  "nop.b 0"
520690075Sobrien  [(set_attr "itanium_class" "nop_b")])
520790075Sobrien
520890075Sobrien(define_insn "nop_x"
520990075Sobrien  [(const_int 5)]
521090075Sobrien  ""
521190075Sobrien  ""
521290075Sobrien  [(set_attr "itanium_class" "nop_x")])
521390075Sobrien
521490075Sobrien(define_insn "bundle_selector"
5215117395Skan  [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
521690075Sobrien  ""
5217117395Skan  { return get_bundle_name (INTVAL (operands[0])); }
521890075Sobrien  [(set_attr "itanium_class" "ignore")
521990075Sobrien   (set_attr "predicable" "no")])
522090075Sobrien
522190075Sobrien;; Pseudo instruction that prevents the scheduler from moving code above this
522290075Sobrien;; point.
522390075Sobrien(define_insn "blockage"
5224117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
522590075Sobrien  ""
522690075Sobrien  ""
522790075Sobrien  [(set_attr "itanium_class" "ignore")
522890075Sobrien   (set_attr "predicable" "no")])
522990075Sobrien
523090075Sobrien(define_insn "insn_group_barrier"
5231117395Skan  [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5232117395Skan		    UNSPECV_INSN_GROUP_BARRIER)]
523390075Sobrien  ""
523490075Sobrien  ";;"
523590075Sobrien  [(set_attr "itanium_class" "stop_bit")
523690075Sobrien   (set_attr "predicable" "no")])
523790075Sobrien
523896263Sobrien(define_expand "trap"
523996263Sobrien  [(trap_if (const_int 1) (const_int 0))]
524096263Sobrien  ""
524196263Sobrien  "")
524296263Sobrien
524396263Sobrien;; ??? We don't have a match-any slot type.  Setting the type to unknown
524496263Sobrien;; produces worse code that setting the slot type to A.
524596263Sobrien
524696263Sobrien(define_insn "*trap"
524796263Sobrien  [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
524896263Sobrien  ""
524996263Sobrien  "break %0"
525096263Sobrien  [(set_attr "itanium_class" "chk_s")])
525196263Sobrien
525296263Sobrien(define_expand "conditional_trap"
525396263Sobrien  [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
525496263Sobrien  ""
525596263Sobrien{
525696263Sobrien  operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
525796263Sobrien})
525896263Sobrien
525996263Sobrien(define_insn "*conditional_trap"
526096263Sobrien  [(trap_if (match_operator 0 "predicate_operator"
526196263Sobrien	      [(match_operand:BI 1 "register_operand" "c")
526296263Sobrien	       (const_int 0)])  
526396263Sobrien	    (match_operand 2 "const_int_operand" ""))]
526496263Sobrien  ""
526596263Sobrien  "(%J0) break %2"
526696263Sobrien  [(set_attr "itanium_class" "chk_s")
526796263Sobrien   (set_attr "predicable" "no")])
526896263Sobrien
526990075Sobrien(define_insn "break_f"
5270117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
527190075Sobrien  ""
527290075Sobrien  "break.f 0"
527390075Sobrien  [(set_attr "itanium_class" "nop_f")])
527490075Sobrien
527590075Sobrien(define_insn "prefetch"
527690075Sobrien  [(prefetch (match_operand:DI 0 "address_operand" "p")
527790075Sobrien	     (match_operand:DI 1 "const_int_operand" "n")
527890075Sobrien	     (match_operand:DI 2 "const_int_operand" "n"))]
527990075Sobrien  ""
528090075Sobrien{
528190075Sobrien  static const char * const alt[2][4] = {
528290075Sobrien    {
5283119256Skan      "%,lfetch.nta [%0]",
5284119256Skan      "%,lfetch.nt1 [%0]",
5285119256Skan      "%,lfetch.nt2 [%0]",
5286119256Skan      "%,lfetch [%0]"
528790075Sobrien    },
528890075Sobrien    {
5289119256Skan      "%,lfetch.excl.nta [%0]",
5290119256Skan      "%,lfetch.excl.nt1 [%0]",
5291119256Skan      "%,lfetch.excl.nt2 [%0]",
5292119256Skan      "%,lfetch.excl [%0]"
529390075Sobrien    }
529490075Sobrien  };
529590075Sobrien  int i = (INTVAL (operands[1]));
529690075Sobrien  int j = (INTVAL (operands[2]));
529790075Sobrien
529890075Sobrien  if (i != 0 && i != 1)
529990075Sobrien    abort ();
530090075Sobrien  if (j < 0 || j > 3)
530190075Sobrien    abort ();
530290075Sobrien  return alt[i][j];
530390075Sobrien}
530490075Sobrien  [(set_attr "itanium_class" "lfetch")])
530590075Sobrien
530690075Sobrien;; Non-local goto support.
530790075Sobrien
530890075Sobrien(define_expand "save_stack_nonlocal"
530990075Sobrien  [(use (match_operand:OI 0 "memory_operand" ""))
531090075Sobrien   (use (match_operand:DI 1 "register_operand" ""))]
531190075Sobrien  ""
531290075Sobrien{
531390075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
531490075Sobrien					 \"__ia64_save_stack_nonlocal\"),
531590075Sobrien		     0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
531690075Sobrien		     operands[1], Pmode);
531790075Sobrien  DONE;
5318117395Skan})
531990075Sobrien
532090075Sobrien(define_expand "nonlocal_goto"
532190075Sobrien  [(use (match_operand 0 "general_operand" ""))
532290075Sobrien   (use (match_operand 1 "general_operand" ""))
532390075Sobrien   (use (match_operand 2 "general_operand" ""))
532490075Sobrien   (use (match_operand 3 "general_operand" ""))]
532590075Sobrien  ""
532690075Sobrien{
532790075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
532890075Sobrien		     LCT_NORETURN, VOIDmode, 3,
532990075Sobrien		     operands[1], Pmode,
533090075Sobrien		     copy_to_reg (XEXP (operands[2], 0)), Pmode,
533190075Sobrien		     operands[3], Pmode);
533290075Sobrien  emit_barrier ();
533390075Sobrien  DONE;
5334117395Skan})
533590075Sobrien
5336117395Skan(define_insn_and_split "builtin_setjmp_receiver"
5337117395Skan  [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
533890075Sobrien  ""
5339117395Skan  "#"
5340117395Skan  "reload_completed"
5341117395Skan  [(const_int 0)]
534290075Sobrien{
5343117395Skan  ia64_reload_gp ();
534490075Sobrien  DONE;
5345117395Skan})
534690075Sobrien
534790075Sobrien(define_expand "eh_epilogue"
534890075Sobrien  [(use (match_operand:DI 0 "register_operand" "r"))
534990075Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
535090075Sobrien   (use (match_operand:DI 2 "register_operand" "r"))]
535190075Sobrien  ""
535290075Sobrien{
535390075Sobrien  rtx bsp = gen_rtx_REG (Pmode, 10);
535490075Sobrien  rtx sp = gen_rtx_REG (Pmode, 9);
535590075Sobrien
535690075Sobrien  if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
535790075Sobrien    {
535890075Sobrien      emit_move_insn (bsp, operands[0]);
535990075Sobrien      operands[0] = bsp;
536090075Sobrien    }
536190075Sobrien  if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
536290075Sobrien    {
536390075Sobrien      emit_move_insn (sp, operands[2]);
536490075Sobrien      operands[2] = sp;
536590075Sobrien    }
536690075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, sp));
536790075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, bsp));
536890075Sobrien
536990075Sobrien  cfun->machine->ia64_eh_epilogue_sp = sp;
537090075Sobrien  cfun->machine->ia64_eh_epilogue_bsp = bsp;
5371117395Skan})
537290075Sobrien
537390075Sobrien;; Builtin apply support.
537490075Sobrien
537590075Sobrien(define_expand "restore_stack_nonlocal"
537690075Sobrien  [(use (match_operand:DI 0 "register_operand" ""))
537790075Sobrien   (use (match_operand:OI 1 "memory_operand" ""))]
537890075Sobrien  ""
537990075Sobrien{
538090075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5381117395Skan					 "__ia64_restore_stack_nonlocal"),
538290075Sobrien		     0, VOIDmode, 1,
538390075Sobrien		     copy_to_reg (XEXP (operands[1], 0)), Pmode);
538490075Sobrien  DONE;
5385117395Skan})
538690075Sobrien
538790075Sobrien
538890075Sobrien;;; Intrinsics support.
538990075Sobrien
539090075Sobrien(define_expand "mf"
539190075Sobrien  [(set (mem:BLK (match_dup 0))
5392117395Skan	(unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
539390075Sobrien  ""
539490075Sobrien{
539590075Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
539690075Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
5397117395Skan})
539890075Sobrien
539990075Sobrien(define_insn "*mf_internal"
540090075Sobrien  [(set (match_operand:BLK 0 "" "")
5401117395Skan	(unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
540290075Sobrien  ""
540390075Sobrien  "mf"
540490075Sobrien  [(set_attr "itanium_class" "syst_m")])
540590075Sobrien
540690075Sobrien(define_insn "fetchadd_acq_si"
540790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
540890075Sobrien	(match_dup 1))
540990075Sobrien   (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
541090075Sobrien	(unspec:SI [(match_dup 1)
5411117395Skan		    (match_operand:SI 2 "fetchadd_operand" "n")]
5412117395Skan		   UNSPEC_FETCHADD_ACQ))]
541390075Sobrien  ""
541490075Sobrien  "fetchadd4.acq %0 = %1, %2"
541590075Sobrien  [(set_attr "itanium_class" "sem")])
541690075Sobrien
541790075Sobrien(define_insn "fetchadd_acq_di"
541890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
541990075Sobrien	(match_dup 1))
542090075Sobrien   (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
542190075Sobrien	(unspec:DI [(match_dup 1)
5422117395Skan		    (match_operand:DI 2 "fetchadd_operand" "n")]
5423117395Skan		   UNSPEC_FETCHADD_ACQ))]
542490075Sobrien  ""
542590075Sobrien  "fetchadd8.acq %0 = %1, %2"
542690075Sobrien  [(set_attr "itanium_class" "sem")])
542790075Sobrien
542890075Sobrien(define_insn "cmpxchg_acq_si"
542990075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
543090075Sobrien	(match_dup 1))
543190075Sobrien   (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
543290075Sobrien        (unspec:SI [(match_dup 1)
543390075Sobrien                    (match_operand:SI 2 "gr_register_operand" "r")
5434117395Skan		    (match_operand 3 "ar_ccv_reg_operand" "")]
5435117395Skan		   UNSPEC_CMPXCHG_ACQ))]
543690075Sobrien  ""
543790075Sobrien  "cmpxchg4.acq %0 = %1, %2, %3"
543890075Sobrien  [(set_attr "itanium_class" "sem")])
543990075Sobrien
544090075Sobrien(define_insn "cmpxchg_acq_di"
544190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
544290075Sobrien	(match_dup 1))
544390075Sobrien   (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
544490075Sobrien        (unspec:DI [(match_dup 1)
544590075Sobrien                    (match_operand:DI 2 "gr_register_operand" "r")
5446117395Skan		    (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5447117395Skan		   UNSPEC_CMPXCHG_ACQ))]
544890075Sobrien  ""
544990075Sobrien  "cmpxchg8.acq %0 = %1, %2, %3"
545090075Sobrien  [(set_attr "itanium_class" "sem")])
545190075Sobrien
545290075Sobrien(define_insn "xchgsi"
545390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
545490075Sobrien        (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
545590075Sobrien   (set (match_dup 1)
545690075Sobrien        (match_operand:SI 2 "gr_register_operand" "r"))]
545790075Sobrien  ""
545890075Sobrien  "xchg4 %0 = %1, %2"
545990075Sobrien  [(set_attr "itanium_class" "sem")])
546090075Sobrien
546190075Sobrien(define_insn "xchgdi"
546290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
546390075Sobrien        (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
546490075Sobrien   (set (match_dup 1)
546590075Sobrien        (match_operand:DI 2 "gr_register_operand" "r"))]
546690075Sobrien  ""
546790075Sobrien  "xchg8 %0 = %1, %2"
546890075Sobrien  [(set_attr "itanium_class" "sem")])
546990075Sobrien
547090075Sobrien;; Predication.
547190075Sobrien
547290075Sobrien(define_cond_exec
547390075Sobrien  [(match_operator 0 "predicate_operator"
547490075Sobrien     [(match_operand:BI 1 "register_operand" "c")
547590075Sobrien      (const_int 0)])]
547690075Sobrien  ""
547790075Sobrien  "(%J0)")
547890075Sobrien
547990075Sobrien(define_insn "pred_rel_mutex"
548090075Sobrien  [(set (match_operand:BI 0 "register_operand" "+c")
5481117395Skan       (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
548290075Sobrien  ""
548390075Sobrien  ".pred.rel.mutex %0, %I0"
548490075Sobrien  [(set_attr "itanium_class" "ignore")
548590075Sobrien   (set_attr "predicable" "no")])
548690075Sobrien
548790075Sobrien(define_insn "safe_across_calls_all"
5488117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
548990075Sobrien  ""
549090075Sobrien  ".pred.safe_across_calls p1-p63"
549190075Sobrien  [(set_attr "itanium_class" "ignore")
549290075Sobrien   (set_attr "predicable" "no")])
549390075Sobrien
549490075Sobrien(define_insn "safe_across_calls_normal"
5495117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
549690075Sobrien  ""
549790075Sobrien{
549890075Sobrien  emit_safe_across_calls (asm_out_file);
5499117395Skan  return "";
5500117395Skan}
550190075Sobrien  [(set_attr "itanium_class" "ignore")
550290075Sobrien   (set_attr "predicable" "no")])
550390075Sobrien
550490075Sobrien;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
550590075Sobrien;; pointer.  This is used by the HP-UX 32 bit mode.
550690075Sobrien
550790075Sobrien(define_insn "ptr_extend"
550890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5509117395Skan        (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
5510117395Skan		   UNSPEC_ADDP4))]
551190075Sobrien  ""
551290075Sobrien  "addp4 %0 = 0,%1"
551390075Sobrien  [(set_attr "itanium_class" "ialu")])
551490075Sobrien
551590075Sobrien;;
5516117395Skan;; Optimizations for ptr_extend
5517117395Skan
5518117395Skan(define_insn "*ptr_extend_plus_1"
5519117395Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5520117395Skan        (unspec:DI
5521117395Skan         [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
5522117395Skan                   (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
5523117395Skan         UNSPEC_ADDP4))]
5524117395Skan  "addp4_optimize_ok (operands[1], operands[2])"
5525117395Skan  "addp4 %0 = %2, %1"
5526117395Skan  [(set_attr "itanium_class" "ialu")])
5527117395Skan
5528117395Skan(define_insn "*ptr_extend_plus_2"
5529117395Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5530117395Skan        (unspec:DI
5531117395Skan         [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
5532117395Skan                   (match_operand:SI 2 "basereg_operand" "r"))]
5533117395Skan         UNSPEC_ADDP4))]
5534117395Skan  "addp4_optimize_ok (operands[1], operands[2])"
5535117395Skan  "addp4 %0 = %1, %2"
5536117395Skan  [(set_attr "itanium_class" "ialu")])
5537