ia64.md revision 132718
190075Sobrien;; IA-64 Machine description template
2132718Skan;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
3132718Skan;; Free Software Foundation, Inc.
490075Sobrien;; Contributed by James E. Wilson <wilson@cygnus.com> and
590075Sobrien;;		  David Mosberger <davidm@hpl.hp.com>.
690075Sobrien
7132718Skan;; This file is part of GCC.
890075Sobrien
9132718Skan;; GCC is free software; you can redistribute it and/or modify
1090075Sobrien;; it under the terms of the GNU General Public License as published by
1190075Sobrien;; the Free Software Foundation; either version 2, or (at your option)
1290075Sobrien;; any later version.
1390075Sobrien
14132718Skan;; GCC is distributed in the hope that it will be useful,
1590075Sobrien;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1690075Sobrien;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1790075Sobrien;; GNU General Public License for more details.
1890075Sobrien
1990075Sobrien;; You should have received a copy of the GNU General Public License
20132718Skan;; along with GCC; see the file COPYING.  If not, write to
2190075Sobrien;; the Free Software Foundation, 59 Temple Place - Suite 330,
2290075Sobrien;; Boston, MA 02111-1307, USA.
2390075Sobrien
2490075Sobrien;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
2590075Sobrien
2690075Sobrien;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
2790075Sobrien;; reload.  This will be fixed once scheduling support is turned on.
2890075Sobrien
2990075Sobrien;; ??? Optimize for post-increment addressing modes.
3090075Sobrien
3190075Sobrien;; ??? fselect is not supported, because there is no integer register
3290075Sobrien;; equivalent.
3390075Sobrien
3490075Sobrien;; ??? fp abs/min/max instructions may also work for integer values.
3590075Sobrien
3690075Sobrien;; ??? Would a predicate_reg_operand predicate be useful?  The HP one is buggy,
3790075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking.
3890075Sobrien
3990075Sobrien;; ??? Would a branch_reg_operand predicate be useful?  The HP one is buggy,
4090075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking.
4190075Sobrien
4290075Sobrien;; ??? Go through list of documented named patterns and look for more to
4390075Sobrien;; implement.
4490075Sobrien
4590075Sobrien;; ??? Go through instruction manual and look for more instructions that
4690075Sobrien;; can be emitted.
4790075Sobrien
4890075Sobrien;; ??? Add function unit scheduling info for Itanium (TM) processor.
4990075Sobrien
5090075Sobrien;; ??? Need a better way to describe alternate fp status registers.
5190075Sobrien
52117395Skan(define_constants
53117395Skan  [; Relocations
54117395Skan   (UNSPEC_LTOFF_DTPMOD		0)
55117395Skan   (UNSPEC_LTOFF_DTPREL		1)
56117395Skan   (UNSPEC_DTPREL		2)
57117395Skan   (UNSPEC_LTOFF_TPREL		3)
58117395Skan   (UNSPEC_TPREL		4)
59117395Skan
60117395Skan   (UNSPEC_LD_BASE		9)
61117395Skan   (UNSPEC_GR_SPILL		10)
62117395Skan   (UNSPEC_GR_RESTORE		11)
63117395Skan   (UNSPEC_FR_SPILL		12)
64117395Skan   (UNSPEC_FR_RESTORE		13)
65117395Skan   (UNSPEC_FR_RECIP_APPROX	14)
66117395Skan   (UNSPEC_PRED_REL_MUTEX	15)
67132718Skan   (UNSPEC_GETF_EXP		16)
68117395Skan   (UNSPEC_PIC_CALL		17)
69117395Skan   (UNSPEC_MF			18)
70117395Skan   (UNSPEC_CMPXCHG_ACQ		19)
71117395Skan   (UNSPEC_FETCHADD_ACQ		20)
72117395Skan   (UNSPEC_BSP_VALUE		21)
73117395Skan   (UNSPEC_FLUSHRS		22)
74117395Skan   (UNSPEC_BUNDLE_SELECTOR	23)
75117395Skan   (UNSPEC_ADDP4		24)
76117395Skan   (UNSPEC_PROLOGUE_USE		25)
77122180Skan   (UNSPEC_RET_ADDR		26)
78132718Skan   (UNSPEC_SETF_EXP             27)
79132718Skan   (UNSPEC_FR_SQRT_RECIP_APPROX 28)
80117395Skan  ])
81117395Skan
82117395Skan(define_constants
83117395Skan  [(UNSPECV_ALLOC		0)
84117395Skan   (UNSPECV_BLOCKAGE		1)
85117395Skan   (UNSPECV_INSN_GROUP_BARRIER	2)
86117395Skan   (UNSPECV_BREAK		3)
87117395Skan   (UNSPECV_SET_BSP		4)
88117395Skan   (UNSPECV_PSAC_ALL		5)	; pred.safe_across_calls
89117395Skan   (UNSPECV_PSAC_NORMAL		6)
90117395Skan   (UNSPECV_SETJMP_RECEIVER	7)
91117395Skan  ])
9290075Sobrien
9390075Sobrien;; ::::::::::::::::::::
9490075Sobrien;; ::
9590075Sobrien;; :: Attributes
9690075Sobrien;; ::
9790075Sobrien;; ::::::::::::::::::::
9890075Sobrien
99132718Skan;; Processor type.  This attribute must exactly match the processor_type
100132718Skan;; enumeration in ia64.h.
101132718Skan(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
102132718Skan
10390075Sobrien;; Instruction type.  This primarily determines how instructions can be
10490075Sobrien;; packed in bundles, and secondarily affects scheduling to function units.
10590075Sobrien
10690075Sobrien;; A alu, can go in I or M syllable of a bundle
10790075Sobrien;; I integer
10890075Sobrien;; M memory
10990075Sobrien;; F floating-point
11090075Sobrien;; B branch
11190075Sobrien;; L long immediate, takes two syllables
11290075Sobrien;; S stop bit
11390075Sobrien
11490075Sobrien;; ??? Should not have any pattern with type unknown.  Perhaps add code to
11590075Sobrien;; check this in md_reorg?  Currently use unknown for patterns which emit
11690075Sobrien;; multiple instructions, patterns which emit 0 instructions, and patterns
11790075Sobrien;; which emit instruction that can go in any slot (e.g. nop).
11890075Sobrien
119117395Skan(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
120117395Skan	fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
121117395Skan	chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
122132718Skan	syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
123132718Skan	nop_i,nop_m,nop_x,lfetch,pre_cycle"
124117395Skan  (const_string "unknown"))
12590075Sobrien
12690075Sobrien;; chk_s has an I and an M form; use type A for convenience.
12790075Sobrien(define_attr "type" "unknown,A,I,M,F,B,L,X,S"
12890075Sobrien  (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
12990075Sobrien	 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
13090075Sobrien	 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
13190075Sobrien	 (eq_attr "itanium_class" "lfetch") (const_string "M")
13290075Sobrien	 (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A")
13390075Sobrien	 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
13490075Sobrien	 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
13590075Sobrien	 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
13690075Sobrien	 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
13790075Sobrien	 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
13890075Sobrien	 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
13990075Sobrien	 (eq_attr "itanium_class" "stop_bit") (const_string "S")
14090075Sobrien	 (eq_attr "itanium_class" "nop_x") (const_string "X")
14190075Sobrien	 (eq_attr "itanium_class" "long_i") (const_string "L")]
14290075Sobrien	(const_string "unknown")))
14390075Sobrien
14490075Sobrien(define_attr "itanium_requires_unit0" "no,yes"
14590075Sobrien  (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
14690075Sobrien	 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
14790075Sobrien	 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
14890075Sobrien	 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
14990075Sobrien	 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
15090075Sobrien	 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
15190075Sobrien	(const_string "no")))
15290075Sobrien
15390075Sobrien;; Predication.  True iff this instruction can be predicated.
15490075Sobrien
15590075Sobrien(define_attr "predicable" "no,yes" (const_string "yes"))
15690075Sobrien
157132718Skan;; Empty.  True iff this insn does not generate any code.
158132718Skan
159132718Skan(define_attr "empty" "no,yes" (const_string "no"))
160132718Skan
16190075Sobrien
16290075Sobrien
163132718Skan;; DFA descriptions of ia64 processors used for insn scheduling and
164132718Skan;; bundling.
16590075Sobrien
166132718Skan(automata_option "ndfa")
16790075Sobrien
168132718Skan;; Uncomment the following line to output automata for debugging.
169132718Skan;; (automata_option "v")
17090075Sobrien
171132718Skan(automata_option "w")
17290075Sobrien
173132718Skan;;(automata_option "no-minimization")
17490075Sobrien
17590075Sobrien
176132718Skan(include "itanium1.md")
177132718Skan(include "itanium2.md")
17890075Sobrien
17990075Sobrien
18090075Sobrien;; ::::::::::::::::::::
18190075Sobrien;; ::
18290075Sobrien;; :: Moves
18390075Sobrien;; ::
18490075Sobrien;; ::::::::::::::::::::
18590075Sobrien
18690075Sobrien;; Set of a single predicate register.  This is only used to implement
18790075Sobrien;; pr-to-pr move and complement.
18890075Sobrien
18990075Sobrien(define_insn "*movcci"
19090075Sobrien  [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
19190075Sobrien	(match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
19290075Sobrien  ""
19390075Sobrien  "@
19490075Sobrien   cmp.ne %0, p0 = r0, r0
19590075Sobrien   cmp.eq %0, p0 = r0, r0
19690075Sobrien   (%1) cmp.eq.unc %0, p0 = r0, r0"
19790075Sobrien  [(set_attr "itanium_class" "icmp")
19890075Sobrien   (set_attr "predicable" "no")])
19990075Sobrien
20090075Sobrien(define_insn "movbi"
20190075Sobrien  [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
20290075Sobrien	(match_operand:BI 1 "move_operand"         " O,n, c,  c,*r, n,*m,*r,*r"))]
20390075Sobrien  ""
20490075Sobrien  "@
20590075Sobrien   cmp.ne %0, %I0 = r0, r0
20690075Sobrien   cmp.eq %0, %I0 = r0, r0
20790075Sobrien   #
20890075Sobrien   #
20990075Sobrien   tbit.nz %0, %I0 = %1, 0
21090075Sobrien   adds %0 = %1, r0
21190075Sobrien   ld1%O1 %0 = %1%P1
21290075Sobrien   st1%Q0 %0 = %1%P0
21390075Sobrien   mov %0 = %1"
21490075Sobrien  [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
21590075Sobrien
21690075Sobrien(define_split
21790075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
21890075Sobrien	(match_operand:BI 1 "register_operand" ""))]
21990075Sobrien  "reload_completed
22090075Sobrien   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
22190075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
22290075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
22390075Sobrien     (set (match_dup 0) (const_int 1)))
22490075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
22590075Sobrien     (set (match_dup 0) (const_int 0)))]
22690075Sobrien  "")
22790075Sobrien
22890075Sobrien(define_split
22990075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
23090075Sobrien	(match_operand:BI 1 "register_operand" ""))]
23190075Sobrien  "reload_completed
23290075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
23390075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
23490075Sobrien  [(set (match_dup 2) (match_dup 4))
23590075Sobrien   (set (match_dup 3) (match_dup 5))
236117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
23790075Sobrien  "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
23890075Sobrien   operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
23990075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
24090075Sobrien   operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
24190075Sobrien
24290075Sobrien(define_expand "movqi"
24390075Sobrien  [(set (match_operand:QI 0 "general_operand" "")
24490075Sobrien	(match_operand:QI 1 "general_operand" ""))]
24590075Sobrien  ""
24690075Sobrien{
247117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
248117395Skan  if (!op1)
249117395Skan    DONE;
250117395Skan  operands[1] = op1;
251117395Skan})
25290075Sobrien
25390075Sobrien(define_insn "*movqi_internal"
25490075Sobrien  [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
25590075Sobrien	(match_operand:QI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
25690075Sobrien  "ia64_move_ok (operands[0], operands[1])"
25790075Sobrien  "@
25890075Sobrien   mov %0 = %r1
25990075Sobrien   addl %0 = %1, r0
26090075Sobrien   ld1%O1 %0 = %1%P1
26190075Sobrien   st1%Q0 %0 = %r1%P0
26290075Sobrien   getf.sig %0 = %1
26390075Sobrien   setf.sig %0 = %r1
26490075Sobrien   mov %0 = %1"
26590075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
26690075Sobrien
26790075Sobrien(define_expand "movhi"
26890075Sobrien  [(set (match_operand:HI 0 "general_operand" "")
26990075Sobrien	(match_operand:HI 1 "general_operand" ""))]
27090075Sobrien  ""
27190075Sobrien{
272117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
273117395Skan  if (!op1)
274117395Skan    DONE;
275117395Skan  operands[1] = op1;
276117395Skan})
27790075Sobrien
27890075Sobrien(define_insn "*movhi_internal"
27990075Sobrien  [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
28090075Sobrien	(match_operand:HI 1 "move_operand"        "rO,J,m,rO,*f,rO,*f"))]
28190075Sobrien  "ia64_move_ok (operands[0], operands[1])"
28290075Sobrien  "@
28390075Sobrien   mov %0 = %r1
28490075Sobrien   addl %0 = %1, r0
28590075Sobrien   ld2%O1 %0 = %1%P1
28690075Sobrien   st2%Q0 %0 = %r1%P0
28790075Sobrien   getf.sig %0 = %1
28890075Sobrien   setf.sig %0 = %r1
28990075Sobrien   mov %0 = %1"
29090075Sobrien  [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
29190075Sobrien
29290075Sobrien(define_expand "movsi"
29390075Sobrien  [(set (match_operand:SI 0 "general_operand" "")
29490075Sobrien	(match_operand:SI 1 "general_operand" ""))]
29590075Sobrien  ""
29690075Sobrien{
297117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
298117395Skan  if (!op1)
299117395Skan    DONE;
300117395Skan  operands[1] = op1;
301117395Skan})
30290075Sobrien
30390075Sobrien(define_insn "*movsi_internal"
30490075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
30590075Sobrien	(match_operand:SI 1 "move_operand"        "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
30690075Sobrien  "ia64_move_ok (operands[0], operands[1])"
30790075Sobrien  "@
30890075Sobrien  mov %0 = %r1
30990075Sobrien  addl %0 = %1, r0
31090075Sobrien  movl %0 = %1
31190075Sobrien  ld4%O1 %0 = %1%P1
31290075Sobrien  st4%Q0 %0 = %r1%P0
31390075Sobrien  getf.sig %0 = %1
31490075Sobrien  setf.sig %0 = %r1
31590075Sobrien  mov %0 = %1
31690075Sobrien  mov %0 = %1
31790075Sobrien  mov %0 = %r1"
318117395Skan  ;; frar_m, toar_m ??? why not frar_i and toar_i
31990075Sobrien  [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
32090075Sobrien
32190075Sobrien(define_expand "movdi"
32290075Sobrien  [(set (match_operand:DI 0 "general_operand" "")
32390075Sobrien	(match_operand:DI 1 "general_operand" ""))]
32490075Sobrien  ""
32590075Sobrien{
326117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
327117395Skan  if (!op1)
328117395Skan    DONE;
329117395Skan  operands[1] = op1;
330117395Skan})
33190075Sobrien
33290075Sobrien(define_insn "*movdi_internal"
33390075Sobrien  [(set (match_operand:DI 0 "destination_operand"
33490075Sobrien		    "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
33590075Sobrien	(match_operand:DI 1 "move_operand"
336132718Skan		    "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
33790075Sobrien  "ia64_move_ok (operands[0], operands[1])"
33890075Sobrien{
33990075Sobrien  static const char * const alt[] = {
340117395Skan    "%,mov %0 = %r1",
341117395Skan    "%,addl %0 = %1, r0",
342117395Skan    "%,movl %0 = %1",
343117395Skan    "%,ld8%O1 %0 = %1%P1",
344117395Skan    "%,st8%Q0 %0 = %r1%P0",
345117395Skan    "%,getf.sig %0 = %1",
346117395Skan    "%,setf.sig %0 = %r1",
347117395Skan    "%,mov %0 = %1",
348117395Skan    "%,ldf8 %0 = %1%P1",
349117395Skan    "%,stf8 %0 = %1%P0",
350117395Skan    "%,mov %0 = %1",
351117395Skan    "%,mov %0 = %r1",
352117395Skan    "%,mov %0 = %1",
353117395Skan    "%,mov %0 = %1",
354117395Skan    "%,mov %0 = %1",
355117395Skan    "%,mov %0 = %1",
356117395Skan    "mov %0 = pr",
357117395Skan    "mov pr = %1, -1"
35890075Sobrien  };
35990075Sobrien
36090075Sobrien  if (which_alternative == 2 && ! TARGET_NO_PIC
36190075Sobrien      && symbolic_operand (operands[1], VOIDmode))
36290075Sobrien    abort ();
36390075Sobrien
36490075Sobrien  return alt[which_alternative];
365117395Skan}
36690075Sobrien  [(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")])
36790075Sobrien
36890075Sobrien(define_split
369132718Skan  [(set (match_operand 0 "register_operand" "")
370132718Skan	(match_operand 1 "symbolic_operand" ""))]
37190075Sobrien  "reload_completed && ! TARGET_NO_PIC"
37290075Sobrien  [(const_int 0)]
37390075Sobrien{
374132718Skan  ia64_expand_load_address (operands[0], operands[1]);
37590075Sobrien  DONE;
376117395Skan})
37790075Sobrien
37890075Sobrien(define_expand "load_fptr"
37990075Sobrien  [(set (match_dup 2)
380117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
38190075Sobrien   (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
38290075Sobrien  ""
38390075Sobrien{
38490075Sobrien  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
38590075Sobrien  operands[3] = gen_rtx_MEM (DImode, operands[2]);
38690075Sobrien  RTX_UNCHANGING_P (operands[3]) = 1;
387117395Skan})
38890075Sobrien
38990075Sobrien(define_insn "*load_fptr_internal1"
39090075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
391117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
39290075Sobrien  ""
39390075Sobrien  "addl %0 = @ltoff(@fptr(%1)), gp"
39490075Sobrien  [(set_attr "itanium_class" "ialu")])
39590075Sobrien
39690075Sobrien(define_insn "load_gprel"
39790075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
398117395Skan	(plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
39990075Sobrien  ""
40090075Sobrien  "addl %0 = @gprel(%1), gp"
40190075Sobrien  [(set_attr "itanium_class" "ialu")])
40290075Sobrien
40390075Sobrien(define_insn "gprel64_offset"
40490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
40590075Sobrien	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
40690075Sobrien  ""
40790075Sobrien  "movl %0 = @gprel(%1)"
40890075Sobrien  [(set_attr "itanium_class" "long_i")])
40990075Sobrien
41090075Sobrien(define_expand "load_gprel64"
41190075Sobrien  [(set (match_dup 2)
41290075Sobrien	(minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
41390075Sobrien   (set (match_operand:DI 0 "register_operand" "")
41490075Sobrien	(plus:DI (match_dup 3) (match_dup 2)))]
41590075Sobrien  ""
41690075Sobrien{
41790075Sobrien  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
41890075Sobrien  operands[3] = pic_offset_table_rtx;
419117395Skan})
42090075Sobrien
421132718Skan;; This is used as a placeholder for the return address during early
422132718Skan;; compilation.  We won't know where we've placed this until during
423132718Skan;; reload, at which point it can wind up in b0, a general register,
424132718Skan;; or memory.  The only safe destination under these conditions is a
425132718Skan;; general register.
426132718Skan
427132718Skan(define_insn_and_split "*movdi_ret_addr"
428132718Skan  [(set (match_operand:DI 0 "register_operand" "=r")
429132718Skan	(unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
43090075Sobrien  ""
431132718Skan  "#"
432132718Skan  "reload_completed"
433132718Skan  [(const_int 0)]
43490075Sobrien{
435132718Skan  ia64_split_return_addr_rtx (operands[0]);
436132718Skan  DONE;
437132718Skan}
438132718Skan  [(set_attr "itanium_class" "ialu")])
43990075Sobrien
440117395Skan(define_insn "*load_symptr_high"
44190075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
442117395Skan	(plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
443117395Skan		 (match_operand:DI 2 "register_operand" "a")))]
44490075Sobrien  ""
445117395Skan{
446117395Skan  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
447117395Skan    return "%,addl %0 = @ltoffx(%1), %2";
448117395Skan  else
449117395Skan    return "%,addl %0 = @ltoff(%1), %2";
450117395Skan}
45190075Sobrien  [(set_attr "itanium_class" "ialu")])
45290075Sobrien
453117395Skan(define_insn "*load_symptr_low"
454117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
455117395Skan	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
456117395Skan		   (match_operand 2 "got_symbolic_operand" "s")))]
457117395Skan  ""
458117395Skan{
459117395Skan  if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
460117395Skan    return "%,ld8.mov %0 = [%1], %2";
461117395Skan  else
462117395Skan    return "%,ld8 %0 = [%1]";
463117395Skan}
464117395Skan  [(set_attr "itanium_class" "ld")])
465117395Skan
466117395Skan(define_insn "load_ltoff_dtpmod"
467117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
468117395Skan	(plus:DI (reg:DI 1)
469117395Skan		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
470117395Skan			    UNSPEC_LTOFF_DTPMOD)))]
471117395Skan  ""
472117395Skan  "addl %0 = @ltoff(@dtpmod(%1)), gp"
473117395Skan  [(set_attr "itanium_class" "ialu")])
474117395Skan
475117395Skan(define_insn "load_ltoff_dtprel"
476117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
477117395Skan	(plus:DI (reg:DI 1)
478117395Skan		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
479117395Skan			    UNSPEC_LTOFF_DTPREL)))]
480117395Skan  ""
481117395Skan  "addl %0 = @ltoff(@dtprel(%1)), gp"
482117395Skan  [(set_attr "itanium_class" "ialu")])
483117395Skan
484117395Skan(define_expand "load_dtprel"
485117395Skan  [(set (match_operand:DI 0 "register_operand" "")
486117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
487117395Skan		   UNSPEC_DTPREL))]
488117395Skan  ""
489117395Skan  "")
490117395Skan
491117395Skan(define_insn "*load_dtprel64"
492117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
493117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
494117395Skan		   UNSPEC_DTPREL))]
495117395Skan  "TARGET_TLS64"
496117395Skan  "movl %0 = @dtprel(%1)"
497117395Skan  [(set_attr "itanium_class" "long_i")])
498117395Skan
499117395Skan(define_insn "*load_dtprel22"
500117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
501117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
502117395Skan		   UNSPEC_DTPREL))]
503117395Skan  ""
504117395Skan  "addl %0 = @dtprel(%1), r0"
505117395Skan  [(set_attr "itanium_class" "ialu")])
506117395Skan
507117395Skan(define_expand "add_dtprel"
508117395Skan  [(set (match_operand:DI 0 "register_operand" "")
509117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "")
510117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
511117395Skan			    UNSPEC_DTPREL)))]
512117395Skan  "!TARGET_TLS64"
513117395Skan  "")
514117395Skan
515117395Skan(define_insn "*add_dtprel14"
516117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
517117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "r")
518117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
519117395Skan			    UNSPEC_DTPREL)))]
520117395Skan  "TARGET_TLS14"
521117395Skan  "adds %0 = @dtprel(%2), %1"
522117395Skan  [(set_attr "itanium_class" "ialu")])
523117395Skan
524117395Skan(define_insn "*add_dtprel22"
525117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
526117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "a")
527117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
528117395Skan			    UNSPEC_DTPREL)))]
529117395Skan  "TARGET_TLS22"
530117395Skan  "addl %0 = @dtprel(%2), %1"
531117395Skan  [(set_attr "itanium_class" "ialu")])
532117395Skan
533117395Skan(define_insn "load_ltoff_tprel"
534117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
535117395Skan	(plus:DI (reg:DI 1)
536117395Skan		 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
537117395Skan			    UNSPEC_LTOFF_TPREL)))]
538117395Skan  ""
539117395Skan  "addl %0 = @ltoff(@tprel(%1)), gp"
540117395Skan  [(set_attr "itanium_class" "ialu")])
541117395Skan
542117395Skan(define_expand "load_tprel"
543117395Skan  [(set (match_operand:DI 0 "register_operand" "")
544117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
545117395Skan		   UNSPEC_TPREL))]
546117395Skan  ""
547117395Skan  "")
548117395Skan
549117395Skan(define_insn "*load_tprel64"
550117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
551117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
552117395Skan		   UNSPEC_TPREL))]
553117395Skan  "TARGET_TLS64"
554117395Skan  "movl %0 = @tprel(%1)"
555117395Skan  [(set_attr "itanium_class" "long_i")])
556117395Skan
557117395Skan(define_insn "*load_tprel22"
558117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
559117395Skan	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
560117395Skan		   UNSPEC_TPREL))]
561117395Skan  ""
562117395Skan  "addl %0 = @tprel(%1), r0"
563117395Skan  [(set_attr "itanium_class" "ialu")])
564117395Skan
565117395Skan(define_expand "add_tprel"
566117395Skan  [(set (match_operand:DI 0 "register_operand" "")
567117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "")
568117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
569117395Skan			    UNSPEC_TPREL)))]
570117395Skan  "!TARGET_TLS64"
571117395Skan  "")
572117395Skan
573117395Skan(define_insn "*add_tprel14"
574117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
575117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "r")
576117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
577117395Skan			    UNSPEC_TPREL)))]
578117395Skan  "TARGET_TLS14"
579117395Skan  "adds %0 = @tprel(%2), %1"
580117395Skan  [(set_attr "itanium_class" "ialu")])
581117395Skan
582117395Skan(define_insn "*add_tprel22"
583117395Skan  [(set (match_operand:DI 0 "register_operand" "=r")
584117395Skan	(plus:DI (match_operand:DI 1 "register_operand" "a")
585117395Skan		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
586117395Skan			    UNSPEC_TPREL)))]
587117395Skan  "TARGET_TLS22"
588117395Skan  "addl %0 = @tprel(%2), %1"
589117395Skan  [(set_attr "itanium_class" "ialu")])
590117395Skan
59190075Sobrien;; With no offsettable memory references, we've got to have a scratch
592132718Skan;; around to play with the second word.  However, in order to avoid a
593132718Skan;; reload nightmare we lie, claim we don't need one, and fix it up
594132718Skan;; in ia64_split_tmode_move.
59590075Sobrien(define_expand "movti"
596132718Skan  [(set (match_operand:TI 0 "general_operand" "")
597132718Skan	(match_operand:TI 1 "general_operand" ""))]
59890075Sobrien  ""
59990075Sobrien{
600117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
601117395Skan  if (!op1)
602117395Skan    DONE;
603117395Skan  operands[1] = op1;
604117395Skan})
60590075Sobrien
60690075Sobrien(define_insn_and_split "*movti_internal"
60790075Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
608132718Skan	(match_operand:TI 1 "general_operand"      "ri,m,r"))]
60990075Sobrien  "ia64_move_ok (operands[0], operands[1])"
61090075Sobrien  "#"
61190075Sobrien  "reload_completed"
61290075Sobrien  [(const_int 0)]
61390075Sobrien{
614132718Skan  ia64_split_tmode_move (operands);
61590075Sobrien  DONE;
616117395Skan}
61790075Sobrien  [(set_attr "itanium_class" "unknown")
61890075Sobrien   (set_attr "predicable" "no")])
61990075Sobrien
62090075Sobrien;; Floating Point Moves
62190075Sobrien;;
62290075Sobrien;; Note - Patterns for SF mode moves are compulsory, but
623117395Skan;; patterns for DF are optional, as GCC can synthesize them.
62490075Sobrien
62590075Sobrien(define_expand "movsf"
62690075Sobrien  [(set (match_operand:SF 0 "general_operand" "")
62790075Sobrien	(match_operand:SF 1 "general_operand" ""))]
62890075Sobrien  ""
62990075Sobrien{
630117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
631117395Skan  if (!op1)
632117395Skan    DONE;
633117395Skan  operands[1] = op1;
634117395Skan})
63590075Sobrien
63690075Sobrien(define_insn "*movsf_internal"
63790075Sobrien  [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
63890075Sobrien	(match_operand:SF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
63990075Sobrien  "ia64_move_ok (operands[0], operands[1])"
64090075Sobrien  "@
641117395Skan   mov %0 = %F1
642117395Skan   ldfs %0 = %1%P1
643117395Skan   stfs %0 = %F1%P0
644117395Skan   getf.s %0 = %F1
645117395Skan   setf.s %0 = %1
646117395Skan   mov %0 = %1
647117395Skan   ld4%O1 %0 = %1%P1
648117395Skan   st4%Q0 %0 = %1%P0"
64990075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
65090075Sobrien
65190075Sobrien(define_expand "movdf"
65290075Sobrien  [(set (match_operand:DF 0 "general_operand" "")
65390075Sobrien	(match_operand:DF 1 "general_operand" ""))]
65490075Sobrien  ""
65590075Sobrien{
656117395Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
657117395Skan  if (!op1)
658117395Skan    DONE;
659117395Skan  operands[1] = op1;
660117395Skan})
66190075Sobrien
66290075Sobrien(define_insn "*movdf_internal"
66390075Sobrien  [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
66490075Sobrien	(match_operand:DF 1 "general_operand"     "fG,Q,fG,fG,*r,*r, m,*r"))]
66590075Sobrien  "ia64_move_ok (operands[0], operands[1])"
66690075Sobrien  "@
667117395Skan   mov %0 = %F1
668117395Skan   ldfd %0 = %1%P1
669117395Skan   stfd %0 = %F1%P0
670117395Skan   getf.d %0 = %F1
671117395Skan   setf.d %0 = %1
672117395Skan   mov %0 = %1
673117395Skan   ld8%O1 %0 = %1%P1
674117395Skan   st8%Q0 %0 = %1%P0"
67590075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
67690075Sobrien
67790075Sobrien;; With no offsettable memory references, we've got to have a scratch
67890075Sobrien;; around to play with the second word if the variable winds up in GRs.
679132718Skan(define_expand "movxf"
680132718Skan  [(set (match_operand:XF 0 "general_operand" "")
681132718Skan	(match_operand:XF 1 "general_operand" ""))]
682132718Skan  ""
68390075Sobrien{
684132718Skan  /* We must support XFmode loads into general registers for stdarg/vararg
68590075Sobrien     and unprototyped calls.  We split them into DImode loads for convenience.
686132718Skan     We don't need XFmode stores from general regs, because a stdarg/vararg
68790075Sobrien     routine does a block store to memory of unnamed arguments.  */
68890075Sobrien  if (GET_CODE (operands[0]) == REG
68990075Sobrien      && GR_REGNO_P (REGNO (operands[0])))
69090075Sobrien    {
691132718Skan      /* We're hoping to transform everything that deals with XFmode
69290075Sobrien	 quantities and GR registers early in the compiler.  */
69390075Sobrien      if (no_new_pseudos)
69490075Sobrien	abort ();
69590075Sobrien
69690075Sobrien      /* Struct to register can just use TImode instead.  */
69790075Sobrien      if ((GET_CODE (operands[1]) == SUBREG
69890075Sobrien	   && GET_MODE (SUBREG_REG (operands[1])) == TImode)
69990075Sobrien	  || (GET_CODE (operands[1]) == REG
70090075Sobrien	      && GR_REGNO_P (REGNO (operands[1]))))
70190075Sobrien	{
70290075Sobrien	  emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
70390075Sobrien			  SUBREG_REG (operands[1]));
70490075Sobrien	  DONE;
70590075Sobrien	}
70690075Sobrien
70790075Sobrien      if (GET_CODE (operands[1]) == CONST_DOUBLE)
70890075Sobrien	{
70990075Sobrien	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
710132718Skan			  operand_subword (operands[1], 0, 0, XFmode));
71190075Sobrien	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
712132718Skan			  operand_subword (operands[1], 1, 0, XFmode));
71390075Sobrien	  DONE;
71490075Sobrien	}
71590075Sobrien
71690075Sobrien      /* If the quantity is in a register not known to be GR, spill it.  */
717132718Skan      if (register_operand (operands[1], XFmode))
718132718Skan	operands[1] = spill_xfmode_operand (operands[1], 1);
71990075Sobrien
72090075Sobrien      if (GET_CODE (operands[1]) == MEM)
72190075Sobrien	{
72290075Sobrien	  rtx out[2];
72390075Sobrien
72490075Sobrien	  out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
72590075Sobrien	  out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
72690075Sobrien
72790075Sobrien	  emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
72890075Sobrien	  emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
72990075Sobrien	  DONE;
73090075Sobrien	}
73190075Sobrien
73290075Sobrien      abort ();
73390075Sobrien    }
73490075Sobrien
73590075Sobrien  if (! reload_in_progress && ! reload_completed)
73690075Sobrien    {
737132718Skan      operands[0] = spill_xfmode_operand (operands[0], 0);
738132718Skan      operands[1] = spill_xfmode_operand (operands[1], 0);
73990075Sobrien
74090075Sobrien      if (! ia64_move_ok (operands[0], operands[1]))
741132718Skan	operands[1] = force_reg (XFmode, operands[1]);
74290075Sobrien    }
743117395Skan})
74490075Sobrien
74590075Sobrien;; ??? There's no easy way to mind volatile acquire/release semantics.
74690075Sobrien
747132718Skan(define_insn "*movxf_internal"
748132718Skan  [(set (match_operand:XF 0 "destination_xfmode_operand" "=f,f, m")
749132718Skan	(match_operand:XF 1 "general_xfmode_operand"     "fG,m,fG"))]
750132718Skan  "ia64_move_ok (operands[0], operands[1])"
75190075Sobrien  "@
752117395Skan   mov %0 = %F1
753117395Skan   ldfe %0 = %1%P1
754117395Skan   stfe %0 = %F1%P0"
75590075Sobrien  [(set_attr "itanium_class" "fmisc,fld,stf")])
756132718Skan
757132718Skan;; Better code generation via insns that deal with TFmode register pairs
758132718Skan;; directly.  Same concerns apply as for TImode.
759132718Skan(define_expand "movtf"
760132718Skan  [(set (match_operand:TF 0 "general_operand" "")
761132718Skan	(match_operand:TF 1 "general_operand" ""))]
762132718Skan  ""
763132718Skan{
764132718Skan  rtx op1 = ia64_expand_move (operands[0], operands[1]);
765132718Skan  if (!op1)
766132718Skan    DONE;
767132718Skan  operands[1] = op1;
768132718Skan})
769132718Skan
770132718Skan(define_insn_and_split "*movtf_internal"
771132718Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m")
772132718Skan	(match_operand:TF 1 "general_operand"      "ri,m,r"))]
773132718Skan  "ia64_move_ok (operands[0], operands[1])"
774132718Skan  "#"
775132718Skan  "reload_completed"
776132718Skan  [(const_int 0)]
777132718Skan{
778132718Skan  ia64_split_tmode_move (operands);
779132718Skan  DONE;
780132718Skan}
781132718Skan  [(set_attr "itanium_class" "unknown")
782132718Skan   (set_attr "predicable" "no")])
783132718Skan
78490075Sobrien
78590075Sobrien;; ::::::::::::::::::::
78690075Sobrien;; ::
78790075Sobrien;; :: Conversions
78890075Sobrien;; ::
78990075Sobrien;; ::::::::::::::::::::
79090075Sobrien
79190075Sobrien;; Signed conversions from a smaller integer to a larger integer
79290075Sobrien
79390075Sobrien(define_insn "extendqidi2"
79490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
79590075Sobrien	(sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
79690075Sobrien  ""
79790075Sobrien  "sxt1 %0 = %1"
79890075Sobrien  [(set_attr "itanium_class" "xtd")])
79990075Sobrien
80090075Sobrien(define_insn "extendhidi2"
80190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
80290075Sobrien	(sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
80390075Sobrien  ""
80490075Sobrien  "sxt2 %0 = %1"
80590075Sobrien  [(set_attr "itanium_class" "xtd")])
80690075Sobrien
80790075Sobrien(define_insn "extendsidi2"
80890075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
80990075Sobrien	(sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
81090075Sobrien  ""
81190075Sobrien  "@
81290075Sobrien   sxt4 %0 = %1
81390075Sobrien   fsxt.r %0 = %1, %1"
81490075Sobrien  [(set_attr "itanium_class" "xtd,fmisc")])
81590075Sobrien
81690075Sobrien;; Unsigned conversions from a smaller integer to a larger integer
81790075Sobrien
81890075Sobrien(define_insn "zero_extendqidi2"
81990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
82090075Sobrien	(zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
82190075Sobrien  ""
82290075Sobrien  "@
82390075Sobrien   zxt1 %0 = %1
82490075Sobrien   ld1%O1 %0 = %1%P1"
82590075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
82690075Sobrien
82790075Sobrien(define_insn "zero_extendhidi2"
82890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
82990075Sobrien	(zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
83090075Sobrien  ""
83190075Sobrien  "@
83290075Sobrien   zxt2 %0 = %1
83390075Sobrien   ld2%O1 %0 = %1%P1"
83490075Sobrien  [(set_attr "itanium_class" "xtd,ld")])
83590075Sobrien
83690075Sobrien(define_insn "zero_extendsidi2"
83790075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
83890075Sobrien	(zero_extend:DI
83990075Sobrien	  (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
84090075Sobrien  ""
84190075Sobrien  "@
84290075Sobrien   zxt4 %0 = %1
84390075Sobrien   ld4%O1 %0 = %1%P1
84490075Sobrien   fmix.r %0 = f0, %1"
84590075Sobrien  [(set_attr "itanium_class" "xtd,ld,fmisc")])
84690075Sobrien
84790075Sobrien;; Convert between floating point types of different sizes.
84890075Sobrien
84990075Sobrien;; At first glance, it would appear that emitting fnorm for an extending
85090075Sobrien;; conversion is unnecessary.  However, the stf and getf instructions work
85190075Sobrien;; correctly only if the input is properly rounded for its type.  In
85290075Sobrien;; particular, we get the wrong result for getf.d/stfd if the input is a
85390075Sobrien;; denorm single.  Since we don't know what the next instruction will be, we
85490075Sobrien;; have to emit an fnorm.
85590075Sobrien
85690075Sobrien;; ??? Optimization opportunity here.  Get rid of the insn altogether
85790075Sobrien;; when we can.  Should probably use a scheme like has been proposed
85890075Sobrien;; for ia32 in dealing with operands that match unary operators.  This
85990075Sobrien;; would let combine merge the thing into adjacent insns.  See also how the
86090075Sobrien;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
86190075Sobrien;; se_register_operand.
86290075Sobrien
86390075Sobrien(define_insn "extendsfdf2"
86490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
86590075Sobrien	(float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
86690075Sobrien  ""
86790075Sobrien  "fnorm.d %0 = %1"
86890075Sobrien  [(set_attr "itanium_class" "fmac")])
86990075Sobrien
870132718Skan(define_insn "extendsfxf2"
871132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
872132718Skan	(float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]
873132718Skan  ""
87490075Sobrien  "fnorm %0 = %1"
87590075Sobrien  [(set_attr "itanium_class" "fmac")])
87690075Sobrien
877132718Skan(define_insn "extenddfxf2"
878132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
879132718Skan	(float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]
880132718Skan  ""
88190075Sobrien  "fnorm %0 = %1"
88290075Sobrien  [(set_attr "itanium_class" "fmac")])
88390075Sobrien
88490075Sobrien(define_insn "truncdfsf2"
88590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
88690075Sobrien	(float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
88790075Sobrien  ""
88890075Sobrien  "fnorm.s %0 = %1"
88990075Sobrien  [(set_attr "itanium_class" "fmac")])
89090075Sobrien
891132718Skan(define_insn "truncxfsf2"
89290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
893132718Skan	(float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]
894132718Skan  ""
89590075Sobrien  "fnorm.s %0 = %1"
89690075Sobrien  [(set_attr "itanium_class" "fmac")])
89790075Sobrien
898132718Skan(define_insn "truncxfdf2"
89990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
900132718Skan	(float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]
901132718Skan  ""
90290075Sobrien  "fnorm.d %0 = %1"
90390075Sobrien  [(set_attr "itanium_class" "fmac")])
90490075Sobrien
90590075Sobrien;; Convert between signed integer types and floating point.
90690075Sobrien
907132718Skan(define_insn "floatdixf2"
908132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
909132718Skan	(float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
910132718Skan  ""
91190075Sobrien  "fcvt.xf %0 = %1"
91290075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
91390075Sobrien
91490075Sobrien(define_insn "fix_truncsfdi2"
91590075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
91690075Sobrien	(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
91790075Sobrien  ""
91890075Sobrien  "fcvt.fx.trunc %0 = %1"
91990075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
92090075Sobrien
92190075Sobrien(define_insn "fix_truncdfdi2"
92290075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
92390075Sobrien	(fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
92490075Sobrien  ""
92590075Sobrien  "fcvt.fx.trunc %0 = %1"
92690075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
92790075Sobrien
928132718Skan(define_insn "fix_truncxfdi2"
92990075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
930132718Skan	(fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
931132718Skan  ""
93290075Sobrien  "fcvt.fx.trunc %0 = %1"
93390075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
93490075Sobrien
935132718Skan(define_insn "fix_truncxfdi2_alts"
93690075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
937132718Skan	(fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
93890075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
939132718Skan  ""
94090075Sobrien  "fcvt.fx.trunc.s%2 %0 = %1"
94190075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
94290075Sobrien
94390075Sobrien;; Convert between unsigned integer types and floating point.
94490075Sobrien
94590075Sobrien(define_insn "floatunsdisf2"
94690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
94790075Sobrien	(unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
94890075Sobrien  ""
94990075Sobrien  "fcvt.xuf.s %0 = %1"
95090075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
95190075Sobrien
95290075Sobrien(define_insn "floatunsdidf2"
95390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
95490075Sobrien	(unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
95590075Sobrien  ""
95690075Sobrien  "fcvt.xuf.d %0 = %1"
95790075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
95890075Sobrien
959132718Skan(define_insn "floatunsdixf2"
960132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
961132718Skan	(unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
962132718Skan  ""
96390075Sobrien  "fcvt.xuf %0 = %1"
96490075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
96590075Sobrien
96690075Sobrien(define_insn "fixuns_truncsfdi2"
96790075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
96890075Sobrien	(unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
96990075Sobrien  ""
97090075Sobrien  "fcvt.fxu.trunc %0 = %1"
97190075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
97290075Sobrien
97390075Sobrien(define_insn "fixuns_truncdfdi2"
97490075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
97590075Sobrien	(unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
97690075Sobrien  ""
97790075Sobrien  "fcvt.fxu.trunc %0 = %1"
97890075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
97990075Sobrien
980132718Skan(define_insn "fixuns_truncxfdi2"
98190075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
982132718Skan	(unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
983132718Skan  ""
98490075Sobrien  "fcvt.fxu.trunc %0 = %1"
98590075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
98690075Sobrien
987132718Skan(define_insn "fixuns_truncxfdi2_alts"
98890075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
989132718Skan	(unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
99090075Sobrien   (use (match_operand:SI 2 "const_int_operand" ""))]
991132718Skan  ""
99290075Sobrien  "fcvt.fxu.trunc.s%2 %0 = %1"
99390075Sobrien  [(set_attr "itanium_class" "fcvtfx")])
99490075Sobrien
99590075Sobrien;; ::::::::::::::::::::
99690075Sobrien;; ::
99790075Sobrien;; :: Bit field extraction
99890075Sobrien;; ::
99990075Sobrien;; ::::::::::::::::::::
100090075Sobrien
100190075Sobrien(define_insn "extv"
100290075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
100390075Sobrien	(sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
100490075Sobrien			 (match_operand:DI 2 "const_int_operand" "n")
100590075Sobrien			 (match_operand:DI 3 "const_int_operand" "n")))]
100690075Sobrien  ""
100790075Sobrien  "extr %0 = %1, %3, %2"
100890075Sobrien  [(set_attr "itanium_class" "ishf")])
100990075Sobrien
101090075Sobrien(define_insn "extzv"
101190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
101290075Sobrien	(zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
101390075Sobrien			 (match_operand:DI 2 "const_int_operand" "n")
101490075Sobrien			 (match_operand:DI 3 "const_int_operand" "n")))]
101590075Sobrien  ""
101690075Sobrien  "extr.u %0 = %1, %3, %2"
101790075Sobrien  [(set_attr "itanium_class" "ishf")])
101890075Sobrien
101990075Sobrien;; Insert a bit field.
102090075Sobrien;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
102190075Sobrien;; Source1 can be 0 or -1.
102290075Sobrien;; Source2 can be 0.
102390075Sobrien
102490075Sobrien;; ??? Actual dep instruction is more powerful than what these insv
102590075Sobrien;; patterns support.  Unfortunately, combine is unable to create patterns
102690075Sobrien;; where source2 != dest.
102790075Sobrien
102890075Sobrien(define_expand "insv"
102990075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
103090075Sobrien			 (match_operand:DI 1 "const_int_operand" "")
103190075Sobrien			 (match_operand:DI 2 "const_int_operand" ""))
103290075Sobrien	(match_operand:DI 3 "nonmemory_operand" ""))]
103390075Sobrien  ""
103490075Sobrien{
103590075Sobrien  int width = INTVAL (operands[1]);
103690075Sobrien  int shift = INTVAL (operands[2]);
103790075Sobrien
103890075Sobrien  /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
103990075Sobrien     pseudo.  */
104090075Sobrien  if (! register_operand (operands[3], DImode)
104190075Sobrien      && operands[3] != const0_rtx && operands[3] != constm1_rtx)
104290075Sobrien    operands[3] = force_reg (DImode, operands[3]);
104390075Sobrien
104490075Sobrien  /* If this is a single dep instruction, we have nothing to do.  */
104590075Sobrien  if (! ((register_operand (operands[3], DImode) && width <= 16)
104690075Sobrien	 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
104790075Sobrien    {
104890075Sobrien      /* Check for cases that can be implemented with a mix instruction.  */
104990075Sobrien      if (width == 32 && shift == 0)
105090075Sobrien	{
105190075Sobrien	  /* Directly generating the mix4left instruction confuses
105290075Sobrien	     optimize_bit_field in function.c.  Since this is performing
105390075Sobrien	     a useful optimization, we defer generation of the complicated
105490075Sobrien	     mix4left RTL to the first splitting phase.  */
105590075Sobrien	  rtx tmp = gen_reg_rtx (DImode);
105690075Sobrien	  emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
105790075Sobrien	  DONE;
105890075Sobrien	}
105990075Sobrien      else if (width == 32 && shift == 32)
106090075Sobrien	{
106190075Sobrien	  emit_insn (gen_mix4right (operands[0], operands[3]));
106290075Sobrien	  DONE;
106390075Sobrien	}
106490075Sobrien
106590075Sobrien      /* We could handle remaining cases by emitting multiple dep
106690075Sobrien	 instructions.
106790075Sobrien
106890075Sobrien	 If we need more than two dep instructions then we lose.  A 6
106990075Sobrien	 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
107090075Sobrien	 mov;;dep,shr;;dep,shr;;dep.  The former can be executed in 3 cycles,
107190075Sobrien	 the latter is 6 cycles on an Itanium (TM) processor, because there is
107290075Sobrien	 only one function unit that can execute dep and shr immed.
107390075Sobrien
107490075Sobrien	 If we only need two dep instruction, then we still lose.
107590075Sobrien	 mov;;dep,shr;;dep is still 4 cycles.  Even if we optimize away
107690075Sobrien	 the unnecessary mov, this is still undesirable because it will be
107790075Sobrien	 hard to optimize, and it creates unnecessary pressure on the I0
107890075Sobrien	 function unit.  */
107990075Sobrien
108090075Sobrien      FAIL;
108190075Sobrien
108290075Sobrien#if 0
108390075Sobrien      /* This code may be useful for other IA-64 processors, so we leave it in
108490075Sobrien	 for now.  */
108590075Sobrien      while (width > 16)
108690075Sobrien	{
108790075Sobrien	  rtx tmp;
108890075Sobrien
108990075Sobrien	  emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
109090075Sobrien			       operands[3]));
109190075Sobrien	  shift += 16;
109290075Sobrien	  width -= 16;
109390075Sobrien	  tmp = gen_reg_rtx (DImode);
109490075Sobrien	  emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
109590075Sobrien	  operands[3] = tmp;
109690075Sobrien	}
109790075Sobrien      operands[1] = GEN_INT (width);
109890075Sobrien      operands[2] = GEN_INT (shift);
109990075Sobrien#endif
110090075Sobrien    }
1101117395Skan})
110290075Sobrien
110390075Sobrien(define_insn "*insv_internal"
110490075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
110590075Sobrien			 (match_operand:DI 1 "const_int_operand" "n")
110690075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
110790075Sobrien	(match_operand:DI 3 "nonmemory_operand" "rP"))]
110890075Sobrien  "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
110990075Sobrien   || operands[3] == const0_rtx || operands[3] == constm1_rtx"
111090075Sobrien  "dep %0 = %3, %0, %2, %1"
111190075Sobrien  [(set_attr "itanium_class" "ishf")])
111290075Sobrien
1113117395Skan;; Combine doesn't like to create bit-field insertions into zero.
111490075Sobrien(define_insn "*depz_internal"
111590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
111690075Sobrien	(and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
111790075Sobrien			   (match_operand:DI 2 "const_int_operand" "n"))
111890075Sobrien		(match_operand:DI 3 "const_int_operand" "n")))]
111990075Sobrien  "CONST_OK_FOR_M (INTVAL (operands[2]))
112090075Sobrien   && ia64_depz_field_mask (operands[3], operands[2]) > 0"
112190075Sobrien{
112290075Sobrien  operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1123117395Skan  return "%,dep.z %0 = %1, %2, %3";
1124117395Skan}
112590075Sobrien  [(set_attr "itanium_class" "ishf")])
112690075Sobrien
112790075Sobrien(define_insn "shift_mix4left"
112890075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
112990075Sobrien			 (const_int 32) (const_int 0))
113090075Sobrien	(match_operand:DI 1 "gr_register_operand" "r"))
113190075Sobrien   (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
113290075Sobrien  ""
113390075Sobrien  "#"
113490075Sobrien  [(set_attr "itanium_class" "unknown")])
113590075Sobrien
113690075Sobrien(define_split
113790075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
113890075Sobrien			 (const_int 32) (const_int 0))
113990075Sobrien	(match_operand:DI 1 "register_operand" ""))
114090075Sobrien   (clobber (match_operand:DI 2 "register_operand" ""))]
114190075Sobrien  "reload_completed"
114290075Sobrien  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
114390075Sobrien   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
114490075Sobrien	(lshiftrt:DI (match_dup 3) (const_int 32)))]
114590075Sobrien  "operands[3] = operands[2];")
114690075Sobrien
114790075Sobrien(define_split
114890075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
114990075Sobrien			 (const_int 32) (const_int 0))
115090075Sobrien	(match_operand:DI 1 "register_operand" ""))
115190075Sobrien   (clobber (match_operand:DI 2 "register_operand" ""))]
115290075Sobrien  "! reload_completed"
115390075Sobrien  [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
115490075Sobrien   (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
115590075Sobrien	(lshiftrt:DI (match_dup 3) (const_int 32)))]
115690075Sobrien  "operands[3] = operands[2];")
115790075Sobrien
115890075Sobrien(define_insn "*mix4left"
115990075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
116090075Sobrien			 (const_int 32) (const_int 0))
116190075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
116290075Sobrien		     (const_int 32)))]
116390075Sobrien  ""
116490075Sobrien  "mix4.l %0 = %0, %r1"
116590075Sobrien  [(set_attr "itanium_class" "mmshf")])
116690075Sobrien
116790075Sobrien(define_insn "mix4right"
116890075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
116990075Sobrien			 (const_int 32) (const_int 32))
117090075Sobrien	(match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
117190075Sobrien  ""
117290075Sobrien  "mix4.r %0 = %r1, %0"
117390075Sobrien  [(set_attr "itanium_class" "mmshf")])
117490075Sobrien
117590075Sobrien;; This is used by the rotrsi3 pattern.
117690075Sobrien
117790075Sobrien(define_insn "*mix4right_3op"
117890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
117990075Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
118090075Sobrien		(ashift:DI (zero_extend:DI
118190075Sobrien			     (match_operand:SI 2 "gr_register_operand" "r"))
118290075Sobrien			   (const_int 32))))]
118390075Sobrien  ""
118490075Sobrien  "mix4.r %0 = %2, %1"
118590075Sobrien  [(set_attr "itanium_class" "mmshf")])
118690075Sobrien
118790075Sobrien
118890075Sobrien;; ::::::::::::::::::::
118990075Sobrien;; ::
119090075Sobrien;; :: 1 bit Integer arithmetic
119190075Sobrien;; ::
119290075Sobrien;; ::::::::::::::::::::
119390075Sobrien
119490075Sobrien(define_insn_and_split "andbi3"
119590075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
119690075Sobrien	(and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
119790075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
119890075Sobrien  ""
119990075Sobrien  "@
120090075Sobrien   #
120190075Sobrien   tbit.nz.and.orcm %0, %I0 = %2, 0
120290075Sobrien   and %0 = %2, %1"
120390075Sobrien  "reload_completed
120490075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
120590075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
120690075Sobrien  [(cond_exec (eq (match_dup 2) (const_int 0))
120790075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
120890075Sobrien				(match_dup 0))))]
120990075Sobrien  ""
121090075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
121190075Sobrien
121290075Sobrien(define_insn_and_split "*andcmbi3"
121390075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
121490075Sobrien	(and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
121590075Sobrien		(match_operand:BI 2 "register_operand" "0,0,r")))]
121690075Sobrien  ""
121790075Sobrien  "@
121890075Sobrien   #
121990075Sobrien   tbit.z.and.orcm %0, %I0 = %1, 0
122090075Sobrien   andcm %0 = %2, %1"
122190075Sobrien  "reload_completed
122290075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
122390075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
122490075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
122590075Sobrien     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
122690075Sobrien				(match_dup 0))))]
122790075Sobrien  ""
122890075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
122990075Sobrien
123090075Sobrien(define_insn_and_split "iorbi3"
123190075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
123290075Sobrien	(ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
123390075Sobrien		(match_operand:BI 2 "register_operand" "c,r,r")))]
123490075Sobrien  ""
123590075Sobrien  "@
123690075Sobrien   #
123790075Sobrien   tbit.nz.or.andcm %0, %I0 = %2, 0
123890075Sobrien   or %0 = %2, %1"
123990075Sobrien  "reload_completed
124090075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
124190075Sobrien   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
124290075Sobrien  [(cond_exec (ne (match_dup 2) (const_int 0))
124390075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
124490075Sobrien				(match_dup 0))))]
124590075Sobrien  ""
124690075Sobrien  [(set_attr "itanium_class" "unknown,tbit,ilog")])
124790075Sobrien
124890075Sobrien(define_insn_and_split "*iorcmbi3"
124990075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,c")
125090075Sobrien	(ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
125190075Sobrien		(match_operand:BI 2 "register_operand" "0,0")))]
125290075Sobrien  ""
125390075Sobrien  "@
125490075Sobrien   #
125590075Sobrien   tbit.z.or.andcm %0, %I0 = %1, 0"
125690075Sobrien  "reload_completed
125790075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
125890075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
125990075Sobrien  [(cond_exec (eq (match_dup 1) (const_int 0))
126090075Sobrien     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
126190075Sobrien				(match_dup 0))))]
126290075Sobrien  ""
126390075Sobrien  [(set_attr "itanium_class" "unknown,tbit")])
126490075Sobrien
126590075Sobrien(define_insn "one_cmplbi2"
126690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
126790075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
126890075Sobrien   (clobber (match_scratch:BI 2 "=X,X,c,X"))]
126990075Sobrien  ""
127090075Sobrien  "@
127190075Sobrien   tbit.z %0, %I0 = %1, 0
127290075Sobrien   xor %0 = 1, %1
127390075Sobrien   #
127490075Sobrien   #"
127590075Sobrien  [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
127690075Sobrien
127790075Sobrien(define_split
127890075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
127990075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
128090075Sobrien   (clobber (match_scratch:BI 2 ""))]
128190075Sobrien  "reload_completed
128290075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
128390075Sobrien   && rtx_equal_p (operands[0], operands[1])"
128490075Sobrien  [(set (match_dup 4) (match_dup 3))
128590075Sobrien   (set (match_dup 0) (const_int 1))
128690075Sobrien   (cond_exec (ne (match_dup 2) (const_int 0))
128790075Sobrien     (set (match_dup 0) (const_int 0)))
1288117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
128990075Sobrien  "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
129090075Sobrien   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
129190075Sobrien
129290075Sobrien(define_split
129390075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
129490075Sobrien	(not:BI (match_operand:BI 1 "register_operand" "")))
129590075Sobrien   (clobber (match_scratch:BI 2 ""))]
129690075Sobrien  "reload_completed
129790075Sobrien   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
129890075Sobrien   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
129990075Sobrien   && ! rtx_equal_p (operands[0], operands[1])"
130090075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
130190075Sobrien     (set (match_dup 0) (const_int 0)))
130290075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
130390075Sobrien     (set (match_dup 0) (const_int 1)))
1304117395Skan   (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
130590075Sobrien  "")
130690075Sobrien
130790075Sobrien(define_insn "*cmpsi_and_0"
130890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
130990075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
131090075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
131190075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
131290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
131390075Sobrien  ""
131490075Sobrien  "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
131590075Sobrien  [(set_attr "itanium_class" "icmp")])
131690075Sobrien
131790075Sobrien(define_insn "*cmpsi_and_1"
131890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
131990075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
132090075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
132190075Sobrien		   (const_int 0)])
132290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
132390075Sobrien  ""
132490075Sobrien  "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
132590075Sobrien  [(set_attr "itanium_class" "icmp")])
132690075Sobrien
132790075Sobrien(define_insn "*cmpsi_andnot_0"
132890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
132990075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
133090075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
133190075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
133290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
133390075Sobrien  ""
133490075Sobrien  "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
133590075Sobrien  [(set_attr "itanium_class" "icmp")])
133690075Sobrien
133790075Sobrien(define_insn "*cmpsi_andnot_1"
133890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
133990075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
134090075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
134190075Sobrien			   (const_int 0)]))
134290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
134390075Sobrien  ""
134490075Sobrien  "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
134590075Sobrien  [(set_attr "itanium_class" "icmp")])
134690075Sobrien
134790075Sobrien(define_insn "*cmpdi_and_0"
134890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
134990075Sobrien	(and:BI (match_operator:BI 4 "predicate_operator"
135090075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
135190075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
135290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
135390075Sobrien  ""
135490075Sobrien  "cmp.%C4.and.orcm %0, %I0 = %3, %2"
135590075Sobrien  [(set_attr "itanium_class" "icmp")])
135690075Sobrien
135790075Sobrien(define_insn "*cmpdi_and_1"
135890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
135990075Sobrien	(and:BI (match_operator:BI 3 "signed_inequality_operator"
136090075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
136190075Sobrien		   (const_int 0)])
136290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
136390075Sobrien  ""
136490075Sobrien  "cmp.%C3.and.orcm %0, %I0 = r0, %2"
136590075Sobrien  [(set_attr "itanium_class" "icmp")])
136690075Sobrien
136790075Sobrien(define_insn "*cmpdi_andnot_0"
136890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
136990075Sobrien	(and:BI (not:BI (match_operator:BI 4 "predicate_operator"
137090075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
137190075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
137290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
137390075Sobrien  ""
137490075Sobrien  "cmp.%C4.or.andcm %I0, %0 = %3, %2"
137590075Sobrien  [(set_attr "itanium_class" "icmp")])
137690075Sobrien
137790075Sobrien(define_insn "*cmpdi_andnot_1"
137890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
137990075Sobrien	(and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
138090075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
138190075Sobrien			   (const_int 0)]))
138290075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
138390075Sobrien  ""
138490075Sobrien  "cmp.%C3.or.andcm %I0, %0 = r0, %2"
138590075Sobrien  [(set_attr "itanium_class" "icmp")])
138690075Sobrien
138790075Sobrien(define_insn "*tbit_and_0"
138890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
138990075Sobrien	(and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
139090075Sobrien			       (const_int 1))
139190075Sobrien		       (const_int 0))
139290075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
139390075Sobrien  ""
139490075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, 0"
139590075Sobrien  [(set_attr "itanium_class" "tbit")])
139690075Sobrien
139790075Sobrien(define_insn "*tbit_and_1"
139890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
139990075Sobrien	(and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
140090075Sobrien			       (const_int 1))
140190075Sobrien		       (const_int 0))
140290075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
140390075Sobrien  ""
140490075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, 0"
140590075Sobrien  [(set_attr "itanium_class" "tbit")])
140690075Sobrien
140790075Sobrien(define_insn "*tbit_and_2"
140890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
140990075Sobrien	(and:BI (ne:BI (zero_extract:DI
141090075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
141190075Sobrien			 (const_int 1)
141290075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
141390075Sobrien		       (const_int 0))
141490075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
141590075Sobrien  ""
141690075Sobrien  "tbit.nz.and.orcm %0, %I0 = %1, %2"
141790075Sobrien  [(set_attr "itanium_class" "tbit")])
141890075Sobrien
141990075Sobrien(define_insn "*tbit_and_3"
142090075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
142190075Sobrien	(and:BI (eq:BI (zero_extract:DI
142290075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
142390075Sobrien			 (const_int 1)
142490075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
142590075Sobrien		       (const_int 0))
142690075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
142790075Sobrien  ""
142890075Sobrien  "tbit.z.and.orcm %0, %I0 = %1, %2"
142990075Sobrien  [(set_attr "itanium_class" "tbit")])
143090075Sobrien
143190075Sobrien(define_insn "*cmpsi_or_0"
143290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
143390075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
143490075Sobrien		  [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
143590075Sobrien		   (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
143690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
143790075Sobrien  ""
143890075Sobrien  "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
143990075Sobrien  [(set_attr "itanium_class" "icmp")])
144090075Sobrien
144190075Sobrien(define_insn "*cmpsi_or_1"
144290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
144390075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
144490075Sobrien		  [(match_operand:SI 2 "gr_register_operand" "r")
144590075Sobrien		   (const_int 0)])
144690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
144790075Sobrien  ""
144890075Sobrien  "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
144990075Sobrien  [(set_attr "itanium_class" "icmp")])
145090075Sobrien
145190075Sobrien(define_insn "*cmpsi_orcm_0"
145290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
145390075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
145490075Sobrien			 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
145590075Sobrien			  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
145690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
145790075Sobrien  ""
145890075Sobrien  "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
145990075Sobrien  [(set_attr "itanium_class" "icmp")])
146090075Sobrien
146190075Sobrien(define_insn "*cmpsi_orcm_1"
146290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
146390075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
146490075Sobrien			  [(match_operand:SI 2 "gr_register_operand" "r")
146590075Sobrien			   (const_int 0)]))
146690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
146790075Sobrien  ""
146890075Sobrien  "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
146990075Sobrien  [(set_attr "itanium_class" "icmp")])
147090075Sobrien
147190075Sobrien(define_insn "*cmpdi_or_0"
147290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
147390075Sobrien	(ior:BI (match_operator:BI 4 "predicate_operator"
147490075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
147590075Sobrien		   (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
147690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
147790075Sobrien  ""
147890075Sobrien  "cmp.%C4.or.andcm %0, %I0 = %3, %2"
147990075Sobrien  [(set_attr "itanium_class" "icmp")])
148090075Sobrien
148190075Sobrien(define_insn "*cmpdi_or_1"
148290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
148390075Sobrien	(ior:BI (match_operator:BI 3 "signed_inequality_operator"
148490075Sobrien		  [(match_operand:DI 2 "gr_register_operand" "r")
148590075Sobrien		   (const_int 0)])
148690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
148790075Sobrien  ""
148890075Sobrien  "cmp.%C3.or.andcm %0, %I0 = r0, %2"
148990075Sobrien  [(set_attr "itanium_class" "icmp")])
149090075Sobrien
149190075Sobrien(define_insn "*cmpdi_orcm_0"
149290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
149390075Sobrien	(ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
149490075Sobrien			 [(match_operand:DI 2 "gr_register_operand" "r")
149590075Sobrien			  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
149690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
149790075Sobrien  ""
149890075Sobrien  "cmp.%C4.and.orcm %I0, %0 = %3, %2"
149990075Sobrien  [(set_attr "itanium_class" "icmp")])
150090075Sobrien
150190075Sobrien(define_insn "*cmpdi_orcm_1"
150290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
150390075Sobrien	(ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
150490075Sobrien			  [(match_operand:DI 2 "gr_register_operand" "r")
150590075Sobrien			   (const_int 0)]))
150690075Sobrien		(match_operand:BI 1 "register_operand" "0")))]
150790075Sobrien  ""
150890075Sobrien  "cmp.%C3.and.orcm %I0, %0 = r0, %2"
150990075Sobrien  [(set_attr "itanium_class" "icmp")])
151090075Sobrien
151190075Sobrien(define_insn "*tbit_or_0"
151290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
151390075Sobrien	(ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
151490075Sobrien			       (const_int 1))
151590075Sobrien		       (const_int 0))
151690075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
151790075Sobrien  ""
151890075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, 0"
151990075Sobrien  [(set_attr "itanium_class" "tbit")])
152090075Sobrien
152190075Sobrien(define_insn "*tbit_or_1"
152290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
152390075Sobrien	(ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
152490075Sobrien			       (const_int 1))
152590075Sobrien		       (const_int 0))
152690075Sobrien		(match_operand:BI 2 "register_operand" "0")))]
152790075Sobrien  ""
152890075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, 0"
152990075Sobrien  [(set_attr "itanium_class" "tbit")])
153090075Sobrien
153190075Sobrien(define_insn "*tbit_or_2"
153290075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
153390075Sobrien	(ior:BI (ne:BI (zero_extract:DI
153490075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
153590075Sobrien			 (const_int 1)
153690075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
153790075Sobrien		       (const_int 0))
153890075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
153990075Sobrien  ""
154090075Sobrien  "tbit.nz.or.andcm %0, %I0 = %1, %2"
154190075Sobrien  [(set_attr "itanium_class" "tbit")])
154290075Sobrien
154390075Sobrien(define_insn "*tbit_or_3"
154490075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
154590075Sobrien	(ior:BI (eq:BI (zero_extract:DI
154690075Sobrien			 (match_operand:DI 1 "gr_register_operand" "r")
154790075Sobrien			 (const_int 1)
154890075Sobrien			 (match_operand:DI 2 "const_int_operand" "n"))
154990075Sobrien		       (const_int 0))
155090075Sobrien		(match_operand:BI 3 "register_operand" "0")))]
155190075Sobrien  ""
155290075Sobrien  "tbit.z.or.andcm %0, %I0 = %1, %2"
155390075Sobrien  [(set_attr "itanium_class" "tbit")])
155490075Sobrien
155590075Sobrien;; Transform test of and/or of setcc into parallel comparisons.
155690075Sobrien
155790075Sobrien(define_split
155890075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
155990075Sobrien	(ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
156090075Sobrien			      (const_int 0))
156190075Sobrien		       (match_operand:DI 3 "register_operand" ""))
156290075Sobrien	       (const_int 0)))]
156390075Sobrien  ""
156490075Sobrien  [(set (match_dup 0)
156590075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
156690075Sobrien		(match_dup 2)))]
156790075Sobrien  "")
156890075Sobrien
156990075Sobrien(define_split
157090075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
157190075Sobrien	(eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
157290075Sobrien			      (const_int 0))
157390075Sobrien		       (match_operand:DI 3 "register_operand" ""))
157490075Sobrien	       (const_int 0)))]
157590075Sobrien  ""
157690075Sobrien  [(set (match_dup 0)
157790075Sobrien	(and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
157890075Sobrien		(match_dup 2)))
157990075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
158090075Sobrien	      (clobber (scratch))])]
158190075Sobrien  "")
158290075Sobrien
158390075Sobrien(define_split
158490075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
158590075Sobrien	(ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
158690075Sobrien			      (const_int 0))
158790075Sobrien		       (match_operand:DI 3 "register_operand" ""))
158890075Sobrien	       (const_int 0)))]
158990075Sobrien  ""
159090075Sobrien  [(set (match_dup 0) 
159190075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
159290075Sobrien		(match_dup 2)))]
159390075Sobrien  "")
159490075Sobrien
159590075Sobrien(define_split
159690075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
159790075Sobrien	(eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
159890075Sobrien			      (const_int 0))
159990075Sobrien		       (match_operand:DI 3 "register_operand" ""))
160090075Sobrien	       (const_int 0)))]
160190075Sobrien  ""
160290075Sobrien  [(set (match_dup 0) 
160390075Sobrien	(ior:BI (ne:BI (match_dup 3) (const_int 0))
160490075Sobrien		(match_dup 2)))
160590075Sobrien   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
160690075Sobrien	      (clobber (scratch))])]
160790075Sobrien  "")
160890075Sobrien
160990075Sobrien;; ??? Incredibly hackish.  Either need four proper patterns with all
161090075Sobrien;; the alternatives, or rely on sched1 to split the insn and hope that
161190075Sobrien;; nothing bad happens to the comparisons in the meantime.
161290075Sobrien;;
161390075Sobrien;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
161490075Sobrien;; that we're doing height reduction.
161590075Sobrien;
161690075Sobrien;(define_insn_and_split ""
161790075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
161890075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
161990075Sobrien;			  [(match_operand 2 "" "")
162090075Sobrien;			   (match_operand 3 "" "")])
162190075Sobrien;			(match_operator:BI 4 "comparison_operator"
162290075Sobrien;			  [(match_operand 5 "" "")
162390075Sobrien;			   (match_operand 6 "" "")]))
162490075Sobrien;		(match_dup 0)))]
162590075Sobrien;  "flag_schedule_insns"
162690075Sobrien;  "#"
162790075Sobrien;  ""
162890075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
162990075Sobrien;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
163090075Sobrien;  "")
163190075Sobrien;
163290075Sobrien;(define_insn_and_split ""
163390075Sobrien;  [(set (match_operand:BI 0 "register_operand" "=c")
163490075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
163590075Sobrien;			  [(match_operand 2 "" "")
163690075Sobrien;			   (match_operand 3 "" "")])
163790075Sobrien;			(match_operator:BI 4 "comparison_operator"
163890075Sobrien;			  [(match_operand 5 "" "")
163990075Sobrien;			   (match_operand 6 "" "")]))
164090075Sobrien;		(match_dup 0)))]
164190075Sobrien;  "flag_schedule_insns"
164290075Sobrien;  "#"
164390075Sobrien;  ""
164490075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
164590075Sobrien;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
164690075Sobrien;  "")
164790075Sobrien;
164890075Sobrien;(define_split
164990075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
165090075Sobrien;	(and:BI (and:BI (match_operator:BI 1 "comparison_operator"
165190075Sobrien;			  [(match_operand 2 "" "")
165290075Sobrien;			   (match_operand 3 "" "")])
165390075Sobrien;			(match_operand:BI 7 "register_operand" ""))
165490075Sobrien;		(and:BI (match_operator:BI 4 "comparison_operator"
165590075Sobrien;			  [(match_operand 5 "" "")
165690075Sobrien;			   (match_operand 6 "" "")])
165790075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
165890075Sobrien;  ""
165990075Sobrien;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
166090075Sobrien;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
166190075Sobrien;			      (match_dup 0)))]
166290075Sobrien;  "")
166390075Sobrien;
166490075Sobrien;(define_split
166590075Sobrien;  [(set (match_operand:BI 0 "register_operand" "")
166690075Sobrien;	(ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
166790075Sobrien;			  [(match_operand 2 "" "")
166890075Sobrien;			   (match_operand 3 "" "")])
166990075Sobrien;			(match_operand:BI 7 "register_operand" ""))
167090075Sobrien;		(ior:BI (match_operator:BI 4 "comparison_operator"
167190075Sobrien;			  [(match_operand 5 "" "")
167290075Sobrien;			   (match_operand 6 "" "")])
167390075Sobrien;			(match_operand:BI 8 "register_operand" ""))))]
167490075Sobrien;  ""
167590075Sobrien;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
167690075Sobrien;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
167790075Sobrien;			      (match_dup 0)))]
167890075Sobrien;  "")
167990075Sobrien
168090075Sobrien;; Try harder to avoid predicate copies by duplicating compares.
168190075Sobrien;; Note that we'll have already split the predicate copy, which
168290075Sobrien;; is kind of a pain, but oh well.
168390075Sobrien
168490075Sobrien(define_peephole2
168590075Sobrien  [(set (match_operand:BI 0 "register_operand" "")
168690075Sobrien	(match_operand:BI 1 "comparison_operator" ""))
168790075Sobrien   (set (match_operand:CCI 2 "register_operand" "")
168890075Sobrien	(match_operand:CCI 3 "register_operand" ""))
168990075Sobrien   (set (match_operand:CCI 4 "register_operand" "")
169090075Sobrien	(match_operand:CCI 5 "register_operand" ""))
169190075Sobrien   (set (match_operand:BI 6 "register_operand" "")
1692117395Skan	(unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
169390075Sobrien  "REGNO (operands[3]) == REGNO (operands[0])
169490075Sobrien   && REGNO (operands[4]) == REGNO (operands[0]) + 1
169590075Sobrien   && REGNO (operands[4]) == REGNO (operands[2]) + 1
169690075Sobrien   && REGNO (operands[6]) == REGNO (operands[2])"
169790075Sobrien  [(set (match_dup 0) (match_dup 1))
169890075Sobrien   (set (match_dup 6) (match_dup 7))]
169990075Sobrien  "operands[7] = copy_rtx (operands[1]);")
170090075Sobrien
170190075Sobrien;; ::::::::::::::::::::
170290075Sobrien;; ::
170390075Sobrien;; :: 16 bit Integer arithmetic
170490075Sobrien;; ::
170590075Sobrien;; ::::::::::::::::::::
170690075Sobrien
170790075Sobrien(define_insn "mulhi3"
170890075Sobrien  [(set (match_operand:HI 0 "gr_register_operand" "=r")
170990075Sobrien	(mult:HI (match_operand:HI 1 "gr_register_operand" "r")
171090075Sobrien		 (match_operand:HI 2 "gr_register_operand" "r")))]
171190075Sobrien  ""
171290075Sobrien  "pmpy2.r %0 = %1, %2"
171390075Sobrien  [(set_attr "itanium_class" "mmmul")])
171490075Sobrien
171590075Sobrien
171690075Sobrien;; ::::::::::::::::::::
171790075Sobrien;; ::
171890075Sobrien;; :: 32 bit Integer arithmetic
171990075Sobrien;; ::
172090075Sobrien;; ::::::::::::::::::::
172190075Sobrien
172290075Sobrien(define_insn "addsi3"
172390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
172490075Sobrien	(plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
172590075Sobrien		 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
172690075Sobrien  ""
172790075Sobrien  "@
1728117395Skan   add %0 = %1, %2
1729117395Skan   adds %0 = %2, %1
1730117395Skan   addl %0 = %2, %1"
173190075Sobrien  [(set_attr "itanium_class" "ialu")])
173290075Sobrien
173390075Sobrien(define_insn "*addsi3_plus1"
173490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
173590075Sobrien	(plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
173690075Sobrien			  (match_operand:SI 2 "gr_register_operand" "r"))
173790075Sobrien		 (const_int 1)))]
173890075Sobrien  ""
173990075Sobrien  "add %0 = %1, %2, 1"
174090075Sobrien  [(set_attr "itanium_class" "ialu")])
174190075Sobrien
174290075Sobrien(define_insn "*addsi3_plus1_alt"
174390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
174490075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
174590075Sobrien			  (const_int 2))
174690075Sobrien		 (const_int 1)))]
174790075Sobrien  ""
174890075Sobrien  "add %0 = %1, %1, 1"
174990075Sobrien  [(set_attr "itanium_class" "ialu")])
175090075Sobrien
175190075Sobrien(define_insn "*addsi3_shladd"
175290075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
175390075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
175490075Sobrien			  (match_operand:SI 2 "shladd_operand" "n"))
175590075Sobrien		 (match_operand:SI 3 "gr_register_operand" "r")))]
175690075Sobrien  ""
175790075Sobrien  "shladd %0 = %1, %S2, %3"
175890075Sobrien  [(set_attr "itanium_class" "ialu")])
175990075Sobrien
176090075Sobrien(define_insn "subsi3"
176190075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
176290075Sobrien	(minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
176390075Sobrien		  (match_operand:SI 2 "gr_register_operand" "r")))]
176490075Sobrien  ""
176590075Sobrien  "sub %0 = %1, %2"
176690075Sobrien  [(set_attr "itanium_class" "ialu")])
176790075Sobrien
176890075Sobrien(define_insn "*subsi3_minus1"
176990075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
177090075Sobrien	(plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
177190075Sobrien		 (match_operand:SI 2 "gr_register_operand" "r")))]
177290075Sobrien  ""
177390075Sobrien  "sub %0 = %2, %1, 1"
177490075Sobrien  [(set_attr "itanium_class" "ialu")])
177590075Sobrien
177690075Sobrien;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
177790075Sobrien
177890075Sobrien(define_insn "mulsi3"
177990075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
178090075Sobrien	(mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
178190075Sobrien		 (match_operand:SI 2 "grfr_register_operand" "f")))]
178290075Sobrien  ""
178390075Sobrien  "xmpy.l %0 = %1, %2"
178490075Sobrien  [(set_attr "itanium_class" "xmpy")])
178590075Sobrien
178690075Sobrien(define_insn "maddsi4"
178790075Sobrien  [(set (match_operand:SI 0 "fr_register_operand" "=f")
178890075Sobrien	(plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
178990075Sobrien			  (match_operand:SI 2 "grfr_register_operand" "f"))
179090075Sobrien		 (match_operand:SI 3 "grfr_register_operand" "f")))]
179190075Sobrien  ""
179290075Sobrien  "xma.l %0 = %1, %2, %3"
179390075Sobrien  [(set_attr "itanium_class" "xmpy")])
179490075Sobrien
179590075Sobrien(define_insn "negsi2"
179690075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
179790075Sobrien	(neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
179890075Sobrien  ""
179990075Sobrien  "sub %0 = r0, %1"
180090075Sobrien  [(set_attr "itanium_class" "ialu")])
180190075Sobrien
180290075Sobrien(define_expand "abssi2"
180390075Sobrien  [(set (match_dup 2)
180490075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
180590075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
180690075Sobrien	(if_then_else:SI (eq (match_dup 2) (const_int 0))
180790075Sobrien			 (neg:SI (match_dup 1))
180890075Sobrien			 (match_dup 1)))]
180990075Sobrien  ""
1810117395Skan  { operands[2] = gen_reg_rtx (BImode); })
181190075Sobrien
181290075Sobrien(define_expand "sminsi3"
181390075Sobrien  [(set (match_dup 3)
181490075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
181590075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
181690075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
181790075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
181890075Sobrien			 (match_dup 2) (match_dup 1)))]
181990075Sobrien  ""
1820117395Skan  { operands[3] = gen_reg_rtx (BImode); })
182190075Sobrien
182290075Sobrien(define_expand "smaxsi3"
182390075Sobrien  [(set (match_dup 3)
182490075Sobrien	(ge:BI (match_operand:SI 1 "gr_register_operand" "")
182590075Sobrien	       (match_operand:SI 2 "gr_register_operand" "")))
182690075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
182790075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
182890075Sobrien			 (match_dup 1) (match_dup 2)))]
182990075Sobrien  ""
1830117395Skan  { operands[3] = gen_reg_rtx (BImode); })
183190075Sobrien
183290075Sobrien(define_expand "uminsi3"
183390075Sobrien  [(set (match_dup 3)
183490075Sobrien	(geu: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 2) (match_dup 1)))]
183990075Sobrien  ""
1840117395Skan  { operands[3] = gen_reg_rtx (BImode); })
184190075Sobrien
184290075Sobrien(define_expand "umaxsi3"
184390075Sobrien  [(set (match_dup 3)
184490075Sobrien	(geu:BI (match_operand:SI 1 "gr_register_operand" "")
184590075Sobrien		(match_operand:SI 2 "gr_register_operand" "")))
184690075Sobrien   (set (match_operand:SI 0 "gr_register_operand" "")
184790075Sobrien	(if_then_else:SI (ne (match_dup 3) (const_int 0))
184890075Sobrien			 (match_dup 1) (match_dup 2)))]
184990075Sobrien  ""
1850117395Skan  { operands[3] = gen_reg_rtx (BImode); })
185190075Sobrien
185290075Sobrien(define_expand "divsi3"
185390075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
185490075Sobrien	(div:SI (match_operand:SI 1 "general_operand" "")
185590075Sobrien		(match_operand:SI 2 "general_operand" "")))]
1856132718Skan  "TARGET_INLINE_INT_DIV"
185790075Sobrien{
1858132718Skan  rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1859117395Skan  REAL_VALUE_TYPE twon34_r;
186090075Sobrien
1861132718Skan  op0_xf = gen_reg_rtx (XFmode);
186290075Sobrien  op0_di = gen_reg_rtx (DImode);
186390075Sobrien
186490075Sobrien  if (CONSTANT_P (operands[1]))
186590075Sobrien    operands[1] = force_reg (SImode, operands[1]);
1866132718Skan  op1_xf = gen_reg_rtx (XFmode);
1867132718Skan  expand_float (op1_xf, operands[1], 0);
186890075Sobrien
186990075Sobrien  if (CONSTANT_P (operands[2]))
187090075Sobrien    operands[2] = force_reg (SImode, operands[2]);
1871132718Skan  op2_xf = gen_reg_rtx (XFmode);
1872132718Skan  expand_float (op2_xf, operands[2], 0);
187390075Sobrien
187490075Sobrien  /* 2^-34 */
1875117395Skan  real_2expN (&twon34_r, -34);
1876132718Skan  twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
1877132718Skan  twon34 = force_reg (XFmode, twon34);
187890075Sobrien
1879132718Skan  emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
188090075Sobrien
1881132718Skan  emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
188290075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
188390075Sobrien  DONE;
1884117395Skan})
188590075Sobrien
188690075Sobrien(define_expand "modsi3"
188790075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
188890075Sobrien	(mod:SI (match_operand:SI 1 "general_operand" "")
188990075Sobrien		(match_operand:SI 2 "general_operand" "")))]
1890132718Skan  "TARGET_INLINE_INT_DIV"
189190075Sobrien{
189290075Sobrien  rtx op2_neg, op1_di, div;
189390075Sobrien
189490075Sobrien  div = gen_reg_rtx (SImode);
189590075Sobrien  emit_insn (gen_divsi3 (div, operands[1], operands[2]));
189690075Sobrien
189790075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
189890075Sobrien
189990075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
190090075Sobrien     have already copied to the FP regs.  */
190190075Sobrien  op1_di = gen_reg_rtx (DImode);
190290075Sobrien  convert_move (op1_di, operands[1], 0);
190390075Sobrien
190490075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
190590075Sobrien			  gen_lowpart (SImode, op1_di)));
190690075Sobrien  DONE;
1907117395Skan})
190890075Sobrien
190990075Sobrien(define_expand "udivsi3"
191090075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
191190075Sobrien	(udiv:SI (match_operand:SI 1 "general_operand" "")
191290075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
1913132718Skan  "TARGET_INLINE_INT_DIV"
191490075Sobrien{
1915132718Skan  rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1916117395Skan  REAL_VALUE_TYPE twon34_r;
191790075Sobrien
1918132718Skan  op0_xf = gen_reg_rtx (XFmode);
191990075Sobrien  op0_di = gen_reg_rtx (DImode);
192090075Sobrien
192190075Sobrien  if (CONSTANT_P (operands[1]))
192290075Sobrien    operands[1] = force_reg (SImode, operands[1]);
1923132718Skan  op1_xf = gen_reg_rtx (XFmode);
1924132718Skan  expand_float (op1_xf, operands[1], 1);
192590075Sobrien
192690075Sobrien  if (CONSTANT_P (operands[2]))
192790075Sobrien    operands[2] = force_reg (SImode, operands[2]);
1928132718Skan  op2_xf = gen_reg_rtx (XFmode);
1929132718Skan  expand_float (op2_xf, operands[2], 1);
193090075Sobrien
193190075Sobrien  /* 2^-34 */
1932117395Skan  real_2expN (&twon34_r, -34);
1933132718Skan  twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
1934132718Skan  twon34 = force_reg (XFmode, twon34);
193590075Sobrien
1936132718Skan  emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
193790075Sobrien
1938132718Skan  emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
193990075Sobrien  emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
194090075Sobrien  DONE;
1941117395Skan})
194290075Sobrien
194390075Sobrien(define_expand "umodsi3"
194490075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
194590075Sobrien	(umod:SI (match_operand:SI 1 "general_operand" "")
194690075Sobrien		 (match_operand:SI 2 "general_operand" "")))]
1947132718Skan  "TARGET_INLINE_INT_DIV"
194890075Sobrien{
194990075Sobrien  rtx op2_neg, op1_di, div;
195090075Sobrien
195190075Sobrien  div = gen_reg_rtx (SImode);
195290075Sobrien  emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
195390075Sobrien
195490075Sobrien  op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
195590075Sobrien
195690075Sobrien  /* This is a trick to get us to reuse the value that we're sure to
195790075Sobrien     have already copied to the FP regs.  */
195890075Sobrien  op1_di = gen_reg_rtx (DImode);
195990075Sobrien  convert_move (op1_di, operands[1], 1);
196090075Sobrien
196190075Sobrien  emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
196290075Sobrien			  gen_lowpart (SImode, op1_di)));
196390075Sobrien  DONE;
1964117395Skan})
196590075Sobrien
196690075Sobrien(define_insn_and_split "divsi3_internal"
1967132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
1968132718Skan	(float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
1969132718Skan			  (match_operand:XF 2 "fr_register_operand" "f"))))
1970132718Skan   (clobber (match_scratch:XF 4 "=&f"))
1971132718Skan   (clobber (match_scratch:XF 5 "=&f"))
197290075Sobrien   (clobber (match_scratch:BI 6 "=c"))
1973132718Skan   (use (match_operand:XF 3 "fr_register_operand" "f"))]
1974132718Skan  "TARGET_INLINE_INT_DIV"
197590075Sobrien  "#"
197690075Sobrien  "&& reload_completed"
1977132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
1978117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
1979117395Skan					    UNSPEC_FR_RECIP_APPROX))
198090075Sobrien	      (use (const_int 1))])
198190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
1982132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
198390075Sobrien		(use (const_int 1))]))
198490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
198590075Sobrien     (parallel [(set (match_dup 5)
1986132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
198790075Sobrien			      (match_dup 7)))
198890075Sobrien		(use (const_int 1))]))
198990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
199090075Sobrien     (parallel [(set (match_dup 4)
1991132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 4))
199290075Sobrien			      (match_dup 4)))
199390075Sobrien		(use (const_int 1))]))
199490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
199590075Sobrien     (parallel [(set (match_dup 5)
1996132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 5))
199790075Sobrien			      (match_dup 3)))
199890075Sobrien		(use (const_int 1))]))
199990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
200090075Sobrien     (parallel [(set (match_dup 0)
2001132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 4))
200290075Sobrien			      (match_dup 4)))
200390075Sobrien		(use (const_int 1))]))
200490075Sobrien  ] 
2005132718Skan  "operands[7] = CONST1_RTX (XFmode);"
200690075Sobrien  [(set_attr "predicable" "no")])
200790075Sobrien
200890075Sobrien;; ::::::::::::::::::::
200990075Sobrien;; ::
201090075Sobrien;; :: 64 bit Integer arithmetic
201190075Sobrien;; ::
201290075Sobrien;; ::::::::::::::::::::
201390075Sobrien
201490075Sobrien(define_insn "adddi3"
201590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
201690075Sobrien	(plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
201790075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
201890075Sobrien  ""
201990075Sobrien  "@
2020117395Skan   add %0 = %1, %2
2021117395Skan   adds %0 = %2, %1
2022117395Skan   addl %0 = %2, %1"
202390075Sobrien  [(set_attr "itanium_class" "ialu")])
202490075Sobrien
202590075Sobrien(define_insn "*adddi3_plus1"
202690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
202790075Sobrien	(plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
202890075Sobrien			  (match_operand:DI 2 "gr_register_operand" "r"))
202990075Sobrien		 (const_int 1)))]
203090075Sobrien  ""
203190075Sobrien  "add %0 = %1, %2, 1"
203290075Sobrien  [(set_attr "itanium_class" "ialu")])
203390075Sobrien
203490075Sobrien;; This has some of the same problems as shladd.  We let the shladd
203590075Sobrien;; eliminator hack handle it, which results in the 1 being forced into
203690075Sobrien;; a register, but not more ugliness here.
203790075Sobrien(define_insn "*adddi3_plus1_alt"
203890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
203990075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
204090075Sobrien			  (const_int 2))
204190075Sobrien		 (const_int 1)))]
204290075Sobrien  ""
204390075Sobrien  "add %0 = %1, %1, 1"
204490075Sobrien  [(set_attr "itanium_class" "ialu")])
204590075Sobrien
204690075Sobrien(define_insn "subdi3"
204790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
204890075Sobrien	(minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
204990075Sobrien		  (match_operand:DI 2 "gr_register_operand" "r")))]
205090075Sobrien  ""
205190075Sobrien  "sub %0 = %1, %2"
205290075Sobrien  [(set_attr "itanium_class" "ialu")])
205390075Sobrien
205490075Sobrien(define_insn "*subdi3_minus1"
205590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
205690075Sobrien	(plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
205790075Sobrien		 (match_operand:DI 2 "gr_register_operand" "r")))]
205890075Sobrien  ""
205990075Sobrien  "sub %0 = %2, %1, 1"
206090075Sobrien  [(set_attr "itanium_class" "ialu")])
206190075Sobrien
206290075Sobrien;; ??? Use grfr instead of fr because of virtual register elimination
206390075Sobrien;; and silly test cases multiplying by the frame pointer.
206490075Sobrien(define_insn "muldi3"
206590075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
206690075Sobrien	(mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
206790075Sobrien		 (match_operand:DI 2 "grfr_register_operand" "f")))]
206890075Sobrien  ""
206990075Sobrien  "xmpy.l %0 = %1, %2"
207090075Sobrien  [(set_attr "itanium_class" "xmpy")])
207190075Sobrien
207290075Sobrien;; ??? If operand 3 is an eliminable reg, then register elimination causes the
207390075Sobrien;; same problem that we have with shladd below.  Unfortunately, this case is
207490075Sobrien;; much harder to fix because the multiply puts the result in an FP register,
207590075Sobrien;; but the add needs inputs from a general register.  We add a spurious clobber
207690075Sobrien;; here so that it will be present just in case register elimination gives us
207790075Sobrien;; the funny result.
207890075Sobrien
207990075Sobrien;; ??? Maybe validate_changes should try adding match_scratch clobbers?
208090075Sobrien
208190075Sobrien;; ??? Maybe we should change how adds are canonicalized.
208290075Sobrien
208390075Sobrien(define_insn "madddi4"
208490075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
208590075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
208690075Sobrien			  (match_operand:DI 2 "grfr_register_operand" "f"))
208790075Sobrien		 (match_operand:DI 3 "grfr_register_operand" "f")))
208890075Sobrien   (clobber (match_scratch:DI 4 "=X"))]
208990075Sobrien  ""
209090075Sobrien  "xma.l %0 = %1, %2, %3"
209190075Sobrien  [(set_attr "itanium_class" "xmpy")])
209290075Sobrien
209390075Sobrien;; This can be created by register elimination if operand3 of shladd is an
209490075Sobrien;; eliminable register or has reg_equiv_constant set.
209590075Sobrien
209690075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
209790075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
209890075Sobrien;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
209990075Sobrien;; incorrectly.
210090075Sobrien
210190075Sobrien(define_insn "*madddi4_elim"
210290075Sobrien  [(set (match_operand:DI 0 "register_operand" "=&r")
210390075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
210490075Sobrien				   (match_operand:DI 2 "register_operand" "f"))
210590075Sobrien			  (match_operand:DI 3 "register_operand" "f"))
210690075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))
210790075Sobrien   (clobber (match_scratch:DI 5 "=f"))]
210890075Sobrien  "reload_in_progress"
210990075Sobrien  "#"
211090075Sobrien  [(set_attr "itanium_class" "unknown")])
211190075Sobrien
211290075Sobrien(define_split
211390075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
211490075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
211590075Sobrien				   (match_operand:DI 2 "register_operand" ""))
211690075Sobrien			  (match_operand:DI 3 "register_operand" ""))
211790075Sobrien		 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
211890075Sobrien   (clobber (match_scratch:DI 5 ""))]
211990075Sobrien  "reload_completed"
212090075Sobrien  [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
212190075Sobrien					  (match_dup 3)))
212290075Sobrien	      (clobber (match_dup 0))])
212390075Sobrien   (set (match_dup 0) (match_dup 5))
212490075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
212590075Sobrien  "")
212690075Sobrien
212790075Sobrien;; ??? There are highpart multiply and add instructions, but we have no way
212890075Sobrien;; to generate them.
212990075Sobrien
213090075Sobrien(define_insn "smuldi3_highpart"
213190075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
213290075Sobrien	(truncate:DI
213390075Sobrien	 (lshiftrt:TI
213490075Sobrien	  (mult:TI (sign_extend:TI
213590075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
213690075Sobrien		   (sign_extend:TI
213790075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
213890075Sobrien	  (const_int 64))))]
213990075Sobrien  ""
214090075Sobrien  "xmpy.h %0 = %1, %2"
214190075Sobrien  [(set_attr "itanium_class" "xmpy")])
214290075Sobrien
214390075Sobrien(define_insn "umuldi3_highpart"
214490075Sobrien  [(set (match_operand:DI 0 "fr_register_operand" "=f")
214590075Sobrien	(truncate:DI
214690075Sobrien	 (lshiftrt:TI
214790075Sobrien	  (mult:TI (zero_extend:TI
214890075Sobrien		     (match_operand:DI 1 "fr_register_operand" "f"))
214990075Sobrien		   (zero_extend:TI
215090075Sobrien		     (match_operand:DI 2 "fr_register_operand" "f")))
215190075Sobrien	  (const_int 64))))]
215290075Sobrien  ""
215390075Sobrien  "xmpy.hu %0 = %1, %2"
215490075Sobrien  [(set_attr "itanium_class" "xmpy")])
215590075Sobrien
215690075Sobrien(define_insn "negdi2"
215790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
215890075Sobrien	(neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
215990075Sobrien  ""
216090075Sobrien  "sub %0 = r0, %1"
216190075Sobrien  [(set_attr "itanium_class" "ialu")])
216290075Sobrien
216390075Sobrien(define_expand "absdi2"
216490075Sobrien  [(set (match_dup 2)
216590075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
216690075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
216790075Sobrien	(if_then_else:DI (eq (match_dup 2) (const_int 0))
216890075Sobrien			 (neg:DI (match_dup 1))
216990075Sobrien			 (match_dup 1)))]
217090075Sobrien  ""
2171117395Skan  { operands[2] = gen_reg_rtx (BImode); })
217290075Sobrien
217390075Sobrien(define_expand "smindi3"
217490075Sobrien  [(set (match_dup 3)
217590075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
217690075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
217790075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
217890075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
217990075Sobrien			 (match_dup 2) (match_dup 1)))]
218090075Sobrien  ""
2181117395Skan  { operands[3] = gen_reg_rtx (BImode); })
218290075Sobrien
218390075Sobrien(define_expand "smaxdi3"
218490075Sobrien  [(set (match_dup 3)
218590075Sobrien	(ge:BI (match_operand:DI 1 "gr_register_operand" "")
218690075Sobrien	       (match_operand:DI 2 "gr_register_operand" "")))
218790075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
218890075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
218990075Sobrien			 (match_dup 1) (match_dup 2)))]
219090075Sobrien  ""
2191117395Skan  { operands[3] = gen_reg_rtx (BImode); })
219290075Sobrien
219390075Sobrien(define_expand "umindi3"
219490075Sobrien  [(set (match_dup 3)
219590075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
219690075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
219790075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
219890075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
219990075Sobrien			 (match_dup 2) (match_dup 1)))]
220090075Sobrien  ""
2201117395Skan  { operands[3] = gen_reg_rtx (BImode); })
220290075Sobrien
220390075Sobrien(define_expand "umaxdi3"
220490075Sobrien  [(set (match_dup 3)
220590075Sobrien	(geu:BI (match_operand:DI 1 "gr_register_operand" "")
220690075Sobrien		(match_operand:DI 2 "gr_register_operand" "")))
220790075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
220890075Sobrien	(if_then_else:DI (ne (match_dup 3) (const_int 0))
220990075Sobrien			 (match_dup 1) (match_dup 2)))]
221090075Sobrien  ""
2211117395Skan  { operands[3] = gen_reg_rtx (BImode); })
221290075Sobrien
221390075Sobrien(define_expand "ffsdi2"
221490075Sobrien  [(set (match_dup 6)
221590075Sobrien	(eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
221690075Sobrien   (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
221790075Sobrien   (set (match_dup 5) (const_int 0))
221890075Sobrien   (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2219132718Skan   (set (match_dup 4) (popcount:DI (match_dup 3)))
222090075Sobrien   (set (match_operand:DI 0 "gr_register_operand" "")
222190075Sobrien	(if_then_else:DI (ne (match_dup 6) (const_int 0))
222290075Sobrien			 (match_dup 5) (match_dup 4)))]
222390075Sobrien  ""
222490075Sobrien{
222590075Sobrien  operands[2] = gen_reg_rtx (DImode);
222690075Sobrien  operands[3] = gen_reg_rtx (DImode);
222790075Sobrien  operands[4] = gen_reg_rtx (DImode);
222890075Sobrien  operands[5] = gen_reg_rtx (DImode);
222990075Sobrien  operands[6] = gen_reg_rtx (BImode);
2230117395Skan})
223190075Sobrien
2232132718Skan(define_expand "ctzdi2"
2233132718Skan  [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
2234132718Skan			       (const_int -1)))
2235132718Skan   (set (match_dup 3) (not:DI (match_dup 1)))
2236132718Skan   (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
2237132718Skan   (set (match_operand:DI 0 "gr_register_operand" "")
2238132718Skan	(popcount:DI (match_dup 4)))]
2239132718Skan  ""
2240132718Skan{
2241132718Skan  operands[2] = gen_reg_rtx (DImode);
2242132718Skan  operands[3] = gen_reg_rtx (DImode);
2243132718Skan  operands[4] = gen_reg_rtx (DImode);
2244132718Skan})
2245132718Skan
2246132718Skan;; Note the computation here is op0 = 63 - (exp - 0xffff).
2247132718Skan(define_expand "clzdi2"
2248132718Skan  [(set (match_dup 2)
2249132718Skan	(unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "")))
2250132718Skan   (set (match_dup 3)
2251132718Skan	(unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
2252132718Skan   (set (match_dup 4) (const_int 65598))
2253132718Skan   (set (match_operand:DI 0 "gr_register_operand" "")
2254132718Skan	(minus:DI (match_dup 4) (match_dup 3)))]
2255132718Skan  ""
2256132718Skan{
2257132718Skan  operands[2] = gen_reg_rtx (XFmode);
2258132718Skan  operands[3] = gen_reg_rtx (DImode);
2259132718Skan  operands[4] = gen_reg_rtx (DImode);
2260132718Skan})
2261132718Skan
2262132718Skan(define_insn "popcountdi2"
226390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2264132718Skan	(popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
226590075Sobrien  ""
226690075Sobrien  "popcnt %0 = %1"
226790075Sobrien  [(set_attr "itanium_class" "mmmul")])
226890075Sobrien
2269132718Skan(define_insn "*getf_exp_xf"
2270132718Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
2271132718Skan	(unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
2272132718Skan		   UNSPEC_GETF_EXP))]
2273132718Skan  ""
2274132718Skan  "getf.exp %0 = %1"
2275132718Skan  [(set_attr "itanium_class" "frfr")])
2276132718Skan
227790075Sobrien(define_expand "divdi3"
227890075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
227990075Sobrien	(div:DI (match_operand:DI 1 "general_operand" "")
228090075Sobrien		(match_operand:DI 2 "general_operand" "")))]
2281132718Skan  "TARGET_INLINE_INT_DIV"
228290075Sobrien{
2283132718Skan  rtx op1_xf, op2_xf, op0_xf;
228490075Sobrien
2285132718Skan  op0_xf = gen_reg_rtx (XFmode);
228690075Sobrien
228790075Sobrien  if (CONSTANT_P (operands[1]))
228890075Sobrien    operands[1] = force_reg (DImode, operands[1]);
2289132718Skan  op1_xf = gen_reg_rtx (XFmode);
2290132718Skan  expand_float (op1_xf, operands[1], 0);
229190075Sobrien
229290075Sobrien  if (CONSTANT_P (operands[2]))
229390075Sobrien    operands[2] = force_reg (DImode, operands[2]);
2294132718Skan  op2_xf = gen_reg_rtx (XFmode);
2295132718Skan  expand_float (op2_xf, operands[2], 0);
229690075Sobrien
2297117395Skan  if (TARGET_INLINE_INT_DIV_LAT)
2298132718Skan    emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
229990075Sobrien  else
2300132718Skan    emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
230190075Sobrien
2302132718Skan  emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
230390075Sobrien  DONE;
2304117395Skan})
230590075Sobrien
230690075Sobrien(define_expand "moddi3"
230790075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
230890075Sobrien	(mod:SI (match_operand:DI 1 "general_operand" "")
230990075Sobrien		(match_operand:DI 2 "general_operand" "")))]
2310132718Skan  "TARGET_INLINE_INT_DIV"
231190075Sobrien{
231290075Sobrien  rtx op2_neg, div;
231390075Sobrien
231490075Sobrien  div = gen_reg_rtx (DImode);
231590075Sobrien  emit_insn (gen_divdi3 (div, operands[1], operands[2]));
231690075Sobrien
231790075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
231890075Sobrien
231990075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
232090075Sobrien  DONE;
2321117395Skan})
232290075Sobrien
232390075Sobrien(define_expand "udivdi3"
232490075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
232590075Sobrien	(udiv:DI (match_operand:DI 1 "general_operand" "")
232690075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
2327132718Skan  "TARGET_INLINE_INT_DIV"
232890075Sobrien{
2329132718Skan  rtx op1_xf, op2_xf, op0_xf;
233090075Sobrien
2331132718Skan  op0_xf = gen_reg_rtx (XFmode);
233290075Sobrien
233390075Sobrien  if (CONSTANT_P (operands[1]))
233490075Sobrien    operands[1] = force_reg (DImode, operands[1]);
2335132718Skan  op1_xf = gen_reg_rtx (XFmode);
2336132718Skan  expand_float (op1_xf, operands[1], 1);
233790075Sobrien
233890075Sobrien  if (CONSTANT_P (operands[2]))
233990075Sobrien    operands[2] = force_reg (DImode, operands[2]);
2340132718Skan  op2_xf = gen_reg_rtx (XFmode);
2341132718Skan  expand_float (op2_xf, operands[2], 1);
234290075Sobrien
2343117395Skan  if (TARGET_INLINE_INT_DIV_LAT)
2344132718Skan    emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
234590075Sobrien  else
2346132718Skan    emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
234790075Sobrien
2348132718Skan  emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
234990075Sobrien  DONE;
2350117395Skan})
235190075Sobrien
235290075Sobrien(define_expand "umoddi3"
235390075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
235490075Sobrien	(umod:DI (match_operand:DI 1 "general_operand" "")
235590075Sobrien		 (match_operand:DI 2 "general_operand" "")))]
2356132718Skan  "TARGET_INLINE_INT_DIV"
235790075Sobrien{
235890075Sobrien  rtx op2_neg, div;
235990075Sobrien
236090075Sobrien  div = gen_reg_rtx (DImode);
236190075Sobrien  emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
236290075Sobrien
236390075Sobrien  op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
236490075Sobrien
236590075Sobrien  emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
236690075Sobrien  DONE;
2367117395Skan})
236890075Sobrien
236990075Sobrien(define_insn_and_split "divdi3_internal_lat"
2370132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2371132718Skan	(float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2372132718Skan			  (match_operand:XF 2 "fr_register_operand" "f"))))
2373132718Skan   (clobber (match_scratch:XF 3 "=&f"))
2374132718Skan   (clobber (match_scratch:XF 4 "=&f"))
2375132718Skan   (clobber (match_scratch:XF 5 "=&f"))
237690075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
2377132718Skan  "TARGET_INLINE_INT_DIV_LAT"
237890075Sobrien  "#"
237990075Sobrien  "&& reload_completed"
2380132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2381117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2382117395Skan					    UNSPEC_FR_RECIP_APPROX))
238390075Sobrien	      (use (const_int 1))])
238490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
238590075Sobrien     (parallel [(set (match_dup 3)
2386132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
238790075Sobrien			      (match_dup 7)))
238890075Sobrien		(use (const_int 1))]))
238990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
2390132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
239190075Sobrien		(use (const_int 1))]))
239290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
2393132718Skan     (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
239490075Sobrien		(use (const_int 1))]))
239590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
239690075Sobrien     (parallel [(set (match_dup 4)
2397132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 4))
239890075Sobrien			      (match_dup 4)))
239990075Sobrien		(use (const_int 1))]))
240090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
240190075Sobrien     (parallel [(set (match_dup 0)
2402132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
240390075Sobrien			      (match_dup 0)))
240490075Sobrien		(use (const_int 1))]))
240590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
240690075Sobrien     (parallel [(set (match_dup 3)
2407132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 4))
240890075Sobrien			      (match_dup 4)))
240990075Sobrien		(use (const_int 1))]))
241090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
241190075Sobrien     (parallel [(set (match_dup 0)
2412132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 0))
241390075Sobrien			      (match_dup 0)))
241490075Sobrien		(use (const_int 1))]))
241590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
241690075Sobrien     (parallel [(set (match_dup 4)
2417132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
241890075Sobrien			      (match_dup 1)))
241990075Sobrien		(use (const_int 1))]))
242090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
242190075Sobrien     (parallel [(set (match_dup 0)
2422132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
242390075Sobrien			      (match_dup 3)))
242490075Sobrien		(use (const_int 1))]))
242590075Sobrien  ] 
2426132718Skan  "operands[7] = CONST1_RTX (XFmode);"
242790075Sobrien  [(set_attr "predicable" "no")])
242890075Sobrien
242990075Sobrien(define_insn_and_split "divdi3_internal_thr"
2430132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2431132718Skan	(float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2432132718Skan			  (match_operand:XF 2 "fr_register_operand" "f"))))
2433132718Skan   (clobber (match_scratch:XF 3 "=&f"))
2434132718Skan   (clobber (match_scratch:XF 4 "=f"))
243590075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
2436132718Skan  "TARGET_INLINE_INT_DIV_THR"
243790075Sobrien  "#"
243890075Sobrien  "&& reload_completed"
2439132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2440117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 
2441117395Skan					    UNSPEC_FR_RECIP_APPROX))
244290075Sobrien	      (use (const_int 1))])
244390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
244490075Sobrien     (parallel [(set (match_dup 3)
2445132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
244690075Sobrien			      (match_dup 6)))
244790075Sobrien		(use (const_int 1))]))
244890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
244990075Sobrien     (parallel [(set (match_dup 0)
2450132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
245190075Sobrien			      (match_dup 0)))
245290075Sobrien		(use (const_int 1))]))
245390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
2454132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
245590075Sobrien		(use (const_int 1))]))
245690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
245790075Sobrien     (parallel [(set (match_dup 0)
2458132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
245990075Sobrien			      (match_dup 0)))
246090075Sobrien		(use (const_int 1))]))
246190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
2462132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
246390075Sobrien		(use (const_int 1))]))
246490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
246590075Sobrien     (parallel [(set (match_dup 4)
2466132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
246790075Sobrien			      (match_dup 1)))
246890075Sobrien		(use (const_int 1))]))
246990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
247090075Sobrien     (parallel [(set (match_dup 0)
2471132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
247290075Sobrien			      (match_dup 3)))
247390075Sobrien		(use (const_int 1))]))
247490075Sobrien  ] 
2475132718Skan  "operands[6] = CONST1_RTX (XFmode);"
247690075Sobrien  [(set_attr "predicable" "no")])
247790075Sobrien
247890075Sobrien;; ::::::::::::::::::::
247990075Sobrien;; ::
248090075Sobrien;; :: 32 bit floating point arithmetic
248190075Sobrien;; ::
248290075Sobrien;; ::::::::::::::::::::
248390075Sobrien
248490075Sobrien(define_insn "addsf3"
248590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
248690075Sobrien	(plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
248790075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
248890075Sobrien  ""
248990075Sobrien  "fadd.s %0 = %1, %F2"
249090075Sobrien  [(set_attr "itanium_class" "fmac")])
249190075Sobrien
249290075Sobrien(define_insn "subsf3"
249390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
249490075Sobrien	(minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
249590075Sobrien		  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
249690075Sobrien  ""
249790075Sobrien  "fsub.s %0 = %F1, %F2"
249890075Sobrien  [(set_attr "itanium_class" "fmac")])
249990075Sobrien
250090075Sobrien(define_insn "mulsf3"
250190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
250290075Sobrien	(mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
250390075Sobrien		 (match_operand:SF 2 "fr_register_operand" "f")))]
250490075Sobrien  ""
250590075Sobrien  "fmpy.s %0 = %1, %2"
250690075Sobrien  [(set_attr "itanium_class" "fmac")])
250790075Sobrien
250890075Sobrien(define_insn "abssf2"
250990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
251090075Sobrien	(abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
251190075Sobrien  ""
251290075Sobrien  "fabs %0 = %1"
251390075Sobrien  [(set_attr "itanium_class" "fmisc")])
251490075Sobrien
251590075Sobrien(define_insn "negsf2"
251690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
251790075Sobrien	(neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
251890075Sobrien  ""
251990075Sobrien  "fneg %0 = %1"
252090075Sobrien  [(set_attr "itanium_class" "fmisc")])
252190075Sobrien
252290075Sobrien(define_insn "*nabssf2"
252390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
252490075Sobrien	(neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
252590075Sobrien  ""
252690075Sobrien  "fnegabs %0 = %1"
252790075Sobrien  [(set_attr "itanium_class" "fmisc")])
252890075Sobrien
252990075Sobrien(define_insn "minsf3"
253090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
253190075Sobrien	(smin:SF (match_operand:SF 1 "fr_register_operand" "f")
253290075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
253390075Sobrien  ""
253490075Sobrien  "fmin %0 = %1, %F2"
253590075Sobrien  [(set_attr "itanium_class" "fmisc")])
253690075Sobrien
253790075Sobrien(define_insn "maxsf3"
253890075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
253990075Sobrien	(smax:SF (match_operand:SF 1 "fr_register_operand" "f")
254090075Sobrien		 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
254190075Sobrien  ""
254290075Sobrien  "fmax %0 = %1, %F2"
254390075Sobrien  [(set_attr "itanium_class" "fmisc")])
254490075Sobrien
254590075Sobrien(define_insn "*maddsf4"
254690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
254790075Sobrien	(plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
254890075Sobrien			  (match_operand:SF 2 "fr_register_operand" "f"))
254990075Sobrien		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
255090075Sobrien  ""
255190075Sobrien  "fma.s %0 = %1, %2, %F3"
255290075Sobrien  [(set_attr "itanium_class" "fmac")])
255390075Sobrien
255490075Sobrien(define_insn "*msubsf4"
255590075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
255690075Sobrien	(minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
255790075Sobrien			   (match_operand:SF 2 "fr_register_operand" "f"))
255890075Sobrien		  (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
255990075Sobrien  ""
256090075Sobrien  "fms.s %0 = %1, %2, %F3"
256190075Sobrien  [(set_attr "itanium_class" "fmac")])
256290075Sobrien
256390075Sobrien(define_insn "*nmulsf3"
256490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
256590075Sobrien	(neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
256690075Sobrien			 (match_operand:SF 2 "fr_register_operand" "f"))))]
256790075Sobrien  ""
256890075Sobrien  "fnmpy.s %0 = %1, %2"
256990075Sobrien  [(set_attr "itanium_class" "fmac")])
257090075Sobrien
257190075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
257290075Sobrien
257390075Sobrien(define_insn "*nmaddsf4"
257490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
257590075Sobrien	(plus:SF (neg:SF (mult:SF
257690075Sobrien			   (match_operand:SF 1 "fr_register_operand" "f")
257790075Sobrien			   (match_operand:SF 2 "fr_register_operand" "f")))
257890075Sobrien		 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
257990075Sobrien  ""
258090075Sobrien  "fnma.s %0 = %1, %2, %F3"
258190075Sobrien  [(set_attr "itanium_class" "fmac")])
258290075Sobrien
258390075Sobrien(define_expand "divsf3"
258490075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "")
258590075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "")
258690075Sobrien		(match_operand:SF 2 "fr_register_operand" "")))]
2587132718Skan  "TARGET_INLINE_FLOAT_DIV"
258890075Sobrien{
258990075Sobrien  rtx insn;
2590117395Skan  if (TARGET_INLINE_FLOAT_DIV_LAT)
259190075Sobrien    insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
259290075Sobrien  else
259390075Sobrien    insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
259490075Sobrien  emit_insn (insn);
259590075Sobrien  DONE;
2596117395Skan})
259790075Sobrien
259890075Sobrien(define_insn_and_split "divsf3_internal_lat"
259990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
260090075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
260190075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
2602132718Skan   (clobber (match_scratch:XF 3 "=&f"))
2603132718Skan   (clobber (match_scratch:XF 4 "=f"))
260490075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
2605132718Skan  "TARGET_INLINE_FLOAT_DIV_LAT"
260690075Sobrien  "#"
260790075Sobrien  "&& reload_completed"
2608132718Skan  [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2609117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2610117395Skan					    UNSPEC_FR_RECIP_APPROX))
261190075Sobrien	      (use (const_int 1))])
261290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
2613132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
261490075Sobrien		(use (const_int 1))]))
261590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
261690075Sobrien     (parallel [(set (match_dup 4)
2617132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
261890075Sobrien			      (match_dup 10)))
261990075Sobrien		(use (const_int 1))]))
262090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
262190075Sobrien     (parallel [(set (match_dup 3)
2622132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 3))
262390075Sobrien			      (match_dup 3)))
262490075Sobrien		(use (const_int 1))]))
262590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
2626132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
262790075Sobrien		(use (const_int 1))]))
262890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
262990075Sobrien     (parallel [(set (match_dup 3)
2630132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 3))
263190075Sobrien			      (match_dup 3)))
263290075Sobrien		(use (const_int 1))]))
263390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
2634132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
263590075Sobrien		(use (const_int 1))]))
263690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
263790075Sobrien     (parallel [(set (match_dup 9)
263890075Sobrien		     (float_truncate:DF
2639132718Skan		       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
264090075Sobrien			      (match_dup 3))))
264190075Sobrien		(use (const_int 1))]))
264290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
264390075Sobrien     (set (match_dup 0)
264490075Sobrien	  (float_truncate:SF (match_dup 6))))
264590075Sobrien  ] 
2646117395Skan{
2647132718Skan  operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2648132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2649132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2650117395Skan  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2651132718Skan  operands[10] = CONST1_RTX (XFmode);
2652117395Skan}
265390075Sobrien  [(set_attr "predicable" "no")])
265490075Sobrien
265590075Sobrien(define_insn_and_split "divsf3_internal_thr"
265690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
265790075Sobrien	(div:SF (match_operand:SF 1 "fr_register_operand" "f")
265890075Sobrien		(match_operand:SF 2 "fr_register_operand" "f")))
2659132718Skan   (clobber (match_scratch:XF 3 "=&f"))
2660132718Skan   (clobber (match_scratch:XF 4 "=f"))
266190075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
2662132718Skan  "TARGET_INLINE_FLOAT_DIV_THR"
266390075Sobrien  "#"
266490075Sobrien  "&& reload_completed"
2665132718Skan  [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2666117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2667117395Skan					    UNSPEC_FR_RECIP_APPROX))
266890075Sobrien	      (use (const_int 1))])
266990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
267090075Sobrien     (parallel [(set (match_dup 3)
2671132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
267290075Sobrien			      (match_dup 10)))
267390075Sobrien		(use (const_int 1))]))
267490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
267590075Sobrien     (parallel [(set (match_dup 3)
2676132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 3))
267790075Sobrien			      (match_dup 3)))
267890075Sobrien		(use (const_int 1))]))
267990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
268090075Sobrien     (parallel [(set (match_dup 6)
2681132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
268290075Sobrien			      (match_dup 6)))
268390075Sobrien		(use (const_int 1))]))
268490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
268590075Sobrien     (parallel [(set (match_dup 9)
268690075Sobrien		     (float_truncate:SF
2687132718Skan		       (mult:XF (match_dup 7) (match_dup 6))))
268890075Sobrien		(use (const_int 1))]))
268990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
269090075Sobrien     (parallel [(set (match_dup 4)
2691132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 3)))
269290075Sobrien			      (match_dup 7)))
269390075Sobrien		(use (const_int 1))]))
269490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
269590075Sobrien     (set (match_dup 0)
269690075Sobrien	  (float_truncate:SF
2697132718Skan	    (plus:XF (mult:XF (match_dup 4) (match_dup 6))
269890075Sobrien			      (match_dup 3)))))
269990075Sobrien  ] 
2700117395Skan{
2701132718Skan  operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2702132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2703132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2704117395Skan  operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
2705132718Skan  operands[10] = CONST1_RTX (XFmode);
2706117395Skan}
270790075Sobrien  [(set_attr "predicable" "no")])
2708132718Skan
2709132718Skan;; Inline square root.
2710132718Skan
2711132718Skan(define_insn "*sqrt_approx"
2712132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
2713132718Skan        (div:XF (const_int 1)
2714132718Skan                (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
2715132718Skan   (set (match_operand:BI 1 "register_operand" "=c")
2716132718Skan        (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
2717132718Skan   (use (match_operand:SI 3 "const_int_operand" "")) ]
2718132718Skan  ""
2719132718Skan  "frsqrta.s%3 %0, %1 = %2"
2720132718Skan  [(set_attr "itanium_class" "fmisc")
2721132718Skan   (set_attr "predicable" "no")])
2722132718Skan
2723132718Skan(define_insn "*setf_exp_xf"
2724132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
2725132718Skan        (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
2726132718Skan                  UNSPEC_SETF_EXP))]
2727132718Skan  ""
2728132718Skan  "setf.exp %0 = %1"
2729132718Skan  [(set_attr "itanium_class" "frfr")])
2730132718Skan
2731132718Skan(define_expand "sqrtsf2"
2732132718Skan  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2733132718Skan	(sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2734132718Skan  "TARGET_INLINE_SQRT"
2735132718Skan{
2736132718Skan  rtx insn;
2737132718Skan  if (TARGET_INLINE_SQRT_LAT)
2738132718Skan#if 0
2739132718Skan    insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
2740132718Skan#else
2741132718Skan    abort ();
2742132718Skan#endif
2743132718Skan  else
2744132718Skan    insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
2745132718Skan  emit_insn (insn);
2746132718Skan  DONE;
2747132718Skan})
2748132718Skan
2749132718Skan;; Latency-optimized square root.
2750132718Skan;; FIXME: Implement.
2751132718Skan
2752132718Skan;; Throughput-optimized square root.
2753132718Skan
2754132718Skan(define_insn_and_split "sqrtsf2_internal_thr"
2755132718Skan  [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2756132718Skan	(sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))
2757132718Skan   ;; Register r2 in optimization guide.
2758132718Skan   (clobber (match_scratch:DI 2 "=r"))
2759132718Skan   ;; Register f8 in optimization guide
2760132718Skan   (clobber (match_scratch:XF 3 "=&f"))
2761132718Skan   ;; Register f9 in optimization guide
2762132718Skan   (clobber (match_scratch:XF 4 "=&f"))
2763132718Skan   ;; Register f10 in optimization guide
2764132718Skan   (clobber (match_scratch:XF 5 "=&f"))
2765132718Skan   ;; Register p6 in optimization guide.
2766132718Skan   (clobber (match_scratch:BI 6 "=c"))]
2767132718Skan  "TARGET_INLINE_SQRT_THR"
2768132718Skan  "#"
2769132718Skan  "&& reload_completed"
2770132718Skan  [ ;; exponent of +1/2 in r2
2771132718Skan    (set (match_dup 2) (const_int 65534))
2772132718Skan    ;; +1/2 in f8
2773132718Skan    (set (match_dup 3) 
2774132718Skan         (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
2775132718Skan    ;; Step 1
2776132718Skan    ;; y0 = 1/sqrt(a) in f7
2777132718Skan    (parallel [(set (match_dup 7)
2778132718Skan                    (div:XF (const_int 1)
2779132718Skan                            (sqrt:XF (match_dup 8))))
2780132718Skan               (set (match_dup 6)
2781132718Skan                    (unspec:BI [(match_dup 8)]
2782132718Skan                                 UNSPEC_FR_SQRT_RECIP_APPROX))
2783132718Skan               (use (const_int 0))])
2784132718Skan    ;; Step 2
2785132718Skan    ;; H0 = 1/2 * y0 in f9
2786132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2787132718Skan      (parallel [(set (match_dup 4)
2788132718Skan                      (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2789132718Skan                               (match_dup 9)))
2790132718Skan                 (use (const_int 1))]))
2791132718Skan    ;; Step 3
2792132718Skan    ;; S0 = a * y0 in f7
2793132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2794132718Skan      (parallel [(set (match_dup 7)
2795132718Skan                      (plus:XF (mult:XF (match_dup 8) (match_dup 7))
2796132718Skan                               (match_dup 9)))
2797132718Skan                 (use (const_int 1))]))
2798132718Skan    ;; Step 4
2799132718Skan    ;; d = 1/2 - S0 * H0 in f10
2800132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2801132718Skan      (parallel [(set (match_dup 5)
2802132718Skan                      (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 4)))
2803132718Skan                               (match_dup 3)))
2804132718Skan                 (use (const_int 1))]))
2805132718Skan    ;; Step 5
2806132718Skan    ;; d' = d + 1/2 * d in f8
2807132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2808132718Skan       (parallel [(set (match_dup 3)
2809132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 5))
2810132718Skan                                (match_dup 5)))
2811132718Skan                  (use (const_int 1))]))
2812132718Skan    ;; Step 6
2813132718Skan    ;; e = d + d * d' in f8
2814132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2815132718Skan       (parallel [(set (match_dup 3)
2816132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 3))
2817132718Skan                                (match_dup 5)))
2818132718Skan                  (use (const_int 1))]))
2819132718Skan    ;; Step 7
2820132718Skan    ;; S1 = S0 + e * S0 in f7
2821132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2822132718Skan      (parallel [(set (match_dup 0)
2823132718Skan		      (float_truncate:SF
2824132718Skan                        (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2825132718Skan                                 (match_dup 7))))
2826132718Skan                 (use (const_int 1))]))
2827132718Skan    ;; Step 8
2828132718Skan    ;; H1 = H0 + e * H0 in f8
2829132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2830132718Skan       (parallel [(set (match_dup 3)
2831132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2832132718Skan                                (match_dup 4)))
2833132718Skan                  (use (const_int 1))]))
2834132718Skan    ;; Step 9 
2835132718Skan    ;; d1 = a - S1 * S1 in f9
2836132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2837132718Skan       (parallel [(set (match_dup 4)
2838132718Skan                       (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
2839132718Skan                                (match_dup 8)))
2840132718Skan                  (use (const_int 1))]))
2841132718Skan    ;; Step 10
2842132718Skan    ;; S = S1 + d1 * H1 in f7
2843132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
2844132718Skan       (parallel [(set (match_dup 0)
2845132718Skan                       (float_truncate:SF
2846132718Skan                         (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2847132718Skan                                  (match_dup 7))))
2848132718Skan                  (use (const_int 0))]))]
2849132718Skan{
2850132718Skan  /* Generate 82-bit versions of the input and output operands.  */
2851132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2852132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2853132718Skan  /* Generate required floating-point constants.  */
2854132718Skan  operands[9] = CONST0_RTX (XFmode);
2855132718Skan}
2856132718Skan  [(set_attr "predicable" "no")])
285790075Sobrien
285890075Sobrien;; ::::::::::::::::::::
285990075Sobrien;; ::
286090075Sobrien;; :: 64 bit floating point arithmetic
286190075Sobrien;; ::
286290075Sobrien;; ::::::::::::::::::::
286390075Sobrien
286490075Sobrien(define_insn "adddf3"
286590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
286690075Sobrien	(plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
286790075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
286890075Sobrien  ""
286990075Sobrien  "fadd.d %0 = %1, %F2"
287090075Sobrien  [(set_attr "itanium_class" "fmac")])
287190075Sobrien
287290075Sobrien(define_insn "*adddf3_trunc"
287390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
287490075Sobrien	(float_truncate:SF
287590075Sobrien	  (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
287690075Sobrien		   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
287790075Sobrien  ""
287890075Sobrien  "fadd.s %0 = %1, %F2"
287990075Sobrien  [(set_attr "itanium_class" "fmac")])
288090075Sobrien
288190075Sobrien(define_insn "subdf3"
288290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
288390075Sobrien	(minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
288490075Sobrien		  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
288590075Sobrien  ""
288690075Sobrien  "fsub.d %0 = %F1, %F2"
288790075Sobrien  [(set_attr "itanium_class" "fmac")])
288890075Sobrien
288990075Sobrien(define_insn "*subdf3_trunc"
289090075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
289190075Sobrien	(float_truncate:SF
289290075Sobrien	  (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
289390075Sobrien		    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
289490075Sobrien  ""
289590075Sobrien  "fsub.s %0 = %F1, %F2"
289690075Sobrien  [(set_attr "itanium_class" "fmac")])
289790075Sobrien
289890075Sobrien(define_insn "muldf3"
289990075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
290090075Sobrien	(mult:DF (match_operand:DF 1 "fr_register_operand" "f")
290190075Sobrien		 (match_operand:DF 2 "fr_register_operand" "f")))]
290290075Sobrien  ""
290390075Sobrien  "fmpy.d %0 = %1, %2"
290490075Sobrien  [(set_attr "itanium_class" "fmac")])
290590075Sobrien
290690075Sobrien(define_insn "*muldf3_trunc"
290790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
290890075Sobrien	(float_truncate:SF
290990075Sobrien	  (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
291090075Sobrien		   (match_operand:DF 2 "fr_register_operand" "f"))))]
291190075Sobrien  ""
291290075Sobrien  "fmpy.s %0 = %1, %2"
291390075Sobrien  [(set_attr "itanium_class" "fmac")])
291490075Sobrien
291590075Sobrien(define_insn "absdf2"
291690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
291790075Sobrien	(abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
291890075Sobrien  ""
291990075Sobrien  "fabs %0 = %1"
292090075Sobrien  [(set_attr "itanium_class" "fmisc")])
292190075Sobrien
292290075Sobrien(define_insn "negdf2"
292390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
292490075Sobrien	(neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
292590075Sobrien  ""
292690075Sobrien  "fneg %0 = %1"
292790075Sobrien  [(set_attr "itanium_class" "fmisc")])
292890075Sobrien
292990075Sobrien(define_insn "*nabsdf2"
293090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
293190075Sobrien	(neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
293290075Sobrien  ""
293390075Sobrien  "fnegabs %0 = %1"
293490075Sobrien  [(set_attr "itanium_class" "fmisc")])
293590075Sobrien
293690075Sobrien(define_insn "mindf3"
293790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
293890075Sobrien	(smin:DF (match_operand:DF 1 "fr_register_operand" "f")
293990075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
294090075Sobrien  ""
294190075Sobrien  "fmin %0 = %1, %F2"
294290075Sobrien  [(set_attr "itanium_class" "fmisc")])
294390075Sobrien
294490075Sobrien(define_insn "maxdf3"
294590075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
294690075Sobrien	(smax:DF (match_operand:DF 1 "fr_register_operand" "f")
294790075Sobrien		 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
294890075Sobrien  ""
294990075Sobrien  "fmax %0 = %1, %F2"
295090075Sobrien  [(set_attr "itanium_class" "fmisc")])
295190075Sobrien
295290075Sobrien(define_insn "*madddf4"
295390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
295490075Sobrien	(plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
295590075Sobrien			  (match_operand:DF 2 "fr_register_operand" "f"))
295690075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
295790075Sobrien  ""
295890075Sobrien  "fma.d %0 = %1, %2, %F3"
295990075Sobrien  [(set_attr "itanium_class" "fmac")])
296090075Sobrien
296190075Sobrien(define_insn "*madddf4_trunc"
296290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
296390075Sobrien	(float_truncate:SF
296490075Sobrien	  (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
296590075Sobrien			    (match_operand:DF 2 "fr_register_operand" "f"))
296690075Sobrien		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
296790075Sobrien  ""
296890075Sobrien  "fma.s %0 = %1, %2, %F3"
296990075Sobrien  [(set_attr "itanium_class" "fmac")])
297090075Sobrien
297190075Sobrien(define_insn "*msubdf4"
297290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
297390075Sobrien	(minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
297490075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f"))
297590075Sobrien		  (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
297690075Sobrien  ""
297790075Sobrien  "fms.d %0 = %1, %2, %F3"
297890075Sobrien  [(set_attr "itanium_class" "fmac")])
297990075Sobrien
298090075Sobrien(define_insn "*msubdf4_trunc"
298190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
298290075Sobrien	(float_truncate:SF
298390075Sobrien	  (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
298490075Sobrien			     (match_operand:DF 2 "fr_register_operand" "f"))
298590075Sobrien		    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
298690075Sobrien  ""
298790075Sobrien  "fms.s %0 = %1, %2, %F3"
298890075Sobrien  [(set_attr "itanium_class" "fmac")])
298990075Sobrien
299090075Sobrien(define_insn "*nmuldf3"
299190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
299290075Sobrien	(neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
299390075Sobrien			 (match_operand:DF 2 "fr_register_operand" "f"))))]
299490075Sobrien  ""
299590075Sobrien  "fnmpy.d %0 = %1, %2"
299690075Sobrien  [(set_attr "itanium_class" "fmac")])
299790075Sobrien
299890075Sobrien(define_insn "*nmuldf3_trunc"
299990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
300090075Sobrien	(float_truncate:SF
300190075Sobrien	  (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
300290075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))))]
300390075Sobrien  ""
300490075Sobrien  "fnmpy.s %0 = %1, %2"
300590075Sobrien  [(set_attr "itanium_class" "fmac")])
300690075Sobrien
300790075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
300890075Sobrien
300990075Sobrien(define_insn "*nmadddf4"
301090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
301190075Sobrien	(plus:DF (neg:DF (mult:DF
301290075Sobrien			   (match_operand:DF 1 "fr_register_operand" "f")
301390075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))
301490075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
301590075Sobrien  ""
301690075Sobrien  "fnma.d %0 = %1, %2, %F3"
301790075Sobrien  [(set_attr "itanium_class" "fmac")])
301890075Sobrien
301990075Sobrien(define_insn "*nmadddf4_alts"
302090075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
302190075Sobrien	(plus:DF (neg:DF (mult:DF
302290075Sobrien			   (match_operand:DF 1 "fr_register_operand" "f")
302390075Sobrien			   (match_operand:DF 2 "fr_register_operand" "f")))
302490075Sobrien		 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
302590075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
302690075Sobrien  ""
302790075Sobrien  "fnma.d.s%4 %0 = %1, %2, %F3"
302890075Sobrien  [(set_attr "itanium_class" "fmac")])
302990075Sobrien
303090075Sobrien(define_insn "*nmadddf4_trunc"
303190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
303290075Sobrien	(float_truncate:SF
303390075Sobrien	  (plus:DF (neg:DF (mult:DF
303490075Sobrien			     (match_operand:DF 1 "fr_register_operand" "f")
303590075Sobrien			     (match_operand:DF 2 "fr_register_operand" "f")))
303690075Sobrien		   (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
303790075Sobrien  ""
303890075Sobrien  "fnma.s %0 = %1, %2, %F3"
303990075Sobrien  [(set_attr "itanium_class" "fmac")])
304090075Sobrien
304190075Sobrien(define_expand "divdf3"
304290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "")
304390075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "")
304490075Sobrien		(match_operand:DF 2 "fr_register_operand" "")))]
3045132718Skan  "TARGET_INLINE_FLOAT_DIV"
304690075Sobrien{
304790075Sobrien  rtx insn;
3048117395Skan  if (TARGET_INLINE_FLOAT_DIV_LAT)
304990075Sobrien    insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
305090075Sobrien  else
305190075Sobrien    insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
305290075Sobrien  emit_insn (insn);
305390075Sobrien  DONE;
3054117395Skan})
305590075Sobrien
305690075Sobrien(define_insn_and_split "divdf3_internal_lat"
305790075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
305890075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
305990075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
3060132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3061132718Skan   (clobber (match_scratch:XF 4 "=&f"))
3062132718Skan   (clobber (match_scratch:XF 5 "=&f"))
306390075Sobrien   (clobber (match_scratch:BI 6 "=c"))]
3064132718Skan  "TARGET_INLINE_FLOAT_DIV_LAT"
306590075Sobrien  "#"
306690075Sobrien  "&& reload_completed"
3067132718Skan  [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
3068117395Skan	      (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3069117395Skan					    UNSPEC_FR_RECIP_APPROX))
307090075Sobrien	      (use (const_int 1))])
307190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
3072132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
307390075Sobrien		(use (const_int 1))]))
307490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
307590075Sobrien     (parallel [(set (match_dup 4)
3076132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 7)))
307790075Sobrien			      (match_dup 12)))
307890075Sobrien		(use (const_int 1))]))
307990075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
308090075Sobrien     (parallel [(set (match_dup 3)
3081132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 3))
308290075Sobrien			      (match_dup 3)))
308390075Sobrien		(use (const_int 1))]))
308490075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
3085132718Skan     (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
308690075Sobrien		(use (const_int 1))]))
308790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
308890075Sobrien     (parallel [(set (match_dup 7)
3089132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 7))
309090075Sobrien			      (match_dup 7)))
309190075Sobrien		(use (const_int 1))]))
309290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
309390075Sobrien     (parallel [(set (match_dup 3)
3094132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 3))
309590075Sobrien			      (match_dup 3)))
309690075Sobrien		(use (const_int 1))]))
309790075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
3098132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
309990075Sobrien		(use (const_int 1))]))
310090075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
310190075Sobrien     (parallel [(set (match_dup 7)
3102132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 7))
310390075Sobrien			      (match_dup 7)))
310490075Sobrien		(use (const_int 1))]))
310590075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
310690075Sobrien     (parallel [(set (match_dup 10)
310790075Sobrien		     (float_truncate:DF
3108132718Skan		       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
310990075Sobrien			      (match_dup 3))))
311090075Sobrien		(use (const_int 1))]))
311190075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
311290075Sobrien     (parallel [(set (match_dup 7)
3113132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 7))
311490075Sobrien			      (match_dup 7)))
311590075Sobrien		(use (const_int 1))]))
311690075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
311790075Sobrien     (parallel [(set (match_dup 11)
311890075Sobrien		     (float_truncate:DF
3119132718Skan		       (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 3)))
312090075Sobrien			        (match_dup 8))))
312190075Sobrien		(use (const_int 1))]))
312290075Sobrien   (cond_exec (ne (match_dup 6) (const_int 0))
312390075Sobrien     (set (match_dup 0)
3124132718Skan	  (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
312590075Sobrien			      (match_dup 3)))))
312690075Sobrien  ] 
3127117395Skan{
3128132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3129132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3130132718Skan  operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3131117395Skan  operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3132117395Skan  operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3133132718Skan  operands[12] = CONST1_RTX (XFmode);
3134117395Skan}
313590075Sobrien  [(set_attr "predicable" "no")])
313690075Sobrien
313790075Sobrien(define_insn_and_split "divdf3_internal_thr"
313890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
313990075Sobrien	(div:DF (match_operand:DF 1 "fr_register_operand" "f")
314090075Sobrien		(match_operand:DF 2 "fr_register_operand" "f")))
3141132718Skan   (clobber (match_scratch:XF 3 "=&f"))
314290075Sobrien   (clobber (match_scratch:DF 4 "=f"))
314390075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
3144132718Skan  "TARGET_INLINE_FLOAT_DIV_THR"
314590075Sobrien  "#"
314690075Sobrien  "&& reload_completed"
3147132718Skan  [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3148117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3149117395Skan					    UNSPEC_FR_RECIP_APPROX))
315090075Sobrien	      (use (const_int 1))])
315190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
315290075Sobrien     (parallel [(set (match_dup 3)
3153132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
315490075Sobrien			      (match_dup 10)))
315590075Sobrien		(use (const_int 1))]))
315690075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
315790075Sobrien     (parallel [(set (match_dup 6)
3158132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
315990075Sobrien			      (match_dup 6)))
316090075Sobrien		(use (const_int 1))]))
316190075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
316290075Sobrien     (parallel [(set (match_dup 3)
3163132718Skan		     (mult:XF (match_dup 3) (match_dup 3)))
316490075Sobrien		(use (const_int 1))]))
316590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
316690075Sobrien     (parallel [(set (match_dup 6)
3167132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
316890075Sobrien			      (match_dup 6)))
316990075Sobrien		(use (const_int 1))]))
317090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
317190075Sobrien     (parallel [(set (match_dup 3)
3172132718Skan		     (mult:XF (match_dup 3) (match_dup 3)))
317390075Sobrien		(use (const_int 1))]))
317490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
317590075Sobrien     (parallel [(set (match_dup 6)
3176132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 6))
317790075Sobrien			      (match_dup 6)))
317890075Sobrien		(use (const_int 1))]))
317990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
318090075Sobrien     (parallel [(set (match_dup 9)
318190075Sobrien		     (float_truncate:DF
3182132718Skan		       (mult:XF (match_dup 7) (match_dup 3))))
318390075Sobrien		(use (const_int 1))]))
318490075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
318590075Sobrien     (parallel [(set (match_dup 4)
318690075Sobrien		     (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
318790075Sobrien			      (match_dup 1)))
318890075Sobrien		(use (const_int 1))]))
318990075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
319090075Sobrien     (set (match_dup 0)
319190075Sobrien	  (plus:DF (mult:DF (match_dup 4) (match_dup 0))
319290075Sobrien			    (match_dup 9))))
319390075Sobrien  ] 
3194117395Skan{
3195132718Skan  operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3196132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3197132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3198117395Skan  operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3199132718Skan  operands[10] = CONST1_RTX (XFmode);
3200117395Skan}
320190075Sobrien  [(set_attr "predicable" "no")])
3202132718Skan
3203132718Skan;; Inline square root.
3204132718Skan
3205132718Skan(define_expand "sqrtdf2"
3206132718Skan  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3207132718Skan	(sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3208132718Skan  "TARGET_INLINE_SQRT"
3209132718Skan{
3210132718Skan  rtx insn;
3211132718Skan  if (TARGET_INLINE_SQRT_LAT)
3212132718Skan#if 0
3213132718Skan    insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
3214132718Skan#else
3215132718Skan    abort ();
3216132718Skan#endif
3217132718Skan  else
3218132718Skan    insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
3219132718Skan  emit_insn (insn);
3220132718Skan  DONE;
3221132718Skan})
3222132718Skan
3223132718Skan;; Latency-optimized square root.
3224132718Skan;; FIXME: Implement.
3225132718Skan
3226132718Skan;; Throughput-optimized square root.
3227132718Skan
3228132718Skan(define_insn_and_split "sqrtdf2_internal_thr"
3229132718Skan  [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3230132718Skan	(sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))
3231132718Skan   ;; Register r2 in optimization guide.
3232132718Skan   (clobber (match_scratch:DI 2 "=r"))
3233132718Skan   ;; Register f8 in optimization guide
3234132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3235132718Skan   ;; Register f9 in optimization guide
3236132718Skan   (clobber (match_scratch:XF 4 "=&f"))
3237132718Skan   ;; Register f10 in optimization guide
3238132718Skan   (clobber (match_scratch:XF 5 "=&f"))
3239132718Skan   ;; Register p6 in optimization guide.
3240132718Skan   (clobber (match_scratch:BI 6 "=c"))]
3241132718Skan  "TARGET_INLINE_SQRT_THR"
3242132718Skan  "#"
3243132718Skan  "&& reload_completed"
3244132718Skan  [ ;; exponent of +1/2 in r2
3245132718Skan    (set (match_dup 2) (const_int 65534))
3246132718Skan    ;; +1/2 in f10
3247132718Skan    (set (match_dup 5) 
3248132718Skan         (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3249132718Skan    ;; Step 1
3250132718Skan    ;; y0 = 1/sqrt(a) in f7
3251132718Skan    (parallel [(set (match_dup 7)
3252132718Skan                    (div:XF (const_int 1)
3253132718Skan                            (sqrt:XF (match_dup 8))))
3254132718Skan               (set (match_dup 6)
3255132718Skan                    (unspec:BI [(match_dup 8)]
3256132718Skan                                 UNSPEC_FR_SQRT_RECIP_APPROX))
3257132718Skan               (use (const_int 0))])
3258132718Skan    ;; Step 2
3259132718Skan    ;; H0 = 1/2 * y0 in f8
3260132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3261132718Skan      (parallel [(set (match_dup 3)
3262132718Skan                      (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3263132718Skan                               (match_dup 9)))
3264132718Skan                 (use (const_int 1))]))
3265132718Skan    ;; Step 3
3266132718Skan    ;; G0 = a * y0 in f7
3267132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3268132718Skan      (parallel [(set (match_dup 7)
3269132718Skan                      (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3270132718Skan                               (match_dup 9)))
3271132718Skan                 (use (const_int 1))]))
3272132718Skan    ;; Step 4
3273132718Skan    ;; r0 = 1/2 - G0 * H0 in f9
3274132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3275132718Skan      (parallel [(set (match_dup 4)
3276132718Skan                      (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
3277132718Skan                               (match_dup 5)))
3278132718Skan                 (use (const_int 1))]))
3279132718Skan    ;; Step 5
3280132718Skan    ;; H1 = H0 + r0 * H0 in f8
3281132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3282132718Skan       (parallel [(set (match_dup 3)
3283132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3284132718Skan                                (match_dup 3)))
3285132718Skan                  (use (const_int 1))]))
3286132718Skan    ;; Step 6
3287132718Skan    ;; G1 = G0 + r0 * G0 in f7
3288132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3289132718Skan       (parallel [(set (match_dup 7)
3290132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3291132718Skan                                (match_dup 7)))
3292132718Skan                  (use (const_int 1))]))
3293132718Skan    ;; Step 7
3294132718Skan    ;; r1 = 1/2 - G1 * H1 in f9
3295132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3296132718Skan      (parallel [(set (match_dup 4)
3297132718Skan                      (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
3298132718Skan                               (match_dup 5)))
3299132718Skan                 (use (const_int 1))]))
3300132718Skan    ;; Step 8
3301132718Skan    ;; H2 = H1 + r1 * H1 in f8
3302132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3303132718Skan       (parallel [(set (match_dup 3)
3304132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3305132718Skan                                (match_dup 3)))
3306132718Skan                  (use (const_int 1))]))
3307132718Skan    ;; Step 9 
3308132718Skan    ;; G2 = G1 + r1 * G1 in f7
3309132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3310132718Skan       (parallel [(set (match_dup 7)
3311132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3312132718Skan                                (match_dup 7)))
3313132718Skan                  (use (const_int 1))]))
3314132718Skan    ;; Step 10
3315132718Skan    ;; d2 = a - G2 * G2 in f9
3316132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3317132718Skan       (parallel [(set (match_dup 4)
3318132718Skan                       (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
3319132718Skan                                (match_dup 8)))
3320132718Skan                  (use (const_int 1))]))
3321132718Skan    ;; Step 11
3322132718Skan    ;; G3 = G2 + d2 * H2 in f7
3323132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3324132718Skan       (parallel [(set (match_dup 7)
3325132718Skan                       (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3326132718Skan                                (match_dup 7)))
3327132718Skan                  (use (const_int 1))]))
3328132718Skan    ;; Step 12
3329132718Skan    ;; d3 = a - G3 * G3 in f9
3330132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3331132718Skan       (parallel [(set (match_dup 4)
3332132718Skan                       (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
3333132718Skan                                (match_dup 8)))
3334132718Skan                  (use (const_int 1))]))
3335132718Skan    ;; Step 13
3336132718Skan    ;; S = G3 + d3 * H2 in f7
3337132718Skan    (cond_exec (ne (match_dup 6) (const_int 0))
3338132718Skan       (parallel [(set (match_dup 0)
3339132718Skan                       (float_truncate:DF
3340132718Skan                         (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3341132718Skan                                  (match_dup 7))))
3342132718Skan                  (use (const_int 0))]))]
3343132718Skan{
3344132718Skan  /* Generate 82-bit versions of the input and output operands.  */
3345132718Skan  operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3346132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3347132718Skan  /* Generate required floating-point constants.  */
3348132718Skan  operands[9] = CONST0_RTX (XFmode);
3349132718Skan}
3350132718Skan  [(set_attr "predicable" "no")])
335190075Sobrien
335290075Sobrien;; ::::::::::::::::::::
335390075Sobrien;; ::
335490075Sobrien;; :: 80 bit floating point arithmetic
335590075Sobrien;; ::
335690075Sobrien;; ::::::::::::::::::::
335790075Sobrien
3358132718Skan(define_insn "addxf3"
3359132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3360132718Skan	(plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3361132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3362132718Skan  ""
336390075Sobrien  "fadd %0 = %F1, %F2"
336490075Sobrien  [(set_attr "itanium_class" "fmac")])
336590075Sobrien
3366132718Skan(define_insn "*addxf3_truncsf"
336790075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
336890075Sobrien	(float_truncate:SF
3369132718Skan	  (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3370132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3371132718Skan  ""
337290075Sobrien  "fadd.s %0 = %F1, %F2"
337390075Sobrien  [(set_attr "itanium_class" "fmac")])
337490075Sobrien
3375132718Skan(define_insn "*addxf3_truncdf"
337690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
337790075Sobrien	(float_truncate:DF
3378132718Skan	  (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3379132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3380132718Skan  ""
338190075Sobrien  "fadd.d %0 = %F1, %F2"
338290075Sobrien  [(set_attr "itanium_class" "fmac")])
338390075Sobrien
3384132718Skan(define_insn "subxf3"
3385132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3386132718Skan	(minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3387132718Skan		  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3388132718Skan  ""
338990075Sobrien  "fsub %0 = %F1, %F2"
339090075Sobrien  [(set_attr "itanium_class" "fmac")])
339190075Sobrien
3392132718Skan(define_insn "*subxf3_truncsf"
339390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
339490075Sobrien	(float_truncate:SF
3395132718Skan	  (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3396132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3397132718Skan  ""
339890075Sobrien  "fsub.s %0 = %F1, %F2"
339990075Sobrien  [(set_attr "itanium_class" "fmac")])
340090075Sobrien
3401132718Skan(define_insn "*subxf3_truncdf"
340290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
340390075Sobrien	(float_truncate:DF
3404132718Skan	  (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3405132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3406132718Skan  ""
340790075Sobrien  "fsub.d %0 = %F1, %F2"
340890075Sobrien  [(set_attr "itanium_class" "fmac")])
340990075Sobrien
3410132718Skan(define_insn "mulxf3"
3411132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3412132718Skan	(mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3413132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3414132718Skan  ""
341590075Sobrien  "fmpy %0 = %F1, %F2"
341690075Sobrien  [(set_attr "itanium_class" "fmac")])
341790075Sobrien
3418132718Skan(define_insn "*mulxf3_truncsf"
341990075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
342090075Sobrien	(float_truncate:SF
3421132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3422132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3423132718Skan  ""
342490075Sobrien  "fmpy.s %0 = %F1, %F2"
342590075Sobrien  [(set_attr "itanium_class" "fmac")])
342690075Sobrien
3427132718Skan(define_insn "*mulxf3_truncdf"
342890075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
342990075Sobrien	(float_truncate:DF
3430132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3431132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3432132718Skan  ""
343390075Sobrien  "fmpy.d %0 = %F1, %F2"
343490075Sobrien  [(set_attr "itanium_class" "fmac")])
343590075Sobrien
3436132718Skan(define_insn "*mulxf3_alts"
3437132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3438132718Skan	(mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3439132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
344090075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
3441132718Skan  ""
344290075Sobrien  "fmpy.s%3 %0 = %F1, %F2"
344390075Sobrien  [(set_attr "itanium_class" "fmac")])
344490075Sobrien
3445132718Skan(define_insn "*mulxf3_truncsf_alts"
344690075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
344790075Sobrien	(float_truncate:SF
3448132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3449132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
345090075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
3451132718Skan  ""
345290075Sobrien  "fmpy.s.s%3 %0 = %F1, %F2"
345390075Sobrien  [(set_attr "itanium_class" "fmac")])
345490075Sobrien
3455132718Skan(define_insn "*mulxf3_truncdf_alts"
345690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
345790075Sobrien	(float_truncate:DF
3458132718Skan	  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3459132718Skan		   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
346090075Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
3461132718Skan  ""
346290075Sobrien  "fmpy.d.s%3 %0 = %F1, %F2"
346390075Sobrien  [(set_attr "itanium_class" "fmac")])
346490075Sobrien
3465132718Skan(define_insn "absxf2"
3466132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3467132718Skan	(abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3468132718Skan  ""
346990075Sobrien  "fabs %0 = %F1"
347090075Sobrien  [(set_attr "itanium_class" "fmisc")])
347190075Sobrien
3472132718Skan(define_insn "negxf2"
3473132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3474132718Skan	(neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3475132718Skan  ""
347690075Sobrien  "fneg %0 = %F1"
347790075Sobrien  [(set_attr "itanium_class" "fmisc")])
347890075Sobrien
3479132718Skan(define_insn "*nabsxf2"
3480132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3481132718Skan	(neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
3482132718Skan  ""
348390075Sobrien  "fnegabs %0 = %F1"
348490075Sobrien  [(set_attr "itanium_class" "fmisc")])
348590075Sobrien
3486132718Skan(define_insn "minxf3"
3487132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3488132718Skan	(smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3489132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3490132718Skan  ""
349190075Sobrien  "fmin %0 = %F1, %F2"
349290075Sobrien  [(set_attr "itanium_class" "fmisc")])
349390075Sobrien
3494132718Skan(define_insn "maxxf3"
3495132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3496132718Skan	(smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3497132718Skan		 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3498132718Skan  ""
349990075Sobrien  "fmax %0 = %F1, %F2"
350090075Sobrien  [(set_attr "itanium_class" "fmisc")])
350190075Sobrien
3502132718Skan(define_insn "*maddxf4"
3503132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3504132718Skan	(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3505132718Skan			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3506132718Skan		 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3507132718Skan  ""
350890075Sobrien  "fma %0 = %F1, %F2, %F3"
350990075Sobrien  [(set_attr "itanium_class" "fmac")])
351090075Sobrien
3511132718Skan(define_insn "*maddxf4_truncsf"
351290075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
351390075Sobrien	(float_truncate:SF
3514132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3515132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3516132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3517132718Skan  ""
351890075Sobrien  "fma.s %0 = %F1, %F2, %F3"
351990075Sobrien  [(set_attr "itanium_class" "fmac")])
352090075Sobrien
3521132718Skan(define_insn "*maddxf4_truncdf"
352290075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
352390075Sobrien	(float_truncate:DF
3524132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3525132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3526132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3527132718Skan  ""
352890075Sobrien  "fma.d %0 = %F1, %F2, %F3"
352990075Sobrien  [(set_attr "itanium_class" "fmac")])
353090075Sobrien
3531132718Skan(define_insn "*maddxf4_alts"
3532132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3533132718Skan	(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3534132718Skan			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3535132718Skan		 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
353690075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
3537132718Skan  ""
353890075Sobrien  "fma.s%4 %0 = %F1, %F2, %F3"
353990075Sobrien  [(set_attr "itanium_class" "fmac")])
354090075Sobrien
3541132718Skan(define_insn "*maddxf4_alts_truncsf"
3542132718Skan  [(set (match_operand:SF 0 "fr_register_operand" "=f")
3543132718Skan	(float_truncate:SF
3544132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3545132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3546132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3547132718Skan   (use (match_operand:SI 4 "const_int_operand" ""))]
3548132718Skan  ""
3549132718Skan  "fma.s.s%4 %0 = %F1, %F2, %F3"
3550132718Skan  [(set_attr "itanium_class" "fmac")])
3551132718Skan
3552132718Skan(define_insn "*maddxf4_alts_truncdf"
355390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
355490075Sobrien	(float_truncate:DF
3555132718Skan	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3556132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3557132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
355890075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
3559132718Skan  ""
356090075Sobrien  "fma.d.s%4 %0 = %F1, %F2, %F3"
356190075Sobrien  [(set_attr "itanium_class" "fmac")])
356290075Sobrien
3563132718Skan(define_insn "*msubxf4"
3564132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3565132718Skan	(minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3566132718Skan			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3567132718Skan		  (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3568132718Skan  ""
356990075Sobrien  "fms %0 = %F1, %F2, %F3"
357090075Sobrien  [(set_attr "itanium_class" "fmac")])
357190075Sobrien
3572132718Skan(define_insn "*msubxf4_truncsf"
357390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
357490075Sobrien	(float_truncate:SF
3575132718Skan	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3576132718Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3577132718Skan		    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3578132718Skan  ""
357990075Sobrien  "fms.s %0 = %F1, %F2, %F3"
358090075Sobrien  [(set_attr "itanium_class" "fmac")])
358190075Sobrien
3582132718Skan(define_insn "*msubxf4_truncdf"
358390075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
358490075Sobrien	(float_truncate:DF
3585132718Skan	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3586132718Skan			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3587132718Skan		    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3588132718Skan  ""
358990075Sobrien  "fms.d %0 = %F1, %F2, %F3"
359090075Sobrien  [(set_attr "itanium_class" "fmac")])
359190075Sobrien
3592132718Skan(define_insn "*nmulxf3"
3593132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3594132718Skan	(neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3595132718Skan			 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3596132718Skan  ""
359790075Sobrien  "fnmpy %0 = %F1, %F2"
359890075Sobrien  [(set_attr "itanium_class" "fmac")])
359990075Sobrien
3600132718Skan(define_insn "*nmulxf3_truncsf"
360190075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
360290075Sobrien	(float_truncate:SF
3603132718Skan	  (neg:XF (mult:XF
3604132718Skan		    (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3605132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3606132718Skan  ""
360790075Sobrien  "fnmpy.s %0 = %F1, %F2"
360890075Sobrien  [(set_attr "itanium_class" "fmac")])
360990075Sobrien
3610132718Skan(define_insn "*nmulxf3_truncdf"
361190075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
361290075Sobrien	(float_truncate:DF
3613132718Skan	  (neg:XF (mult:XF
3614132718Skan		    (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3615132718Skan		    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3616132718Skan  ""
361790075Sobrien  "fnmpy.d %0 = %F1, %F2"
361890075Sobrien  [(set_attr "itanium_class" "fmac")])
361990075Sobrien
362090075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
362190075Sobrien
3622132718Skan(define_insn "*nmaddxf4"
3623132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3624132718Skan	(plus:XF (neg:XF (mult:XF
3625132718Skan			  (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3626132718Skan			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3627132718Skan		 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3628132718Skan  ""
362990075Sobrien  "fnma %0 = %F1, %F2, %F3"
363090075Sobrien  [(set_attr "itanium_class" "fmac")])
363190075Sobrien
3632132718Skan(define_insn "*nmaddxf4_truncsf"
363390075Sobrien  [(set (match_operand:SF 0 "fr_register_operand" "=f")
363490075Sobrien	(float_truncate:SF
3635132718Skan	  (plus:XF (neg:XF (mult:XF
3636132718Skan			    (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3637132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3638132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3639132718Skan  ""
364090075Sobrien  "fnma.s %0 = %F1, %F2, %F3"
364190075Sobrien  [(set_attr "itanium_class" "fmac")])
364290075Sobrien
3643132718Skan(define_insn "*nmaddxf4_truncdf"
364490075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
364590075Sobrien	(float_truncate:DF
3646132718Skan	  (plus:XF (neg:XF (mult:XF
3647132718Skan			    (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3648132718Skan			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3649132718Skan		   (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3650132718Skan  ""
365190075Sobrien  "fnma.d %0 = %F1, %F2, %F3"
365290075Sobrien  [(set_attr "itanium_class" "fmac")])
365390075Sobrien
3654132718Skan(define_insn "*nmaddxf4_alts"
3655132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
3656132718Skan	(plus:XF (neg:XF (mult:XF
3657132718Skan			  (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3658132718Skan			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3659132718Skan		 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
366090075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
3661132718Skan  ""
366290075Sobrien  "fnma.s%4 %0 = %F1, %F2, %F3"
366390075Sobrien  [(set_attr "itanium_class" "fmac")])
366490075Sobrien
3665132718Skan(define_insn "*nmaddxf4_truncdf_alts"
366690075Sobrien  [(set (match_operand:DF 0 "fr_register_operand" "=f")
366790075Sobrien	(float_truncate:DF
3668132718Skan	  (plus:XF (neg:XF
3669132718Skan		     (mult:XF
3670132718Skan		       (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3671132718Skan		       (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3672132718Skan		 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
367390075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
3674132718Skan  ""
367590075Sobrien  "fnma.d.s%4 %0 = %F1, %F2, %F3"
367690075Sobrien  [(set_attr "itanium_class" "fmac")])
367790075Sobrien
3678132718Skan(define_expand "divxf3"
3679132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "")
3680132718Skan	(div:XF (match_operand:XF 1 "fr_register_operand" "")
3681132718Skan		(match_operand:XF 2 "fr_register_operand" "")))]
3682132718Skan  "TARGET_INLINE_FLOAT_DIV"
368390075Sobrien{
368490075Sobrien  rtx insn;
3685117395Skan  if (TARGET_INLINE_FLOAT_DIV_LAT)
3686132718Skan    insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
368790075Sobrien  else
3688132718Skan    insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
368990075Sobrien  emit_insn (insn);
369090075Sobrien  DONE;
3691117395Skan})
369290075Sobrien
3693132718Skan(define_insn_and_split "divxf3_internal_lat"
3694132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3695132718Skan	(div:XF (match_operand:XF 1 "fr_register_operand" "f")
3696132718Skan		(match_operand:XF 2 "fr_register_operand" "f")))
3697132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3698132718Skan   (clobber (match_scratch:XF 4 "=&f"))
3699132718Skan   (clobber (match_scratch:XF 5 "=&f"))
3700132718Skan   (clobber (match_scratch:XF 6 "=&f"))
370190075Sobrien   (clobber (match_scratch:BI 7 "=c"))]
3702132718Skan  "TARGET_INLINE_FLOAT_DIV_LAT"
370390075Sobrien  "#"
370490075Sobrien  "&& reload_completed"
3705132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
3706117395Skan	      (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
3707117395Skan					    UNSPEC_FR_RECIP_APPROX))
370890075Sobrien	      (use (const_int 1))])
370990075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
371090075Sobrien     (parallel [(set (match_dup 3)
3711132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
371290075Sobrien			      (match_dup 8)))
371390075Sobrien		(use (const_int 1))]))
371490075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
3715132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
371690075Sobrien		(use (const_int 1))]))
371790075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
3718132718Skan     (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
371990075Sobrien		(use (const_int 1))]))
372090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
372190075Sobrien     (parallel [(set (match_dup 6)
3722132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 3))
372390075Sobrien			      (match_dup 3)))
372490075Sobrien		(use (const_int 1))]))
372590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
372690075Sobrien     (parallel [(set (match_dup 3)
3727132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 5))
372890075Sobrien			      (match_dup 3)))
372990075Sobrien		(use (const_int 1))]))
373090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
373190075Sobrien     (parallel [(set (match_dup 5)
3732132718Skan		     (plus:XF (mult:XF (match_dup 6) (match_dup 0))
373390075Sobrien			      (match_dup 0)))
373490075Sobrien		(use (const_int 1))]))
373590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
373690075Sobrien     (parallel [(set (match_dup 0)
3737132718Skan		     (plus:XF (mult:XF (match_dup 5) (match_dup 3))
373890075Sobrien			      (match_dup 0)))
373990075Sobrien		(use (const_int 1))]))
374090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
374190075Sobrien     (parallel [(set (match_dup 4)
3742132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
374390075Sobrien			      (match_dup 1)))
374490075Sobrien		(use (const_int 1))]))
374590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
374690075Sobrien     (parallel [(set (match_dup 3)
3747132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
374890075Sobrien			      (match_dup 4)))
374990075Sobrien		(use (const_int 1))]))
375090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
375190075Sobrien     (parallel [(set (match_dup 5)
3752132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
375390075Sobrien			      (match_dup 8)))
375490075Sobrien		(use (const_int 1))]))
375590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
375690075Sobrien     (parallel [(set (match_dup 0)
3757132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
375890075Sobrien			      (match_dup 0)))
375990075Sobrien		(use (const_int 1))]))
376090075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
376190075Sobrien     (parallel [(set (match_dup 4)
3762132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
376390075Sobrien			      (match_dup 1)))
376490075Sobrien		(use (const_int 1))]))
376590075Sobrien   (cond_exec (ne (match_dup 7) (const_int 0))
376690075Sobrien     (set (match_dup 0)
3767132718Skan	  (plus:XF (mult:XF (match_dup 4) (match_dup 0))
376890075Sobrien		   (match_dup 3))))
376990075Sobrien  ] 
3770132718Skan  "operands[8] = CONST1_RTX (XFmode);"
377190075Sobrien  [(set_attr "predicable" "no")])
377290075Sobrien
3773132718Skan(define_insn_and_split "divxf3_internal_thr"
3774132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3775132718Skan	(div:XF (match_operand:XF 1 "fr_register_operand" "f")
3776132718Skan		(match_operand:XF 2 "fr_register_operand" "f")))
3777132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3778132718Skan   (clobber (match_scratch:XF 4 "=&f"))
377990075Sobrien   (clobber (match_scratch:BI 5 "=c"))]
3780132718Skan  "TARGET_INLINE_FLOAT_DIV_THR"
378190075Sobrien  "#"
378290075Sobrien  "&& reload_completed"
3783132718Skan  [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
3784117395Skan	      (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
3785117395Skan					    UNSPEC_FR_RECIP_APPROX))
378690075Sobrien	      (use (const_int 1))])
378790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
378890075Sobrien     (parallel [(set (match_dup 3)
3789132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
379090075Sobrien			      (match_dup 6)))
379190075Sobrien		(use (const_int 1))]))
379290075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
379390075Sobrien     (parallel [(set (match_dup 4)
3794132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
379590075Sobrien			      (match_dup 0)))
379690075Sobrien		(use (const_int 1))]))
379790075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
3798132718Skan     (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
379990075Sobrien		(use (const_int 1))]))
380090075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
380190075Sobrien     (parallel [(set (match_dup 3)
3802132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 4))
380390075Sobrien			      (match_dup 4)))
380490075Sobrien		(use (const_int 1))]))
380590075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
3806132718Skan     (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
380790075Sobrien		(use (const_int 1))]))
380890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
380990075Sobrien     (parallel [(set (match_dup 0)
3810132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
381190075Sobrien			      (match_dup 6)))
381290075Sobrien		(use (const_int 1))]))
381390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
381490075Sobrien     (parallel [(set (match_dup 0)
3815132718Skan		     (plus:XF (mult:XF (match_dup 0) (match_dup 3))
381690075Sobrien			      (match_dup 3)))
381790075Sobrien		(use (const_int 1))]))
381890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
381990075Sobrien     (parallel [(set (match_dup 3)
3820132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
382190075Sobrien			      (match_dup 1)))
382290075Sobrien		(use (const_int 1))]))
382390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
382490075Sobrien     (parallel [(set (match_dup 3)
3825132718Skan		     (plus:XF (mult:XF (match_dup 3) (match_dup 0))
382690075Sobrien			      (match_dup 4)))
382790075Sobrien		(use (const_int 1))]))
382890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
382990075Sobrien     (parallel [(set (match_dup 4)
3830132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
383190075Sobrien			      (match_dup 6)))
383290075Sobrien		(use (const_int 1))]))
383390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
383490075Sobrien     (parallel [(set (match_dup 0)
3835132718Skan		     (plus:XF (mult:XF (match_dup 4) (match_dup 0))
383690075Sobrien			      (match_dup 0)))
383790075Sobrien		(use (const_int 1))]))
383890075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
383990075Sobrien     (parallel [(set (match_dup 4)
3840132718Skan		     (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
384190075Sobrien			      (match_dup 1)))
384290075Sobrien		(use (const_int 1))]))
384390075Sobrien   (cond_exec (ne (match_dup 5) (const_int 0))
384490075Sobrien     (set (match_dup 0)
3845132718Skan	  (plus:XF (mult:XF (match_dup 4) (match_dup 0))
384690075Sobrien		   (match_dup 3))))
384790075Sobrien  ] 
3848132718Skan  "operands[6] = CONST1_RTX (XFmode);"
384990075Sobrien  [(set_attr "predicable" "no")])
385090075Sobrien
3851132718Skan;; Inline square root.
3852132718Skan
3853132718Skan(define_expand "sqrtxf2"
3854132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3855132718Skan	(sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))]
3856132718Skan  "TARGET_INLINE_SQRT"
3857132718Skan{
3858132718Skan  rtx insn;
3859132718Skan  if (TARGET_INLINE_SQRT_LAT)
3860132718Skan#if 0
3861132718Skan    insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
3862132718Skan#else
3863132718Skan    abort ();
3864132718Skan#endif
3865132718Skan  else
3866132718Skan    insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]);
3867132718Skan  emit_insn (insn);
3868132718Skan  DONE;
3869132718Skan})
3870132718Skan
3871132718Skan;; Latency-optimized square root.
3872132718Skan;; FIXME: Implement.
3873132718Skan
3874132718Skan;; Throughput-optimized square root.
3875132718Skan
3876132718Skan(define_insn_and_split "sqrtxf2_internal_thr"
3877132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3878132718Skan	(sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))
3879132718Skan   ;; Register r2 in optimization guide.
3880132718Skan   (clobber (match_scratch:DI 2 "=r"))
3881132718Skan   ;; Register f8 in optimization guide
3882132718Skan   (clobber (match_scratch:XF 3 "=&f"))
3883132718Skan   ;; Register f9 in optimization guide
3884132718Skan   (clobber (match_scratch:XF 4 "=&f"))
3885132718Skan   ;; Register f10 in optimization guide
3886132718Skan   (clobber (match_scratch:XF 5 "=&f"))
3887132718Skan   ;; Register f11 in optimization guide
3888132718Skan   (clobber (match_scratch:XF 6 "=&f"))
3889132718Skan   ;; Register p6 in optimization guide.
3890132718Skan   (clobber (match_scratch:BI 7 "=c"))]
3891132718Skan  "TARGET_INLINE_SQRT_THR"
3892132718Skan  "#"
3893132718Skan  "&& reload_completed"
3894132718Skan  [ ;; exponent of +1/2 in r2
3895132718Skan    (set (match_dup 2) (const_int 65534))
3896132718Skan    ;; +1/2 in f8.  The Intel manual mistakenly specifies f10.
3897132718Skan    (set (match_dup 3) 
3898132718Skan         (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3899132718Skan    ;; Step 1
3900132718Skan    ;; y0 = 1/sqrt(a) in f7
3901132718Skan    (parallel [(set (match_dup 8)
3902132718Skan                    (div:XF (const_int 1)
3903132718Skan                            (sqrt:XF (match_dup 9))))
3904132718Skan               (set (match_dup 7)
3905132718Skan                    (unspec:BI [(match_dup 9)]
3906132718Skan                                 UNSPEC_FR_SQRT_RECIP_APPROX))
3907132718Skan               (use (const_int 0))])
3908132718Skan    ;; Step 2
3909132718Skan    ;; H0 = 1/2 * y0 in f9
3910132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3911132718Skan      (parallel [(set (match_dup 4)
3912132718Skan                      (plus:XF (mult:XF (match_dup 3) (match_dup 8))
3913132718Skan                               (match_dup 10)))
3914132718Skan                 (use (const_int 1))]))
3915132718Skan    ;; Step 3
3916132718Skan    ;; S0 = a * y0 in f7
3917132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3918132718Skan      (parallel [(set (match_dup 8)
3919132718Skan                      (plus:XF (mult:XF (match_dup 9) (match_dup 8))
3920132718Skan                               (match_dup 10)))
3921132718Skan                 (use (const_int 1))]))
3922132718Skan    ;; Step 4
3923132718Skan    ;; d0 = 1/2 - S0 * H0 in f10
3924132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3925132718Skan      (parallel [(set (match_dup 5)
3926132718Skan                      (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
3927132718Skan                               (match_dup 3)))
3928132718Skan                 (use (const_int 1))]))
3929132718Skan    ;; Step 5
3930132718Skan    ;; H1 = H0 + d0 * H0 in f9
3931132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3932132718Skan       (parallel [(set (match_dup 4)
3933132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 4))
3934132718Skan                                (match_dup 4)))
3935132718Skan                  (use (const_int 1))]))
3936132718Skan    ;; Step 6
3937132718Skan    ;; S1 = S0 + d0 * S0 in f7
3938132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3939132718Skan       (parallel [(set (match_dup 8)
3940132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 8))
3941132718Skan                                (match_dup 8)))
3942132718Skan                  (use (const_int 1))]))
3943132718Skan    ;; Step 7
3944132718Skan    ;; d1 = 1/2 - S1 * H1 in f10
3945132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3946132718Skan      (parallel [(set (match_dup 5)
3947132718Skan                      (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
3948132718Skan                               (match_dup 3)))
3949132718Skan                 (use (const_int 1))]))
3950132718Skan    ;; Step 8
3951132718Skan    ;; H2 = H1 + d1 * H1 in f9
3952132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3953132718Skan       (parallel [(set (match_dup 4)
3954132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 4))
3955132718Skan                                (match_dup 4)))
3956132718Skan                  (use (const_int 1))]))
3957132718Skan    ;; Step 9 
3958132718Skan    ;; S2 = S1 + d1 * S1 in f7
3959132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3960132718Skan       (parallel [(set (match_dup 8)
3961132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 8))
3962132718Skan                                (match_dup 8)))
3963132718Skan                  (use (const_int 1))]))
3964132718Skan    ;; Step 10
3965132718Skan    ;; d2 = 1/2 - S2 * H2 in f10
3966132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3967132718Skan       (parallel [(set (match_dup 5)
3968132718Skan                       (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
3969132718Skan                                (match_dup 3)))
3970132718Skan                  (use (const_int 1))]))
3971132718Skan    ;; Step 11
3972132718Skan    ;; e2 = a - S2 * S2 in f8
3973132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3974132718Skan       (parallel [(set (match_dup 3)
3975132718Skan                       (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
3976132718Skan                                (match_dup 9)))
3977132718Skan                  (use (const_int 1))]))
3978132718Skan    ;; Step 12
3979132718Skan    ;; S3 = S2 + e2 * H2 in f7
3980132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3981132718Skan       (parallel [(set (match_dup 8)
3982132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 4))
3983132718Skan                                (match_dup 8)))
3984132718Skan                  (use (const_int 1))]))
3985132718Skan    ;; Step 13
3986132718Skan    ;; H3 = H2 + d2 * H2 in f9
3987132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3988132718Skan       (parallel [(set (match_dup 4)
3989132718Skan                       (plus:XF (mult:XF (match_dup 5) (match_dup 4))
3990132718Skan                                (match_dup 4)))
3991132718Skan                  (use (const_int 1))]))
3992132718Skan    ;; Step 14
3993132718Skan    ;; e3 = a - S3 * S3 in f8
3994132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
3995132718Skan       (parallel [(set (match_dup 3)
3996132718Skan                       (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
3997132718Skan                                (match_dup 9)))
3998132718Skan                  (use (const_int 1))]))
3999132718Skan    ;; Step 15
4000132718Skan    ;; S = S3 + e3 * H3 in f7
4001132718Skan    (cond_exec (ne (match_dup 7) (const_int 0))
4002132718Skan       (parallel [(set (match_dup 0)
4003132718Skan                       (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4004132718Skan                                (match_dup 8)))
4005132718Skan                  (use (const_int 0))]))]
4006132718Skan{
4007132718Skan  /* Generate 82-bit versions of the input and output operands.  */
4008132718Skan  operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0]));
4009132718Skan  operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1]));
4010132718Skan  /* Generate required floating-point constants.  */
4011132718Skan  operands[10] = CONST0_RTX (XFmode);
4012132718Skan}
4013132718Skan  [(set_attr "predicable" "no")])
4014132718Skan
401590075Sobrien;; ??? frcpa works like cmp.foo.unc.
401690075Sobrien
401790075Sobrien(define_insn "*recip_approx"
4018132718Skan  [(set (match_operand:XF 0 "fr_register_operand" "=f")
4019132718Skan	(div:XF (const_int 1)
4020132718Skan		(match_operand:XF 3 "fr_register_operand" "f")))
402190075Sobrien   (set (match_operand:BI 1 "register_operand" "=c")
4022132718Skan	(unspec:BI [(match_operand:XF 2 "fr_register_operand" "f")
4023117395Skan		    (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
402490075Sobrien   (use (match_operand:SI 4 "const_int_operand" ""))]
4025132718Skan  ""
402690075Sobrien  "frcpa.s%4 %0, %1 = %2, %3"
402790075Sobrien  [(set_attr "itanium_class" "fmisc")
402890075Sobrien   (set_attr "predicable" "no")])
402990075Sobrien
403090075Sobrien;; ::::::::::::::::::::
403190075Sobrien;; ::
403290075Sobrien;; :: 32 bit Integer Shifts and Rotates
403390075Sobrien;; ::
403490075Sobrien;; ::::::::::::::::::::
403590075Sobrien
403690075Sobrien(define_expand "ashlsi3"
403790075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
403890075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "")
403990075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
404090075Sobrien  ""
404190075Sobrien{
404290075Sobrien  if (GET_CODE (operands[2]) != CONST_INT)
404390075Sobrien    {
404490075Sobrien      /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED?  Now
404590075Sobrien	 we've got to get rid of stray bits outside the SImode register.  */
404690075Sobrien      rtx subshift = gen_reg_rtx (DImode);
404790075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
404890075Sobrien      operands[2] = subshift;
404990075Sobrien    }
4050117395Skan})
405190075Sobrien
405290075Sobrien(define_insn "*ashlsi3_internal"
405390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
405490075Sobrien	(ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
405590075Sobrien		   (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
405690075Sobrien  ""
405790075Sobrien  "@
405890075Sobrien   shladd %0 = %1, %2, r0
405990075Sobrien   dep.z %0 = %1, %2, %E2
406090075Sobrien   shl %0 = %1, %2"
406190075Sobrien  [(set_attr "itanium_class" "ialu,ishf,mmshf")])
406290075Sobrien
406390075Sobrien(define_expand "ashrsi3"
406490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
406590075Sobrien	(ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
406690075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
406790075Sobrien  ""
406890075Sobrien{
406990075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
407090075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
407190075Sobrien    emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
407290075Sobrien			 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
407390075Sobrien  else
407490075Sobrien    {
407590075Sobrien      rtx subshift = gen_reg_rtx (DImode);
407690075Sobrien      emit_insn (gen_extendsidi2 (subtarget, operands[1]));
407790075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
407890075Sobrien      emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
407990075Sobrien    }
408090075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
408190075Sobrien  DONE;
4082117395Skan})
408390075Sobrien
408490075Sobrien(define_expand "lshrsi3"
408590075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
408690075Sobrien	(lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
408790075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
408890075Sobrien  ""
408990075Sobrien{
409090075Sobrien  rtx subtarget = gen_reg_rtx (DImode);
409190075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
409290075Sobrien    emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
409390075Sobrien			  GEN_INT (32 - INTVAL (operands[2])), operands[2]));
409490075Sobrien  else
409590075Sobrien    {
409690075Sobrien      rtx subshift = gen_reg_rtx (DImode);
409790075Sobrien      emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
409890075Sobrien      emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
409990075Sobrien      emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
410090075Sobrien    }
410190075Sobrien  emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
410290075Sobrien  DONE;
4103117395Skan})
410490075Sobrien
410590075Sobrien;; Use mix4.r/shr to implement rotrsi3.  We only get 32 bits of valid result
410690075Sobrien;; here, instead of 64 like the patterns above.  Keep the pattern together
410790075Sobrien;; until after combine; otherwise it won't get matched often.
410890075Sobrien
410990075Sobrien(define_expand "rotrsi3"
411090075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
411190075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
411290075Sobrien		     (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
411390075Sobrien  ""
411490075Sobrien{
411590075Sobrien  if (GET_MODE (operands[2]) != VOIDmode)
411690075Sobrien    {
411790075Sobrien      rtx tmp = gen_reg_rtx (DImode);
411890075Sobrien      emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
411990075Sobrien      operands[2] = tmp;
412090075Sobrien    }
4121117395Skan})
412290075Sobrien
412390075Sobrien(define_insn_and_split "*rotrsi3_internal"
412490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=&r")
412590075Sobrien	(rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
412690075Sobrien		     (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
412790075Sobrien  ""
412890075Sobrien  "#"
412990075Sobrien  "reload_completed"
413090075Sobrien  [(set (match_dup 3)
413190075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
413290075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
413390075Sobrien   (set (match_dup 3)
413490075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
413590075Sobrien  "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
413690075Sobrien
413790075Sobrien(define_expand "rotlsi3"
413890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "")
413990075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "")
414090075Sobrien		   (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
414190075Sobrien  ""
414290075Sobrien{
414390075Sobrien  if (! shift_32bit_count_operand (operands[2], SImode))
414490075Sobrien    {
414590075Sobrien      rtx tmp = gen_reg_rtx (SImode);
414690075Sobrien      emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
414790075Sobrien      emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
414890075Sobrien      DONE;
414990075Sobrien    }
4150117395Skan})
415190075Sobrien
415290075Sobrien(define_insn_and_split "*rotlsi3_internal"
415390075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
415490075Sobrien	(rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
415590075Sobrien		   (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
415690075Sobrien  ""
415790075Sobrien  "#"
415890075Sobrien  "reload_completed"
415990075Sobrien  [(set (match_dup 3)
416090075Sobrien	(ior:DI (zero_extend:DI (match_dup 1))
416190075Sobrien		(ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
416290075Sobrien   (set (match_dup 3)
416390075Sobrien	(lshiftrt:DI (match_dup 3) (match_dup 2)))]
4164117395Skan{
4165117395Skan  operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
4166117395Skan  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4167117395Skan})
416890075Sobrien
416990075Sobrien;; ::::::::::::::::::::
417090075Sobrien;; ::
417190075Sobrien;; :: 64 bit Integer Shifts and Rotates
417290075Sobrien;; ::
417390075Sobrien;; ::::::::::::::::::::
417490075Sobrien
417590075Sobrien(define_insn "ashldi3"
417690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
417790075Sobrien	(ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
417890075Sobrien		   (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
417990075Sobrien  ""
418090075Sobrien  "@
418190075Sobrien   shladd %0 = %1, %2, r0
418290075Sobrien   shl %0 = %1, %2
418390075Sobrien   shl %0 = %1, %2"
418490075Sobrien  [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
418590075Sobrien
418690075Sobrien;; ??? Maybe combine this with the multiply and add instruction?
418790075Sobrien
418890075Sobrien(define_insn "*shladd"
418990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
419090075Sobrien	(plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
419190075Sobrien			  (match_operand:DI 2 "shladd_operand" "n"))
419290075Sobrien		 (match_operand:DI 3 "gr_register_operand" "r")))]
419390075Sobrien  ""
419490075Sobrien  "shladd %0 = %1, %S2, %3"
419590075Sobrien  [(set_attr "itanium_class" "ialu")])
419690075Sobrien
419790075Sobrien;; This can be created by register elimination if operand3 of shladd is an
419890075Sobrien;; eliminable register or has reg_equiv_constant set.
419990075Sobrien
420090075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the
420190075Sobrien;; validate_changes call inside eliminate_regs will always succeed.  If it
420290075Sobrien;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
420390075Sobrien;; incorrectly.
420490075Sobrien
420590075Sobrien(define_insn_and_split "*shladd_elim"
420690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=&r")
420790075Sobrien	(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
420890075Sobrien				   (match_operand:DI 2 "shladd_operand" "n"))
420990075Sobrien			  (match_operand:DI 3 "nonmemory_operand" "r"))
421090075Sobrien		 (match_operand:DI 4 "nonmemory_operand" "rI")))]
421190075Sobrien  "reload_in_progress"
421290075Sobrien  "* abort ();"
421390075Sobrien  "reload_completed"
421490075Sobrien  [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
421590075Sobrien			       (match_dup 3)))
421690075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
421790075Sobrien  ""
421890075Sobrien  [(set_attr "itanium_class" "unknown")])
421990075Sobrien
422090075Sobrien(define_insn "ashrdi3"
422190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
422290075Sobrien	(ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
422390075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
422490075Sobrien  ""
422590075Sobrien  "@
422690075Sobrien   shr %0 = %1, %2
422790075Sobrien   shr %0 = %1, %2"
422890075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
422990075Sobrien
423090075Sobrien(define_insn "lshrdi3"
423190075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
423290075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
423390075Sobrien		     (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
423490075Sobrien  ""
423590075Sobrien  "@
423690075Sobrien   shr.u %0 = %1, %2
423790075Sobrien   shr.u %0 = %1, %2"
423890075Sobrien  [(set_attr "itanium_class" "mmshf,mmshfi")])
423990075Sobrien
424090075Sobrien;; Using a predicate that accepts only constants doesn't work, because optabs
424190075Sobrien;; will load the operand into a register and call the pattern if the predicate
424290075Sobrien;; did not accept it on the first try.  So we use nonmemory_operand and then
424390075Sobrien;; verify that we have an appropriate constant in the expander.
424490075Sobrien
424590075Sobrien(define_expand "rotrdi3"
424690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
424790075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
424890075Sobrien		     (match_operand:DI 2 "nonmemory_operand" "")))]
424990075Sobrien  ""
425090075Sobrien{
425190075Sobrien  if (! shift_count_operand (operands[2], DImode))
425290075Sobrien    FAIL;
4253117395Skan})
425490075Sobrien
425590075Sobrien(define_insn "*rotrdi3_internal"
425690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
425790075Sobrien	(rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
425890075Sobrien		     (match_operand:DI 2 "shift_count_operand" "M")))]
425990075Sobrien  ""
426090075Sobrien  "shrp %0 = %1, %1, %2"
426190075Sobrien  [(set_attr "itanium_class" "ishf")])
426290075Sobrien
426390075Sobrien(define_expand "rotldi3"
426490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "")
426590075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "")
426690075Sobrien		   (match_operand:DI 2 "nonmemory_operand" "")))]
426790075Sobrien  ""
426890075Sobrien{
426990075Sobrien  if (! shift_count_operand (operands[2], DImode))
427090075Sobrien    FAIL;
4271117395Skan})
427290075Sobrien
427390075Sobrien(define_insn "*rotldi3_internal"
427490075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
427590075Sobrien	(rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
427690075Sobrien		   (match_operand:DI 2 "shift_count_operand" "M")))]
427790075Sobrien  ""
427890075Sobrien  "shrp %0 = %1, %1, %e2"
427990075Sobrien  [(set_attr "itanium_class" "ishf")])
428090075Sobrien
428190075Sobrien;; ::::::::::::::::::::
428290075Sobrien;; ::
428390075Sobrien;; :: 32 bit Integer Logical operations
428490075Sobrien;; ::
428590075Sobrien;; ::::::::::::::::::::
428690075Sobrien
428790075Sobrien;; We don't seem to need any other 32-bit logical operations, because gcc
428890075Sobrien;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
428990075Sobrien;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
429090075Sobrien;; This doesn't work for unary logical operations, because we don't call
429190075Sobrien;; apply_distributive_law for them.
429290075Sobrien
429390075Sobrien;; ??? Likewise, this doesn't work for andnot, which isn't handled by
429490075Sobrien;; apply_distributive_law.  We get inefficient code for
429590075Sobrien;; int sub4 (int i, int j) { return i & ~j; }
429690075Sobrien;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
429790075Sobrien;; (zero_extend (and (not A) B)) in combine.
429890075Sobrien;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
429990075Sobrien;; one_cmplsi2 pattern.
430090075Sobrien
430190075Sobrien(define_insn "one_cmplsi2"
430290075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
430390075Sobrien	(not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
430490075Sobrien  ""
430590075Sobrien  "andcm %0 = -1, %1"
430690075Sobrien  [(set_attr "itanium_class" "ilog")])
430790075Sobrien
430890075Sobrien;; ::::::::::::::::::::
430990075Sobrien;; ::
431090075Sobrien;; :: 64 bit Integer Logical operations
431190075Sobrien;; ::
431290075Sobrien;; ::::::::::::::::::::
431390075Sobrien
431490075Sobrien(define_insn "anddi3"
431590075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
431690075Sobrien	(and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
431790075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
431890075Sobrien  ""
431990075Sobrien  "@
432090075Sobrien   and %0 = %2, %1
432190075Sobrien   fand %0 = %2, %1"
432290075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
432390075Sobrien
432490075Sobrien(define_insn "*andnot"
432590075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
432690075Sobrien	(and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
432790075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
432890075Sobrien  ""
432990075Sobrien  "@
433090075Sobrien   andcm %0 = %2, %1
433190075Sobrien   fandcm %0 = %2, %1"
433290075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
433390075Sobrien
433490075Sobrien(define_insn "iordi3"
433590075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
433690075Sobrien	(ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
433790075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
433890075Sobrien  ""
433990075Sobrien  "@
434090075Sobrien   or %0 = %2, %1
434190075Sobrien   for %0 = %2, %1"
434290075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
434390075Sobrien
434490075Sobrien(define_insn "xordi3"
434590075Sobrien  [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
434690075Sobrien	(xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
434790075Sobrien		(match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
434890075Sobrien  ""
434990075Sobrien  "@
435090075Sobrien   xor %0 = %2, %1
435190075Sobrien   fxor %0 = %2, %1"
435290075Sobrien  [(set_attr "itanium_class" "ilog,fmisc")])
435390075Sobrien
435490075Sobrien(define_insn "one_cmpldi2"
435590075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
435690075Sobrien	(not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
435790075Sobrien  ""
435890075Sobrien  "andcm %0 = -1, %1"
435990075Sobrien  [(set_attr "itanium_class" "ilog")])
436090075Sobrien
436190075Sobrien;; ::::::::::::::::::::
436290075Sobrien;; ::
436390075Sobrien;; :: Comparisons
436490075Sobrien;; ::
436590075Sobrien;; ::::::::::::::::::::
436690075Sobrien
436790075Sobrien(define_expand "cmpbi"
436890075Sobrien  [(set (cc0)
436990075Sobrien        (compare (match_operand:BI 0 "register_operand" "")
437090075Sobrien  		 (match_operand:BI 1 "const_int_operand" "")))]
437190075Sobrien  ""
437290075Sobrien{
437390075Sobrien  ia64_compare_op0 = operands[0];
437490075Sobrien  ia64_compare_op1 = operands[1];
437590075Sobrien  DONE;
4376117395Skan})
437790075Sobrien
437890075Sobrien(define_expand "cmpsi"
437990075Sobrien  [(set (cc0)
438090075Sobrien        (compare (match_operand:SI 0 "gr_register_operand" "")
438190075Sobrien  		 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
438290075Sobrien  ""
438390075Sobrien{
438490075Sobrien  ia64_compare_op0 = operands[0];
438590075Sobrien  ia64_compare_op1 = operands[1];
438690075Sobrien  DONE;
4387117395Skan})
438890075Sobrien
438990075Sobrien(define_expand "cmpdi"
439090075Sobrien  [(set (cc0)
439190075Sobrien        (compare (match_operand:DI 0 "gr_register_operand" "")
439290075Sobrien  		 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
439390075Sobrien  ""
439490075Sobrien{
439590075Sobrien  ia64_compare_op0 = operands[0];
439690075Sobrien  ia64_compare_op1 = operands[1];
439790075Sobrien  DONE;
4398117395Skan})
439990075Sobrien
440090075Sobrien(define_expand "cmpsf"
440190075Sobrien  [(set (cc0)
440290075Sobrien        (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
440390075Sobrien  		 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
440490075Sobrien  ""
440590075Sobrien{
440690075Sobrien  ia64_compare_op0 = operands[0];
440790075Sobrien  ia64_compare_op1 = operands[1];
440890075Sobrien  DONE;
4409117395Skan})
441090075Sobrien
441190075Sobrien(define_expand "cmpdf"
441290075Sobrien  [(set (cc0)
441390075Sobrien        (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
441490075Sobrien  		 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
441590075Sobrien  ""
441690075Sobrien{
441790075Sobrien  ia64_compare_op0 = operands[0];
441890075Sobrien  ia64_compare_op1 = operands[1];
441990075Sobrien  DONE;
4420117395Skan})
442190075Sobrien
4422132718Skan(define_expand "cmpxf"
4423132718Skan  [(set (cc0)
4424132718Skan        (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
4425132718Skan  		 (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
4426132718Skan  ""
4427132718Skan{
4428132718Skan  ia64_compare_op0 = operands[0];
4429132718Skan  ia64_compare_op1 = operands[1];
4430132718Skan  DONE;
4431132718Skan})
4432132718Skan
443390075Sobrien(define_expand "cmptf"
443490075Sobrien  [(set (cc0)
4435132718Skan        (compare (match_operand:TF 0 "gr_register_operand" "")
4436132718Skan  		 (match_operand:TF 1 "gr_register_operand" "")))]
4437132718Skan  "TARGET_HPUX"
443890075Sobrien{
443990075Sobrien  ia64_compare_op0 = operands[0];
444090075Sobrien  ia64_compare_op1 = operands[1];
444190075Sobrien  DONE;
4442117395Skan})
444390075Sobrien
444490075Sobrien(define_insn "*cmpsi_normal"
444590075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
444690075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
444790075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
444890075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
444990075Sobrien  ""
445090075Sobrien  "cmp4.%C1 %0, %I0 = %3, %2"
445190075Sobrien  [(set_attr "itanium_class" "icmp")])
445290075Sobrien
445390075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
445490075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
445590075Sobrien
445690075Sobrien(define_insn "*cmpsi_adjusted"
445790075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
445890075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
445990075Sobrien	   [(match_operand:SI 2 "gr_register_operand" "r")
446090075Sobrien	    (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
446190075Sobrien  ""
446290075Sobrien  "cmp4.%C1 %0, %I0 = %r3, %2"
446390075Sobrien  [(set_attr "itanium_class" "icmp")])
446490075Sobrien
446590075Sobrien(define_insn "*cmpdi_normal"
446690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
446790075Sobrien	(match_operator:BI 1 "normal_comparison_operator"
446890075Sobrien	   [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
446990075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
447090075Sobrien  ""
447190075Sobrien  "cmp.%C1 %0, %I0 = %3, %r2"
447290075Sobrien  [(set_attr "itanium_class" "icmp")])
447390075Sobrien
447490075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the
447590075Sobrien;; unsigned comparisons don't accept immediate operands of zero.
447690075Sobrien
447790075Sobrien(define_insn "*cmpdi_adjusted"
447890075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
447990075Sobrien	(match_operator:BI 1 "adjusted_comparison_operator"
448090075Sobrien	   [(match_operand:DI 2 "gr_register_operand" "r")
448190075Sobrien	    (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
448290075Sobrien  ""
448390075Sobrien  "cmp.%C1 %0, %I0 = %r3, %2"
448490075Sobrien  [(set_attr "itanium_class" "icmp")])
448590075Sobrien
448690075Sobrien(define_insn "*cmpsf_internal"
448790075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
448890075Sobrien	(match_operator:BI 1 "comparison_operator"
448990075Sobrien	   [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
449090075Sobrien	    (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
449190075Sobrien  ""
449290075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
449390075Sobrien  [(set_attr "itanium_class" "fcmp")])
449490075Sobrien
449590075Sobrien(define_insn "*cmpdf_internal"
449690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
449790075Sobrien	(match_operator:BI 1 "comparison_operator"
449890075Sobrien	   [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
449990075Sobrien	    (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
450090075Sobrien  ""
450190075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
450290075Sobrien  [(set_attr "itanium_class" "fcmp")])
450390075Sobrien
4504132718Skan(define_insn "*cmpxf_internal"
450590075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
450690075Sobrien	(match_operator:BI 1 "comparison_operator"
4507132718Skan		   [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4508132718Skan		    (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
4509132718Skan  ""
451090075Sobrien  "fcmp.%D1 %0, %I0 = %F2, %F3"
451190075Sobrien  [(set_attr "itanium_class" "fcmp")])
451290075Sobrien
451390075Sobrien;; ??? Can this pattern be generated?
451490075Sobrien
451590075Sobrien(define_insn "*bit_zero"
451690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
451790075Sobrien	(eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
451890075Sobrien				(const_int 1)
451990075Sobrien				(match_operand:DI 2 "immediate_operand" "n"))
452090075Sobrien	       (const_int 0)))]
452190075Sobrien  ""
452290075Sobrien  "tbit.z %0, %I0 = %1, %2"
452390075Sobrien  [(set_attr "itanium_class" "tbit")])
452490075Sobrien
452590075Sobrien(define_insn "*bit_one"
452690075Sobrien  [(set (match_operand:BI 0 "register_operand" "=c")
452790075Sobrien	(ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
452890075Sobrien				(const_int 1)
452990075Sobrien				(match_operand:DI 2 "immediate_operand" "n"))
453090075Sobrien	       (const_int 0)))]
453190075Sobrien  ""
453290075Sobrien  "tbit.nz %0, %I0 = %1, %2"
453390075Sobrien  [(set_attr "itanium_class" "tbit")])
453490075Sobrien
453590075Sobrien;; ::::::::::::::::::::
453690075Sobrien;; ::
453790075Sobrien;; :: Branches
453890075Sobrien;; ::
453990075Sobrien;; ::::::::::::::::::::
454090075Sobrien
454190075Sobrien(define_expand "beq"
454290075Sobrien  [(set (pc)
454390075Sobrien	(if_then_else (match_dup 1)
454490075Sobrien		      (label_ref (match_operand 0 "" ""))
454590075Sobrien		      (pc)))]
454690075Sobrien  ""
454790075Sobrien  "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
454890075Sobrien
454990075Sobrien(define_expand "bne"
455090075Sobrien  [(set (pc)
455190075Sobrien	(if_then_else (match_dup 1)
455290075Sobrien		      (label_ref (match_operand 0 "" ""))
455390075Sobrien		      (pc)))]
455490075Sobrien  ""
455590075Sobrien  "operands[1] = ia64_expand_compare (NE, VOIDmode);")
455690075Sobrien
455790075Sobrien(define_expand "blt"
455890075Sobrien  [(set (pc)
455990075Sobrien	(if_then_else (match_dup 1)
456090075Sobrien		      (label_ref (match_operand 0 "" ""))
456190075Sobrien		      (pc)))]
456290075Sobrien  ""
456390075Sobrien  "operands[1] = ia64_expand_compare (LT, VOIDmode);")
456490075Sobrien
456590075Sobrien(define_expand "ble"
456690075Sobrien  [(set (pc)
456790075Sobrien	(if_then_else (match_dup 1)
456890075Sobrien		      (label_ref (match_operand 0 "" ""))
456990075Sobrien		      (pc)))]
457090075Sobrien  ""
457190075Sobrien  "operands[1] = ia64_expand_compare (LE, VOIDmode);")
457290075Sobrien
457390075Sobrien(define_expand "bgt"
457490075Sobrien  [(set (pc)
457590075Sobrien	(if_then_else (match_dup 1)
457690075Sobrien		      (label_ref (match_operand 0 "" ""))
457790075Sobrien		      (pc)))]
457890075Sobrien  ""
457990075Sobrien  "operands[1] = ia64_expand_compare (GT, VOIDmode);")
458090075Sobrien
458190075Sobrien(define_expand "bge"
458290075Sobrien  [(set (pc)
458390075Sobrien	(if_then_else (match_dup 1)
458490075Sobrien		      (label_ref (match_operand 0 "" ""))
458590075Sobrien		      (pc)))]
458690075Sobrien  ""
458790075Sobrien  "operands[1] = ia64_expand_compare (GE, VOIDmode);")
458890075Sobrien
458990075Sobrien(define_expand "bltu"
459090075Sobrien  [(set (pc)
459190075Sobrien	(if_then_else (match_dup 1)
459290075Sobrien		      (label_ref (match_operand 0 "" ""))
459390075Sobrien		      (pc)))]
459490075Sobrien  ""
459590075Sobrien  "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
459690075Sobrien
459790075Sobrien(define_expand "bleu"
459890075Sobrien  [(set (pc)
459990075Sobrien	(if_then_else (match_dup 1)
460090075Sobrien		      (label_ref (match_operand 0 "" ""))
460190075Sobrien		      (pc)))]
460290075Sobrien  ""
460390075Sobrien  "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
460490075Sobrien
460590075Sobrien(define_expand "bgtu"
460690075Sobrien  [(set (pc)
460790075Sobrien	(if_then_else (match_dup 1)
460890075Sobrien		      (label_ref (match_operand 0 "" ""))
460990075Sobrien		      (pc)))]
461090075Sobrien  ""
461190075Sobrien  "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
461290075Sobrien
461390075Sobrien(define_expand "bgeu"
461490075Sobrien  [(set (pc)
461590075Sobrien	(if_then_else (match_dup 1)
461690075Sobrien		      (label_ref (match_operand 0 "" ""))
461790075Sobrien		      (pc)))]
461890075Sobrien  ""
461990075Sobrien  "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
462090075Sobrien
462190075Sobrien(define_expand "bunordered"
462290075Sobrien  [(set (pc)
462390075Sobrien	(if_then_else (match_dup 1)
462490075Sobrien		      (label_ref (match_operand 0 "" ""))
462590075Sobrien		      (pc)))]
462690075Sobrien  ""
462790075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
462890075Sobrien
462990075Sobrien(define_expand "bordered"
463090075Sobrien  [(set (pc)
463190075Sobrien	(if_then_else (match_dup 1)
463290075Sobrien		      (label_ref (match_operand 0 "" ""))
463390075Sobrien		      (pc)))]
463490075Sobrien  ""
463590075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
463690075Sobrien
463790075Sobrien(define_insn "*br_true"
463890075Sobrien  [(set (pc)
463990075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
464090075Sobrien			[(match_operand:BI 1 "register_operand" "c")
464190075Sobrien			 (const_int 0)])
464290075Sobrien		      (label_ref (match_operand 2 "" ""))
464390075Sobrien		      (pc)))]
464490075Sobrien  ""
464590075Sobrien  "(%J0) br.cond%+ %l2"
464690075Sobrien  [(set_attr "itanium_class" "br")
464790075Sobrien   (set_attr "predicable" "no")])
464890075Sobrien
464990075Sobrien(define_insn "*br_false"
465090075Sobrien  [(set (pc)
465190075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
465290075Sobrien			[(match_operand:BI 1 "register_operand" "c")
465390075Sobrien			 (const_int 0)])
465490075Sobrien		      (pc)
465590075Sobrien		      (label_ref (match_operand 2 "" ""))))]
465690075Sobrien  ""
465790075Sobrien  "(%j0) br.cond%+ %l2"
465890075Sobrien  [(set_attr "itanium_class" "br")
465990075Sobrien   (set_attr "predicable" "no")])
466090075Sobrien
466190075Sobrien;; ::::::::::::::::::::
466290075Sobrien;; ::
466390075Sobrien;; :: Counted loop operations
466490075Sobrien;; ::
466590075Sobrien;; ::::::::::::::::::::
466690075Sobrien
466790075Sobrien(define_expand "doloop_end"
466890075Sobrien  [(use (match_operand 0 "" ""))	; loop pseudo
466990075Sobrien   (use (match_operand 1 "" ""))	; iterations; zero if unknown
467090075Sobrien   (use (match_operand 2 "" ""))	; max iterations
467190075Sobrien   (use (match_operand 3 "" ""))	; loop level
467290075Sobrien   (use (match_operand 4 "" ""))]	; label
467390075Sobrien  ""
467490075Sobrien{
467590075Sobrien  /* Only use cloop on innermost loops.  */
467690075Sobrien  if (INTVAL (operands[3]) > 1)
467790075Sobrien    FAIL;
467890075Sobrien  emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
467990075Sobrien					   operands[4]));
468090075Sobrien  DONE;
4681117395Skan})
468290075Sobrien
468390075Sobrien(define_insn "doloop_end_internal"
468490075Sobrien  [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
468590075Sobrien			       (const_int 0))
468690075Sobrien		(label_ref (match_operand 1 "" ""))
468790075Sobrien		(pc)))
468890075Sobrien   (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
4689117395Skan			 (plus:DI (match_dup 0) (const_int -1))
4690117395Skan			 (match_dup 0)))]
469190075Sobrien  ""
469290075Sobrien  "br.cloop.sptk.few %l1"
469390075Sobrien  [(set_attr "itanium_class" "br")
469490075Sobrien   (set_attr "predicable" "no")])
469590075Sobrien
469690075Sobrien;; ::::::::::::::::::::
469790075Sobrien;; ::
469890075Sobrien;; :: Set flag operations
469990075Sobrien;; ::
470090075Sobrien;; ::::::::::::::::::::
470190075Sobrien
470290075Sobrien(define_expand "seq"
470390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
470490075Sobrien  ""
470590075Sobrien  "operands[1] = ia64_expand_compare (EQ, DImode);")
470690075Sobrien
470790075Sobrien(define_expand "sne"
470890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
470990075Sobrien  ""
471090075Sobrien  "operands[1] = ia64_expand_compare (NE, DImode);")
471190075Sobrien
471290075Sobrien(define_expand "slt"
471390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
471490075Sobrien  ""
471590075Sobrien  "operands[1] = ia64_expand_compare (LT, DImode);")
471690075Sobrien
471790075Sobrien(define_expand "sle"
471890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
471990075Sobrien  ""
472090075Sobrien  "operands[1] = ia64_expand_compare (LE, DImode);")
472190075Sobrien
472290075Sobrien(define_expand "sgt"
472390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
472490075Sobrien  ""
472590075Sobrien  "operands[1] = ia64_expand_compare (GT, DImode);")
472690075Sobrien
472790075Sobrien(define_expand "sge"
472890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
472990075Sobrien  ""
473090075Sobrien  "operands[1] = ia64_expand_compare (GE, DImode);")
473190075Sobrien
473290075Sobrien(define_expand "sltu"
473390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
473490075Sobrien  ""
473590075Sobrien  "operands[1] = ia64_expand_compare (LTU, DImode);")
473690075Sobrien
473790075Sobrien(define_expand "sleu"
473890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
473990075Sobrien  ""
474090075Sobrien  "operands[1] = ia64_expand_compare (LEU, DImode);")
474190075Sobrien
474290075Sobrien(define_expand "sgtu"
474390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
474490075Sobrien  ""
474590075Sobrien  "operands[1] = ia64_expand_compare (GTU, DImode);")
474690075Sobrien
474790075Sobrien(define_expand "sgeu"
474890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
474990075Sobrien  ""
475090075Sobrien  "operands[1] = ia64_expand_compare (GEU, DImode);")
475190075Sobrien
475290075Sobrien(define_expand "sunordered"
475390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
475490075Sobrien  ""
475590075Sobrien  "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
475690075Sobrien
475790075Sobrien(define_expand "sordered"
475890075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
475990075Sobrien  ""
476090075Sobrien  "operands[1] = ia64_expand_compare (ORDERED, DImode);")
476190075Sobrien
476290075Sobrien;; Don't allow memory as destination here, because cmov/cmov/st is more
476390075Sobrien;; efficient than mov/mov/cst/cst.
476490075Sobrien
476590075Sobrien(define_insn_and_split "*sne_internal"
476690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
476790075Sobrien	(ne:DI (match_operand:BI 1 "register_operand" "c")
476890075Sobrien	       (const_int 0)))]
476990075Sobrien  ""
477090075Sobrien  "#"
477190075Sobrien  "reload_completed"
477290075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
477390075Sobrien     (set (match_dup 0) (const_int 1)))
477490075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
477590075Sobrien     (set (match_dup 0) (const_int 0)))]
477690075Sobrien  ""
477790075Sobrien  [(set_attr "itanium_class" "unknown")])
477890075Sobrien
477990075Sobrien(define_insn_and_split "*seq_internal"
478090075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
478190075Sobrien	(eq:DI (match_operand:BI 1 "register_operand" "c")
478290075Sobrien	       (const_int 0)))]
478390075Sobrien  ""
478490075Sobrien  "#"
478590075Sobrien  "reload_completed"
478690075Sobrien  [(cond_exec (ne (match_dup 1) (const_int 0))
478790075Sobrien     (set (match_dup 0) (const_int 0)))
478890075Sobrien   (cond_exec (eq (match_dup 1) (const_int 0))
478990075Sobrien     (set (match_dup 0) (const_int 1)))]
479090075Sobrien  ""
479190075Sobrien  [(set_attr "itanium_class" "unknown")])
479290075Sobrien
479390075Sobrien;; ::::::::::::::::::::
479490075Sobrien;; ::
479590075Sobrien;; :: Conditional move instructions.
479690075Sobrien;; ::
479790075Sobrien;; ::::::::::::::::::::
479890075Sobrien
479990075Sobrien;; ??? Add movXXcc patterns?
480090075Sobrien
480190075Sobrien;;
480290075Sobrien;; DImode if_then_else patterns.
480390075Sobrien;;
480490075Sobrien
480590075Sobrien(define_insn "*cmovdi_internal"
480690075Sobrien  [(set (match_operand:DI 0 "destination_operand"
480790075Sobrien	   "= r,  r,  r,   r,  r,  r,   r, r, r,   r, m, Q, *f,*b,*d*e")
480890075Sobrien	(if_then_else:DI
480990075Sobrien	  (match_operator 4 "predicate_operator"
481090075Sobrien	    [(match_operand:BI 1 "register_operand"
481190075Sobrien		"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
481290075Sobrien	     (const_int 0)])
481390075Sobrien	  (match_operand:DI 2 "move_operand"
4814132718Skan	   "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")
481590075Sobrien	  (match_operand:DI 3 "move_operand"
4816132718Skan	   "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO,  rK")))]
481790075Sobrien  "ia64_move_ok (operands[0], operands[2])
481890075Sobrien   && ia64_move_ok (operands[0], operands[3])"
4819117395Skan  { abort (); }
482090075Sobrien  [(set_attr "predicable" "no")])
482190075Sobrien
482290075Sobrien(define_split
482390075Sobrien  [(set (match_operand 0 "destination_operand" "")
482490075Sobrien	(if_then_else
482590075Sobrien	  (match_operator 4 "predicate_operator"
482690075Sobrien	    [(match_operand:BI 1 "register_operand" "")
482790075Sobrien	     (const_int 0)])
482890075Sobrien	  (match_operand 2 "move_operand" "")
482990075Sobrien	  (match_operand 3 "move_operand" "")))]
483090075Sobrien  "reload_completed"
483190075Sobrien  [(const_int 0)]
483290075Sobrien{
4833132718Skan  bool emitted_something = false;
4834132718Skan  rtx dest = operands[0];
4835132718Skan  rtx srct = operands[2];
4836132718Skan  rtx srcf = operands[3];
4837132718Skan  rtx cond = operands[4];
4838117395Skan
4839132718Skan  if (! rtx_equal_p (dest, srct))
484090075Sobrien    {
4841132718Skan      ia64_emit_cond_move (dest, srct, cond);
4842132718Skan      emitted_something = true;
484390075Sobrien    }
4844132718Skan  if (! rtx_equal_p (dest, srcf))
484590075Sobrien    {
4846132718Skan      cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
4847132718Skan 			     VOIDmode, operands[1], const0_rtx);
4848132718Skan      ia64_emit_cond_move (dest, srcf, cond);
4849132718Skan      emitted_something = true;
485090075Sobrien    }
4851117395Skan  if (! emitted_something)
4852132718Skan    emit_note (NOTE_INSN_DELETED);
485390075Sobrien  DONE;
4854117395Skan})
485590075Sobrien
485690075Sobrien;; Absolute value pattern.
485790075Sobrien
485890075Sobrien(define_insn "*absdi2_internal"
485990075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
486090075Sobrien	(if_then_else:DI
486190075Sobrien	  (match_operator 4 "predicate_operator"
486290075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
486390075Sobrien	     (const_int 0)])
486490075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
486590075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
486690075Sobrien  ""
486790075Sobrien  "#"
486890075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
486990075Sobrien   (set_attr "predicable" "no")])
487090075Sobrien
487190075Sobrien(define_split
487290075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
487390075Sobrien	(if_then_else:DI
487490075Sobrien	  (match_operator 4 "predicate_operator"
487590075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
487690075Sobrien	     (const_int 0)])
487790075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
487890075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
487990075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
488090075Sobrien  [(cond_exec
488190075Sobrien     (match_dup 4)
488290075Sobrien     (set (match_dup 0)
488390075Sobrien	  (neg:DI (match_dup 2))))]
488490075Sobrien  "")
488590075Sobrien
488690075Sobrien(define_split
488790075Sobrien  [(set (match_operand:DI 0 "register_operand" "")
488890075Sobrien	(if_then_else:DI
488990075Sobrien	  (match_operator 4 "predicate_operator"
489090075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
489190075Sobrien	     (const_int 0)])
489290075Sobrien	  (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
489390075Sobrien	  (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
489490075Sobrien  "reload_completed"
489590075Sobrien  [(cond_exec
489690075Sobrien     (match_dup 4)
489790075Sobrien     (set (match_dup 0) (neg:DI (match_dup 2))))
489890075Sobrien   (cond_exec
489990075Sobrien     (match_dup 5)
490090075Sobrien     (set (match_dup 0) (match_dup 3)))]
490190075Sobrien{
490290075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
490390075Sobrien				VOIDmode, operands[1], const0_rtx);
4904117395Skan})
490590075Sobrien
490690075Sobrien;;
490790075Sobrien;; SImode if_then_else patterns.
490890075Sobrien;;
490990075Sobrien
491090075Sobrien(define_insn "*cmovsi_internal"
491190075Sobrien  [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
491290075Sobrien	(if_then_else:SI
491390075Sobrien	  (match_operator 4 "predicate_operator"
491490075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
491590075Sobrien	     (const_int 0)])
491690075Sobrien	  (match_operand:SI 2 "move_operand"
4917132718Skan		    "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
491890075Sobrien	  (match_operand:SI 3 "move_operand"
4919132718Skan		    "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
492090075Sobrien  "ia64_move_ok (operands[0], operands[2])
492190075Sobrien   && ia64_move_ok (operands[0], operands[3])"
4922117395Skan  { abort (); }
492390075Sobrien  [(set_attr "predicable" "no")])
492490075Sobrien
492590075Sobrien(define_insn "*abssi2_internal"
492690075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
492790075Sobrien	(if_then_else:SI
492890075Sobrien	  (match_operator 4 "predicate_operator"
492990075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
493090075Sobrien	     (const_int 0)])
493190075Sobrien	  (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
493290075Sobrien	  (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
493390075Sobrien  ""
493490075Sobrien  "#"
493590075Sobrien  [(set_attr "itanium_class" "ialu,unknown")
493690075Sobrien   (set_attr "predicable" "no")])
493790075Sobrien
493890075Sobrien(define_split
493990075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
494090075Sobrien	(if_then_else:SI
494190075Sobrien	  (match_operator 4 "predicate_operator"
494290075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
494390075Sobrien	     (const_int 0)])
494490075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
494590075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
494690075Sobrien  "reload_completed && rtx_equal_p (operands[0], operands[3])"
494790075Sobrien  [(cond_exec
494890075Sobrien     (match_dup 4)
494990075Sobrien     (set (match_dup 0)
495090075Sobrien	  (neg:SI (match_dup 2))))]
495190075Sobrien  "")
495290075Sobrien
495390075Sobrien(define_split
495490075Sobrien  [(set (match_operand:SI 0 "register_operand" "")
495590075Sobrien	(if_then_else:SI
495690075Sobrien	  (match_operator 4 "predicate_operator"
495790075Sobrien	    [(match_operand:BI 1 "register_operand" "c,c")
495890075Sobrien	     (const_int 0)])
495990075Sobrien	  (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
496090075Sobrien	  (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
496190075Sobrien  "reload_completed"
496290075Sobrien  [(cond_exec
496390075Sobrien     (match_dup 4)
496490075Sobrien     (set (match_dup 0) (neg:SI (match_dup 2))))
496590075Sobrien   (cond_exec
496690075Sobrien     (match_dup 5)
496790075Sobrien     (set (match_dup 0) (match_dup 3)))]
496890075Sobrien{
496990075Sobrien  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
497090075Sobrien				VOIDmode, operands[1], const0_rtx);
4971117395Skan})
497290075Sobrien
497390075Sobrien(define_insn_and_split "*cond_opsi2_internal"
497490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
497590075Sobrien	(match_operator:SI 5 "condop_operator"
497690075Sobrien	  [(if_then_else:SI
497790075Sobrien	     (match_operator 6 "predicate_operator"
497890075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
497990075Sobrien	        (const_int 0)])
498090075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
498190075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))
498290075Sobrien	   (match_operand:SI 4 "gr_register_operand" "r")]))]
498390075Sobrien  ""
498490075Sobrien  "#"
498590075Sobrien  "reload_completed"
498690075Sobrien  [(cond_exec
498790075Sobrien     (match_dup 6)
498890075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
498990075Sobrien   (cond_exec
499090075Sobrien     (match_dup 7)
499190075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
499290075Sobrien{
499390075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
499490075Sobrien				VOIDmode, operands[1], const0_rtx);
4995117395Skan}
499690075Sobrien  [(set_attr "itanium_class" "ialu")
499790075Sobrien   (set_attr "predicable" "no")])
499890075Sobrien
499990075Sobrien
500090075Sobrien(define_insn_and_split "*cond_opsi2_internal_b"
500190075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
500290075Sobrien	(match_operator:SI 5 "condop_operator"
500390075Sobrien	  [(match_operand:SI 4 "gr_register_operand" "r")
500490075Sobrien	   (if_then_else:SI
500590075Sobrien	     (match_operator 6 "predicate_operator"
500690075Sobrien	       [(match_operand:BI 1 "register_operand" "c")
500790075Sobrien	        (const_int 0)])
500890075Sobrien	     (match_operand:SI 2 "gr_register_operand" "r")
500990075Sobrien	     (match_operand:SI 3 "gr_register_operand" "r"))]))]
501090075Sobrien  ""
501190075Sobrien  "#"
501290075Sobrien  "reload_completed"
501390075Sobrien  [(cond_exec
501490075Sobrien     (match_dup 6)
501590075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
501690075Sobrien   (cond_exec
501790075Sobrien     (match_dup 7)
501890075Sobrien     (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
501990075Sobrien{
502090075Sobrien  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
502190075Sobrien				VOIDmode, operands[1], const0_rtx);
5022117395Skan}
502390075Sobrien  [(set_attr "itanium_class" "ialu")
502490075Sobrien   (set_attr "predicable" "no")])
502590075Sobrien
502690075Sobrien
502790075Sobrien;; ::::::::::::::::::::
502890075Sobrien;; ::
502990075Sobrien;; :: Call and branch instructions
503090075Sobrien;; ::
503190075Sobrien;; ::::::::::::::::::::
503290075Sobrien
503390075Sobrien;; Subroutine call instruction returning no value.  Operand 0 is the function
503490075Sobrien;; to call; operand 1 is the number of bytes of arguments pushed (in mode
503590075Sobrien;; `SImode', except it is normally a `const_int'); operand 2 is the number of
503690075Sobrien;; registers used as operands.
503790075Sobrien
503890075Sobrien;; On most machines, operand 2 is not actually stored into the RTL pattern.  It
503990075Sobrien;; is supplied for the sake of some RISC machines which need to put this
504090075Sobrien;; information into the assembler code; they can put it in the RTL instead of
504190075Sobrien;; operand 1.
504290075Sobrien
504390075Sobrien(define_expand "call"
504490075Sobrien  [(use (match_operand:DI 0 "" ""))
504590075Sobrien   (use (match_operand 1 "" ""))
504690075Sobrien   (use (match_operand 2 "" ""))
504790075Sobrien   (use (match_operand 3 "" ""))]
504890075Sobrien  ""
504990075Sobrien{
5050117395Skan  ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
505190075Sobrien  DONE;
5052117395Skan})
505390075Sobrien
505490075Sobrien(define_expand "sibcall"
505590075Sobrien  [(use (match_operand:DI 0 "" ""))
505690075Sobrien   (use (match_operand 1 "" ""))
505790075Sobrien   (use (match_operand 2 "" ""))
505890075Sobrien   (use (match_operand 3 "" ""))]
505990075Sobrien  ""
506090075Sobrien{
5061117395Skan  ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
506290075Sobrien  DONE;
5063117395Skan})
506490075Sobrien
506590075Sobrien;; Subroutine call instruction returning a value.  Operand 0 is the hard
506690075Sobrien;; register in which the value is returned.  There are three more operands,
506790075Sobrien;; the same as the three operands of the `call' instruction (but with numbers
506890075Sobrien;; increased by one).
506990075Sobrien;;
507090075Sobrien;; Subroutines that return `BLKmode' objects use the `call' insn.
507190075Sobrien
507290075Sobrien(define_expand "call_value"
507390075Sobrien  [(use (match_operand 0 "" ""))
507490075Sobrien   (use (match_operand:DI 1 "" ""))
507590075Sobrien   (use (match_operand 2 "" ""))
507690075Sobrien   (use (match_operand 3 "" ""))
507790075Sobrien   (use (match_operand 4 "" ""))]
507890075Sobrien  ""
507990075Sobrien{
5080117395Skan  ia64_expand_call (operands[0], operands[1], operands[3], false);
508190075Sobrien  DONE;
5082117395Skan})
508390075Sobrien
508490075Sobrien(define_expand "sibcall_value"
508590075Sobrien  [(use (match_operand 0 "" ""))
508690075Sobrien   (use (match_operand:DI 1 "" ""))
508790075Sobrien   (use (match_operand 2 "" ""))
508890075Sobrien   (use (match_operand 3 "" ""))
508990075Sobrien   (use (match_operand 4 "" ""))]
509090075Sobrien  ""
509190075Sobrien{
5092117395Skan  ia64_expand_call (operands[0], operands[1], operands[3], true);
509390075Sobrien  DONE;
5094117395Skan})
509590075Sobrien
509690075Sobrien;; Call subroutine returning any type.
509790075Sobrien
509890075Sobrien(define_expand "untyped_call"
509990075Sobrien  [(parallel [(call (match_operand 0 "" "")
510090075Sobrien		    (const_int 0))
510190075Sobrien	      (match_operand 1 "" "")
510290075Sobrien	      (match_operand 2 "" "")])]
510390075Sobrien  ""
510490075Sobrien{
510590075Sobrien  int i;
510690075Sobrien
510790075Sobrien  emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
510890075Sobrien
510990075Sobrien  for (i = 0; i < XVECLEN (operands[2], 0); i++)
511090075Sobrien    {
511190075Sobrien      rtx set = XVECEXP (operands[2], 0, i);
511290075Sobrien      emit_move_insn (SET_DEST (set), SET_SRC (set));
511390075Sobrien    }
511490075Sobrien
511590075Sobrien  /* The optimizer does not know that the call sets the function value
511690075Sobrien     registers we stored in the result block.  We avoid problems by
511790075Sobrien     claiming that all hard registers are used and clobbered at this
511890075Sobrien     point.  */
511990075Sobrien  emit_insn (gen_blockage ());
512090075Sobrien
512190075Sobrien  DONE;
5122117395Skan})
512390075Sobrien
5124117395Skan(define_insn "call_nogp"
5125117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5126117395Skan	 (const_int 0))
5127117395Skan   (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
512890075Sobrien  ""
5129117395Skan  "br.call%+.many %1 = %0"
513090075Sobrien  [(set_attr "itanium_class" "br,scall")])
513190075Sobrien
5132117395Skan(define_insn "call_value_nogp"
5133132718Skan  [(set (match_operand 0 "" "=X,X")
5134117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
5135117395Skan	      (const_int 0)))
5136117395Skan   (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
513790075Sobrien  ""
5138117395Skan  "br.call%+.many %2 = %1"
513990075Sobrien  [(set_attr "itanium_class" "br,scall")])
514090075Sobrien
5141117395Skan(define_insn "sibcall_nogp"
5142117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5143117395Skan	 (const_int 0))]
514490075Sobrien  ""
514590075Sobrien  "br%+.many %0"
514690075Sobrien  [(set_attr "itanium_class" "br,scall")])
514790075Sobrien
5148117395Skan(define_insn "call_gp"
5149132718Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5150117395Skan	 (const_int 1))
5151117395Skan   (clobber (match_operand:DI 1 "register_operand" "=b,b"))
5152117395Skan   (clobber (match_scratch:DI 2 "=&r,X"))
5153117395Skan   (clobber (match_scratch:DI 3 "=b,X"))]
515490075Sobrien  ""
5155117395Skan  "#"
515690075Sobrien  [(set_attr "itanium_class" "br,scall")])
515790075Sobrien
5158117395Skan;; Irritatingly, we don't have access to INSN within the split body.
5159117395Skan;; See commentary in ia64_split_call as to why these aren't peep2.
5160117395Skan(define_split
5161117395Skan  [(call (mem (match_operand 0 "call_operand" ""))
5162117395Skan	 (const_int 1))
5163117395Skan   (clobber (match_operand:DI 1 "register_operand" ""))
5164117395Skan   (clobber (match_scratch:DI 2 ""))
5165117395Skan   (clobber (match_scratch:DI 3 ""))]
5166117395Skan  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5167117395Skan  [(const_int 0)]
5168117395Skan{
5169117395Skan  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5170117395Skan		   operands[3], true, false);
5171117395Skan  DONE;
5172117395Skan})
5173117395Skan
5174117395Skan(define_split
5175117395Skan  [(call (mem (match_operand 0 "call_operand" ""))
5176117395Skan	 (const_int 1))
5177117395Skan   (clobber (match_operand:DI 1 "register_operand" ""))
5178117395Skan   (clobber (match_scratch:DI 2 ""))
5179117395Skan   (clobber (match_scratch:DI 3 ""))]
5180117395Skan  "reload_completed"
5181117395Skan  [(const_int 0)]
5182117395Skan{
5183117395Skan  ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5184117395Skan		   operands[3], false, false);
5185117395Skan  DONE;
5186117395Skan})
5187117395Skan
5188117395Skan(define_insn "call_value_gp"
5189132718Skan  [(set (match_operand 0 "" "=X,X")
5190117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
5191117395Skan	      (const_int 1)))
5192117395Skan   (clobber (match_operand:DI 2 "register_operand" "=b,b"))
5193117395Skan   (clobber (match_scratch:DI 3 "=&r,X"))
5194117395Skan   (clobber (match_scratch:DI 4 "=b,X"))]
519590075Sobrien  ""
5196117395Skan  "#"
519790075Sobrien  [(set_attr "itanium_class" "br,scall")])
519890075Sobrien
5199117395Skan(define_split
5200117395Skan  [(set (match_operand 0 "" "")
5201117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
5202117395Skan	      (const_int 1)))
5203117395Skan   (clobber (match_operand:DI 2 "register_operand" ""))
5204117395Skan   (clobber (match_scratch:DI 3 ""))
5205117395Skan   (clobber (match_scratch:DI 4 ""))]
5206117395Skan  "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5207117395Skan  [(const_int 0)]
5208117395Skan{
5209117395Skan  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5210117395Skan		   operands[4], true, false);
5211117395Skan  DONE;
5212117395Skan})
5213117395Skan
5214117395Skan(define_split
5215117395Skan  [(set (match_operand 0 "" "")
5216117395Skan	(call (mem:DI (match_operand:DI 1 "call_operand" ""))
5217117395Skan	      (const_int 1)))
5218117395Skan   (clobber (match_operand:DI 2 "register_operand" ""))
5219117395Skan   (clobber (match_scratch:DI 3 ""))
5220117395Skan   (clobber (match_scratch:DI 4 ""))]
5221117395Skan  "reload_completed"
5222117395Skan  [(const_int 0)]
5223117395Skan{
5224117395Skan  ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5225117395Skan		   operands[4], false, false);
5226117395Skan  DONE;
5227117395Skan})
5228117395Skan
5229117395Skan(define_insn_and_split "sibcall_gp"
5230117395Skan  [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5231117395Skan	 (const_int 1))
5232117395Skan   (clobber (match_scratch:DI 1 "=&r,X"))
5233117395Skan   (clobber (match_scratch:DI 2 "=b,X"))]
523490075Sobrien  ""
5235117395Skan  "#"
5236117395Skan  "reload_completed"
5237117395Skan  [(const_int 0)]
5238117395Skan{
5239117395Skan  ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
5240117395Skan		   operands[2], true, true);
5241117395Skan  DONE;
5242117395Skan}
524390075Sobrien  [(set_attr "itanium_class" "br")])
524490075Sobrien
524590075Sobrien(define_insn "return_internal"
524690075Sobrien  [(return)
524790075Sobrien   (use (match_operand:DI 0 "register_operand" "b"))]
524890075Sobrien  ""
524990075Sobrien  "br.ret.sptk.many %0"
525090075Sobrien  [(set_attr "itanium_class" "br")])
525190075Sobrien
525290075Sobrien(define_insn "return"
525390075Sobrien  [(return)]
525490075Sobrien  "ia64_direct_return ()"
525590075Sobrien  "br.ret.sptk.many rp"
525690075Sobrien  [(set_attr "itanium_class" "br")])
525790075Sobrien
525890075Sobrien(define_insn "*return_true"
525990075Sobrien  [(set (pc)
526090075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
526190075Sobrien			[(match_operand:BI 1 "register_operand" "c")
526290075Sobrien			 (const_int 0)])
526390075Sobrien		      (return)
526490075Sobrien		      (pc)))]
526590075Sobrien  "ia64_direct_return ()"
526690075Sobrien  "(%J0) br.ret%+.many rp"
526790075Sobrien  [(set_attr "itanium_class" "br")
526890075Sobrien   (set_attr "predicable" "no")])
526990075Sobrien
527090075Sobrien(define_insn "*return_false"
527190075Sobrien  [(set (pc)
527290075Sobrien	(if_then_else (match_operator 0 "predicate_operator"
527390075Sobrien			[(match_operand:BI 1 "register_operand" "c")
527490075Sobrien			 (const_int 0)])
527590075Sobrien		      (pc)
527690075Sobrien		      (return)))]
527790075Sobrien  "ia64_direct_return ()"
527890075Sobrien  "(%j0) br.ret%+.many rp"
527990075Sobrien  [(set_attr "itanium_class" "br")
528090075Sobrien   (set_attr "predicable" "no")])
528190075Sobrien
528290075Sobrien(define_insn "jump"
528390075Sobrien  [(set (pc) (label_ref (match_operand 0 "" "")))]
528490075Sobrien  ""
528590075Sobrien  "br %l0"
528690075Sobrien  [(set_attr "itanium_class" "br")])
528790075Sobrien
528890075Sobrien(define_insn "indirect_jump"
528990075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
529090075Sobrien  ""
529190075Sobrien  "br %0"
529290075Sobrien  [(set_attr "itanium_class" "br")])
529390075Sobrien
529490075Sobrien(define_expand "tablejump"
529590075Sobrien  [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
529690075Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
529790075Sobrien  ""
529890075Sobrien{
529990075Sobrien  rtx op0 = operands[0];
530090075Sobrien  rtx addr;
530190075Sobrien
530290075Sobrien  /* ??? Bother -- do_tablejump is "helpful" and pulls the table
530390075Sobrien     element into a register without bothering to see whether that
530490075Sobrien     is necessary given the operand predicate.  Check for MEM just
530590075Sobrien     in case someone fixes this.  */
530690075Sobrien  if (GET_CODE (op0) == MEM)
530790075Sobrien    addr = XEXP (op0, 0);
530890075Sobrien  else
530990075Sobrien    {
531090075Sobrien      /* Otherwise, cheat and guess that the previous insn in the
531190075Sobrien	 stream was the memory load.  Grab the address from that.
531290075Sobrien	 Note we have to momentarily pop out of the sequence started
531390075Sobrien	 by the insn-emit wrapper in order to grab the last insn.  */
531490075Sobrien      rtx last, set;
531590075Sobrien
531690075Sobrien      end_sequence ();
531790075Sobrien      last = get_last_insn ();
531890075Sobrien      start_sequence ();
531990075Sobrien      set = single_set (last);
532090075Sobrien
532190075Sobrien      if (! rtx_equal_p (SET_DEST (set), op0)
532290075Sobrien	  || GET_CODE (SET_SRC (set)) != MEM)
532390075Sobrien	abort ();
532490075Sobrien      addr = XEXP (SET_SRC (set), 0);
532590075Sobrien      if (rtx_equal_p (addr, op0))
532690075Sobrien	abort ();
532790075Sobrien    }
532890075Sobrien
532990075Sobrien  /* Jump table elements are stored pc-relative.  That is, a displacement
533090075Sobrien     from the entry to the label.  Thus to convert to an absolute address
533190075Sobrien     we add the address of the memory from which the value is loaded.  */
533290075Sobrien  operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
533390075Sobrien				     NULL_RTX, 1, OPTAB_DIRECT);
533490075Sobrien})
533590075Sobrien
533690075Sobrien(define_insn "*tablejump_internal"
533790075Sobrien  [(set (pc) (match_operand:DI 0 "register_operand" "b"))
533890075Sobrien   (use (label_ref (match_operand 1 "" "")))]
533990075Sobrien  ""
534090075Sobrien  "br %0"
534190075Sobrien  [(set_attr "itanium_class" "br")])
534290075Sobrien
534390075Sobrien
534490075Sobrien;; ::::::::::::::::::::
534590075Sobrien;; ::
534690075Sobrien;; :: Prologue and Epilogue instructions
534790075Sobrien;; ::
534890075Sobrien;; ::::::::::::::::::::
534990075Sobrien
535090075Sobrien(define_expand "prologue"
535190075Sobrien  [(const_int 1)]
535290075Sobrien  ""
535390075Sobrien{
535490075Sobrien  ia64_expand_prologue ();
535590075Sobrien  DONE;
5356117395Skan})
535790075Sobrien
535890075Sobrien(define_expand "epilogue"
535990075Sobrien  [(return)]
536090075Sobrien  ""
536190075Sobrien{
536290075Sobrien  ia64_expand_epilogue (0);
536390075Sobrien  DONE;
5364117395Skan})
536590075Sobrien
536690075Sobrien(define_expand "sibcall_epilogue"
536790075Sobrien  [(return)]
536890075Sobrien  ""
536990075Sobrien{
537090075Sobrien  ia64_expand_epilogue (1);
537190075Sobrien  DONE;
5372117395Skan})
537390075Sobrien
537490075Sobrien;; This prevents the scheduler from moving the SP decrement past FP-relative
537590075Sobrien;; stack accesses.  This is the same as adddi3 plus the extra set.
537690075Sobrien
537790075Sobrien(define_insn "prologue_allocate_stack"
537890075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
537990075Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
538090075Sobrien		 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
538196263Sobrien   (set (match_operand:DI 3 "register_operand" "+r,r,r")
538290075Sobrien	(match_dup 3))]
538390075Sobrien  ""
538490075Sobrien  "@
5385117395Skan   add %0 = %1, %2
5386117395Skan   adds %0 = %2, %1
5387117395Skan   addl %0 = %2, %1"
538890075Sobrien  [(set_attr "itanium_class" "ialu")])
538990075Sobrien
539090075Sobrien;; This prevents the scheduler from moving the SP restore past FP-relative
539190075Sobrien;; stack accesses.  This is similar to movdi plus the extra set.
539290075Sobrien
539390075Sobrien(define_insn "epilogue_deallocate_stack"
539490075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
539590075Sobrien	(match_operand:DI 1 "register_operand" "+r"))
539690075Sobrien   (set (match_dup 1) (match_dup 1))]
539790075Sobrien  ""
539890075Sobrien  "mov %0 = %1"
539990075Sobrien  [(set_attr "itanium_class" "ialu")])
540090075Sobrien
5401117395Skan;; As USE insns aren't meaningful after reload, this is used instead
5402117395Skan;; to prevent deleting instructions setting registers for EH handling
5403117395Skan(define_insn "prologue_use"
5404117395Skan  [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
5405117395Skan	      UNSPEC_PROLOGUE_USE)]
5406117395Skan  ""
5407117395Skan  ""
5408117395Skan  [(set_attr "itanium_class" "ignore")
5409132718Skan   (set_attr "predicable" "no")
5410132718Skan   (set_attr "empty" "yes")])
5411117395Skan
541290075Sobrien;; Allocate a new register frame.
541390075Sobrien
541490075Sobrien(define_insn "alloc"
541590075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
5416117395Skan	(unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
541790075Sobrien   (use (match_operand:DI 1 "const_int_operand" "i"))
541890075Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
541990075Sobrien   (use (match_operand:DI 3 "const_int_operand" "i"))
542090075Sobrien   (use (match_operand:DI 4 "const_int_operand" "i"))]
542190075Sobrien  ""
542290075Sobrien  "alloc %0 = ar.pfs, %1, %2, %3, %4"
542390075Sobrien  [(set_attr "itanium_class" "syst_m0")
542490075Sobrien   (set_attr "predicable" "no")])
542590075Sobrien
542690075Sobrien;; Modifies ar.unat
542790075Sobrien(define_expand "gr_spill"
542890075Sobrien  [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
542990075Sobrien		   (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5430117395Skan			       (match_operand:DI 2 "const_int_operand" "")]
5431117395Skan			      UNSPEC_GR_SPILL))
543290075Sobrien	      (clobber (match_dup 3))])]
543390075Sobrien  ""
543490075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
543590075Sobrien
543690075Sobrien(define_insn "gr_spill_internal"
543790075Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
543890075Sobrien	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5439117395Skan		    (match_operand:DI 2 "const_int_operand" "")]
5440117395Skan		   UNSPEC_GR_SPILL))
544190075Sobrien   (clobber (match_operand:DI 3 "register_operand" ""))]
544290075Sobrien  ""
544390075Sobrien{
5444117395Skan  /* Note that we use a C output pattern here to avoid the predicate
5445117395Skan     being automatically added before the .mem.offset directive.  */
5446117395Skan  return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
5447117395Skan}
544890075Sobrien  [(set_attr "itanium_class" "st")])
544990075Sobrien
545090075Sobrien;; Reads ar.unat
545190075Sobrien(define_expand "gr_restore"
545290075Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
545390075Sobrien		   (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5454117395Skan			       (match_operand:DI 2 "const_int_operand" "")]
5455117395Skan			      UNSPEC_GR_RESTORE))
545690075Sobrien	      (use (match_dup 3))])]
545790075Sobrien  ""
545890075Sobrien  "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
545990075Sobrien
546090075Sobrien(define_insn "gr_restore_internal"
546190075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
546290075Sobrien	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5463117395Skan		    (match_operand:DI 2 "const_int_operand" "")]
5464117395Skan		   UNSPEC_GR_RESTORE))
546590075Sobrien   (use (match_operand:DI 3 "register_operand" ""))]
546690075Sobrien  ""
5467117395Skan  { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
546890075Sobrien  [(set_attr "itanium_class" "ld")])
546990075Sobrien
547090075Sobrien(define_insn "fr_spill"
5471132718Skan  [(set (match_operand:XF 0 "memory_operand" "=m")
5472132718Skan	(unspec:XF [(match_operand:XF 1 "register_operand" "f")]
5473117395Skan		   UNSPEC_FR_SPILL))]
547490075Sobrien  ""
547590075Sobrien  "stf.spill %0 = %1%P0"
547690075Sobrien  [(set_attr "itanium_class" "stf")])
547790075Sobrien
547890075Sobrien(define_insn "fr_restore"
5479132718Skan  [(set (match_operand:XF 0 "register_operand" "=f")
5480132718Skan	(unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
5481117395Skan		   UNSPEC_FR_RESTORE))]
548290075Sobrien  ""
548390075Sobrien  "ldf.fill %0 = %1%P1"
548490075Sobrien  [(set_attr "itanium_class" "fld")])
548590075Sobrien
548690075Sobrien;; ??? The explicit stop is not ideal.  It would be better if
548790075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
548890075Sobrien;; fixed later.  This avoids an RSE DV.
548990075Sobrien
549090075Sobrien(define_insn "bsp_value"
549190075Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
5492117395Skan	(unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
549390075Sobrien  ""
5494117395Skan  "*
5495117395Skan{
5496117395Skan  return \";;\;%,mov %0 = ar.bsp\";
5497117395Skan}"
549890075Sobrien  [(set_attr "itanium_class" "frar_i")])
549990075Sobrien
550090075Sobrien(define_insn "set_bsp"
5501117395Skan  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
5502117395Skan		    UNSPECV_SET_BSP)]
550390075Sobrien  ""
5504117395Skan  "flushrs
5505117395Skan	mov r19=ar.rsc
5506117395Skan	;;
5507117395Skan	and r19=0x1c,r19
5508117395Skan	;;
5509117395Skan	mov ar.rsc=r19
5510117395Skan	;;
5511117395Skan	mov ar.bspstore=%0
5512117395Skan	;;
5513117395Skan	or r19=0x3,r19
5514117395Skan	;;
5515117395Skan	loadrs
5516117395Skan	invala
5517117395Skan	;;
5518117395Skan	mov ar.rsc=r19"
551990075Sobrien  [(set_attr "itanium_class" "unknown")
552090075Sobrien   (set_attr "predicable" "no")])
552190075Sobrien
552290075Sobrien;; ??? The explicit stops are not ideal.  It would be better if
552390075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be
552490075Sobrien;; fixed later.  This avoids an RSE DV.
552590075Sobrien
552690075Sobrien(define_insn "flushrs"
5527117395Skan  [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
552890075Sobrien  ""
552990075Sobrien  ";;\;flushrs\;;;"
5530117395Skan  [(set_attr "itanium_class" "rse_m")
5531117395Skan   (set_attr "predicable" "no")])
553290075Sobrien
553390075Sobrien;; ::::::::::::::::::::
553490075Sobrien;; ::
553590075Sobrien;; :: Miscellaneous instructions
553690075Sobrien;; ::
553790075Sobrien;; ::::::::::::::::::::
553890075Sobrien
5539132718Skan;; ??? Emitting a NOP instruction isn't very useful.  This should probably
554090075Sobrien;; be emitting ";;" to force a break in the instruction packing.
554190075Sobrien
554290075Sobrien;; No operation, needed in case the user uses -g but not -O.
554390075Sobrien(define_insn "nop"
554490075Sobrien  [(const_int 0)]
554590075Sobrien  ""
554690075Sobrien  "nop 0"
5547132718Skan  [(set_attr "itanium_class" "nop")])
554890075Sobrien
554990075Sobrien(define_insn "nop_m"
555090075Sobrien  [(const_int 1)]
555190075Sobrien  ""
555290075Sobrien  "nop.m 0"
555390075Sobrien  [(set_attr "itanium_class" "nop_m")])
555490075Sobrien
555590075Sobrien(define_insn "nop_i"
555690075Sobrien  [(const_int 2)]
555790075Sobrien  ""
555890075Sobrien  "nop.i 0"
555990075Sobrien  [(set_attr "itanium_class" "nop_i")])
556090075Sobrien
556190075Sobrien(define_insn "nop_f"
556290075Sobrien  [(const_int 3)]
556390075Sobrien  ""
556490075Sobrien  "nop.f 0"
556590075Sobrien  [(set_attr "itanium_class" "nop_f")])
556690075Sobrien
556790075Sobrien(define_insn "nop_b"
556890075Sobrien  [(const_int 4)]
556990075Sobrien  ""
557090075Sobrien  "nop.b 0"
557190075Sobrien  [(set_attr "itanium_class" "nop_b")])
557290075Sobrien
557390075Sobrien(define_insn "nop_x"
557490075Sobrien  [(const_int 5)]
557590075Sobrien  ""
557690075Sobrien  ""
5577132718Skan  [(set_attr "itanium_class" "nop_x")
5578132718Skan   (set_attr "empty" "yes")])
557990075Sobrien
5580132718Skan;; The following insn will be never generated.  It is used only by
5581132718Skan;; insn scheduler to change state before advancing cycle.
5582132718Skan(define_insn "pre_cycle"
5583132718Skan  [(const_int 6)]
5584132718Skan  ""
5585132718Skan  ""
5586132718Skan  [(set_attr "itanium_class" "pre_cycle")])
5587132718Skan
558890075Sobrien(define_insn "bundle_selector"
5589117395Skan  [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
559090075Sobrien  ""
5591117395Skan  { return get_bundle_name (INTVAL (operands[0])); }
559290075Sobrien  [(set_attr "itanium_class" "ignore")
559390075Sobrien   (set_attr "predicable" "no")])
559490075Sobrien
559590075Sobrien;; Pseudo instruction that prevents the scheduler from moving code above this
559690075Sobrien;; point.
559790075Sobrien(define_insn "blockage"
5598117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
559990075Sobrien  ""
560090075Sobrien  ""
560190075Sobrien  [(set_attr "itanium_class" "ignore")
560290075Sobrien   (set_attr "predicable" "no")])
560390075Sobrien
560490075Sobrien(define_insn "insn_group_barrier"
5605117395Skan  [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5606117395Skan		    UNSPECV_INSN_GROUP_BARRIER)]
560790075Sobrien  ""
560890075Sobrien  ";;"
560990075Sobrien  [(set_attr "itanium_class" "stop_bit")
5610132718Skan   (set_attr "predicable" "no")
5611132718Skan   (set_attr "empty" "yes")])
561290075Sobrien
561396263Sobrien(define_expand "trap"
561496263Sobrien  [(trap_if (const_int 1) (const_int 0))]
561596263Sobrien  ""
561696263Sobrien  "")
561796263Sobrien
561896263Sobrien;; ??? We don't have a match-any slot type.  Setting the type to unknown
561996263Sobrien;; produces worse code that setting the slot type to A.
562096263Sobrien
562196263Sobrien(define_insn "*trap"
562296263Sobrien  [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
562396263Sobrien  ""
562496263Sobrien  "break %0"
562596263Sobrien  [(set_attr "itanium_class" "chk_s")])
562696263Sobrien
562796263Sobrien(define_expand "conditional_trap"
562896263Sobrien  [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
562996263Sobrien  ""
563096263Sobrien{
563196263Sobrien  operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
563296263Sobrien})
563396263Sobrien
563496263Sobrien(define_insn "*conditional_trap"
563596263Sobrien  [(trap_if (match_operator 0 "predicate_operator"
563696263Sobrien	      [(match_operand:BI 1 "register_operand" "c")
563796263Sobrien	       (const_int 0)])  
563896263Sobrien	    (match_operand 2 "const_int_operand" ""))]
563996263Sobrien  ""
564096263Sobrien  "(%J0) break %2"
564196263Sobrien  [(set_attr "itanium_class" "chk_s")
564296263Sobrien   (set_attr "predicable" "no")])
564396263Sobrien
564490075Sobrien(define_insn "break_f"
5645117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
564690075Sobrien  ""
564790075Sobrien  "break.f 0"
564890075Sobrien  [(set_attr "itanium_class" "nop_f")])
564990075Sobrien
565090075Sobrien(define_insn "prefetch"
565190075Sobrien  [(prefetch (match_operand:DI 0 "address_operand" "p")
565290075Sobrien	     (match_operand:DI 1 "const_int_operand" "n")
565390075Sobrien	     (match_operand:DI 2 "const_int_operand" "n"))]
565490075Sobrien  ""
565590075Sobrien{
565690075Sobrien  static const char * const alt[2][4] = {
565790075Sobrien    {
5658119256Skan      "%,lfetch.nta [%0]",
5659119256Skan      "%,lfetch.nt1 [%0]",
5660119256Skan      "%,lfetch.nt2 [%0]",
5661119256Skan      "%,lfetch [%0]"
566290075Sobrien    },
566390075Sobrien    {
5664119256Skan      "%,lfetch.excl.nta [%0]",
5665119256Skan      "%,lfetch.excl.nt1 [%0]",
5666119256Skan      "%,lfetch.excl.nt2 [%0]",
5667119256Skan      "%,lfetch.excl [%0]"
566890075Sobrien    }
566990075Sobrien  };
567090075Sobrien  int i = (INTVAL (operands[1]));
567190075Sobrien  int j = (INTVAL (operands[2]));
567290075Sobrien
567390075Sobrien  if (i != 0 && i != 1)
567490075Sobrien    abort ();
567590075Sobrien  if (j < 0 || j > 3)
567690075Sobrien    abort ();
567790075Sobrien  return alt[i][j];
567890075Sobrien}
567990075Sobrien  [(set_attr "itanium_class" "lfetch")])
568090075Sobrien
568190075Sobrien;; Non-local goto support.
568290075Sobrien
568390075Sobrien(define_expand "save_stack_nonlocal"
568490075Sobrien  [(use (match_operand:OI 0 "memory_operand" ""))
568590075Sobrien   (use (match_operand:DI 1 "register_operand" ""))]
568690075Sobrien  ""
568790075Sobrien{
568890075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
568990075Sobrien					 \"__ia64_save_stack_nonlocal\"),
569090075Sobrien		     0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
569190075Sobrien		     operands[1], Pmode);
569290075Sobrien  DONE;
5693117395Skan})
569490075Sobrien
569590075Sobrien(define_expand "nonlocal_goto"
569690075Sobrien  [(use (match_operand 0 "general_operand" ""))
569790075Sobrien   (use (match_operand 1 "general_operand" ""))
569890075Sobrien   (use (match_operand 2 "general_operand" ""))
569990075Sobrien   (use (match_operand 3 "general_operand" ""))]
570090075Sobrien  ""
570190075Sobrien{
570290075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
570390075Sobrien		     LCT_NORETURN, VOIDmode, 3,
570490075Sobrien		     operands[1], Pmode,
570590075Sobrien		     copy_to_reg (XEXP (operands[2], 0)), Pmode,
570690075Sobrien		     operands[3], Pmode);
570790075Sobrien  emit_barrier ();
570890075Sobrien  DONE;
5709117395Skan})
571090075Sobrien
5711117395Skan(define_insn_and_split "builtin_setjmp_receiver"
5712117395Skan  [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
571390075Sobrien  ""
5714117395Skan  "#"
5715117395Skan  "reload_completed"
5716117395Skan  [(const_int 0)]
571790075Sobrien{
5718117395Skan  ia64_reload_gp ();
571990075Sobrien  DONE;
5720117395Skan})
572190075Sobrien
572290075Sobrien(define_expand "eh_epilogue"
572390075Sobrien  [(use (match_operand:DI 0 "register_operand" "r"))
572490075Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
572590075Sobrien   (use (match_operand:DI 2 "register_operand" "r"))]
572690075Sobrien  ""
572790075Sobrien{
572890075Sobrien  rtx bsp = gen_rtx_REG (Pmode, 10);
572990075Sobrien  rtx sp = gen_rtx_REG (Pmode, 9);
573090075Sobrien
573190075Sobrien  if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
573290075Sobrien    {
573390075Sobrien      emit_move_insn (bsp, operands[0]);
573490075Sobrien      operands[0] = bsp;
573590075Sobrien    }
573690075Sobrien  if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
573790075Sobrien    {
573890075Sobrien      emit_move_insn (sp, operands[2]);
573990075Sobrien      operands[2] = sp;
574090075Sobrien    }
574190075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, sp));
574290075Sobrien  emit_insn (gen_rtx_USE (VOIDmode, bsp));
574390075Sobrien
574490075Sobrien  cfun->machine->ia64_eh_epilogue_sp = sp;
574590075Sobrien  cfun->machine->ia64_eh_epilogue_bsp = bsp;
5746117395Skan})
574790075Sobrien
574890075Sobrien;; Builtin apply support.
574990075Sobrien
575090075Sobrien(define_expand "restore_stack_nonlocal"
575190075Sobrien  [(use (match_operand:DI 0 "register_operand" ""))
575290075Sobrien   (use (match_operand:OI 1 "memory_operand" ""))]
575390075Sobrien  ""
575490075Sobrien{
575590075Sobrien  emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5756117395Skan					 "__ia64_restore_stack_nonlocal"),
575790075Sobrien		     0, VOIDmode, 1,
575890075Sobrien		     copy_to_reg (XEXP (operands[1], 0)), Pmode);
575990075Sobrien  DONE;
5760117395Skan})
576190075Sobrien
576290075Sobrien
576390075Sobrien;;; Intrinsics support.
576490075Sobrien
576590075Sobrien(define_expand "mf"
576690075Sobrien  [(set (mem:BLK (match_dup 0))
5767117395Skan	(unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
576890075Sobrien  ""
576990075Sobrien{
577090075Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
577190075Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
5772117395Skan})
577390075Sobrien
577490075Sobrien(define_insn "*mf_internal"
577590075Sobrien  [(set (match_operand:BLK 0 "" "")
5776117395Skan	(unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
577790075Sobrien  ""
577890075Sobrien  "mf"
577990075Sobrien  [(set_attr "itanium_class" "syst_m")])
578090075Sobrien
578190075Sobrien(define_insn "fetchadd_acq_si"
578290075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
5783132718Skan	(match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5784132718Skan   (set (match_dup 1)
578590075Sobrien	(unspec:SI [(match_dup 1)
5786117395Skan		    (match_operand:SI 2 "fetchadd_operand" "n")]
5787117395Skan		   UNSPEC_FETCHADD_ACQ))]
578890075Sobrien  ""
578990075Sobrien  "fetchadd4.acq %0 = %1, %2"
579090075Sobrien  [(set_attr "itanium_class" "sem")])
579190075Sobrien
579290075Sobrien(define_insn "fetchadd_acq_di"
579390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5794132718Skan	(match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5795132718Skan   (set (match_dup 1)
579690075Sobrien	(unspec:DI [(match_dup 1)
5797117395Skan		    (match_operand:DI 2 "fetchadd_operand" "n")]
5798117395Skan		   UNSPEC_FETCHADD_ACQ))]
579990075Sobrien  ""
580090075Sobrien  "fetchadd8.acq %0 = %1, %2"
580190075Sobrien  [(set_attr "itanium_class" "sem")])
580290075Sobrien
580390075Sobrien(define_insn "cmpxchg_acq_si"
580490075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
5805132718Skan	(match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5806132718Skan   (set (match_dup 1)
580790075Sobrien        (unspec:SI [(match_dup 1)
580890075Sobrien                    (match_operand:SI 2 "gr_register_operand" "r")
5809132718Skan		    (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5810117395Skan		   UNSPEC_CMPXCHG_ACQ))]
581190075Sobrien  ""
581290075Sobrien  "cmpxchg4.acq %0 = %1, %2, %3"
581390075Sobrien  [(set_attr "itanium_class" "sem")])
581490075Sobrien
581590075Sobrien(define_insn "cmpxchg_acq_di"
581690075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5817132718Skan	(match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5818132718Skan   (set (match_dup 1)
581990075Sobrien        (unspec:DI [(match_dup 1)
582090075Sobrien                    (match_operand:DI 2 "gr_register_operand" "r")
5821117395Skan		    (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5822117395Skan		   UNSPEC_CMPXCHG_ACQ))]
582390075Sobrien  ""
582490075Sobrien  "cmpxchg8.acq %0 = %1, %2, %3"
582590075Sobrien  [(set_attr "itanium_class" "sem")])
582690075Sobrien
582790075Sobrien(define_insn "xchgsi"
582890075Sobrien  [(set (match_operand:SI 0 "gr_register_operand" "=r")
582990075Sobrien        (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
583090075Sobrien   (set (match_dup 1)
583190075Sobrien        (match_operand:SI 2 "gr_register_operand" "r"))]
583290075Sobrien  ""
583390075Sobrien  "xchg4 %0 = %1, %2"
583490075Sobrien  [(set_attr "itanium_class" "sem")])
583590075Sobrien
583690075Sobrien(define_insn "xchgdi"
583790075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
583890075Sobrien        (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
583990075Sobrien   (set (match_dup 1)
584090075Sobrien        (match_operand:DI 2 "gr_register_operand" "r"))]
584190075Sobrien  ""
584290075Sobrien  "xchg8 %0 = %1, %2"
584390075Sobrien  [(set_attr "itanium_class" "sem")])
584490075Sobrien
584590075Sobrien;; Predication.
584690075Sobrien
584790075Sobrien(define_cond_exec
584890075Sobrien  [(match_operator 0 "predicate_operator"
584990075Sobrien     [(match_operand:BI 1 "register_operand" "c")
585090075Sobrien      (const_int 0)])]
585190075Sobrien  ""
585290075Sobrien  "(%J0)")
585390075Sobrien
585490075Sobrien(define_insn "pred_rel_mutex"
585590075Sobrien  [(set (match_operand:BI 0 "register_operand" "+c")
5856117395Skan       (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
585790075Sobrien  ""
585890075Sobrien  ".pred.rel.mutex %0, %I0"
585990075Sobrien  [(set_attr "itanium_class" "ignore")
586090075Sobrien   (set_attr "predicable" "no")])
586190075Sobrien
586290075Sobrien(define_insn "safe_across_calls_all"
5863117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
586490075Sobrien  ""
586590075Sobrien  ".pred.safe_across_calls p1-p63"
586690075Sobrien  [(set_attr "itanium_class" "ignore")
586790075Sobrien   (set_attr "predicable" "no")])
586890075Sobrien
586990075Sobrien(define_insn "safe_across_calls_normal"
5870117395Skan  [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
587190075Sobrien  ""
587290075Sobrien{
5873132718Skan  emit_safe_across_calls ();
5874117395Skan  return "";
5875117395Skan}
587690075Sobrien  [(set_attr "itanium_class" "ignore")
587790075Sobrien   (set_attr "predicable" "no")])
587890075Sobrien
587990075Sobrien;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
588090075Sobrien;; pointer.  This is used by the HP-UX 32 bit mode.
588190075Sobrien
588290075Sobrien(define_insn "ptr_extend"
588390075Sobrien  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5884117395Skan        (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
5885117395Skan		   UNSPEC_ADDP4))]
588690075Sobrien  ""
588790075Sobrien  "addp4 %0 = 0,%1"
588890075Sobrien  [(set_attr "itanium_class" "ialu")])
588990075Sobrien
589090075Sobrien;;
5891117395Skan;; Optimizations for ptr_extend
5892117395Skan
5893132718Skan(define_insn "ptr_extend_plus_imm"
5894117395Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5895117395Skan        (unspec:DI
5896117395Skan         [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
5897117395Skan                   (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
5898117395Skan         UNSPEC_ADDP4))]
5899117395Skan  "addp4_optimize_ok (operands[1], operands[2])"
5900117395Skan  "addp4 %0 = %2, %1"
5901117395Skan  [(set_attr "itanium_class" "ialu")])
5902117395Skan
5903117395Skan(define_insn "*ptr_extend_plus_2"
5904117395Skan  [(set (match_operand:DI 0 "gr_register_operand" "=r")
5905117395Skan        (unspec:DI
5906117395Skan         [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
5907117395Skan                   (match_operand:SI 2 "basereg_operand" "r"))]
5908117395Skan         UNSPEC_ADDP4))]
5909117395Skan  "addp4_optimize_ok (operands[1], operands[2])"
5910117395Skan  "addp4 %0 = %1, %2"
5911117395Skan  [(set_attr "itanium_class" "ialu")])
5912