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