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