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>.
6 ;; This file is part of GCC.
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)
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.
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.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
26 ;; reload. This will be fixed once scheduling support is turned on.
28 ;; ??? Optimize for post-increment addressing modes.
30 ;; ??? fselect is not supported, because there is no integer register
33 ;; ??? fp abs/min/max instructions may also work for integer values.
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.
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.
41 ;; ??? Go through list of documented named patterns and look for more to
44 ;; ??? Go through instruction manual and look for more instructions that
47 ;; ??? Add function unit scheduling info for Itanium (TM) processor.
49 ;; ??? Need a better way to describe alternate fp status registers.
53 (UNSPEC_LTOFF_DTPMOD 0)
54 (UNSPEC_LTOFF_DTPREL 1)
56 (UNSPEC_LTOFF_TPREL 3)
61 (UNSPEC_GR_RESTORE 11)
63 (UNSPEC_FR_RESTORE 13)
64 (UNSPEC_FR_RECIP_APPROX 14)
65 (UNSPEC_PRED_REL_MUTEX 15)
69 (UNSPEC_CMPXCHG_ACQ 19)
70 (UNSPEC_FETCHADD_ACQ 20)
73 (UNSPEC_BUNDLE_SELECTOR 23)
75 (UNSPEC_PROLOGUE_USE 25)
78 (UNSPEC_FR_SQRT_RECIP_APPROX 28)
84 (UNSPECV_INSN_GROUP_BARRIER 2)
87 (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls
88 (UNSPECV_PSAC_NORMAL 6)
89 (UNSPECV_SETJMP_RECEIVER 7)
92 ;; ::::::::::::::::::::
96 ;; ::::::::::::::::::::
98 ;; Processor type. This attribute must exactly match the processor_type
99 ;; enumeration in ia64.h.
100 (define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
102 ;; Instruction type. This primarily determines how instructions can be
103 ;; packed in bundles, and secondarily affects scheduling to function units.
105 ;; A alu, can go in I or M syllable of a bundle
110 ;; L long immediate, takes two syllables
113 ;; ??? Should not have any pattern with type unknown. Perhaps add code to
114 ;; check this in md_reorg? Currently use unknown for patterns which emit
115 ;; multiple instructions, patterns which emit 0 instructions, and patterns
116 ;; which emit instruction that can go in any slot (e.g. nop).
118 (define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
119 fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
120 chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
121 syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
122 nop_i,nop_m,nop_x,lfetch,pre_cycle"
123 (const_string "unknown"))
125 ;; chk_s has an I and an M form; use type A for convenience.
126 (define_attr "type" "unknown,A,I,M,F,B,L,X,S"
127 (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
128 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
129 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
130 (eq_attr "itanium_class" "lfetch") (const_string "M")
131 (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A")
132 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
133 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
134 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
135 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
136 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
137 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
138 (eq_attr "itanium_class" "stop_bit") (const_string "S")
139 (eq_attr "itanium_class" "nop_x") (const_string "X")
140 (eq_attr "itanium_class" "long_i") (const_string "L")]
141 (const_string "unknown")))
143 (define_attr "itanium_requires_unit0" "no,yes"
144 (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
145 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
146 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
147 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
148 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
149 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
150 (const_string "no")))
152 ;; Predication. True iff this instruction can be predicated.
154 (define_attr "predicable" "no,yes" (const_string "yes"))
158 ;; DFA descriptions of ia64 processors used for insn scheduling and
161 (automata_option "ndfa")
163 ;; Uncomment the following line to output automata for debugging.
164 ;; (automata_option "v")
166 (automata_option "w")
168 ;;(automata_option "no-minimization")
171 (include "itanium1.md")
172 (include "itanium2.md")
175 ;; ::::::::::::::::::::
179 ;; ::::::::::::::::::::
181 ;; Set of a single predicate register. This is only used to implement
182 ;; pr-to-pr move and complement.
184 (define_insn "*movcci"
185 [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
186 (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
189 cmp.ne %0, p0 = r0, r0
190 cmp.eq %0, p0 = r0, r0
191 (%1) cmp.eq.unc %0, p0 = r0, r0"
192 [(set_attr "itanium_class" "icmp")
193 (set_attr "predicable" "no")])
196 [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
197 (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))]
200 cmp.ne %0, %I0 = r0, r0
201 cmp.eq %0, %I0 = r0, r0
204 tbit.nz %0, %I0 = %1, 0
209 [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
212 [(set (match_operand:BI 0 "register_operand" "")
213 (match_operand:BI 1 "register_operand" ""))]
215 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
216 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
217 [(cond_exec (ne (match_dup 1) (const_int 0))
218 (set (match_dup 0) (const_int 1)))
219 (cond_exec (eq (match_dup 1) (const_int 0))
220 (set (match_dup 0) (const_int 0)))]
224 [(set (match_operand:BI 0 "register_operand" "")
225 (match_operand:BI 1 "register_operand" ""))]
227 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
228 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
229 [(set (match_dup 2) (match_dup 4))
230 (set (match_dup 3) (match_dup 5))
231 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
232 "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
233 operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
234 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
235 operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
237 (define_expand "movqi"
238 [(set (match_operand:QI 0 "general_operand" "")
239 (match_operand:QI 1 "general_operand" ""))]
242 rtx op1 = ia64_expand_move (operands[0], operands[1]);
248 (define_insn "*movqi_internal"
249 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
250 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
251 "ia64_move_ok (operands[0], operands[1])"
260 [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
262 (define_expand "movhi"
263 [(set (match_operand:HI 0 "general_operand" "")
264 (match_operand:HI 1 "general_operand" ""))]
267 rtx op1 = ia64_expand_move (operands[0], operands[1]);
273 (define_insn "*movhi_internal"
274 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
275 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
276 "ia64_move_ok (operands[0], operands[1])"
285 [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
287 (define_expand "movsi"
288 [(set (match_operand:SI 0 "general_operand" "")
289 (match_operand:SI 1 "general_operand" ""))]
292 rtx op1 = ia64_expand_move (operands[0], operands[1]);
298 (define_insn "*movsi_internal"
299 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
300 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
301 "ia64_move_ok (operands[0], operands[1])"
313 ;; frar_m, toar_m ??? why not frar_i and toar_i
314 [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
316 (define_expand "movdi"
317 [(set (match_operand:DI 0 "general_operand" "")
318 (match_operand:DI 1 "general_operand" ""))]
321 rtx op1 = ia64_expand_move (operands[0], operands[1]);
327 (define_insn "*movdi_internal"
328 [(set (match_operand:DI 0 "destination_operand"
329 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
330 (match_operand:DI 1 "move_operand"
331 "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
332 "ia64_move_ok (operands[0], operands[1])"
334 static const char * const alt[] = {
336 "%,addl %0 = %1, r0",
338 "%,ld8%O1 %0 = %1%P1",
339 "%,st8%Q0 %0 = %r1%P0",
340 "%,getf.sig %0 = %1",
341 "%,setf.sig %0 = %r1",
355 if (which_alternative == 2 && ! TARGET_NO_PIC
356 && symbolic_operand (operands[1], VOIDmode))
359 return alt[which_alternative];
361 [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,fld,stf,frbr,tobr,frar_i,toar_i,frar_m,toar_m,frpr,topr")])
364 [(set (match_operand 0 "register_operand" "")
365 (match_operand 1 "symbolic_operand" ""))]
366 "reload_completed && ! TARGET_NO_PIC"
369 ia64_expand_load_address (operands[0], operands[1]);
373 (define_expand "load_fptr"
375 (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
376 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
379 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
380 operands[3] = gen_rtx_MEM (DImode, operands[2]);
381 RTX_UNCHANGING_P (operands[3]) = 1;
384 (define_insn "*load_fptr_internal1"
385 [(set (match_operand:DI 0 "register_operand" "=r")
386 (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
388 "addl %0 = @ltoff(@fptr(%1)), gp"
389 [(set_attr "itanium_class" "ialu")])
391 (define_insn "load_gprel"
392 [(set (match_operand:DI 0 "register_operand" "=r")
393 (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
395 "addl %0 = @gprel(%1), gp"
396 [(set_attr "itanium_class" "ialu")])
398 (define_insn "gprel64_offset"
399 [(set (match_operand:DI 0 "register_operand" "=r")
400 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
402 "movl %0 = @gprel(%1)"
403 [(set_attr "itanium_class" "long_i")])
405 (define_expand "load_gprel64"
407 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
408 (set (match_operand:DI 0 "register_operand" "")
409 (plus:DI (match_dup 3) (match_dup 2)))]
412 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
413 operands[3] = pic_offset_table_rtx;
416 ;; This is used as a placeholder for the return address during early
417 ;; compilation. We won't know where we've placed this until during
418 ;; reload, at which point it can wind up in b0, a general register,
419 ;; or memory. The only safe destination under these conditions is a
422 (define_insn_and_split "*movdi_ret_addr"
423 [(set (match_operand:DI 0 "register_operand" "=r")
424 (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
430 ia64_split_return_addr_rtx (operands[0]);
433 [(set_attr "itanium_class" "ialu")])
435 (define_insn "*load_symptr_high"
436 [(set (match_operand:DI 0 "register_operand" "=r")
437 (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
438 (match_operand:DI 2 "register_operand" "a")))]
441 if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
442 return "%,addl %0 = @ltoffx(%1), %2";
444 return "%,addl %0 = @ltoff(%1), %2";
446 [(set_attr "itanium_class" "ialu")])
448 (define_insn "*load_symptr_low"
449 [(set (match_operand:DI 0 "register_operand" "=r")
450 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
451 (match_operand 2 "got_symbolic_operand" "s")))]
454 if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
455 return "%,ld8.mov %0 = [%1], %2";
457 return "%,ld8 %0 = [%1]";
459 [(set_attr "itanium_class" "ld")])
461 (define_insn "load_ltoff_dtpmod"
462 [(set (match_operand:DI 0 "register_operand" "=r")
464 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
465 UNSPEC_LTOFF_DTPMOD)))]
467 "addl %0 = @ltoff(@dtpmod(%1)), gp"
468 [(set_attr "itanium_class" "ialu")])
470 (define_insn "load_ltoff_dtprel"
471 [(set (match_operand:DI 0 "register_operand" "=r")
473 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
474 UNSPEC_LTOFF_DTPREL)))]
476 "addl %0 = @ltoff(@dtprel(%1)), gp"
477 [(set_attr "itanium_class" "ialu")])
479 (define_expand "load_dtprel"
480 [(set (match_operand:DI 0 "register_operand" "")
481 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
486 (define_insn "*load_dtprel64"
487 [(set (match_operand:DI 0 "register_operand" "=r")
488 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
491 "movl %0 = @dtprel(%1)"
492 [(set_attr "itanium_class" "long_i")])
494 (define_insn "*load_dtprel22"
495 [(set (match_operand:DI 0 "register_operand" "=r")
496 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
499 "addl %0 = @dtprel(%1), r0"
500 [(set_attr "itanium_class" "ialu")])
502 (define_expand "add_dtprel"
503 [(set (match_operand:DI 0 "register_operand" "")
504 (plus:DI (match_operand:DI 1 "register_operand" "")
505 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
510 (define_insn "*add_dtprel14"
511 [(set (match_operand:DI 0 "register_operand" "=r")
512 (plus:DI (match_operand:DI 1 "register_operand" "r")
513 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
516 "adds %0 = @dtprel(%2), %1"
517 [(set_attr "itanium_class" "ialu")])
519 (define_insn "*add_dtprel22"
520 [(set (match_operand:DI 0 "register_operand" "=r")
521 (plus:DI (match_operand:DI 1 "register_operand" "a")
522 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
525 "addl %0 = @dtprel(%2), %1"
526 [(set_attr "itanium_class" "ialu")])
528 (define_insn "load_ltoff_tprel"
529 [(set (match_operand:DI 0 "register_operand" "=r")
531 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
532 UNSPEC_LTOFF_TPREL)))]
534 "addl %0 = @ltoff(@tprel(%1)), gp"
535 [(set_attr "itanium_class" "ialu")])
537 (define_expand "load_tprel"
538 [(set (match_operand:DI 0 "register_operand" "")
539 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
544 (define_insn "*load_tprel64"
545 [(set (match_operand:DI 0 "register_operand" "=r")
546 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
549 "movl %0 = @tprel(%1)"
550 [(set_attr "itanium_class" "long_i")])
552 (define_insn "*load_tprel22"
553 [(set (match_operand:DI 0 "register_operand" "=r")
554 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
557 "addl %0 = @tprel(%1), r0"
558 [(set_attr "itanium_class" "ialu")])
560 (define_expand "add_tprel"
561 [(set (match_operand:DI 0 "register_operand" "")
562 (plus:DI (match_operand:DI 1 "register_operand" "")
563 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
568 (define_insn "*add_tprel14"
569 [(set (match_operand:DI 0 "register_operand" "=r")
570 (plus:DI (match_operand:DI 1 "register_operand" "r")
571 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
574 "adds %0 = @tprel(%2), %1"
575 [(set_attr "itanium_class" "ialu")])
577 (define_insn "*add_tprel22"
578 [(set (match_operand:DI 0 "register_operand" "=r")
579 (plus:DI (match_operand:DI 1 "register_operand" "a")
580 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
583 "addl %0 = @tprel(%2), %1"
584 [(set_attr "itanium_class" "ialu")])
586 ;; With no offsettable memory references, we've got to have a scratch
587 ;; around to play with the second word.
588 (define_expand "movti"
589 [(parallel [(set (match_operand:TI 0 "general_operand" "")
590 (match_operand:TI 1 "general_operand" ""))
591 (clobber (match_scratch:DI 2 ""))])]
594 rtx op1 = ia64_expand_move (operands[0], operands[1]);
600 (define_insn_and_split "*movti_internal"
601 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
602 (match_operand:TI 1 "general_operand" "ri,m,r"))
603 (clobber (match_scratch:DI 2 "=X,&r,&r"))]
604 "ia64_move_ok (operands[0], operands[1])"
609 rtx adj1, adj2, in[2], out[2], insn;
612 adj1 = ia64_split_timode (in, operands[1], operands[2]);
613 adj2 = ia64_split_timode (out, operands[0], operands[2]);
616 if (reg_overlap_mentioned_p (out[0], in[1]))
618 if (reg_overlap_mentioned_p (out[1], in[0]))
629 insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
630 if (GET_CODE (out[first]) == MEM
631 && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
632 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
633 XEXP (XEXP (out[first], 0), 0),
635 insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
636 if (GET_CODE (out[!first]) == MEM
637 && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
638 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
639 XEXP (XEXP (out[!first], 0), 0),
643 [(set_attr "itanium_class" "unknown")
644 (set_attr "predicable" "no")])
646 ;; ??? SSA creates these. Can't allow memories since we don't have
647 ;; the scratch register. Fortunately combine will know how to add
648 ;; the clobber and scratch.
649 (define_insn_and_split "*movti_internal_reg"
650 [(set (match_operand:TI 0 "register_operand" "=r")
651 (match_operand:TI 1 "nonmemory_operand" "ri"))]
660 ia64_split_timode (in, operands[1], NULL_RTX);
661 ia64_split_timode (out, operands[0], NULL_RTX);
664 if (reg_overlap_mentioned_p (out[0], in[1]))
666 if (reg_overlap_mentioned_p (out[1], in[0]))
671 emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
672 emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
675 [(set_attr "itanium_class" "unknown")
676 (set_attr "predicable" "no")])
678 (define_expand "reload_inti"
679 [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
680 (match_operand:TI 1 "" "m"))
681 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
684 unsigned int s_regno = REGNO (operands[2]);
685 if (s_regno == REGNO (operands[0]))
687 operands[2] = gen_rtx_REG (DImode, s_regno);
690 (define_expand "reload_outti"
691 [(parallel [(set (match_operand:TI 0 "" "=m")
692 (match_operand:TI 1 "register_operand" "r"))
693 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
696 unsigned int s_regno = REGNO (operands[2]);
697 if (s_regno == REGNO (operands[1]))
699 operands[2] = gen_rtx_REG (DImode, s_regno);
702 ;; Floating Point Moves
704 ;; Note - Patterns for SF mode moves are compulsory, but
705 ;; patterns for DF are optional, as GCC can synthesize them.
707 (define_expand "movsf"
708 [(set (match_operand:SF 0 "general_operand" "")
709 (match_operand:SF 1 "general_operand" ""))]
712 rtx op1 = ia64_expand_move (operands[0], operands[1]);
718 (define_insn "*movsf_internal"
719 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
720 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
721 "ia64_move_ok (operands[0], operands[1])"
731 [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
733 (define_expand "movdf"
734 [(set (match_operand:DF 0 "general_operand" "")
735 (match_operand:DF 1 "general_operand" ""))]
738 rtx op1 = ia64_expand_move (operands[0], operands[1]);
744 (define_insn "*movdf_internal"
745 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
746 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
747 "ia64_move_ok (operands[0], operands[1])"
757 [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
759 ;; With no offsettable memory references, we've got to have a scratch
760 ;; around to play with the second word if the variable winds up in GRs.
761 (define_expand "movxf"
762 [(set (match_operand:XF 0 "general_operand" "")
763 (match_operand:XF 1 "general_operand" ""))]
766 /* We must support XFmode loads into general registers for stdarg/vararg
767 and unprototyped calls. We split them into DImode loads for convenience.
768 We don't need XFmode stores from general regs, because a stdarg/vararg
769 routine does a block store to memory of unnamed arguments. */
770 if (GET_CODE (operands[0]) == REG
771 && GR_REGNO_P (REGNO (operands[0])))
773 /* We're hoping to transform everything that deals with XFmode
774 quantities and GR registers early in the compiler. */
778 /* Struct to register can just use TImode instead. */
779 if ((GET_CODE (operands[1]) == SUBREG
780 && GET_MODE (SUBREG_REG (operands[1])) == TImode)
781 || (GET_CODE (operands[1]) == REG
782 && GR_REGNO_P (REGNO (operands[1]))))
784 emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
785 SUBREG_REG (operands[1]));
789 if (GET_CODE (operands[1]) == CONST_DOUBLE)
791 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
792 operand_subword (operands[1], 0, 0, XFmode));
793 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
794 operand_subword (operands[1], 1, 0, XFmode));
798 /* If the quantity is in a register not known to be GR, spill it. */
799 if (register_operand (operands[1], XFmode))
800 operands[1] = spill_xfmode_operand (operands[1], 1);
802 if (GET_CODE (operands[1]) == MEM)
806 out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
807 out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
809 emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
810 emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
817 if (! reload_in_progress && ! reload_completed)
819 operands[0] = spill_xfmode_operand (operands[0], 0);
820 operands[1] = spill_xfmode_operand (operands[1], 0);
822 if (! ia64_move_ok (operands[0], operands[1]))
823 operands[1] = force_reg (XFmode, operands[1]);
827 ;; ??? There's no easy way to mind volatile acquire/release semantics.
829 (define_insn "*movxf_internal"
830 [(set (match_operand:XF 0 "destination_xfmode_operand" "=f,f, m")
831 (match_operand:XF 1 "general_xfmode_operand" "fG,m,fG"))]
832 "ia64_move_ok (operands[0], operands[1])"
837 [(set_attr "itanium_class" "fmisc,fld,stf")])
839 ;; ::::::::::::::::::::
843 ;; ::::::::::::::::::::
845 ;; Signed conversions from a smaller integer to a larger integer
847 (define_insn "extendqidi2"
848 [(set (match_operand:DI 0 "gr_register_operand" "=r")
849 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
852 [(set_attr "itanium_class" "xtd")])
854 (define_insn "extendhidi2"
855 [(set (match_operand:DI 0 "gr_register_operand" "=r")
856 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
859 [(set_attr "itanium_class" "xtd")])
861 (define_insn "extendsidi2"
862 [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
863 (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
868 [(set_attr "itanium_class" "xtd,fmisc")])
870 ;; Unsigned conversions from a smaller integer to a larger integer
872 (define_insn "zero_extendqidi2"
873 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
874 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
879 [(set_attr "itanium_class" "xtd,ld")])
881 (define_insn "zero_extendhidi2"
882 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
883 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
888 [(set_attr "itanium_class" "xtd,ld")])
890 (define_insn "zero_extendsidi2"
891 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
893 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
899 [(set_attr "itanium_class" "xtd,ld,fmisc")])
901 ;; Convert between floating point types of different sizes.
903 ;; At first glance, it would appear that emitting fnorm for an extending
904 ;; conversion is unnecessary. However, the stf and getf instructions work
905 ;; correctly only if the input is properly rounded for its type. In
906 ;; particular, we get the wrong result for getf.d/stfd if the input is a
907 ;; denorm single. Since we don't know what the next instruction will be, we
908 ;; have to emit an fnorm.
910 ;; ??? Optimization opportunity here. Get rid of the insn altogether
911 ;; when we can. Should probably use a scheme like has been proposed
912 ;; for ia32 in dealing with operands that match unary operators. This
913 ;; would let combine merge the thing into adjacent insns. See also how the
914 ;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
915 ;; se_register_operand.
917 (define_insn "extendsfdf2"
918 [(set (match_operand:DF 0 "fr_register_operand" "=f")
919 (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
922 [(set_attr "itanium_class" "fmac")])
924 (define_insn "extendsfxf2"
925 [(set (match_operand:XF 0 "fr_register_operand" "=f")
926 (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]
929 [(set_attr "itanium_class" "fmac")])
931 (define_insn "extenddfxf2"
932 [(set (match_operand:XF 0 "fr_register_operand" "=f")
933 (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]
936 [(set_attr "itanium_class" "fmac")])
938 (define_insn "truncdfsf2"
939 [(set (match_operand:SF 0 "fr_register_operand" "=f")
940 (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
943 [(set_attr "itanium_class" "fmac")])
945 (define_insn "truncxfsf2"
946 [(set (match_operand:SF 0 "fr_register_operand" "=f")
947 (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]
950 [(set_attr "itanium_class" "fmac")])
952 (define_insn "truncxfdf2"
953 [(set (match_operand:DF 0 "fr_register_operand" "=f")
954 (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]
957 [(set_attr "itanium_class" "fmac")])
959 ;; Convert between signed integer types and floating point.
961 (define_insn "floatdixf2"
962 [(set (match_operand:XF 0 "fr_register_operand" "=f")
963 (float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
966 [(set_attr "itanium_class" "fcvtfx")])
968 (define_insn "fix_truncsfdi2"
969 [(set (match_operand:DI 0 "fr_register_operand" "=f")
970 (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
972 "fcvt.fx.trunc %0 = %1"
973 [(set_attr "itanium_class" "fcvtfx")])
975 (define_insn "fix_truncdfdi2"
976 [(set (match_operand:DI 0 "fr_register_operand" "=f")
977 (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
979 "fcvt.fx.trunc %0 = %1"
980 [(set_attr "itanium_class" "fcvtfx")])
982 (define_insn "fix_truncxfdi2"
983 [(set (match_operand:DI 0 "fr_register_operand" "=f")
984 (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
986 "fcvt.fx.trunc %0 = %1"
987 [(set_attr "itanium_class" "fcvtfx")])
989 (define_insn "fix_truncxfdi2_alts"
990 [(set (match_operand:DI 0 "fr_register_operand" "=f")
991 (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
992 (use (match_operand:SI 2 "const_int_operand" ""))]
994 "fcvt.fx.trunc.s%2 %0 = %1"
995 [(set_attr "itanium_class" "fcvtfx")])
997 ;; Convert between unsigned integer types and floating point.
999 (define_insn "floatunsdisf2"
1000 [(set (match_operand:SF 0 "fr_register_operand" "=f")
1001 (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
1003 "fcvt.xuf.s %0 = %1"
1004 [(set_attr "itanium_class" "fcvtfx")])
1006 (define_insn "floatunsdidf2"
1007 [(set (match_operand:DF 0 "fr_register_operand" "=f")
1008 (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
1010 "fcvt.xuf.d %0 = %1"
1011 [(set_attr "itanium_class" "fcvtfx")])
1013 (define_insn "floatunsdixf2"
1014 [(set (match_operand:XF 0 "fr_register_operand" "=f")
1015 (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
1018 [(set_attr "itanium_class" "fcvtfx")])
1020 (define_insn "fixuns_truncsfdi2"
1021 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1022 (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
1024 "fcvt.fxu.trunc %0 = %1"
1025 [(set_attr "itanium_class" "fcvtfx")])
1027 (define_insn "fixuns_truncdfdi2"
1028 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1029 (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
1031 "fcvt.fxu.trunc %0 = %1"
1032 [(set_attr "itanium_class" "fcvtfx")])
1034 (define_insn "fixuns_truncxfdi2"
1035 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1036 (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
1038 "fcvt.fxu.trunc %0 = %1"
1039 [(set_attr "itanium_class" "fcvtfx")])
1041 (define_insn "fixuns_truncxfdi2_alts"
1042 [(set (match_operand:DI 0 "fr_register_operand" "=f")
1043 (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
1044 (use (match_operand:SI 2 "const_int_operand" ""))]
1046 "fcvt.fxu.trunc.s%2 %0 = %1"
1047 [(set_attr "itanium_class" "fcvtfx")])
1049 ;; ::::::::::::::::::::
1051 ;; :: Bit field extraction
1053 ;; ::::::::::::::::::::
1056 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1057 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1058 (match_operand:DI 2 "const_int_operand" "n")
1059 (match_operand:DI 3 "const_int_operand" "n")))]
1061 "extr %0 = %1, %3, %2"
1062 [(set_attr "itanium_class" "ishf")])
1064 (define_insn "extzv"
1065 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1066 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1067 (match_operand:DI 2 "const_int_operand" "n")
1068 (match_operand:DI 3 "const_int_operand" "n")))]
1070 "extr.u %0 = %1, %3, %2"
1071 [(set_attr "itanium_class" "ishf")])
1073 ;; Insert a bit field.
1074 ;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1075 ;; Source1 can be 0 or -1.
1076 ;; Source2 can be 0.
1078 ;; ??? Actual dep instruction is more powerful than what these insv
1079 ;; patterns support. Unfortunately, combine is unable to create patterns
1080 ;; where source2 != dest.
1082 (define_expand "insv"
1083 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1084 (match_operand:DI 1 "const_int_operand" "")
1085 (match_operand:DI 2 "const_int_operand" ""))
1086 (match_operand:DI 3 "nonmemory_operand" ""))]
1089 int width = INTVAL (operands[1]);
1090 int shift = INTVAL (operands[2]);
1092 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1094 if (! register_operand (operands[3], DImode)
1095 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1096 operands[3] = force_reg (DImode, operands[3]);
1098 /* If this is a single dep instruction, we have nothing to do. */
1099 if (! ((register_operand (operands[3], DImode) && width <= 16)
1100 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1102 /* Check for cases that can be implemented with a mix instruction. */
1103 if (width == 32 && shift == 0)
1105 /* Directly generating the mix4left instruction confuses
1106 optimize_bit_field in function.c. Since this is performing
1107 a useful optimization, we defer generation of the complicated
1108 mix4left RTL to the first splitting phase. */
1109 rtx tmp = gen_reg_rtx (DImode);
1110 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1113 else if (width == 32 && shift == 32)
1115 emit_insn (gen_mix4right (operands[0], operands[3]));
1119 /* We could handle remaining cases by emitting multiple dep
1122 If we need more than two dep instructions then we lose. A 6
1123 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1124 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1125 the latter is 6 cycles on an Itanium (TM) processor, because there is
1126 only one function unit that can execute dep and shr immed.
1128 If we only need two dep instruction, then we still lose.
1129 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1130 the unnecessary mov, this is still undesirable because it will be
1131 hard to optimize, and it creates unnecessary pressure on the I0
1137 /* This code may be useful for other IA-64 processors, so we leave it in
1143 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1147 tmp = gen_reg_rtx (DImode);
1148 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1151 operands[1] = GEN_INT (width);
1152 operands[2] = GEN_INT (shift);
1157 (define_insn "*insv_internal"
1158 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1159 (match_operand:DI 1 "const_int_operand" "n")
1160 (match_operand:DI 2 "const_int_operand" "n"))
1161 (match_operand:DI 3 "nonmemory_operand" "rP"))]
1162 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1163 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1164 "dep %0 = %3, %0, %2, %1"
1165 [(set_attr "itanium_class" "ishf")])
1167 ;; Combine doesn't like to create bit-field insertions into zero.
1168 (define_insn "*depz_internal"
1169 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1170 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1171 (match_operand:DI 2 "const_int_operand" "n"))
1172 (match_operand:DI 3 "const_int_operand" "n")))]
1173 "CONST_OK_FOR_M (INTVAL (operands[2]))
1174 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1176 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1177 return "%,dep.z %0 = %1, %2, %3";
1179 [(set_attr "itanium_class" "ishf")])
1181 (define_insn "shift_mix4left"
1182 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1183 (const_int 32) (const_int 0))
1184 (match_operand:DI 1 "gr_register_operand" "r"))
1185 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1188 [(set_attr "itanium_class" "unknown")])
1191 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1192 (const_int 32) (const_int 0))
1193 (match_operand:DI 1 "register_operand" ""))
1194 (clobber (match_operand:DI 2 "register_operand" ""))]
1196 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1197 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1198 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1199 "operands[3] = operands[2];")
1202 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1203 (const_int 32) (const_int 0))
1204 (match_operand:DI 1 "register_operand" ""))
1205 (clobber (match_operand:DI 2 "register_operand" ""))]
1206 "! reload_completed"
1207 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1208 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1209 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1210 "operands[3] = operands[2];")
1212 (define_insn "*mix4left"
1213 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1214 (const_int 32) (const_int 0))
1215 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1218 "mix4.l %0 = %0, %r1"
1219 [(set_attr "itanium_class" "mmshf")])
1221 (define_insn "mix4right"
1222 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1223 (const_int 32) (const_int 32))
1224 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1226 "mix4.r %0 = %r1, %0"
1227 [(set_attr "itanium_class" "mmshf")])
1229 ;; This is used by the rotrsi3 pattern.
1231 (define_insn "*mix4right_3op"
1232 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1233 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1234 (ashift:DI (zero_extend:DI
1235 (match_operand:SI 2 "gr_register_operand" "r"))
1238 "mix4.r %0 = %2, %1"
1239 [(set_attr "itanium_class" "mmshf")])
1242 ;; ::::::::::::::::::::
1244 ;; :: 1 bit Integer arithmetic
1246 ;; ::::::::::::::::::::
1248 (define_insn_and_split "andbi3"
1249 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1250 (and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1251 (match_operand:BI 2 "register_operand" "c,r,r")))]
1255 tbit.nz.and.orcm %0, %I0 = %2, 0
1258 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1259 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1260 [(cond_exec (eq (match_dup 2) (const_int 0))
1261 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1264 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1266 (define_insn_and_split "*andcmbi3"
1267 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1268 (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
1269 (match_operand:BI 2 "register_operand" "0,0,r")))]
1273 tbit.z.and.orcm %0, %I0 = %1, 0
1276 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1277 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1278 [(cond_exec (ne (match_dup 1) (const_int 0))
1279 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1282 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1284 (define_insn_and_split "iorbi3"
1285 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1286 (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1287 (match_operand:BI 2 "register_operand" "c,r,r")))]
1291 tbit.nz.or.andcm %0, %I0 = %2, 0
1294 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1295 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1296 [(cond_exec (ne (match_dup 2) (const_int 0))
1297 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1300 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1302 (define_insn_and_split "*iorcmbi3"
1303 [(set (match_operand:BI 0 "register_operand" "=c,c")
1304 (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
1305 (match_operand:BI 2 "register_operand" "0,0")))]
1309 tbit.z.or.andcm %0, %I0 = %1, 0"
1311 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1312 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1313 [(cond_exec (eq (match_dup 1) (const_int 0))
1314 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1317 [(set_attr "itanium_class" "unknown,tbit")])
1319 (define_insn "one_cmplbi2"
1320 [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
1321 (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
1322 (clobber (match_scratch:BI 2 "=X,X,c,X"))]
1325 tbit.z %0, %I0 = %1, 0
1329 [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
1332 [(set (match_operand:BI 0 "register_operand" "")
1333 (not:BI (match_operand:BI 1 "register_operand" "")))
1334 (clobber (match_scratch:BI 2 ""))]
1336 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1337 && rtx_equal_p (operands[0], operands[1])"
1338 [(set (match_dup 4) (match_dup 3))
1339 (set (match_dup 0) (const_int 1))
1340 (cond_exec (ne (match_dup 2) (const_int 0))
1341 (set (match_dup 0) (const_int 0)))
1342 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1343 "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
1344 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
1347 [(set (match_operand:BI 0 "register_operand" "")
1348 (not:BI (match_operand:BI 1 "register_operand" "")))
1349 (clobber (match_scratch:BI 2 ""))]
1351 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1352 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1353 && ! rtx_equal_p (operands[0], operands[1])"
1354 [(cond_exec (ne (match_dup 1) (const_int 0))
1355 (set (match_dup 0) (const_int 0)))
1356 (cond_exec (eq (match_dup 1) (const_int 0))
1357 (set (match_dup 0) (const_int 1)))
1358 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1361 (define_insn "*cmpsi_and_0"
1362 [(set (match_operand:BI 0 "register_operand" "=c")
1363 (and:BI (match_operator:BI 4 "predicate_operator"
1364 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1365 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1366 (match_operand:BI 1 "register_operand" "0")))]
1368 "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
1369 [(set_attr "itanium_class" "icmp")])
1371 (define_insn "*cmpsi_and_1"
1372 [(set (match_operand:BI 0 "register_operand" "=c")
1373 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1374 [(match_operand:SI 2 "gr_register_operand" "r")
1376 (match_operand:BI 1 "register_operand" "0")))]
1378 "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
1379 [(set_attr "itanium_class" "icmp")])
1381 (define_insn "*cmpsi_andnot_0"
1382 [(set (match_operand:BI 0 "register_operand" "=c")
1383 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1384 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1385 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1386 (match_operand:BI 1 "register_operand" "0")))]
1388 "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
1389 [(set_attr "itanium_class" "icmp")])
1391 (define_insn "*cmpsi_andnot_1"
1392 [(set (match_operand:BI 0 "register_operand" "=c")
1393 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1394 [(match_operand:SI 2 "gr_register_operand" "r")
1396 (match_operand:BI 1 "register_operand" "0")))]
1398 "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
1399 [(set_attr "itanium_class" "icmp")])
1401 (define_insn "*cmpdi_and_0"
1402 [(set (match_operand:BI 0 "register_operand" "=c")
1403 (and:BI (match_operator:BI 4 "predicate_operator"
1404 [(match_operand:DI 2 "gr_register_operand" "r")
1405 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1406 (match_operand:BI 1 "register_operand" "0")))]
1408 "cmp.%C4.and.orcm %0, %I0 = %3, %2"
1409 [(set_attr "itanium_class" "icmp")])
1411 (define_insn "*cmpdi_and_1"
1412 [(set (match_operand:BI 0 "register_operand" "=c")
1413 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1414 [(match_operand:DI 2 "gr_register_operand" "r")
1416 (match_operand:BI 1 "register_operand" "0")))]
1418 "cmp.%C3.and.orcm %0, %I0 = r0, %2"
1419 [(set_attr "itanium_class" "icmp")])
1421 (define_insn "*cmpdi_andnot_0"
1422 [(set (match_operand:BI 0 "register_operand" "=c")
1423 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1424 [(match_operand:DI 2 "gr_register_operand" "r")
1425 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1426 (match_operand:BI 1 "register_operand" "0")))]
1428 "cmp.%C4.or.andcm %I0, %0 = %3, %2"
1429 [(set_attr "itanium_class" "icmp")])
1431 (define_insn "*cmpdi_andnot_1"
1432 [(set (match_operand:BI 0 "register_operand" "=c")
1433 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1434 [(match_operand:DI 2 "gr_register_operand" "r")
1436 (match_operand:BI 1 "register_operand" "0")))]
1438 "cmp.%C3.or.andcm %I0, %0 = r0, %2"
1439 [(set_attr "itanium_class" "icmp")])
1441 (define_insn "*tbit_and_0"
1442 [(set (match_operand:BI 0 "register_operand" "=c")
1443 (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1446 (match_operand:BI 2 "register_operand" "0")))]
1448 "tbit.nz.and.orcm %0, %I0 = %1, 0"
1449 [(set_attr "itanium_class" "tbit")])
1451 (define_insn "*tbit_and_1"
1452 [(set (match_operand:BI 0 "register_operand" "=c")
1453 (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1456 (match_operand:BI 2 "register_operand" "0")))]
1458 "tbit.z.and.orcm %0, %I0 = %1, 0"
1459 [(set_attr "itanium_class" "tbit")])
1461 (define_insn "*tbit_and_2"
1462 [(set (match_operand:BI 0 "register_operand" "=c")
1463 (and:BI (ne:BI (zero_extract:DI
1464 (match_operand:DI 1 "gr_register_operand" "r")
1466 (match_operand:DI 2 "const_int_operand" "n"))
1468 (match_operand:BI 3 "register_operand" "0")))]
1470 "tbit.nz.and.orcm %0, %I0 = %1, %2"
1471 [(set_attr "itanium_class" "tbit")])
1473 (define_insn "*tbit_and_3"
1474 [(set (match_operand:BI 0 "register_operand" "=c")
1475 (and:BI (eq:BI (zero_extract:DI
1476 (match_operand:DI 1 "gr_register_operand" "r")
1478 (match_operand:DI 2 "const_int_operand" "n"))
1480 (match_operand:BI 3 "register_operand" "0")))]
1482 "tbit.z.and.orcm %0, %I0 = %1, %2"
1483 [(set_attr "itanium_class" "tbit")])
1485 (define_insn "*cmpsi_or_0"
1486 [(set (match_operand:BI 0 "register_operand" "=c")
1487 (ior:BI (match_operator:BI 4 "predicate_operator"
1488 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1489 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1490 (match_operand:BI 1 "register_operand" "0")))]
1492 "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
1493 [(set_attr "itanium_class" "icmp")])
1495 (define_insn "*cmpsi_or_1"
1496 [(set (match_operand:BI 0 "register_operand" "=c")
1497 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1498 [(match_operand:SI 2 "gr_register_operand" "r")
1500 (match_operand:BI 1 "register_operand" "0")))]
1502 "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
1503 [(set_attr "itanium_class" "icmp")])
1505 (define_insn "*cmpsi_orcm_0"
1506 [(set (match_operand:BI 0 "register_operand" "=c")
1507 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1508 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1509 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1510 (match_operand:BI 1 "register_operand" "0")))]
1512 "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
1513 [(set_attr "itanium_class" "icmp")])
1515 (define_insn "*cmpsi_orcm_1"
1516 [(set (match_operand:BI 0 "register_operand" "=c")
1517 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1518 [(match_operand:SI 2 "gr_register_operand" "r")
1520 (match_operand:BI 1 "register_operand" "0")))]
1522 "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
1523 [(set_attr "itanium_class" "icmp")])
1525 (define_insn "*cmpdi_or_0"
1526 [(set (match_operand:BI 0 "register_operand" "=c")
1527 (ior:BI (match_operator:BI 4 "predicate_operator"
1528 [(match_operand:DI 2 "gr_register_operand" "r")
1529 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1530 (match_operand:BI 1 "register_operand" "0")))]
1532 "cmp.%C4.or.andcm %0, %I0 = %3, %2"
1533 [(set_attr "itanium_class" "icmp")])
1535 (define_insn "*cmpdi_or_1"
1536 [(set (match_operand:BI 0 "register_operand" "=c")
1537 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1538 [(match_operand:DI 2 "gr_register_operand" "r")
1540 (match_operand:BI 1 "register_operand" "0")))]
1542 "cmp.%C3.or.andcm %0, %I0 = r0, %2"
1543 [(set_attr "itanium_class" "icmp")])
1545 (define_insn "*cmpdi_orcm_0"
1546 [(set (match_operand:BI 0 "register_operand" "=c")
1547 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1548 [(match_operand:DI 2 "gr_register_operand" "r")
1549 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1550 (match_operand:BI 1 "register_operand" "0")))]
1552 "cmp.%C4.and.orcm %I0, %0 = %3, %2"
1553 [(set_attr "itanium_class" "icmp")])
1555 (define_insn "*cmpdi_orcm_1"
1556 [(set (match_operand:BI 0 "register_operand" "=c")
1557 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1558 [(match_operand:DI 2 "gr_register_operand" "r")
1560 (match_operand:BI 1 "register_operand" "0")))]
1562 "cmp.%C3.and.orcm %I0, %0 = r0, %2"
1563 [(set_attr "itanium_class" "icmp")])
1565 (define_insn "*tbit_or_0"
1566 [(set (match_operand:BI 0 "register_operand" "=c")
1567 (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1570 (match_operand:BI 2 "register_operand" "0")))]
1572 "tbit.nz.or.andcm %0, %I0 = %1, 0"
1573 [(set_attr "itanium_class" "tbit")])
1575 (define_insn "*tbit_or_1"
1576 [(set (match_operand:BI 0 "register_operand" "=c")
1577 (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1580 (match_operand:BI 2 "register_operand" "0")))]
1582 "tbit.z.or.andcm %0, %I0 = %1, 0"
1583 [(set_attr "itanium_class" "tbit")])
1585 (define_insn "*tbit_or_2"
1586 [(set (match_operand:BI 0 "register_operand" "=c")
1587 (ior:BI (ne:BI (zero_extract:DI
1588 (match_operand:DI 1 "gr_register_operand" "r")
1590 (match_operand:DI 2 "const_int_operand" "n"))
1592 (match_operand:BI 3 "register_operand" "0")))]
1594 "tbit.nz.or.andcm %0, %I0 = %1, %2"
1595 [(set_attr "itanium_class" "tbit")])
1597 (define_insn "*tbit_or_3"
1598 [(set (match_operand:BI 0 "register_operand" "=c")
1599 (ior:BI (eq:BI (zero_extract:DI
1600 (match_operand:DI 1 "gr_register_operand" "r")
1602 (match_operand:DI 2 "const_int_operand" "n"))
1604 (match_operand:BI 3 "register_operand" "0")))]
1606 "tbit.z.or.andcm %0, %I0 = %1, %2"
1607 [(set_attr "itanium_class" "tbit")])
1609 ;; Transform test of and/or of setcc into parallel comparisons.
1612 [(set (match_operand:BI 0 "register_operand" "")
1613 (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1615 (match_operand:DI 3 "register_operand" ""))
1619 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1624 [(set (match_operand:BI 0 "register_operand" "")
1625 (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1627 (match_operand:DI 3 "register_operand" ""))
1631 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1633 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1634 (clobber (scratch))])]
1638 [(set (match_operand:BI 0 "register_operand" "")
1639 (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1641 (match_operand:DI 3 "register_operand" ""))
1645 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1650 [(set (match_operand:BI 0 "register_operand" "")
1651 (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1653 (match_operand:DI 3 "register_operand" ""))
1657 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1659 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1660 (clobber (scratch))])]
1663 ;; ??? Incredibly hackish. Either need four proper patterns with all
1664 ;; the alternatives, or rely on sched1 to split the insn and hope that
1665 ;; nothing bad happens to the comparisons in the meantime.
1667 ;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1668 ;; that we're doing height reduction.
1670 ;(define_insn_and_split ""
1671 ; [(set (match_operand:BI 0 "register_operand" "=c")
1672 ; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1673 ; [(match_operand 2 "" "")
1674 ; (match_operand 3 "" "")])
1675 ; (match_operator:BI 4 "comparison_operator"
1676 ; [(match_operand 5 "" "")
1677 ; (match_operand 6 "" "")]))
1679 ; "flag_schedule_insns"
1682 ; [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
1683 ; (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
1686 ;(define_insn_and_split ""
1687 ; [(set (match_operand:BI 0 "register_operand" "=c")
1688 ; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1689 ; [(match_operand 2 "" "")
1690 ; (match_operand 3 "" "")])
1691 ; (match_operator:BI 4 "comparison_operator"
1692 ; [(match_operand 5 "" "")
1693 ; (match_operand 6 "" "")]))
1695 ; "flag_schedule_insns"
1698 ; [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
1699 ; (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
1703 ; [(set (match_operand:BI 0 "register_operand" "")
1704 ; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1705 ; [(match_operand 2 "" "")
1706 ; (match_operand 3 "" "")])
1707 ; (match_operand:BI 7 "register_operand" ""))
1708 ; (and:BI (match_operator:BI 4 "comparison_operator"
1709 ; [(match_operand 5 "" "")
1710 ; (match_operand 6 "" "")])
1711 ; (match_operand:BI 8 "register_operand" ""))))]
1713 ; [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
1714 ; (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
1719 ; [(set (match_operand:BI 0 "register_operand" "")
1720 ; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1721 ; [(match_operand 2 "" "")
1722 ; (match_operand 3 "" "")])
1723 ; (match_operand:BI 7 "register_operand" ""))
1724 ; (ior:BI (match_operator:BI 4 "comparison_operator"
1725 ; [(match_operand 5 "" "")
1726 ; (match_operand 6 "" "")])
1727 ; (match_operand:BI 8 "register_operand" ""))))]
1729 ; [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
1730 ; (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
1734 ;; Try harder to avoid predicate copies by duplicating compares.
1735 ;; Note that we'll have already split the predicate copy, which
1736 ;; is kind of a pain, but oh well.
1739 [(set (match_operand:BI 0 "register_operand" "")
1740 (match_operand:BI 1 "comparison_operator" ""))
1741 (set (match_operand:CCI 2 "register_operand" "")
1742 (match_operand:CCI 3 "register_operand" ""))
1743 (set (match_operand:CCI 4 "register_operand" "")
1744 (match_operand:CCI 5 "register_operand" ""))
1745 (set (match_operand:BI 6 "register_operand" "")
1746 (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
1747 "REGNO (operands[3]) == REGNO (operands[0])
1748 && REGNO (operands[4]) == REGNO (operands[0]) + 1
1749 && REGNO (operands[4]) == REGNO (operands[2]) + 1
1750 && REGNO (operands[6]) == REGNO (operands[2])"
1751 [(set (match_dup 0) (match_dup 1))
1752 (set (match_dup 6) (match_dup 7))]
1753 "operands[7] = copy_rtx (operands[1]);")
1755 ;; ::::::::::::::::::::
1757 ;; :: 16 bit Integer arithmetic
1759 ;; ::::::::::::::::::::
1761 (define_insn "mulhi3"
1762 [(set (match_operand:HI 0 "gr_register_operand" "=r")
1763 (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1764 (match_operand:HI 2 "gr_register_operand" "r")))]
1766 "pmpy2.r %0 = %1, %2"
1767 [(set_attr "itanium_class" "mmmul")])
1770 ;; ::::::::::::::::::::
1772 ;; :: 32 bit Integer arithmetic
1774 ;; ::::::::::::::::::::
1776 (define_insn "addsi3"
1777 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1778 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1779 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1785 [(set_attr "itanium_class" "ialu")])
1787 (define_insn "*addsi3_plus1"
1788 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1789 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1790 (match_operand:SI 2 "gr_register_operand" "r"))
1793 "add %0 = %1, %2, 1"
1794 [(set_attr "itanium_class" "ialu")])
1796 (define_insn "*addsi3_plus1_alt"
1797 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1798 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1802 "add %0 = %1, %1, 1"
1803 [(set_attr "itanium_class" "ialu")])
1805 (define_insn "*addsi3_shladd"
1806 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1807 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1808 (match_operand:SI 2 "shladd_operand" "n"))
1809 (match_operand:SI 3 "gr_register_operand" "r")))]
1811 "shladd %0 = %1, %S2, %3"
1812 [(set_attr "itanium_class" "ialu")])
1814 (define_insn "subsi3"
1815 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1816 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1817 (match_operand:SI 2 "gr_register_operand" "r")))]
1820 [(set_attr "itanium_class" "ialu")])
1822 (define_insn "*subsi3_minus1"
1823 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1824 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1825 (match_operand:SI 2 "gr_register_operand" "r")))]
1827 "sub %0 = %2, %1, 1"
1828 [(set_attr "itanium_class" "ialu")])
1830 ;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
1832 (define_insn "mulsi3"
1833 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1834 (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1835 (match_operand:SI 2 "grfr_register_operand" "f")))]
1837 "xmpy.l %0 = %1, %2"
1838 [(set_attr "itanium_class" "xmpy")])
1840 (define_insn "maddsi4"
1841 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1842 (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1843 (match_operand:SI 2 "grfr_register_operand" "f"))
1844 (match_operand:SI 3 "grfr_register_operand" "f")))]
1846 "xma.l %0 = %1, %2, %3"
1847 [(set_attr "itanium_class" "xmpy")])
1849 (define_insn "negsi2"
1850 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1851 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
1854 [(set_attr "itanium_class" "ialu")])
1856 (define_expand "abssi2"
1858 (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1859 (set (match_operand:SI 0 "gr_register_operand" "")
1860 (if_then_else:SI (eq (match_dup 2) (const_int 0))
1861 (neg:SI (match_dup 1))
1864 { operands[2] = gen_reg_rtx (BImode); })
1866 (define_expand "sminsi3"
1868 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1869 (match_operand:SI 2 "gr_register_operand" "")))
1870 (set (match_operand:SI 0 "gr_register_operand" "")
1871 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1872 (match_dup 2) (match_dup 1)))]
1874 { operands[3] = gen_reg_rtx (BImode); })
1876 (define_expand "smaxsi3"
1878 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1879 (match_operand:SI 2 "gr_register_operand" "")))
1880 (set (match_operand:SI 0 "gr_register_operand" "")
1881 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1882 (match_dup 1) (match_dup 2)))]
1884 { operands[3] = gen_reg_rtx (BImode); })
1886 (define_expand "uminsi3"
1888 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1889 (match_operand:SI 2 "gr_register_operand" "")))
1890 (set (match_operand:SI 0 "gr_register_operand" "")
1891 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1892 (match_dup 2) (match_dup 1)))]
1894 { operands[3] = gen_reg_rtx (BImode); })
1896 (define_expand "umaxsi3"
1898 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1899 (match_operand:SI 2 "gr_register_operand" "")))
1900 (set (match_operand:SI 0 "gr_register_operand" "")
1901 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1902 (match_dup 1) (match_dup 2)))]
1904 { operands[3] = gen_reg_rtx (BImode); })
1906 (define_expand "divsi3"
1907 [(set (match_operand:SI 0 "register_operand" "")
1908 (div:SI (match_operand:SI 1 "general_operand" "")
1909 (match_operand:SI 2 "general_operand" "")))]
1910 "TARGET_INLINE_INT_DIV"
1912 rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1913 REAL_VALUE_TYPE twon34_r;
1915 op0_xf = gen_reg_rtx (XFmode);
1916 op0_di = gen_reg_rtx (DImode);
1918 if (CONSTANT_P (operands[1]))
1919 operands[1] = force_reg (SImode, operands[1]);
1920 op1_xf = gen_reg_rtx (XFmode);
1921 expand_float (op1_xf, operands[1], 0);
1923 if (CONSTANT_P (operands[2]))
1924 operands[2] = force_reg (SImode, operands[2]);
1925 op2_xf = gen_reg_rtx (XFmode);
1926 expand_float (op2_xf, operands[2], 0);
1929 real_2expN (&twon34_r, -34);
1930 twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
1931 twon34 = force_reg (XFmode, twon34);
1933 emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1935 emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
1936 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1940 (define_expand "modsi3"
1941 [(set (match_operand:SI 0 "register_operand" "")
1942 (mod:SI (match_operand:SI 1 "general_operand" "")
1943 (match_operand:SI 2 "general_operand" "")))]
1944 "TARGET_INLINE_INT_DIV"
1946 rtx op2_neg, op1_di, div;
1948 div = gen_reg_rtx (SImode);
1949 emit_insn (gen_divsi3 (div, operands[1], operands[2]));
1951 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1953 /* This is a trick to get us to reuse the value that we're sure to
1954 have already copied to the FP regs. */
1955 op1_di = gen_reg_rtx (DImode);
1956 convert_move (op1_di, operands[1], 0);
1958 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1959 gen_lowpart (SImode, op1_di)));
1963 (define_expand "udivsi3"
1964 [(set (match_operand:SI 0 "register_operand" "")
1965 (udiv:SI (match_operand:SI 1 "general_operand" "")
1966 (match_operand:SI 2 "general_operand" "")))]
1967 "TARGET_INLINE_INT_DIV"
1969 rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1970 REAL_VALUE_TYPE twon34_r;
1972 op0_xf = gen_reg_rtx (XFmode);
1973 op0_di = gen_reg_rtx (DImode);
1975 if (CONSTANT_P (operands[1]))
1976 operands[1] = force_reg (SImode, operands[1]);
1977 op1_xf = gen_reg_rtx (XFmode);
1978 expand_float (op1_xf, operands[1], 1);
1980 if (CONSTANT_P (operands[2]))
1981 operands[2] = force_reg (SImode, operands[2]);
1982 op2_xf = gen_reg_rtx (XFmode);
1983 expand_float (op2_xf, operands[2], 1);
1986 real_2expN (&twon34_r, -34);
1987 twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
1988 twon34 = force_reg (XFmode, twon34);
1990 emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1992 emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
1993 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1997 (define_expand "umodsi3"
1998 [(set (match_operand:SI 0 "register_operand" "")
1999 (umod:SI (match_operand:SI 1 "general_operand" "")
2000 (match_operand:SI 2 "general_operand" "")))]
2001 "TARGET_INLINE_INT_DIV"
2003 rtx op2_neg, op1_di, div;
2005 div = gen_reg_rtx (SImode);
2006 emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
2008 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2010 /* This is a trick to get us to reuse the value that we're sure to
2011 have already copied to the FP regs. */
2012 op1_di = gen_reg_rtx (DImode);
2013 convert_move (op1_di, operands[1], 1);
2015 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2016 gen_lowpart (SImode, op1_di)));
2020 (define_insn_and_split "divsi3_internal"
2021 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2022 (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2023 (match_operand:XF 2 "fr_register_operand" "f"))))
2024 (clobber (match_scratch:XF 4 "=&f"))
2025 (clobber (match_scratch:XF 5 "=&f"))
2026 (clobber (match_scratch:BI 6 "=c"))
2027 (use (match_operand:XF 3 "fr_register_operand" "f"))]
2028 "TARGET_INLINE_INT_DIV"
2030 "&& reload_completed"
2031 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2032 (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2033 UNSPEC_FR_RECIP_APPROX))
2034 (use (const_int 1))])
2035 (cond_exec (ne (match_dup 6) (const_int 0))
2036 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
2037 (use (const_int 1))]))
2038 (cond_exec (ne (match_dup 6) (const_int 0))
2039 (parallel [(set (match_dup 5)
2040 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
2042 (use (const_int 1))]))
2043 (cond_exec (ne (match_dup 6) (const_int 0))
2044 (parallel [(set (match_dup 4)
2045 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2047 (use (const_int 1))]))
2048 (cond_exec (ne (match_dup 6) (const_int 0))
2049 (parallel [(set (match_dup 5)
2050 (plus:XF (mult:XF (match_dup 5) (match_dup 5))
2052 (use (const_int 1))]))
2053 (cond_exec (ne (match_dup 6) (const_int 0))
2054 (parallel [(set (match_dup 0)
2055 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2057 (use (const_int 1))]))
2059 "operands[7] = CONST1_RTX (XFmode);"
2060 [(set_attr "predicable" "no")])
2062 ;; ::::::::::::::::::::
2064 ;; :: 64 bit Integer arithmetic
2066 ;; ::::::::::::::::::::
2068 (define_insn "adddi3"
2069 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
2070 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
2071 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
2077 [(set_attr "itanium_class" "ialu")])
2079 (define_insn "*adddi3_plus1"
2080 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2081 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
2082 (match_operand:DI 2 "gr_register_operand" "r"))
2085 "add %0 = %1, %2, 1"
2086 [(set_attr "itanium_class" "ialu")])
2088 ;; This has some of the same problems as shladd. We let the shladd
2089 ;; eliminator hack handle it, which results in the 1 being forced into
2090 ;; a register, but not more ugliness here.
2091 (define_insn "*adddi3_plus1_alt"
2092 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2093 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2097 "add %0 = %1, %1, 1"
2098 [(set_attr "itanium_class" "ialu")])
2100 (define_insn "subdi3"
2101 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2102 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
2103 (match_operand:DI 2 "gr_register_operand" "r")))]
2106 [(set_attr "itanium_class" "ialu")])
2108 (define_insn "*subdi3_minus1"
2109 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2110 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
2111 (match_operand:DI 2 "gr_register_operand" "r")))]
2113 "sub %0 = %2, %1, 1"
2114 [(set_attr "itanium_class" "ialu")])
2116 ;; ??? Use grfr instead of fr because of virtual register elimination
2117 ;; and silly test cases multiplying by the frame pointer.
2118 (define_insn "muldi3"
2119 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2120 (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2121 (match_operand:DI 2 "grfr_register_operand" "f")))]
2123 "xmpy.l %0 = %1, %2"
2124 [(set_attr "itanium_class" "xmpy")])
2126 ;; ??? If operand 3 is an eliminable reg, then register elimination causes the
2127 ;; same problem that we have with shladd below. Unfortunately, this case is
2128 ;; much harder to fix because the multiply puts the result in an FP register,
2129 ;; but the add needs inputs from a general register. We add a spurious clobber
2130 ;; here so that it will be present just in case register elimination gives us
2131 ;; the funny result.
2133 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2135 ;; ??? Maybe we should change how adds are canonicalized.
2137 (define_insn "madddi4"
2138 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2139 (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2140 (match_operand:DI 2 "grfr_register_operand" "f"))
2141 (match_operand:DI 3 "grfr_register_operand" "f")))
2142 (clobber (match_scratch:DI 4 "=X"))]
2144 "xma.l %0 = %1, %2, %3"
2145 [(set_attr "itanium_class" "xmpy")])
2147 ;; This can be created by register elimination if operand3 of shladd is an
2148 ;; eliminable register or has reg_equiv_constant set.
2150 ;; We have to use nonmemory_operand for operand 4, to ensure that the
2151 ;; validate_changes call inside eliminate_regs will always succeed. If it
2152 ;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
2155 (define_insn "*madddi4_elim"
2156 [(set (match_operand:DI 0 "register_operand" "=&r")
2157 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
2158 (match_operand:DI 2 "register_operand" "f"))
2159 (match_operand:DI 3 "register_operand" "f"))
2160 (match_operand:DI 4 "nonmemory_operand" "rI")))
2161 (clobber (match_scratch:DI 5 "=f"))]
2162 "reload_in_progress"
2164 [(set_attr "itanium_class" "unknown")])
2167 [(set (match_operand:DI 0 "register_operand" "")
2168 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2169 (match_operand:DI 2 "register_operand" ""))
2170 (match_operand:DI 3 "register_operand" ""))
2171 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
2172 (clobber (match_scratch:DI 5 ""))]
2174 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2176 (clobber (match_dup 0))])
2177 (set (match_dup 0) (match_dup 5))
2178 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2181 ;; ??? There are highpart multiply and add instructions, but we have no way
2182 ;; to generate them.
2184 (define_insn "smuldi3_highpart"
2185 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2188 (mult:TI (sign_extend:TI
2189 (match_operand:DI 1 "fr_register_operand" "f"))
2191 (match_operand:DI 2 "fr_register_operand" "f")))
2194 "xmpy.h %0 = %1, %2"
2195 [(set_attr "itanium_class" "xmpy")])
2197 (define_insn "umuldi3_highpart"
2198 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2201 (mult:TI (zero_extend:TI
2202 (match_operand:DI 1 "fr_register_operand" "f"))
2204 (match_operand:DI 2 "fr_register_operand" "f")))
2207 "xmpy.hu %0 = %1, %2"
2208 [(set_attr "itanium_class" "xmpy")])
2210 (define_insn "negdi2"
2211 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2212 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2215 [(set_attr "itanium_class" "ialu")])
2217 (define_expand "absdi2"
2219 (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2220 (set (match_operand:DI 0 "gr_register_operand" "")
2221 (if_then_else:DI (eq (match_dup 2) (const_int 0))
2222 (neg:DI (match_dup 1))
2225 { operands[2] = gen_reg_rtx (BImode); })
2227 (define_expand "smindi3"
2229 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2230 (match_operand:DI 2 "gr_register_operand" "")))
2231 (set (match_operand:DI 0 "gr_register_operand" "")
2232 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2233 (match_dup 2) (match_dup 1)))]
2235 { operands[3] = gen_reg_rtx (BImode); })
2237 (define_expand "smaxdi3"
2239 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2240 (match_operand:DI 2 "gr_register_operand" "")))
2241 (set (match_operand:DI 0 "gr_register_operand" "")
2242 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2243 (match_dup 1) (match_dup 2)))]
2245 { operands[3] = gen_reg_rtx (BImode); })
2247 (define_expand "umindi3"
2249 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2250 (match_operand:DI 2 "gr_register_operand" "")))
2251 (set (match_operand:DI 0 "gr_register_operand" "")
2252 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2253 (match_dup 2) (match_dup 1)))]
2255 { operands[3] = gen_reg_rtx (BImode); })
2257 (define_expand "umaxdi3"
2259 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2260 (match_operand:DI 2 "gr_register_operand" "")))
2261 (set (match_operand:DI 0 "gr_register_operand" "")
2262 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2263 (match_dup 1) (match_dup 2)))]
2265 { operands[3] = gen_reg_rtx (BImode); })
2267 (define_expand "ffsdi2"
2269 (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2270 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
2271 (set (match_dup 5) (const_int 0))
2272 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2273 (set (match_dup 4) (popcount:DI (match_dup 3)))
2274 (set (match_operand:DI 0 "gr_register_operand" "")
2275 (if_then_else:DI (ne (match_dup 6) (const_int 0))
2276 (match_dup 5) (match_dup 4)))]
2279 operands[2] = gen_reg_rtx (DImode);
2280 operands[3] = gen_reg_rtx (DImode);
2281 operands[4] = gen_reg_rtx (DImode);
2282 operands[5] = gen_reg_rtx (DImode);
2283 operands[6] = gen_reg_rtx (BImode);
2286 (define_expand "ctzdi2"
2287 [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
2289 (set (match_dup 3) (not:DI (match_dup 1)))
2290 (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
2291 (set (match_operand:DI 0 "gr_register_operand" "")
2292 (popcount:DI (match_dup 4)))]
2295 operands[2] = gen_reg_rtx (DImode);
2296 operands[3] = gen_reg_rtx (DImode);
2297 operands[4] = gen_reg_rtx (DImode);
2300 ;; Note the computation here is op0 = 63 - (exp - 0xffff).
2301 (define_expand "clzdi2"
2303 (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "")))
2305 (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
2306 (set (match_dup 4) (const_int 65598))
2307 (set (match_operand:DI 0 "gr_register_operand" "")
2308 (minus:DI (match_dup 4) (match_dup 3)))]
2311 operands[2] = gen_reg_rtx (XFmode);
2312 operands[3] = gen_reg_rtx (DImode);
2313 operands[4] = gen_reg_rtx (DImode);
2316 (define_insn "popcountdi2"
2317 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2318 (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2321 [(set_attr "itanium_class" "mmmul")])
2323 (define_insn "*getf_exp_xf"
2324 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2325 (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
2329 [(set_attr "itanium_class" "frfr")])
2331 (define_expand "divdi3"
2332 [(set (match_operand:DI 0 "register_operand" "")
2333 (div:DI (match_operand:DI 1 "general_operand" "")
2334 (match_operand:DI 2 "general_operand" "")))]
2335 "TARGET_INLINE_INT_DIV"
2337 rtx op1_xf, op2_xf, op0_xf;
2339 op0_xf = gen_reg_rtx (XFmode);
2341 if (CONSTANT_P (operands[1]))
2342 operands[1] = force_reg (DImode, operands[1]);
2343 op1_xf = gen_reg_rtx (XFmode);
2344 expand_float (op1_xf, operands[1], 0);
2346 if (CONSTANT_P (operands[2]))
2347 operands[2] = force_reg (DImode, operands[2]);
2348 op2_xf = gen_reg_rtx (XFmode);
2349 expand_float (op2_xf, operands[2], 0);
2351 if (TARGET_INLINE_INT_DIV_LAT)
2352 emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2354 emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2356 emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2360 (define_expand "moddi3"
2361 [(set (match_operand:DI 0 "register_operand" "")
2362 (mod:SI (match_operand:DI 1 "general_operand" "")
2363 (match_operand:DI 2 "general_operand" "")))]
2364 "TARGET_INLINE_INT_DIV"
2368 div = gen_reg_rtx (DImode);
2369 emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2371 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2373 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2377 (define_expand "udivdi3"
2378 [(set (match_operand:DI 0 "register_operand" "")
2379 (udiv:DI (match_operand:DI 1 "general_operand" "")
2380 (match_operand:DI 2 "general_operand" "")))]
2381 "TARGET_INLINE_INT_DIV"
2383 rtx op1_xf, op2_xf, op0_xf;
2385 op0_xf = gen_reg_rtx (XFmode);
2387 if (CONSTANT_P (operands[1]))
2388 operands[1] = force_reg (DImode, operands[1]);
2389 op1_xf = gen_reg_rtx (XFmode);
2390 expand_float (op1_xf, operands[1], 1);
2392 if (CONSTANT_P (operands[2]))
2393 operands[2] = force_reg (DImode, operands[2]);
2394 op2_xf = gen_reg_rtx (XFmode);
2395 expand_float (op2_xf, operands[2], 1);
2397 if (TARGET_INLINE_INT_DIV_LAT)
2398 emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2400 emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2402 emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2406 (define_expand "umoddi3"
2407 [(set (match_operand:DI 0 "register_operand" "")
2408 (umod:DI (match_operand:DI 1 "general_operand" "")
2409 (match_operand:DI 2 "general_operand" "")))]
2410 "TARGET_INLINE_INT_DIV"
2414 div = gen_reg_rtx (DImode);
2415 emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2417 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2419 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2423 (define_insn_and_split "divdi3_internal_lat"
2424 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2425 (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2426 (match_operand:XF 2 "fr_register_operand" "f"))))
2427 (clobber (match_scratch:XF 3 "=&f"))
2428 (clobber (match_scratch:XF 4 "=&f"))
2429 (clobber (match_scratch:XF 5 "=&f"))
2430 (clobber (match_scratch:BI 6 "=c"))]
2431 "TARGET_INLINE_INT_DIV_LAT"
2433 "&& reload_completed"
2434 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2435 (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2436 UNSPEC_FR_RECIP_APPROX))
2437 (use (const_int 1))])
2438 (cond_exec (ne (match_dup 6) (const_int 0))
2439 (parallel [(set (match_dup 3)
2440 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
2442 (use (const_int 1))]))
2443 (cond_exec (ne (match_dup 6) (const_int 0))
2444 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
2445 (use (const_int 1))]))
2446 (cond_exec (ne (match_dup 6) (const_int 0))
2447 (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
2448 (use (const_int 1))]))
2449 (cond_exec (ne (match_dup 6) (const_int 0))
2450 (parallel [(set (match_dup 4)
2451 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2453 (use (const_int 1))]))
2454 (cond_exec (ne (match_dup 6) (const_int 0))
2455 (parallel [(set (match_dup 0)
2456 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2458 (use (const_int 1))]))
2459 (cond_exec (ne (match_dup 6) (const_int 0))
2460 (parallel [(set (match_dup 3)
2461 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2463 (use (const_int 1))]))
2464 (cond_exec (ne (match_dup 6) (const_int 0))
2465 (parallel [(set (match_dup 0)
2466 (plus:XF (mult:XF (match_dup 5) (match_dup 0))
2468 (use (const_int 1))]))
2469 (cond_exec (ne (match_dup 6) (const_int 0))
2470 (parallel [(set (match_dup 4)
2471 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
2473 (use (const_int 1))]))
2474 (cond_exec (ne (match_dup 6) (const_int 0))
2475 (parallel [(set (match_dup 0)
2476 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2478 (use (const_int 1))]))
2480 "operands[7] = CONST1_RTX (XFmode);"
2481 [(set_attr "predicable" "no")])
2483 (define_insn_and_split "divdi3_internal_thr"
2484 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2485 (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2486 (match_operand:XF 2 "fr_register_operand" "f"))))
2487 (clobber (match_scratch:XF 3 "=&f"))
2488 (clobber (match_scratch:XF 4 "=f"))
2489 (clobber (match_scratch:BI 5 "=c"))]
2490 "TARGET_INLINE_INT_DIV_THR"
2492 "&& reload_completed"
2493 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2494 (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
2495 UNSPEC_FR_RECIP_APPROX))
2496 (use (const_int 1))])
2497 (cond_exec (ne (match_dup 5) (const_int 0))
2498 (parallel [(set (match_dup 3)
2499 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
2501 (use (const_int 1))]))
2502 (cond_exec (ne (match_dup 5) (const_int 0))
2503 (parallel [(set (match_dup 0)
2504 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2506 (use (const_int 1))]))
2507 (cond_exec (ne (match_dup 5) (const_int 0))
2508 (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
2509 (use (const_int 1))]))
2510 (cond_exec (ne (match_dup 5) (const_int 0))
2511 (parallel [(set (match_dup 0)
2512 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2514 (use (const_int 1))]))
2515 (cond_exec (ne (match_dup 5) (const_int 0))
2516 (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
2517 (use (const_int 1))]))
2518 (cond_exec (ne (match_dup 5) (const_int 0))
2519 (parallel [(set (match_dup 4)
2520 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
2522 (use (const_int 1))]))
2523 (cond_exec (ne (match_dup 5) (const_int 0))
2524 (parallel [(set (match_dup 0)
2525 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2527 (use (const_int 1))]))
2529 "operands[6] = CONST1_RTX (XFmode);"
2530 [(set_attr "predicable" "no")])
2532 ;; ::::::::::::::::::::
2534 ;; :: 32 bit floating point arithmetic
2536 ;; ::::::::::::::::::::
2538 (define_insn "addsf3"
2539 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2540 (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2541 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2543 "fadd.s %0 = %1, %F2"
2544 [(set_attr "itanium_class" "fmac")])
2546 (define_insn "subsf3"
2547 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2548 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2549 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2551 "fsub.s %0 = %F1, %F2"
2552 [(set_attr "itanium_class" "fmac")])
2554 (define_insn "mulsf3"
2555 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2556 (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2557 (match_operand:SF 2 "fr_register_operand" "f")))]
2559 "fmpy.s %0 = %1, %2"
2560 [(set_attr "itanium_class" "fmac")])
2562 (define_insn "abssf2"
2563 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2564 (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2567 [(set_attr "itanium_class" "fmisc")])
2569 (define_insn "negsf2"
2570 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2571 (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2574 [(set_attr "itanium_class" "fmisc")])
2576 (define_insn "*nabssf2"
2577 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2578 (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
2581 [(set_attr "itanium_class" "fmisc")])
2583 (define_insn "minsf3"
2584 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2585 (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2586 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2589 [(set_attr "itanium_class" "fmisc")])
2591 (define_insn "maxsf3"
2592 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2593 (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2594 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2597 [(set_attr "itanium_class" "fmisc")])
2599 (define_insn "*maddsf4"
2600 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2601 (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2602 (match_operand:SF 2 "fr_register_operand" "f"))
2603 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2605 "fma.s %0 = %1, %2, %F3"
2606 [(set_attr "itanium_class" "fmac")])
2608 (define_insn "*msubsf4"
2609 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2610 (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2611 (match_operand:SF 2 "fr_register_operand" "f"))
2612 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2614 "fms.s %0 = %1, %2, %F3"
2615 [(set_attr "itanium_class" "fmac")])
2617 (define_insn "*nmulsf3"
2618 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2619 (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2620 (match_operand:SF 2 "fr_register_operand" "f"))))]
2622 "fnmpy.s %0 = %1, %2"
2623 [(set_attr "itanium_class" "fmac")])
2625 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2627 (define_insn "*nmaddsf4"
2628 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2629 (plus:SF (neg:SF (mult:SF
2630 (match_operand:SF 1 "fr_register_operand" "f")
2631 (match_operand:SF 2 "fr_register_operand" "f")))
2632 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2634 "fnma.s %0 = %1, %2, %F3"
2635 [(set_attr "itanium_class" "fmac")])
2637 (define_expand "divsf3"
2638 [(set (match_operand:SF 0 "fr_register_operand" "")
2639 (div:SF (match_operand:SF 1 "fr_register_operand" "")
2640 (match_operand:SF 2 "fr_register_operand" "")))]
2641 "TARGET_INLINE_FLOAT_DIV"
2644 if (TARGET_INLINE_FLOAT_DIV_LAT)
2645 insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
2647 insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
2652 (define_insn_and_split "divsf3_internal_lat"
2653 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2654 (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2655 (match_operand:SF 2 "fr_register_operand" "f")))
2656 (clobber (match_scratch:XF 3 "=&f"))
2657 (clobber (match_scratch:XF 4 "=f"))
2658 (clobber (match_scratch:BI 5 "=c"))]
2659 "TARGET_INLINE_FLOAT_DIV_LAT"
2661 "&& reload_completed"
2662 [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2663 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2664 UNSPEC_FR_RECIP_APPROX))
2665 (use (const_int 1))])
2666 (cond_exec (ne (match_dup 5) (const_int 0))
2667 (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
2668 (use (const_int 1))]))
2669 (cond_exec (ne (match_dup 5) (const_int 0))
2670 (parallel [(set (match_dup 4)
2671 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
2673 (use (const_int 1))]))
2674 (cond_exec (ne (match_dup 5) (const_int 0))
2675 (parallel [(set (match_dup 3)
2676 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2678 (use (const_int 1))]))
2679 (cond_exec (ne (match_dup 5) (const_int 0))
2680 (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
2681 (use (const_int 1))]))
2682 (cond_exec (ne (match_dup 5) (const_int 0))
2683 (parallel [(set (match_dup 3)
2684 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2686 (use (const_int 1))]))
2687 (cond_exec (ne (match_dup 5) (const_int 0))
2688 (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
2689 (use (const_int 1))]))
2690 (cond_exec (ne (match_dup 5) (const_int 0))
2691 (parallel [(set (match_dup 9)
2693 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2695 (use (const_int 1))]))
2696 (cond_exec (ne (match_dup 5) (const_int 0))
2698 (float_truncate:SF (match_dup 6))))
2701 operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2702 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2703 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2704 operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2705 operands[10] = CONST1_RTX (XFmode);
2707 [(set_attr "predicable" "no")])
2709 (define_insn_and_split "divsf3_internal_thr"
2710 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2711 (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2712 (match_operand:SF 2 "fr_register_operand" "f")))
2713 (clobber (match_scratch:XF 3 "=&f"))
2714 (clobber (match_scratch:XF 4 "=f"))
2715 (clobber (match_scratch:BI 5 "=c"))]
2716 "TARGET_INLINE_FLOAT_DIV_THR"
2718 "&& reload_completed"
2719 [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2720 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2721 UNSPEC_FR_RECIP_APPROX))
2722 (use (const_int 1))])
2723 (cond_exec (ne (match_dup 5) (const_int 0))
2724 (parallel [(set (match_dup 3)
2725 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
2727 (use (const_int 1))]))
2728 (cond_exec (ne (match_dup 5) (const_int 0))
2729 (parallel [(set (match_dup 3)
2730 (plus:XF (mult:XF (match_dup 3) (match_dup 3))
2732 (use (const_int 1))]))
2733 (cond_exec (ne (match_dup 5) (const_int 0))
2734 (parallel [(set (match_dup 6)
2735 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
2737 (use (const_int 1))]))
2738 (cond_exec (ne (match_dup 5) (const_int 0))
2739 (parallel [(set (match_dup 9)
2741 (mult:XF (match_dup 7) (match_dup 6))))
2742 (use (const_int 1))]))
2743 (cond_exec (ne (match_dup 5) (const_int 0))
2744 (parallel [(set (match_dup 4)
2745 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 3)))
2747 (use (const_int 1))]))
2748 (cond_exec (ne (match_dup 5) (const_int 0))
2751 (plus:XF (mult:XF (match_dup 4) (match_dup 6))
2755 operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2756 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2757 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2758 operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
2759 operands[10] = CONST1_RTX (XFmode);
2761 [(set_attr "predicable" "no")])
2763 ;; Inline square root.
2765 (define_insn "*sqrt_approx"
2766 [(set (match_operand:XF 0 "fr_register_operand" "=f")
2767 (div:XF (const_int 1)
2768 (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
2769 (set (match_operand:BI 1 "register_operand" "=c")
2770 (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
2771 (use (match_operand:SI 3 "const_int_operand" "")) ]
2773 "frsqrta.s%3 %0, %1 = %2"
2774 [(set_attr "itanium_class" "fmisc")
2775 (set_attr "predicable" "no")])
2777 (define_insn "*setf_exp_xf"
2778 [(set (match_operand:XF 0 "fr_register_operand" "=f")
2779 (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
2783 [(set_attr "itanium_class" "frfr")])
2785 (define_expand "sqrtsf2"
2786 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2787 (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2788 "TARGET_INLINE_SQRT"
2791 if (TARGET_INLINE_SQRT_LAT)
2793 insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
2798 insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
2803 ;; Latency-optimized square root.
2804 ;; FIXME: Implement.
2806 ;; Throughput-optimized square root.
2808 (define_insn_and_split "sqrtsf2_internal_thr"
2809 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2810 (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))
2811 ;; Register r2 in optimization guide.
2812 (clobber (match_scratch:DI 2 "=r"))
2813 ;; Register f8 in optimization guide
2814 (clobber (match_scratch:XF 3 "=&f"))
2815 ;; Register f9 in optimization guide
2816 (clobber (match_scratch:XF 4 "=&f"))
2817 ;; Register f10 in optimization guide
2818 (clobber (match_scratch:XF 5 "=&f"))
2819 ;; Register p6 in optimization guide.
2820 (clobber (match_scratch:BI 6 "=c"))]
2821 "TARGET_INLINE_SQRT_THR"
2823 "&& reload_completed"
2824 [ ;; exponent of +1/2 in r2
2825 (set (match_dup 2) (const_int 65534))
2828 (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
2830 ;; y0 = 1/sqrt(a) in f7
2831 (parallel [(set (match_dup 7)
2832 (div:XF (const_int 1)
2833 (sqrt:XF (match_dup 8))))
2835 (unspec:BI [(match_dup 8)]
2836 UNSPEC_FR_SQRT_RECIP_APPROX))
2837 (use (const_int 0))])
2839 ;; H0 = 1/2 * y0 in f9
2840 (cond_exec (ne (match_dup 6) (const_int 0))
2841 (parallel [(set (match_dup 4)
2842 (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2844 (use (const_int 1))]))
2846 ;; S0 = a * y0 in f7
2847 (cond_exec (ne (match_dup 6) (const_int 0))
2848 (parallel [(set (match_dup 7)
2849 (plus:XF (mult:XF (match_dup 8) (match_dup 7))
2851 (use (const_int 1))]))
2853 ;; d = 1/2 - S0 * H0 in f10
2854 (cond_exec (ne (match_dup 6) (const_int 0))
2855 (parallel [(set (match_dup 5)
2856 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 4)))
2858 (use (const_int 1))]))
2860 ;; d' = d + 1/2 * d in f8
2861 (cond_exec (ne (match_dup 6) (const_int 0))
2862 (parallel [(set (match_dup 3)
2863 (plus:XF (mult:XF (match_dup 3) (match_dup 5))
2865 (use (const_int 1))]))
2867 ;; e = d + d * d' in f8
2868 (cond_exec (ne (match_dup 6) (const_int 0))
2869 (parallel [(set (match_dup 3)
2870 (plus:XF (mult:XF (match_dup 5) (match_dup 3))
2872 (use (const_int 1))]))
2874 ;; S1 = S0 + e * S0 in f7
2875 (cond_exec (ne (match_dup 6) (const_int 0))
2876 (parallel [(set (match_dup 0)
2878 (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2880 (use (const_int 1))]))
2882 ;; H1 = H0 + e * H0 in f8
2883 (cond_exec (ne (match_dup 6) (const_int 0))
2884 (parallel [(set (match_dup 3)
2885 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2887 (use (const_int 1))]))
2889 ;; d1 = a - S1 * S1 in f9
2890 (cond_exec (ne (match_dup 6) (const_int 0))
2891 (parallel [(set (match_dup 4)
2892 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
2894 (use (const_int 1))]))
2896 ;; S = S1 + d1 * H1 in f7
2897 (cond_exec (ne (match_dup 6) (const_int 0))
2898 (parallel [(set (match_dup 0)
2900 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2902 (use (const_int 0))]))]
2904 /* Generate 82-bit versions of the input and output operands. */
2905 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2906 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2907 /* Generate required floating-point constants. */
2908 operands[9] = CONST0_RTX (XFmode);
2910 [(set_attr "predicable" "no")])
2912 ;; ::::::::::::::::::::
2914 ;; :: 64 bit floating point arithmetic
2916 ;; ::::::::::::::::::::
2918 (define_insn "adddf3"
2919 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2920 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2921 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2923 "fadd.d %0 = %1, %F2"
2924 [(set_attr "itanium_class" "fmac")])
2926 (define_insn "*adddf3_trunc"
2927 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2929 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2930 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2932 "fadd.s %0 = %1, %F2"
2933 [(set_attr "itanium_class" "fmac")])
2935 (define_insn "subdf3"
2936 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2937 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2938 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2940 "fsub.d %0 = %F1, %F2"
2941 [(set_attr "itanium_class" "fmac")])
2943 (define_insn "*subdf3_trunc"
2944 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2946 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2947 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2949 "fsub.s %0 = %F1, %F2"
2950 [(set_attr "itanium_class" "fmac")])
2952 (define_insn "muldf3"
2953 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2954 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2955 (match_operand:DF 2 "fr_register_operand" "f")))]
2957 "fmpy.d %0 = %1, %2"
2958 [(set_attr "itanium_class" "fmac")])
2960 (define_insn "*muldf3_trunc"
2961 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2963 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2964 (match_operand:DF 2 "fr_register_operand" "f"))))]
2966 "fmpy.s %0 = %1, %2"
2967 [(set_attr "itanium_class" "fmac")])
2969 (define_insn "absdf2"
2970 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2971 (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2974 [(set_attr "itanium_class" "fmisc")])
2976 (define_insn "negdf2"
2977 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2978 (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2981 [(set_attr "itanium_class" "fmisc")])
2983 (define_insn "*nabsdf2"
2984 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2985 (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
2988 [(set_attr "itanium_class" "fmisc")])
2990 (define_insn "mindf3"
2991 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2992 (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
2993 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2996 [(set_attr "itanium_class" "fmisc")])
2998 (define_insn "maxdf3"
2999 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3000 (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
3001 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
3004 [(set_attr "itanium_class" "fmisc")])
3006 (define_insn "*madddf4"
3007 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3008 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3009 (match_operand:DF 2 "fr_register_operand" "f"))
3010 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3012 "fma.d %0 = %1, %2, %F3"
3013 [(set_attr "itanium_class" "fmac")])
3015 (define_insn "*madddf4_trunc"
3016 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3018 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3019 (match_operand:DF 2 "fr_register_operand" "f"))
3020 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3022 "fma.s %0 = %1, %2, %F3"
3023 [(set_attr "itanium_class" "fmac")])
3025 (define_insn "*msubdf4"
3026 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3027 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3028 (match_operand:DF 2 "fr_register_operand" "f"))
3029 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3031 "fms.d %0 = %1, %2, %F3"
3032 [(set_attr "itanium_class" "fmac")])
3034 (define_insn "*msubdf4_trunc"
3035 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3037 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3038 (match_operand:DF 2 "fr_register_operand" "f"))
3039 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3041 "fms.s %0 = %1, %2, %F3"
3042 [(set_attr "itanium_class" "fmac")])
3044 (define_insn "*nmuldf3"
3045 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3046 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3047 (match_operand:DF 2 "fr_register_operand" "f"))))]
3049 "fnmpy.d %0 = %1, %2"
3050 [(set_attr "itanium_class" "fmac")])
3052 (define_insn "*nmuldf3_trunc"
3053 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3055 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3056 (match_operand:DF 2 "fr_register_operand" "f")))))]
3058 "fnmpy.s %0 = %1, %2"
3059 [(set_attr "itanium_class" "fmac")])
3061 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3063 (define_insn "*nmadddf4"
3064 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3065 (plus:DF (neg:DF (mult:DF
3066 (match_operand:DF 1 "fr_register_operand" "f")
3067 (match_operand:DF 2 "fr_register_operand" "f")))
3068 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3070 "fnma.d %0 = %1, %2, %F3"
3071 [(set_attr "itanium_class" "fmac")])
3073 (define_insn "*nmadddf4_alts"
3074 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3075 (plus:DF (neg:DF (mult:DF
3076 (match_operand:DF 1 "fr_register_operand" "f")
3077 (match_operand:DF 2 "fr_register_operand" "f")))
3078 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
3079 (use (match_operand:SI 4 "const_int_operand" ""))]
3081 "fnma.d.s%4 %0 = %1, %2, %F3"
3082 [(set_attr "itanium_class" "fmac")])
3084 (define_insn "*nmadddf4_trunc"
3085 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3087 (plus:DF (neg:DF (mult:DF
3088 (match_operand:DF 1 "fr_register_operand" "f")
3089 (match_operand:DF 2 "fr_register_operand" "f")))
3090 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3092 "fnma.s %0 = %1, %2, %F3"
3093 [(set_attr "itanium_class" "fmac")])
3095 (define_expand "divdf3"
3096 [(set (match_operand:DF 0 "fr_register_operand" "")
3097 (div:DF (match_operand:DF 1 "fr_register_operand" "")
3098 (match_operand:DF 2 "fr_register_operand" "")))]
3099 "TARGET_INLINE_FLOAT_DIV"
3102 if (TARGET_INLINE_FLOAT_DIV_LAT)
3103 insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
3105 insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
3110 (define_insn_and_split "divdf3_internal_lat"
3111 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3112 (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3113 (match_operand:DF 2 "fr_register_operand" "f")))
3114 (clobber (match_scratch:XF 3 "=&f"))
3115 (clobber (match_scratch:XF 4 "=&f"))
3116 (clobber (match_scratch:XF 5 "=&f"))
3117 (clobber (match_scratch:BI 6 "=c"))]
3118 "TARGET_INLINE_FLOAT_DIV_LAT"
3120 "&& reload_completed"
3121 [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
3122 (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3123 UNSPEC_FR_RECIP_APPROX))
3124 (use (const_int 1))])
3125 (cond_exec (ne (match_dup 6) (const_int 0))
3126 (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
3127 (use (const_int 1))]))
3128 (cond_exec (ne (match_dup 6) (const_int 0))
3129 (parallel [(set (match_dup 4)
3130 (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 7)))
3132 (use (const_int 1))]))
3133 (cond_exec (ne (match_dup 6) (const_int 0))
3134 (parallel [(set (match_dup 3)
3135 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3137 (use (const_int 1))]))
3138 (cond_exec (ne (match_dup 6) (const_int 0))
3139 (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
3140 (use (const_int 1))]))
3141 (cond_exec (ne (match_dup 6) (const_int 0))
3142 (parallel [(set (match_dup 7)
3143 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3145 (use (const_int 1))]))
3146 (cond_exec (ne (match_dup 6) (const_int 0))
3147 (parallel [(set (match_dup 3)
3148 (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3150 (use (const_int 1))]))
3151 (cond_exec (ne (match_dup 6) (const_int 0))
3152 (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
3153 (use (const_int 1))]))
3154 (cond_exec (ne (match_dup 6) (const_int 0))
3155 (parallel [(set (match_dup 7)
3156 (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3158 (use (const_int 1))]))
3159 (cond_exec (ne (match_dup 6) (const_int 0))
3160 (parallel [(set (match_dup 10)
3162 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3164 (use (const_int 1))]))
3165 (cond_exec (ne (match_dup 6) (const_int 0))
3166 (parallel [(set (match_dup 7)
3167 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3169 (use (const_int 1))]))
3170 (cond_exec (ne (match_dup 6) (const_int 0))
3171 (parallel [(set (match_dup 11)
3173 (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 3)))
3175 (use (const_int 1))]))
3176 (cond_exec (ne (match_dup 6) (const_int 0))
3178 (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3182 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3183 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3184 operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3185 operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3186 operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3187 operands[12] = CONST1_RTX (XFmode);
3189 [(set_attr "predicable" "no")])
3191 (define_insn_and_split "divdf3_internal_thr"
3192 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3193 (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3194 (match_operand:DF 2 "fr_register_operand" "f")))
3195 (clobber (match_scratch:XF 3 "=&f"))
3196 (clobber (match_scratch:DF 4 "=f"))
3197 (clobber (match_scratch:BI 5 "=c"))]
3198 "TARGET_INLINE_FLOAT_DIV_THR"
3200 "&& reload_completed"
3201 [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3202 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3203 UNSPEC_FR_RECIP_APPROX))
3204 (use (const_int 1))])
3205 (cond_exec (ne (match_dup 5) (const_int 0))
3206 (parallel [(set (match_dup 3)
3207 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
3209 (use (const_int 1))]))
3210 (cond_exec (ne (match_dup 5) (const_int 0))
3211 (parallel [(set (match_dup 6)
3212 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3214 (use (const_int 1))]))
3215 (cond_exec (ne (match_dup 5) (const_int 0))
3216 (parallel [(set (match_dup 3)
3217 (mult:XF (match_dup 3) (match_dup 3)))
3218 (use (const_int 1))]))
3219 (cond_exec (ne (match_dup 5) (const_int 0))
3220 (parallel [(set (match_dup 6)
3221 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3223 (use (const_int 1))]))
3224 (cond_exec (ne (match_dup 5) (const_int 0))
3225 (parallel [(set (match_dup 3)
3226 (mult:XF (match_dup 3) (match_dup 3)))
3227 (use (const_int 1))]))
3228 (cond_exec (ne (match_dup 5) (const_int 0))
3229 (parallel [(set (match_dup 6)
3230 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3232 (use (const_int 1))]))
3233 (cond_exec (ne (match_dup 5) (const_int 0))
3234 (parallel [(set (match_dup 9)
3236 (mult:XF (match_dup 7) (match_dup 3))))
3237 (use (const_int 1))]))
3238 (cond_exec (ne (match_dup 5) (const_int 0))
3239 (parallel [(set (match_dup 4)
3240 (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
3242 (use (const_int 1))]))
3243 (cond_exec (ne (match_dup 5) (const_int 0))
3245 (plus:DF (mult:DF (match_dup 4) (match_dup 0))
3249 operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3250 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3251 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3252 operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3253 operands[10] = CONST1_RTX (XFmode);
3255 [(set_attr "predicable" "no")])
3257 ;; Inline square root.
3259 (define_expand "sqrtdf2"
3260 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3261 (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3262 "TARGET_INLINE_SQRT"
3265 if (TARGET_INLINE_SQRT_LAT)
3267 insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
3272 insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
3277 ;; Latency-optimized square root.
3278 ;; FIXME: Implement.
3280 ;; Throughput-optimized square root.
3282 (define_insn_and_split "sqrtdf2_internal_thr"
3283 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3284 (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))
3285 ;; Register r2 in optimization guide.
3286 (clobber (match_scratch:DI 2 "=r"))
3287 ;; Register f8 in optimization guide
3288 (clobber (match_scratch:XF 3 "=&f"))
3289 ;; Register f9 in optimization guide
3290 (clobber (match_scratch:XF 4 "=&f"))
3291 ;; Register f10 in optimization guide
3292 (clobber (match_scratch:XF 5 "=&f"))
3293 ;; Register p6 in optimization guide.
3294 (clobber (match_scratch:BI 6 "=c"))]
3295 "TARGET_INLINE_SQRT_THR"
3297 "&& reload_completed"
3298 [ ;; exponent of +1/2 in r2
3299 (set (match_dup 2) (const_int 65534))
3302 (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3304 ;; y0 = 1/sqrt(a) in f7
3305 (parallel [(set (match_dup 7)
3306 (div:XF (const_int 1)
3307 (sqrt:XF (match_dup 8))))
3309 (unspec:BI [(match_dup 8)]
3310 UNSPEC_FR_SQRT_RECIP_APPROX))
3311 (use (const_int 0))])
3313 ;; H0 = 1/2 * y0 in f8
3314 (cond_exec (ne (match_dup 6) (const_int 0))
3315 (parallel [(set (match_dup 3)
3316 (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3318 (use (const_int 1))]))
3320 ;; G0 = a * y0 in f7
3321 (cond_exec (ne (match_dup 6) (const_int 0))
3322 (parallel [(set (match_dup 7)
3323 (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3325 (use (const_int 1))]))
3327 ;; r0 = 1/2 - G0 * H0 in f9
3328 (cond_exec (ne (match_dup 6) (const_int 0))
3329 (parallel [(set (match_dup 4)
3330 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
3332 (use (const_int 1))]))
3334 ;; H1 = H0 + r0 * H0 in f8
3335 (cond_exec (ne (match_dup 6) (const_int 0))
3336 (parallel [(set (match_dup 3)
3337 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3339 (use (const_int 1))]))
3341 ;; G1 = G0 + r0 * G0 in f7
3342 (cond_exec (ne (match_dup 6) (const_int 0))
3343 (parallel [(set (match_dup 7)
3344 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3346 (use (const_int 1))]))
3348 ;; r1 = 1/2 - G1 * H1 in f9
3349 (cond_exec (ne (match_dup 6) (const_int 0))
3350 (parallel [(set (match_dup 4)
3351 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
3353 (use (const_int 1))]))
3355 ;; H2 = H1 + r1 * H1 in f8
3356 (cond_exec (ne (match_dup 6) (const_int 0))
3357 (parallel [(set (match_dup 3)
3358 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3360 (use (const_int 1))]))
3362 ;; G2 = G1 + r1 * G1 in f7
3363 (cond_exec (ne (match_dup 6) (const_int 0))
3364 (parallel [(set (match_dup 7)
3365 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3367 (use (const_int 1))]))
3369 ;; d2 = a - G2 * G2 in f9
3370 (cond_exec (ne (match_dup 6) (const_int 0))
3371 (parallel [(set (match_dup 4)
3372 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
3374 (use (const_int 1))]))
3376 ;; G3 = G2 + d2 * H2 in f7
3377 (cond_exec (ne (match_dup 6) (const_int 0))
3378 (parallel [(set (match_dup 7)
3379 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3381 (use (const_int 1))]))
3383 ;; d3 = a - G3 * G3 in f9
3384 (cond_exec (ne (match_dup 6) (const_int 0))
3385 (parallel [(set (match_dup 4)
3386 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
3388 (use (const_int 1))]))
3390 ;; S = G3 + d3 * H2 in f7
3391 (cond_exec (ne (match_dup 6) (const_int 0))
3392 (parallel [(set (match_dup 0)
3394 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3396 (use (const_int 0))]))]
3398 /* Generate 82-bit versions of the input and output operands. */
3399 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3400 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3401 /* Generate required floating-point constants. */
3402 operands[9] = CONST0_RTX (XFmode);
3404 [(set_attr "predicable" "no")])
3406 ;; ::::::::::::::::::::
3408 ;; :: 80 bit floating point arithmetic
3410 ;; ::::::::::::::::::::
3412 (define_insn "addxf3"
3413 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3414 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3415 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3417 "fadd %0 = %F1, %F2"
3418 [(set_attr "itanium_class" "fmac")])
3420 (define_insn "*addxf3_truncsf"
3421 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3423 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3424 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3426 "fadd.s %0 = %F1, %F2"
3427 [(set_attr "itanium_class" "fmac")])
3429 (define_insn "*addxf3_truncdf"
3430 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3432 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3433 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3435 "fadd.d %0 = %F1, %F2"
3436 [(set_attr "itanium_class" "fmac")])
3438 (define_insn "subxf3"
3439 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3440 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3441 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3443 "fsub %0 = %F1, %F2"
3444 [(set_attr "itanium_class" "fmac")])
3446 (define_insn "*subxf3_truncsf"
3447 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3449 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3450 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3452 "fsub.s %0 = %F1, %F2"
3453 [(set_attr "itanium_class" "fmac")])
3455 (define_insn "*subxf3_truncdf"
3456 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3458 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3459 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3461 "fsub.d %0 = %F1, %F2"
3462 [(set_attr "itanium_class" "fmac")])
3464 (define_insn "mulxf3"
3465 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3466 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3467 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3469 "fmpy %0 = %F1, %F2"
3470 [(set_attr "itanium_class" "fmac")])
3472 (define_insn "*mulxf3_truncsf"
3473 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3475 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3476 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3478 "fmpy.s %0 = %F1, %F2"
3479 [(set_attr "itanium_class" "fmac")])
3481 (define_insn "*mulxf3_truncdf"
3482 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3484 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3485 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3487 "fmpy.d %0 = %F1, %F2"
3488 [(set_attr "itanium_class" "fmac")])
3490 (define_insn "*mulxf3_alts"
3491 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3492 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3493 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3494 (use (match_operand:SI 3 "const_int_operand" ""))]
3496 "fmpy.s%3 %0 = %F1, %F2"
3497 [(set_attr "itanium_class" "fmac")])
3499 (define_insn "*mulxf3_truncsf_alts"
3500 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3502 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3503 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3504 (use (match_operand:SI 3 "const_int_operand" ""))]
3506 "fmpy.s.s%3 %0 = %F1, %F2"
3507 [(set_attr "itanium_class" "fmac")])
3509 (define_insn "*mulxf3_truncdf_alts"
3510 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3512 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3513 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3514 (use (match_operand:SI 3 "const_int_operand" ""))]
3516 "fmpy.d.s%3 %0 = %F1, %F2"
3517 [(set_attr "itanium_class" "fmac")])
3519 (define_insn "absxf2"
3520 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3521 (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3524 [(set_attr "itanium_class" "fmisc")])
3526 (define_insn "negxf2"
3527 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3528 (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3531 [(set_attr "itanium_class" "fmisc")])
3533 (define_insn "*nabsxf2"
3534 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3535 (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
3538 [(set_attr "itanium_class" "fmisc")])
3540 (define_insn "minxf3"
3541 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3542 (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3543 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3545 "fmin %0 = %F1, %F2"
3546 [(set_attr "itanium_class" "fmisc")])
3548 (define_insn "maxxf3"
3549 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3550 (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3551 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3553 "fmax %0 = %F1, %F2"
3554 [(set_attr "itanium_class" "fmisc")])
3556 (define_insn "*maddxf4"
3557 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3558 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3559 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3560 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3562 "fma %0 = %F1, %F2, %F3"
3563 [(set_attr "itanium_class" "fmac")])
3565 (define_insn "*maddxf4_truncsf"
3566 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3568 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3569 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3570 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3572 "fma.s %0 = %F1, %F2, %F3"
3573 [(set_attr "itanium_class" "fmac")])
3575 (define_insn "*maddxf4_truncdf"
3576 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3578 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3579 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3580 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3582 "fma.d %0 = %F1, %F2, %F3"
3583 [(set_attr "itanium_class" "fmac")])
3585 (define_insn "*maddxf4_alts"
3586 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3587 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3588 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3589 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
3590 (use (match_operand:SI 4 "const_int_operand" ""))]
3592 "fma.s%4 %0 = %F1, %F2, %F3"
3593 [(set_attr "itanium_class" "fmac")])
3595 (define_insn "*maddxf4_alts_truncsf"
3596 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3598 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3599 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3600 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3601 (use (match_operand:SI 4 "const_int_operand" ""))]
3603 "fma.s.s%4 %0 = %F1, %F2, %F3"
3604 [(set_attr "itanium_class" "fmac")])
3606 (define_insn "*maddxf4_alts_truncdf"
3607 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3609 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3610 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3611 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3612 (use (match_operand:SI 4 "const_int_operand" ""))]
3614 "fma.d.s%4 %0 = %F1, %F2, %F3"
3615 [(set_attr "itanium_class" "fmac")])
3617 (define_insn "*msubxf4"
3618 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3619 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3620 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3621 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3623 "fms %0 = %F1, %F2, %F3"
3624 [(set_attr "itanium_class" "fmac")])
3626 (define_insn "*msubxf4_truncsf"
3627 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3629 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3630 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3631 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3633 "fms.s %0 = %F1, %F2, %F3"
3634 [(set_attr "itanium_class" "fmac")])
3636 (define_insn "*msubxf4_truncdf"
3637 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3639 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3640 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3641 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3643 "fms.d %0 = %F1, %F2, %F3"
3644 [(set_attr "itanium_class" "fmac")])
3646 (define_insn "*nmulxf3"
3647 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3648 (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3649 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3651 "fnmpy %0 = %F1, %F2"
3652 [(set_attr "itanium_class" "fmac")])
3654 (define_insn "*nmulxf3_truncsf"
3655 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3658 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3659 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3661 "fnmpy.s %0 = %F1, %F2"
3662 [(set_attr "itanium_class" "fmac")])
3664 (define_insn "*nmulxf3_truncdf"
3665 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3668 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3669 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3671 "fnmpy.d %0 = %F1, %F2"
3672 [(set_attr "itanium_class" "fmac")])
3674 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3676 (define_insn "*nmaddxf4"
3677 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3678 (plus:XF (neg:XF (mult:XF
3679 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3680 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3681 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3683 "fnma %0 = %F1, %F2, %F3"
3684 [(set_attr "itanium_class" "fmac")])
3686 (define_insn "*nmaddxf4_truncsf"
3687 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3689 (plus:XF (neg:XF (mult:XF
3690 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3691 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3692 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3694 "fnma.s %0 = %F1, %F2, %F3"
3695 [(set_attr "itanium_class" "fmac")])
3697 (define_insn "*nmaddxf4_truncdf"
3698 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3700 (plus:XF (neg:XF (mult:XF
3701 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3702 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3703 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3705 "fnma.d %0 = %F1, %F2, %F3"
3706 [(set_attr "itanium_class" "fmac")])
3708 (define_insn "*nmaddxf4_alts"
3709 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3710 (plus:XF (neg:XF (mult:XF
3711 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3712 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3713 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
3714 (use (match_operand:SI 4 "const_int_operand" ""))]
3716 "fnma.s%4 %0 = %F1, %F2, %F3"
3717 [(set_attr "itanium_class" "fmac")])
3719 (define_insn "*nmaddxf4_truncdf_alts"
3720 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3724 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3725 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3726 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3727 (use (match_operand:SI 4 "const_int_operand" ""))]
3729 "fnma.d.s%4 %0 = %F1, %F2, %F3"
3730 [(set_attr "itanium_class" "fmac")])
3732 (define_expand "divxf3"
3733 [(set (match_operand:XF 0 "fr_register_operand" "")
3734 (div:XF (match_operand:XF 1 "fr_register_operand" "")
3735 (match_operand:XF 2 "fr_register_operand" "")))]
3736 "TARGET_INLINE_FLOAT_DIV"
3739 if (TARGET_INLINE_FLOAT_DIV_LAT)
3740 insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
3742 insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
3747 (define_insn_and_split "divxf3_internal_lat"
3748 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3749 (div:XF (match_operand:XF 1 "fr_register_operand" "f")
3750 (match_operand:XF 2 "fr_register_operand" "f")))
3751 (clobber (match_scratch:XF 3 "=&f"))
3752 (clobber (match_scratch:XF 4 "=&f"))
3753 (clobber (match_scratch:XF 5 "=&f"))
3754 (clobber (match_scratch:XF 6 "=&f"))
3755 (clobber (match_scratch:BI 7 "=c"))]
3756 "TARGET_INLINE_FLOAT_DIV_LAT"
3758 "&& reload_completed"
3759 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
3760 (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
3761 UNSPEC_FR_RECIP_APPROX))
3762 (use (const_int 1))])
3763 (cond_exec (ne (match_dup 7) (const_int 0))
3764 (parallel [(set (match_dup 3)
3765 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3767 (use (const_int 1))]))
3768 (cond_exec (ne (match_dup 7) (const_int 0))
3769 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
3770 (use (const_int 1))]))
3771 (cond_exec (ne (match_dup 7) (const_int 0))
3772 (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
3773 (use (const_int 1))]))
3774 (cond_exec (ne (match_dup 7) (const_int 0))
3775 (parallel [(set (match_dup 6)
3776 (plus:XF (mult:XF (match_dup 3) (match_dup 3))
3778 (use (const_int 1))]))
3779 (cond_exec (ne (match_dup 7) (const_int 0))
3780 (parallel [(set (match_dup 3)
3781 (plus:XF (mult:XF (match_dup 5) (match_dup 5))
3783 (use (const_int 1))]))
3784 (cond_exec (ne (match_dup 7) (const_int 0))
3785 (parallel [(set (match_dup 5)
3786 (plus:XF (mult:XF (match_dup 6) (match_dup 0))
3788 (use (const_int 1))]))
3789 (cond_exec (ne (match_dup 7) (const_int 0))
3790 (parallel [(set (match_dup 0)
3791 (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3793 (use (const_int 1))]))
3794 (cond_exec (ne (match_dup 7) (const_int 0))
3795 (parallel [(set (match_dup 4)
3796 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
3798 (use (const_int 1))]))
3799 (cond_exec (ne (match_dup 7) (const_int 0))
3800 (parallel [(set (match_dup 3)
3801 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
3803 (use (const_int 1))]))
3804 (cond_exec (ne (match_dup 7) (const_int 0))
3805 (parallel [(set (match_dup 5)
3806 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3808 (use (const_int 1))]))
3809 (cond_exec (ne (match_dup 7) (const_int 0))
3810 (parallel [(set (match_dup 0)
3811 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3813 (use (const_int 1))]))
3814 (cond_exec (ne (match_dup 7) (const_int 0))
3815 (parallel [(set (match_dup 4)
3816 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
3818 (use (const_int 1))]))
3819 (cond_exec (ne (match_dup 7) (const_int 0))
3821 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3824 "operands[8] = CONST1_RTX (XFmode);"
3825 [(set_attr "predicable" "no")])
3827 (define_insn_and_split "divxf3_internal_thr"
3828 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3829 (div:XF (match_operand:XF 1 "fr_register_operand" "f")
3830 (match_operand:XF 2 "fr_register_operand" "f")))
3831 (clobber (match_scratch:XF 3 "=&f"))
3832 (clobber (match_scratch:XF 4 "=&f"))
3833 (clobber (match_scratch:BI 5 "=c"))]
3834 "TARGET_INLINE_FLOAT_DIV_THR"
3836 "&& reload_completed"
3837 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
3838 (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
3839 UNSPEC_FR_RECIP_APPROX))
3840 (use (const_int 1))])
3841 (cond_exec (ne (match_dup 5) (const_int 0))
3842 (parallel [(set (match_dup 3)
3843 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3845 (use (const_int 1))]))
3846 (cond_exec (ne (match_dup 5) (const_int 0))
3847 (parallel [(set (match_dup 4)
3848 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
3850 (use (const_int 1))]))
3851 (cond_exec (ne (match_dup 5) (const_int 0))
3852 (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
3853 (use (const_int 1))]))
3854 (cond_exec (ne (match_dup 5) (const_int 0))
3855 (parallel [(set (match_dup 3)
3856 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
3858 (use (const_int 1))]))
3859 (cond_exec (ne (match_dup 5) (const_int 0))
3860 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
3861 (use (const_int 1))]))
3862 (cond_exec (ne (match_dup 5) (const_int 0))
3863 (parallel [(set (match_dup 0)
3864 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
3866 (use (const_int 1))]))
3867 (cond_exec (ne (match_dup 5) (const_int 0))
3868 (parallel [(set (match_dup 0)
3869 (plus:XF (mult:XF (match_dup 0) (match_dup 3))
3871 (use (const_int 1))]))
3872 (cond_exec (ne (match_dup 5) (const_int 0))
3873 (parallel [(set (match_dup 3)
3874 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
3876 (use (const_int 1))]))
3877 (cond_exec (ne (match_dup 5) (const_int 0))
3878 (parallel [(set (match_dup 3)
3879 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
3881 (use (const_int 1))]))
3882 (cond_exec (ne (match_dup 5) (const_int 0))
3883 (parallel [(set (match_dup 4)
3884 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3886 (use (const_int 1))]))
3887 (cond_exec (ne (match_dup 5) (const_int 0))
3888 (parallel [(set (match_dup 0)
3889 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3891 (use (const_int 1))]))
3892 (cond_exec (ne (match_dup 5) (const_int 0))
3893 (parallel [(set (match_dup 4)
3894 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
3896 (use (const_int 1))]))
3897 (cond_exec (ne (match_dup 5) (const_int 0))
3899 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3902 "operands[6] = CONST1_RTX (XFmode);"
3903 [(set_attr "predicable" "no")])
3905 ;; Inline square root.
3907 (define_expand "sqrtxf2"
3908 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3909 (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))]
3910 "TARGET_INLINE_SQRT"
3913 if (TARGET_INLINE_SQRT_LAT)
3915 insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
3920 insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]);
3925 ;; Latency-optimized square root.
3926 ;; FIXME: Implement.
3928 ;; Throughput-optimized square root.
3930 (define_insn_and_split "sqrtxf2_internal_thr"
3931 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3932 (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))
3933 ;; Register r2 in optimization guide.
3934 (clobber (match_scratch:DI 2 "=r"))
3935 ;; Register f8 in optimization guide
3936 (clobber (match_scratch:XF 3 "=&f"))
3937 ;; Register f9 in optimization guide
3938 (clobber (match_scratch:XF 4 "=&f"))
3939 ;; Register f10 in optimization guide
3940 (clobber (match_scratch:XF 5 "=&f"))
3941 ;; Register f11 in optimization guide
3942 (clobber (match_scratch:XF 6 "=&f"))
3943 ;; Register p6 in optimization guide.
3944 (clobber (match_scratch:BI 7 "=c"))]
3945 "TARGET_INLINE_SQRT_THR"
3947 "&& reload_completed"
3948 [ ;; exponent of +1/2 in r2
3949 (set (match_dup 2) (const_int 65534))
3950 ;; +1/2 in f8. The Intel manual mistakenly specifies f10.
3952 (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3954 ;; y0 = 1/sqrt(a) in f7
3955 (parallel [(set (match_dup 8)
3956 (div:XF (const_int 1)
3957 (sqrt:XF (match_dup 9))))
3959 (unspec:BI [(match_dup 9)]
3960 UNSPEC_FR_SQRT_RECIP_APPROX))
3961 (use (const_int 0))])
3963 ;; H0 = 1/2 * y0 in f9
3964 (cond_exec (ne (match_dup 7) (const_int 0))
3965 (parallel [(set (match_dup 4)
3966 (plus:XF (mult:XF (match_dup 3) (match_dup 8))
3968 (use (const_int 1))]))
3970 ;; S0 = a * y0 in f7
3971 (cond_exec (ne (match_dup 7) (const_int 0))
3972 (parallel [(set (match_dup 8)
3973 (plus:XF (mult:XF (match_dup 9) (match_dup 8))
3975 (use (const_int 1))]))
3977 ;; d0 = 1/2 - S0 * H0 in f10
3978 (cond_exec (ne (match_dup 7) (const_int 0))
3979 (parallel [(set (match_dup 5)
3980 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
3982 (use (const_int 1))]))
3984 ;; H1 = H0 + d0 * H0 in f9
3985 (cond_exec (ne (match_dup 7) (const_int 0))
3986 (parallel [(set (match_dup 4)
3987 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
3989 (use (const_int 1))]))
3991 ;; S1 = S0 + d0 * S0 in f7
3992 (cond_exec (ne (match_dup 7) (const_int 0))
3993 (parallel [(set (match_dup 8)
3994 (plus:XF (mult:XF (match_dup 5) (match_dup 8))
3996 (use (const_int 1))]))
3998 ;; d1 = 1/2 - S1 * H1 in f10
3999 (cond_exec (ne (match_dup 7) (const_int 0))
4000 (parallel [(set (match_dup 5)
4001 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
4003 (use (const_int 1))]))
4005 ;; H2 = H1 + d1 * H1 in f9
4006 (cond_exec (ne (match_dup 7) (const_int 0))
4007 (parallel [(set (match_dup 4)
4008 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4010 (use (const_int 1))]))
4012 ;; S2 = S1 + d1 * S1 in f7
4013 (cond_exec (ne (match_dup 7) (const_int 0))
4014 (parallel [(set (match_dup 8)
4015 (plus:XF (mult:XF (match_dup 5) (match_dup 8))
4017 (use (const_int 1))]))
4019 ;; d2 = 1/2 - S2 * H2 in f10
4020 (cond_exec (ne (match_dup 7) (const_int 0))
4021 (parallel [(set (match_dup 5)
4022 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
4024 (use (const_int 1))]))
4026 ;; e2 = a - S2 * S2 in f8
4027 (cond_exec (ne (match_dup 7) (const_int 0))
4028 (parallel [(set (match_dup 3)
4029 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
4031 (use (const_int 1))]))
4033 ;; S3 = S2 + e2 * H2 in f7
4034 (cond_exec (ne (match_dup 7) (const_int 0))
4035 (parallel [(set (match_dup 8)
4036 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4038 (use (const_int 1))]))
4040 ;; H3 = H2 + d2 * H2 in f9
4041 (cond_exec (ne (match_dup 7) (const_int 0))
4042 (parallel [(set (match_dup 4)
4043 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
4045 (use (const_int 1))]))
4047 ;; e3 = a - S3 * S3 in f8
4048 (cond_exec (ne (match_dup 7) (const_int 0))
4049 (parallel [(set (match_dup 3)
4050 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
4052 (use (const_int 1))]))
4054 ;; S = S3 + e3 * H3 in f7
4055 (cond_exec (ne (match_dup 7) (const_int 0))
4056 (parallel [(set (match_dup 0)
4057 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4059 (use (const_int 0))]))]
4061 /* Generate 82-bit versions of the input and output operands. */
4062 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0]));
4063 operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1]));
4064 /* Generate required floating-point constants. */
4065 operands[10] = CONST0_RTX (XFmode);
4067 [(set_attr "predicable" "no")])
4069 ;; ??? frcpa works like cmp.foo.unc.
4071 (define_insn "*recip_approx"
4072 [(set (match_operand:XF 0 "fr_register_operand" "=f")
4073 (div:XF (const_int 1)
4074 (match_operand:XF 3 "fr_register_operand" "f")))
4075 (set (match_operand:BI 1 "register_operand" "=c")
4076 (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f")
4077 (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
4078 (use (match_operand:SI 4 "const_int_operand" ""))]
4080 "frcpa.s%4 %0, %1 = %2, %3"
4081 [(set_attr "itanium_class" "fmisc")
4082 (set_attr "predicable" "no")])
4084 ;; ::::::::::::::::::::
4086 ;; :: 32 bit Integer Shifts and Rotates
4088 ;; ::::::::::::::::::::
4090 (define_expand "ashlsi3"
4091 [(set (match_operand:SI 0 "gr_register_operand" "")
4092 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
4093 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4096 if (GET_CODE (operands[2]) != CONST_INT)
4098 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
4099 we've got to get rid of stray bits outside the SImode register. */
4100 rtx subshift = gen_reg_rtx (DImode);
4101 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4102 operands[2] = subshift;
4106 (define_insn "*ashlsi3_internal"
4107 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
4108 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
4109 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
4112 shladd %0 = %1, %2, r0
4113 dep.z %0 = %1, %2, %E2
4115 [(set_attr "itanium_class" "ialu,ishf,mmshf")])
4117 (define_expand "ashrsi3"
4118 [(set (match_operand:SI 0 "gr_register_operand" "")
4119 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
4120 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4123 rtx subtarget = gen_reg_rtx (DImode);
4124 if (GET_CODE (operands[2]) == CONST_INT)
4125 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
4126 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
4129 rtx subshift = gen_reg_rtx (DImode);
4130 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
4131 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4132 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
4134 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
4138 (define_expand "lshrsi3"
4139 [(set (match_operand:SI 0 "gr_register_operand" "")
4140 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
4141 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4144 rtx subtarget = gen_reg_rtx (DImode);
4145 if (GET_CODE (operands[2]) == CONST_INT)
4146 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
4147 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
4150 rtx subshift = gen_reg_rtx (DImode);
4151 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
4152 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4153 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
4155 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
4159 ;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
4160 ;; here, instead of 64 like the patterns above. Keep the pattern together
4161 ;; until after combine; otherwise it won't get matched often.
4163 (define_expand "rotrsi3"
4164 [(set (match_operand:SI 0 "gr_register_operand" "")
4165 (rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
4166 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4169 if (GET_MODE (operands[2]) != VOIDmode)
4171 rtx tmp = gen_reg_rtx (DImode);
4172 emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
4177 (define_insn_and_split "*rotrsi3_internal"
4178 [(set (match_operand:SI 0 "gr_register_operand" "=&r")
4179 (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
4180 (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
4185 (ior:DI (zero_extend:DI (match_dup 1))
4186 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
4188 (lshiftrt:DI (match_dup 3) (match_dup 2)))]
4189 "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
4191 (define_expand "rotlsi3"
4192 [(set (match_operand:SI 0 "gr_register_operand" "")
4193 (rotate:SI (match_operand:SI 1 "gr_register_operand" "")
4194 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4197 if (! shift_32bit_count_operand (operands[2], SImode))
4199 rtx tmp = gen_reg_rtx (SImode);
4200 emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
4201 emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
4206 (define_insn_and_split "*rotlsi3_internal"
4207 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4208 (rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
4209 (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
4214 (ior:DI (zero_extend:DI (match_dup 1))
4215 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
4217 (lshiftrt:DI (match_dup 3) (match_dup 2)))]
4219 operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
4220 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4223 ;; ::::::::::::::::::::
4225 ;; :: 64 bit Integer Shifts and Rotates
4227 ;; ::::::::::::::::::::
4229 (define_insn "ashldi3"
4230 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
4231 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
4232 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
4235 shladd %0 = %1, %2, r0
4238 [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
4240 ;; ??? Maybe combine this with the multiply and add instruction?
4242 (define_insn "*shladd"
4243 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4244 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
4245 (match_operand:DI 2 "shladd_operand" "n"))
4246 (match_operand:DI 3 "gr_register_operand" "r")))]
4248 "shladd %0 = %1, %S2, %3"
4249 [(set_attr "itanium_class" "ialu")])
4251 ;; This can be created by register elimination if operand3 of shladd is an
4252 ;; eliminable register or has reg_equiv_constant set.
4254 ;; We have to use nonmemory_operand for operand 4, to ensure that the
4255 ;; validate_changes call inside eliminate_regs will always succeed. If it
4256 ;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
4259 (define_insn_and_split "*shladd_elim"
4260 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
4261 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
4262 (match_operand:DI 2 "shladd_operand" "n"))
4263 (match_operand:DI 3 "nonmemory_operand" "r"))
4264 (match_operand:DI 4 "nonmemory_operand" "rI")))]
4265 "reload_in_progress"
4268 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
4270 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4272 [(set_attr "itanium_class" "unknown")])
4274 (define_insn "ashrdi3"
4275 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4276 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
4277 (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
4282 [(set_attr "itanium_class" "mmshf,mmshfi")])
4284 (define_insn "lshrdi3"
4285 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4286 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
4287 (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
4292 [(set_attr "itanium_class" "mmshf,mmshfi")])
4294 ;; Using a predicate that accepts only constants doesn't work, because optabs
4295 ;; will load the operand into a register and call the pattern if the predicate
4296 ;; did not accept it on the first try. So we use nonmemory_operand and then
4297 ;; verify that we have an appropriate constant in the expander.
4299 (define_expand "rotrdi3"
4300 [(set (match_operand:DI 0 "gr_register_operand" "")
4301 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
4302 (match_operand:DI 2 "nonmemory_operand" "")))]
4305 if (! shift_count_operand (operands[2], DImode))
4309 (define_insn "*rotrdi3_internal"
4310 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4311 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
4312 (match_operand:DI 2 "shift_count_operand" "M")))]
4314 "shrp %0 = %1, %1, %2"
4315 [(set_attr "itanium_class" "ishf")])
4317 (define_expand "rotldi3"
4318 [(set (match_operand:DI 0 "gr_register_operand" "")
4319 (rotate:DI (match_operand:DI 1 "gr_register_operand" "")
4320 (match_operand:DI 2 "nonmemory_operand" "")))]
4323 if (! shift_count_operand (operands[2], DImode))
4327 (define_insn "*rotldi3_internal"
4328 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4329 (rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
4330 (match_operand:DI 2 "shift_count_operand" "M")))]
4332 "shrp %0 = %1, %1, %e2"
4333 [(set_attr "itanium_class" "ishf")])
4335 ;; ::::::::::::::::::::
4337 ;; :: 32 bit Integer Logical operations
4339 ;; ::::::::::::::::::::
4341 ;; We don't seem to need any other 32-bit logical operations, because gcc
4342 ;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
4343 ;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
4344 ;; This doesn't work for unary logical operations, because we don't call
4345 ;; apply_distributive_law for them.
4347 ;; ??? Likewise, this doesn't work for andnot, which isn't handled by
4348 ;; apply_distributive_law. We get inefficient code for
4349 ;; int sub4 (int i, int j) { return i & ~j; }
4350 ;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
4351 ;; (zero_extend (and (not A) B)) in combine.
4352 ;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
4353 ;; one_cmplsi2 pattern.
4355 (define_insn "one_cmplsi2"
4356 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4357 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
4360 [(set_attr "itanium_class" "ilog")])
4362 ;; ::::::::::::::::::::
4364 ;; :: 64 bit Integer Logical operations
4366 ;; ::::::::::::::::::::
4368 (define_insn "anddi3"
4369 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4370 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4371 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4376 [(set_attr "itanium_class" "ilog,fmisc")])
4378 (define_insn "*andnot"
4379 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4380 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
4381 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4386 [(set_attr "itanium_class" "ilog,fmisc")])
4388 (define_insn "iordi3"
4389 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4390 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4391 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4396 [(set_attr "itanium_class" "ilog,fmisc")])
4398 (define_insn "xordi3"
4399 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4400 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4401 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4406 [(set_attr "itanium_class" "ilog,fmisc")])
4408 (define_insn "one_cmpldi2"
4409 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4410 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
4413 [(set_attr "itanium_class" "ilog")])
4415 ;; ::::::::::::::::::::
4419 ;; ::::::::::::::::::::
4421 (define_expand "cmpbi"
4423 (compare (match_operand:BI 0 "register_operand" "")
4424 (match_operand:BI 1 "const_int_operand" "")))]
4427 ia64_compare_op0 = operands[0];
4428 ia64_compare_op1 = operands[1];
4432 (define_expand "cmpsi"
4434 (compare (match_operand:SI 0 "gr_register_operand" "")
4435 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
4438 ia64_compare_op0 = operands[0];
4439 ia64_compare_op1 = operands[1];
4443 (define_expand "cmpdi"
4445 (compare (match_operand:DI 0 "gr_register_operand" "")
4446 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
4449 ia64_compare_op0 = operands[0];
4450 ia64_compare_op1 = operands[1];
4454 (define_expand "cmpsf"
4456 (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
4457 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
4460 ia64_compare_op0 = operands[0];
4461 ia64_compare_op1 = operands[1];
4465 (define_expand "cmpdf"
4467 (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
4468 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
4471 ia64_compare_op0 = operands[0];
4472 ia64_compare_op1 = operands[1];
4476 (define_expand "cmpxf"
4478 (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
4479 (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
4482 ia64_compare_op0 = operands[0];
4483 ia64_compare_op1 = operands[1];
4487 (define_insn "*cmpsi_normal"
4488 [(set (match_operand:BI 0 "register_operand" "=c")
4489 (match_operator:BI 1 "normal_comparison_operator"
4490 [(match_operand:SI 2 "gr_register_operand" "r")
4491 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
4493 "cmp4.%C1 %0, %I0 = %3, %2"
4494 [(set_attr "itanium_class" "icmp")])
4496 ;; We use %r3 because it is possible for us to match a 0, and two of the
4497 ;; unsigned comparisons don't accept immediate operands of zero.
4499 (define_insn "*cmpsi_adjusted"
4500 [(set (match_operand:BI 0 "register_operand" "=c")
4501 (match_operator:BI 1 "adjusted_comparison_operator"
4502 [(match_operand:SI 2 "gr_register_operand" "r")
4503 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4505 "cmp4.%C1 %0, %I0 = %r3, %2"
4506 [(set_attr "itanium_class" "icmp")])
4508 (define_insn "*cmpdi_normal"
4509 [(set (match_operand:BI 0 "register_operand" "=c")
4510 (match_operator:BI 1 "normal_comparison_operator"
4511 [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
4512 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
4514 "cmp.%C1 %0, %I0 = %3, %r2"
4515 [(set_attr "itanium_class" "icmp")])
4517 ;; We use %r3 because it is possible for us to match a 0, and two of the
4518 ;; unsigned comparisons don't accept immediate operands of zero.
4520 (define_insn "*cmpdi_adjusted"
4521 [(set (match_operand:BI 0 "register_operand" "=c")
4522 (match_operator:BI 1 "adjusted_comparison_operator"
4523 [(match_operand:DI 2 "gr_register_operand" "r")
4524 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4526 "cmp.%C1 %0, %I0 = %r3, %2"
4527 [(set_attr "itanium_class" "icmp")])
4529 (define_insn "*cmpsf_internal"
4530 [(set (match_operand:BI 0 "register_operand" "=c")
4531 (match_operator:BI 1 "comparison_operator"
4532 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
4533 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
4535 "fcmp.%D1 %0, %I0 = %F2, %F3"
4536 [(set_attr "itanium_class" "fcmp")])
4538 (define_insn "*cmpdf_internal"
4539 [(set (match_operand:BI 0 "register_operand" "=c")
4540 (match_operator:BI 1 "comparison_operator"
4541 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
4542 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
4544 "fcmp.%D1 %0, %I0 = %F2, %F3"
4545 [(set_attr "itanium_class" "fcmp")])
4547 (define_insn "*cmpxf_internal"
4548 [(set (match_operand:BI 0 "register_operand" "=c")
4549 (match_operator:BI 1 "comparison_operator"
4550 [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4551 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
4553 "fcmp.%D1 %0, %I0 = %F2, %F3"
4554 [(set_attr "itanium_class" "fcmp")])
4556 ;; ??? Can this pattern be generated?
4558 (define_insn "*bit_zero"
4559 [(set (match_operand:BI 0 "register_operand" "=c")
4560 (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4562 (match_operand:DI 2 "immediate_operand" "n"))
4565 "tbit.z %0, %I0 = %1, %2"
4566 [(set_attr "itanium_class" "tbit")])
4568 (define_insn "*bit_one"
4569 [(set (match_operand:BI 0 "register_operand" "=c")
4570 (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4572 (match_operand:DI 2 "immediate_operand" "n"))
4575 "tbit.nz %0, %I0 = %1, %2"
4576 [(set_attr "itanium_class" "tbit")])
4578 ;; ::::::::::::::::::::
4582 ;; ::::::::::::::::::::
4584 (define_expand "beq"
4586 (if_then_else (match_dup 1)
4587 (label_ref (match_operand 0 "" ""))
4590 "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
4592 (define_expand "bne"
4594 (if_then_else (match_dup 1)
4595 (label_ref (match_operand 0 "" ""))
4598 "operands[1] = ia64_expand_compare (NE, VOIDmode);")
4600 (define_expand "blt"
4602 (if_then_else (match_dup 1)
4603 (label_ref (match_operand 0 "" ""))
4606 "operands[1] = ia64_expand_compare (LT, VOIDmode);")
4608 (define_expand "ble"
4610 (if_then_else (match_dup 1)
4611 (label_ref (match_operand 0 "" ""))
4614 "operands[1] = ia64_expand_compare (LE, VOIDmode);")
4616 (define_expand "bgt"
4618 (if_then_else (match_dup 1)
4619 (label_ref (match_operand 0 "" ""))
4622 "operands[1] = ia64_expand_compare (GT, VOIDmode);")
4624 (define_expand "bge"
4626 (if_then_else (match_dup 1)
4627 (label_ref (match_operand 0 "" ""))
4630 "operands[1] = ia64_expand_compare (GE, VOIDmode);")
4632 (define_expand "bltu"
4634 (if_then_else (match_dup 1)
4635 (label_ref (match_operand 0 "" ""))
4638 "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
4640 (define_expand "bleu"
4642 (if_then_else (match_dup 1)
4643 (label_ref (match_operand 0 "" ""))
4646 "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
4648 (define_expand "bgtu"
4650 (if_then_else (match_dup 1)
4651 (label_ref (match_operand 0 "" ""))
4654 "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
4656 (define_expand "bgeu"
4658 (if_then_else (match_dup 1)
4659 (label_ref (match_operand 0 "" ""))
4662 "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
4664 (define_expand "bunordered"
4666 (if_then_else (match_dup 1)
4667 (label_ref (match_operand 0 "" ""))
4670 "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
4672 (define_expand "bordered"
4674 (if_then_else (match_dup 1)
4675 (label_ref (match_operand 0 "" ""))
4678 "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
4680 (define_insn "*br_true"
4682 (if_then_else (match_operator 0 "predicate_operator"
4683 [(match_operand:BI 1 "register_operand" "c")
4685 (label_ref (match_operand 2 "" ""))
4688 "(%J0) br.cond%+ %l2"
4689 [(set_attr "itanium_class" "br")
4690 (set_attr "predicable" "no")])
4692 (define_insn "*br_false"
4694 (if_then_else (match_operator 0 "predicate_operator"
4695 [(match_operand:BI 1 "register_operand" "c")
4698 (label_ref (match_operand 2 "" ""))))]
4700 "(%j0) br.cond%+ %l2"
4701 [(set_attr "itanium_class" "br")
4702 (set_attr "predicable" "no")])
4704 ;; ::::::::::::::::::::
4706 ;; :: Counted loop operations
4708 ;; ::::::::::::::::::::
4710 (define_expand "doloop_end"
4711 [(use (match_operand 0 "" "")) ; loop pseudo
4712 (use (match_operand 1 "" "")) ; iterations; zero if unknown
4713 (use (match_operand 2 "" "")) ; max iterations
4714 (use (match_operand 3 "" "")) ; loop level
4715 (use (match_operand 4 "" ""))] ; label
4718 /* Only use cloop on innermost loops. */
4719 if (INTVAL (operands[3]) > 1)
4721 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
4726 (define_insn "doloop_end_internal"
4727 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
4729 (label_ref (match_operand 1 "" ""))
4731 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
4732 (plus:DI (match_dup 0) (const_int -1))
4735 "br.cloop.sptk.few %l1"
4736 [(set_attr "itanium_class" "br")
4737 (set_attr "predicable" "no")])
4739 ;; ::::::::::::::::::::
4741 ;; :: Set flag operations
4743 ;; ::::::::::::::::::::
4745 (define_expand "seq"
4746 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4748 "operands[1] = ia64_expand_compare (EQ, DImode);")
4750 (define_expand "sne"
4751 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4753 "operands[1] = ia64_expand_compare (NE, DImode);")
4755 (define_expand "slt"
4756 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4758 "operands[1] = ia64_expand_compare (LT, DImode);")
4760 (define_expand "sle"
4761 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4763 "operands[1] = ia64_expand_compare (LE, DImode);")
4765 (define_expand "sgt"
4766 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4768 "operands[1] = ia64_expand_compare (GT, DImode);")
4770 (define_expand "sge"
4771 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4773 "operands[1] = ia64_expand_compare (GE, DImode);")
4775 (define_expand "sltu"
4776 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4778 "operands[1] = ia64_expand_compare (LTU, DImode);")
4780 (define_expand "sleu"
4781 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4783 "operands[1] = ia64_expand_compare (LEU, DImode);")
4785 (define_expand "sgtu"
4786 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4788 "operands[1] = ia64_expand_compare (GTU, DImode);")
4790 (define_expand "sgeu"
4791 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4793 "operands[1] = ia64_expand_compare (GEU, DImode);")
4795 (define_expand "sunordered"
4796 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4798 "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
4800 (define_expand "sordered"
4801 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4803 "operands[1] = ia64_expand_compare (ORDERED, DImode);")
4805 ;; Don't allow memory as destination here, because cmov/cmov/st is more
4806 ;; efficient than mov/mov/cst/cst.
4808 (define_insn_and_split "*sne_internal"
4809 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4810 (ne:DI (match_operand:BI 1 "register_operand" "c")
4815 [(cond_exec (ne (match_dup 1) (const_int 0))
4816 (set (match_dup 0) (const_int 1)))
4817 (cond_exec (eq (match_dup 1) (const_int 0))
4818 (set (match_dup 0) (const_int 0)))]
4820 [(set_attr "itanium_class" "unknown")])
4822 (define_insn_and_split "*seq_internal"
4823 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4824 (eq:DI (match_operand:BI 1 "register_operand" "c")
4829 [(cond_exec (ne (match_dup 1) (const_int 0))
4830 (set (match_dup 0) (const_int 0)))
4831 (cond_exec (eq (match_dup 1) (const_int 0))
4832 (set (match_dup 0) (const_int 1)))]
4834 [(set_attr "itanium_class" "unknown")])
4836 ;; ::::::::::::::::::::
4838 ;; :: Conditional move instructions.
4840 ;; ::::::::::::::::::::
4842 ;; ??? Add movXXcc patterns?
4845 ;; DImode if_then_else patterns.
4848 (define_insn "*cmovdi_internal"
4849 [(set (match_operand:DI 0 "destination_operand"
4850 "= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e")
4852 (match_operator 4 "predicate_operator"
4853 [(match_operand:BI 1 "register_operand"
4854 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
4856 (match_operand:DI 2 "move_operand"
4857 "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
4858 (match_operand:DI 3 "move_operand"
4859 "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
4860 "ia64_move_ok (operands[0], operands[2])
4861 && ia64_move_ok (operands[0], operands[3])"
4863 [(set_attr "predicable" "no")])
4866 [(set (match_operand 0 "destination_operand" "")
4868 (match_operator 4 "predicate_operator"
4869 [(match_operand:BI 1 "register_operand" "")
4871 (match_operand 2 "move_operand" "")
4872 (match_operand 3 "move_operand" "")))]
4876 bool emitted_something = false;
4877 rtx dest = operands[0];
4878 rtx srct = operands[2];
4879 rtx srcf = operands[3];
4880 rtx cond = operands[4];
4882 if (! rtx_equal_p (dest, srct))
4884 ia64_emit_cond_move (dest, srct, cond);
4885 emitted_something = true;
4887 if (! rtx_equal_p (dest, srcf))
4889 cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
4890 VOIDmode, operands[1], const0_rtx);
4891 ia64_emit_cond_move (dest, srcf, cond);
4892 emitted_something = true;
4894 if (! emitted_something)
4895 emit_note (NOTE_INSN_DELETED);
4899 ;; Absolute value pattern.
4901 (define_insn "*absdi2_internal"
4902 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4904 (match_operator 4 "predicate_operator"
4905 [(match_operand:BI 1 "register_operand" "c,c")
4907 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
4908 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
4911 [(set_attr "itanium_class" "ialu,unknown")
4912 (set_attr "predicable" "no")])
4915 [(set (match_operand:DI 0 "register_operand" "")
4917 (match_operator 4 "predicate_operator"
4918 [(match_operand:BI 1 "register_operand" "c,c")
4920 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4921 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4922 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4926 (neg:DI (match_dup 2))))]
4930 [(set (match_operand:DI 0 "register_operand" "")
4932 (match_operator 4 "predicate_operator"
4933 [(match_operand:BI 1 "register_operand" "c,c")
4935 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4936 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4940 (set (match_dup 0) (neg:DI (match_dup 2))))
4943 (set (match_dup 0) (match_dup 3)))]
4945 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4946 VOIDmode, operands[1], const0_rtx);
4950 ;; SImode if_then_else patterns.
4953 (define_insn "*cmovsi_internal"
4954 [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
4956 (match_operator 4 "predicate_operator"
4957 [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
4959 (match_operand:SI 2 "move_operand"
4960 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
4961 (match_operand:SI 3 "move_operand"
4962 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
4963 "ia64_move_ok (operands[0], operands[2])
4964 && ia64_move_ok (operands[0], operands[3])"
4966 [(set_attr "predicable" "no")])
4968 (define_insn "*abssi2_internal"
4969 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
4971 (match_operator 4 "predicate_operator"
4972 [(match_operand:BI 1 "register_operand" "c,c")
4974 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
4975 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
4978 [(set_attr "itanium_class" "ialu,unknown")
4979 (set_attr "predicable" "no")])
4982 [(set (match_operand:SI 0 "register_operand" "")
4984 (match_operator 4 "predicate_operator"
4985 [(match_operand:BI 1 "register_operand" "c,c")
4987 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4988 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4989 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4993 (neg:SI (match_dup 2))))]
4997 [(set (match_operand:SI 0 "register_operand" "")
4999 (match_operator 4 "predicate_operator"
5000 [(match_operand:BI 1 "register_operand" "c,c")
5002 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
5003 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
5007 (set (match_dup 0) (neg:SI (match_dup 2))))
5010 (set (match_dup 0) (match_dup 3)))]
5012 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
5013 VOIDmode, operands[1], const0_rtx);
5016 (define_insn_and_split "*cond_opsi2_internal"
5017 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5018 (match_operator:SI 5 "condop_operator"
5020 (match_operator 6 "predicate_operator"
5021 [(match_operand:BI 1 "register_operand" "c")
5023 (match_operand:SI 2 "gr_register_operand" "r")
5024 (match_operand:SI 3 "gr_register_operand" "r"))
5025 (match_operand:SI 4 "gr_register_operand" "r")]))]
5031 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
5034 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
5036 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5037 VOIDmode, operands[1], const0_rtx);
5039 [(set_attr "itanium_class" "ialu")
5040 (set_attr "predicable" "no")])
5043 (define_insn_and_split "*cond_opsi2_internal_b"
5044 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5045 (match_operator:SI 5 "condop_operator"
5046 [(match_operand:SI 4 "gr_register_operand" "r")
5048 (match_operator 6 "predicate_operator"
5049 [(match_operand:BI 1 "register_operand" "c")
5051 (match_operand:SI 2 "gr_register_operand" "r")
5052 (match_operand:SI 3 "gr_register_operand" "r"))]))]
5058 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
5061 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
5063 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5064 VOIDmode, operands[1], const0_rtx);
5066 [(set_attr "itanium_class" "ialu")
5067 (set_attr "predicable" "no")])
5070 ;; ::::::::::::::::::::
5072 ;; :: Call and branch instructions
5074 ;; ::::::::::::::::::::
5076 ;; Subroutine call instruction returning no value. Operand 0 is the function
5077 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
5078 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
5079 ;; registers used as operands.
5081 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
5082 ;; is supplied for the sake of some RISC machines which need to put this
5083 ;; information into the assembler code; they can put it in the RTL instead of
5086 (define_expand "call"
5087 [(use (match_operand:DI 0 "" ""))
5088 (use (match_operand 1 "" ""))
5089 (use (match_operand 2 "" ""))
5090 (use (match_operand 3 "" ""))]
5093 ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
5097 (define_expand "sibcall"
5098 [(use (match_operand:DI 0 "" ""))
5099 (use (match_operand 1 "" ""))
5100 (use (match_operand 2 "" ""))
5101 (use (match_operand 3 "" ""))]
5104 ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
5108 ;; Subroutine call instruction returning a value. Operand 0 is the hard
5109 ;; register in which the value is returned. There are three more operands,
5110 ;; the same as the three operands of the `call' instruction (but with numbers
5111 ;; increased by one).
5113 ;; Subroutines that return `BLKmode' objects use the `call' insn.
5115 (define_expand "call_value"
5116 [(use (match_operand 0 "" ""))
5117 (use (match_operand:DI 1 "" ""))
5118 (use (match_operand 2 "" ""))
5119 (use (match_operand 3 "" ""))
5120 (use (match_operand 4 "" ""))]
5123 ia64_expand_call (operands[0], operands[1], operands[3], false);
5127 (define_expand "sibcall_value"
5128 [(use (match_operand 0 "" ""))
5129 (use (match_operand:DI 1 "" ""))
5130 (use (match_operand 2 "" ""))
5131 (use (match_operand 3 "" ""))
5132 (use (match_operand 4 "" ""))]
5135 ia64_expand_call (operands[0], operands[1], operands[3], true);
5139 ;; Call subroutine returning any type.
5141 (define_expand "untyped_call"
5142 [(parallel [(call (match_operand 0 "" "")
5144 (match_operand 1 "" "")
5145 (match_operand 2 "" "")])]
5150 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
5152 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5154 rtx set = XVECEXP (operands[2], 0, i);
5155 emit_move_insn (SET_DEST (set), SET_SRC (set));
5158 /* The optimizer does not know that the call sets the function value
5159 registers we stored in the result block. We avoid problems by
5160 claiming that all hard registers are used and clobbered at this
5162 emit_insn (gen_blockage ());
5167 (define_insn "call_nogp"
5168 [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5170 (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
5172 "br.call%+.many %1 = %0"
5173 [(set_attr "itanium_class" "br,scall")])
5175 (define_insn "call_value_nogp"
5176 [(set (match_operand 0 "" "")
5177 (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
5179 (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
5181 "br.call%+.many %2 = %1"
5182 [(set_attr "itanium_class" "br,scall")])
5184 (define_insn "sibcall_nogp"
5185 [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5189 [(set_attr "itanium_class" "br,scall")])
5191 (define_insn "call_gp"
5192 [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5194 (clobber (match_operand:DI 1 "register_operand" "=b,b"))
5195 (clobber (match_scratch:DI 2 "=&r,X"))
5196 (clobber (match_scratch:DI 3 "=b,X"))]
5199 [(set_attr "itanium_class" "br,scall")])
5201 ;; Irritatingly, we don't have access to INSN within the split body.
5202 ;; See commentary in ia64_split_call as to why these aren't peep2.
5204 [(call (mem (match_operand 0 "call_operand" ""))
5206 (clobber (match_operand:DI 1 "register_operand" ""))
5207 (clobber (match_scratch:DI 2 ""))
5208 (clobber (match_scratch:DI 3 ""))]
5209 "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5212 ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5213 operands[3], true, false);
5218 [(call (mem (match_operand 0 "call_operand" ""))
5220 (clobber (match_operand:DI 1 "register_operand" ""))
5221 (clobber (match_scratch:DI 2 ""))
5222 (clobber (match_scratch:DI 3 ""))]
5226 ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5227 operands[3], false, false);
5231 (define_insn "call_value_gp"
5232 [(set (match_operand 0 "" "")
5233 (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
5235 (clobber (match_operand:DI 2 "register_operand" "=b,b"))
5236 (clobber (match_scratch:DI 3 "=&r,X"))
5237 (clobber (match_scratch:DI 4 "=b,X"))]
5240 [(set_attr "itanium_class" "br,scall")])
5243 [(set (match_operand 0 "" "")
5244 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
5246 (clobber (match_operand:DI 2 "register_operand" ""))
5247 (clobber (match_scratch:DI 3 ""))
5248 (clobber (match_scratch:DI 4 ""))]
5249 "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5252 ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5253 operands[4], true, false);
5258 [(set (match_operand 0 "" "")
5259 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
5261 (clobber (match_operand:DI 2 "register_operand" ""))
5262 (clobber (match_scratch:DI 3 ""))
5263 (clobber (match_scratch:DI 4 ""))]
5267 ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5268 operands[4], false, false);
5272 (define_insn_and_split "sibcall_gp"
5273 [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5275 (clobber (match_scratch:DI 1 "=&r,X"))
5276 (clobber (match_scratch:DI 2 "=b,X"))]
5282 ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
5283 operands[2], true, true);
5286 [(set_attr "itanium_class" "br")])
5288 (define_insn "return_internal"
5290 (use (match_operand:DI 0 "register_operand" "b"))]
5292 "br.ret.sptk.many %0"
5293 [(set_attr "itanium_class" "br")])
5295 (define_insn "return"
5297 "ia64_direct_return ()"
5298 "br.ret.sptk.many rp"
5299 [(set_attr "itanium_class" "br")])
5301 (define_insn "*return_true"
5303 (if_then_else (match_operator 0 "predicate_operator"
5304 [(match_operand:BI 1 "register_operand" "c")
5308 "ia64_direct_return ()"
5309 "(%J0) br.ret%+.many rp"
5310 [(set_attr "itanium_class" "br")
5311 (set_attr "predicable" "no")])
5313 (define_insn "*return_false"
5315 (if_then_else (match_operator 0 "predicate_operator"
5316 [(match_operand:BI 1 "register_operand" "c")
5320 "ia64_direct_return ()"
5321 "(%j0) br.ret%+.many rp"
5322 [(set_attr "itanium_class" "br")
5323 (set_attr "predicable" "no")])
5326 [(set (pc) (label_ref (match_operand 0 "" "")))]
5329 [(set_attr "itanium_class" "br")])
5331 (define_insn "indirect_jump"
5332 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
5335 [(set_attr "itanium_class" "br")])
5337 (define_expand "tablejump"
5338 [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
5339 (use (label_ref (match_operand 1 "" "")))])]
5342 rtx op0 = operands[0];
5345 /* ??? Bother -- do_tablejump is "helpful" and pulls the table
5346 element into a register without bothering to see whether that
5347 is necessary given the operand predicate. Check for MEM just
5348 in case someone fixes this. */
5349 if (GET_CODE (op0) == MEM)
5350 addr = XEXP (op0, 0);
5353 /* Otherwise, cheat and guess that the previous insn in the
5354 stream was the memory load. Grab the address from that.
5355 Note we have to momentarily pop out of the sequence started
5356 by the insn-emit wrapper in order to grab the last insn. */
5360 last = get_last_insn ();
5362 set = single_set (last);
5364 if (! rtx_equal_p (SET_DEST (set), op0)
5365 || GET_CODE (SET_SRC (set)) != MEM)
5367 addr = XEXP (SET_SRC (set), 0);
5368 if (rtx_equal_p (addr, op0))
5372 /* Jump table elements are stored pc-relative. That is, a displacement
5373 from the entry to the label. Thus to convert to an absolute address
5374 we add the address of the memory from which the value is loaded. */
5375 operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
5376 NULL_RTX, 1, OPTAB_DIRECT);
5379 (define_insn "*tablejump_internal"
5380 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
5381 (use (label_ref (match_operand 1 "" "")))]
5384 [(set_attr "itanium_class" "br")])
5387 ;; ::::::::::::::::::::
5389 ;; :: Prologue and Epilogue instructions
5391 ;; ::::::::::::::::::::
5393 (define_expand "prologue"
5397 ia64_expand_prologue ();
5401 (define_expand "epilogue"
5405 ia64_expand_epilogue (0);
5409 (define_expand "sibcall_epilogue"
5413 ia64_expand_epilogue (1);
5417 ;; This prevents the scheduler from moving the SP decrement past FP-relative
5418 ;; stack accesses. This is the same as adddi3 plus the extra set.
5420 (define_insn "prologue_allocate_stack"
5421 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5422 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
5423 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
5424 (set (match_operand:DI 3 "register_operand" "+r,r,r")
5431 [(set_attr "itanium_class" "ialu")])
5433 ;; This prevents the scheduler from moving the SP restore past FP-relative
5434 ;; stack accesses. This is similar to movdi plus the extra set.
5436 (define_insn "epilogue_deallocate_stack"
5437 [(set (match_operand:DI 0 "register_operand" "=r")
5438 (match_operand:DI 1 "register_operand" "+r"))
5439 (set (match_dup 1) (match_dup 1))]
5442 [(set_attr "itanium_class" "ialu")])
5444 ;; As USE insns aren't meaningful after reload, this is used instead
5445 ;; to prevent deleting instructions setting registers for EH handling
5446 (define_insn "prologue_use"
5447 [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
5448 UNSPEC_PROLOGUE_USE)]
5451 [(set_attr "itanium_class" "ignore")
5452 (set_attr "predicable" "no")])
5454 ;; Allocate a new register frame.
5456 (define_insn "alloc"
5457 [(set (match_operand:DI 0 "register_operand" "=r")
5458 (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
5459 (use (match_operand:DI 1 "const_int_operand" "i"))
5460 (use (match_operand:DI 2 "const_int_operand" "i"))
5461 (use (match_operand:DI 3 "const_int_operand" "i"))
5462 (use (match_operand:DI 4 "const_int_operand" "i"))]
5464 "alloc %0 = ar.pfs, %1, %2, %3, %4"
5465 [(set_attr "itanium_class" "syst_m0")
5466 (set_attr "predicable" "no")])
5469 (define_expand "gr_spill"
5470 [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
5471 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5472 (match_operand:DI 2 "const_int_operand" "")]
5474 (clobber (match_dup 3))])]
5476 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5478 (define_insn "gr_spill_internal"
5479 [(set (match_operand:DI 0 "memory_operand" "=m")
5480 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5481 (match_operand:DI 2 "const_int_operand" "")]
5483 (clobber (match_operand:DI 3 "register_operand" ""))]
5486 /* Note that we use a C output pattern here to avoid the predicate
5487 being automatically added before the .mem.offset directive. */
5488 return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
5490 [(set_attr "itanium_class" "st")])
5493 (define_expand "gr_restore"
5494 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5495 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5496 (match_operand:DI 2 "const_int_operand" "")]
5498 (use (match_dup 3))])]
5500 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5502 (define_insn "gr_restore_internal"
5503 [(set (match_operand:DI 0 "register_operand" "=r")
5504 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5505 (match_operand:DI 2 "const_int_operand" "")]
5507 (use (match_operand:DI 3 "register_operand" ""))]
5509 { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
5510 [(set_attr "itanium_class" "ld")])
5512 (define_insn "fr_spill"
5513 [(set (match_operand:XF 0 "memory_operand" "=m")
5514 (unspec:XF [(match_operand:XF 1 "register_operand" "f")]
5517 "stf.spill %0 = %1%P0"
5518 [(set_attr "itanium_class" "stf")])
5520 (define_insn "fr_restore"
5521 [(set (match_operand:XF 0 "register_operand" "=f")
5522 (unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
5523 UNSPEC_FR_RESTORE))]
5525 "ldf.fill %0 = %1%P1"
5526 [(set_attr "itanium_class" "fld")])
5528 ;; ??? The explicit stop is not ideal. It would be better if
5529 ;; rtx_needs_barrier took care of this, but this is something that can be
5530 ;; fixed later. This avoids an RSE DV.
5532 (define_insn "bsp_value"
5533 [(set (match_operand:DI 0 "register_operand" "=r")
5534 (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
5538 return \";;\;%,mov %0 = ar.bsp\";
5540 [(set_attr "itanium_class" "frar_i")])
5542 (define_insn "set_bsp"
5543 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
5561 [(set_attr "itanium_class" "unknown")
5562 (set_attr "predicable" "no")])
5564 ;; ??? The explicit stops are not ideal. It would be better if
5565 ;; rtx_needs_barrier took care of this, but this is something that can be
5566 ;; fixed later. This avoids an RSE DV.
5568 (define_insn "flushrs"
5569 [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
5572 [(set_attr "itanium_class" "rse_m")
5573 (set_attr "predicable" "no")])
5575 ;; ::::::::::::::::::::
5577 ;; :: Miscellaneous instructions
5579 ;; ::::::::::::::::::::
5581 ;; ??? Emiting a NOP instruction isn't very useful. This should probably
5582 ;; be emitting ";;" to force a break in the instruction packing.
5584 ;; No operation, needed in case the user uses -g but not -O.
5589 [(set_attr "itanium_class" "nop")])
5591 (define_insn "nop_m"
5595 [(set_attr "itanium_class" "nop_m")])
5597 (define_insn "nop_i"
5601 [(set_attr "itanium_class" "nop_i")])
5603 (define_insn "nop_f"
5607 [(set_attr "itanium_class" "nop_f")])
5609 (define_insn "nop_b"
5613 [(set_attr "itanium_class" "nop_b")])
5615 (define_insn "nop_x"
5619 [(set_attr "itanium_class" "nop_x")])
5621 ;; The following insn will be never generated. It is used only by
5622 ;; insn scheduler to change state before advancing cycle.
5623 (define_insn "pre_cycle"
5627 [(set_attr "itanium_class" "pre_cycle")])
5629 (define_insn "bundle_selector"
5630 [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
5632 { return get_bundle_name (INTVAL (operands[0])); }
5633 [(set_attr "itanium_class" "ignore")
5634 (set_attr "predicable" "no")])
5636 ;; Pseudo instruction that prevents the scheduler from moving code above this
5638 (define_insn "blockage"
5639 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
5642 [(set_attr "itanium_class" "ignore")
5643 (set_attr "predicable" "no")])
5645 (define_insn "insn_group_barrier"
5646 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5647 UNSPECV_INSN_GROUP_BARRIER)]
5650 [(set_attr "itanium_class" "stop_bit")
5651 (set_attr "predicable" "no")])
5653 (define_expand "trap"
5654 [(trap_if (const_int 1) (const_int 0))]
5658 ;; ??? We don't have a match-any slot type. Setting the type to unknown
5659 ;; produces worse code that setting the slot type to A.
5661 (define_insn "*trap"
5662 [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
5665 [(set_attr "itanium_class" "chk_s")])
5667 (define_expand "conditional_trap"
5668 [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
5671 operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
5674 (define_insn "*conditional_trap"
5675 [(trap_if (match_operator 0 "predicate_operator"
5676 [(match_operand:BI 1 "register_operand" "c")
5678 (match_operand 2 "const_int_operand" ""))]
5681 [(set_attr "itanium_class" "chk_s")
5682 (set_attr "predicable" "no")])
5684 (define_insn "break_f"
5685 [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
5688 [(set_attr "itanium_class" "nop_f")])
5690 (define_insn "prefetch"
5691 [(prefetch (match_operand:DI 0 "address_operand" "p")
5692 (match_operand:DI 1 "const_int_operand" "n")
5693 (match_operand:DI 2 "const_int_operand" "n"))]
5696 static const char * const alt[2][4] = {
5698 "%,lfetch.nta [%0]",
5699 "%,lfetch.nt1 [%0]",
5700 "%,lfetch.nt2 [%0]",
5704 "%,lfetch.excl.nta [%0]",
5705 "%,lfetch.excl.nt1 [%0]",
5706 "%,lfetch.excl.nt2 [%0]",
5707 "%,lfetch.excl [%0]"
5710 int i = (INTVAL (operands[1]));
5711 int j = (INTVAL (operands[2]));
5713 if (i != 0 && i != 1)
5719 [(set_attr "itanium_class" "lfetch")])
5721 ;; Non-local goto support.
5723 (define_expand "save_stack_nonlocal"
5724 [(use (match_operand:OI 0 "memory_operand" ""))
5725 (use (match_operand:DI 1 "register_operand" ""))]
5728 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5729 \"__ia64_save_stack_nonlocal\"),
5730 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
5731 operands[1], Pmode);
5735 (define_expand "nonlocal_goto"
5736 [(use (match_operand 0 "general_operand" ""))
5737 (use (match_operand 1 "general_operand" ""))
5738 (use (match_operand 2 "general_operand" ""))
5739 (use (match_operand 3 "general_operand" ""))]
5742 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
5743 LCT_NORETURN, VOIDmode, 3,
5745 copy_to_reg (XEXP (operands[2], 0)), Pmode,
5746 operands[3], Pmode);
5751 (define_insn_and_split "builtin_setjmp_receiver"
5752 [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
5762 (define_expand "eh_epilogue"
5763 [(use (match_operand:DI 0 "register_operand" "r"))
5764 (use (match_operand:DI 1 "register_operand" "r"))
5765 (use (match_operand:DI 2 "register_operand" "r"))]
5768 rtx bsp = gen_rtx_REG (Pmode, 10);
5769 rtx sp = gen_rtx_REG (Pmode, 9);
5771 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
5773 emit_move_insn (bsp, operands[0]);
5776 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
5778 emit_move_insn (sp, operands[2]);
5781 emit_insn (gen_rtx_USE (VOIDmode, sp));
5782 emit_insn (gen_rtx_USE (VOIDmode, bsp));
5784 cfun->machine->ia64_eh_epilogue_sp = sp;
5785 cfun->machine->ia64_eh_epilogue_bsp = bsp;
5788 ;; Builtin apply support.
5790 (define_expand "restore_stack_nonlocal"
5791 [(use (match_operand:DI 0 "register_operand" ""))
5792 (use (match_operand:OI 1 "memory_operand" ""))]
5795 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5796 "__ia64_restore_stack_nonlocal"),
5798 copy_to_reg (XEXP (operands[1], 0)), Pmode);
5803 ;;; Intrinsics support.
5806 [(set (mem:BLK (match_dup 0))
5807 (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
5810 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
5811 MEM_VOLATILE_P (operands[0]) = 1;
5814 (define_insn "*mf_internal"
5815 [(set (match_operand:BLK 0 "" "")
5816 (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
5819 [(set_attr "itanium_class" "syst_m")])
5821 (define_insn "fetchadd_acq_si"
5822 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5824 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5825 (unspec:SI [(match_dup 1)
5826 (match_operand:SI 2 "fetchadd_operand" "n")]
5827 UNSPEC_FETCHADD_ACQ))]
5829 "fetchadd4.acq %0 = %1, %2"
5830 [(set_attr "itanium_class" "sem")])
5832 (define_insn "fetchadd_acq_di"
5833 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5835 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5836 (unspec:DI [(match_dup 1)
5837 (match_operand:DI 2 "fetchadd_operand" "n")]
5838 UNSPEC_FETCHADD_ACQ))]
5840 "fetchadd8.acq %0 = %1, %2"
5841 [(set_attr "itanium_class" "sem")])
5843 (define_insn "cmpxchg_acq_si"
5844 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5846 (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
5847 (unspec:SI [(match_dup 1)
5848 (match_operand:SI 2 "gr_register_operand" "r")
5849 (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5850 UNSPEC_CMPXCHG_ACQ))]
5852 "cmpxchg4.acq %0 = %1, %2, %3"
5853 [(set_attr "itanium_class" "sem")])
5855 (define_insn "cmpxchg_acq_di"
5856 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5858 (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
5859 (unspec:DI [(match_dup 1)
5860 (match_operand:DI 2 "gr_register_operand" "r")
5861 (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5862 UNSPEC_CMPXCHG_ACQ))]
5864 "cmpxchg8.acq %0 = %1, %2, %3"
5865 [(set_attr "itanium_class" "sem")])
5867 (define_insn "xchgsi"
5868 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5869 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5871 (match_operand:SI 2 "gr_register_operand" "r"))]
5874 [(set_attr "itanium_class" "sem")])
5876 (define_insn "xchgdi"
5877 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5878 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5880 (match_operand:DI 2 "gr_register_operand" "r"))]
5883 [(set_attr "itanium_class" "sem")])
5888 [(match_operator 0 "predicate_operator"
5889 [(match_operand:BI 1 "register_operand" "c")
5894 (define_insn "pred_rel_mutex"
5895 [(set (match_operand:BI 0 "register_operand" "+c")
5896 (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
5898 ".pred.rel.mutex %0, %I0"
5899 [(set_attr "itanium_class" "ignore")
5900 (set_attr "predicable" "no")])
5902 (define_insn "safe_across_calls_all"
5903 [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
5905 ".pred.safe_across_calls p1-p63"
5906 [(set_attr "itanium_class" "ignore")
5907 (set_attr "predicable" "no")])
5909 (define_insn "safe_across_calls_normal"
5910 [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
5913 emit_safe_across_calls ();
5916 [(set_attr "itanium_class" "ignore")
5917 (set_attr "predicable" "no")])
5919 ;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
5920 ;; pointer. This is used by the HP-UX 32 bit mode.
5922 (define_insn "ptr_extend"
5923 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5924 (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
5928 [(set_attr "itanium_class" "ialu")])
5931 ;; Optimizations for ptr_extend
5933 (define_insn "ptr_extend_plus_imm"
5934 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5936 [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
5937 (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
5939 "addp4_optimize_ok (operands[1], operands[2])"
5941 [(set_attr "itanium_class" "ialu")])
5943 (define_insn "*ptr_extend_plus_2"
5944 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5946 [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
5947 (match_operand:SI 2 "basereg_operand" "r"))]
5949 "addp4_optimize_ok (operands[1], operands[2])"
5951 [(set_attr "itanium_class" "ialu")])