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