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