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