ia64.md revision 90075
190075Sobrien;; IA-64 Machine description template
290075Sobrien;; Copyright (C) 1999, 2000, 2001 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
5190075Sobrien;; Unspec usage:
5290075Sobrien;;
5390075Sobrien;; unspec:
5490075Sobrien;;	1	gr_spill
5590075Sobrien;;	2	gr_restore
5690075Sobrien;;	3	fr_spill
5790075Sobrien;;	4	fr_restore
5890075Sobrien;;	5	recip_approx
5990075Sobrien;;	7	pred_rel_mutex
6090075Sobrien;;	8	popcnt
6190075Sobrien;;	9	pic call
6290075Sobrien;;	12	mf
6390075Sobrien;;	13	cmpxchg_acq
6490075Sobrien;;	19	fetchadd_acq
6590075Sobrien;;	20	bsp_value
6690075Sobrien;;	21	flushrs
6790075Sobrien;;	22      bundle selector
6890075Sobrien;;	23      cycle display
6990075Sobrien;;      24      addp4
7090075Sobrien;;	25	prologue_use
7190075Sobrien;;
7290075Sobrien;; unspec_volatile:
7390075Sobrien;;	0	alloc
7490075Sobrien;;	1	blockage
7590075Sobrien;;	2	insn_group_barrier
7690075Sobrien;;	3	break
7790075Sobrien;;	5	set_bsp
7890075Sobrien;;	8	pred.safe_across_calls all
7990075Sobrien;;	9	pred.safe_across_calls normal
8090075Sobrien
8190075Sobrien;; ::::::::::::::::::::
8290075Sobrien;; ::
8390075Sobrien;; :: Attributes
8490075Sobrien;; ::
8590075Sobrien;; ::::::::::::::::::::
8690075Sobrien
8790075Sobrien;; Instruction type.  This primarily determines how instructions can be
8890075Sobrien;; packed in bundles, and secondarily affects scheduling to function units.
8990075Sobrien
9090075Sobrien;; A alu, can go in I or M syllable of a bundle
9190075Sobrien;; I integer
9290075Sobrien;; M memory
9390075Sobrien;; F floating-point
9490075Sobrien;; B branch
9590075Sobrien;; L long immediate, takes two syllables
9690075Sobrien;; S stop bit
9790075Sobrien
9890075Sobrien;; ??? Should not have any pattern with type unknown.  Perhaps add code to
9990075Sobrien;; check this in md_reorg?  Currently use unknown for patterns which emit
10090075Sobrien;; multiple instructions, patterns which emit 0 instructions, and patterns
10190075Sobrien;; which emit instruction that can go in any slot (e.g. nop).
10290075Sobrien
10390075Sobrien(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f,nop_i,nop_m,nop_x,lfetch"
10490075Sobrien         (const_string "unknown"))
10590075Sobrien
10690075Sobrien;; chk_s has an I and an M form; use type A for convenience.
10790075Sobrien(define_attr "type" "unknown,A,I,M,F,B,L,X,S"
10890075Sobrien  (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
10990075Sobrien	 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
11090075Sobrien	 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
11190075Sobrien	 (eq_attr "itanium_class" "lfetch") (const_string "M")
11290075Sobrien	 (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A")
11390075Sobrien	 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
11490075Sobrien	 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
11590075Sobrien	 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
11690075Sobrien	 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
11790075Sobrien	 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
11890075Sobrien	 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
11990075Sobrien	 (eq_attr "itanium_class" "stop_bit") (const_string "S")
12090075Sobrien	 (eq_attr "itanium_class" "nop_x") (const_string "X")
12190075Sobrien	 (eq_attr "itanium_class" "long_i") (const_string "L")]
12290075Sobrien	(const_string "unknown")))
12390075Sobrien
12490075Sobrien(define_attr "itanium_requires_unit0" "no,yes"
12590075Sobrien  (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
12690075Sobrien	 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
12790075Sobrien	 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
12890075Sobrien	 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
12990075Sobrien	 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
13090075Sobrien	 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
13190075Sobrien	(const_string "no")))
13290075Sobrien
13390075Sobrien;; Predication.  True iff this instruction can be predicated.
13490075Sobrien
13590075Sobrien(define_attr "predicable" "no,yes" (const_string "yes"))
13690075Sobrien
13790075Sobrien
13890075Sobrien;; ::::::::::::::::::::
13990075Sobrien;; ::
14090075Sobrien;; :: Function Units
14190075Sobrien;; ::
14290075Sobrien;; ::::::::::::::::::::
14390075Sobrien
14490075Sobrien;; We define 6 "dummy" functional units.  All the real work to decide which
14590075Sobrien;; insn uses which unit is done by our MD_SCHED_REORDER hooks.  We only
14690075Sobrien;; have to ensure here that there are enough copies of the dummy unit so
14790075Sobrien;; that the scheduler doesn't get confused by MD_SCHED_REORDER.
14890075Sobrien;; Other than the 6 dummies for normal insns, we also add a single dummy unit
14990075Sobrien;; for stop bits.
15090075Sobrien
15190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br")     0 0)
15290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall")  0 0)
15390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp")   2 0)
15490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0)
15590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld")    9 0)
15690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac")   5 0)
15790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc")  5 0)
15890075Sobrien
15990075Sobrien;; There is only one insn `mov = ar.bsp' for frar_i:
16090075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0)
16190075Sobrien;; There is only ony insn `mov = ar.unat' for frar_m:
16290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0)
16390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr")   2 0)
16490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr")   2 0)
16590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr")   2 0)
16690075Sobrien
16790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu")   1 0)
16890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp")   1 0)
16990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog")   1 0)
17090075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf")   1 0)
17190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld")     2 0)
17290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0)
17390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul")  2 0)
17490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf")  2 0)
17590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi")  2 0)
17690075Sobrien
17790075Sobrien;; Now we have only one insn (flushrs) of such class.  We assume that flushrs
17890075Sobrien;; is the 1st syllable of the bundle after stop bit.
17990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m")  0 0)
18090075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem")   11 0)
18190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf")    1 0)
18290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st")     1 0)
18390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0)
18490075Sobrien;; Now we use only one insn `mf'.  Therfore latency time is set up to 0.
18590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0)
18690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit")   1 0)
18790075Sobrien
18890075Sobrien;; There is only one insn `mov ar.pfs =' for toar_i therefore we use
18990075Sobrien;; latency time equal to 0:
19090075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0)
19190075Sobrien;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
19290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0)
19390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr")   1 0)
19490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr")   9 0)
19590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr")   1 0)
19690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy")   7 0)
19790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd")    1 0)
19890075Sobrien
19990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m")  0 0)
20090075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i")  0 0)
20190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f")  0 0)
20290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b")  0 0)
20390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x")  0 0)
20490075Sobrien
20590075Sobrien(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0)
20690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0)
20790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0)
20890075Sobrien
20990075Sobrien;; ::::::::::::::::::::
21090075Sobrien;; ::
21190075Sobrien;; :: Moves
21290075Sobrien;; ::
21390075Sobrien;; ::::::::::::::::::::
21490075Sobrien
21590075Sobrien;; Set of a single predicate register.  This is only used to implement
21690075Sobrien;; pr-to-pr move and complement.
21790075Sobrien
21890075Sobrien(define_insn "*movcci"
21990075Sobrien  [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
22090075Sobrien	(match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
22190075Sobrien  ""
22290075Sobrien  "@
22390075Sobrien   cmp.ne %0, p0 = r0, r0
22490075Sobrien   cmp.eq %0, p0 = r0, r0
22590075Sobrien   (%1) cmp.eq.unc %0, p0 = r0, r0"
22690075Sobrien  [(set_attr "itanium_class" "icmp")
22790075Sobrien   (set_attr "predicable" "no")])
22890075Sobrien
22990075Sobrien(define_insn "movbi"
23090075Sobrien  [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
23190075Sobrien	(match_operand:BI 1 "move_operand"         " O,n, c,  c,*r, n,*m,*r,*r"))]
23290075Sobrien  ""
23390075Sobrien  "@
23490075Sobrien   cmp.ne %0, %I0 = r0, r0
23590075Sobrien   cmp.eq %0, %I0 = r0, r0
23690075Sobrien   #
23790075Sobrien   #
23890075Sobrien   tbit.nz %0, %I0 = %1, 0
23990075Sobrien   adds %0 = %1, r0
24090075Sobrien   ld1%O1 %0 = %1%P1
24190075Sobrien   st1%Q0 %0 = %1%P0
24290075Sobrien   mov %0 = %1"
24390075Sobrien  [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
24490075Sobrien
24590075Sobrien(define_split
24690075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
24790075Sobrien	(match_operand:BI 1 "register_operand" ""))]
24890075Sobrien  "reload_completed
24990075Sobrien   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
25090075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
25190075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
25290075Sobrien     (set (match_dup 0) (const_int 1)))
25390075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
25490075Sobrien     (set (match_dup 0) (const_int 0)))]
25590075Sobrien  "")
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 && PR_REGNO_P (REGNO (operands[0]))
26290075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
26390075Sobrien  [(set (match_dup 2) (match_dup 4))
26490075Sobrien   (set (match_dup 3) (match_dup 5))
26590075Sobrien   (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
26690075Sobrien  "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
26790075Sobrien   operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
26890075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
26990075Sobrien   operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
27090075Sobrien
27190075Sobrien(define_expand "movqi"
27290075Sobrien  [(set (match_operand:QI 0 "general_operand" "")
27390075Sobrien	(match_operand:QI 1 "general_operand" ""))]
27490075Sobrien  ""
27590075Sobrien  "
27690075Sobrien{
27790075Sobrien  if (! reload_in_progress && ! reload_completed
27890075Sobrien      && ! ia64_move_ok (operands[0], operands[1]))
27990075Sobrien    operands[1] = force_reg (QImode, operands[1]);
28090075Sobrien}")
28190075Sobrien
28290075Sobrien(define_insn "*movqi_internal"
28390075Sobrien  [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
28490075Sobrien	(match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
28590075Sobrien  "ia64_move_ok (operands[0], operands[1])"
28690075Sobrien  "@
28790075Sobrien   mov %0 = %r1
28890075Sobrien   addl %0 = %1, r0
28990075Sobrien   ld1%O1 %0 = %1%P1
29090075Sobrien   st1%Q0 %0 = %r1%P0
29190075Sobrien   getf.sig %0 = %1
29290075Sobrien   setf.sig %0 = %r1
29390075Sobrien   mov %0 = %1"
29490075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
29590075Sobrien
29690075Sobrien(define_expand "movhi"
29790075Sobrien  [(set (match_operand:HI 0 "general_operand" "")
29890075Sobrien	(match_operand:HI 1 "general_operand" ""))]
29990075Sobrien  ""
30090075Sobrien  "
30190075Sobrien{
30290075Sobrien  if (! reload_in_progress && ! reload_completed
30390075Sobrien      && ! ia64_move_ok (operands[0], operands[1]))
30490075Sobrien    operands[1] = force_reg (HImode, operands[1]);
30590075Sobrien}")
30690075Sobrien
30790075Sobrien(define_insn "*movhi_internal"
30890075Sobrien  [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
30990075Sobrien	(match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
31090075Sobrien  "ia64_move_ok (operands[0], operands[1])"
31190075Sobrien  "@
31290075Sobrien   mov %0 = %r1
31390075Sobrien   addl %0 = %1, r0
31490075Sobrien   ld2%O1 %0 = %1%P1
31590075Sobrien   st2%Q0 %0 = %r1%P0
31690075Sobrien   getf.sig %0 = %1
31790075Sobrien   setf.sig %0 = %r1
31890075Sobrien   mov %0 = %1"
31990075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
32090075Sobrien
32190075Sobrien(define_expand "movsi"
32290075Sobrien  [(set (match_operand:SI 0 "general_operand" "")
32390075Sobrien	(match_operand:SI 1 "general_operand" ""))]
32490075Sobrien  ""
32590075Sobrien  "
32690075Sobrien{
32790075Sobrien  if (! reload_in_progress && ! reload_completed
32890075Sobrien      && ! ia64_move_ok (operands[0], operands[1]))
32990075Sobrien    operands[1] = force_reg (SImode, operands[1]);
33090075Sobrien}")
33190075Sobrien
33290075Sobrien(define_insn "*movsi_internal"
33390075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
33490075Sobrien	(match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
33590075Sobrien  "ia64_move_ok (operands[0], operands[1])"
33690075Sobrien  "@
33790075Sobrien  mov %0 = %r1
33890075Sobrien  addl %0 = %1, r0
33990075Sobrien  movl %0 = %1
34090075Sobrien  ld4%O1 %0 = %1%P1
34190075Sobrien  st4%Q0 %0 = %r1%P0
34290075Sobrien  getf.sig %0 = %1
34390075Sobrien  setf.sig %0 = %r1
34490075Sobrien  mov %0 = %1
34590075Sobrien  mov %0 = %1
34690075Sobrien  mov %0 = %r1"
34790075Sobrien;; frar_m, toar_m ??? why not frar_i and toar_i
34890075Sobrien  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
34990075Sobrien
35090075Sobrien(define_expand "movdi"
35190075Sobrien  [(set (match_operand:DI 0 "general_operand" "")
35290075Sobrien	(match_operand:DI 1 "general_operand" ""))]
35390075Sobrien  ""
35490075Sobrien  "
35590075Sobrien{
35690075Sobrien  if (! reload_in_progress && ! reload_completed
35790075Sobrien      && ! ia64_move_ok (operands[0], operands[1]))
35890075Sobrien    operands[1] = force_reg (DImode, operands[1]);
35990075Sobrien  if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
36090075Sobrien    {
36190075Sobrien      /* Before optimization starts, delay committing to any particular
36290075Sobrien	 type of PIC address load.  If this function gets deferred, we
36390075Sobrien	 may acquire information that changes the value of the
36490075Sobrien	 sdata_symbolic_operand predicate.  */
36590075Sobrien      /* But don't delay for function pointers.  Loading a function address
36690075Sobrien	 actually loads the address of the descriptor not the function.
36790075Sobrien	 If we represent these as SYMBOL_REFs, then they get cse'd with
36890075Sobrien	 calls, and we end up with calls to the descriptor address instead of
36990075Sobrien	 calls to the function address.  Functions are not candidates for
37090075Sobrien	 sdata anyways.  */
37190075Sobrien      if (rtx_equal_function_value_matters
37290075Sobrien	  && ! (GET_CODE (operands[1]) == SYMBOL_REF
37390075Sobrien		&& SYMBOL_REF_FLAG (operands[1])))
37490075Sobrien	emit_insn (gen_movdi_symbolic (operands[0], operands[1], gen_reg_rtx (DImode)));
37590075Sobrien      else
37690075Sobrien        ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
37790075Sobrien      DONE;
37890075Sobrien    }
37990075Sobrien}")
38090075Sobrien
38190075Sobrien;; This is used during early compilation to delay the decision on
38290075Sobrien;; how to refer to a variable as long as possible.  This is especially
38390075Sobrien;; important between initial rtl generation and optimization for
38490075Sobrien;; deferred functions, since we may acquire additional information
38590075Sobrien;; on the variables used in the meantime.
38690075Sobrien
38790075Sobrien;; ??? This causes us to lose REG_LABEL notes, because the insn splitter
38890075Sobrien;; does not attempt to preserve any REG_NOTES on the input instruction.
38990075Sobrien
39090075Sobrien(define_insn_and_split "movdi_symbolic"
39190075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
39290075Sobrien	(match_operand:DI 1 "symbolic_operand" "s"))
39390075Sobrien   (clobber (match_operand:DI  2 "register_operand" "+r"))
39490075Sobrien   (use (reg:DI 1))]
39590075Sobrien  ""
39690075Sobrien  "* abort ();"
39790075Sobrien  ""
39890075Sobrien  [(const_int 0)]
39990075Sobrien  "ia64_expand_load_address (operands[0], operands[1], operands[2]); DONE;")
40090075Sobrien
40190075Sobrien(define_insn "*movdi_internal"
40290075Sobrien  [(set (match_operand:DI 0 "destination_operand"
40390075Sobrien		    "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
40490075Sobrien	(match_operand:DI 1 "move_operand"
40590075Sobrien		    "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
40690075Sobrien  "ia64_move_ok (operands[0], operands[1])"
40790075Sobrien  "*
40890075Sobrien{
40990075Sobrien  static const char * const alt[] = {
41090075Sobrien    \"%,mov %0 = %r1\",
41190075Sobrien    \"%,addl %0 = %1, r0\",
41290075Sobrien    \"%,movl %0 = %1\",
41390075Sobrien    \"%,ld8%O1 %0 = %1%P1\",
41490075Sobrien    \"%,st8%Q0 %0 = %r1%P0\",
41590075Sobrien    \"%,getf.sig %0 = %1\",
41690075Sobrien    \"%,setf.sig %0 = %r1\",
41790075Sobrien    \"%,mov %0 = %1\",
41890075Sobrien    \"%,ldf8 %0 = %1%P1\",
41990075Sobrien    \"%,stf8 %0 = %1%P0\",
42090075Sobrien    \"%,mov %0 = %1\",
42190075Sobrien    \"%,mov %0 = %r1\",
42290075Sobrien    \"%,mov %0 = %1\",
42390075Sobrien    \"%,mov %0 = %1\",
42490075Sobrien    \"%,mov %0 = %1\",
42590075Sobrien    \"%,mov %0 = %1\",
42690075Sobrien    \"mov %0 = pr\",
42790075Sobrien    \"mov pr = %1, -1\"
42890075Sobrien  };
42990075Sobrien
43090075Sobrien  if (which_alternative == 2 && ! TARGET_NO_PIC
43190075Sobrien      && symbolic_operand (operands[1], VOIDmode))
43290075Sobrien    abort ();
43390075Sobrien
43490075Sobrien  return alt[which_alternative];
43590075Sobrien}"
43690075Sobrien  [(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")])
43790075Sobrien
43890075Sobrien(define_split
43990075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
44090075Sobrien	(match_operand:DI 1 "symbolic_operand" ""))]
44190075Sobrien  "reload_completed && ! TARGET_NO_PIC"
44290075Sobrien  [(const_int 0)]
44390075Sobrien  "
44490075Sobrien{
44590075Sobrien  ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
44690075Sobrien  DONE;
44790075Sobrien}")
44890075Sobrien
44990075Sobrien(define_expand "load_fptr"
45090075Sobrien  [(set (match_dup 2)
45190075Sobrien	(plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
45290075Sobrien   (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
45390075Sobrien  ""
45490075Sobrien  "
45590075Sobrien{
45690075Sobrien  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
45790075Sobrien  operands[3] = gen_rtx_MEM (DImode, operands[2]);
45890075Sobrien  RTX_UNCHANGING_P (operands[3]) = 1;
45990075Sobrien}")
46090075Sobrien
46190075Sobrien(define_insn "*load_fptr_internal1"
46290075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
46390075Sobrien	(plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "s")))]
46490075Sobrien  ""
46590075Sobrien  "addl %0 = @ltoff(@fptr(%1)), gp"
46690075Sobrien  [(set_attr "itanium_class" "ialu")])
46790075Sobrien
46890075Sobrien(define_insn "load_gprel"
46990075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
47090075Sobrien	(plus:DI (reg:DI 1) (match_operand:DI 1 "sdata_symbolic_operand" "s")))]
47190075Sobrien  ""
47290075Sobrien  "addl %0 = @gprel(%1), gp"
47390075Sobrien  [(set_attr "itanium_class" "ialu")])
47490075Sobrien
47590075Sobrien(define_insn "gprel64_offset"
47690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
47790075Sobrien	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
47890075Sobrien  ""
47990075Sobrien  "movl %0 = @gprel(%1)"
48090075Sobrien  [(set_attr "itanium_class" "long_i")])
48190075Sobrien
48290075Sobrien(define_expand "load_gprel64"
48390075Sobrien  [(set (match_dup 2)
48490075Sobrien	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
48590075Sobrien   (set (match_operand:DI 0 "register_operand" "")
48690075Sobrien	(plus:DI (match_dup 3) (match_dup 2)))]
48790075Sobrien  ""
48890075Sobrien  "
48990075Sobrien{
49090075Sobrien  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
49190075Sobrien  operands[3] = pic_offset_table_rtx;
49290075Sobrien}")
49390075Sobrien
49490075Sobrien(define_expand "load_symptr"
49590075Sobrien  [(set (match_operand:DI 2 "register_operand" "")
49690075Sobrien	(plus:DI (match_dup 4) (match_operand:DI 1 "got_symbolic_operand" "")))
49790075Sobrien   (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
49890075Sobrien  ""
49990075Sobrien  "
50090075Sobrien{
50190075Sobrien  operands[3] = gen_rtx_MEM (DImode, operands[2]);
50290075Sobrien  operands[4] = pic_offset_table_rtx;
50390075Sobrien  RTX_UNCHANGING_P (operands[3]) = 1;
50490075Sobrien}")
50590075Sobrien
50690075Sobrien(define_insn "*load_symptr_internal1"
50790075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
50890075Sobrien	(plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
50990075Sobrien  ""
51090075Sobrien  "addl %0 = @ltoff(%1), gp"
51190075Sobrien  [(set_attr "itanium_class" "ialu")])
51290075Sobrien
51390075Sobrien;; With no offsettable memory references, we've got to have a scratch
51490075Sobrien;; around to play with the second word.
51590075Sobrien(define_expand "movti"
51690075Sobrien  [(parallel [(set (match_operand:TI 0 "general_operand" "")
51790075Sobrien		   (match_operand:TI 1 "general_operand" ""))
51890075Sobrien	      (clobber (match_scratch:DI 2 ""))])]
51990075Sobrien  ""
52090075Sobrien  "
52190075Sobrien{
52290075Sobrien  if (! reload_in_progress && ! reload_completed
52390075Sobrien      && ! ia64_move_ok (operands[0], operands[1]))
52490075Sobrien    operands[1] = force_reg (TImode, operands[1]);
52590075Sobrien}")
52690075Sobrien
52790075Sobrien(define_insn_and_split "*movti_internal"
52890075Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
52990075Sobrien	(match_operand:TI 1 "general_operand"      "ri,m,r"))
53090075Sobrien   (clobber (match_scratch:DI 2 "=X,&r,&r"))]
53190075Sobrien  "ia64_move_ok (operands[0], operands[1])"
53290075Sobrien  "#"
53390075Sobrien  "reload_completed"
53490075Sobrien  [(const_int 0)]
53590075Sobrien  "
53690075Sobrien{
53790075Sobrien  rtx adj1, adj2, in[2], out[2], insn;
53890075Sobrien  int first;
53990075Sobrien
54090075Sobrien  adj1 = ia64_split_timode (in, operands[1], operands[2]);
54190075Sobrien  adj2 = ia64_split_timode (out, operands[0], operands[2]);
54290075Sobrien
54390075Sobrien  first = 0;
54490075Sobrien  if (reg_overlap_mentioned_p (out[0], in[1]))
54590075Sobrien    {
54690075Sobrien      if (reg_overlap_mentioned_p (out[1], in[0]))
54790075Sobrien	abort ();
54890075Sobrien      first = 1;
54990075Sobrien    }
55090075Sobrien
55190075Sobrien  if (adj1 && adj2)
55290075Sobrien    abort ();
55390075Sobrien  if (adj1)
55490075Sobrien    emit_insn (adj1);
55590075Sobrien  if (adj2)
55690075Sobrien    emit_insn (adj2);
55790075Sobrien  insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
55890075Sobrien  if (GET_CODE (out[first]) == MEM
55990075Sobrien      && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
56090075Sobrien    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
56190075Sobrien					  XEXP (XEXP (out[first], 0), 0),
56290075Sobrien					  REG_NOTES (insn));
56390075Sobrien  insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
56490075Sobrien  if (GET_CODE (out[!first]) == MEM
56590075Sobrien      && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
56690075Sobrien    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
56790075Sobrien					  XEXP (XEXP (out[!first], 0), 0),
56890075Sobrien					  REG_NOTES (insn));
56990075Sobrien  DONE;
57090075Sobrien}"
57190075Sobrien  [(set_attr "itanium_class" "unknown")
57290075Sobrien   (set_attr "predicable" "no")])
57390075Sobrien
57490075Sobrien;; ??? SSA creates these.  Can't allow memories since we don't have
57590075Sobrien;; the scratch register.  Fortunately combine will know how to add
57690075Sobrien;; the clobber and scratch.
57790075Sobrien(define_insn_and_split "*movti_internal_reg"
57890075Sobrien  [(set (match_operand:TI 0 "register_operand"  "=r")
57990075Sobrien	(match_operand:TI 1 "nonmemory_operand" "ri"))]
58090075Sobrien  ""
58190075Sobrien  "#"
58290075Sobrien  "reload_completed"
58390075Sobrien  [(const_int 0)]
58490075Sobrien  "
58590075Sobrien{
58690075Sobrien  rtx in[2], out[2];
58790075Sobrien  int first;
58890075Sobrien
58990075Sobrien  ia64_split_timode (in, operands[1], NULL_RTX);
59090075Sobrien  ia64_split_timode (out, operands[0], NULL_RTX);
59190075Sobrien
59290075Sobrien  first = 0;
59390075Sobrien  if (reg_overlap_mentioned_p (out[0], in[1]))
59490075Sobrien    {
59590075Sobrien      if (reg_overlap_mentioned_p (out[1], in[0]))
59690075Sobrien	abort ();
59790075Sobrien      first = 1;
59890075Sobrien    }
59990075Sobrien
60090075Sobrien  emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
60190075Sobrien  emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
60290075Sobrien  DONE;
60390075Sobrien}"
60490075Sobrien  [(set_attr "itanium_class" "unknown")
60590075Sobrien   (set_attr "predicable" "no")])
60690075Sobrien
60790075Sobrien(define_expand "reload_inti"
60890075Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
60990075Sobrien		   (match_operand:TI 1 "" "m"))
61090075Sobrien	      (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
61190075Sobrien  ""
61290075Sobrien  "
61390075Sobrien{
61490075Sobrien  unsigned int s_regno = REGNO (operands[2]);
61590075Sobrien  if (s_regno == REGNO (operands[0]))
61690075Sobrien    s_regno += 1;
61790075Sobrien  operands[2] = gen_rtx_REG (DImode, s_regno);
61890075Sobrien}")
61990075Sobrien
62090075Sobrien(define_expand "reload_outti"
62190075Sobrien  [(parallel [(set (match_operand:TI 0 "" "=m")
62290075Sobrien		   (match_operand:TI 1 "register_operand" "r"))
62390075Sobrien	      (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
62490075Sobrien  ""
62590075Sobrien  "
62690075Sobrien{
62790075Sobrien  unsigned int s_regno = REGNO (operands[2]);
62890075Sobrien  if (s_regno == REGNO (operands[1]))
62990075Sobrien    s_regno += 1;
63090075Sobrien  operands[2] = gen_rtx_REG (DImode, s_regno);
63190075Sobrien}")
63290075Sobrien
63390075Sobrien;; Floating Point Moves
63490075Sobrien;;
63590075Sobrien;; Note - Patterns for SF mode moves are compulsory, but
63690075Sobrien;; patterns for DF are optional, as GCC can synthesise them.
63790075Sobrien
63890075Sobrien(define_expand "movsf"
63990075Sobrien  [(set (match_operand:SF 0 "general_operand" "")
64090075Sobrien	(match_operand:SF 1 "general_operand" ""))]
64190075Sobrien  ""
64290075Sobrien  "
64390075Sobrien{
64490075Sobrien  if (! reload_in_progress && ! reload_completed
64590075Sobrien      && ! ia64_move_ok (operands[0], operands[1]))
64690075Sobrien    operands[1] = force_reg (SFmode, operands[1]);
64790075Sobrien}")
64890075Sobrien
64990075Sobrien(define_insn "*movsf_internal"
65090075Sobrien  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
65190075Sobrien	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
65290075Sobrien  "ia64_move_ok (operands[0], operands[1])"
65390075Sobrien  "@
65490075Sobrien  mov %0 = %F1
65590075Sobrien  ldfs %0 = %1%P1
65690075Sobrien  stfs %0 = %F1%P0
65790075Sobrien  getf.s %0 = %F1
65890075Sobrien  setf.s %0 = %1
65990075Sobrien  mov %0 = %1
66090075Sobrien  ld4%O1 %0 = %1%P1
66190075Sobrien  st4%Q0 %0 = %1%P0"
66290075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
66390075Sobrien
66490075Sobrien(define_expand "movdf"
66590075Sobrien  [(set (match_operand:DF 0 "general_operand" "")
66690075Sobrien	(match_operand:DF 1 "general_operand" ""))]
66790075Sobrien  ""
66890075Sobrien  "
66990075Sobrien{
67090075Sobrien  if (! reload_in_progress && ! reload_completed
67190075Sobrien      && ! ia64_move_ok (operands[0], operands[1]))
67290075Sobrien    operands[1] = force_reg (DFmode, operands[1]);
67390075Sobrien}")
67490075Sobrien
67590075Sobrien(define_insn "*movdf_internal"
67690075Sobrien  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
67790075Sobrien	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
67890075Sobrien  "ia64_move_ok (operands[0], operands[1])"
67990075Sobrien  "@
68090075Sobrien  mov %0 = %F1
68190075Sobrien  ldfd %0 = %1%P1
68290075Sobrien  stfd %0 = %F1%P0
68390075Sobrien  getf.d %0 = %F1
68490075Sobrien  setf.d %0 = %1
68590075Sobrien  mov %0 = %1
68690075Sobrien  ld8%O1 %0 = %1%P1
68790075Sobrien  st8%Q0 %0 = %1%P0"
68890075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
68990075Sobrien
69090075Sobrien;; With no offsettable memory references, we've got to have a scratch
69190075Sobrien;; around to play with the second word if the variable winds up in GRs.
69290075Sobrien(define_expand "movtf"
69390075Sobrien  [(set (match_operand:TF 0 "general_operand" "")
69490075Sobrien	(match_operand:TF 1 "general_operand" ""))]
69590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
69690075Sobrien  "
69790075Sobrien{
69890075Sobrien  /* We must support TFmode loads into general registers for stdarg/vararg
69990075Sobrien     and unprototyped calls.  We split them into DImode loads for convenience.
70090075Sobrien     We don't need TFmode stores from general regs, because a stdarg/vararg
70190075Sobrien     routine does a block store to memory of unnamed arguments.  */
70290075Sobrien  if (GET_CODE (operands[0]) == REG
70390075Sobrien      && GR_REGNO_P (REGNO (operands[0])))
70490075Sobrien    {
70590075Sobrien      /* We're hoping to transform everything that deals with TFmode
70690075Sobrien	 quantities and GR registers early in the compiler.  */
70790075Sobrien      if (no_new_pseudos)
70890075Sobrien	abort ();
70990075Sobrien
71090075Sobrien      /* Struct to register can just use TImode instead.  */
71190075Sobrien      if ((GET_CODE (operands[1]) == SUBREG
71290075Sobrien	   && GET_MODE (SUBREG_REG (operands[1])) == TImode)
71390075Sobrien	  || (GET_CODE (operands[1]) == REG
71490075Sobrien	      && GR_REGNO_P (REGNO (operands[1]))))
71590075Sobrien	{
71690075Sobrien	  emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
71790075Sobrien			  SUBREG_REG (operands[1]));
71890075Sobrien	  DONE;
71990075Sobrien	}
72090075Sobrien
72190075Sobrien      if (GET_CODE (operands[1]) == CONST_DOUBLE)
72290075Sobrien	{
72390075Sobrien	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
72490075Sobrien			  operand_subword (operands[1], 0, 0, TFmode));
72590075Sobrien	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
72690075Sobrien			  operand_subword (operands[1], 1, 0, TFmode));
72790075Sobrien	  DONE;
72890075Sobrien	}
72990075Sobrien
73090075Sobrien      /* If the quantity is in a register not known to be GR, spill it.  */
73190075Sobrien      if (register_operand (operands[1], TFmode))
73290075Sobrien	operands[1] = spill_tfmode_operand (operands[1], 1);
73390075Sobrien
73490075Sobrien      if (GET_CODE (operands[1]) == MEM)
73590075Sobrien	{
73690075Sobrien	  rtx out[2];
73790075Sobrien
73890075Sobrien	  out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
73990075Sobrien	  out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
74090075Sobrien
74190075Sobrien	  emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
74290075Sobrien	  emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
74390075Sobrien	  DONE;
74490075Sobrien	}
74590075Sobrien
74690075Sobrien      abort ();
74790075Sobrien    }
74890075Sobrien
74990075Sobrien  if (! reload_in_progress && ! reload_completed)
75090075Sobrien    {
75190075Sobrien      operands[0] = spill_tfmode_operand (operands[0], 0);
75290075Sobrien      operands[1] = spill_tfmode_operand (operands[1], 0);
75390075Sobrien
75490075Sobrien      if (! ia64_move_ok (operands[0], operands[1]))
75590075Sobrien	operands[1] = force_reg (TFmode, operands[1]);
75690075Sobrien    }
75790075Sobrien}")
75890075Sobrien
75990075Sobrien;; ??? There's no easy way to mind volatile acquire/release semantics.
76090075Sobrien
76190075Sobrien(define_insn "*movtf_internal"
76290075Sobrien  [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
76390075Sobrien	(match_operand:TF 1 "general_tfmode_operand"     "fG,m,fG"))]
76490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])"
76590075Sobrien  "@
76690075Sobrien  mov %0 = %F1
76790075Sobrien  ldfe %0 = %1%P1
76890075Sobrien  stfe %0 = %F1%P0"
76990075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf")])
77090075Sobrien
77190075Sobrien;; ::::::::::::::::::::
77290075Sobrien;; ::
77390075Sobrien;; :: Conversions
77490075Sobrien;; ::
77590075Sobrien;; ::::::::::::::::::::
77690075Sobrien
77790075Sobrien;; Signed conversions from a smaller integer to a larger integer
77890075Sobrien
77990075Sobrien(define_insn "extendqidi2"
78090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
78190075Sobrien	(sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
78290075Sobrien  ""
78390075Sobrien  "sxt1 %0 = %1"
78490075Sobrien  [(set_attr "itanium_class" "xtd")])
78590075Sobrien
78690075Sobrien(define_insn "extendhidi2"
78790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
78890075Sobrien	(sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
78990075Sobrien  ""
79090075Sobrien  "sxt2 %0 = %1"
79190075Sobrien  [(set_attr "itanium_class" "xtd")])
79290075Sobrien
79390075Sobrien(define_insn "extendsidi2"
79490075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
79590075Sobrien	(sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
79690075Sobrien  ""
79790075Sobrien  "@
79890075Sobrien   sxt4 %0 = %1
79990075Sobrien   fsxt.r %0 = %1, %1"
80090075Sobrien  [(set_attr "itanium_class" "xtd,fmisc")])
80190075Sobrien
80290075Sobrien;; Unsigned conversions from a smaller integer to a larger integer
80390075Sobrien
80490075Sobrien(define_insn "zero_extendqidi2"
80590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
80690075Sobrien	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
80790075Sobrien  ""
80890075Sobrien  "@
80990075Sobrien   zxt1 %0 = %1
81090075Sobrien   ld1%O1 %0 = %1%P1"
81190075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
81290075Sobrien
81390075Sobrien(define_insn "zero_extendhidi2"
81490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
81590075Sobrien	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
81690075Sobrien  ""
81790075Sobrien  "@
81890075Sobrien   zxt2 %0 = %1
81990075Sobrien   ld2%O1 %0 = %1%P1"
82090075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
82190075Sobrien
82290075Sobrien(define_insn "zero_extendsidi2"
82390075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
82490075Sobrien	(zero_extend:DI
82590075Sobrien	  (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
82690075Sobrien  ""
82790075Sobrien  "@
82890075Sobrien   zxt4 %0 = %1
82990075Sobrien   ld4%O1 %0 = %1%P1
83090075Sobrien   fmix.r %0 = f0, %1"
83190075Sobrien  [(set_attr "itanium_class" "xtd,ld,fmisc")])
83290075Sobrien
83390075Sobrien;; Convert between floating point types of different sizes.
83490075Sobrien
83590075Sobrien;; At first glance, it would appear that emitting fnorm for an extending
83690075Sobrien;; conversion is unnecessary.  However, the stf and getf instructions work
83790075Sobrien;; correctly only if the input is properly rounded for its type.  In
83890075Sobrien;; particular, we get the wrong result for getf.d/stfd if the input is a
83990075Sobrien;; denorm single.  Since we don't know what the next instruction will be, we
84090075Sobrien;; have to emit an fnorm.
84190075Sobrien
84290075Sobrien;; ??? Optimization opportunity here.  Get rid of the insn altogether
84390075Sobrien;; when we can.  Should probably use a scheme like has been proposed
84490075Sobrien;; for ia32 in dealing with operands that match unary operators.  This
84590075Sobrien;; would let combine merge the thing into adjacent insns.  See also how the
84690075Sobrien;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
84790075Sobrien;; se_register_operand.
84890075Sobrien
84990075Sobrien(define_insn "extendsfdf2"
85090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
85190075Sobrien	(float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
85290075Sobrien  ""
85390075Sobrien  "fnorm.d %0 = %1"
85490075Sobrien  [(set_attr "itanium_class" "fmac")])
85590075Sobrien
85690075Sobrien(define_insn "extendsftf2"
85790075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
85890075Sobrien	(float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))]
85990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
86090075Sobrien  "fnorm %0 = %1"
86190075Sobrien  [(set_attr "itanium_class" "fmac")])
86290075Sobrien
86390075Sobrien(define_insn "extenddftf2"
86490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
86590075Sobrien	(float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))]
86690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
86790075Sobrien  "fnorm %0 = %1"
86890075Sobrien  [(set_attr "itanium_class" "fmac")])
86990075Sobrien
87090075Sobrien(define_insn "truncdfsf2"
87190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
87290075Sobrien	(float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
87390075Sobrien  ""
87490075Sobrien  "fnorm.s %0 = %1"
87590075Sobrien  [(set_attr "itanium_class" "fmac")])
87690075Sobrien
87790075Sobrien(define_insn "trunctfsf2"
87890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
87990075Sobrien	(float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
88090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
88190075Sobrien  "fnorm.s %0 = %1"
88290075Sobrien  [(set_attr "itanium_class" "fmac")])
88390075Sobrien
88490075Sobrien(define_insn "trunctfdf2"
88590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
88690075Sobrien	(float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
88790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
88890075Sobrien  "fnorm.d %0 = %1"
88990075Sobrien  [(set_attr "itanium_class" "fmac")])
89090075Sobrien
89190075Sobrien;; Convert between signed integer types and floating point.
89290075Sobrien
89390075Sobrien(define_insn "floatditf2"
89490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
89590075Sobrien	(float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
89690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
89790075Sobrien  "fcvt.xf %0 = %1"
89890075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
89990075Sobrien
90090075Sobrien;; ??? Suboptimal.  This should be split somehow.
90190075Sobrien(define_insn "floatdidf2"
90290075Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
90390075Sobrien        (float:DF (match_operand:DI 1 "register_operand" "f")))]
90490075Sobrien  "!INTEL_EXTENDED_IEEE_FORMAT"
90590075Sobrien  "fcvt.xf %0 = %1\;;;\;fnorm.d %0 = %0"
90690075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
90790075Sobrien
90890075Sobrien;; ??? Suboptimal.  This should be split somehow.
90990075Sobrien(define_insn "floatdisf2"
91090075Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
91190075Sobrien        (float:SF (match_operand:DI 1 "register_operand" "f")))]
91290075Sobrien  "!INTEL_EXTENDED_IEEE_FORMAT"
91390075Sobrien  "fcvt.xf %0 = %1\;;;\;fnorm.s %0 = %0"
91490075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
91590075Sobrien
91690075Sobrien(define_insn "fix_truncsfdi2"
91790075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
91890075Sobrien	(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
91990075Sobrien  ""
92090075Sobrien  "fcvt.fx.trunc %0 = %1"
92190075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
92290075Sobrien
92390075Sobrien(define_insn "fix_truncdfdi2"
92490075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
92590075Sobrien	(fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
92690075Sobrien  ""
92790075Sobrien  "fcvt.fx.trunc %0 = %1"
92890075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
92990075Sobrien
93090075Sobrien(define_insn "fix_trunctfdi2"
93190075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
93290075Sobrien	(fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
93390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
93490075Sobrien  "fcvt.fx.trunc %0 = %1"
93590075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
93690075Sobrien
93790075Sobrien(define_insn "fix_trunctfdi2_alts"
93890075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
93990075Sobrien	(fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
94090075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
94190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
94290075Sobrien  "fcvt.fx.trunc.s%2 %0 = %1"
94390075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
94490075Sobrien
94590075Sobrien;; Convert between unsigned integer types and floating point.
94690075Sobrien
94790075Sobrien(define_insn "floatunsdisf2"
94890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
94990075Sobrien	(unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
95090075Sobrien  ""
95190075Sobrien  "fcvt.xuf.s %0 = %1"
95290075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
95390075Sobrien
95490075Sobrien(define_insn "floatunsdidf2"
95590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
95690075Sobrien	(unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
95790075Sobrien  ""
95890075Sobrien  "fcvt.xuf.d %0 = %1"
95990075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
96090075Sobrien
96190075Sobrien(define_insn "floatunsditf2"
96290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
96390075Sobrien	(unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
96490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
96590075Sobrien  "fcvt.xuf %0 = %1"
96690075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
96790075Sobrien
96890075Sobrien(define_insn "fixuns_truncsfdi2"
96990075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
97090075Sobrien	(unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
97190075Sobrien  ""
97290075Sobrien  "fcvt.fxu.trunc %0 = %1"
97390075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
97490075Sobrien
97590075Sobrien(define_insn "fixuns_truncdfdi2"
97690075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
97790075Sobrien	(unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
97890075Sobrien  ""
97990075Sobrien  "fcvt.fxu.trunc %0 = %1"
98090075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
98190075Sobrien
98290075Sobrien(define_insn "fixuns_trunctfdi2"
98390075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
98490075Sobrien	(unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
98590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
98690075Sobrien  "fcvt.fxu.trunc %0 = %1"
98790075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
98890075Sobrien
98990075Sobrien(define_insn "fixuns_trunctfdi2_alts"
99090075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
99190075Sobrien	(unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
99290075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
99390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
99490075Sobrien  "fcvt.fxu.trunc.s%2 %0 = %1"
99590075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
99690075Sobrien
99790075Sobrien;; ::::::::::::::::::::
99890075Sobrien;; ::
99990075Sobrien;; :: Bit field extraction
100090075Sobrien;; ::
100190075Sobrien;; ::::::::::::::::::::
100290075Sobrien
100390075Sobrien(define_insn "extv"
100490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
100590075Sobrien	(sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
100690075Sobrien			 (match_operand:DI 2 "const_int_operand" "n")
100790075Sobrien			 (match_operand:DI 3 "const_int_operand" "n")))]
100890075Sobrien  ""
100990075Sobrien  "extr %0 = %1, %3, %2"
101090075Sobrien  [(set_attr "itanium_class" "ishf")])
101190075Sobrien
101290075Sobrien(define_insn "extzv"
101390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
101490075Sobrien	(zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
101590075Sobrien			 (match_operand:DI 2 "const_int_operand" "n")
101690075Sobrien			 (match_operand:DI 3 "const_int_operand" "n")))]
101790075Sobrien  ""
101890075Sobrien  "extr.u %0 = %1, %3, %2"
101990075Sobrien  [(set_attr "itanium_class" "ishf")])
102090075Sobrien
102190075Sobrien;; Insert a bit field.
102290075Sobrien;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
102390075Sobrien;; Source1 can be 0 or -1.
102490075Sobrien;; Source2 can be 0.
102590075Sobrien
102690075Sobrien;; ??? Actual dep instruction is more powerful than what these insv
102790075Sobrien;; patterns support.  Unfortunately, combine is unable to create patterns
102890075Sobrien;; where source2 != dest.
102990075Sobrien
103090075Sobrien(define_expand "insv"
103190075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
103290075Sobrien			 (match_operand:DI 1 "const_int_operand" "")
103390075Sobrien			 (match_operand:DI 2 "const_int_operand" ""))
103490075Sobrien	(match_operand:DI 3 "nonmemory_operand" ""))]
103590075Sobrien  ""
103690075Sobrien  "
103790075Sobrien{
103890075Sobrien  int width = INTVAL (operands[1]);
103990075Sobrien  int shift = INTVAL (operands[2]);
104090075Sobrien
104190075Sobrien  /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
104290075Sobrien     pseudo.  */
104390075Sobrien  if (! register_operand (operands[3], DImode)
104490075Sobrien      && operands[3] != const0_rtx && operands[3] != constm1_rtx)
104590075Sobrien    operands[3] = force_reg (DImode, operands[3]);
104690075Sobrien
104790075Sobrien  /* If this is a single dep instruction, we have nothing to do.  */
104890075Sobrien  if (! ((register_operand (operands[3], DImode) && width <= 16)
104990075Sobrien	 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
105090075Sobrien    {
105190075Sobrien      /* Check for cases that can be implemented with a mix instruction.  */
105290075Sobrien      if (width == 32 && shift == 0)
105390075Sobrien	{
105490075Sobrien	  /* Directly generating the mix4left instruction confuses
105590075Sobrien	     optimize_bit_field in function.c.  Since this is performing
105690075Sobrien	     a useful optimization, we defer generation of the complicated
105790075Sobrien	     mix4left RTL to the first splitting phase.  */
105890075Sobrien	  rtx tmp = gen_reg_rtx (DImode);
105990075Sobrien	  emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
106090075Sobrien	  DONE;
106190075Sobrien	}
106290075Sobrien      else if (width == 32 && shift == 32)
106390075Sobrien	{
106490075Sobrien	  emit_insn (gen_mix4right (operands[0], operands[3]));
106590075Sobrien	  DONE;
106690075Sobrien	}
106790075Sobrien
106890075Sobrien      /* We could handle remaining cases by emitting multiple dep
106990075Sobrien	 instructions.
107090075Sobrien
107190075Sobrien	 If we need more than two dep instructions then we lose.  A 6
107290075Sobrien	 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
107390075Sobrien	 mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,
107490075Sobrien	 the latter is 6 cycles on an Itanium (TM) processor, because there is
107590075Sobrien	 only one function unit that can execute dep and shr immed.
107690075Sobrien
107790075Sobrien	 If we only need two dep instruction, then we still lose.
107890075Sobrien	 mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away
107990075Sobrien	 the unnecessary mov, this is still undesirable because it will be
108090075Sobrien	 hard to optimize, and it creates unnecessary pressure on the I0
108190075Sobrien	 function unit.  */
108290075Sobrien
108390075Sobrien      FAIL;
108490075Sobrien
108590075Sobrien#if 0
108690075Sobrien      /* This code may be useful for other IA-64 processors, so we leave it in
108790075Sobrien	 for now.  */
108890075Sobrien      while (width > 16)
108990075Sobrien	{
109090075Sobrien	  rtx tmp;
109190075Sobrien
109290075Sobrien	  emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
109390075Sobrien			       operands[3]));
109490075Sobrien	  shift += 16;
109590075Sobrien	  width -= 16;
109690075Sobrien	  tmp = gen_reg_rtx (DImode);
109790075Sobrien	  emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
109890075Sobrien	  operands[3] = tmp;
109990075Sobrien	}
110090075Sobrien      operands[1] = GEN_INT (width);
110190075Sobrien      operands[2] = GEN_INT (shift);
110290075Sobrien#endif
110390075Sobrien    }
110490075Sobrien}")
110590075Sobrien
110690075Sobrien(define_insn "*insv_internal"
110790075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
110890075Sobrien			 (match_operand:DI 1 "const_int_operand" "n")
110990075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
111090075Sobrien	(match_operand:DI 3 "nonmemory_operand" "rP"))]
111190075Sobrien  "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
111290075Sobrien   || operands[3] == const0_rtx || operands[3] == constm1_rtx"
111390075Sobrien  "dep %0 = %3, %0, %2, %1"
111490075Sobrien  [(set_attr "itanium_class" "ishf")])
111590075Sobrien
111690075Sobrien;; Combine doesn't like to create bitfield insertions into zero.
111790075Sobrien(define_insn "*depz_internal"
111890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
111990075Sobrien	(and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
112090075Sobrien			   (match_operand:DI 2 "const_int_operand" "n"))
112190075Sobrien		(match_operand:DI 3 "const_int_operand" "n")))]
112290075Sobrien  "CONST_OK_FOR_M (INTVAL (operands[2]))
112390075Sobrien   && ia64_depz_field_mask (operands[3], operands[2]) > 0"
112490075Sobrien  "*
112590075Sobrien{
112690075Sobrien  operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
112790075Sobrien  return \"%,dep.z %0 = %1, %2, %3\";
112890075Sobrien}"
112990075Sobrien  [(set_attr "itanium_class" "ishf")])
113090075Sobrien
113190075Sobrien(define_insn "shift_mix4left"
113290075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
113390075Sobrien			 (const_int 32) (const_int 0))
113490075Sobrien	(match_operand:DI 1 "gr_register_operand" "r"))
113590075Sobrien   (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
113690075Sobrien  ""
113790075Sobrien  "#"
113890075Sobrien  [(set_attr "itanium_class" "unknown")])
113990075Sobrien
114090075Sobrien(define_split
114190075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
114290075Sobrien			 (const_int 32) (const_int 0))
114390075Sobrien	(match_operand:DI 1 "register_operand" ""))
114490075Sobrien   (clobber (match_operand:DI 2 "register_operand" ""))]
114590075Sobrien  "reload_completed"
114690075Sobrien  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
114790075Sobrien   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
114890075Sobrien	(lshiftrt:DI (match_dup 3) (const_int 32)))]
114990075Sobrien  "operands[3] = operands[2];")
115090075Sobrien
115190075Sobrien(define_split
115290075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
115390075Sobrien			 (const_int 32) (const_int 0))
115490075Sobrien	(match_operand:DI 1 "register_operand" ""))
115590075Sobrien   (clobber (match_operand:DI 2 "register_operand" ""))]
115690075Sobrien  "! reload_completed"
115790075Sobrien  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
115890075Sobrien   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
115990075Sobrien	(lshiftrt:DI (match_dup 3) (const_int 32)))]
116090075Sobrien  "operands[3] = operands[2];")
116190075Sobrien
116290075Sobrien(define_insn "*mix4left"
116390075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
116490075Sobrien			 (const_int 32) (const_int 0))
116590075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
116690075Sobrien		     (const_int 32)))]
116790075Sobrien  ""
116890075Sobrien  "mix4.l %0 = %0, %r1"
116990075Sobrien  [(set_attr "itanium_class" "mmshf")])
117090075Sobrien
117190075Sobrien(define_insn "mix4right"
117290075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
117390075Sobrien			 (const_int 32) (const_int 32))
117490075Sobrien	(match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
117590075Sobrien  ""
117690075Sobrien  "mix4.r %0 = %r1, %0"
117790075Sobrien  [(set_attr "itanium_class" "mmshf")])
117890075Sobrien
117990075Sobrien;; This is used by the rotrsi3 pattern.
118090075Sobrien
118190075Sobrien(define_insn "*mix4right_3op"
118290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
118390075Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
118490075Sobrien		(ashift:DI (zero_extend:DI
118590075Sobrien			     (match_operand:SI 2 "gr_register_operand" "r"))
118690075Sobrien			   (const_int 32))))]
118790075Sobrien  ""
118890075Sobrien  "mix4.r %0 = %2, %1"
118990075Sobrien  [(set_attr "itanium_class" "mmshf")])
119090075Sobrien
119190075Sobrien
119290075Sobrien;; ::::::::::::::::::::
119390075Sobrien;; ::
119490075Sobrien;; :: 1 bit Integer arithmetic
119590075Sobrien;; ::
119690075Sobrien;; ::::::::::::::::::::
119790075Sobrien
119890075Sobrien(define_insn_and_split "andbi3"
119990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
120090075Sobrien	(and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
120190075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
120290075Sobrien  ""
120390075Sobrien  "@
120490075Sobrien   #
120590075Sobrien   tbit.nz.and.orcm %0, %I0 = %2, 0
120690075Sobrien   and %0 = %2, %1"
120790075Sobrien  "reload_completed
120890075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
120990075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
121090075Sobrien  [(cond_exec (eq (match_dup 2) (const_int 0))
121190075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
121290075Sobrien				(match_dup 0))))]
121390075Sobrien  ""
121490075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
121590075Sobrien
121690075Sobrien(define_insn_and_split "*andcmbi3"
121790075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
121890075Sobrien	(and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
121990075Sobrien		(match_operand:BI 2 "register_operand" "0,0,r")))]
122090075Sobrien  ""
122190075Sobrien  "@
122290075Sobrien   #
122390075Sobrien   tbit.z.and.orcm %0, %I0 = %1, 0
122490075Sobrien   andcm %0 = %2, %1"
122590075Sobrien  "reload_completed
122690075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
122790075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
122890075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
122990075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
123090075Sobrien				(match_dup 0))))]
123190075Sobrien  ""
123290075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
123390075Sobrien
123490075Sobrien(define_insn_and_split "iorbi3"
123590075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
123690075Sobrien	(ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
123790075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
123890075Sobrien  ""
123990075Sobrien  "@
124090075Sobrien   #
124190075Sobrien   tbit.nz.or.andcm %0, %I0 = %2, 0
124290075Sobrien   or %0 = %2, %1"
124390075Sobrien  "reload_completed
124490075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
124590075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
124690075Sobrien  [(cond_exec (ne (match_dup 2) (const_int 0))
124790075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
124890075Sobrien				(match_dup 0))))]
124990075Sobrien  ""
125090075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
125190075Sobrien
125290075Sobrien(define_insn_and_split "*iorcmbi3"
125390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c")
125490075Sobrien	(ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
125590075Sobrien		(match_operand:BI 2 "register_operand" "0,0")))]
125690075Sobrien  ""
125790075Sobrien  "@
125890075Sobrien   #
125990075Sobrien   tbit.z.or.andcm %0, %I0 = %1, 0"
126090075Sobrien  "reload_completed
126190075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
126290075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
126390075Sobrien  [(cond_exec (eq (match_dup 1) (const_int 0))
126490075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
126590075Sobrien				(match_dup 0))))]
126690075Sobrien  ""
126790075Sobrien  [(set_attr "itanium_class" "unknown,tbit")])
126890075Sobrien
126990075Sobrien(define_insn "one_cmplbi2"
127090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
127190075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
127290075Sobrien   (clobber (match_scratch:BI 2 "=X,X,c,X"))]
127390075Sobrien  ""
127490075Sobrien  "@
127590075Sobrien   tbit.z %0, %I0 = %1, 0
127690075Sobrien   xor %0 = 1, %1
127790075Sobrien   #
127890075Sobrien   #"
127990075Sobrien  [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
128090075Sobrien
128190075Sobrien(define_split
128290075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
128390075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
128490075Sobrien   (clobber (match_scratch:BI 2 ""))]
128590075Sobrien  "reload_completed
128690075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
128790075Sobrien   && rtx_equal_p (operands[0], operands[1])"
128890075Sobrien  [(set (match_dup 4) (match_dup 3))
128990075Sobrien   (set (match_dup 0) (const_int 1))
129090075Sobrien   (cond_exec (ne (match_dup 2) (const_int 0))
129190075Sobrien     (set (match_dup 0) (const_int 0)))
129290075Sobrien   (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
129390075Sobrien  "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
129490075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
129590075Sobrien
129690075Sobrien(define_split
129790075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
129890075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
129990075Sobrien   (clobber (match_scratch:BI 2 ""))]
130090075Sobrien  "reload_completed
130190075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
130290075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
130390075Sobrien   && ! rtx_equal_p (operands[0], operands[1])"
130490075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
130590075Sobrien     (set (match_dup 0) (const_int 0)))
130690075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
130790075Sobrien     (set (match_dup 0) (const_int 1)))
130890075Sobrien   (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
130990075Sobrien  "")
131090075Sobrien
131190075Sobrien(define_insn "*cmpsi_and_0"
131290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
131390075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
131490075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
131590075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
131690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
131790075Sobrien  ""
131890075Sobrien  "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
131990075Sobrien  [(set_attr "itanium_class" "icmp")])
132090075Sobrien
132190075Sobrien(define_insn "*cmpsi_and_1"
132290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
132390075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
132490075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
132590075Sobrien		   (const_int 0)])
132690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
132790075Sobrien  ""
132890075Sobrien  "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
132990075Sobrien  [(set_attr "itanium_class" "icmp")])
133090075Sobrien
133190075Sobrien(define_insn "*cmpsi_andnot_0"
133290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
133390075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
133490075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
133590075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
133690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
133790075Sobrien  ""
133890075Sobrien  "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
133990075Sobrien  [(set_attr "itanium_class" "icmp")])
134090075Sobrien
134190075Sobrien(define_insn "*cmpsi_andnot_1"
134290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
134390075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
134490075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
134590075Sobrien			   (const_int 0)]))
134690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
134790075Sobrien  ""
134890075Sobrien  "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
134990075Sobrien  [(set_attr "itanium_class" "icmp")])
135090075Sobrien
135190075Sobrien(define_insn "*cmpdi_and_0"
135290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
135390075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
135490075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
135590075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
135690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
135790075Sobrien  ""
135890075Sobrien  "cmp.%C4.and.orcm %0, %I0 = %3, %2"
135990075Sobrien  [(set_attr "itanium_class" "icmp")])
136090075Sobrien
136190075Sobrien(define_insn "*cmpdi_and_1"
136290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
136390075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
136490075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
136590075Sobrien		   (const_int 0)])
136690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
136790075Sobrien  ""
136890075Sobrien  "cmp.%C3.and.orcm %0, %I0 = r0, %2"
136990075Sobrien  [(set_attr "itanium_class" "icmp")])
137090075Sobrien
137190075Sobrien(define_insn "*cmpdi_andnot_0"
137290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
137390075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
137490075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
137590075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
137690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
137790075Sobrien  ""
137890075Sobrien  "cmp.%C4.or.andcm %I0, %0 = %3, %2"
137990075Sobrien  [(set_attr "itanium_class" "icmp")])
138090075Sobrien
138190075Sobrien(define_insn "*cmpdi_andnot_1"
138290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
138390075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
138490075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
138590075Sobrien			   (const_int 0)]))
138690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
138790075Sobrien  ""
138890075Sobrien  "cmp.%C3.or.andcm %I0, %0 = r0, %2"
138990075Sobrien  [(set_attr "itanium_class" "icmp")])
139090075Sobrien
139190075Sobrien(define_insn "*tbit_and_0"
139290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
139390075Sobrien	(and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
139490075Sobrien			       (const_int 1))
139590075Sobrien		       (const_int 0))
139690075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
139790075Sobrien  ""
139890075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, 0"
139990075Sobrien  [(set_attr "itanium_class" "tbit")])
140090075Sobrien
140190075Sobrien(define_insn "*tbit_and_1"
140290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
140390075Sobrien	(and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
140490075Sobrien			       (const_int 1))
140590075Sobrien		       (const_int 0))
140690075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
140790075Sobrien  ""
140890075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, 0"
140990075Sobrien  [(set_attr "itanium_class" "tbit")])
141090075Sobrien
141190075Sobrien(define_insn "*tbit_and_2"
141290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
141390075Sobrien	(and:BI (ne:BI (zero_extract:DI
141490075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
141590075Sobrien			 (const_int 1)
141690075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
141790075Sobrien		       (const_int 0))
141890075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
141990075Sobrien  ""
142090075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, %2"
142190075Sobrien  [(set_attr "itanium_class" "tbit")])
142290075Sobrien
142390075Sobrien(define_insn "*tbit_and_3"
142490075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
142590075Sobrien	(and:BI (eq:BI (zero_extract:DI
142690075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
142790075Sobrien			 (const_int 1)
142890075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
142990075Sobrien		       (const_int 0))
143090075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
143190075Sobrien  ""
143290075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, %2"
143390075Sobrien  [(set_attr "itanium_class" "tbit")])
143490075Sobrien
143590075Sobrien(define_insn "*cmpsi_or_0"
143690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
143790075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
143890075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
143990075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
144090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
144190075Sobrien  ""
144290075Sobrien  "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
144390075Sobrien  [(set_attr "itanium_class" "icmp")])
144490075Sobrien
144590075Sobrien(define_insn "*cmpsi_or_1"
144690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
144790075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
144890075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
144990075Sobrien		   (const_int 0)])
145090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
145190075Sobrien  ""
145290075Sobrien  "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
145390075Sobrien  [(set_attr "itanium_class" "icmp")])
145490075Sobrien
145590075Sobrien(define_insn "*cmpsi_orcm_0"
145690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
145790075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
145890075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
145990075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
146090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
146190075Sobrien  ""
146290075Sobrien  "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
146390075Sobrien  [(set_attr "itanium_class" "icmp")])
146490075Sobrien
146590075Sobrien(define_insn "*cmpsi_orcm_1"
146690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
146790075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
146890075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
146990075Sobrien			   (const_int 0)]))
147090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
147190075Sobrien  ""
147290075Sobrien  "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
147390075Sobrien  [(set_attr "itanium_class" "icmp")])
147490075Sobrien
147590075Sobrien(define_insn "*cmpdi_or_0"
147690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
147790075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
147890075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
147990075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
148090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
148190075Sobrien  ""
148290075Sobrien  "cmp.%C4.or.andcm %0, %I0 = %3, %2"
148390075Sobrien  [(set_attr "itanium_class" "icmp")])
148490075Sobrien
148590075Sobrien(define_insn "*cmpdi_or_1"
148690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
148790075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
148890075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
148990075Sobrien		   (const_int 0)])
149090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
149190075Sobrien  ""
149290075Sobrien  "cmp.%C3.or.andcm %0, %I0 = r0, %2"
149390075Sobrien  [(set_attr "itanium_class" "icmp")])
149490075Sobrien
149590075Sobrien(define_insn "*cmpdi_orcm_0"
149690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
149790075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
149890075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
149990075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
150090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
150190075Sobrien  ""
150290075Sobrien  "cmp.%C4.and.orcm %I0, %0 = %3, %2"
150390075Sobrien  [(set_attr "itanium_class" "icmp")])
150490075Sobrien
150590075Sobrien(define_insn "*cmpdi_orcm_1"
150690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
150790075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
150890075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
150990075Sobrien			   (const_int 0)]))
151090075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
151190075Sobrien  ""
151290075Sobrien  "cmp.%C3.and.orcm %I0, %0 = r0, %2"
151390075Sobrien  [(set_attr "itanium_class" "icmp")])
151490075Sobrien
151590075Sobrien(define_insn "*tbit_or_0"
151690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
151790075Sobrien	(ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
151890075Sobrien			       (const_int 1))
151990075Sobrien		       (const_int 0))
152090075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
152190075Sobrien  ""
152290075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, 0"
152390075Sobrien  [(set_attr "itanium_class" "tbit")])
152490075Sobrien
152590075Sobrien(define_insn "*tbit_or_1"
152690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
152790075Sobrien	(ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
152890075Sobrien			       (const_int 1))
152990075Sobrien		       (const_int 0))
153090075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
153190075Sobrien  ""
153290075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, 0"
153390075Sobrien  [(set_attr "itanium_class" "tbit")])
153490075Sobrien
153590075Sobrien(define_insn "*tbit_or_2"
153690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
153790075Sobrien	(ior:BI (ne:BI (zero_extract:DI
153890075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
153990075Sobrien			 (const_int 1)
154090075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
154190075Sobrien		       (const_int 0))
154290075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
154390075Sobrien  ""
154490075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, %2"
154590075Sobrien  [(set_attr "itanium_class" "tbit")])
154690075Sobrien
154790075Sobrien(define_insn "*tbit_or_3"
154890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
154990075Sobrien	(ior:BI (eq:BI (zero_extract:DI
155090075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
155190075Sobrien			 (const_int 1)
155290075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
155390075Sobrien		       (const_int 0))
155490075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
155590075Sobrien  ""
155690075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, %2"
155790075Sobrien  [(set_attr "itanium_class" "tbit")])
155890075Sobrien
155990075Sobrien;; Transform test of and/or of setcc into parallel comparisons.
156090075Sobrien
156190075Sobrien(define_split
156290075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
156390075Sobrien	(ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
156490075Sobrien			      (const_int 0))
156590075Sobrien		       (match_operand:DI 3 "register_operand" ""))
156690075Sobrien	       (const_int 0)))]
156790075Sobrien  ""
156890075Sobrien  [(set (match_dup 0)
156990075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
157090075Sobrien		(match_dup 2)))]
157190075Sobrien  "")
157290075Sobrien
157390075Sobrien(define_split
157490075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
157590075Sobrien	(eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
157690075Sobrien			      (const_int 0))
157790075Sobrien		       (match_operand:DI 3 "register_operand" ""))
157890075Sobrien	       (const_int 0)))]
157990075Sobrien  ""
158090075Sobrien  [(set (match_dup 0)
158190075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
158290075Sobrien		(match_dup 2)))
158390075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
158490075Sobrien	      (clobber (scratch))])]
158590075Sobrien  "")
158690075Sobrien
158790075Sobrien(define_split
158890075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
158990075Sobrien	(ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
159090075Sobrien			      (const_int 0))
159190075Sobrien		       (match_operand:DI 3 "register_operand" ""))
159290075Sobrien	       (const_int 0)))]
159390075Sobrien  ""
159490075Sobrien  [(set (match_dup 0) 
159590075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
159690075Sobrien		(match_dup 2)))]
159790075Sobrien  "")
159890075Sobrien
159990075Sobrien(define_split
160090075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
160190075Sobrien	(eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
160290075Sobrien			      (const_int 0))
160390075Sobrien		       (match_operand:DI 3 "register_operand" ""))
160490075Sobrien	       (const_int 0)))]
160590075Sobrien  ""
160690075Sobrien  [(set (match_dup 0) 
160790075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
160890075Sobrien		(match_dup 2)))
160990075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
161090075Sobrien	      (clobber (scratch))])]
161190075Sobrien  "")
161290075Sobrien
161390075Sobrien;; ??? Incredibly hackish.  Either need four proper patterns with all
161490075Sobrien;; the alternatives, or rely on sched1 to split the insn and hope that
161590075Sobrien;; nothing bad happens to the comparisons in the meantime.
161690075Sobrien;;
161790075Sobrien;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
161890075Sobrien;; that we're doing height reduction.
161990075Sobrien;
162090075Sobrien;(define_insn_and_split ""
162190075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
162290075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
162390075Sobrien;			  [(match_operand 2 "" "")
162490075Sobrien;			   (match_operand 3 "" "")])
162590075Sobrien;			(match_operator:BI 4 "comparison_operator"
162690075Sobrien;			  [(match_operand 5 "" "")
162790075Sobrien;			   (match_operand 6 "" "")]))
162890075Sobrien;		(match_dup 0)))]
162990075Sobrien;  "flag_schedule_insns"
163090075Sobrien;  "#"
163190075Sobrien;  ""
163290075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
163390075Sobrien;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
163490075Sobrien;  "")
163590075Sobrien;
163690075Sobrien;(define_insn_and_split ""
163790075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
163890075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
163990075Sobrien;			  [(match_operand 2 "" "")
164090075Sobrien;			   (match_operand 3 "" "")])
164190075Sobrien;			(match_operator:BI 4 "comparison_operator"
164290075Sobrien;			  [(match_operand 5 "" "")
164390075Sobrien;			   (match_operand 6 "" "")]))
164490075Sobrien;		(match_dup 0)))]
164590075Sobrien;  "flag_schedule_insns"
164690075Sobrien;  "#"
164790075Sobrien;  ""
164890075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
164990075Sobrien;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
165090075Sobrien;  "")
165190075Sobrien;
165290075Sobrien;(define_split
165390075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
165490075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
165590075Sobrien;			  [(match_operand 2 "" "")
165690075Sobrien;			   (match_operand 3 "" "")])
165790075Sobrien;			(match_operand:BI 7 "register_operand" ""))
165890075Sobrien;		(and:BI (match_operator:BI 4 "comparison_operator"
165990075Sobrien;			  [(match_operand 5 "" "")
166090075Sobrien;			   (match_operand 6 "" "")])
166190075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
166290075Sobrien;  ""
166390075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
166490075Sobrien;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
166590075Sobrien;			      (match_dup 0)))]
166690075Sobrien;  "")
166790075Sobrien;
166890075Sobrien;(define_split
166990075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
167090075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
167190075Sobrien;			  [(match_operand 2 "" "")
167290075Sobrien;			   (match_operand 3 "" "")])
167390075Sobrien;			(match_operand:BI 7 "register_operand" ""))
167490075Sobrien;		(ior:BI (match_operator:BI 4 "comparison_operator"
167590075Sobrien;			  [(match_operand 5 "" "")
167690075Sobrien;			   (match_operand 6 "" "")])
167790075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
167890075Sobrien;  ""
167990075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
168090075Sobrien;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
168190075Sobrien;			      (match_dup 0)))]
168290075Sobrien;  "")
168390075Sobrien
168490075Sobrien;; Try harder to avoid predicate copies by duplicating compares.
168590075Sobrien;; Note that we'll have already split the predicate copy, which
168690075Sobrien;; is kind of a pain, but oh well.
168790075Sobrien
168890075Sobrien(define_peephole2
168990075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
169090075Sobrien	(match_operand:BI 1 "comparison_operator" ""))
169190075Sobrien   (set (match_operand:CCI 2 "register_operand" "")
169290075Sobrien	(match_operand:CCI 3 "register_operand" ""))
169390075Sobrien   (set (match_operand:CCI 4 "register_operand" "")
169490075Sobrien	(match_operand:CCI 5 "register_operand" ""))
169590075Sobrien   (set (match_operand:BI 6 "register_operand" "")
169690075Sobrien	(unspec:BI [(match_dup 6)] 7))]
169790075Sobrien  "REGNO (operands[3]) == REGNO (operands[0])
169890075Sobrien   && REGNO (operands[4]) == REGNO (operands[0]) + 1
169990075Sobrien   && REGNO (operands[4]) == REGNO (operands[2]) + 1
170090075Sobrien   && REGNO (operands[6]) == REGNO (operands[2])"
170190075Sobrien  [(set (match_dup 0) (match_dup 1))
170290075Sobrien   (set (match_dup 6) (match_dup 7))]
170390075Sobrien  "operands[7] = copy_rtx (operands[1]);")
170490075Sobrien
170590075Sobrien;; ::::::::::::::::::::
170690075Sobrien;; ::
170790075Sobrien;; :: 16 bit Integer arithmetic
170890075Sobrien;; ::
170990075Sobrien;; ::::::::::::::::::::
171090075Sobrien
171190075Sobrien(define_insn "mulhi3"
171290075Sobrien  [(set (match_operand:HI 0 "gr_register_operand" "=r")
171390075Sobrien	(mult:HI (match_operand:HI 1 "gr_register_operand" "r")
171490075Sobrien		 (match_operand:HI 2 "gr_register_operand" "r")))]
171590075Sobrien  ""
171690075Sobrien  "pmpy2.r %0 = %1, %2"
171790075Sobrien  [(set_attr "itanium_class" "mmmul")])
171890075Sobrien
171990075Sobrien
172090075Sobrien;; ::::::::::::::::::::
172190075Sobrien;; ::
172290075Sobrien;; :: 32 bit Integer arithmetic
172390075Sobrien;; ::
172490075Sobrien;; ::::::::::::::::::::
172590075Sobrien
172690075Sobrien(define_insn "addsi3"
172790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
172890075Sobrien	(plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
172990075Sobrien		 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
173090075Sobrien  ""
173190075Sobrien  "@
173290075Sobrien  add %0 = %1, %2
173390075Sobrien  adds %0 = %2, %1
173490075Sobrien  addl %0 = %2, %1"
173590075Sobrien  [(set_attr "itanium_class" "ialu")])
173690075Sobrien
173790075Sobrien(define_insn "*addsi3_plus1"
173890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
173990075Sobrien	(plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
174090075Sobrien			  (match_operand:SI 2 "gr_register_operand" "r"))
174190075Sobrien		 (const_int 1)))]
174290075Sobrien  ""
174390075Sobrien  "add %0 = %1, %2, 1"
174490075Sobrien  [(set_attr "itanium_class" "ialu")])
174590075Sobrien
174690075Sobrien(define_insn "*addsi3_plus1_alt"
174790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
174890075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
174990075Sobrien			  (const_int 2))
175090075Sobrien		 (const_int 1)))]
175190075Sobrien  ""
175290075Sobrien  "add %0 = %1, %1, 1"
175390075Sobrien  [(set_attr "itanium_class" "ialu")])
175490075Sobrien
175590075Sobrien(define_insn "*addsi3_shladd"
175690075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
175790075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
175890075Sobrien			  (match_operand:SI 2 "shladd_operand" "n"))
175990075Sobrien		 (match_operand:SI 3 "gr_register_operand" "r")))]
176090075Sobrien  ""
176190075Sobrien  "shladd %0 = %1, %S2, %3"
176290075Sobrien  [(set_attr "itanium_class" "ialu")])
176390075Sobrien
176490075Sobrien(define_insn "subsi3"
176590075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
176690075Sobrien	(minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
176790075Sobrien		  (match_operand:SI 2 "gr_register_operand" "r")))]
176890075Sobrien  ""
176990075Sobrien  "sub %0 = %1, %2"
177090075Sobrien  [(set_attr "itanium_class" "ialu")])
177190075Sobrien
177290075Sobrien(define_insn "*subsi3_minus1"
177390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
177490075Sobrien	(plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
177590075Sobrien		 (match_operand:SI 2 "gr_register_operand" "r")))]
177690075Sobrien  ""
177790075Sobrien  "sub %0 = %2, %1, 1"
177890075Sobrien  [(set_attr "itanium_class" "ialu")])
177990075Sobrien
178090075Sobrien;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
178190075Sobrien
178290075Sobrien(define_insn "mulsi3"
178390075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
178490075Sobrien	(mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
178590075Sobrien		 (match_operand:SI 2 "grfr_register_operand" "f")))]
178690075Sobrien  ""
178790075Sobrien  "xmpy.l %0 = %1, %2"
178890075Sobrien  [(set_attr "itanium_class" "xmpy")])
178990075Sobrien
179090075Sobrien(define_insn "maddsi4"
179190075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
179290075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
179390075Sobrien			  (match_operand:SI 2 "grfr_register_operand" "f"))
179490075Sobrien		 (match_operand:SI 3 "grfr_register_operand" "f")))]
179590075Sobrien  ""
179690075Sobrien  "xma.l %0 = %1, %2, %3"
179790075Sobrien  [(set_attr "itanium_class" "xmpy")])
179890075Sobrien
179990075Sobrien(define_insn "negsi2"
180090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
180190075Sobrien	(neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
180290075Sobrien  ""
180390075Sobrien  "sub %0 = r0, %1"
180490075Sobrien  [(set_attr "itanium_class" "ialu")])
180590075Sobrien
180690075Sobrien(define_expand "abssi2"
180790075Sobrien  [(set (match_dup 2)
180890075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
180990075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
181090075Sobrien	(if_then_else:SI (eq (match_dup 2) (const_int 0))
181190075Sobrien			 (neg:SI (match_dup 1))
181290075Sobrien			 (match_dup 1)))]
181390075Sobrien  ""
181490075Sobrien  "
181590075Sobrien{
181690075Sobrien  operands[2] = gen_reg_rtx (BImode);
181790075Sobrien}")
181890075Sobrien
181990075Sobrien(define_expand "sminsi3"
182090075Sobrien  [(set (match_dup 3)
182190075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
182290075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
182390075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
182490075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
182590075Sobrien			 (match_dup 2) (match_dup 1)))]
182690075Sobrien  ""
182790075Sobrien  "
182890075Sobrien{
182990075Sobrien  operands[3] = gen_reg_rtx (BImode);
183090075Sobrien}")
183190075Sobrien
183290075Sobrien(define_expand "smaxsi3"
183390075Sobrien  [(set (match_dup 3)
183490075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
183590075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
183690075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
183790075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
183890075Sobrien			 (match_dup 1) (match_dup 2)))]
183990075Sobrien  ""
184090075Sobrien  "
184190075Sobrien{
184290075Sobrien  operands[3] = gen_reg_rtx (BImode);
184390075Sobrien}")
184490075Sobrien
184590075Sobrien(define_expand "uminsi3"
184690075Sobrien  [(set (match_dup 3)
184790075Sobrien	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
184890075Sobrien		(match_operand:SI 2 "gr_register_operand" "")))
184990075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
185090075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
185190075Sobrien			 (match_dup 2) (match_dup 1)))]
185290075Sobrien  ""
185390075Sobrien  "
185490075Sobrien{
185590075Sobrien  operands[3] = gen_reg_rtx (BImode);
185690075Sobrien}")
185790075Sobrien
185890075Sobrien(define_expand "umaxsi3"
185990075Sobrien  [(set (match_dup 3)
186090075Sobrien	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
186190075Sobrien		(match_operand:SI 2 "gr_register_operand" "")))
186290075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
186390075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
186490075Sobrien			 (match_dup 1) (match_dup 2)))]
186590075Sobrien  ""
186690075Sobrien  "
186790075Sobrien{
186890075Sobrien  operands[3] = gen_reg_rtx (BImode);
186990075Sobrien}")
187090075Sobrien
187190075Sobrien(define_expand "divsi3"
187290075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
187390075Sobrien	(div:SI (match_operand:SI 1 "general_operand" "")
187490075Sobrien		(match_operand:SI 2 "general_operand" "")))]
187590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
187690075Sobrien  "
187790075Sobrien{
187890075Sobrien  rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
187990075Sobrien
188090075Sobrien  op0_tf = gen_reg_rtx (TFmode);
188190075Sobrien  op0_di = gen_reg_rtx (DImode);
188290075Sobrien
188390075Sobrien  if (CONSTANT_P (operands[1]))
188490075Sobrien    operands[1] = force_reg (SImode, operands[1]);
188590075Sobrien  op1_tf = gen_reg_rtx (TFmode);
188690075Sobrien  expand_float (op1_tf, operands[1], 0);
188790075Sobrien
188890075Sobrien  if (CONSTANT_P (operands[2]))
188990075Sobrien    operands[2] = force_reg (SImode, operands[2]);
189090075Sobrien  op2_tf = gen_reg_rtx (TFmode);
189190075Sobrien  expand_float (op2_tf, operands[2], 0);
189290075Sobrien
189390075Sobrien  /* 2^-34 */
189490075Sobrien#if 0
189590075Sobrien  twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
189690075Sobrien	    (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
189790075Sobrien  twon34 = force_reg (TFmode, twon34);
189890075Sobrien#else
189990075Sobrien  twon34 = gen_reg_rtx (TFmode);
190090075Sobrien  convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
190190075Sobrien#endif
190290075Sobrien
190390075Sobrien  emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
190490075Sobrien
190590075Sobrien  emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
190690075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
190790075Sobrien  DONE;
190890075Sobrien}")
190990075Sobrien
191090075Sobrien(define_expand "modsi3"
191190075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
191290075Sobrien	(mod:SI (match_operand:SI 1 "general_operand" "")
191390075Sobrien		(match_operand:SI 2 "general_operand" "")))]
191490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
191590075Sobrien  "
191690075Sobrien{
191790075Sobrien  rtx op2_neg, op1_di, div;
191890075Sobrien
191990075Sobrien  div = gen_reg_rtx (SImode);
192090075Sobrien  emit_insn (gen_divsi3 (div, operands[1], operands[2]));
192190075Sobrien
192290075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
192390075Sobrien
192490075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
192590075Sobrien     have already copied to the FP regs.  */
192690075Sobrien  op1_di = gen_reg_rtx (DImode);
192790075Sobrien  convert_move (op1_di, operands[1], 0);
192890075Sobrien
192990075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
193090075Sobrien			  gen_lowpart (SImode, op1_di)));
193190075Sobrien  DONE;
193290075Sobrien}")
193390075Sobrien
193490075Sobrien(define_expand "udivsi3"
193590075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
193690075Sobrien	(udiv:SI (match_operand:SI 1 "general_operand" "")
193790075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
193890075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
193990075Sobrien  "
194090075Sobrien{
194190075Sobrien  rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
194290075Sobrien
194390075Sobrien  op0_tf = gen_reg_rtx (TFmode);
194490075Sobrien  op0_di = gen_reg_rtx (DImode);
194590075Sobrien
194690075Sobrien  if (CONSTANT_P (operands[1]))
194790075Sobrien    operands[1] = force_reg (SImode, operands[1]);
194890075Sobrien  op1_tf = gen_reg_rtx (TFmode);
194990075Sobrien  expand_float (op1_tf, operands[1], 1);
195090075Sobrien
195190075Sobrien  if (CONSTANT_P (operands[2]))
195290075Sobrien    operands[2] = force_reg (SImode, operands[2]);
195390075Sobrien  op2_tf = gen_reg_rtx (TFmode);
195490075Sobrien  expand_float (op2_tf, operands[2], 1);
195590075Sobrien
195690075Sobrien  /* 2^-34 */
195790075Sobrien#if 0
195890075Sobrien  twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
195990075Sobrien	    (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
196090075Sobrien  twon34 = force_reg (TFmode, twon34);
196190075Sobrien#else
196290075Sobrien  twon34 = gen_reg_rtx (TFmode);
196390075Sobrien  convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
196490075Sobrien#endif
196590075Sobrien
196690075Sobrien  emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
196790075Sobrien
196890075Sobrien  emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
196990075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
197090075Sobrien  DONE;
197190075Sobrien}")
197290075Sobrien
197390075Sobrien(define_expand "umodsi3"
197490075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
197590075Sobrien	(umod:SI (match_operand:SI 1 "general_operand" "")
197690075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
197790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
197890075Sobrien  "
197990075Sobrien{
198090075Sobrien  rtx op2_neg, op1_di, div;
198190075Sobrien
198290075Sobrien  div = gen_reg_rtx (SImode);
198390075Sobrien  emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
198490075Sobrien
198590075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
198690075Sobrien
198790075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
198890075Sobrien     have already copied to the FP regs.  */
198990075Sobrien  op1_di = gen_reg_rtx (DImode);
199090075Sobrien  convert_move (op1_di, operands[1], 1);
199190075Sobrien
199290075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
199390075Sobrien			  gen_lowpart (SImode, op1_di)));
199490075Sobrien  DONE;
199590075Sobrien}")
199690075Sobrien
199790075Sobrien(define_insn_and_split "divsi3_internal"
199890075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
199990075Sobrien	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
200090075Sobrien			  (match_operand:TF 2 "fr_register_operand" "f"))))
200190075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
200290075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
200390075Sobrien   (clobber (match_scratch:BI 6 "=c"))
200490075Sobrien   (use (match_operand:TF 3 "fr_register_operand" "f"))]
200590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
200690075Sobrien  "#"
200790075Sobrien  "&& reload_completed"
200890075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
200990075Sobrien	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
201090075Sobrien	      (use (const_int 1))])
201190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
201290075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
201390075Sobrien		(use (const_int 1))]))
201490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
201590075Sobrien     (parallel [(set (match_dup 5)
201690075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
201790075Sobrien			      (match_dup 7)))
201890075Sobrien		(use (const_int 1))]))
201990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
202090075Sobrien     (parallel [(set (match_dup 4)
202190075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
202290075Sobrien			      (match_dup 4)))
202390075Sobrien		(use (const_int 1))]))
202490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
202590075Sobrien     (parallel [(set (match_dup 5)
202690075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 5))
202790075Sobrien			      (match_dup 3)))
202890075Sobrien		(use (const_int 1))]))
202990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
203090075Sobrien     (parallel [(set (match_dup 0)
203190075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
203290075Sobrien			      (match_dup 4)))
203390075Sobrien		(use (const_int 1))]))
203490075Sobrien  ] 
203590075Sobrien  "operands[7] = CONST1_RTX (TFmode);"
203690075Sobrien  [(set_attr "predicable" "no")])
203790075Sobrien
203890075Sobrien;; ::::::::::::::::::::
203990075Sobrien;; ::
204090075Sobrien;; :: 64 bit Integer arithmetic
204190075Sobrien;; ::
204290075Sobrien;; ::::::::::::::::::::
204390075Sobrien
204490075Sobrien(define_insn "adddi3"
204590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
204690075Sobrien	(plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
204790075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
204890075Sobrien  ""
204990075Sobrien  "@
205090075Sobrien  add %0 = %1, %2
205190075Sobrien  adds %0 = %2, %1
205290075Sobrien  addl %0 = %2, %1"
205390075Sobrien  [(set_attr "itanium_class" "ialu")])
205490075Sobrien
205590075Sobrien(define_insn "*adddi3_plus1"
205690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
205790075Sobrien	(plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
205890075Sobrien			  (match_operand:DI 2 "gr_register_operand" "r"))
205990075Sobrien		 (const_int 1)))]
206090075Sobrien  ""
206190075Sobrien  "add %0 = %1, %2, 1"
206290075Sobrien  [(set_attr "itanium_class" "ialu")])
206390075Sobrien
206490075Sobrien;; This has some of the same problems as shladd.  We let the shladd
206590075Sobrien;; eliminator hack handle it, which results in the 1 being forced into
206690075Sobrien;; a register, but not more ugliness here.
206790075Sobrien(define_insn "*adddi3_plus1_alt"
206890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
206990075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
207090075Sobrien			  (const_int 2))
207190075Sobrien		 (const_int 1)))]
207290075Sobrien  ""
207390075Sobrien  "add %0 = %1, %1, 1"
207490075Sobrien  [(set_attr "itanium_class" "ialu")])
207590075Sobrien
207690075Sobrien(define_insn "subdi3"
207790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
207890075Sobrien	(minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
207990075Sobrien		  (match_operand:DI 2 "gr_register_operand" "r")))]
208090075Sobrien  ""
208190075Sobrien  "sub %0 = %1, %2"
208290075Sobrien  [(set_attr "itanium_class" "ialu")])
208390075Sobrien
208490075Sobrien(define_insn "*subdi3_minus1"
208590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
208690075Sobrien	(plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
208790075Sobrien		 (match_operand:DI 2 "gr_register_operand" "r")))]
208890075Sobrien  ""
208990075Sobrien  "sub %0 = %2, %1, 1"
209090075Sobrien  [(set_attr "itanium_class" "ialu")])
209190075Sobrien
209290075Sobrien;; ??? Use grfr instead of fr because of virtual register elimination
209390075Sobrien;; and silly test cases multiplying by the frame pointer.
209490075Sobrien(define_insn "muldi3"
209590075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
209690075Sobrien	(mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
209790075Sobrien		 (match_operand:DI 2 "grfr_register_operand" "f")))]
209890075Sobrien  ""
209990075Sobrien  "xmpy.l %0 = %1, %2"
210090075Sobrien  [(set_attr "itanium_class" "xmpy")])
210190075Sobrien
210290075Sobrien;; ??? If operand 3 is an eliminable reg, then register elimination causes the
210390075Sobrien;; same problem that we have with shladd below.  Unfortunately, this case is
210490075Sobrien;; much harder to fix because the multiply puts the result in an FP register,
210590075Sobrien;; but the add needs inputs from a general register.  We add a spurious clobber
210690075Sobrien;; here so that it will be present just in case register elimination gives us
210790075Sobrien;; the funny result.
210890075Sobrien
210990075Sobrien;; ??? Maybe validate_changes should try adding match_scratch clobbers?
211090075Sobrien
211190075Sobrien;; ??? Maybe we should change how adds are canonicalized.
211290075Sobrien
211390075Sobrien(define_insn "madddi4"
211490075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
211590075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
211690075Sobrien			  (match_operand:DI 2 "grfr_register_operand" "f"))
211790075Sobrien		 (match_operand:DI 3 "grfr_register_operand" "f")))
211890075Sobrien   (clobber (match_scratch:DI 4 "=X"))]
211990075Sobrien  ""
212090075Sobrien  "xma.l %0 = %1, %2, %3"
212190075Sobrien  [(set_attr "itanium_class" "xmpy")])
212290075Sobrien
212390075Sobrien;; This can be created by register elimination if operand3 of shladd is an
212490075Sobrien;; eliminable register or has reg_equiv_constant set.
212590075Sobrien
212690075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
212790075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
212890075Sobrien;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
212990075Sobrien;; incorrectly.
213090075Sobrien
213190075Sobrien(define_insn "*madddi4_elim"
213290075Sobrien  [(set (match_operand:DI 0 "register_operand" "=&r")
213390075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
213490075Sobrien				   (match_operand:DI 2 "register_operand" "f"))
213590075Sobrien			  (match_operand:DI 3 "register_operand" "f"))
213690075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))
213790075Sobrien   (clobber (match_scratch:DI 5 "=f"))]
213890075Sobrien  "reload_in_progress"
213990075Sobrien  "#"
214090075Sobrien  [(set_attr "itanium_class" "unknown")])
214190075Sobrien
214290075Sobrien(define_split
214390075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
214490075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
214590075Sobrien				   (match_operand:DI 2 "register_operand" ""))
214690075Sobrien			  (match_operand:DI 3 "register_operand" ""))
214790075Sobrien		 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
214890075Sobrien   (clobber (match_scratch:DI 5 ""))]
214990075Sobrien  "reload_completed"
215090075Sobrien  [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
215190075Sobrien					  (match_dup 3)))
215290075Sobrien	      (clobber (match_dup 0))])
215390075Sobrien   (set (match_dup 0) (match_dup 5))
215490075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
215590075Sobrien  "")
215690075Sobrien
215790075Sobrien;; ??? There are highpart multiply and add instructions, but we have no way
215890075Sobrien;; to generate them.
215990075Sobrien
216090075Sobrien(define_insn "smuldi3_highpart"
216190075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
216290075Sobrien	(truncate:DI
216390075Sobrien	 (lshiftrt:TI
216490075Sobrien	  (mult:TI (sign_extend:TI
216590075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
216690075Sobrien		   (sign_extend:TI
216790075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
216890075Sobrien	  (const_int 64))))]
216990075Sobrien  ""
217090075Sobrien  "xmpy.h %0 = %1, %2"
217190075Sobrien  [(set_attr "itanium_class" "xmpy")])
217290075Sobrien
217390075Sobrien(define_insn "umuldi3_highpart"
217490075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
217590075Sobrien	(truncate:DI
217690075Sobrien	 (lshiftrt:TI
217790075Sobrien	  (mult:TI (zero_extend:TI
217890075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
217990075Sobrien		   (zero_extend:TI
218090075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
218190075Sobrien	  (const_int 64))))]
218290075Sobrien  ""
218390075Sobrien  "xmpy.hu %0 = %1, %2"
218490075Sobrien  [(set_attr "itanium_class" "xmpy")])
218590075Sobrien
218690075Sobrien(define_insn "negdi2"
218790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
218890075Sobrien	(neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
218990075Sobrien  ""
219090075Sobrien  "sub %0 = r0, %1"
219190075Sobrien  [(set_attr "itanium_class" "ialu")])
219290075Sobrien
219390075Sobrien(define_expand "absdi2"
219490075Sobrien  [(set (match_dup 2)
219590075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
219690075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
219790075Sobrien	(if_then_else:DI (eq (match_dup 2) (const_int 0))
219890075Sobrien			 (neg:DI (match_dup 1))
219990075Sobrien			 (match_dup 1)))]
220090075Sobrien  ""
220190075Sobrien  "
220290075Sobrien{
220390075Sobrien  operands[2] = gen_reg_rtx (BImode);
220490075Sobrien}")
220590075Sobrien
220690075Sobrien(define_expand "smindi3"
220790075Sobrien  [(set (match_dup 3)
220890075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
220990075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
221090075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
221190075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
221290075Sobrien			 (match_dup 2) (match_dup 1)))]
221390075Sobrien  ""
221490075Sobrien  "
221590075Sobrien{
221690075Sobrien  operands[3] = gen_reg_rtx (BImode);
221790075Sobrien}")
221890075Sobrien
221990075Sobrien(define_expand "smaxdi3"
222090075Sobrien  [(set (match_dup 3)
222190075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
222290075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
222390075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
222490075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
222590075Sobrien			 (match_dup 1) (match_dup 2)))]
222690075Sobrien  ""
222790075Sobrien  "
222890075Sobrien{
222990075Sobrien  operands[3] = gen_reg_rtx (BImode);
223090075Sobrien}")
223190075Sobrien
223290075Sobrien(define_expand "umindi3"
223390075Sobrien  [(set (match_dup 3)
223490075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
223590075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
223690075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
223790075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
223890075Sobrien			 (match_dup 2) (match_dup 1)))]
223990075Sobrien  ""
224090075Sobrien  "
224190075Sobrien{
224290075Sobrien  operands[3] = gen_reg_rtx (BImode);
224390075Sobrien}")
224490075Sobrien
224590075Sobrien(define_expand "umaxdi3"
224690075Sobrien  [(set (match_dup 3)
224790075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
224890075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
224990075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
225090075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
225190075Sobrien			 (match_dup 1) (match_dup 2)))]
225290075Sobrien  ""
225390075Sobrien  "
225490075Sobrien{
225590075Sobrien  operands[3] = gen_reg_rtx (BImode);
225690075Sobrien}")
225790075Sobrien
225890075Sobrien(define_expand "ffsdi2"
225990075Sobrien  [(set (match_dup 6)
226090075Sobrien	(eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
226190075Sobrien   (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
226290075Sobrien   (set (match_dup 5) (const_int 0))
226390075Sobrien   (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
226490075Sobrien   (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
226590075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
226690075Sobrien	(if_then_else:DI (ne (match_dup 6) (const_int 0))
226790075Sobrien			 (match_dup 5) (match_dup 4)))]
226890075Sobrien  ""
226990075Sobrien  "
227090075Sobrien{
227190075Sobrien  operands[2] = gen_reg_rtx (DImode);
227290075Sobrien  operands[3] = gen_reg_rtx (DImode);
227390075Sobrien  operands[4] = gen_reg_rtx (DImode);
227490075Sobrien  operands[5] = gen_reg_rtx (DImode);
227590075Sobrien  operands[6] = gen_reg_rtx (BImode);
227690075Sobrien}")
227790075Sobrien
227890075Sobrien(define_insn "*popcnt"
227990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
228090075Sobrien	(unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] 8))]
228190075Sobrien  ""
228290075Sobrien  "popcnt %0 = %1"
228390075Sobrien  [(set_attr "itanium_class" "mmmul")])
228490075Sobrien
228590075Sobrien(define_expand "divdi3"
228690075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
228790075Sobrien	(div:DI (match_operand:DI 1 "general_operand" "")
228890075Sobrien		(match_operand:DI 2 "general_operand" "")))]
228990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
229090075Sobrien  "
229190075Sobrien{
229290075Sobrien  rtx op1_tf, op2_tf, op0_tf;
229390075Sobrien
229490075Sobrien  op0_tf = gen_reg_rtx (TFmode);
229590075Sobrien
229690075Sobrien  if (CONSTANT_P (operands[1]))
229790075Sobrien    operands[1] = force_reg (DImode, operands[1]);
229890075Sobrien  op1_tf = gen_reg_rtx (TFmode);
229990075Sobrien  expand_float (op1_tf, operands[1], 0);
230090075Sobrien
230190075Sobrien  if (CONSTANT_P (operands[2]))
230290075Sobrien    operands[2] = force_reg (DImode, operands[2]);
230390075Sobrien  op2_tf = gen_reg_rtx (TFmode);
230490075Sobrien  expand_float (op2_tf, operands[2], 0);
230590075Sobrien
230690075Sobrien  if (TARGET_INLINE_DIV_LAT)
230790075Sobrien    emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
230890075Sobrien  else
230990075Sobrien    emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
231090075Sobrien
231190075Sobrien  emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
231290075Sobrien  DONE;
231390075Sobrien}")
231490075Sobrien
231590075Sobrien(define_expand "moddi3"
231690075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
231790075Sobrien	(mod:SI (match_operand:DI 1 "general_operand" "")
231890075Sobrien		(match_operand:DI 2 "general_operand" "")))]
231990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
232090075Sobrien  "
232190075Sobrien{
232290075Sobrien  rtx op2_neg, div;
232390075Sobrien
232490075Sobrien  div = gen_reg_rtx (DImode);
232590075Sobrien  emit_insn (gen_divdi3 (div, operands[1], operands[2]));
232690075Sobrien
232790075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
232890075Sobrien
232990075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
233090075Sobrien  DONE;
233190075Sobrien}")
233290075Sobrien
233390075Sobrien(define_expand "udivdi3"
233490075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
233590075Sobrien	(udiv:DI (match_operand:DI 1 "general_operand" "")
233690075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
233790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
233890075Sobrien  "
233990075Sobrien{
234090075Sobrien  rtx op1_tf, op2_tf, op0_tf;
234190075Sobrien
234290075Sobrien  op0_tf = gen_reg_rtx (TFmode);
234390075Sobrien
234490075Sobrien  if (CONSTANT_P (operands[1]))
234590075Sobrien    operands[1] = force_reg (DImode, operands[1]);
234690075Sobrien  op1_tf = gen_reg_rtx (TFmode);
234790075Sobrien  expand_float (op1_tf, operands[1], 1);
234890075Sobrien
234990075Sobrien  if (CONSTANT_P (operands[2]))
235090075Sobrien    operands[2] = force_reg (DImode, operands[2]);
235190075Sobrien  op2_tf = gen_reg_rtx (TFmode);
235290075Sobrien  expand_float (op2_tf, operands[2], 1);
235390075Sobrien
235490075Sobrien  if (TARGET_INLINE_DIV_LAT)
235590075Sobrien    emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
235690075Sobrien  else
235790075Sobrien    emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
235890075Sobrien
235990075Sobrien  emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
236090075Sobrien  DONE;
236190075Sobrien}")
236290075Sobrien
236390075Sobrien(define_expand "umoddi3"
236490075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
236590075Sobrien	(umod:DI (match_operand:DI 1 "general_operand" "")
236690075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
236790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
236890075Sobrien  "
236990075Sobrien{
237090075Sobrien  rtx op2_neg, div;
237190075Sobrien
237290075Sobrien  div = gen_reg_rtx (DImode);
237390075Sobrien  emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
237490075Sobrien
237590075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
237690075Sobrien
237790075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
237890075Sobrien  DONE;
237990075Sobrien}")
238090075Sobrien
238190075Sobrien(define_insn_and_split "divdi3_internal_lat"
238290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
238390075Sobrien	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
238490075Sobrien			  (match_operand:TF 2 "fr_register_operand" "f"))))
238590075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
238690075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
238790075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
238890075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
238990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_LAT"
239090075Sobrien  "#"
239190075Sobrien  "&& reload_completed"
239290075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
239390075Sobrien	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
239490075Sobrien	      (use (const_int 1))])
239590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
239690075Sobrien     (parallel [(set (match_dup 3)
239790075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
239890075Sobrien			      (match_dup 7)))
239990075Sobrien		(use (const_int 1))]))
240090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
240190075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
240290075Sobrien		(use (const_int 1))]))
240390075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
240490075Sobrien     (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
240590075Sobrien		(use (const_int 1))]))
240690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
240790075Sobrien     (parallel [(set (match_dup 4)
240890075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 4))
240990075Sobrien			      (match_dup 4)))
241090075Sobrien		(use (const_int 1))]))
241190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
241290075Sobrien     (parallel [(set (match_dup 0)
241390075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
241490075Sobrien			      (match_dup 0)))
241590075Sobrien		(use (const_int 1))]))
241690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
241790075Sobrien     (parallel [(set (match_dup 3)
241890075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 4))
241990075Sobrien			      (match_dup 4)))
242090075Sobrien		(use (const_int 1))]))
242190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
242290075Sobrien     (parallel [(set (match_dup 0)
242390075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 0))
242490075Sobrien			      (match_dup 0)))
242590075Sobrien		(use (const_int 1))]))
242690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
242790075Sobrien     (parallel [(set (match_dup 4)
242890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
242990075Sobrien			      (match_dup 1)))
243090075Sobrien		(use (const_int 1))]))
243190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
243290075Sobrien     (parallel [(set (match_dup 0)
243390075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
243490075Sobrien			      (match_dup 3)))
243590075Sobrien		(use (const_int 1))]))
243690075Sobrien  ] 
243790075Sobrien  "operands[7] = CONST1_RTX (TFmode);"
243890075Sobrien  [(set_attr "predicable" "no")])
243990075Sobrien
244090075Sobrien(define_insn_and_split "divdi3_internal_thr"
244190075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
244290075Sobrien	(float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
244390075Sobrien			  (match_operand:TF 2 "fr_register_operand" "f"))))
244490075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
244590075Sobrien   (clobber (match_scratch:TF 4 "=f"))
244690075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
244790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_THR"
244890075Sobrien  "#"
244990075Sobrien  "&& reload_completed"
245090075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
245190075Sobrien	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
245290075Sobrien	      (use (const_int 1))])
245390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
245490075Sobrien     (parallel [(set (match_dup 3)
245590075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
245690075Sobrien			      (match_dup 6)))
245790075Sobrien		(use (const_int 1))]))
245890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
245990075Sobrien     (parallel [(set (match_dup 0)
246090075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
246190075Sobrien			      (match_dup 0)))
246290075Sobrien		(use (const_int 1))]))
246390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
246490075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
246590075Sobrien		(use (const_int 1))]))
246690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
246790075Sobrien     (parallel [(set (match_dup 0)
246890075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
246990075Sobrien			      (match_dup 0)))
247090075Sobrien		(use (const_int 1))]))
247190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
247290075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
247390075Sobrien		(use (const_int 1))]))
247490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
247590075Sobrien     (parallel [(set (match_dup 4)
247690075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
247790075Sobrien			      (match_dup 1)))
247890075Sobrien		(use (const_int 1))]))
247990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
248090075Sobrien     (parallel [(set (match_dup 0)
248190075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
248290075Sobrien			      (match_dup 3)))
248390075Sobrien		(use (const_int 1))]))
248490075Sobrien  ] 
248590075Sobrien  "operands[6] = CONST1_RTX (TFmode);"
248690075Sobrien  [(set_attr "predicable" "no")])
248790075Sobrien
248890075Sobrien;; ::::::::::::::::::::
248990075Sobrien;; ::
249090075Sobrien;; :: 32 bit floating point arithmetic
249190075Sobrien;; ::
249290075Sobrien;; ::::::::::::::::::::
249390075Sobrien
249490075Sobrien(define_insn "addsf3"
249590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
249690075Sobrien	(plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
249790075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
249890075Sobrien  ""
249990075Sobrien  "fadd.s %0 = %1, %F2"
250090075Sobrien  [(set_attr "itanium_class" "fmac")])
250190075Sobrien
250290075Sobrien(define_insn "subsf3"
250390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
250490075Sobrien	(minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
250590075Sobrien		  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
250690075Sobrien  ""
250790075Sobrien  "fsub.s %0 = %F1, %F2"
250890075Sobrien  [(set_attr "itanium_class" "fmac")])
250990075Sobrien
251090075Sobrien(define_insn "mulsf3"
251190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
251290075Sobrien	(mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
251390075Sobrien		 (match_operand:SF 2 "fr_register_operand" "f")))]
251490075Sobrien  ""
251590075Sobrien  "fmpy.s %0 = %1, %2"
251690075Sobrien  [(set_attr "itanium_class" "fmac")])
251790075Sobrien
251890075Sobrien(define_insn "abssf2"
251990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
252090075Sobrien	(abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
252190075Sobrien  ""
252290075Sobrien  "fabs %0 = %1"
252390075Sobrien  [(set_attr "itanium_class" "fmisc")])
252490075Sobrien
252590075Sobrien(define_insn "negsf2"
252690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
252790075Sobrien	(neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
252890075Sobrien  ""
252990075Sobrien  "fneg %0 = %1"
253090075Sobrien  [(set_attr "itanium_class" "fmisc")])
253190075Sobrien
253290075Sobrien(define_insn "*nabssf2"
253390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
253490075Sobrien	(neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
253590075Sobrien  ""
253690075Sobrien  "fnegabs %0 = %1"
253790075Sobrien  [(set_attr "itanium_class" "fmisc")])
253890075Sobrien
253990075Sobrien(define_insn "minsf3"
254090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
254190075Sobrien	(smin:SF (match_operand:SF 1 "fr_register_operand" "f")
254290075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
254390075Sobrien  ""
254490075Sobrien  "fmin %0 = %1, %F2"
254590075Sobrien  [(set_attr "itanium_class" "fmisc")])
254690075Sobrien
254790075Sobrien(define_insn "maxsf3"
254890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
254990075Sobrien	(smax:SF (match_operand:SF 1 "fr_register_operand" "f")
255090075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
255190075Sobrien  ""
255290075Sobrien  "fmax %0 = %1, %F2"
255390075Sobrien  [(set_attr "itanium_class" "fmisc")])
255490075Sobrien
255590075Sobrien(define_insn "*maddsf4"
255690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
255790075Sobrien	(plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
255890075Sobrien			  (match_operand:SF 2 "fr_register_operand" "f"))
255990075Sobrien		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
256090075Sobrien  ""
256190075Sobrien  "fma.s %0 = %1, %2, %F3"
256290075Sobrien  [(set_attr "itanium_class" "fmac")])
256390075Sobrien
256490075Sobrien(define_insn "*msubsf4"
256590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
256690075Sobrien	(minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
256790075Sobrien			   (match_operand:SF 2 "fr_register_operand" "f"))
256890075Sobrien		  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
256990075Sobrien  ""
257090075Sobrien  "fms.s %0 = %1, %2, %F3"
257190075Sobrien  [(set_attr "itanium_class" "fmac")])
257290075Sobrien
257390075Sobrien(define_insn "*nmulsf3"
257490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
257590075Sobrien	(neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
257690075Sobrien			 (match_operand:SF 2 "fr_register_operand" "f"))))]
257790075Sobrien  ""
257890075Sobrien  "fnmpy.s %0 = %1, %2"
257990075Sobrien  [(set_attr "itanium_class" "fmac")])
258090075Sobrien
258190075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
258290075Sobrien
258390075Sobrien(define_insn "*nmaddsf4"
258490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
258590075Sobrien	(plus:SF (neg:SF (mult:SF
258690075Sobrien			   (match_operand:SF 1 "fr_register_operand" "f")
258790075Sobrien			   (match_operand:SF 2 "fr_register_operand" "f")))
258890075Sobrien		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
258990075Sobrien  ""
259090075Sobrien  "fnma.s %0 = %1, %2, %F3"
259190075Sobrien  [(set_attr "itanium_class" "fmac")])
259290075Sobrien
259390075Sobrien(define_expand "divsf3"
259490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "")
259590075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "")
259690075Sobrien		(match_operand:SF 2 "fr_register_operand" "")))]
259790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
259890075Sobrien  "
259990075Sobrien{
260090075Sobrien  rtx insn;
260190075Sobrien  if (TARGET_INLINE_DIV_LAT)
260290075Sobrien    insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
260390075Sobrien  else
260490075Sobrien    insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
260590075Sobrien  emit_insn (insn);
260690075Sobrien  DONE;
260790075Sobrien}")
260890075Sobrien
260990075Sobrien(define_insn_and_split "divsf3_internal_lat"
261090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
261190075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
261290075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
261390075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
261490075Sobrien   (clobber (match_scratch:TF 4 "=f"))
261590075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
261690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_LAT"
261790075Sobrien  "#"
261890075Sobrien  "&& reload_completed"
261990075Sobrien  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
262090075Sobrien	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
262190075Sobrien	      (use (const_int 1))])
262290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
262390075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
262490075Sobrien		(use (const_int 1))]))
262590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
262690075Sobrien     (parallel [(set (match_dup 4)
262790075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
262890075Sobrien			      (match_dup 10)))
262990075Sobrien		(use (const_int 1))]))
263090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
263190075Sobrien     (parallel [(set (match_dup 3)
263290075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
263390075Sobrien			      (match_dup 3)))
263490075Sobrien		(use (const_int 1))]))
263590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
263690075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
263790075Sobrien		(use (const_int 1))]))
263890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
263990075Sobrien     (parallel [(set (match_dup 3)
264090075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
264190075Sobrien			      (match_dup 3)))
264290075Sobrien		(use (const_int 1))]))
264390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
264490075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
264590075Sobrien		(use (const_int 1))]))
264690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
264790075Sobrien     (parallel [(set (match_dup 9)
264890075Sobrien		     (float_truncate:DF
264990075Sobrien		       (plus:TF (mult:TF (match_dup 4) (match_dup 3))
265090075Sobrien			      (match_dup 3))))
265190075Sobrien		(use (const_int 1))]))
265290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
265390075Sobrien     (set (match_dup 0)
265490075Sobrien	  (float_truncate:SF (match_dup 6))))
265590075Sobrien  ] 
265690075Sobrien  "operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
265790075Sobrien   operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
265890075Sobrien   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
265990075Sobrien   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
266090075Sobrien   operands[10] = CONST1_RTX (TFmode);"
266190075Sobrien  [(set_attr "predicable" "no")])
266290075Sobrien
266390075Sobrien(define_insn_and_split "divsf3_internal_thr"
266490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
266590075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
266690075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
266790075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
266890075Sobrien   (clobber (match_scratch:TF 4 "=f"))
266990075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
267090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_THR"
267190075Sobrien  "#"
267290075Sobrien  "&& reload_completed"
267390075Sobrien  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
267490075Sobrien	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
267590075Sobrien	      (use (const_int 1))])
267690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
267790075Sobrien     (parallel [(set (match_dup 3)
267890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
267990075Sobrien			      (match_dup 10)))
268090075Sobrien		(use (const_int 1))]))
268190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
268290075Sobrien     (parallel [(set (match_dup 3)
268390075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 3))
268490075Sobrien			      (match_dup 3)))
268590075Sobrien		(use (const_int 1))]))
268690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
268790075Sobrien     (parallel [(set (match_dup 6)
268890075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
268990075Sobrien			      (match_dup 6)))
269090075Sobrien		(use (const_int 1))]))
269190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
269290075Sobrien     (parallel [(set (match_dup 9)
269390075Sobrien		     (float_truncate:SF
269490075Sobrien		       (mult:TF (match_dup 7) (match_dup 6))))
269590075Sobrien		(use (const_int 1))]))
269690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
269790075Sobrien     (parallel [(set (match_dup 4)
269890075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3)))
269990075Sobrien			      (match_dup 7)))
270090075Sobrien		(use (const_int 1))]))
270190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
270290075Sobrien     (set (match_dup 0)
270390075Sobrien	  (float_truncate:SF
270490075Sobrien	    (plus:TF (mult:TF (match_dup 4) (match_dup 6))
270590075Sobrien			      (match_dup 3)))))
270690075Sobrien  ] 
270790075Sobrien  "operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
270890075Sobrien   operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
270990075Sobrien   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
271090075Sobrien   operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
271190075Sobrien   operands[10] = CONST1_RTX (TFmode);"
271290075Sobrien  [(set_attr "predicable" "no")])
271390075Sobrien
271490075Sobrien;; ::::::::::::::::::::
271590075Sobrien;; ::
271690075Sobrien;; :: 64 bit floating point arithmetic
271790075Sobrien;; ::
271890075Sobrien;; ::::::::::::::::::::
271990075Sobrien
272090075Sobrien(define_insn "adddf3"
272190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
272290075Sobrien	(plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
272390075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
272490075Sobrien  ""
272590075Sobrien  "fadd.d %0 = %1, %F2"
272690075Sobrien  [(set_attr "itanium_class" "fmac")])
272790075Sobrien
272890075Sobrien(define_insn "*adddf3_trunc"
272990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
273090075Sobrien	(float_truncate:SF
273190075Sobrien	  (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
273290075Sobrien		   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
273390075Sobrien  ""
273490075Sobrien  "fadd.s %0 = %1, %F2"
273590075Sobrien  [(set_attr "itanium_class" "fmac")])
273690075Sobrien
273790075Sobrien(define_insn "subdf3"
273890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
273990075Sobrien	(minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
274090075Sobrien		  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
274190075Sobrien  ""
274290075Sobrien  "fsub.d %0 = %F1, %F2"
274390075Sobrien  [(set_attr "itanium_class" "fmac")])
274490075Sobrien
274590075Sobrien(define_insn "*subdf3_trunc"
274690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
274790075Sobrien	(float_truncate:SF
274890075Sobrien	  (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
274990075Sobrien		    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
275090075Sobrien  ""
275190075Sobrien  "fsub.s %0 = %F1, %F2"
275290075Sobrien  [(set_attr "itanium_class" "fmac")])
275390075Sobrien
275490075Sobrien(define_insn "muldf3"
275590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
275690075Sobrien	(mult:DF (match_operand:DF 1 "fr_register_operand" "f")
275790075Sobrien		 (match_operand:DF 2 "fr_register_operand" "f")))]
275890075Sobrien  ""
275990075Sobrien  "fmpy.d %0 = %1, %2"
276090075Sobrien  [(set_attr "itanium_class" "fmac")])
276190075Sobrien
276290075Sobrien(define_insn "*muldf3_trunc"
276390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
276490075Sobrien	(float_truncate:SF
276590075Sobrien	  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
276690075Sobrien		   (match_operand:DF 2 "fr_register_operand" "f"))))]
276790075Sobrien  ""
276890075Sobrien  "fmpy.s %0 = %1, %2"
276990075Sobrien  [(set_attr "itanium_class" "fmac")])
277090075Sobrien
277190075Sobrien(define_insn "absdf2"
277290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
277390075Sobrien	(abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
277490075Sobrien  ""
277590075Sobrien  "fabs %0 = %1"
277690075Sobrien  [(set_attr "itanium_class" "fmisc")])
277790075Sobrien
277890075Sobrien(define_insn "negdf2"
277990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
278090075Sobrien	(neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
278190075Sobrien  ""
278290075Sobrien  "fneg %0 = %1"
278390075Sobrien  [(set_attr "itanium_class" "fmisc")])
278490075Sobrien
278590075Sobrien(define_insn "*nabsdf2"
278690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
278790075Sobrien	(neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
278890075Sobrien  ""
278990075Sobrien  "fnegabs %0 = %1"
279090075Sobrien  [(set_attr "itanium_class" "fmisc")])
279190075Sobrien
279290075Sobrien(define_insn "mindf3"
279390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
279490075Sobrien	(smin:DF (match_operand:DF 1 "fr_register_operand" "f")
279590075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
279690075Sobrien  ""
279790075Sobrien  "fmin %0 = %1, %F2"
279890075Sobrien  [(set_attr "itanium_class" "fmisc")])
279990075Sobrien
280090075Sobrien(define_insn "maxdf3"
280190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
280290075Sobrien	(smax:DF (match_operand:DF 1 "fr_register_operand" "f")
280390075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
280490075Sobrien  ""
280590075Sobrien  "fmax %0 = %1, %F2"
280690075Sobrien  [(set_attr "itanium_class" "fmisc")])
280790075Sobrien
280890075Sobrien(define_insn "*madddf4"
280990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
281090075Sobrien	(plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
281190075Sobrien			  (match_operand:DF 2 "fr_register_operand" "f"))
281290075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
281390075Sobrien  ""
281490075Sobrien  "fma.d %0 = %1, %2, %F3"
281590075Sobrien  [(set_attr "itanium_class" "fmac")])
281690075Sobrien
281790075Sobrien(define_insn "*madddf4_trunc"
281890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
281990075Sobrien	(float_truncate:SF
282090075Sobrien	  (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
282190075Sobrien			    (match_operand:DF 2 "fr_register_operand" "f"))
282290075Sobrien		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
282390075Sobrien  ""
282490075Sobrien  "fma.s %0 = %1, %2, %F3"
282590075Sobrien  [(set_attr "itanium_class" "fmac")])
282690075Sobrien
282790075Sobrien(define_insn "*msubdf4"
282890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
282990075Sobrien	(minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
283090075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f"))
283190075Sobrien		  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
283290075Sobrien  ""
283390075Sobrien  "fms.d %0 = %1, %2, %F3"
283490075Sobrien  [(set_attr "itanium_class" "fmac")])
283590075Sobrien
283690075Sobrien(define_insn "*msubdf4_trunc"
283790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
283890075Sobrien	(float_truncate:SF
283990075Sobrien	  (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
284090075Sobrien			     (match_operand:DF 2 "fr_register_operand" "f"))
284190075Sobrien		    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
284290075Sobrien  ""
284390075Sobrien  "fms.s %0 = %1, %2, %F3"
284490075Sobrien  [(set_attr "itanium_class" "fmac")])
284590075Sobrien
284690075Sobrien(define_insn "*nmuldf3"
284790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
284890075Sobrien	(neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
284990075Sobrien			 (match_operand:DF 2 "fr_register_operand" "f"))))]
285090075Sobrien  ""
285190075Sobrien  "fnmpy.d %0 = %1, %2"
285290075Sobrien  [(set_attr "itanium_class" "fmac")])
285390075Sobrien
285490075Sobrien(define_insn "*nmuldf3_trunc"
285590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
285690075Sobrien	(float_truncate:SF
285790075Sobrien	  (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
285890075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))))]
285990075Sobrien  ""
286090075Sobrien  "fnmpy.s %0 = %1, %2"
286190075Sobrien  [(set_attr "itanium_class" "fmac")])
286290075Sobrien
286390075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
286490075Sobrien
286590075Sobrien(define_insn "*nmadddf4"
286690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
286790075Sobrien	(plus:DF (neg:DF (mult:DF
286890075Sobrien			   (match_operand:DF 1 "fr_register_operand" "f")
286990075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))
287090075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
287190075Sobrien  ""
287290075Sobrien  "fnma.d %0 = %1, %2, %F3"
287390075Sobrien  [(set_attr "itanium_class" "fmac")])
287490075Sobrien
287590075Sobrien(define_insn "*nmadddf4_alts"
287690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
287790075Sobrien	(plus:DF (neg:DF (mult:DF
287890075Sobrien			   (match_operand:DF 1 "fr_register_operand" "f")
287990075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))
288090075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
288190075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
288290075Sobrien  ""
288390075Sobrien  "fnma.d.s%4 %0 = %1, %2, %F3"
288490075Sobrien  [(set_attr "itanium_class" "fmac")])
288590075Sobrien
288690075Sobrien(define_insn "*nmadddf4_trunc"
288790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
288890075Sobrien	(float_truncate:SF
288990075Sobrien	  (plus:DF (neg:DF (mult:DF
289090075Sobrien			     (match_operand:DF 1 "fr_register_operand" "f")
289190075Sobrien			     (match_operand:DF 2 "fr_register_operand" "f")))
289290075Sobrien		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
289390075Sobrien  ""
289490075Sobrien  "fnma.s %0 = %1, %2, %F3"
289590075Sobrien  [(set_attr "itanium_class" "fmac")])
289690075Sobrien
289790075Sobrien(define_expand "divdf3"
289890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "")
289990075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "")
290090075Sobrien		(match_operand:DF 2 "fr_register_operand" "")))]
290190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
290290075Sobrien  "
290390075Sobrien{
290490075Sobrien  rtx insn;
290590075Sobrien  if (TARGET_INLINE_DIV_LAT)
290690075Sobrien    insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
290790075Sobrien  else
290890075Sobrien    insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
290990075Sobrien  emit_insn (insn);
291090075Sobrien  DONE;
291190075Sobrien}")
291290075Sobrien
291390075Sobrien(define_insn_and_split "divdf3_internal_lat"
291490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
291590075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
291690075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
291790075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
291890075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
291990075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
292090075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
292190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_LAT"
292290075Sobrien  "#"
292390075Sobrien  "&& reload_completed"
292490075Sobrien  [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
292590075Sobrien	      (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] 5))
292690075Sobrien	      (use (const_int 1))])
292790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
292890075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
292990075Sobrien		(use (const_int 1))]))
293090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
293190075Sobrien     (parallel [(set (match_dup 4)
293290075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7)))
293390075Sobrien			      (match_dup 12)))
293490075Sobrien		(use (const_int 1))]))
293590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
293690075Sobrien     (parallel [(set (match_dup 3)
293790075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 3))
293890075Sobrien			      (match_dup 3)))
293990075Sobrien		(use (const_int 1))]))
294090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
294190075Sobrien     (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4)))
294290075Sobrien		(use (const_int 1))]))
294390075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
294490075Sobrien     (parallel [(set (match_dup 7)
294590075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 7))
294690075Sobrien			      (match_dup 7)))
294790075Sobrien		(use (const_int 1))]))
294890075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
294990075Sobrien     (parallel [(set (match_dup 3)
295090075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 3))
295190075Sobrien			      (match_dup 3)))
295290075Sobrien		(use (const_int 1))]))
295390075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
295490075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5)))
295590075Sobrien		(use (const_int 1))]))
295690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
295790075Sobrien     (parallel [(set (match_dup 7)
295890075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 7))
295990075Sobrien			      (match_dup 7)))
296090075Sobrien		(use (const_int 1))]))
296190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
296290075Sobrien     (parallel [(set (match_dup 10)
296390075Sobrien		     (float_truncate:DF
296490075Sobrien		       (plus:TF (mult:TF (match_dup 4) (match_dup 3))
296590075Sobrien			      (match_dup 3))))
296690075Sobrien		(use (const_int 1))]))
296790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
296890075Sobrien     (parallel [(set (match_dup 7)
296990075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 7))
297090075Sobrien			      (match_dup 7)))
297190075Sobrien		(use (const_int 1))]))
297290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
297390075Sobrien     (parallel [(set (match_dup 11)
297490075Sobrien		     (float_truncate:DF
297590075Sobrien		       (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3)))
297690075Sobrien			        (match_dup 8))))
297790075Sobrien		(use (const_int 1))]))
297890075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
297990075Sobrien     (set (match_dup 0)
298090075Sobrien	  (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7))
298190075Sobrien			      (match_dup 3)))))
298290075Sobrien  ] 
298390075Sobrien  "operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0]));
298490075Sobrien   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1]));
298590075Sobrien   operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2]));
298690075Sobrien   operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
298790075Sobrien   operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
298890075Sobrien   operands[12] = CONST1_RTX (TFmode);"
298990075Sobrien  [(set_attr "predicable" "no")])
299090075Sobrien
299190075Sobrien(define_insn_and_split "divdf3_internal_thr"
299290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
299390075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
299490075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
299590075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
299690075Sobrien   (clobber (match_scratch:DF 4 "=f"))
299790075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
299890075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_THR"
299990075Sobrien  "#"
300090075Sobrien  "&& reload_completed"
300190075Sobrien  [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
300290075Sobrien	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
300390075Sobrien	      (use (const_int 1))])
300490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
300590075Sobrien     (parallel [(set (match_dup 3)
300690075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
300790075Sobrien			      (match_dup 10)))
300890075Sobrien		(use (const_int 1))]))
300990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
301090075Sobrien     (parallel [(set (match_dup 6)
301190075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
301290075Sobrien			      (match_dup 6)))
301390075Sobrien		(use (const_int 1))]))
301490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
301590075Sobrien     (parallel [(set (match_dup 3)
301690075Sobrien		     (mult:TF (match_dup 3) (match_dup 3)))
301790075Sobrien		(use (const_int 1))]))
301890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
301990075Sobrien     (parallel [(set (match_dup 6)
302090075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
302190075Sobrien			      (match_dup 6)))
302290075Sobrien		(use (const_int 1))]))
302390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
302490075Sobrien     (parallel [(set (match_dup 3)
302590075Sobrien		     (mult:TF (match_dup 3) (match_dup 3)))
302690075Sobrien		(use (const_int 1))]))
302790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
302890075Sobrien     (parallel [(set (match_dup 6)
302990075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 6))
303090075Sobrien			      (match_dup 6)))
303190075Sobrien		(use (const_int 1))]))
303290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
303390075Sobrien     (parallel [(set (match_dup 9)
303490075Sobrien		     (float_truncate:DF
303590075Sobrien		       (mult:TF (match_dup 7) (match_dup 3))))
303690075Sobrien		(use (const_int 1))]))
303790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
303890075Sobrien     (parallel [(set (match_dup 4)
303990075Sobrien		     (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
304090075Sobrien			      (match_dup 1)))
304190075Sobrien		(use (const_int 1))]))
304290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
304390075Sobrien     (set (match_dup 0)
304490075Sobrien	  (plus:DF (mult:DF (match_dup 4) (match_dup 0))
304590075Sobrien			    (match_dup 9))))
304690075Sobrien  ] 
304790075Sobrien  "operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
304890075Sobrien   operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
304990075Sobrien   operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
305090075Sobrien   operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
305190075Sobrien   operands[10] = CONST1_RTX (TFmode);"
305290075Sobrien  [(set_attr "predicable" "no")])
305390075Sobrien
305490075Sobrien;; ::::::::::::::::::::
305590075Sobrien;; ::
305690075Sobrien;; :: 80 bit floating point arithmetic
305790075Sobrien;; ::
305890075Sobrien;; ::::::::::::::::::::
305990075Sobrien
306090075Sobrien(define_insn "addtf3"
306190075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
306290075Sobrien	(plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
306390075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
306490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
306590075Sobrien  "fadd %0 = %F1, %F2"
306690075Sobrien  [(set_attr "itanium_class" "fmac")])
306790075Sobrien
306890075Sobrien(define_insn "*addtf3_truncsf"
306990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
307090075Sobrien	(float_truncate:SF
307190075Sobrien	  (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
307290075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
307390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
307490075Sobrien  "fadd.s %0 = %F1, %F2"
307590075Sobrien  [(set_attr "itanium_class" "fmac")])
307690075Sobrien
307790075Sobrien(define_insn "*addtf3_truncdf"
307890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
307990075Sobrien	(float_truncate:DF
308090075Sobrien	  (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
308190075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
308290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
308390075Sobrien  "fadd.d %0 = %F1, %F2"
308490075Sobrien  [(set_attr "itanium_class" "fmac")])
308590075Sobrien
308690075Sobrien(define_insn "subtf3"
308790075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
308890075Sobrien	(minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
308990075Sobrien		  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
309090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
309190075Sobrien  "fsub %0 = %F1, %F2"
309290075Sobrien  [(set_attr "itanium_class" "fmac")])
309390075Sobrien
309490075Sobrien(define_insn "*subtf3_truncsf"
309590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
309690075Sobrien	(float_truncate:SF
309790075Sobrien	  (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
309890075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
309990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
310090075Sobrien  "fsub.s %0 = %F1, %F2"
310190075Sobrien  [(set_attr "itanium_class" "fmac")])
310290075Sobrien
310390075Sobrien(define_insn "*subtf3_truncdf"
310490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
310590075Sobrien	(float_truncate:DF
310690075Sobrien	  (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
310790075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
310890075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
310990075Sobrien  "fsub.d %0 = %F1, %F2"
311090075Sobrien  [(set_attr "itanium_class" "fmac")])
311190075Sobrien
311290075Sobrien(define_insn "multf3"
311390075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
311490075Sobrien	(mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
311590075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
311690075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
311790075Sobrien  "fmpy %0 = %F1, %F2"
311890075Sobrien  [(set_attr "itanium_class" "fmac")])
311990075Sobrien
312090075Sobrien(define_insn "*multf3_truncsf"
312190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
312290075Sobrien	(float_truncate:SF
312390075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
312490075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
312590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
312690075Sobrien  "fmpy.s %0 = %F1, %F2"
312790075Sobrien  [(set_attr "itanium_class" "fmac")])
312890075Sobrien
312990075Sobrien(define_insn "*multf3_truncdf"
313090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
313190075Sobrien	(float_truncate:DF
313290075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
313390075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
313490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
313590075Sobrien  "fmpy.d %0 = %F1, %F2"
313690075Sobrien  [(set_attr "itanium_class" "fmac")])
313790075Sobrien
313890075Sobrien(define_insn "*multf3_alts"
313990075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
314090075Sobrien	(mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
314190075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
314290075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
314390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
314490075Sobrien  "fmpy.s%3 %0 = %F1, %F2"
314590075Sobrien  [(set_attr "itanium_class" "fmac")])
314690075Sobrien
314790075Sobrien(define_insn "*multf3_truncsf_alts"
314890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
314990075Sobrien	(float_truncate:SF
315090075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
315190075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
315290075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
315390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
315490075Sobrien  "fmpy.s.s%3 %0 = %F1, %F2"
315590075Sobrien  [(set_attr "itanium_class" "fmac")])
315690075Sobrien
315790075Sobrien(define_insn "*multf3_truncdf_alts"
315890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
315990075Sobrien	(float_truncate:DF
316090075Sobrien	  (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
316190075Sobrien		   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
316290075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
316390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
316490075Sobrien  "fmpy.d.s%3 %0 = %F1, %F2"
316590075Sobrien  [(set_attr "itanium_class" "fmac")])
316690075Sobrien
316790075Sobrien(define_insn "abstf2"
316890075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
316990075Sobrien	(abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
317090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
317190075Sobrien  "fabs %0 = %F1"
317290075Sobrien  [(set_attr "itanium_class" "fmisc")])
317390075Sobrien
317490075Sobrien(define_insn "negtf2"
317590075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
317690075Sobrien	(neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
317790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
317890075Sobrien  "fneg %0 = %F1"
317990075Sobrien  [(set_attr "itanium_class" "fmisc")])
318090075Sobrien
318190075Sobrien(define_insn "*nabstf2"
318290075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
318390075Sobrien	(neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
318490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
318590075Sobrien  "fnegabs %0 = %F1"
318690075Sobrien  [(set_attr "itanium_class" "fmisc")])
318790075Sobrien
318890075Sobrien(define_insn "mintf3"
318990075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
319090075Sobrien	(smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
319190075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
319290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
319390075Sobrien  "fmin %0 = %F1, %F2"
319490075Sobrien  [(set_attr "itanium_class" "fmisc")])
319590075Sobrien
319690075Sobrien(define_insn "maxtf3"
319790075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
319890075Sobrien	(smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
319990075Sobrien		 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
320090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
320190075Sobrien  "fmax %0 = %F1, %F2"
320290075Sobrien  [(set_attr "itanium_class" "fmisc")])
320390075Sobrien
320490075Sobrien(define_insn "*maddtf4"
320590075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
320690075Sobrien	(plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
320790075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
320890075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
320990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
321090075Sobrien  "fma %0 = %F1, %F2, %F3"
321190075Sobrien  [(set_attr "itanium_class" "fmac")])
321290075Sobrien
321390075Sobrien(define_insn "*maddtf4_truncsf"
321490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
321590075Sobrien	(float_truncate:SF
321690075Sobrien	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
321790075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
321890075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
321990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
322090075Sobrien  "fma.s %0 = %F1, %F2, %F3"
322190075Sobrien  [(set_attr "itanium_class" "fmac")])
322290075Sobrien
322390075Sobrien(define_insn "*maddtf4_truncdf"
322490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
322590075Sobrien	(float_truncate:DF
322690075Sobrien	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
322790075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
322890075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
322990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
323090075Sobrien  "fma.d %0 = %F1, %F2, %F3"
323190075Sobrien  [(set_attr "itanium_class" "fmac")])
323290075Sobrien
323390075Sobrien(define_insn "*maddtf4_alts"
323490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
323590075Sobrien	(plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
323690075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
323790075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
323890075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
323990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
324090075Sobrien  "fma.s%4 %0 = %F1, %F2, %F3"
324190075Sobrien  [(set_attr "itanium_class" "fmac")])
324290075Sobrien
324390075Sobrien(define_insn "*maddtf4_alts_truncdf"
324490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
324590075Sobrien	(float_truncate:DF
324690075Sobrien	  (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
324790075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
324890075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
324990075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
325090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
325190075Sobrien  "fma.d.s%4 %0 = %F1, %F2, %F3"
325290075Sobrien  [(set_attr "itanium_class" "fmac")])
325390075Sobrien
325490075Sobrien(define_insn "*msubtf4"
325590075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
325690075Sobrien	(minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
325790075Sobrien			   (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
325890075Sobrien		  (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
325990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
326090075Sobrien  "fms %0 = %F1, %F2, %F3"
326190075Sobrien  [(set_attr "itanium_class" "fmac")])
326290075Sobrien
326390075Sobrien(define_insn "*msubtf4_truncsf"
326490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
326590075Sobrien	(float_truncate:SF
326690075Sobrien	  (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
326790075Sobrien			     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
326890075Sobrien		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
326990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
327090075Sobrien  "fms.s %0 = %F1, %F2, %F3"
327190075Sobrien  [(set_attr "itanium_class" "fmac")])
327290075Sobrien
327390075Sobrien(define_insn "*msubtf4_truncdf"
327490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
327590075Sobrien	(float_truncate:DF
327690075Sobrien	  (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
327790075Sobrien			     (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
327890075Sobrien		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
327990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
328090075Sobrien  "fms.d %0 = %F1, %F2, %F3"
328190075Sobrien  [(set_attr "itanium_class" "fmac")])
328290075Sobrien
328390075Sobrien(define_insn "*nmultf3"
328490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
328590075Sobrien	(neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
328690075Sobrien			 (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
328790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
328890075Sobrien  "fnmpy %0 = %F1, %F2"
328990075Sobrien  [(set_attr "itanium_class" "fmac")])
329090075Sobrien
329190075Sobrien(define_insn "*nmultf3_truncsf"
329290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
329390075Sobrien	(float_truncate:SF
329490075Sobrien	  (neg:TF (mult:TF
329590075Sobrien		    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
329690075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
329790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
329890075Sobrien  "fnmpy.s %0 = %F1, %F2"
329990075Sobrien  [(set_attr "itanium_class" "fmac")])
330090075Sobrien
330190075Sobrien(define_insn "*nmultf3_truncdf"
330290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
330390075Sobrien	(float_truncate:DF
330490075Sobrien	  (neg:TF (mult:TF
330590075Sobrien		    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
330690075Sobrien		    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
330790075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
330890075Sobrien  "fnmpy.d %0 = %F1, %F2"
330990075Sobrien  [(set_attr "itanium_class" "fmac")])
331090075Sobrien
331190075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
331290075Sobrien
331390075Sobrien(define_insn "*nmaddtf4"
331490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
331590075Sobrien	(plus:TF (neg:TF (mult:TF
331690075Sobrien			  (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
331790075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
331890075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
331990075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
332090075Sobrien  "fnma %0 = %F1, %F2, %F3"
332190075Sobrien  [(set_attr "itanium_class" "fmac")])
332290075Sobrien
332390075Sobrien(define_insn "*nmaddtf4_truncsf"
332490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
332590075Sobrien	(float_truncate:SF
332690075Sobrien	  (plus:TF (neg:TF (mult:TF
332790075Sobrien			    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
332890075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
332990075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
333090075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
333190075Sobrien  "fnma.s %0 = %F1, %F2, %F3"
333290075Sobrien  [(set_attr "itanium_class" "fmac")])
333390075Sobrien
333490075Sobrien(define_insn "*nmaddtf4_truncdf"
333590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
333690075Sobrien	(float_truncate:DF
333790075Sobrien	  (plus:TF (neg:TF (mult:TF
333890075Sobrien			    (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
333990075Sobrien			    (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
334090075Sobrien		   (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
334190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
334290075Sobrien  "fnma.d %0 = %F1, %F2, %F3"
334390075Sobrien  [(set_attr "itanium_class" "fmac")])
334490075Sobrien
334590075Sobrien(define_insn "*nmaddtf4_alts"
334690075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
334790075Sobrien	(plus:TF (neg:TF (mult:TF
334890075Sobrien			  (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
334990075Sobrien			  (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
335090075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
335190075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
335290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
335390075Sobrien  "fnma.s%4 %0 = %F1, %F2, %F3"
335490075Sobrien  [(set_attr "itanium_class" "fmac")])
335590075Sobrien
335690075Sobrien(define_insn "*nmaddtf4_truncdf_alts"
335790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
335890075Sobrien	(float_truncate:DF
335990075Sobrien	  (plus:TF (neg:TF
336090075Sobrien		     (mult:TF
336190075Sobrien		       (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
336290075Sobrien		       (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
336390075Sobrien		 (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
336490075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
336590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
336690075Sobrien  "fnma.d.s%4 %0 = %F1, %F2, %F3"
336790075Sobrien  [(set_attr "itanium_class" "fmac")])
336890075Sobrien
336990075Sobrien(define_expand "divtf3"
337090075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "")
337190075Sobrien	(div:TF (match_operand:TF 1 "fr_register_operand" "")
337290075Sobrien		(match_operand:TF 2 "fr_register_operand" "")))]
337390075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV"
337490075Sobrien  "
337590075Sobrien{
337690075Sobrien  rtx insn;
337790075Sobrien  if (TARGET_INLINE_DIV_LAT)
337890075Sobrien    insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]);
337990075Sobrien  else
338090075Sobrien    insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]);
338190075Sobrien  emit_insn (insn);
338290075Sobrien  DONE;
338390075Sobrien}")
338490075Sobrien
338590075Sobrien(define_insn_and_split "divtf3_internal_lat"
338690075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
338790075Sobrien	(div:TF (match_operand:TF 1 "fr_register_operand" "f")
338890075Sobrien		(match_operand:TF 2 "fr_register_operand" "f")))
338990075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
339090075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
339190075Sobrien   (clobber (match_scratch:TF 5 "=&f"))
339290075Sobrien   (clobber (match_scratch:TF 6 "=&f"))
339390075Sobrien   (clobber (match_scratch:BI 7 "=c"))]
339490075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_LAT"
339590075Sobrien  "#"
339690075Sobrien  "&& reload_completed"
339790075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
339890075Sobrien	      (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
339990075Sobrien	      (use (const_int 1))])
340090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
340190075Sobrien     (parallel [(set (match_dup 3)
340290075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
340390075Sobrien			      (match_dup 8)))
340490075Sobrien		(use (const_int 1))]))
340590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
340690075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
340790075Sobrien		(use (const_int 1))]))
340890075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
340990075Sobrien     (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
341090075Sobrien		(use (const_int 1))]))
341190075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
341290075Sobrien     (parallel [(set (match_dup 6)
341390075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 3))
341490075Sobrien			      (match_dup 3)))
341590075Sobrien		(use (const_int 1))]))
341690075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
341790075Sobrien     (parallel [(set (match_dup 3)
341890075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 5))
341990075Sobrien			      (match_dup 3)))
342090075Sobrien		(use (const_int 1))]))
342190075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
342290075Sobrien     (parallel [(set (match_dup 5)
342390075Sobrien		     (plus:TF (mult:TF (match_dup 6) (match_dup 0))
342490075Sobrien			      (match_dup 0)))
342590075Sobrien		(use (const_int 1))]))
342690075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
342790075Sobrien     (parallel [(set (match_dup 0)
342890075Sobrien		     (plus:TF (mult:TF (match_dup 5) (match_dup 3))
342990075Sobrien			      (match_dup 0)))
343090075Sobrien		(use (const_int 1))]))
343190075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
343290075Sobrien     (parallel [(set (match_dup 4)
343390075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
343490075Sobrien			      (match_dup 1)))
343590075Sobrien		(use (const_int 1))]))
343690075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
343790075Sobrien     (parallel [(set (match_dup 3)
343890075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
343990075Sobrien			      (match_dup 4)))
344090075Sobrien		(use (const_int 1))]))
344190075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
344290075Sobrien     (parallel [(set (match_dup 5)
344390075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
344490075Sobrien			      (match_dup 8)))
344590075Sobrien		(use (const_int 1))]))
344690075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
344790075Sobrien     (parallel [(set (match_dup 0)
344890075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
344990075Sobrien			      (match_dup 0)))
345090075Sobrien		(use (const_int 1))]))
345190075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
345290075Sobrien     (parallel [(set (match_dup 4)
345390075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
345490075Sobrien			      (match_dup 1)))
345590075Sobrien		(use (const_int 1))]))
345690075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
345790075Sobrien     (set (match_dup 0)
345890075Sobrien	  (plus:TF (mult:TF (match_dup 4) (match_dup 0))
345990075Sobrien		   (match_dup 3))))
346090075Sobrien  ] 
346190075Sobrien  "operands[8] = CONST1_RTX (TFmode);"
346290075Sobrien  [(set_attr "predicable" "no")])
346390075Sobrien
346490075Sobrien(define_insn_and_split "divtf3_internal_thr"
346590075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=&f")
346690075Sobrien	(div:TF (match_operand:TF 1 "fr_register_operand" "f")
346790075Sobrien		(match_operand:TF 2 "fr_register_operand" "f")))
346890075Sobrien   (clobber (match_scratch:TF 3 "=&f"))
346990075Sobrien   (clobber (match_scratch:TF 4 "=&f"))
347090075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
347190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_DIV_THR"
347290075Sobrien  "#"
347390075Sobrien  "&& reload_completed"
347490075Sobrien  [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
347590075Sobrien	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
347690075Sobrien	      (use (const_int 1))])
347790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
347890075Sobrien     (parallel [(set (match_dup 3)
347990075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
348090075Sobrien			      (match_dup 6)))
348190075Sobrien		(use (const_int 1))]))
348290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
348390075Sobrien     (parallel [(set (match_dup 4)
348490075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
348590075Sobrien			      (match_dup 0)))
348690075Sobrien		(use (const_int 1))]))
348790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
348890075Sobrien     (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
348990075Sobrien		(use (const_int 1))]))
349090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
349190075Sobrien     (parallel [(set (match_dup 3)
349290075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 4))
349390075Sobrien			      (match_dup 4)))
349490075Sobrien		(use (const_int 1))]))
349590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
349690075Sobrien     (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
349790075Sobrien		(use (const_int 1))]))
349890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
349990075Sobrien     (parallel [(set (match_dup 0)
350090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
350190075Sobrien			      (match_dup 6)))
350290075Sobrien		(use (const_int 1))]))
350390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
350490075Sobrien     (parallel [(set (match_dup 0)
350590075Sobrien		     (plus:TF (mult:TF (match_dup 0) (match_dup 3))
350690075Sobrien			      (match_dup 3)))
350790075Sobrien		(use (const_int 1))]))
350890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
350990075Sobrien     (parallel [(set (match_dup 3)
351090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
351190075Sobrien			      (match_dup 1)))
351290075Sobrien		(use (const_int 1))]))
351390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
351490075Sobrien     (parallel [(set (match_dup 3)
351590075Sobrien		     (plus:TF (mult:TF (match_dup 3) (match_dup 0))
351690075Sobrien			      (match_dup 4)))
351790075Sobrien		(use (const_int 1))]))
351890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
351990075Sobrien     (parallel [(set (match_dup 4)
352090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
352190075Sobrien			      (match_dup 6)))
352290075Sobrien		(use (const_int 1))]))
352390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
352490075Sobrien     (parallel [(set (match_dup 0)
352590075Sobrien		     (plus:TF (mult:TF (match_dup 4) (match_dup 0))
352690075Sobrien			      (match_dup 0)))
352790075Sobrien		(use (const_int 1))]))
352890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
352990075Sobrien     (parallel [(set (match_dup 4)
353090075Sobrien		     (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
353190075Sobrien			      (match_dup 1)))
353290075Sobrien		(use (const_int 1))]))
353390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
353490075Sobrien     (set (match_dup 0)
353590075Sobrien	  (plus:TF (mult:TF (match_dup 4) (match_dup 0))
353690075Sobrien		   (match_dup 3))))
353790075Sobrien  ] 
353890075Sobrien  "operands[6] = CONST1_RTX (TFmode);"
353990075Sobrien  [(set_attr "predicable" "no")])
354090075Sobrien
354190075Sobrien;; ??? frcpa works like cmp.foo.unc.
354290075Sobrien
354390075Sobrien(define_insn "*recip_approx"
354490075Sobrien  [(set (match_operand:TF 0 "fr_register_operand" "=f")
354590075Sobrien	(div:TF (const_int 1)
354690075Sobrien		(match_operand:TF 3 "fr_register_operand" "f")))
354790075Sobrien   (set (match_operand:BI 1 "register_operand" "=c")
354890075Sobrien	(unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
354990075Sobrien		    (match_dup 3)] 5))
355090075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
355190075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
355290075Sobrien  "frcpa.s%4 %0, %1 = %2, %3"
355390075Sobrien  [(set_attr "itanium_class" "fmisc")
355490075Sobrien   (set_attr "predicable" "no")])
355590075Sobrien
355690075Sobrien;; ::::::::::::::::::::
355790075Sobrien;; ::
355890075Sobrien;; :: 32 bit Integer Shifts and Rotates
355990075Sobrien;; ::
356090075Sobrien;; ::::::::::::::::::::
356190075Sobrien
356290075Sobrien(define_expand "ashlsi3"
356390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
356490075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "")
356590075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
356690075Sobrien  ""
356790075Sobrien  "
356890075Sobrien{
356990075Sobrien  if (GET_CODE (operands[2]) != CONST_INT)
357090075Sobrien    {
357190075Sobrien      /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
357290075Sobrien	 we've got to get rid of stray bits outside the SImode register.  */
357390075Sobrien      rtx subshift = gen_reg_rtx (DImode);
357490075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
357590075Sobrien      operands[2] = subshift;
357690075Sobrien    }
357790075Sobrien}")
357890075Sobrien
357990075Sobrien(define_insn "*ashlsi3_internal"
358090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
358190075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
358290075Sobrien		   (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
358390075Sobrien  ""
358490075Sobrien  "@
358590075Sobrien   shladd %0 = %1, %2, r0
358690075Sobrien   dep.z %0 = %1, %2, %E2
358790075Sobrien   shl %0 = %1, %2"
358890075Sobrien  [(set_attr "itanium_class" "ialu,ishf,mmshf")])
358990075Sobrien
359090075Sobrien(define_expand "ashrsi3"
359190075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
359290075Sobrien	(ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
359390075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
359490075Sobrien  ""
359590075Sobrien  "
359690075Sobrien{
359790075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
359890075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
359990075Sobrien    emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
360090075Sobrien			 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
360190075Sobrien  else
360290075Sobrien    {
360390075Sobrien      rtx subshift = gen_reg_rtx (DImode);
360490075Sobrien      emit_insn (gen_extendsidi2 (subtarget, operands[1]));
360590075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
360690075Sobrien      emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
360790075Sobrien    }
360890075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
360990075Sobrien  DONE;
361090075Sobrien}")
361190075Sobrien
361290075Sobrien(define_expand "lshrsi3"
361390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
361490075Sobrien	(lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
361590075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
361690075Sobrien  ""
361790075Sobrien  "
361890075Sobrien{
361990075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
362090075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
362190075Sobrien    emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
362290075Sobrien			  GEN_INT (32 - INTVAL (operands[2])), operands[2]));
362390075Sobrien  else
362490075Sobrien    {
362590075Sobrien      rtx subshift = gen_reg_rtx (DImode);
362690075Sobrien      emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
362790075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
362890075Sobrien      emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
362990075Sobrien    }
363090075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
363190075Sobrien  DONE;
363290075Sobrien}")
363390075Sobrien
363490075Sobrien;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
363590075Sobrien;; here, instead of 64 like the patterns above.  Keep the pattern together
363690075Sobrien;; until after combine; otherwise it won't get matched often.
363790075Sobrien
363890075Sobrien(define_expand "rotrsi3"
363990075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
364090075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
364190075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
364290075Sobrien  ""
364390075Sobrien  "
364490075Sobrien{
364590075Sobrien  if (GET_MODE (operands[2]) != VOIDmode)
364690075Sobrien    {
364790075Sobrien      rtx tmp = gen_reg_rtx (DImode);
364890075Sobrien      emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
364990075Sobrien      operands[2] = tmp;
365090075Sobrien    }
365190075Sobrien}")
365290075Sobrien
365390075Sobrien(define_insn_and_split "*rotrsi3_internal"
365490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=&r")
365590075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
365690075Sobrien		     (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
365790075Sobrien  ""
365890075Sobrien  "#"
365990075Sobrien  "reload_completed"
366090075Sobrien  [(set (match_dup 3)
366190075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
366290075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
366390075Sobrien   (set (match_dup 3)
366490075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
366590075Sobrien  "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
366690075Sobrien
366790075Sobrien(define_expand "rotlsi3"
366890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
366990075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "")
367090075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
367190075Sobrien  ""
367290075Sobrien  "
367390075Sobrien{
367490075Sobrien  if (! shift_32bit_count_operand (operands[2], SImode))
367590075Sobrien    {
367690075Sobrien      rtx tmp = gen_reg_rtx (SImode);
367790075Sobrien      emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
367890075Sobrien      emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
367990075Sobrien      DONE;
368090075Sobrien    }
368190075Sobrien}")
368290075Sobrien
368390075Sobrien(define_insn_and_split "*rotlsi3_internal"
368490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
368590075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
368690075Sobrien		   (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
368790075Sobrien  ""
368890075Sobrien  "#"
368990075Sobrien  "reload_completed"
369090075Sobrien  [(set (match_dup 3)
369190075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
369290075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
369390075Sobrien   (set (match_dup 3)
369490075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
369590075Sobrien  "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
369690075Sobrien   operands[2] = GEN_INT (32 - INTVAL (operands[2]));")
369790075Sobrien
369890075Sobrien;; ::::::::::::::::::::
369990075Sobrien;; ::
370090075Sobrien;; :: 64 bit Integer Shifts and Rotates
370190075Sobrien;; ::
370290075Sobrien;; ::::::::::::::::::::
370390075Sobrien
370490075Sobrien(define_insn "ashldi3"
370590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
370690075Sobrien	(ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
370790075Sobrien		   (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
370890075Sobrien  ""
370990075Sobrien  "@
371090075Sobrien   shladd %0 = %1, %2, r0
371190075Sobrien   shl %0 = %1, %2
371290075Sobrien   shl %0 = %1, %2"
371390075Sobrien  [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
371490075Sobrien
371590075Sobrien;; ??? Maybe combine this with the multiply and add instruction?
371690075Sobrien
371790075Sobrien(define_insn "*shladd"
371890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
371990075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
372090075Sobrien			  (match_operand:DI 2 "shladd_operand" "n"))
372190075Sobrien		 (match_operand:DI 3 "gr_register_operand" "r")))]
372290075Sobrien  ""
372390075Sobrien  "shladd %0 = %1, %S2, %3"
372490075Sobrien  [(set_attr "itanium_class" "ialu")])
372590075Sobrien
372690075Sobrien;; This can be created by register elimination if operand3 of shladd is an
372790075Sobrien;; eliminable register or has reg_equiv_constant set.
372890075Sobrien
372990075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
373090075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
373190075Sobrien;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
373290075Sobrien;; incorrectly.
373390075Sobrien
373490075Sobrien(define_insn_and_split "*shladd_elim"
373590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=&r")
373690075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
373790075Sobrien				   (match_operand:DI 2 "shladd_operand" "n"))
373890075Sobrien			  (match_operand:DI 3 "nonmemory_operand" "r"))
373990075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))]
374090075Sobrien  "reload_in_progress"
374190075Sobrien  "* abort ();"
374290075Sobrien  "reload_completed"
374390075Sobrien  [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
374490075Sobrien			       (match_dup 3)))
374590075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
374690075Sobrien  ""
374790075Sobrien  [(set_attr "itanium_class" "unknown")])
374890075Sobrien
374990075Sobrien(define_insn "ashrdi3"
375090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
375190075Sobrien	(ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
375290075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
375390075Sobrien  ""
375490075Sobrien  "@
375590075Sobrien   shr %0 = %1, %2
375690075Sobrien   shr %0 = %1, %2"
375790075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
375890075Sobrien
375990075Sobrien(define_insn "lshrdi3"
376090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
376190075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
376290075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
376390075Sobrien  ""
376490075Sobrien  "@
376590075Sobrien   shr.u %0 = %1, %2
376690075Sobrien   shr.u %0 = %1, %2"
376790075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
376890075Sobrien
376990075Sobrien;; Using a predicate that accepts only constants doesn't work, because optabs
377090075Sobrien;; will load the operand into a register and call the pattern if the predicate
377190075Sobrien;; did not accept it on the first try.  So we use nonmemory_operand and then
377290075Sobrien;; verify that we have an appropriate constant in the expander.
377390075Sobrien
377490075Sobrien(define_expand "rotrdi3"
377590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
377690075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
377790075Sobrien		     (match_operand:DI 2 "nonmemory_operand" "")))]
377890075Sobrien  ""
377990075Sobrien  "
378090075Sobrien{
378190075Sobrien  if (! shift_count_operand (operands[2], DImode))
378290075Sobrien    FAIL;
378390075Sobrien}")
378490075Sobrien
378590075Sobrien(define_insn "*rotrdi3_internal"
378690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
378790075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
378890075Sobrien		     (match_operand:DI 2 "shift_count_operand" "M")))]
378990075Sobrien  ""
379090075Sobrien  "shrp %0 = %1, %1, %2"
379190075Sobrien  [(set_attr "itanium_class" "ishf")])
379290075Sobrien
379390075Sobrien(define_expand "rotldi3"
379490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
379590075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "")
379690075Sobrien		   (match_operand:DI 2 "nonmemory_operand" "")))]
379790075Sobrien  ""
379890075Sobrien  "
379990075Sobrien{
380090075Sobrien  if (! shift_count_operand (operands[2], DImode))
380190075Sobrien    FAIL;
380290075Sobrien}")
380390075Sobrien
380490075Sobrien(define_insn "*rotldi3_internal"
380590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
380690075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
380790075Sobrien		   (match_operand:DI 2 "shift_count_operand" "M")))]
380890075Sobrien  ""
380990075Sobrien  "shrp %0 = %1, %1, %e2"
381090075Sobrien  [(set_attr "itanium_class" "ishf")])
381190075Sobrien
381290075Sobrien;; ::::::::::::::::::::
381390075Sobrien;; ::
381490075Sobrien;; :: 32 bit Integer Logical operations
381590075Sobrien;; ::
381690075Sobrien;; ::::::::::::::::::::
381790075Sobrien
381890075Sobrien;; We don't seem to need any other 32-bit logical operations, because gcc
381990075Sobrien;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
382090075Sobrien;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
382190075Sobrien;; This doesn't work for unary logical operations, because we don't call
382290075Sobrien;; apply_distributive_law for them.
382390075Sobrien
382490075Sobrien;; ??? Likewise, this doesn't work for andnot, which isn't handled by
382590075Sobrien;; apply_distributive_law.  We get inefficient code for
382690075Sobrien;; int sub4 (int i, int j) { return i & ~j; }
382790075Sobrien;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
382890075Sobrien;; (zero_extend (and (not A) B)) in combine.
382990075Sobrien;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
383090075Sobrien;; one_cmplsi2 pattern.
383190075Sobrien
383290075Sobrien(define_insn "one_cmplsi2"
383390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
383490075Sobrien	(not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
383590075Sobrien  ""
383690075Sobrien  "andcm %0 = -1, %1"
383790075Sobrien  [(set_attr "itanium_class" "ilog")])
383890075Sobrien
383990075Sobrien;; ::::::::::::::::::::
384090075Sobrien;; ::
384190075Sobrien;; :: 64 bit Integer Logical operations
384290075Sobrien;; ::
384390075Sobrien;; ::::::::::::::::::::
384490075Sobrien
384590075Sobrien(define_insn "anddi3"
384690075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
384790075Sobrien	(and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
384890075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
384990075Sobrien  ""
385090075Sobrien  "@
385190075Sobrien   and %0 = %2, %1
385290075Sobrien   fand %0 = %2, %1"
385390075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
385490075Sobrien
385590075Sobrien(define_insn "*andnot"
385690075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
385790075Sobrien	(and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
385890075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
385990075Sobrien  ""
386090075Sobrien  "@
386190075Sobrien   andcm %0 = %2, %1
386290075Sobrien   fandcm %0 = %2, %1"
386390075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
386490075Sobrien
386590075Sobrien(define_insn "iordi3"
386690075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
386790075Sobrien	(ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
386890075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
386990075Sobrien  ""
387090075Sobrien  "@
387190075Sobrien   or %0 = %2, %1
387290075Sobrien   for %0 = %2, %1"
387390075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
387490075Sobrien
387590075Sobrien(define_insn "xordi3"
387690075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
387790075Sobrien	(xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
387890075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
387990075Sobrien  ""
388090075Sobrien  "@
388190075Sobrien   xor %0 = %2, %1
388290075Sobrien   fxor %0 = %2, %1"
388390075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
388490075Sobrien
388590075Sobrien(define_insn "one_cmpldi2"
388690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
388790075Sobrien	(not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
388890075Sobrien  ""
388990075Sobrien  "andcm %0 = -1, %1"
389090075Sobrien  [(set_attr "itanium_class" "ilog")])
389190075Sobrien
389290075Sobrien;; ::::::::::::::::::::
389390075Sobrien;; ::
389490075Sobrien;; :: Comparisons
389590075Sobrien;; ::
389690075Sobrien;; ::::::::::::::::::::
389790075Sobrien
389890075Sobrien(define_expand "cmpbi"
389990075Sobrien  [(set (cc0)
390090075Sobrien        (compare (match_operand:BI 0 "register_operand" "")
390190075Sobrien  		 (match_operand:BI 1 "const_int_operand" "")))]
390290075Sobrien  ""
390390075Sobrien  "
390490075Sobrien{
390590075Sobrien  ia64_compare_op0 = operands[0];
390690075Sobrien  ia64_compare_op1 = operands[1];
390790075Sobrien  DONE;
390890075Sobrien}")
390990075Sobrien
391090075Sobrien(define_expand "cmpsi"
391190075Sobrien  [(set (cc0)
391290075Sobrien        (compare (match_operand:SI 0 "gr_register_operand" "")
391390075Sobrien  		 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
391490075Sobrien  ""
391590075Sobrien  "
391690075Sobrien{
391790075Sobrien  ia64_compare_op0 = operands[0];
391890075Sobrien  ia64_compare_op1 = operands[1];
391990075Sobrien  DONE;
392090075Sobrien}")
392190075Sobrien
392290075Sobrien(define_expand "cmpdi"
392390075Sobrien  [(set (cc0)
392490075Sobrien        (compare (match_operand:DI 0 "gr_register_operand" "")
392590075Sobrien  		 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
392690075Sobrien  ""
392790075Sobrien  "
392890075Sobrien{
392990075Sobrien  ia64_compare_op0 = operands[0];
393090075Sobrien  ia64_compare_op1 = operands[1];
393190075Sobrien  DONE;
393290075Sobrien}")
393390075Sobrien
393490075Sobrien(define_expand "cmpsf"
393590075Sobrien  [(set (cc0)
393690075Sobrien        (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
393790075Sobrien  		 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
393890075Sobrien  ""
393990075Sobrien  "
394090075Sobrien{
394190075Sobrien  ia64_compare_op0 = operands[0];
394290075Sobrien  ia64_compare_op1 = operands[1];
394390075Sobrien  DONE;
394490075Sobrien}")
394590075Sobrien
394690075Sobrien(define_expand "cmpdf"
394790075Sobrien  [(set (cc0)
394890075Sobrien        (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
394990075Sobrien  		 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
395090075Sobrien  ""
395190075Sobrien  "
395290075Sobrien{
395390075Sobrien  ia64_compare_op0 = operands[0];
395490075Sobrien  ia64_compare_op1 = operands[1];
395590075Sobrien  DONE;
395690075Sobrien}")
395790075Sobrien
395890075Sobrien(define_expand "cmptf"
395990075Sobrien  [(set (cc0)
396090075Sobrien        (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
396190075Sobrien  		 (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
396290075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
396390075Sobrien  "
396490075Sobrien{
396590075Sobrien  ia64_compare_op0 = operands[0];
396690075Sobrien  ia64_compare_op1 = operands[1];
396790075Sobrien  DONE;
396890075Sobrien}")
396990075Sobrien
397090075Sobrien(define_insn "*cmpsi_normal"
397190075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
397290075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
397390075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
397490075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
397590075Sobrien  ""
397690075Sobrien  "cmp4.%C1 %0, %I0 = %3, %2"
397790075Sobrien  [(set_attr "itanium_class" "icmp")])
397890075Sobrien
397990075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
398090075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
398190075Sobrien
398290075Sobrien(define_insn "*cmpsi_adjusted"
398390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
398490075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
398590075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
398690075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
398790075Sobrien  ""
398890075Sobrien  "cmp4.%C1 %0, %I0 = %r3, %2"
398990075Sobrien  [(set_attr "itanium_class" "icmp")])
399090075Sobrien
399190075Sobrien(define_insn "*cmpdi_normal"
399290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
399390075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
399490075Sobrien	   [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
399590075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
399690075Sobrien  ""
399790075Sobrien  "cmp.%C1 %0, %I0 = %3, %r2"
399890075Sobrien  [(set_attr "itanium_class" "icmp")])
399990075Sobrien
400090075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
400190075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
400290075Sobrien
400390075Sobrien(define_insn "*cmpdi_adjusted"
400490075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
400590075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
400690075Sobrien	   [(match_operand:DI 2 "gr_register_operand" "r")
400790075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
400890075Sobrien  ""
400990075Sobrien  "cmp.%C1 %0, %I0 = %r3, %2"
401090075Sobrien  [(set_attr "itanium_class" "icmp")])
401190075Sobrien
401290075Sobrien(define_insn "*cmpsf_internal"
401390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
401490075Sobrien	(match_operator:BI 1 "comparison_operator"
401590075Sobrien	   [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
401690075Sobrien	    (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
401790075Sobrien  ""
401890075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
401990075Sobrien  [(set_attr "itanium_class" "fcmp")])
402090075Sobrien
402190075Sobrien(define_insn "*cmpdf_internal"
402290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
402390075Sobrien	(match_operator:BI 1 "comparison_operator"
402490075Sobrien	   [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
402590075Sobrien	    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
402690075Sobrien  ""
402790075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
402890075Sobrien  [(set_attr "itanium_class" "fcmp")])
402990075Sobrien
403090075Sobrien(define_insn "*cmptf_internal"
403190075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
403290075Sobrien	(match_operator:BI 1 "comparison_operator"
403390075Sobrien		   [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
403490075Sobrien		    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
403590075Sobrien  "INTEL_EXTENDED_IEEE_FORMAT"
403690075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
403790075Sobrien  [(set_attr "itanium_class" "fcmp")])
403890075Sobrien
403990075Sobrien;; ??? Can this pattern be generated?
404090075Sobrien
404190075Sobrien(define_insn "*bit_zero"
404290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
404390075Sobrien	(eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
404490075Sobrien				(const_int 1)
404590075Sobrien				(match_operand:DI 2 "immediate_operand" "n"))
404690075Sobrien	       (const_int 0)))]
404790075Sobrien  ""
404890075Sobrien  "tbit.z %0, %I0 = %1, %2"
404990075Sobrien  [(set_attr "itanium_class" "tbit")])
405090075Sobrien
405190075Sobrien(define_insn "*bit_one"
405290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
405390075Sobrien	(ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
405490075Sobrien				(const_int 1)
405590075Sobrien				(match_operand:DI 2 "immediate_operand" "n"))
405690075Sobrien	       (const_int 0)))]
405790075Sobrien  ""
405890075Sobrien  "tbit.nz %0, %I0 = %1, %2"
405990075Sobrien  [(set_attr "itanium_class" "tbit")])
406090075Sobrien
406190075Sobrien;; ::::::::::::::::::::
406290075Sobrien;; ::
406390075Sobrien;; :: Branches
406490075Sobrien;; ::
406590075Sobrien;; ::::::::::::::::::::
406690075Sobrien
406790075Sobrien(define_expand "beq"
406890075Sobrien  [(set (pc)
406990075Sobrien	(if_then_else (match_dup 1)
407090075Sobrien		      (label_ref (match_operand 0 "" ""))
407190075Sobrien		      (pc)))]
407290075Sobrien  ""
407390075Sobrien  "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
407490075Sobrien
407590075Sobrien(define_expand "bne"
407690075Sobrien  [(set (pc)
407790075Sobrien	(if_then_else (match_dup 1)
407890075Sobrien		      (label_ref (match_operand 0 "" ""))
407990075Sobrien		      (pc)))]
408090075Sobrien  ""
408190075Sobrien  "operands[1] = ia64_expand_compare (NE, VOIDmode);")
408290075Sobrien
408390075Sobrien(define_expand "blt"
408490075Sobrien  [(set (pc)
408590075Sobrien	(if_then_else (match_dup 1)
408690075Sobrien		      (label_ref (match_operand 0 "" ""))
408790075Sobrien		      (pc)))]
408890075Sobrien  ""
408990075Sobrien  "operands[1] = ia64_expand_compare (LT, VOIDmode);")
409090075Sobrien
409190075Sobrien(define_expand "ble"
409290075Sobrien  [(set (pc)
409390075Sobrien	(if_then_else (match_dup 1)
409490075Sobrien		      (label_ref (match_operand 0 "" ""))
409590075Sobrien		      (pc)))]
409690075Sobrien  ""
409790075Sobrien  "operands[1] = ia64_expand_compare (LE, VOIDmode);")
409890075Sobrien
409990075Sobrien(define_expand "bgt"
410090075Sobrien  [(set (pc)
410190075Sobrien	(if_then_else (match_dup 1)
410290075Sobrien		      (label_ref (match_operand 0 "" ""))
410390075Sobrien		      (pc)))]
410490075Sobrien  ""
410590075Sobrien  "operands[1] = ia64_expand_compare (GT, VOIDmode);")
410690075Sobrien
410790075Sobrien(define_expand "bge"
410890075Sobrien  [(set (pc)
410990075Sobrien	(if_then_else (match_dup 1)
411090075Sobrien		      (label_ref (match_operand 0 "" ""))
411190075Sobrien		      (pc)))]
411290075Sobrien  ""
411390075Sobrien  "operands[1] = ia64_expand_compare (GE, VOIDmode);")
411490075Sobrien
411590075Sobrien(define_expand "bltu"
411690075Sobrien  [(set (pc)
411790075Sobrien	(if_then_else (match_dup 1)
411890075Sobrien		      (label_ref (match_operand 0 "" ""))
411990075Sobrien		      (pc)))]
412090075Sobrien  ""
412190075Sobrien  "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
412290075Sobrien
412390075Sobrien(define_expand "bleu"
412490075Sobrien  [(set (pc)
412590075Sobrien	(if_then_else (match_dup 1)
412690075Sobrien		      (label_ref (match_operand 0 "" ""))
412790075Sobrien		      (pc)))]
412890075Sobrien  ""
412990075Sobrien  "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
413090075Sobrien
413190075Sobrien(define_expand "bgtu"
413290075Sobrien  [(set (pc)
413390075Sobrien	(if_then_else (match_dup 1)
413490075Sobrien		      (label_ref (match_operand 0 "" ""))
413590075Sobrien		      (pc)))]
413690075Sobrien  ""
413790075Sobrien  "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
413890075Sobrien
413990075Sobrien(define_expand "bgeu"
414090075Sobrien  [(set (pc)
414190075Sobrien	(if_then_else (match_dup 1)
414290075Sobrien		      (label_ref (match_operand 0 "" ""))
414390075Sobrien		      (pc)))]
414490075Sobrien  ""
414590075Sobrien  "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
414690075Sobrien
414790075Sobrien(define_expand "bunordered"
414890075Sobrien  [(set (pc)
414990075Sobrien	(if_then_else (match_dup 1)
415090075Sobrien		      (label_ref (match_operand 0 "" ""))
415190075Sobrien		      (pc)))]
415290075Sobrien  ""
415390075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
415490075Sobrien
415590075Sobrien(define_expand "bordered"
415690075Sobrien  [(set (pc)
415790075Sobrien	(if_then_else (match_dup 1)
415890075Sobrien		      (label_ref (match_operand 0 "" ""))
415990075Sobrien		      (pc)))]
416090075Sobrien  ""
416190075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
416290075Sobrien
416390075Sobrien(define_insn "*br_true"
416490075Sobrien  [(set (pc)
416590075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
416690075Sobrien			[(match_operand:BI 1 "register_operand" "c")
416790075Sobrien			 (const_int 0)])
416890075Sobrien		      (label_ref (match_operand 2 "" ""))
416990075Sobrien		      (pc)))]
417090075Sobrien  ""
417190075Sobrien  "(%J0) br.cond%+ %l2"
417290075Sobrien  [(set_attr "itanium_class" "br")
417390075Sobrien   (set_attr "predicable" "no")])
417490075Sobrien
417590075Sobrien(define_insn "*br_false"
417690075Sobrien  [(set (pc)
417790075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
417890075Sobrien			[(match_operand:BI 1 "register_operand" "c")
417990075Sobrien			 (const_int 0)])
418090075Sobrien		      (pc)
418190075Sobrien		      (label_ref (match_operand 2 "" ""))))]
418290075Sobrien  ""
418390075Sobrien  "(%j0) br.cond%+ %l2"
418490075Sobrien  [(set_attr "itanium_class" "br")
418590075Sobrien   (set_attr "predicable" "no")])
418690075Sobrien
418790075Sobrien;; ::::::::::::::::::::
418890075Sobrien;; ::
418990075Sobrien;; :: Counted loop operations
419090075Sobrien;; ::
419190075Sobrien;; ::::::::::::::::::::
419290075Sobrien
419390075Sobrien(define_expand "doloop_end"
419490075Sobrien  [(use (match_operand 0 "" ""))	; loop pseudo
419590075Sobrien   (use (match_operand 1 "" ""))	; iterations; zero if unknown
419690075Sobrien   (use (match_operand 2 "" ""))	; max iterations
419790075Sobrien   (use (match_operand 3 "" ""))	; loop level
419890075Sobrien   (use (match_operand 4 "" ""))]	; label
419990075Sobrien  ""
420090075Sobrien  "
420190075Sobrien{
420290075Sobrien  /* Only use cloop on innermost loops.  */
420390075Sobrien  if (INTVAL (operands[3]) > 1)
420490075Sobrien    FAIL;
420590075Sobrien  emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
420690075Sobrien					   operands[4]));
420790075Sobrien  DONE;
420890075Sobrien}")
420990075Sobrien
421090075Sobrien(define_insn "doloop_end_internal"
421190075Sobrien  [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
421290075Sobrien			       (const_int 0))
421390075Sobrien		(label_ref (match_operand 1 "" ""))
421490075Sobrien		(pc)))
421590075Sobrien   (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
421690075Sobrien			 (match_dup 0)
421790075Sobrien			 (plus:DI (match_dup 0) (const_int -1))))]
421890075Sobrien  ""
421990075Sobrien  "br.cloop.sptk.few %l1"
422090075Sobrien  [(set_attr "itanium_class" "br")
422190075Sobrien   (set_attr "predicable" "no")])
422290075Sobrien
422390075Sobrien;; ::::::::::::::::::::
422490075Sobrien;; ::
422590075Sobrien;; :: Set flag operations
422690075Sobrien;; ::
422790075Sobrien;; ::::::::::::::::::::
422890075Sobrien
422990075Sobrien(define_expand "seq"
423090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
423190075Sobrien  ""
423290075Sobrien  "operands[1] = ia64_expand_compare (EQ, DImode);")
423390075Sobrien
423490075Sobrien(define_expand "sne"
423590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
423690075Sobrien  ""
423790075Sobrien  "operands[1] = ia64_expand_compare (NE, DImode);")
423890075Sobrien
423990075Sobrien(define_expand "slt"
424090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
424190075Sobrien  ""
424290075Sobrien  "operands[1] = ia64_expand_compare (LT, DImode);")
424390075Sobrien
424490075Sobrien(define_expand "sle"
424590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
424690075Sobrien  ""
424790075Sobrien  "operands[1] = ia64_expand_compare (LE, DImode);")
424890075Sobrien
424990075Sobrien(define_expand "sgt"
425090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
425190075Sobrien  ""
425290075Sobrien  "operands[1] = ia64_expand_compare (GT, DImode);")
425390075Sobrien
425490075Sobrien(define_expand "sge"
425590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
425690075Sobrien  ""
425790075Sobrien  "operands[1] = ia64_expand_compare (GE, DImode);")
425890075Sobrien
425990075Sobrien(define_expand "sltu"
426090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
426190075Sobrien  ""
426290075Sobrien  "operands[1] = ia64_expand_compare (LTU, DImode);")
426390075Sobrien
426490075Sobrien(define_expand "sleu"
426590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
426690075Sobrien  ""
426790075Sobrien  "operands[1] = ia64_expand_compare (LEU, DImode);")
426890075Sobrien
426990075Sobrien(define_expand "sgtu"
427090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
427190075Sobrien  ""
427290075Sobrien  "operands[1] = ia64_expand_compare (GTU, DImode);")
427390075Sobrien
427490075Sobrien(define_expand "sgeu"
427590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
427690075Sobrien  ""
427790075Sobrien  "operands[1] = ia64_expand_compare (GEU, DImode);")
427890075Sobrien
427990075Sobrien(define_expand "sunordered"
428090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
428190075Sobrien  ""
428290075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
428390075Sobrien
428490075Sobrien(define_expand "sordered"
428590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
428690075Sobrien  ""
428790075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, DImode);")
428890075Sobrien
428990075Sobrien;; Don't allow memory as destination here, because cmov/cmov/st is more
429090075Sobrien;; efficient than mov/mov/cst/cst.
429190075Sobrien
429290075Sobrien(define_insn_and_split "*sne_internal"
429390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
429490075Sobrien	(ne:DI (match_operand:BI 1 "register_operand" "c")
429590075Sobrien	       (const_int 0)))]
429690075Sobrien  ""
429790075Sobrien  "#"
429890075Sobrien  "reload_completed"
429990075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
430090075Sobrien     (set (match_dup 0) (const_int 1)))
430190075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
430290075Sobrien     (set (match_dup 0) (const_int 0)))]
430390075Sobrien  ""
430490075Sobrien  [(set_attr "itanium_class" "unknown")])
430590075Sobrien
430690075Sobrien(define_insn_and_split "*seq_internal"
430790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
430890075Sobrien	(eq:DI (match_operand:BI 1 "register_operand" "c")
430990075Sobrien	       (const_int 0)))]
431090075Sobrien  ""
431190075Sobrien  "#"
431290075Sobrien  "reload_completed"
431390075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
431490075Sobrien     (set (match_dup 0) (const_int 0)))
431590075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
431690075Sobrien     (set (match_dup 0) (const_int 1)))]
431790075Sobrien  ""
431890075Sobrien  [(set_attr "itanium_class" "unknown")])
431990075Sobrien
432090075Sobrien;; ::::::::::::::::::::
432190075Sobrien;; ::
432290075Sobrien;; :: Conditional move instructions.
432390075Sobrien;; ::
432490075Sobrien;; ::::::::::::::::::::
432590075Sobrien
432690075Sobrien;; ??? Add movXXcc patterns?
432790075Sobrien
432890075Sobrien;;
432990075Sobrien;; DImode if_then_else patterns.
433090075Sobrien;;
433190075Sobrien
433290075Sobrien(define_insn "*cmovdi_internal"
433390075Sobrien  [(set (match_operand:DI 0 "destination_operand"
433490075Sobrien	   "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
433590075Sobrien	(if_then_else:DI
433690075Sobrien	  (match_operator 4 "predicate_operator"
433790075Sobrien	    [(match_operand:BI 1 "register_operand"
433890075Sobrien		"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
433990075Sobrien	     (const_int 0)])
434090075Sobrien	  (match_operand:DI 2 "move_operand"
434190075Sobrien	   "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
434290075Sobrien	  (match_operand:DI 3 "move_operand"
434390075Sobrien	   "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
434490075Sobrien  "ia64_move_ok (operands[0], operands[2])
434590075Sobrien   && ia64_move_ok (operands[0], operands[3])"
434690075Sobrien  "* abort ();"
434790075Sobrien  [(set_attr "predicable" "no")])
434890075Sobrien
434990075Sobrien(define_split
435090075Sobrien  [(set (match_operand 0 "destination_operand" "")
435190075Sobrien	(if_then_else
435290075Sobrien	  (match_operator 4 "predicate_operator"
435390075Sobrien	    [(match_operand:BI 1 "register_operand" "")
435490075Sobrien	     (const_int 0)])
435590075Sobrien	  (match_operand 2 "move_operand" "")
435690075Sobrien	  (match_operand 3 "move_operand" "")))]
435790075Sobrien  "reload_completed"
435890075Sobrien  [(const_int 0)]
435990075Sobrien  "
436090075Sobrien{
436190075Sobrien  rtx tmp;
436290075Sobrien  if (! rtx_equal_p (operands[0], operands[2]))
436390075Sobrien    {
436490075Sobrien      tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
436590075Sobrien      tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
436690075Sobrien      emit_insn (tmp);
436790075Sobrien    }
436890075Sobrien  if (! rtx_equal_p (operands[0], operands[3]))
436990075Sobrien    {
437090075Sobrien      tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
437190075Sobrien			    VOIDmode, operands[1], const0_rtx);
437290075Sobrien      tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
437390075Sobrien			       gen_rtx_SET (VOIDmode, operands[0],
437490075Sobrien					    operands[3]));
437590075Sobrien      emit_insn (tmp);
437690075Sobrien    }
437790075Sobrien  DONE;
437890075Sobrien}")
437990075Sobrien
438090075Sobrien;; Absolute value pattern.
438190075Sobrien
438290075Sobrien(define_insn "*absdi2_internal"
438390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
438490075Sobrien	(if_then_else:DI
438590075Sobrien	  (match_operator 4 "predicate_operator"
438690075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
438790075Sobrien	     (const_int 0)])
438890075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
438990075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
439090075Sobrien  ""
439190075Sobrien  "#"
439290075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
439390075Sobrien   (set_attr "predicable" "no")])
439490075Sobrien
439590075Sobrien(define_split
439690075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
439790075Sobrien	(if_then_else:DI
439890075Sobrien	  (match_operator 4 "predicate_operator"
439990075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
440090075Sobrien	     (const_int 0)])
440190075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
440290075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
440390075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
440490075Sobrien  [(cond_exec
440590075Sobrien     (match_dup 4)
440690075Sobrien     (set (match_dup 0)
440790075Sobrien	  (neg:DI (match_dup 2))))]
440890075Sobrien  "")
440990075Sobrien
441090075Sobrien(define_split
441190075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
441290075Sobrien	(if_then_else:DI
441390075Sobrien	  (match_operator 4 "predicate_operator"
441490075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
441590075Sobrien	     (const_int 0)])
441690075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
441790075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
441890075Sobrien  "reload_completed"
441990075Sobrien  [(cond_exec
442090075Sobrien     (match_dup 4)
442190075Sobrien     (set (match_dup 0) (neg:DI (match_dup 2))))
442290075Sobrien   (cond_exec
442390075Sobrien     (match_dup 5)
442490075Sobrien     (set (match_dup 0) (match_dup 3)))]
442590075Sobrien  "
442690075Sobrien{
442790075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
442890075Sobrien				VOIDmode, operands[1], const0_rtx);
442990075Sobrien}")
443090075Sobrien
443190075Sobrien;;
443290075Sobrien;; SImode if_then_else patterns.
443390075Sobrien;;
443490075Sobrien
443590075Sobrien(define_insn "*cmovsi_internal"
443690075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
443790075Sobrien	(if_then_else:SI
443890075Sobrien	  (match_operator 4 "predicate_operator"
443990075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
444090075Sobrien	     (const_int 0)])
444190075Sobrien	  (match_operand:SI 2 "move_operand"
444290075Sobrien		    "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
444390075Sobrien	  (match_operand:SI 3 "move_operand"
444490075Sobrien		    "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
444590075Sobrien  "ia64_move_ok (operands[0], operands[2])
444690075Sobrien   && ia64_move_ok (operands[0], operands[3])"
444790075Sobrien  "* abort ();"
444890075Sobrien  [(set_attr "predicable" "no")])
444990075Sobrien
445090075Sobrien(define_insn "*abssi2_internal"
445190075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
445290075Sobrien	(if_then_else:SI
445390075Sobrien	  (match_operator 4 "predicate_operator"
445490075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
445590075Sobrien	     (const_int 0)])
445690075Sobrien	  (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
445790075Sobrien	  (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
445890075Sobrien  ""
445990075Sobrien  "#"
446090075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
446190075Sobrien   (set_attr "predicable" "no")])
446290075Sobrien
446390075Sobrien(define_split
446490075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
446590075Sobrien	(if_then_else:SI
446690075Sobrien	  (match_operator 4 "predicate_operator"
446790075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
446890075Sobrien	     (const_int 0)])
446990075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
447090075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
447190075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
447290075Sobrien  [(cond_exec
447390075Sobrien     (match_dup 4)
447490075Sobrien     (set (match_dup 0)
447590075Sobrien	  (neg:SI (match_dup 2))))]
447690075Sobrien  "")
447790075Sobrien
447890075Sobrien(define_split
447990075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
448090075Sobrien	(if_then_else:SI
448190075Sobrien	  (match_operator 4 "predicate_operator"
448290075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
448390075Sobrien	     (const_int 0)])
448490075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
448590075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
448690075Sobrien  "reload_completed"
448790075Sobrien  [(cond_exec
448890075Sobrien     (match_dup 4)
448990075Sobrien     (set (match_dup 0) (neg:SI (match_dup 2))))
449090075Sobrien   (cond_exec
449190075Sobrien     (match_dup 5)
449290075Sobrien     (set (match_dup 0) (match_dup 3)))]
449390075Sobrien  "
449490075Sobrien{
449590075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
449690075Sobrien				VOIDmode, operands[1], const0_rtx);
449790075Sobrien}")
449890075Sobrien
449990075Sobrien(define_insn_and_split "*cond_opsi2_internal"
450090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
450190075Sobrien	(match_operator:SI 5 "condop_operator"
450290075Sobrien	  [(if_then_else:SI
450390075Sobrien	     (match_operator 6 "predicate_operator"
450490075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
450590075Sobrien	        (const_int 0)])
450690075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
450790075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))
450890075Sobrien	   (match_operand:SI 4 "gr_register_operand" "r")]))]
450990075Sobrien  ""
451090075Sobrien  "#"
451190075Sobrien  "reload_completed"
451290075Sobrien  [(cond_exec
451390075Sobrien     (match_dup 6)
451490075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
451590075Sobrien   (cond_exec
451690075Sobrien     (match_dup 7)
451790075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
451890075Sobrien  "
451990075Sobrien{
452090075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
452190075Sobrien				VOIDmode, operands[1], const0_rtx);
452290075Sobrien}"
452390075Sobrien  [(set_attr "itanium_class" "ialu")
452490075Sobrien   (set_attr "predicable" "no")])
452590075Sobrien
452690075Sobrien
452790075Sobrien(define_insn_and_split "*cond_opsi2_internal_b"
452890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
452990075Sobrien	(match_operator:SI 5 "condop_operator"
453090075Sobrien	  [(match_operand:SI 4 "gr_register_operand" "r")
453190075Sobrien	   (if_then_else:SI
453290075Sobrien	     (match_operator 6 "predicate_operator"
453390075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
453490075Sobrien	        (const_int 0)])
453590075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
453690075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))]))]
453790075Sobrien  ""
453890075Sobrien  "#"
453990075Sobrien  "reload_completed"
454090075Sobrien  [(cond_exec
454190075Sobrien     (match_dup 6)
454290075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
454390075Sobrien   (cond_exec
454490075Sobrien     (match_dup 7)
454590075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
454690075Sobrien  "
454790075Sobrien{
454890075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
454990075Sobrien				VOIDmode, operands[1], const0_rtx);
455090075Sobrien}"
455190075Sobrien  [(set_attr "itanium_class" "ialu")
455290075Sobrien   (set_attr "predicable" "no")])
455390075Sobrien
455490075Sobrien
455590075Sobrien;; ::::::::::::::::::::
455690075Sobrien;; ::
455790075Sobrien;; :: Call and branch instructions
455890075Sobrien;; ::
455990075Sobrien;; ::::::::::::::::::::
456090075Sobrien
456190075Sobrien;; Subroutine call instruction returning no value.  Operand 0 is the function
456290075Sobrien;; to call; operand 1 is the number of bytes of arguments pushed (in mode
456390075Sobrien;; `SImode', except it is normally a `const_int'); operand 2 is the number of
456490075Sobrien;; registers used as operands.
456590075Sobrien
456690075Sobrien;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
456790075Sobrien;; is supplied for the sake of some RISC machines which need to put this
456890075Sobrien;; information into the assembler code; they can put it in the RTL instead of
456990075Sobrien;; operand 1.
457090075Sobrien
457190075Sobrien(define_expand "call"
457290075Sobrien  [(use (match_operand:DI 0 "" ""))
457390075Sobrien   (use (match_operand 1 "" ""))
457490075Sobrien   (use (match_operand 2 "" ""))
457590075Sobrien   (use (match_operand 3 "" ""))]
457690075Sobrien  ""
457790075Sobrien  "
457890075Sobrien{
457990075Sobrien  ia64_expand_call (NULL_RTX, operands[0], operands[2], 0);
458090075Sobrien  DONE;
458190075Sobrien}")
458290075Sobrien
458390075Sobrien(define_expand "sibcall"
458490075Sobrien  [(use (match_operand:DI 0 "" ""))
458590075Sobrien   (use (match_operand 1 "" ""))
458690075Sobrien   (use (match_operand 2 "" ""))
458790075Sobrien   (use (match_operand 3 "" ""))]
458890075Sobrien  ""
458990075Sobrien  "
459090075Sobrien{
459190075Sobrien  ia64_expand_call (NULL_RTX, operands[0], operands[2], 1);
459290075Sobrien  DONE;
459390075Sobrien}")
459490075Sobrien
459590075Sobrien;; Subroutine call instruction returning a value.  Operand 0 is the hard
459690075Sobrien;; register in which the value is returned.  There are three more operands,
459790075Sobrien;; the same as the three operands of the `call' instruction (but with numbers
459890075Sobrien;; increased by one).
459990075Sobrien;;
460090075Sobrien;; Subroutines that return `BLKmode' objects use the `call' insn.
460190075Sobrien
460290075Sobrien(define_expand "call_value"
460390075Sobrien  [(use (match_operand 0 "" ""))
460490075Sobrien   (use (match_operand:DI 1 "" ""))
460590075Sobrien   (use (match_operand 2 "" ""))
460690075Sobrien   (use (match_operand 3 "" ""))
460790075Sobrien   (use (match_operand 4 "" ""))]
460890075Sobrien  ""
460990075Sobrien  "
461090075Sobrien{
461190075Sobrien  ia64_expand_call (operands[0], operands[1], operands[3], 0);
461290075Sobrien  DONE;
461390075Sobrien}")
461490075Sobrien
461590075Sobrien(define_expand "sibcall_value"
461690075Sobrien  [(use (match_operand 0 "" ""))
461790075Sobrien   (use (match_operand:DI 1 "" ""))
461890075Sobrien   (use (match_operand 2 "" ""))
461990075Sobrien   (use (match_operand 3 "" ""))
462090075Sobrien   (use (match_operand 4 "" ""))]
462190075Sobrien  ""
462290075Sobrien  "
462390075Sobrien{
462490075Sobrien  ia64_expand_call (operands[0], operands[1], operands[3], 1);
462590075Sobrien  DONE;
462690075Sobrien}")
462790075Sobrien
462890075Sobrien;; Call subroutine returning any type.
462990075Sobrien
463090075Sobrien(define_expand "untyped_call"
463190075Sobrien  [(parallel [(call (match_operand 0 "" "")
463290075Sobrien		    (const_int 0))
463390075Sobrien	      (match_operand 1 "" "")
463490075Sobrien	      (match_operand 2 "" "")])]
463590075Sobrien  ""
463690075Sobrien  "
463790075Sobrien{
463890075Sobrien  int i;
463990075Sobrien
464090075Sobrien  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
464190075Sobrien
464290075Sobrien  for (i = 0; i < XVECLEN (operands[2], 0); i++)
464390075Sobrien    {
464490075Sobrien      rtx set = XVECEXP (operands[2], 0, i);
464590075Sobrien      emit_move_insn (SET_DEST (set), SET_SRC (set));
464690075Sobrien    }
464790075Sobrien
464890075Sobrien  /* The optimizer does not know that the call sets the function value
464990075Sobrien     registers we stored in the result block.  We avoid problems by
465090075Sobrien     claiming that all hard registers are used and clobbered at this
465190075Sobrien     point.  */
465290075Sobrien  emit_insn (gen_blockage ());
465390075Sobrien
465490075Sobrien  DONE;
465590075Sobrien}")
465690075Sobrien
465790075Sobrien(define_insn "call_nopic"
465890075Sobrien  [(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
465990075Sobrien	 (match_operand 1 "" ""))
466090075Sobrien   (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
466190075Sobrien  ""
466290075Sobrien  "br.call%+.many %2 = %0"
466390075Sobrien  [(set_attr "itanium_class" "br,scall")])
466490075Sobrien
466590075Sobrien(define_insn "call_value_nopic"
466690075Sobrien  [(set (match_operand 0 "" "")
466790075Sobrien	(call (mem:DI (match_operand:DI 1 "call_operand" "b,i"))
466890075Sobrien	      (match_operand 2 "" "")))
466990075Sobrien   (clobber (match_operand:DI 3 "register_operand" "=b,b"))]
467090075Sobrien  ""
467190075Sobrien  "br.call%+.many %3 = %1"
467290075Sobrien  [(set_attr "itanium_class" "br,scall")])
467390075Sobrien
467490075Sobrien(define_insn "sibcall_nopic"
467590075Sobrien  [(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
467690075Sobrien	 (match_operand 1 "" ""))
467790075Sobrien   (use (match_operand:DI 2 "register_operand" "=b,b"))
467890075Sobrien   (use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
467990075Sobrien  ""
468090075Sobrien  "br%+.many %0"
468190075Sobrien  [(set_attr "itanium_class" "br,scall")])
468290075Sobrien
468390075Sobrien(define_insn "call_pic"
468490075Sobrien  [(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
468590075Sobrien	 (match_operand 1 "" ""))
468690075Sobrien   (use (unspec [(reg:DI 1)] 9))
468790075Sobrien   (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
468890075Sobrien  ""
468990075Sobrien  "br.call%+.many %2 = %0"
469090075Sobrien  [(set_attr "itanium_class" "br,scall")])
469190075Sobrien
469290075Sobrien(define_insn "call_value_pic"
469390075Sobrien  [(set (match_operand 0 "" "")
469490075Sobrien	(call (mem:DI (match_operand:DI 1 "call_operand" "b,i"))
469590075Sobrien	      (match_operand 2 "" "")))
469690075Sobrien   (use (unspec [(reg:DI 1)] 9))
469790075Sobrien   (clobber (match_operand:DI 3 "register_operand" "=b,b"))]
469890075Sobrien  ""
469990075Sobrien  "br.call%+.many %3 = %1"
470090075Sobrien  [(set_attr "itanium_class" "br,scall")])
470190075Sobrien
470290075Sobrien(define_insn "sibcall_pic"
470390075Sobrien  [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
470490075Sobrien	 (match_operand 1 "" ""))
470590075Sobrien   (use (unspec [(reg:DI 1)] 9))
470690075Sobrien   (use (match_operand:DI 2 "register_operand" "=b"))
470790075Sobrien   (use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
470890075Sobrien  ""
470990075Sobrien  "br%+.many %0"
471090075Sobrien  [(set_attr "itanium_class" "br")])
471190075Sobrien
471290075Sobrien(define_insn "return_internal"
471390075Sobrien  [(return)
471490075Sobrien   (use (match_operand:DI 0 "register_operand" "b"))]
471590075Sobrien  ""
471690075Sobrien  "br.ret.sptk.many %0"
471790075Sobrien  [(set_attr "itanium_class" "br")])
471890075Sobrien
471990075Sobrien(define_insn "return"
472090075Sobrien  [(return)]
472190075Sobrien  "ia64_direct_return ()"
472290075Sobrien  "br.ret.sptk.many rp"
472390075Sobrien  [(set_attr "itanium_class" "br")])
472490075Sobrien
472590075Sobrien(define_insn "*return_true"
472690075Sobrien  [(set (pc)
472790075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
472890075Sobrien			[(match_operand:BI 1 "register_operand" "c")
472990075Sobrien			 (const_int 0)])
473090075Sobrien		      (return)
473190075Sobrien		      (pc)))]
473290075Sobrien  "ia64_direct_return ()"
473390075Sobrien  "(%J0) br.ret%+.many rp"
473490075Sobrien  [(set_attr "itanium_class" "br")
473590075Sobrien   (set_attr "predicable" "no")])
473690075Sobrien
473790075Sobrien(define_insn "*return_false"
473890075Sobrien  [(set (pc)
473990075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
474090075Sobrien			[(match_operand:BI 1 "register_operand" "c")
474190075Sobrien			 (const_int 0)])
474290075Sobrien		      (pc)
474390075Sobrien		      (return)))]
474490075Sobrien  "ia64_direct_return ()"
474590075Sobrien  "(%j0) br.ret%+.many rp"
474690075Sobrien  [(set_attr "itanium_class" "br")
474790075Sobrien   (set_attr "predicable" "no")])
474890075Sobrien
474990075Sobrien(define_insn "jump"
475090075Sobrien  [(set (pc) (label_ref (match_operand 0 "" "")))]
475190075Sobrien  ""
475290075Sobrien  "br %l0"
475390075Sobrien  [(set_attr "itanium_class" "br")])
475490075Sobrien
475590075Sobrien(define_insn "indirect_jump"
475690075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
475790075Sobrien  ""
475890075Sobrien  "br %0"
475990075Sobrien  [(set_attr "itanium_class" "br")])
476090075Sobrien
476190075Sobrien(define_expand "tablejump"
476290075Sobrien  [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
476390075Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
476490075Sobrien  ""
476590075Sobrien{
476690075Sobrien  rtx op0 = operands[0];
476790075Sobrien  rtx addr;
476890075Sobrien
476990075Sobrien  /* ??? Bother -- do_tablejump is "helpful" and pulls the table
477090075Sobrien     element into a register without bothering to see whether that
477190075Sobrien     is necessary given the operand predicate.  Check for MEM just
477290075Sobrien     in case someone fixes this.  */
477390075Sobrien  if (GET_CODE (op0) == MEM)
477490075Sobrien    addr = XEXP (op0, 0);
477590075Sobrien  else
477690075Sobrien    {
477790075Sobrien      /* Otherwise, cheat and guess that the previous insn in the
477890075Sobrien	 stream was the memory load.  Grab the address from that.
477990075Sobrien	 Note we have to momentarily pop out of the sequence started
478090075Sobrien	 by the insn-emit wrapper in order to grab the last insn.  */
478190075Sobrien      rtx last, set;
478290075Sobrien
478390075Sobrien      end_sequence ();
478490075Sobrien      last = get_last_insn ();
478590075Sobrien      start_sequence ();
478690075Sobrien      set = single_set (last);
478790075Sobrien
478890075Sobrien      if (! rtx_equal_p (SET_DEST (set), op0)
478990075Sobrien	  || GET_CODE (SET_SRC (set)) != MEM)
479090075Sobrien	abort ();
479190075Sobrien      addr = XEXP (SET_SRC (set), 0);
479290075Sobrien      if (rtx_equal_p (addr, op0))
479390075Sobrien	abort ();
479490075Sobrien    }
479590075Sobrien
479690075Sobrien  /* Jump table elements are stored pc-relative.  That is, a displacement
479790075Sobrien     from the entry to the label.  Thus to convert to an absolute address
479890075Sobrien     we add the address of the memory from which the value is loaded.  */
479990075Sobrien  operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
480090075Sobrien				     NULL_RTX, 1, OPTAB_DIRECT);
480190075Sobrien})
480290075Sobrien
480390075Sobrien(define_insn "*tablejump_internal"
480490075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))
480590075Sobrien   (use (label_ref (match_operand 1 "" "")))]
480690075Sobrien  ""
480790075Sobrien  "br %0"
480890075Sobrien  [(set_attr "itanium_class" "br")])
480990075Sobrien
481090075Sobrien
481190075Sobrien;; ::::::::::::::::::::
481290075Sobrien;; ::
481390075Sobrien;; :: Prologue and Epilogue instructions
481490075Sobrien;; ::
481590075Sobrien;; ::::::::::::::::::::
481690075Sobrien
481790075Sobrien(define_expand "prologue"
481890075Sobrien  [(const_int 1)]
481990075Sobrien  ""
482090075Sobrien  "
482190075Sobrien{
482290075Sobrien  ia64_expand_prologue ();
482390075Sobrien  DONE;
482490075Sobrien}")
482590075Sobrien
482690075Sobrien(define_expand "epilogue"
482790075Sobrien  [(return)]
482890075Sobrien  ""
482990075Sobrien  "
483090075Sobrien{
483190075Sobrien  ia64_expand_epilogue (0);
483290075Sobrien  DONE;
483390075Sobrien}")
483490075Sobrien
483590075Sobrien(define_expand "sibcall_epilogue"
483690075Sobrien  [(return)]
483790075Sobrien  ""
483890075Sobrien  "
483990075Sobrien{
484090075Sobrien  ia64_expand_epilogue (1);
484190075Sobrien  DONE;
484290075Sobrien}")
484390075Sobrien
484490075Sobrien;; This prevents the scheduler from moving the SP decrement past FP-relative
484590075Sobrien;; stack accesses.  This is the same as adddi3 plus the extra set.
484690075Sobrien
484790075Sobrien(define_insn "prologue_allocate_stack"
484890075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
484990075Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
485090075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
485190075Sobrien   (set (match_operand:DI 3 "register_operand" "=r,r,r")
485290075Sobrien	(match_dup 3))]
485390075Sobrien  ""
485490075Sobrien  "@
485590075Sobrien  add %0 = %1, %2
485690075Sobrien  adds %0 = %2, %1
485790075Sobrien  addl %0 = %2, %1"
485890075Sobrien  [(set_attr "itanium_class" "ialu")])
485990075Sobrien
486090075Sobrien;; This prevents the scheduler from moving the SP restore past FP-relative
486190075Sobrien;; stack accesses.  This is similar to movdi plus the extra set.
486290075Sobrien
486390075Sobrien(define_insn "epilogue_deallocate_stack"
486490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
486590075Sobrien	(match_operand:DI 1 "register_operand" "+r"))
486690075Sobrien   (set (match_dup 1) (match_dup 1))]
486790075Sobrien  ""
486890075Sobrien  "mov %0 = %1"
486990075Sobrien  [(set_attr "itanium_class" "ialu")])
487090075Sobrien
487190075Sobrien;; Allocate a new register frame.
487290075Sobrien
487390075Sobrien(define_insn "alloc"
487490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
487590075Sobrien	(unspec_volatile:DI [(const_int 0)] 0))
487690075Sobrien   (use (match_operand:DI 1 "const_int_operand" "i"))
487790075Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
487890075Sobrien   (use (match_operand:DI 3 "const_int_operand" "i"))
487990075Sobrien   (use (match_operand:DI 4 "const_int_operand" "i"))]
488090075Sobrien  ""
488190075Sobrien  "alloc %0 = ar.pfs, %1, %2, %3, %4"
488290075Sobrien  [(set_attr "itanium_class" "syst_m0")
488390075Sobrien   (set_attr "predicable" "no")])
488490075Sobrien
488590075Sobrien;; Modifies ar.unat
488690075Sobrien(define_expand "gr_spill"
488790075Sobrien  [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
488890075Sobrien		   (unspec:DI [(match_operand:DI 1 "register_operand" "r")
488990075Sobrien			       (match_operand:DI 2 "const_int_operand" "")] 1))
489090075Sobrien	      (clobber (match_dup 3))])]
489190075Sobrien  ""
489290075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
489390075Sobrien
489490075Sobrien(define_insn "gr_spill_internal"
489590075Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
489690075Sobrien	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
489790075Sobrien		    (match_operand:DI 2 "const_int_operand" "")] 1))
489890075Sobrien   (clobber (match_operand:DI 3 "register_operand" ""))]
489990075Sobrien  ""
490090075Sobrien  "*
490190075Sobrien{
490290075Sobrien  return \".mem.offset %2, 0\;%,st8.spill %0 = %1%P0\";
490390075Sobrien}"
490490075Sobrien  [(set_attr "itanium_class" "st")])
490590075Sobrien
490690075Sobrien;; Reads ar.unat
490790075Sobrien(define_expand "gr_restore"
490890075Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
490990075Sobrien		   (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
491090075Sobrien			       (match_operand:DI 2 "const_int_operand" "")] 2))
491190075Sobrien	      (use (match_dup 3))])]
491290075Sobrien  ""
491390075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
491490075Sobrien
491590075Sobrien(define_insn "gr_restore_internal"
491690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
491790075Sobrien	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
491890075Sobrien		    (match_operand:DI 2 "const_int_operand" "")] 2))
491990075Sobrien   (use (match_operand:DI 3 "register_operand" ""))]
492090075Sobrien  ""
492190075Sobrien  "*
492290075Sobrien{
492390075Sobrien  return \".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1\";
492490075Sobrien}"
492590075Sobrien  [(set_attr "itanium_class" "ld")])
492690075Sobrien
492790075Sobrien(define_insn "fr_spill"
492890075Sobrien  [(set (match_operand:TF 0 "memory_operand" "=m")
492990075Sobrien	(unspec:TF [(match_operand:TF 1 "register_operand" "f")] 3))]
493090075Sobrien  ""
493190075Sobrien  "stf.spill %0 = %1%P0"
493290075Sobrien  [(set_attr "itanium_class" "stf")])
493390075Sobrien
493490075Sobrien(define_insn "fr_restore"
493590075Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
493690075Sobrien	(unspec:TF [(match_operand:TF 1 "memory_operand" "m")] 4))]
493790075Sobrien  ""
493890075Sobrien  "ldf.fill %0 = %1%P1"
493990075Sobrien  [(set_attr "itanium_class" "fld")])
494090075Sobrien
494190075Sobrien;; ??? The explicit stop is not ideal.  It would be better if
494290075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
494390075Sobrien;; fixed later.  This avoids an RSE DV.
494490075Sobrien
494590075Sobrien(define_insn "bsp_value"
494690075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
494790075Sobrien	(unspec:DI [(const_int 0)] 20))]
494890075Sobrien  ""
494990075Sobrien  ";;\;mov %0 = ar.bsp"
495090075Sobrien  [(set_attr "itanium_class" "frar_i")])
495190075Sobrien
495290075Sobrien(define_insn "set_bsp"
495390075Sobrien  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 5)]
495490075Sobrien  ""
495590075Sobrien  "flushrs\;mov r19=ar.rsc\;;;\;and r19=0x1c,r19\;;;\;mov ar.rsc=r19\;;;\;mov ar.bspstore=%0\;;;\;or r19=0x3,r19\;;;\;loadrs\;invala\;;;\;mov ar.rsc=r19"
495690075Sobrien  [(set_attr "itanium_class" "unknown")
495790075Sobrien   (set_attr "predicable" "no")])
495890075Sobrien
495990075Sobrien;; ??? The explicit stops are not ideal.  It would be better if
496090075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
496190075Sobrien;; fixed later.  This avoids an RSE DV.
496290075Sobrien
496390075Sobrien(define_insn "flushrs"
496490075Sobrien  [(unspec [(const_int 0)] 21)]
496590075Sobrien  ""
496690075Sobrien  ";;\;flushrs\;;;"
496790075Sobrien  [(set_attr "itanium_class" "rse_m")])
496890075Sobrien
496990075Sobrien;; ::::::::::::::::::::
497090075Sobrien;; ::
497190075Sobrien;; :: Miscellaneous instructions
497290075Sobrien;; ::
497390075Sobrien;; ::::::::::::::::::::
497490075Sobrien
497590075Sobrien;; ??? Emiting a NOP instruction isn't very useful.  This should probably
497690075Sobrien;; be emitting ";;" to force a break in the instruction packing.
497790075Sobrien
497890075Sobrien;; No operation, needed in case the user uses -g but not -O.
497990075Sobrien(define_insn "nop"
498090075Sobrien  [(const_int 0)]
498190075Sobrien  ""
498290075Sobrien  "nop 0"
498390075Sobrien  [(set_attr "itanium_class" "unknown")])
498490075Sobrien
498590075Sobrien(define_insn "nop_m"
498690075Sobrien  [(const_int 1)]
498790075Sobrien  ""
498890075Sobrien  "nop.m 0"
498990075Sobrien  [(set_attr "itanium_class" "nop_m")])
499090075Sobrien
499190075Sobrien(define_insn "nop_i"
499290075Sobrien  [(const_int 2)]
499390075Sobrien  ""
499490075Sobrien  "nop.i 0"
499590075Sobrien  [(set_attr "itanium_class" "nop_i")])
499690075Sobrien
499790075Sobrien(define_insn "nop_f"
499890075Sobrien  [(const_int 3)]
499990075Sobrien  ""
500090075Sobrien  "nop.f 0"
500190075Sobrien  [(set_attr "itanium_class" "nop_f")])
500290075Sobrien
500390075Sobrien(define_insn "nop_b"
500490075Sobrien  [(const_int 4)]
500590075Sobrien  ""
500690075Sobrien  "nop.b 0"
500790075Sobrien  [(set_attr "itanium_class" "nop_b")])
500890075Sobrien
500990075Sobrien(define_insn "nop_x"
501090075Sobrien  [(const_int 5)]
501190075Sobrien  ""
501290075Sobrien  ""
501390075Sobrien  [(set_attr "itanium_class" "nop_x")])
501490075Sobrien
501590075Sobrien(define_insn "cycle_display"
501690075Sobrien  [(unspec [(match_operand 0 "const_int_operand" "")] 23)]
501790075Sobrien  ""
501890075Sobrien  "// cycle %0"
501990075Sobrien  [(set_attr "itanium_class" "ignore")
502090075Sobrien   (set_attr "predicable" "no")])
502190075Sobrien
502290075Sobrien(define_insn "bundle_selector"
502390075Sobrien  [(unspec [(match_operand 0 "const_int_operand" "")] 22)]
502490075Sobrien  ""
502590075Sobrien  "*
502690075Sobrien{
502790075Sobrien  return get_bundle_name (INTVAL (operands[0]));
502890075Sobrien}"
502990075Sobrien  [(set_attr "itanium_class" "ignore")
503090075Sobrien   (set_attr "predicable" "no")])
503190075Sobrien
503290075Sobrien;; Pseudo instruction that prevents the scheduler from moving code above this
503390075Sobrien;; point.
503490075Sobrien(define_insn "blockage"
503590075Sobrien  [(unspec_volatile [(const_int 0)] 1)]
503690075Sobrien  ""
503790075Sobrien  ""
503890075Sobrien  [(set_attr "itanium_class" "ignore")
503990075Sobrien   (set_attr "predicable" "no")])
504090075Sobrien
504190075Sobrien(define_insn "insn_group_barrier"
504290075Sobrien  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 2)]
504390075Sobrien  ""
504490075Sobrien  ";;"
504590075Sobrien  [(set_attr "itanium_class" "stop_bit")
504690075Sobrien   (set_attr "predicable" "no")])
504790075Sobrien
504890075Sobrien(define_insn "break_f"
504990075Sobrien  [(unspec_volatile [(const_int 0)] 3)]
505090075Sobrien  ""
505190075Sobrien  "break.f 0"
505290075Sobrien  [(set_attr "itanium_class" "nop_f")])
505390075Sobrien
505490075Sobrien(define_insn "prefetch"
505590075Sobrien  [(prefetch (match_operand:DI 0 "address_operand" "p")
505690075Sobrien	     (match_operand:DI 1 "const_int_operand" "n")
505790075Sobrien	     (match_operand:DI 2 "const_int_operand" "n"))]
505890075Sobrien  ""
505990075Sobrien{
506090075Sobrien  static const char * const alt[2][4] = {
506190075Sobrien    {
506290075Sobrien      "lfetch.nta [%0]",
506390075Sobrien      "lfetch.nt1 [%0]",
506490075Sobrien      "lfetch.nt2 [%0]",
506590075Sobrien      "lfetch [%0]"
506690075Sobrien    },
506790075Sobrien    {
506890075Sobrien      "lfetch.excl.nta [%0]",
506990075Sobrien      "lfetch.excl.nt1 [%0]",
507090075Sobrien      "lfetch.excl.nt2 [%0]",
507190075Sobrien      "lfetch.excl [%0]"
507290075Sobrien    }
507390075Sobrien  };
507490075Sobrien  int i = (INTVAL (operands[1]));
507590075Sobrien  int j = (INTVAL (operands[2]));
507690075Sobrien
507790075Sobrien  if (i != 0 && i != 1)
507890075Sobrien    abort ();
507990075Sobrien  if (j < 0 || j > 3)
508090075Sobrien    abort ();
508190075Sobrien  return alt[i][j];
508290075Sobrien}
508390075Sobrien  [(set_attr "itanium_class" "lfetch")])
508490075Sobrien
508590075Sobrien;; Non-local goto support.
508690075Sobrien
508790075Sobrien(define_expand "save_stack_nonlocal"
508890075Sobrien  [(use (match_operand:OI 0 "memory_operand" ""))
508990075Sobrien   (use (match_operand:DI 1 "register_operand" ""))]
509090075Sobrien  ""
509190075Sobrien  "
509290075Sobrien{
509390075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
509490075Sobrien					 \"__ia64_save_stack_nonlocal\"),
509590075Sobrien		     0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
509690075Sobrien		     operands[1], Pmode);
509790075Sobrien  DONE;
509890075Sobrien}")
509990075Sobrien
510090075Sobrien(define_expand "nonlocal_goto"
510190075Sobrien  [(use (match_operand 0 "general_operand" ""))
510290075Sobrien   (use (match_operand 1 "general_operand" ""))
510390075Sobrien   (use (match_operand 2 "general_operand" ""))
510490075Sobrien   (use (match_operand 3 "general_operand" ""))]
510590075Sobrien  ""
510690075Sobrien  "
510790075Sobrien{
510890075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
510990075Sobrien		     LCT_NORETURN, VOIDmode, 3,
511090075Sobrien		     operands[1], Pmode,
511190075Sobrien		     copy_to_reg (XEXP (operands[2], 0)), Pmode,
511290075Sobrien		     operands[3], Pmode);
511390075Sobrien  emit_barrier ();
511490075Sobrien  DONE;
511590075Sobrien}")
511690075Sobrien
511790075Sobrien;; The rest of the setjmp processing happens with the nonlocal_goto expander.
511890075Sobrien;; ??? This is not tested.
511990075Sobrien(define_expand "builtin_setjmp_setup"
512090075Sobrien  [(use (match_operand:DI 0 "" ""))]
512190075Sobrien  ""
512290075Sobrien  "
512390075Sobrien{
512490075Sobrien  emit_move_insn (ia64_gp_save_reg (0), gen_rtx_REG (DImode, GR_REG (1)));
512590075Sobrien  DONE;
512690075Sobrien}")
512790075Sobrien
512890075Sobrien(define_expand "builtin_setjmp_receiver"
512990075Sobrien  [(use (match_operand:DI 0 "" ""))]
513090075Sobrien  ""
513190075Sobrien  "
513290075Sobrien{
513390075Sobrien  emit_move_insn (gen_rtx_REG (DImode, GR_REG (1)), ia64_gp_save_reg (0));
513490075Sobrien  DONE;
513590075Sobrien}")
513690075Sobrien
513790075Sobrien(define_expand "eh_epilogue"
513890075Sobrien  [(use (match_operand:DI 0 "register_operand" "r"))
513990075Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
514090075Sobrien   (use (match_operand:DI 2 "register_operand" "r"))]
514190075Sobrien  ""
514290075Sobrien  "
514390075Sobrien{
514490075Sobrien  rtx bsp = gen_rtx_REG (Pmode, 10);
514590075Sobrien  rtx sp = gen_rtx_REG (Pmode, 9);
514690075Sobrien
514790075Sobrien  if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
514890075Sobrien    {
514990075Sobrien      emit_move_insn (bsp, operands[0]);
515090075Sobrien      operands[0] = bsp;
515190075Sobrien    }
515290075Sobrien  if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
515390075Sobrien    {
515490075Sobrien      emit_move_insn (sp, operands[2]);
515590075Sobrien      operands[2] = sp;
515690075Sobrien    }
515790075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, sp));
515890075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, bsp));
515990075Sobrien
516090075Sobrien  cfun->machine->ia64_eh_epilogue_sp = sp;
516190075Sobrien  cfun->machine->ia64_eh_epilogue_bsp = bsp;
516290075Sobrien}")
516390075Sobrien
516490075Sobrien;; Builtin apply support.
516590075Sobrien
516690075Sobrien(define_expand "restore_stack_nonlocal"
516790075Sobrien  [(use (match_operand:DI 0 "register_operand" ""))
516890075Sobrien   (use (match_operand:OI 1 "memory_operand" ""))]
516990075Sobrien  ""
517090075Sobrien  "
517190075Sobrien{
517290075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
517390075Sobrien					 \"__ia64_restore_stack_nonlocal\"),
517490075Sobrien		     0, VOIDmode, 1,
517590075Sobrien		     copy_to_reg (XEXP (operands[1], 0)), Pmode);
517690075Sobrien  DONE;
517790075Sobrien}")
517890075Sobrien
517990075Sobrien
518090075Sobrien;;; Intrinsics support.
518190075Sobrien
518290075Sobrien(define_expand "mf"
518390075Sobrien  [(set (mem:BLK (match_dup 0))
518490075Sobrien	(unspec:BLK [(mem:BLK (match_dup 0))] 12))]
518590075Sobrien  ""
518690075Sobrien  "
518790075Sobrien{
518890075Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
518990075Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
519090075Sobrien}")
519190075Sobrien
519290075Sobrien(define_insn "*mf_internal"
519390075Sobrien  [(set (match_operand:BLK 0 "" "")
519490075Sobrien	(unspec:BLK [(match_operand:BLK 1 "" "")] 12))]
519590075Sobrien  ""
519690075Sobrien  "mf"
519790075Sobrien  [(set_attr "itanium_class" "syst_m")])
519890075Sobrien
519990075Sobrien(define_insn "fetchadd_acq_si"
520090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
520190075Sobrien	(match_dup 1))
520290075Sobrien   (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
520390075Sobrien	(unspec:SI [(match_dup 1)
520490075Sobrien		    (match_operand:SI 2 "fetchadd_operand" "n")] 19))]
520590075Sobrien  ""
520690075Sobrien  "fetchadd4.acq %0 = %1, %2"
520790075Sobrien  [(set_attr "itanium_class" "sem")])
520890075Sobrien
520990075Sobrien(define_insn "fetchadd_acq_di"
521090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
521190075Sobrien	(match_dup 1))
521290075Sobrien   (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
521390075Sobrien	(unspec:DI [(match_dup 1)
521490075Sobrien		    (match_operand:DI 2 "fetchadd_operand" "n")] 19))]
521590075Sobrien  ""
521690075Sobrien  "fetchadd8.acq %0 = %1, %2"
521790075Sobrien  [(set_attr "itanium_class" "sem")])
521890075Sobrien
521990075Sobrien(define_insn "cmpxchg_acq_si"
522090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
522190075Sobrien	(match_dup 1))
522290075Sobrien   (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
522390075Sobrien        (unspec:SI [(match_dup 1)
522490075Sobrien                    (match_operand:SI 2 "gr_register_operand" "r")
522590075Sobrien		    (match_operand:SI 3 "ar_ccv_reg_operand" "")] 13))]
522690075Sobrien  ""
522790075Sobrien  "cmpxchg4.acq %0 = %1, %2, %3"
522890075Sobrien  [(set_attr "itanium_class" "sem")])
522990075Sobrien
523090075Sobrien(define_insn "cmpxchg_acq_di"
523190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
523290075Sobrien	(match_dup 1))
523390075Sobrien   (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
523490075Sobrien        (unspec:DI [(match_dup 1)
523590075Sobrien                    (match_operand:DI 2 "gr_register_operand" "r")
523690075Sobrien		    (match_operand:DI 3 "ar_ccv_reg_operand" "")] 13))]
523790075Sobrien  ""
523890075Sobrien  "cmpxchg8.acq %0 = %1, %2, %3"
523990075Sobrien  [(set_attr "itanium_class" "sem")])
524090075Sobrien
524190075Sobrien(define_insn "xchgsi"
524290075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
524390075Sobrien        (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
524490075Sobrien   (set (match_dup 1)
524590075Sobrien        (match_operand:SI 2 "gr_register_operand" "r"))]
524690075Sobrien  ""
524790075Sobrien  "xchg4 %0 = %1, %2"
524890075Sobrien  [(set_attr "itanium_class" "sem")])
524990075Sobrien
525090075Sobrien(define_insn "xchgdi"
525190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
525290075Sobrien        (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
525390075Sobrien   (set (match_dup 1)
525490075Sobrien        (match_operand:DI 2 "gr_register_operand" "r"))]
525590075Sobrien  ""
525690075Sobrien  "xchg8 %0 = %1, %2"
525790075Sobrien  [(set_attr "itanium_class" "sem")])
525890075Sobrien
525990075Sobrien;; Predication.
526090075Sobrien
526190075Sobrien(define_cond_exec
526290075Sobrien  [(match_operator 0 "predicate_operator"
526390075Sobrien     [(match_operand:BI 1 "register_operand" "c")
526490075Sobrien      (const_int 0)])]
526590075Sobrien  ""
526690075Sobrien  "(%J0)")
526790075Sobrien
526890075Sobrien(define_insn "pred_rel_mutex"
526990075Sobrien  [(set (match_operand:BI 0 "register_operand" "+c")
527090075Sobrien       (unspec:BI [(match_dup 0)] 7))]
527190075Sobrien  ""
527290075Sobrien  ".pred.rel.mutex %0, %I0"
527390075Sobrien  [(set_attr "itanium_class" "ignore")
527490075Sobrien   (set_attr "predicable" "no")])
527590075Sobrien
527690075Sobrien(define_insn "safe_across_calls_all"
527790075Sobrien  [(unspec_volatile [(const_int 0)] 8)]
527890075Sobrien  ""
527990075Sobrien  ".pred.safe_across_calls p1-p63"
528090075Sobrien  [(set_attr "itanium_class" "ignore")
528190075Sobrien   (set_attr "predicable" "no")])
528290075Sobrien
528390075Sobrien(define_insn "safe_across_calls_normal"
528490075Sobrien  [(unspec_volatile [(const_int 0)] 9)]
528590075Sobrien  ""
528690075Sobrien  "*
528790075Sobrien{
528890075Sobrien  emit_safe_across_calls (asm_out_file);
528990075Sobrien  return \"\";
529090075Sobrien}"
529190075Sobrien  [(set_attr "itanium_class" "ignore")
529290075Sobrien   (set_attr "predicable" "no")])
529390075Sobrien
529490075Sobrien;;
529590075Sobrien;;
529690075Sobrien;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
529790075Sobrien;; pointer.  This is used by the HP-UX 32 bit mode.
529890075Sobrien
529990075Sobrien(define_insn "ptr_extend"
530090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
530190075Sobrien        (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")] 24))]
530290075Sobrien  ""
530390075Sobrien  "addp4 %0 = 0,%1"
530490075Sobrien  [(set_attr "itanium_class" "ialu")])
530590075Sobrien
530690075Sobrien;;
530790075Sobrien;; As USE insns aren't meaningful after reload, this is used instead
530890075Sobrien;; to prevent deleting instructions setting registers for EH handling
530990075Sobrien(define_insn "prologue_use"
531090075Sobrien  [(unspec:DI [(match_operand:DI 0 "register_operand" "")] 25)]
531190075Sobrien  ""
531290075Sobrien  "// %0 needed for EH"
531390075Sobrien  [(set_attr "itanium_class" "ignore")
531490075Sobrien   (set_attr "predicable" "no")])
5315