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