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