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