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