1 ;; IA-64 Machine description template
2 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by James E. Wilson <wilson@cygnus.com> and
5 ;; David Mosberger <davidm@hpl.hp.com>.
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
27 ;; reload. This will be fixed once scheduling support is turned on.
29 ;; ??? Optimize for post-increment addressing modes.
31 ;; ??? fselect is not supported, because there is no integer register
34 ;; ??? fp abs/min/max instructions may also work for integer values.
36 ;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy,
37 ;; it assumes the operand is a register and takes REGNO of it without checking.
39 ;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy,
40 ;; it assumes the operand is a register and takes REGNO of it without checking.
42 ;; ??? Go through list of documented named patterns and look for more to
45 ;; ??? Go through instruction manual and look for more instructions that
48 ;; ??? Add function unit scheduling info for Itanium (TM) processor.
50 ;; ??? Need a better way to describe alternate fp status registers.
54 (UNSPEC_LTOFF_DTPMOD 0)
55 (UNSPEC_LTOFF_DTPREL 1)
57 (UNSPEC_LTOFF_TPREL 3)
62 (UNSPEC_GR_RESTORE 11)
64 (UNSPEC_FR_RESTORE 13)
65 (UNSPEC_FR_RECIP_APPROX 14)
66 (UNSPEC_PRED_REL_MUTEX 15)
70 (UNSPEC_CMPXCHG_ACQ 19)
71 (UNSPEC_FETCHADD_ACQ 20)
74 (UNSPEC_BUNDLE_SELECTOR 23)
76 (UNSPEC_PROLOGUE_USE 25)
79 (UNSPEC_FR_SQRT_RECIP_APPROX 28)
85 (UNSPECV_INSN_GROUP_BARRIER 2)
88 (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls
89 (UNSPECV_PSAC_NORMAL 6)
90 (UNSPECV_SETJMP_RECEIVER 7)
93 ;; ::::::::::::::::::::
97 ;; ::::::::::::::::::::
99 ;; Processor type. This attribute must exactly match the processor_type
100 ;; enumeration in ia64.h.
101 (define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
103 ;; Instruction type. This primarily determines how instructions can be
104 ;; packed in bundles, and secondarily affects scheduling to function units.
106 ;; A alu, can go in I or M syllable of a bundle
111 ;; L long immediate, takes two syllables
114 ;; ??? Should not have any pattern with type unknown. Perhaps add code to
115 ;; check this in md_reorg? Currently use unknown for patterns which emit
116 ;; multiple instructions, patterns which emit 0 instructions, and patterns
117 ;; which emit instruction that can go in any slot (e.g. nop).
119 (define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
120 fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
121 chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
122 syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
123 nop_i,nop_m,nop_x,lfetch,pre_cycle"
124 (const_string "unknown"))
126 ;; chk_s has an I and an M form; use type A for convenience.
127 (define_attr "type" "unknown,A,I,M,F,B,L,X,S"
128 (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M")
129 (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M")
130 (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M")
131 (eq_attr "itanium_class" "lfetch") (const_string "M")
132 (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A")
133 (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F")
134 (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F")
135 (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I")
136 (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I")
137 (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I")
138 (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B")
139 (eq_attr "itanium_class" "stop_bit") (const_string "S")
140 (eq_attr "itanium_class" "nop_x") (const_string "X")
141 (eq_attr "itanium_class" "long_i") (const_string "L")]
142 (const_string "unknown")))
144 (define_attr "itanium_requires_unit0" "no,yes"
145 (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes")
146 (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes")
147 (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes")
148 (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes")
149 (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes")
150 (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")]
151 (const_string "no")))
153 ;; Predication. True iff this instruction can be predicated.
155 (define_attr "predicable" "no,yes" (const_string "yes"))
157 ;; Empty. True iff this insn does not generate any code.
159 (define_attr "empty" "no,yes" (const_string "no"))
163 ;; DFA descriptions of ia64 processors used for insn scheduling and
166 (automata_option "ndfa")
168 ;; Uncomment the following line to output automata for debugging.
169 ;; (automata_option "v")
171 (automata_option "w")
173 ;;(automata_option "no-minimization")
176 (include "itanium1.md")
177 (include "itanium2.md")
180 ;; ::::::::::::::::::::
184 ;; ::::::::::::::::::::
186 ;; Set of a single predicate register. This is only used to implement
187 ;; pr-to-pr move and complement.
189 (define_insn "*movcci"
190 [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
191 (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
194 cmp.ne %0, p0 = r0, r0
195 cmp.eq %0, p0 = r0, r0
196 (%1) cmp.eq.unc %0, p0 = r0, r0"
197 [(set_attr "itanium_class" "icmp")
198 (set_attr "predicable" "no")])
201 [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r")
202 (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))]
205 cmp.ne %0, %I0 = r0, r0
206 cmp.eq %0, %I0 = r0, r0
209 tbit.nz %0, %I0 = %1, 0
214 [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")])
217 [(set (match_operand:BI 0 "register_operand" "")
218 (match_operand:BI 1 "register_operand" ""))]
220 && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
221 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
222 [(cond_exec (ne (match_dup 1) (const_int 0))
223 (set (match_dup 0) (const_int 1)))
224 (cond_exec (eq (match_dup 1) (const_int 0))
225 (set (match_dup 0) (const_int 0)))]
229 [(set (match_operand:BI 0 "register_operand" "")
230 (match_operand:BI 1 "register_operand" ""))]
232 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
233 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
234 [(set (match_dup 2) (match_dup 4))
235 (set (match_dup 3) (match_dup 5))
236 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
237 "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
238 operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
239 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
240 operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
242 (define_expand "movqi"
243 [(set (match_operand:QI 0 "general_operand" "")
244 (match_operand:QI 1 "general_operand" ""))]
247 rtx op1 = ia64_expand_move (operands[0], operands[1]);
253 (define_insn "*movqi_internal"
254 [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
255 (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
256 "ia64_move_ok (operands[0], operands[1])"
265 [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
267 (define_expand "movhi"
268 [(set (match_operand:HI 0 "general_operand" "")
269 (match_operand:HI 1 "general_operand" ""))]
272 rtx op1 = ia64_expand_move (operands[0], operands[1]);
278 (define_insn "*movhi_internal"
279 [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f")
280 (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))]
281 "ia64_move_ok (operands[0], operands[1])"
290 [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")])
292 (define_expand "movsi"
293 [(set (match_operand:SI 0 "general_operand" "")
294 (match_operand:SI 1 "general_operand" ""))]
297 rtx op1 = ia64_expand_move (operands[0], operands[1]);
303 (define_insn "*movsi_internal"
304 [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
305 (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
306 "ia64_move_ok (operands[0], operands[1])"
318 ;; frar_m, toar_m ??? why not frar_i and toar_i
319 [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")])
321 (define_expand "movdi"
322 [(set (match_operand:DI 0 "general_operand" "")
323 (match_operand:DI 1 "general_operand" ""))]
326 rtx op1 = ia64_expand_move (operands[0], operands[1]);
332 (define_insn "*movdi_internal"
333 [(set (match_operand:DI 0 "destination_operand"
334 "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
335 (match_operand:DI 1 "move_operand"
336 "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
337 "ia64_move_ok (operands[0], operands[1])"
339 static const char * const alt[] = {
341 "%,addl %0 = %1, r0",
343 "%,ld8%O1 %0 = %1%P1",
344 "%,st8%Q0 %0 = %r1%P0",
345 "%,getf.sig %0 = %1",
346 "%,setf.sig %0 = %r1",
360 if (which_alternative == 2 && ! TARGET_NO_PIC
361 && symbolic_operand (operands[1], VOIDmode))
364 return alt[which_alternative];
366 [(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")])
369 [(set (match_operand 0 "register_operand" "")
370 (match_operand 1 "symbolic_operand" ""))]
371 "reload_completed && ! TARGET_NO_PIC"
374 ia64_expand_load_address (operands[0], operands[1]);
378 (define_expand "load_fptr"
380 (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "")))
381 (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
384 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
385 operands[3] = gen_rtx_MEM (DImode, operands[2]);
386 RTX_UNCHANGING_P (operands[3]) = 1;
389 (define_insn "*load_fptr_internal1"
390 [(set (match_operand:DI 0 "register_operand" "=r")
391 (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))]
393 "addl %0 = @ltoff(@fptr(%1)), gp"
394 [(set_attr "itanium_class" "ialu")])
396 (define_insn "load_gprel"
397 [(set (match_operand:DI 0 "register_operand" "=r")
398 (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))]
400 "addl %0 = @gprel(%1), gp"
401 [(set_attr "itanium_class" "ialu")])
403 (define_insn "gprel64_offset"
404 [(set (match_operand:DI 0 "register_operand" "=r")
405 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))]
407 "movl %0 = @gprel(%1)"
408 [(set_attr "itanium_class" "long_i")])
410 (define_expand "load_gprel64"
412 (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3)))
413 (set (match_operand:DI 0 "register_operand" "")
414 (plus:DI (match_dup 3) (match_dup 2)))]
417 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
418 operands[3] = pic_offset_table_rtx;
421 ;; This is used as a placeholder for the return address during early
422 ;; compilation. We won't know where we've placed this until during
423 ;; reload, at which point it can wind up in b0, a general register,
424 ;; or memory. The only safe destination under these conditions is a
427 (define_insn_and_split "*movdi_ret_addr"
428 [(set (match_operand:DI 0 "register_operand" "=r")
429 (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
435 ia64_split_return_addr_rtx (operands[0]);
438 [(set_attr "itanium_class" "ialu")])
440 (define_insn "*load_symptr_high"
441 [(set (match_operand:DI 0 "register_operand" "=r")
442 (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
443 (match_operand:DI 2 "register_operand" "a")))]
446 if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
447 return "%,addl %0 = @ltoffx(%1), %2";
449 return "%,addl %0 = @ltoff(%1), %2";
451 [(set_attr "itanium_class" "ialu")])
453 (define_insn "*load_symptr_low"
454 [(set (match_operand:DI 0 "register_operand" "=r")
455 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
456 (match_operand 2 "got_symbolic_operand" "s")))]
459 if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
460 return "%,ld8.mov %0 = [%1], %2";
462 return "%,ld8 %0 = [%1]";
464 [(set_attr "itanium_class" "ld")])
466 (define_insn "load_ltoff_dtpmod"
467 [(set (match_operand:DI 0 "register_operand" "=r")
469 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
470 UNSPEC_LTOFF_DTPMOD)))]
472 "addl %0 = @ltoff(@dtpmod(%1)), gp"
473 [(set_attr "itanium_class" "ialu")])
475 (define_insn "load_ltoff_dtprel"
476 [(set (match_operand:DI 0 "register_operand" "=r")
478 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
479 UNSPEC_LTOFF_DTPREL)))]
481 "addl %0 = @ltoff(@dtprel(%1)), gp"
482 [(set_attr "itanium_class" "ialu")])
484 (define_expand "load_dtprel"
485 [(set (match_operand:DI 0 "register_operand" "")
486 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
491 (define_insn "*load_dtprel64"
492 [(set (match_operand:DI 0 "register_operand" "=r")
493 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
496 "movl %0 = @dtprel(%1)"
497 [(set_attr "itanium_class" "long_i")])
499 (define_insn "*load_dtprel22"
500 [(set (match_operand:DI 0 "register_operand" "=r")
501 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
504 "addl %0 = @dtprel(%1), r0"
505 [(set_attr "itanium_class" "ialu")])
507 (define_expand "add_dtprel"
508 [(set (match_operand:DI 0 "register_operand" "")
509 (plus:DI (match_operand:DI 1 "register_operand" "")
510 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
515 (define_insn "*add_dtprel14"
516 [(set (match_operand:DI 0 "register_operand" "=r")
517 (plus:DI (match_operand:DI 1 "register_operand" "r")
518 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
521 "adds %0 = @dtprel(%2), %1"
522 [(set_attr "itanium_class" "ialu")])
524 (define_insn "*add_dtprel22"
525 [(set (match_operand:DI 0 "register_operand" "=r")
526 (plus:DI (match_operand:DI 1 "register_operand" "a")
527 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
530 "addl %0 = @dtprel(%2), %1"
531 [(set_attr "itanium_class" "ialu")])
533 (define_insn "load_ltoff_tprel"
534 [(set (match_operand:DI 0 "register_operand" "=r")
536 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
537 UNSPEC_LTOFF_TPREL)))]
539 "addl %0 = @ltoff(@tprel(%1)), gp"
540 [(set_attr "itanium_class" "ialu")])
542 (define_expand "load_tprel"
543 [(set (match_operand:DI 0 "register_operand" "")
544 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
549 (define_insn "*load_tprel64"
550 [(set (match_operand:DI 0 "register_operand" "=r")
551 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
554 "movl %0 = @tprel(%1)"
555 [(set_attr "itanium_class" "long_i")])
557 (define_insn "*load_tprel22"
558 [(set (match_operand:DI 0 "register_operand" "=r")
559 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
562 "addl %0 = @tprel(%1), r0"
563 [(set_attr "itanium_class" "ialu")])
565 (define_expand "add_tprel"
566 [(set (match_operand:DI 0 "register_operand" "")
567 (plus:DI (match_operand:DI 1 "register_operand" "")
568 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
573 (define_insn "*add_tprel14"
574 [(set (match_operand:DI 0 "register_operand" "=r")
575 (plus:DI (match_operand:DI 1 "register_operand" "r")
576 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
579 "adds %0 = @tprel(%2), %1"
580 [(set_attr "itanium_class" "ialu")])
582 (define_insn "*add_tprel22"
583 [(set (match_operand:DI 0 "register_operand" "=r")
584 (plus:DI (match_operand:DI 1 "register_operand" "a")
585 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
588 "addl %0 = @tprel(%2), %1"
589 [(set_attr "itanium_class" "ialu")])
591 ;; With no offsettable memory references, we've got to have a scratch
592 ;; around to play with the second word. However, in order to avoid a
593 ;; reload nightmare we lie, claim we don't need one, and fix it up
594 ;; in ia64_split_tmode_move.
595 (define_expand "movti"
596 [(set (match_operand:TI 0 "general_operand" "")
597 (match_operand:TI 1 "general_operand" ""))]
600 rtx op1 = ia64_expand_move (operands[0], operands[1]);
606 (define_insn_and_split "*movti_internal"
607 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
608 (match_operand:TI 1 "general_operand" "ri,m,r"))]
609 "ia64_move_ok (operands[0], operands[1])"
614 ia64_split_tmode_move (operands);
617 [(set_attr "itanium_class" "unknown")
618 (set_attr "predicable" "no")])
620 ;; Floating Point Moves
622 ;; Note - Patterns for SF mode moves are compulsory, but
623 ;; patterns for DF are optional, as GCC can synthesize them.
625 (define_expand "movsf"
626 [(set (match_operand:SF 0 "general_operand" "")
627 (match_operand:SF 1 "general_operand" ""))]
630 rtx op1 = ia64_expand_move (operands[0], operands[1]);
636 (define_insn "*movsf_internal"
637 [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
638 (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
639 "ia64_move_ok (operands[0], operands[1])"
649 [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
651 (define_expand "movdf"
652 [(set (match_operand:DF 0 "general_operand" "")
653 (match_operand:DF 1 "general_operand" ""))]
656 rtx op1 = ia64_expand_move (operands[0], operands[1]);
662 (define_insn "*movdf_internal"
663 [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m")
664 (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))]
665 "ia64_move_ok (operands[0], operands[1])"
675 [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")])
677 ;; With no offsettable memory references, we've got to have a scratch
678 ;; around to play with the second word if the variable winds up in GRs.
679 (define_expand "movxf"
680 [(set (match_operand:XF 0 "general_operand" "")
681 (match_operand:XF 1 "general_operand" ""))]
684 /* We must support XFmode loads into general registers for stdarg/vararg
685 and unprototyped calls. We split them into DImode loads for convenience.
686 We don't need XFmode stores from general regs, because a stdarg/vararg
687 routine does a block store to memory of unnamed arguments. */
688 if (GET_CODE (operands[0]) == REG
689 && GR_REGNO_P (REGNO (operands[0])))
691 /* We're hoping to transform everything that deals with XFmode
692 quantities and GR registers early in the compiler. */
696 /* Struct to register can just use TImode instead. */
697 if ((GET_CODE (operands[1]) == SUBREG
698 && GET_MODE (SUBREG_REG (operands[1])) == TImode)
699 || (GET_CODE (operands[1]) == REG
700 && GR_REGNO_P (REGNO (operands[1]))))
702 emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
703 SUBREG_REG (operands[1]));
707 if (GET_CODE (operands[1]) == CONST_DOUBLE)
709 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
710 operand_subword (operands[1], 0, 0, XFmode));
711 emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
712 operand_subword (operands[1], 1, 0, XFmode));
716 /* If the quantity is in a register not known to be GR, spill it. */
717 if (register_operand (operands[1], XFmode))
718 operands[1] = spill_xfmode_operand (operands[1], 1);
720 if (GET_CODE (operands[1]) == MEM)
724 out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
725 out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
727 emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
728 emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
735 if (! reload_in_progress && ! reload_completed)
737 operands[0] = spill_xfmode_operand (operands[0], 0);
738 operands[1] = spill_xfmode_operand (operands[1], 0);
740 if (! ia64_move_ok (operands[0], operands[1]))
741 operands[1] = force_reg (XFmode, operands[1]);
745 ;; ??? There's no easy way to mind volatile acquire/release semantics.
747 (define_insn "*movxf_internal"
748 [(set (match_operand:XF 0 "destination_xfmode_operand" "=f,f, m")
749 (match_operand:XF 1 "general_xfmode_operand" "fG,m,fG"))]
750 "ia64_move_ok (operands[0], operands[1])"
755 [(set_attr "itanium_class" "fmisc,fld,stf")])
757 ;; Better code generation via insns that deal with TFmode register pairs
758 ;; directly. Same concerns apply as for TImode.
759 (define_expand "movtf"
760 [(set (match_operand:TF 0 "general_operand" "")
761 (match_operand:TF 1 "general_operand" ""))]
764 rtx op1 = ia64_expand_move (operands[0], operands[1]);
770 (define_insn_and_split "*movtf_internal"
771 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m")
772 (match_operand:TF 1 "general_operand" "ri,m,r"))]
773 "ia64_move_ok (operands[0], operands[1])"
778 ia64_split_tmode_move (operands);
781 [(set_attr "itanium_class" "unknown")
782 (set_attr "predicable" "no")])
785 ;; ::::::::::::::::::::
789 ;; ::::::::::::::::::::
791 ;; Signed conversions from a smaller integer to a larger integer
793 (define_insn "extendqidi2"
794 [(set (match_operand:DI 0 "gr_register_operand" "=r")
795 (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))]
798 [(set_attr "itanium_class" "xtd")])
800 (define_insn "extendhidi2"
801 [(set (match_operand:DI 0 "gr_register_operand" "=r")
802 (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))]
805 [(set_attr "itanium_class" "xtd")])
807 (define_insn "extendsidi2"
808 [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
809 (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
814 [(set_attr "itanium_class" "xtd,fmisc")])
816 ;; Unsigned conversions from a smaller integer to a larger integer
818 (define_insn "zero_extendqidi2"
819 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
820 (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))]
825 [(set_attr "itanium_class" "xtd,ld")])
827 (define_insn "zero_extendhidi2"
828 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
829 (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))]
834 [(set_attr "itanium_class" "xtd,ld")])
836 (define_insn "zero_extendsidi2"
837 [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
839 (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
845 [(set_attr "itanium_class" "xtd,ld,fmisc")])
847 ;; Convert between floating point types of different sizes.
849 ;; At first glance, it would appear that emitting fnorm for an extending
850 ;; conversion is unnecessary. However, the stf and getf instructions work
851 ;; correctly only if the input is properly rounded for its type. In
852 ;; particular, we get the wrong result for getf.d/stfd if the input is a
853 ;; denorm single. Since we don't know what the next instruction will be, we
854 ;; have to emit an fnorm.
856 ;; ??? Optimization opportunity here. Get rid of the insn altogether
857 ;; when we can. Should probably use a scheme like has been proposed
858 ;; for ia32 in dealing with operands that match unary operators. This
859 ;; would let combine merge the thing into adjacent insns. See also how the
860 ;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
861 ;; se_register_operand.
863 (define_insn "extendsfdf2"
864 [(set (match_operand:DF 0 "fr_register_operand" "=f")
865 (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
868 [(set_attr "itanium_class" "fmac")])
870 (define_insn "extendsfxf2"
871 [(set (match_operand:XF 0 "fr_register_operand" "=f")
872 (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]
875 [(set_attr "itanium_class" "fmac")])
877 (define_insn "extenddfxf2"
878 [(set (match_operand:XF 0 "fr_register_operand" "=f")
879 (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]
882 [(set_attr "itanium_class" "fmac")])
884 (define_insn "truncdfsf2"
885 [(set (match_operand:SF 0 "fr_register_operand" "=f")
886 (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))]
889 [(set_attr "itanium_class" "fmac")])
891 (define_insn "truncxfsf2"
892 [(set (match_operand:SF 0 "fr_register_operand" "=f")
893 (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]
896 [(set_attr "itanium_class" "fmac")])
898 (define_insn "truncxfdf2"
899 [(set (match_operand:DF 0 "fr_register_operand" "=f")
900 (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]
903 [(set_attr "itanium_class" "fmac")])
905 ;; Convert between signed integer types and floating point.
907 (define_insn "floatdixf2"
908 [(set (match_operand:XF 0 "fr_register_operand" "=f")
909 (float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
912 [(set_attr "itanium_class" "fcvtfx")])
914 (define_insn "fix_truncsfdi2"
915 [(set (match_operand:DI 0 "fr_register_operand" "=f")
916 (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
918 "fcvt.fx.trunc %0 = %1"
919 [(set_attr "itanium_class" "fcvtfx")])
921 (define_insn "fix_truncdfdi2"
922 [(set (match_operand:DI 0 "fr_register_operand" "=f")
923 (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
925 "fcvt.fx.trunc %0 = %1"
926 [(set_attr "itanium_class" "fcvtfx")])
928 (define_insn "fix_truncxfdi2"
929 [(set (match_operand:DI 0 "fr_register_operand" "=f")
930 (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
932 "fcvt.fx.trunc %0 = %1"
933 [(set_attr "itanium_class" "fcvtfx")])
935 (define_insn "fix_truncxfdi2_alts"
936 [(set (match_operand:DI 0 "fr_register_operand" "=f")
937 (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
938 (use (match_operand:SI 2 "const_int_operand" ""))]
940 "fcvt.fx.trunc.s%2 %0 = %1"
941 [(set_attr "itanium_class" "fcvtfx")])
943 ;; Convert between unsigned integer types and floating point.
945 (define_insn "floatunsdisf2"
946 [(set (match_operand:SF 0 "fr_register_operand" "=f")
947 (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))]
950 [(set_attr "itanium_class" "fcvtfx")])
952 (define_insn "floatunsdidf2"
953 [(set (match_operand:DF 0 "fr_register_operand" "=f")
954 (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))]
957 [(set_attr "itanium_class" "fcvtfx")])
959 (define_insn "floatunsdixf2"
960 [(set (match_operand:XF 0 "fr_register_operand" "=f")
961 (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
964 [(set_attr "itanium_class" "fcvtfx")])
966 (define_insn "fixuns_truncsfdi2"
967 [(set (match_operand:DI 0 "fr_register_operand" "=f")
968 (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
970 "fcvt.fxu.trunc %0 = %1"
971 [(set_attr "itanium_class" "fcvtfx")])
973 (define_insn "fixuns_truncdfdi2"
974 [(set (match_operand:DI 0 "fr_register_operand" "=f")
975 (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))]
977 "fcvt.fxu.trunc %0 = %1"
978 [(set_attr "itanium_class" "fcvtfx")])
980 (define_insn "fixuns_truncxfdi2"
981 [(set (match_operand:DI 0 "fr_register_operand" "=f")
982 (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
984 "fcvt.fxu.trunc %0 = %1"
985 [(set_attr "itanium_class" "fcvtfx")])
987 (define_insn "fixuns_truncxfdi2_alts"
988 [(set (match_operand:DI 0 "fr_register_operand" "=f")
989 (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
990 (use (match_operand:SI 2 "const_int_operand" ""))]
992 "fcvt.fxu.trunc.s%2 %0 = %1"
993 [(set_attr "itanium_class" "fcvtfx")])
995 ;; ::::::::::::::::::::
997 ;; :: Bit field extraction
999 ;; ::::::::::::::::::::
1002 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1003 (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1004 (match_operand:DI 2 "const_int_operand" "n")
1005 (match_operand:DI 3 "const_int_operand" "n")))]
1007 "extr %0 = %1, %3, %2"
1008 [(set_attr "itanium_class" "ishf")])
1010 (define_insn "extzv"
1011 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1012 (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
1013 (match_operand:DI 2 "const_int_operand" "n")
1014 (match_operand:DI 3 "const_int_operand" "n")))]
1016 "extr.u %0 = %1, %3, %2"
1017 [(set_attr "itanium_class" "ishf")])
1019 ;; Insert a bit field.
1020 ;; Can have 3 operands, source1 (inserter), source2 (insertee), dest.
1021 ;; Source1 can be 0 or -1.
1022 ;; Source2 can be 0.
1024 ;; ??? Actual dep instruction is more powerful than what these insv
1025 ;; patterns support. Unfortunately, combine is unable to create patterns
1026 ;; where source2 != dest.
1028 (define_expand "insv"
1029 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "")
1030 (match_operand:DI 1 "const_int_operand" "")
1031 (match_operand:DI 2 "const_int_operand" ""))
1032 (match_operand:DI 3 "nonmemory_operand" ""))]
1035 int width = INTVAL (operands[1]);
1036 int shift = INTVAL (operands[2]);
1038 /* If operand[3] is a constant, and isn't 0 or -1, then load it into a
1040 if (! register_operand (operands[3], DImode)
1041 && operands[3] != const0_rtx && operands[3] != constm1_rtx)
1042 operands[3] = force_reg (DImode, operands[3]);
1044 /* If this is a single dep instruction, we have nothing to do. */
1045 if (! ((register_operand (operands[3], DImode) && width <= 16)
1046 || operands[3] == const0_rtx || operands[3] == constm1_rtx))
1048 /* Check for cases that can be implemented with a mix instruction. */
1049 if (width == 32 && shift == 0)
1051 /* Directly generating the mix4left instruction confuses
1052 optimize_bit_field in function.c. Since this is performing
1053 a useful optimization, we defer generation of the complicated
1054 mix4left RTL to the first splitting phase. */
1055 rtx tmp = gen_reg_rtx (DImode);
1056 emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp));
1059 else if (width == 32 && shift == 32)
1061 emit_insn (gen_mix4right (operands[0], operands[3]));
1065 /* We could handle remaining cases by emitting multiple dep
1068 If we need more than two dep instructions then we lose. A 6
1069 insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than
1070 mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles,
1071 the latter is 6 cycles on an Itanium (TM) processor, because there is
1072 only one function unit that can execute dep and shr immed.
1074 If we only need two dep instruction, then we still lose.
1075 mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away
1076 the unnecessary mov, this is still undesirable because it will be
1077 hard to optimize, and it creates unnecessary pressure on the I0
1083 /* This code may be useful for other IA-64 processors, so we leave it in
1089 emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift),
1093 tmp = gen_reg_rtx (DImode);
1094 emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16)));
1097 operands[1] = GEN_INT (width);
1098 operands[2] = GEN_INT (shift);
1103 (define_insn "*insv_internal"
1104 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1105 (match_operand:DI 1 "const_int_operand" "n")
1106 (match_operand:DI 2 "const_int_operand" "n"))
1107 (match_operand:DI 3 "nonmemory_operand" "rP"))]
1108 "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16)
1109 || operands[3] == const0_rtx || operands[3] == constm1_rtx"
1110 "dep %0 = %3, %0, %2, %1"
1111 [(set_attr "itanium_class" "ishf")])
1113 ;; Combine doesn't like to create bit-field insertions into zero.
1114 (define_insn "*depz_internal"
1115 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1116 (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r")
1117 (match_operand:DI 2 "const_int_operand" "n"))
1118 (match_operand:DI 3 "const_int_operand" "n")))]
1119 "CONST_OK_FOR_M (INTVAL (operands[2]))
1120 && ia64_depz_field_mask (operands[3], operands[2]) > 0"
1122 operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1123 return "%,dep.z %0 = %1, %2, %3";
1125 [(set_attr "itanium_class" "ishf")])
1127 (define_insn "shift_mix4left"
1128 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1129 (const_int 32) (const_int 0))
1130 (match_operand:DI 1 "gr_register_operand" "r"))
1131 (clobber (match_operand:DI 2 "gr_register_operand" "=r"))]
1134 [(set_attr "itanium_class" "unknown")])
1137 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1138 (const_int 32) (const_int 0))
1139 (match_operand:DI 1 "register_operand" ""))
1140 (clobber (match_operand:DI 2 "register_operand" ""))]
1142 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1143 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1144 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1145 "operands[3] = operands[2];")
1148 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
1149 (const_int 32) (const_int 0))
1150 (match_operand:DI 1 "register_operand" ""))
1151 (clobber (match_operand:DI 2 "register_operand" ""))]
1152 "! reload_completed"
1153 [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32)))
1154 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0))
1155 (lshiftrt:DI (match_dup 3) (const_int 32)))]
1156 "operands[3] = operands[2];")
1158 (define_insn "*mix4left"
1159 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1160 (const_int 32) (const_int 0))
1161 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r")
1164 "mix4.l %0 = %0, %r1"
1165 [(set_attr "itanium_class" "mmshf")])
1167 (define_insn "mix4right"
1168 [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r")
1169 (const_int 32) (const_int 32))
1170 (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))]
1172 "mix4.r %0 = %r1, %0"
1173 [(set_attr "itanium_class" "mmshf")])
1175 ;; This is used by the rotrsi3 pattern.
1177 (define_insn "*mix4right_3op"
1178 [(set (match_operand:DI 0 "gr_register_operand" "=r")
1179 (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r"))
1180 (ashift:DI (zero_extend:DI
1181 (match_operand:SI 2 "gr_register_operand" "r"))
1184 "mix4.r %0 = %2, %1"
1185 [(set_attr "itanium_class" "mmshf")])
1188 ;; ::::::::::::::::::::
1190 ;; :: 1 bit Integer arithmetic
1192 ;; ::::::::::::::::::::
1194 (define_insn_and_split "andbi3"
1195 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1196 (and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1197 (match_operand:BI 2 "register_operand" "c,r,r")))]
1201 tbit.nz.and.orcm %0, %I0 = %2, 0
1204 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1205 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1206 [(cond_exec (eq (match_dup 2) (const_int 0))
1207 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1210 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1212 (define_insn_and_split "*andcmbi3"
1213 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1214 (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
1215 (match_operand:BI 2 "register_operand" "0,0,r")))]
1219 tbit.z.and.orcm %0, %I0 = %1, 0
1222 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1223 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1224 [(cond_exec (ne (match_dup 1) (const_int 0))
1225 (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
1228 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1230 (define_insn_and_split "iorbi3"
1231 [(set (match_operand:BI 0 "register_operand" "=c,c,r")
1232 (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
1233 (match_operand:BI 2 "register_operand" "c,r,r")))]
1237 tbit.nz.or.andcm %0, %I0 = %2, 0
1240 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1241 && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
1242 [(cond_exec (ne (match_dup 2) (const_int 0))
1243 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1246 [(set_attr "itanium_class" "unknown,tbit,ilog")])
1248 (define_insn_and_split "*iorcmbi3"
1249 [(set (match_operand:BI 0 "register_operand" "=c,c")
1250 (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
1251 (match_operand:BI 2 "register_operand" "0,0")))]
1255 tbit.z.or.andcm %0, %I0 = %1, 0"
1257 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1258 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
1259 [(cond_exec (eq (match_dup 1) (const_int 0))
1260 (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
1263 [(set_attr "itanium_class" "unknown,tbit")])
1265 (define_insn "one_cmplbi2"
1266 [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
1267 (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
1268 (clobber (match_scratch:BI 2 "=X,X,c,X"))]
1271 tbit.z %0, %I0 = %1, 0
1275 [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")])
1278 [(set (match_operand:BI 0 "register_operand" "")
1279 (not:BI (match_operand:BI 1 "register_operand" "")))
1280 (clobber (match_scratch:BI 2 ""))]
1282 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1283 && rtx_equal_p (operands[0], operands[1])"
1284 [(set (match_dup 4) (match_dup 3))
1285 (set (match_dup 0) (const_int 1))
1286 (cond_exec (ne (match_dup 2) (const_int 0))
1287 (set (match_dup 0) (const_int 0)))
1288 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1289 "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
1290 operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
1293 [(set (match_operand:BI 0 "register_operand" "")
1294 (not:BI (match_operand:BI 1 "register_operand" "")))
1295 (clobber (match_scratch:BI 2 ""))]
1297 && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
1298 && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
1299 && ! rtx_equal_p (operands[0], operands[1])"
1300 [(cond_exec (ne (match_dup 1) (const_int 0))
1301 (set (match_dup 0) (const_int 0)))
1302 (cond_exec (eq (match_dup 1) (const_int 0))
1303 (set (match_dup 0) (const_int 1)))
1304 (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
1307 (define_insn "*cmpsi_and_0"
1308 [(set (match_operand:BI 0 "register_operand" "=c")
1309 (and:BI (match_operator:BI 4 "predicate_operator"
1310 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1311 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1312 (match_operand:BI 1 "register_operand" "0")))]
1314 "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
1315 [(set_attr "itanium_class" "icmp")])
1317 (define_insn "*cmpsi_and_1"
1318 [(set (match_operand:BI 0 "register_operand" "=c")
1319 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1320 [(match_operand:SI 2 "gr_register_operand" "r")
1322 (match_operand:BI 1 "register_operand" "0")))]
1324 "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
1325 [(set_attr "itanium_class" "icmp")])
1327 (define_insn "*cmpsi_andnot_0"
1328 [(set (match_operand:BI 0 "register_operand" "=c")
1329 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1330 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1331 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1332 (match_operand:BI 1 "register_operand" "0")))]
1334 "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
1335 [(set_attr "itanium_class" "icmp")])
1337 (define_insn "*cmpsi_andnot_1"
1338 [(set (match_operand:BI 0 "register_operand" "=c")
1339 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1340 [(match_operand:SI 2 "gr_register_operand" "r")
1342 (match_operand:BI 1 "register_operand" "0")))]
1344 "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
1345 [(set_attr "itanium_class" "icmp")])
1347 (define_insn "*cmpdi_and_0"
1348 [(set (match_operand:BI 0 "register_operand" "=c")
1349 (and:BI (match_operator:BI 4 "predicate_operator"
1350 [(match_operand:DI 2 "gr_register_operand" "r")
1351 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1352 (match_operand:BI 1 "register_operand" "0")))]
1354 "cmp.%C4.and.orcm %0, %I0 = %3, %2"
1355 [(set_attr "itanium_class" "icmp")])
1357 (define_insn "*cmpdi_and_1"
1358 [(set (match_operand:BI 0 "register_operand" "=c")
1359 (and:BI (match_operator:BI 3 "signed_inequality_operator"
1360 [(match_operand:DI 2 "gr_register_operand" "r")
1362 (match_operand:BI 1 "register_operand" "0")))]
1364 "cmp.%C3.and.orcm %0, %I0 = r0, %2"
1365 [(set_attr "itanium_class" "icmp")])
1367 (define_insn "*cmpdi_andnot_0"
1368 [(set (match_operand:BI 0 "register_operand" "=c")
1369 (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
1370 [(match_operand:DI 2 "gr_register_operand" "r")
1371 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1372 (match_operand:BI 1 "register_operand" "0")))]
1374 "cmp.%C4.or.andcm %I0, %0 = %3, %2"
1375 [(set_attr "itanium_class" "icmp")])
1377 (define_insn "*cmpdi_andnot_1"
1378 [(set (match_operand:BI 0 "register_operand" "=c")
1379 (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1380 [(match_operand:DI 2 "gr_register_operand" "r")
1382 (match_operand:BI 1 "register_operand" "0")))]
1384 "cmp.%C3.or.andcm %I0, %0 = r0, %2"
1385 [(set_attr "itanium_class" "icmp")])
1387 (define_insn "*tbit_and_0"
1388 [(set (match_operand:BI 0 "register_operand" "=c")
1389 (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1392 (match_operand:BI 2 "register_operand" "0")))]
1394 "tbit.nz.and.orcm %0, %I0 = %1, 0"
1395 [(set_attr "itanium_class" "tbit")])
1397 (define_insn "*tbit_and_1"
1398 [(set (match_operand:BI 0 "register_operand" "=c")
1399 (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1402 (match_operand:BI 2 "register_operand" "0")))]
1404 "tbit.z.and.orcm %0, %I0 = %1, 0"
1405 [(set_attr "itanium_class" "tbit")])
1407 (define_insn "*tbit_and_2"
1408 [(set (match_operand:BI 0 "register_operand" "=c")
1409 (and:BI (ne:BI (zero_extract:DI
1410 (match_operand:DI 1 "gr_register_operand" "r")
1412 (match_operand:DI 2 "const_int_operand" "n"))
1414 (match_operand:BI 3 "register_operand" "0")))]
1416 "tbit.nz.and.orcm %0, %I0 = %1, %2"
1417 [(set_attr "itanium_class" "tbit")])
1419 (define_insn "*tbit_and_3"
1420 [(set (match_operand:BI 0 "register_operand" "=c")
1421 (and:BI (eq:BI (zero_extract:DI
1422 (match_operand:DI 1 "gr_register_operand" "r")
1424 (match_operand:DI 2 "const_int_operand" "n"))
1426 (match_operand:BI 3 "register_operand" "0")))]
1428 "tbit.z.and.orcm %0, %I0 = %1, %2"
1429 [(set_attr "itanium_class" "tbit")])
1431 (define_insn "*cmpsi_or_0"
1432 [(set (match_operand:BI 0 "register_operand" "=c")
1433 (ior:BI (match_operator:BI 4 "predicate_operator"
1434 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1435 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
1436 (match_operand:BI 1 "register_operand" "0")))]
1438 "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
1439 [(set_attr "itanium_class" "icmp")])
1441 (define_insn "*cmpsi_or_1"
1442 [(set (match_operand:BI 0 "register_operand" "=c")
1443 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1444 [(match_operand:SI 2 "gr_register_operand" "r")
1446 (match_operand:BI 1 "register_operand" "0")))]
1448 "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
1449 [(set_attr "itanium_class" "icmp")])
1451 (define_insn "*cmpsi_orcm_0"
1452 [(set (match_operand:BI 0 "register_operand" "=c")
1453 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1454 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
1455 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
1456 (match_operand:BI 1 "register_operand" "0")))]
1458 "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
1459 [(set_attr "itanium_class" "icmp")])
1461 (define_insn "*cmpsi_orcm_1"
1462 [(set (match_operand:BI 0 "register_operand" "=c")
1463 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1464 [(match_operand:SI 2 "gr_register_operand" "r")
1466 (match_operand:BI 1 "register_operand" "0")))]
1468 "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
1469 [(set_attr "itanium_class" "icmp")])
1471 (define_insn "*cmpdi_or_0"
1472 [(set (match_operand:BI 0 "register_operand" "=c")
1473 (ior:BI (match_operator:BI 4 "predicate_operator"
1474 [(match_operand:DI 2 "gr_register_operand" "r")
1475 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
1476 (match_operand:BI 1 "register_operand" "0")))]
1478 "cmp.%C4.or.andcm %0, %I0 = %3, %2"
1479 [(set_attr "itanium_class" "icmp")])
1481 (define_insn "*cmpdi_or_1"
1482 [(set (match_operand:BI 0 "register_operand" "=c")
1483 (ior:BI (match_operator:BI 3 "signed_inequality_operator"
1484 [(match_operand:DI 2 "gr_register_operand" "r")
1486 (match_operand:BI 1 "register_operand" "0")))]
1488 "cmp.%C3.or.andcm %0, %I0 = r0, %2"
1489 [(set_attr "itanium_class" "icmp")])
1491 (define_insn "*cmpdi_orcm_0"
1492 [(set (match_operand:BI 0 "register_operand" "=c")
1493 (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
1494 [(match_operand:DI 2 "gr_register_operand" "r")
1495 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
1496 (match_operand:BI 1 "register_operand" "0")))]
1498 "cmp.%C4.and.orcm %I0, %0 = %3, %2"
1499 [(set_attr "itanium_class" "icmp")])
1501 (define_insn "*cmpdi_orcm_1"
1502 [(set (match_operand:BI 0 "register_operand" "=c")
1503 (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
1504 [(match_operand:DI 2 "gr_register_operand" "r")
1506 (match_operand:BI 1 "register_operand" "0")))]
1508 "cmp.%C3.and.orcm %I0, %0 = r0, %2"
1509 [(set_attr "itanium_class" "icmp")])
1511 (define_insn "*tbit_or_0"
1512 [(set (match_operand:BI 0 "register_operand" "=c")
1513 (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1516 (match_operand:BI 2 "register_operand" "0")))]
1518 "tbit.nz.or.andcm %0, %I0 = %1, 0"
1519 [(set_attr "itanium_class" "tbit")])
1521 (define_insn "*tbit_or_1"
1522 [(set (match_operand:BI 0 "register_operand" "=c")
1523 (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
1526 (match_operand:BI 2 "register_operand" "0")))]
1528 "tbit.z.or.andcm %0, %I0 = %1, 0"
1529 [(set_attr "itanium_class" "tbit")])
1531 (define_insn "*tbit_or_2"
1532 [(set (match_operand:BI 0 "register_operand" "=c")
1533 (ior:BI (ne:BI (zero_extract:DI
1534 (match_operand:DI 1 "gr_register_operand" "r")
1536 (match_operand:DI 2 "const_int_operand" "n"))
1538 (match_operand:BI 3 "register_operand" "0")))]
1540 "tbit.nz.or.andcm %0, %I0 = %1, %2"
1541 [(set_attr "itanium_class" "tbit")])
1543 (define_insn "*tbit_or_3"
1544 [(set (match_operand:BI 0 "register_operand" "=c")
1545 (ior:BI (eq:BI (zero_extract:DI
1546 (match_operand:DI 1 "gr_register_operand" "r")
1548 (match_operand:DI 2 "const_int_operand" "n"))
1550 (match_operand:BI 3 "register_operand" "0")))]
1552 "tbit.z.or.andcm %0, %I0 = %1, %2"
1553 [(set_attr "itanium_class" "tbit")])
1555 ;; Transform test of and/or of setcc into parallel comparisons.
1558 [(set (match_operand:BI 0 "register_operand" "")
1559 (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1561 (match_operand:DI 3 "register_operand" ""))
1565 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1570 [(set (match_operand:BI 0 "register_operand" "")
1571 (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1573 (match_operand:DI 3 "register_operand" ""))
1577 (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
1579 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1580 (clobber (scratch))])]
1584 [(set (match_operand:BI 0 "register_operand" "")
1585 (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1587 (match_operand:DI 3 "register_operand" ""))
1591 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1596 [(set (match_operand:BI 0 "register_operand" "")
1597 (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
1599 (match_operand:DI 3 "register_operand" ""))
1603 (ior:BI (ne:BI (match_dup 3) (const_int 0))
1605 (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
1606 (clobber (scratch))])]
1609 ;; ??? Incredibly hackish. Either need four proper patterns with all
1610 ;; the alternatives, or rely on sched1 to split the insn and hope that
1611 ;; nothing bad happens to the comparisons in the meantime.
1613 ;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1614 ;; that we're doing height reduction.
1616 ;(define_insn_and_split ""
1617 ; [(set (match_operand:BI 0 "register_operand" "=c")
1618 ; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1619 ; [(match_operand 2 "" "")
1620 ; (match_operand 3 "" "")])
1621 ; (match_operator:BI 4 "comparison_operator"
1622 ; [(match_operand 5 "" "")
1623 ; (match_operand 6 "" "")]))
1625 ; "flag_schedule_insns"
1628 ; [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
1629 ; (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
1632 ;(define_insn_and_split ""
1633 ; [(set (match_operand:BI 0 "register_operand" "=c")
1634 ; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1635 ; [(match_operand 2 "" "")
1636 ; (match_operand 3 "" "")])
1637 ; (match_operator:BI 4 "comparison_operator"
1638 ; [(match_operand 5 "" "")
1639 ; (match_operand 6 "" "")]))
1641 ; "flag_schedule_insns"
1644 ; [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
1645 ; (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
1649 ; [(set (match_operand:BI 0 "register_operand" "")
1650 ; (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
1651 ; [(match_operand 2 "" "")
1652 ; (match_operand 3 "" "")])
1653 ; (match_operand:BI 7 "register_operand" ""))
1654 ; (and:BI (match_operator:BI 4 "comparison_operator"
1655 ; [(match_operand 5 "" "")
1656 ; (match_operand 6 "" "")])
1657 ; (match_operand:BI 8 "register_operand" ""))))]
1659 ; [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
1660 ; (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
1665 ; [(set (match_operand:BI 0 "register_operand" "")
1666 ; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
1667 ; [(match_operand 2 "" "")
1668 ; (match_operand 3 "" "")])
1669 ; (match_operand:BI 7 "register_operand" ""))
1670 ; (ior:BI (match_operator:BI 4 "comparison_operator"
1671 ; [(match_operand 5 "" "")
1672 ; (match_operand 6 "" "")])
1673 ; (match_operand:BI 8 "register_operand" ""))))]
1675 ; [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
1676 ; (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
1680 ;; Try harder to avoid predicate copies by duplicating compares.
1681 ;; Note that we'll have already split the predicate copy, which
1682 ;; is kind of a pain, but oh well.
1685 [(set (match_operand:BI 0 "register_operand" "")
1686 (match_operand:BI 1 "comparison_operator" ""))
1687 (set (match_operand:CCI 2 "register_operand" "")
1688 (match_operand:CCI 3 "register_operand" ""))
1689 (set (match_operand:CCI 4 "register_operand" "")
1690 (match_operand:CCI 5 "register_operand" ""))
1691 (set (match_operand:BI 6 "register_operand" "")
1692 (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))]
1693 "REGNO (operands[3]) == REGNO (operands[0])
1694 && REGNO (operands[4]) == REGNO (operands[0]) + 1
1695 && REGNO (operands[4]) == REGNO (operands[2]) + 1
1696 && REGNO (operands[6]) == REGNO (operands[2])"
1697 [(set (match_dup 0) (match_dup 1))
1698 (set (match_dup 6) (match_dup 7))]
1699 "operands[7] = copy_rtx (operands[1]);")
1701 ;; ::::::::::::::::::::
1703 ;; :: 16 bit Integer arithmetic
1705 ;; ::::::::::::::::::::
1707 (define_insn "mulhi3"
1708 [(set (match_operand:HI 0 "gr_register_operand" "=r")
1709 (mult:HI (match_operand:HI 1 "gr_register_operand" "r")
1710 (match_operand:HI 2 "gr_register_operand" "r")))]
1712 "pmpy2.r %0 = %1, %2"
1713 [(set_attr "itanium_class" "mmmul")])
1716 ;; ::::::::::::::::::::
1718 ;; :: 32 bit Integer arithmetic
1720 ;; ::::::::::::::::::::
1722 (define_insn "addsi3"
1723 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
1724 (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a")
1725 (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
1731 [(set_attr "itanium_class" "ialu")])
1733 (define_insn "*addsi3_plus1"
1734 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1735 (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r")
1736 (match_operand:SI 2 "gr_register_operand" "r"))
1739 "add %0 = %1, %2, 1"
1740 [(set_attr "itanium_class" "ialu")])
1742 (define_insn "*addsi3_plus1_alt"
1743 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1744 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1748 "add %0 = %1, %1, 1"
1749 [(set_attr "itanium_class" "ialu")])
1751 (define_insn "*addsi3_shladd"
1752 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1753 (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r")
1754 (match_operand:SI 2 "shladd_operand" "n"))
1755 (match_operand:SI 3 "gr_register_operand" "r")))]
1757 "shladd %0 = %1, %S2, %3"
1758 [(set_attr "itanium_class" "ialu")])
1760 (define_insn "subsi3"
1761 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1762 (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK")
1763 (match_operand:SI 2 "gr_register_operand" "r")))]
1766 [(set_attr "itanium_class" "ialu")])
1768 (define_insn "*subsi3_minus1"
1769 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1770 (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r"))
1771 (match_operand:SI 2 "gr_register_operand" "r")))]
1773 "sub %0 = %2, %1, 1"
1774 [(set_attr "itanium_class" "ialu")])
1776 ;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
1778 (define_insn "mulsi3"
1779 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1780 (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1781 (match_operand:SI 2 "grfr_register_operand" "f")))]
1783 "xmpy.l %0 = %1, %2"
1784 [(set_attr "itanium_class" "xmpy")])
1786 (define_insn "maddsi4"
1787 [(set (match_operand:SI 0 "fr_register_operand" "=f")
1788 (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
1789 (match_operand:SI 2 "grfr_register_operand" "f"))
1790 (match_operand:SI 3 "grfr_register_operand" "f")))]
1792 "xma.l %0 = %1, %2, %3"
1793 [(set_attr "itanium_class" "xmpy")])
1795 (define_insn "negsi2"
1796 [(set (match_operand:SI 0 "gr_register_operand" "=r")
1797 (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))]
1800 [(set_attr "itanium_class" "ialu")])
1802 (define_expand "abssi2"
1804 (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
1805 (set (match_operand:SI 0 "gr_register_operand" "")
1806 (if_then_else:SI (eq (match_dup 2) (const_int 0))
1807 (neg:SI (match_dup 1))
1810 { operands[2] = gen_reg_rtx (BImode); })
1812 (define_expand "sminsi3"
1814 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1815 (match_operand:SI 2 "gr_register_operand" "")))
1816 (set (match_operand:SI 0 "gr_register_operand" "")
1817 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1818 (match_dup 2) (match_dup 1)))]
1820 { operands[3] = gen_reg_rtx (BImode); })
1822 (define_expand "smaxsi3"
1824 (ge:BI (match_operand:SI 1 "gr_register_operand" "")
1825 (match_operand:SI 2 "gr_register_operand" "")))
1826 (set (match_operand:SI 0 "gr_register_operand" "")
1827 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1828 (match_dup 1) (match_dup 2)))]
1830 { operands[3] = gen_reg_rtx (BImode); })
1832 (define_expand "uminsi3"
1834 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1835 (match_operand:SI 2 "gr_register_operand" "")))
1836 (set (match_operand:SI 0 "gr_register_operand" "")
1837 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1838 (match_dup 2) (match_dup 1)))]
1840 { operands[3] = gen_reg_rtx (BImode); })
1842 (define_expand "umaxsi3"
1844 (geu:BI (match_operand:SI 1 "gr_register_operand" "")
1845 (match_operand:SI 2 "gr_register_operand" "")))
1846 (set (match_operand:SI 0 "gr_register_operand" "")
1847 (if_then_else:SI (ne (match_dup 3) (const_int 0))
1848 (match_dup 1) (match_dup 2)))]
1850 { operands[3] = gen_reg_rtx (BImode); })
1852 (define_expand "divsi3"
1853 [(set (match_operand:SI 0 "register_operand" "")
1854 (div:SI (match_operand:SI 1 "general_operand" "")
1855 (match_operand:SI 2 "general_operand" "")))]
1856 "TARGET_INLINE_INT_DIV"
1858 rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1859 REAL_VALUE_TYPE twon34_r;
1861 op0_xf = gen_reg_rtx (XFmode);
1862 op0_di = gen_reg_rtx (DImode);
1864 if (CONSTANT_P (operands[1]))
1865 operands[1] = force_reg (SImode, operands[1]);
1866 op1_xf = gen_reg_rtx (XFmode);
1867 expand_float (op1_xf, operands[1], 0);
1869 if (CONSTANT_P (operands[2]))
1870 operands[2] = force_reg (SImode, operands[2]);
1871 op2_xf = gen_reg_rtx (XFmode);
1872 expand_float (op2_xf, operands[2], 0);
1875 real_2expN (&twon34_r, -34);
1876 twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
1877 twon34 = force_reg (XFmode, twon34);
1879 emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1881 emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
1882 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1886 (define_expand "modsi3"
1887 [(set (match_operand:SI 0 "register_operand" "")
1888 (mod:SI (match_operand:SI 1 "general_operand" "")
1889 (match_operand:SI 2 "general_operand" "")))]
1890 "TARGET_INLINE_INT_DIV"
1892 rtx op2_neg, op1_di, div;
1894 div = gen_reg_rtx (SImode);
1895 emit_insn (gen_divsi3 (div, operands[1], operands[2]));
1897 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1899 /* This is a trick to get us to reuse the value that we're sure to
1900 have already copied to the FP regs. */
1901 op1_di = gen_reg_rtx (DImode);
1902 convert_move (op1_di, operands[1], 0);
1904 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1905 gen_lowpart (SImode, op1_di)));
1909 (define_expand "udivsi3"
1910 [(set (match_operand:SI 0 "register_operand" "")
1911 (udiv:SI (match_operand:SI 1 "general_operand" "")
1912 (match_operand:SI 2 "general_operand" "")))]
1913 "TARGET_INLINE_INT_DIV"
1915 rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
1916 REAL_VALUE_TYPE twon34_r;
1918 op0_xf = gen_reg_rtx (XFmode);
1919 op0_di = gen_reg_rtx (DImode);
1921 if (CONSTANT_P (operands[1]))
1922 operands[1] = force_reg (SImode, operands[1]);
1923 op1_xf = gen_reg_rtx (XFmode);
1924 expand_float (op1_xf, operands[1], 1);
1926 if (CONSTANT_P (operands[2]))
1927 operands[2] = force_reg (SImode, operands[2]);
1928 op2_xf = gen_reg_rtx (XFmode);
1929 expand_float (op2_xf, operands[2], 1);
1932 real_2expN (&twon34_r, -34);
1933 twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
1934 twon34 = force_reg (XFmode, twon34);
1936 emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
1938 emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
1939 emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
1943 (define_expand "umodsi3"
1944 [(set (match_operand:SI 0 "register_operand" "")
1945 (umod:SI (match_operand:SI 1 "general_operand" "")
1946 (match_operand:SI 2 "general_operand" "")))]
1947 "TARGET_INLINE_INT_DIV"
1949 rtx op2_neg, op1_di, div;
1951 div = gen_reg_rtx (SImode);
1952 emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
1954 op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
1956 /* This is a trick to get us to reuse the value that we're sure to
1957 have already copied to the FP regs. */
1958 op1_di = gen_reg_rtx (DImode);
1959 convert_move (op1_di, operands[1], 1);
1961 emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
1962 gen_lowpart (SImode, op1_di)));
1966 (define_insn_and_split "divsi3_internal"
1967 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
1968 (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
1969 (match_operand:XF 2 "fr_register_operand" "f"))))
1970 (clobber (match_scratch:XF 4 "=&f"))
1971 (clobber (match_scratch:XF 5 "=&f"))
1972 (clobber (match_scratch:BI 6 "=c"))
1973 (use (match_operand:XF 3 "fr_register_operand" "f"))]
1974 "TARGET_INLINE_INT_DIV"
1976 "&& reload_completed"
1977 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
1978 (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
1979 UNSPEC_FR_RECIP_APPROX))
1980 (use (const_int 1))])
1981 (cond_exec (ne (match_dup 6) (const_int 0))
1982 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
1983 (use (const_int 1))]))
1984 (cond_exec (ne (match_dup 6) (const_int 0))
1985 (parallel [(set (match_dup 5)
1986 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
1988 (use (const_int 1))]))
1989 (cond_exec (ne (match_dup 6) (const_int 0))
1990 (parallel [(set (match_dup 4)
1991 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
1993 (use (const_int 1))]))
1994 (cond_exec (ne (match_dup 6) (const_int 0))
1995 (parallel [(set (match_dup 5)
1996 (plus:XF (mult:XF (match_dup 5) (match_dup 5))
1998 (use (const_int 1))]))
1999 (cond_exec (ne (match_dup 6) (const_int 0))
2000 (parallel [(set (match_dup 0)
2001 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2003 (use (const_int 1))]))
2005 "operands[7] = CONST1_RTX (XFmode);"
2006 [(set_attr "predicable" "no")])
2008 ;; ::::::::::::::::::::
2010 ;; :: 64 bit Integer arithmetic
2012 ;; ::::::::::::::::::::
2014 (define_insn "adddi3"
2015 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
2016 (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a")
2017 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))]
2023 [(set_attr "itanium_class" "ialu")])
2025 (define_insn "*adddi3_plus1"
2026 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2027 (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r")
2028 (match_operand:DI 2 "gr_register_operand" "r"))
2031 "add %0 = %1, %2, 1"
2032 [(set_attr "itanium_class" "ialu")])
2034 ;; This has some of the same problems as shladd. We let the shladd
2035 ;; eliminator hack handle it, which results in the 1 being forced into
2036 ;; a register, but not more ugliness here.
2037 (define_insn "*adddi3_plus1_alt"
2038 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2039 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
2043 "add %0 = %1, %1, 1"
2044 [(set_attr "itanium_class" "ialu")])
2046 (define_insn "subdi3"
2047 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2048 (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK")
2049 (match_operand:DI 2 "gr_register_operand" "r")))]
2052 [(set_attr "itanium_class" "ialu")])
2054 (define_insn "*subdi3_minus1"
2055 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2056 (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r"))
2057 (match_operand:DI 2 "gr_register_operand" "r")))]
2059 "sub %0 = %2, %1, 1"
2060 [(set_attr "itanium_class" "ialu")])
2062 ;; ??? Use grfr instead of fr because of virtual register elimination
2063 ;; and silly test cases multiplying by the frame pointer.
2064 (define_insn "muldi3"
2065 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2066 (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2067 (match_operand:DI 2 "grfr_register_operand" "f")))]
2069 "xmpy.l %0 = %1, %2"
2070 [(set_attr "itanium_class" "xmpy")])
2072 ;; ??? If operand 3 is an eliminable reg, then register elimination causes the
2073 ;; same problem that we have with shladd below. Unfortunately, this case is
2074 ;; much harder to fix because the multiply puts the result in an FP register,
2075 ;; but the add needs inputs from a general register. We add a spurious clobber
2076 ;; here so that it will be present just in case register elimination gives us
2077 ;; the funny result.
2079 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2081 ;; ??? Maybe we should change how adds are canonicalized.
2083 (define_insn "madddi4"
2084 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2085 (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
2086 (match_operand:DI 2 "grfr_register_operand" "f"))
2087 (match_operand:DI 3 "grfr_register_operand" "f")))
2088 (clobber (match_scratch:DI 4 "=X"))]
2090 "xma.l %0 = %1, %2, %3"
2091 [(set_attr "itanium_class" "xmpy")])
2093 ;; This can be created by register elimination if operand3 of shladd is an
2094 ;; eliminable register or has reg_equiv_constant set.
2096 ;; We have to use nonmemory_operand for operand 4, to ensure that the
2097 ;; validate_changes call inside eliminate_regs will always succeed. If it
2098 ;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
2101 (define_insn "*madddi4_elim"
2102 [(set (match_operand:DI 0 "register_operand" "=&r")
2103 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
2104 (match_operand:DI 2 "register_operand" "f"))
2105 (match_operand:DI 3 "register_operand" "f"))
2106 (match_operand:DI 4 "nonmemory_operand" "rI")))
2107 (clobber (match_scratch:DI 5 "=f"))]
2108 "reload_in_progress"
2110 [(set_attr "itanium_class" "unknown")])
2113 [(set (match_operand:DI 0 "register_operand" "")
2114 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
2115 (match_operand:DI 2 "register_operand" ""))
2116 (match_operand:DI 3 "register_operand" ""))
2117 (match_operand:DI 4 "gr_reg_or_14bit_operand" "")))
2118 (clobber (match_scratch:DI 5 ""))]
2120 [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
2122 (clobber (match_dup 0))])
2123 (set (match_dup 0) (match_dup 5))
2124 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
2127 ;; ??? There are highpart multiply and add instructions, but we have no way
2128 ;; to generate them.
2130 (define_insn "smuldi3_highpart"
2131 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2134 (mult:TI (sign_extend:TI
2135 (match_operand:DI 1 "fr_register_operand" "f"))
2137 (match_operand:DI 2 "fr_register_operand" "f")))
2140 "xmpy.h %0 = %1, %2"
2141 [(set_attr "itanium_class" "xmpy")])
2143 (define_insn "umuldi3_highpart"
2144 [(set (match_operand:DI 0 "fr_register_operand" "=f")
2147 (mult:TI (zero_extend:TI
2148 (match_operand:DI 1 "fr_register_operand" "f"))
2150 (match_operand:DI 2 "fr_register_operand" "f")))
2153 "xmpy.hu %0 = %1, %2"
2154 [(set_attr "itanium_class" "xmpy")])
2156 (define_insn "negdi2"
2157 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2158 (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2161 [(set_attr "itanium_class" "ialu")])
2163 (define_expand "absdi2"
2165 (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2166 (set (match_operand:DI 0 "gr_register_operand" "")
2167 (if_then_else:DI (eq (match_dup 2) (const_int 0))
2168 (neg:DI (match_dup 1))
2171 { operands[2] = gen_reg_rtx (BImode); })
2173 (define_expand "smindi3"
2175 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2176 (match_operand:DI 2 "gr_register_operand" "")))
2177 (set (match_operand:DI 0 "gr_register_operand" "")
2178 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2179 (match_dup 2) (match_dup 1)))]
2181 { operands[3] = gen_reg_rtx (BImode); })
2183 (define_expand "smaxdi3"
2185 (ge:BI (match_operand:DI 1 "gr_register_operand" "")
2186 (match_operand:DI 2 "gr_register_operand" "")))
2187 (set (match_operand:DI 0 "gr_register_operand" "")
2188 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2189 (match_dup 1) (match_dup 2)))]
2191 { operands[3] = gen_reg_rtx (BImode); })
2193 (define_expand "umindi3"
2195 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2196 (match_operand:DI 2 "gr_register_operand" "")))
2197 (set (match_operand:DI 0 "gr_register_operand" "")
2198 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2199 (match_dup 2) (match_dup 1)))]
2201 { operands[3] = gen_reg_rtx (BImode); })
2203 (define_expand "umaxdi3"
2205 (geu:BI (match_operand:DI 1 "gr_register_operand" "")
2206 (match_operand:DI 2 "gr_register_operand" "")))
2207 (set (match_operand:DI 0 "gr_register_operand" "")
2208 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2209 (match_dup 1) (match_dup 2)))]
2211 { operands[3] = gen_reg_rtx (BImode); })
2213 (define_expand "ffsdi2"
2215 (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
2216 (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
2217 (set (match_dup 5) (const_int 0))
2218 (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
2219 (set (match_dup 4) (popcount:DI (match_dup 3)))
2220 (set (match_operand:DI 0 "gr_register_operand" "")
2221 (if_then_else:DI (ne (match_dup 6) (const_int 0))
2222 (match_dup 5) (match_dup 4)))]
2225 operands[2] = gen_reg_rtx (DImode);
2226 operands[3] = gen_reg_rtx (DImode);
2227 operands[4] = gen_reg_rtx (DImode);
2228 operands[5] = gen_reg_rtx (DImode);
2229 operands[6] = gen_reg_rtx (BImode);
2232 (define_expand "ctzdi2"
2233 [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
2235 (set (match_dup 3) (not:DI (match_dup 1)))
2236 (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
2237 (set (match_operand:DI 0 "gr_register_operand" "")
2238 (popcount:DI (match_dup 4)))]
2241 operands[2] = gen_reg_rtx (DImode);
2242 operands[3] = gen_reg_rtx (DImode);
2243 operands[4] = gen_reg_rtx (DImode);
2246 ;; Note the computation here is op0 = 63 - (exp - 0xffff).
2247 (define_expand "clzdi2"
2249 (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "")))
2251 (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
2252 (set (match_dup 4) (const_int 65598))
2253 (set (match_operand:DI 0 "gr_register_operand" "")
2254 (minus:DI (match_dup 4) (match_dup 3)))]
2257 operands[2] = gen_reg_rtx (XFmode);
2258 operands[3] = gen_reg_rtx (DImode);
2259 operands[4] = gen_reg_rtx (DImode);
2262 (define_insn "popcountdi2"
2263 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2264 (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
2267 [(set_attr "itanium_class" "mmmul")])
2269 (define_insn "*getf_exp_xf"
2270 [(set (match_operand:DI 0 "gr_register_operand" "=r")
2271 (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
2275 [(set_attr "itanium_class" "frfr")])
2277 (define_expand "divdi3"
2278 [(set (match_operand:DI 0 "register_operand" "")
2279 (div:DI (match_operand:DI 1 "general_operand" "")
2280 (match_operand:DI 2 "general_operand" "")))]
2281 "TARGET_INLINE_INT_DIV"
2283 rtx op1_xf, op2_xf, op0_xf;
2285 op0_xf = gen_reg_rtx (XFmode);
2287 if (CONSTANT_P (operands[1]))
2288 operands[1] = force_reg (DImode, operands[1]);
2289 op1_xf = gen_reg_rtx (XFmode);
2290 expand_float (op1_xf, operands[1], 0);
2292 if (CONSTANT_P (operands[2]))
2293 operands[2] = force_reg (DImode, operands[2]);
2294 op2_xf = gen_reg_rtx (XFmode);
2295 expand_float (op2_xf, operands[2], 0);
2297 if (TARGET_INLINE_INT_DIV_LAT)
2298 emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2300 emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2302 emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2306 (define_expand "moddi3"
2307 [(set (match_operand:DI 0 "register_operand" "")
2308 (mod:SI (match_operand:DI 1 "general_operand" "")
2309 (match_operand:DI 2 "general_operand" "")))]
2310 "TARGET_INLINE_INT_DIV"
2314 div = gen_reg_rtx (DImode);
2315 emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2317 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2319 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2323 (define_expand "udivdi3"
2324 [(set (match_operand:DI 0 "register_operand" "")
2325 (udiv:DI (match_operand:DI 1 "general_operand" "")
2326 (match_operand:DI 2 "general_operand" "")))]
2327 "TARGET_INLINE_INT_DIV"
2329 rtx op1_xf, op2_xf, op0_xf;
2331 op0_xf = gen_reg_rtx (XFmode);
2333 if (CONSTANT_P (operands[1]))
2334 operands[1] = force_reg (DImode, operands[1]);
2335 op1_xf = gen_reg_rtx (XFmode);
2336 expand_float (op1_xf, operands[1], 1);
2338 if (CONSTANT_P (operands[2]))
2339 operands[2] = force_reg (DImode, operands[2]);
2340 op2_xf = gen_reg_rtx (XFmode);
2341 expand_float (op2_xf, operands[2], 1);
2343 if (TARGET_INLINE_INT_DIV_LAT)
2344 emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
2346 emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
2348 emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2352 (define_expand "umoddi3"
2353 [(set (match_operand:DI 0 "register_operand" "")
2354 (umod:DI (match_operand:DI 1 "general_operand" "")
2355 (match_operand:DI 2 "general_operand" "")))]
2356 "TARGET_INLINE_INT_DIV"
2360 div = gen_reg_rtx (DImode);
2361 emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2363 op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2365 emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2369 (define_insn_and_split "divdi3_internal_lat"
2370 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2371 (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2372 (match_operand:XF 2 "fr_register_operand" "f"))))
2373 (clobber (match_scratch:XF 3 "=&f"))
2374 (clobber (match_scratch:XF 4 "=&f"))
2375 (clobber (match_scratch:XF 5 "=&f"))
2376 (clobber (match_scratch:BI 6 "=c"))]
2377 "TARGET_INLINE_INT_DIV_LAT"
2379 "&& reload_completed"
2380 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2381 (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
2382 UNSPEC_FR_RECIP_APPROX))
2383 (use (const_int 1))])
2384 (cond_exec (ne (match_dup 6) (const_int 0))
2385 (parallel [(set (match_dup 3)
2386 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
2388 (use (const_int 1))]))
2389 (cond_exec (ne (match_dup 6) (const_int 0))
2390 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
2391 (use (const_int 1))]))
2392 (cond_exec (ne (match_dup 6) (const_int 0))
2393 (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
2394 (use (const_int 1))]))
2395 (cond_exec (ne (match_dup 6) (const_int 0))
2396 (parallel [(set (match_dup 4)
2397 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2399 (use (const_int 1))]))
2400 (cond_exec (ne (match_dup 6) (const_int 0))
2401 (parallel [(set (match_dup 0)
2402 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2404 (use (const_int 1))]))
2405 (cond_exec (ne (match_dup 6) (const_int 0))
2406 (parallel [(set (match_dup 3)
2407 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
2409 (use (const_int 1))]))
2410 (cond_exec (ne (match_dup 6) (const_int 0))
2411 (parallel [(set (match_dup 0)
2412 (plus:XF (mult:XF (match_dup 5) (match_dup 0))
2414 (use (const_int 1))]))
2415 (cond_exec (ne (match_dup 6) (const_int 0))
2416 (parallel [(set (match_dup 4)
2417 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
2419 (use (const_int 1))]))
2420 (cond_exec (ne (match_dup 6) (const_int 0))
2421 (parallel [(set (match_dup 0)
2422 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2424 (use (const_int 1))]))
2426 "operands[7] = CONST1_RTX (XFmode);"
2427 [(set_attr "predicable" "no")])
2429 (define_insn_and_split "divdi3_internal_thr"
2430 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
2431 (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
2432 (match_operand:XF 2 "fr_register_operand" "f"))))
2433 (clobber (match_scratch:XF 3 "=&f"))
2434 (clobber (match_scratch:XF 4 "=f"))
2435 (clobber (match_scratch:BI 5 "=c"))]
2436 "TARGET_INLINE_INT_DIV_THR"
2438 "&& reload_completed"
2439 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
2440 (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
2441 UNSPEC_FR_RECIP_APPROX))
2442 (use (const_int 1))])
2443 (cond_exec (ne (match_dup 5) (const_int 0))
2444 (parallel [(set (match_dup 3)
2445 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
2447 (use (const_int 1))]))
2448 (cond_exec (ne (match_dup 5) (const_int 0))
2449 (parallel [(set (match_dup 0)
2450 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2452 (use (const_int 1))]))
2453 (cond_exec (ne (match_dup 5) (const_int 0))
2454 (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
2455 (use (const_int 1))]))
2456 (cond_exec (ne (match_dup 5) (const_int 0))
2457 (parallel [(set (match_dup 0)
2458 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
2460 (use (const_int 1))]))
2461 (cond_exec (ne (match_dup 5) (const_int 0))
2462 (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
2463 (use (const_int 1))]))
2464 (cond_exec (ne (match_dup 5) (const_int 0))
2465 (parallel [(set (match_dup 4)
2466 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
2468 (use (const_int 1))]))
2469 (cond_exec (ne (match_dup 5) (const_int 0))
2470 (parallel [(set (match_dup 0)
2471 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
2473 (use (const_int 1))]))
2475 "operands[6] = CONST1_RTX (XFmode);"
2476 [(set_attr "predicable" "no")])
2478 ;; ::::::::::::::::::::
2480 ;; :: 32 bit floating point arithmetic
2482 ;; ::::::::::::::::::::
2484 (define_insn "addsf3"
2485 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2486 (plus:SF (match_operand:SF 1 "fr_register_operand" "%f")
2487 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2489 "fadd.s %0 = %1, %F2"
2490 [(set_attr "itanium_class" "fmac")])
2492 (define_insn "subsf3"
2493 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2494 (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
2495 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2497 "fsub.s %0 = %F1, %F2"
2498 [(set_attr "itanium_class" "fmac")])
2500 (define_insn "mulsf3"
2501 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2502 (mult:SF (match_operand:SF 1 "fr_register_operand" "%f")
2503 (match_operand:SF 2 "fr_register_operand" "f")))]
2505 "fmpy.s %0 = %1, %2"
2506 [(set_attr "itanium_class" "fmac")])
2508 (define_insn "abssf2"
2509 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2510 (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2513 [(set_attr "itanium_class" "fmisc")])
2515 (define_insn "negsf2"
2516 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2517 (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2520 [(set_attr "itanium_class" "fmisc")])
2522 (define_insn "*nabssf2"
2523 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2524 (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))]
2527 [(set_attr "itanium_class" "fmisc")])
2529 (define_insn "minsf3"
2530 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2531 (smin:SF (match_operand:SF 1 "fr_register_operand" "f")
2532 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2535 [(set_attr "itanium_class" "fmisc")])
2537 (define_insn "maxsf3"
2538 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2539 (smax:SF (match_operand:SF 1 "fr_register_operand" "f")
2540 (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))]
2543 [(set_attr "itanium_class" "fmisc")])
2545 (define_insn "*maddsf4"
2546 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2547 (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2548 (match_operand:SF 2 "fr_register_operand" "f"))
2549 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2551 "fma.s %0 = %1, %2, %F3"
2552 [(set_attr "itanium_class" "fmac")])
2554 (define_insn "*msubsf4"
2555 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2556 (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2557 (match_operand:SF 2 "fr_register_operand" "f"))
2558 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2560 "fms.s %0 = %1, %2, %F3"
2561 [(set_attr "itanium_class" "fmac")])
2563 (define_insn "*nmulsf3"
2564 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2565 (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
2566 (match_operand:SF 2 "fr_register_operand" "f"))))]
2568 "fnmpy.s %0 = %1, %2"
2569 [(set_attr "itanium_class" "fmac")])
2571 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
2573 (define_insn "*nmaddsf4"
2574 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2575 (plus:SF (neg:SF (mult:SF
2576 (match_operand:SF 1 "fr_register_operand" "f")
2577 (match_operand:SF 2 "fr_register_operand" "f")))
2578 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
2580 "fnma.s %0 = %1, %2, %F3"
2581 [(set_attr "itanium_class" "fmac")])
2583 (define_expand "divsf3"
2584 [(set (match_operand:SF 0 "fr_register_operand" "")
2585 (div:SF (match_operand:SF 1 "fr_register_operand" "")
2586 (match_operand:SF 2 "fr_register_operand" "")))]
2587 "TARGET_INLINE_FLOAT_DIV"
2590 if (TARGET_INLINE_FLOAT_DIV_LAT)
2591 insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
2593 insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
2598 (define_insn_and_split "divsf3_internal_lat"
2599 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2600 (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2601 (match_operand:SF 2 "fr_register_operand" "f")))
2602 (clobber (match_scratch:XF 3 "=&f"))
2603 (clobber (match_scratch:XF 4 "=f"))
2604 (clobber (match_scratch:BI 5 "=c"))]
2605 "TARGET_INLINE_FLOAT_DIV_LAT"
2607 "&& reload_completed"
2608 [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2609 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2610 UNSPEC_FR_RECIP_APPROX))
2611 (use (const_int 1))])
2612 (cond_exec (ne (match_dup 5) (const_int 0))
2613 (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
2614 (use (const_int 1))]))
2615 (cond_exec (ne (match_dup 5) (const_int 0))
2616 (parallel [(set (match_dup 4)
2617 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
2619 (use (const_int 1))]))
2620 (cond_exec (ne (match_dup 5) (const_int 0))
2621 (parallel [(set (match_dup 3)
2622 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2624 (use (const_int 1))]))
2625 (cond_exec (ne (match_dup 5) (const_int 0))
2626 (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
2627 (use (const_int 1))]))
2628 (cond_exec (ne (match_dup 5) (const_int 0))
2629 (parallel [(set (match_dup 3)
2630 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2632 (use (const_int 1))]))
2633 (cond_exec (ne (match_dup 5) (const_int 0))
2634 (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
2635 (use (const_int 1))]))
2636 (cond_exec (ne (match_dup 5) (const_int 0))
2637 (parallel [(set (match_dup 9)
2639 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2641 (use (const_int 1))]))
2642 (cond_exec (ne (match_dup 5) (const_int 0))
2644 (float_truncate:SF (match_dup 6))))
2647 operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2648 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2649 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
2650 operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
2651 operands[10] = CONST1_RTX (XFmode);
2653 [(set_attr "predicable" "no")])
2655 (define_insn_and_split "divsf3_internal_thr"
2656 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2657 (div:SF (match_operand:SF 1 "fr_register_operand" "f")
2658 (match_operand:SF 2 "fr_register_operand" "f")))
2659 (clobber (match_scratch:XF 3 "=&f"))
2660 (clobber (match_scratch:XF 4 "=f"))
2661 (clobber (match_scratch:BI 5 "=c"))]
2662 "TARGET_INLINE_FLOAT_DIV_THR"
2664 "&& reload_completed"
2665 [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
2666 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
2667 UNSPEC_FR_RECIP_APPROX))
2668 (use (const_int 1))])
2669 (cond_exec (ne (match_dup 5) (const_int 0))
2670 (parallel [(set (match_dup 3)
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 3) (match_dup 3))
2678 (use (const_int 1))]))
2679 (cond_exec (ne (match_dup 5) (const_int 0))
2680 (parallel [(set (match_dup 6)
2681 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
2683 (use (const_int 1))]))
2684 (cond_exec (ne (match_dup 5) (const_int 0))
2685 (parallel [(set (match_dup 9)
2687 (mult:XF (match_dup 7) (match_dup 6))))
2688 (use (const_int 1))]))
2689 (cond_exec (ne (match_dup 5) (const_int 0))
2690 (parallel [(set (match_dup 4)
2691 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 3)))
2693 (use (const_int 1))]))
2694 (cond_exec (ne (match_dup 5) (const_int 0))
2697 (plus:XF (mult:XF (match_dup 4) (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 (SFmode, REGNO (operands[3]));
2705 operands[10] = CONST1_RTX (XFmode);
2707 [(set_attr "predicable" "no")])
2709 ;; Inline square root.
2711 (define_insn "*sqrt_approx"
2712 [(set (match_operand:XF 0 "fr_register_operand" "=f")
2713 (div:XF (const_int 1)
2714 (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
2715 (set (match_operand:BI 1 "register_operand" "=c")
2716 (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
2717 (use (match_operand:SI 3 "const_int_operand" "")) ]
2719 "frsqrta.s%3 %0, %1 = %2"
2720 [(set_attr "itanium_class" "fmisc")
2721 (set_attr "predicable" "no")])
2723 (define_insn "*setf_exp_xf"
2724 [(set (match_operand:XF 0 "fr_register_operand" "=f")
2725 (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
2729 [(set_attr "itanium_class" "frfr")])
2731 (define_expand "sqrtsf2"
2732 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2733 (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))]
2734 "TARGET_INLINE_SQRT"
2737 if (TARGET_INLINE_SQRT_LAT)
2739 insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
2744 insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
2749 ;; Latency-optimized square root.
2750 ;; FIXME: Implement.
2752 ;; Throughput-optimized square root.
2754 (define_insn_and_split "sqrtsf2_internal_thr"
2755 [(set (match_operand:SF 0 "fr_register_operand" "=&f")
2756 (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))
2757 ;; Register r2 in optimization guide.
2758 (clobber (match_scratch:DI 2 "=r"))
2759 ;; Register f8 in optimization guide
2760 (clobber (match_scratch:XF 3 "=&f"))
2761 ;; Register f9 in optimization guide
2762 (clobber (match_scratch:XF 4 "=&f"))
2763 ;; Register f10 in optimization guide
2764 (clobber (match_scratch:XF 5 "=&f"))
2765 ;; Register p6 in optimization guide.
2766 (clobber (match_scratch:BI 6 "=c"))]
2767 "TARGET_INLINE_SQRT_THR"
2769 "&& reload_completed"
2770 [ ;; exponent of +1/2 in r2
2771 (set (match_dup 2) (const_int 65534))
2774 (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
2776 ;; y0 = 1/sqrt(a) in f7
2777 (parallel [(set (match_dup 7)
2778 (div:XF (const_int 1)
2779 (sqrt:XF (match_dup 8))))
2781 (unspec:BI [(match_dup 8)]
2782 UNSPEC_FR_SQRT_RECIP_APPROX))
2783 (use (const_int 0))])
2785 ;; H0 = 1/2 * y0 in f9
2786 (cond_exec (ne (match_dup 6) (const_int 0))
2787 (parallel [(set (match_dup 4)
2788 (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2790 (use (const_int 1))]))
2792 ;; S0 = a * y0 in f7
2793 (cond_exec (ne (match_dup 6) (const_int 0))
2794 (parallel [(set (match_dup 7)
2795 (plus:XF (mult:XF (match_dup 8) (match_dup 7))
2797 (use (const_int 1))]))
2799 ;; d = 1/2 - S0 * H0 in f10
2800 (cond_exec (ne (match_dup 6) (const_int 0))
2801 (parallel [(set (match_dup 5)
2802 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 4)))
2804 (use (const_int 1))]))
2806 ;; d' = d + 1/2 * d in f8
2807 (cond_exec (ne (match_dup 6) (const_int 0))
2808 (parallel [(set (match_dup 3)
2809 (plus:XF (mult:XF (match_dup 3) (match_dup 5))
2811 (use (const_int 1))]))
2813 ;; e = d + d * d' in f8
2814 (cond_exec (ne (match_dup 6) (const_int 0))
2815 (parallel [(set (match_dup 3)
2816 (plus:XF (mult:XF (match_dup 5) (match_dup 3))
2818 (use (const_int 1))]))
2820 ;; S1 = S0 + e * S0 in f7
2821 (cond_exec (ne (match_dup 6) (const_int 0))
2822 (parallel [(set (match_dup 0)
2824 (plus:XF (mult:XF (match_dup 3) (match_dup 7))
2826 (use (const_int 1))]))
2828 ;; H1 = H0 + e * H0 in f8
2829 (cond_exec (ne (match_dup 6) (const_int 0))
2830 (parallel [(set (match_dup 3)
2831 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
2833 (use (const_int 1))]))
2835 ;; d1 = a - S1 * S1 in f9
2836 (cond_exec (ne (match_dup 6) (const_int 0))
2837 (parallel [(set (match_dup 4)
2838 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
2840 (use (const_int 1))]))
2842 ;; S = S1 + d1 * H1 in f7
2843 (cond_exec (ne (match_dup 6) (const_int 0))
2844 (parallel [(set (match_dup 0)
2846 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
2848 (use (const_int 0))]))]
2850 /* Generate 82-bit versions of the input and output operands. */
2851 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
2852 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
2853 /* Generate required floating-point constants. */
2854 operands[9] = CONST0_RTX (XFmode);
2856 [(set_attr "predicable" "no")])
2858 ;; ::::::::::::::::::::
2860 ;; :: 64 bit floating point arithmetic
2862 ;; ::::::::::::::::::::
2864 (define_insn "adddf3"
2865 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2866 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2867 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2869 "fadd.d %0 = %1, %F2"
2870 [(set_attr "itanium_class" "fmac")])
2872 (define_insn "*adddf3_trunc"
2873 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2875 (plus:DF (match_operand:DF 1 "fr_register_operand" "%f")
2876 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2878 "fadd.s %0 = %1, %F2"
2879 [(set_attr "itanium_class" "fmac")])
2881 (define_insn "subdf3"
2882 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2883 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2884 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2886 "fsub.d %0 = %F1, %F2"
2887 [(set_attr "itanium_class" "fmac")])
2889 (define_insn "*subdf3_trunc"
2890 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2892 (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
2893 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
2895 "fsub.s %0 = %F1, %F2"
2896 [(set_attr "itanium_class" "fmac")])
2898 (define_insn "muldf3"
2899 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2900 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2901 (match_operand:DF 2 "fr_register_operand" "f")))]
2903 "fmpy.d %0 = %1, %2"
2904 [(set_attr "itanium_class" "fmac")])
2906 (define_insn "*muldf3_trunc"
2907 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2909 (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2910 (match_operand:DF 2 "fr_register_operand" "f"))))]
2912 "fmpy.s %0 = %1, %2"
2913 [(set_attr "itanium_class" "fmac")])
2915 (define_insn "absdf2"
2916 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2917 (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2920 [(set_attr "itanium_class" "fmisc")])
2922 (define_insn "negdf2"
2923 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2924 (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))]
2927 [(set_attr "itanium_class" "fmisc")])
2929 (define_insn "*nabsdf2"
2930 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2931 (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))]
2934 [(set_attr "itanium_class" "fmisc")])
2936 (define_insn "mindf3"
2937 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2938 (smin:DF (match_operand:DF 1 "fr_register_operand" "f")
2939 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2942 [(set_attr "itanium_class" "fmisc")])
2944 (define_insn "maxdf3"
2945 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2946 (smax:DF (match_operand:DF 1 "fr_register_operand" "f")
2947 (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))]
2950 [(set_attr "itanium_class" "fmisc")])
2952 (define_insn "*madddf4"
2953 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2954 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2955 (match_operand:DF 2 "fr_register_operand" "f"))
2956 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2958 "fma.d %0 = %1, %2, %F3"
2959 [(set_attr "itanium_class" "fmac")])
2961 (define_insn "*madddf4_trunc"
2962 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2964 (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2965 (match_operand:DF 2 "fr_register_operand" "f"))
2966 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
2968 "fma.s %0 = %1, %2, %F3"
2969 [(set_attr "itanium_class" "fmac")])
2971 (define_insn "*msubdf4"
2972 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2973 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2974 (match_operand:DF 2 "fr_register_operand" "f"))
2975 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
2977 "fms.d %0 = %1, %2, %F3"
2978 [(set_attr "itanium_class" "fmac")])
2980 (define_insn "*msubdf4_trunc"
2981 [(set (match_operand:SF 0 "fr_register_operand" "=f")
2983 (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2984 (match_operand:DF 2 "fr_register_operand" "f"))
2985 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
2987 "fms.s %0 = %1, %2, %F3"
2988 [(set_attr "itanium_class" "fmac")])
2990 (define_insn "*nmuldf3"
2991 [(set (match_operand:DF 0 "fr_register_operand" "=f")
2992 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
2993 (match_operand:DF 2 "fr_register_operand" "f"))))]
2995 "fnmpy.d %0 = %1, %2"
2996 [(set_attr "itanium_class" "fmac")])
2998 (define_insn "*nmuldf3_trunc"
2999 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3001 (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
3002 (match_operand:DF 2 "fr_register_operand" "f")))))]
3004 "fnmpy.s %0 = %1, %2"
3005 [(set_attr "itanium_class" "fmac")])
3007 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3009 (define_insn "*nmadddf4"
3010 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3011 (plus:DF (neg:DF (mult:DF
3012 (match_operand:DF 1 "fr_register_operand" "f")
3013 (match_operand:DF 2 "fr_register_operand" "f")))
3014 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
3016 "fnma.d %0 = %1, %2, %F3"
3017 [(set_attr "itanium_class" "fmac")])
3019 (define_insn "*nmadddf4_alts"
3020 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3021 (plus:DF (neg:DF (mult:DF
3022 (match_operand:DF 1 "fr_register_operand" "f")
3023 (match_operand:DF 2 "fr_register_operand" "f")))
3024 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))
3025 (use (match_operand:SI 4 "const_int_operand" ""))]
3027 "fnma.d.s%4 %0 = %1, %2, %F3"
3028 [(set_attr "itanium_class" "fmac")])
3030 (define_insn "*nmadddf4_trunc"
3031 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3033 (plus:DF (neg:DF (mult:DF
3034 (match_operand:DF 1 "fr_register_operand" "f")
3035 (match_operand:DF 2 "fr_register_operand" "f")))
3036 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
3038 "fnma.s %0 = %1, %2, %F3"
3039 [(set_attr "itanium_class" "fmac")])
3041 (define_expand "divdf3"
3042 [(set (match_operand:DF 0 "fr_register_operand" "")
3043 (div:DF (match_operand:DF 1 "fr_register_operand" "")
3044 (match_operand:DF 2 "fr_register_operand" "")))]
3045 "TARGET_INLINE_FLOAT_DIV"
3048 if (TARGET_INLINE_FLOAT_DIV_LAT)
3049 insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
3051 insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
3056 (define_insn_and_split "divdf3_internal_lat"
3057 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3058 (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3059 (match_operand:DF 2 "fr_register_operand" "f")))
3060 (clobber (match_scratch:XF 3 "=&f"))
3061 (clobber (match_scratch:XF 4 "=&f"))
3062 (clobber (match_scratch:XF 5 "=&f"))
3063 (clobber (match_scratch:BI 6 "=c"))]
3064 "TARGET_INLINE_FLOAT_DIV_LAT"
3066 "&& reload_completed"
3067 [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
3068 (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
3069 UNSPEC_FR_RECIP_APPROX))
3070 (use (const_int 1))])
3071 (cond_exec (ne (match_dup 6) (const_int 0))
3072 (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
3073 (use (const_int 1))]))
3074 (cond_exec (ne (match_dup 6) (const_int 0))
3075 (parallel [(set (match_dup 4)
3076 (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 7)))
3078 (use (const_int 1))]))
3079 (cond_exec (ne (match_dup 6) (const_int 0))
3080 (parallel [(set (match_dup 3)
3081 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3083 (use (const_int 1))]))
3084 (cond_exec (ne (match_dup 6) (const_int 0))
3085 (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
3086 (use (const_int 1))]))
3087 (cond_exec (ne (match_dup 6) (const_int 0))
3088 (parallel [(set (match_dup 7)
3089 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3091 (use (const_int 1))]))
3092 (cond_exec (ne (match_dup 6) (const_int 0))
3093 (parallel [(set (match_dup 3)
3094 (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3096 (use (const_int 1))]))
3097 (cond_exec (ne (match_dup 6) (const_int 0))
3098 (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
3099 (use (const_int 1))]))
3100 (cond_exec (ne (match_dup 6) (const_int 0))
3101 (parallel [(set (match_dup 7)
3102 (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3104 (use (const_int 1))]))
3105 (cond_exec (ne (match_dup 6) (const_int 0))
3106 (parallel [(set (match_dup 10)
3108 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3110 (use (const_int 1))]))
3111 (cond_exec (ne (match_dup 6) (const_int 0))
3112 (parallel [(set (match_dup 7)
3113 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3115 (use (const_int 1))]))
3116 (cond_exec (ne (match_dup 6) (const_int 0))
3117 (parallel [(set (match_dup 11)
3119 (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 3)))
3121 (use (const_int 1))]))
3122 (cond_exec (ne (match_dup 6) (const_int 0))
3124 (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3128 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3129 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3130 operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3131 operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3132 operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
3133 operands[12] = CONST1_RTX (XFmode);
3135 [(set_attr "predicable" "no")])
3137 (define_insn_and_split "divdf3_internal_thr"
3138 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3139 (div:DF (match_operand:DF 1 "fr_register_operand" "f")
3140 (match_operand:DF 2 "fr_register_operand" "f")))
3141 (clobber (match_scratch:XF 3 "=&f"))
3142 (clobber (match_scratch:DF 4 "=f"))
3143 (clobber (match_scratch:BI 5 "=c"))]
3144 "TARGET_INLINE_FLOAT_DIV_THR"
3146 "&& reload_completed"
3147 [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
3148 (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
3149 UNSPEC_FR_RECIP_APPROX))
3150 (use (const_int 1))])
3151 (cond_exec (ne (match_dup 5) (const_int 0))
3152 (parallel [(set (match_dup 3)
3153 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
3155 (use (const_int 1))]))
3156 (cond_exec (ne (match_dup 5) (const_int 0))
3157 (parallel [(set (match_dup 6)
3158 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3160 (use (const_int 1))]))
3161 (cond_exec (ne (match_dup 5) (const_int 0))
3162 (parallel [(set (match_dup 3)
3163 (mult:XF (match_dup 3) (match_dup 3)))
3164 (use (const_int 1))]))
3165 (cond_exec (ne (match_dup 5) (const_int 0))
3166 (parallel [(set (match_dup 6)
3167 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3169 (use (const_int 1))]))
3170 (cond_exec (ne (match_dup 5) (const_int 0))
3171 (parallel [(set (match_dup 3)
3172 (mult:XF (match_dup 3) (match_dup 3)))
3173 (use (const_int 1))]))
3174 (cond_exec (ne (match_dup 5) (const_int 0))
3175 (parallel [(set (match_dup 6)
3176 (plus:XF (mult:XF (match_dup 3) (match_dup 6))
3178 (use (const_int 1))]))
3179 (cond_exec (ne (match_dup 5) (const_int 0))
3180 (parallel [(set (match_dup 9)
3182 (mult:XF (match_dup 7) (match_dup 3))))
3183 (use (const_int 1))]))
3184 (cond_exec (ne (match_dup 5) (const_int 0))
3185 (parallel [(set (match_dup 4)
3186 (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9)))
3188 (use (const_int 1))]))
3189 (cond_exec (ne (match_dup 5) (const_int 0))
3191 (plus:DF (mult:DF (match_dup 4) (match_dup 0))
3195 operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3196 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3197 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
3198 operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
3199 operands[10] = CONST1_RTX (XFmode);
3201 [(set_attr "predicable" "no")])
3203 ;; Inline square root.
3205 (define_expand "sqrtdf2"
3206 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3207 (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
3208 "TARGET_INLINE_SQRT"
3211 if (TARGET_INLINE_SQRT_LAT)
3213 insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
3218 insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
3223 ;; Latency-optimized square root.
3224 ;; FIXME: Implement.
3226 ;; Throughput-optimized square root.
3228 (define_insn_and_split "sqrtdf2_internal_thr"
3229 [(set (match_operand:DF 0 "fr_register_operand" "=&f")
3230 (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))
3231 ;; Register r2 in optimization guide.
3232 (clobber (match_scratch:DI 2 "=r"))
3233 ;; Register f8 in optimization guide
3234 (clobber (match_scratch:XF 3 "=&f"))
3235 ;; Register f9 in optimization guide
3236 (clobber (match_scratch:XF 4 "=&f"))
3237 ;; Register f10 in optimization guide
3238 (clobber (match_scratch:XF 5 "=&f"))
3239 ;; Register p6 in optimization guide.
3240 (clobber (match_scratch:BI 6 "=c"))]
3241 "TARGET_INLINE_SQRT_THR"
3243 "&& reload_completed"
3244 [ ;; exponent of +1/2 in r2
3245 (set (match_dup 2) (const_int 65534))
3248 (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3250 ;; y0 = 1/sqrt(a) in f7
3251 (parallel [(set (match_dup 7)
3252 (div:XF (const_int 1)
3253 (sqrt:XF (match_dup 8))))
3255 (unspec:BI [(match_dup 8)]
3256 UNSPEC_FR_SQRT_RECIP_APPROX))
3257 (use (const_int 0))])
3259 ;; H0 = 1/2 * y0 in f8
3260 (cond_exec (ne (match_dup 6) (const_int 0))
3261 (parallel [(set (match_dup 3)
3262 (plus:XF (mult:XF (match_dup 5) (match_dup 7))
3264 (use (const_int 1))]))
3266 ;; G0 = a * y0 in f7
3267 (cond_exec (ne (match_dup 6) (const_int 0))
3268 (parallel [(set (match_dup 7)
3269 (plus:XF (mult:XF (match_dup 8) (match_dup 7))
3271 (use (const_int 1))]))
3273 ;; r0 = 1/2 - G0 * H0 in f9
3274 (cond_exec (ne (match_dup 6) (const_int 0))
3275 (parallel [(set (match_dup 4)
3276 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
3278 (use (const_int 1))]))
3280 ;; H1 = H0 + r0 * H0 in f8
3281 (cond_exec (ne (match_dup 6) (const_int 0))
3282 (parallel [(set (match_dup 3)
3283 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3285 (use (const_int 1))]))
3287 ;; G1 = G0 + r0 * G0 in f7
3288 (cond_exec (ne (match_dup 6) (const_int 0))
3289 (parallel [(set (match_dup 7)
3290 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3292 (use (const_int 1))]))
3294 ;; r1 = 1/2 - G1 * H1 in f9
3295 (cond_exec (ne (match_dup 6) (const_int 0))
3296 (parallel [(set (match_dup 4)
3297 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
3299 (use (const_int 1))]))
3301 ;; H2 = H1 + r1 * H1 in f8
3302 (cond_exec (ne (match_dup 6) (const_int 0))
3303 (parallel [(set (match_dup 3)
3304 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3306 (use (const_int 1))]))
3308 ;; G2 = G1 + r1 * G1 in f7
3309 (cond_exec (ne (match_dup 6) (const_int 0))
3310 (parallel [(set (match_dup 7)
3311 (plus:XF (mult:XF (match_dup 4) (match_dup 7))
3313 (use (const_int 1))]))
3315 ;; d2 = a - G2 * G2 in f9
3316 (cond_exec (ne (match_dup 6) (const_int 0))
3317 (parallel [(set (match_dup 4)
3318 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
3320 (use (const_int 1))]))
3322 ;; G3 = G2 + d2 * H2 in f7
3323 (cond_exec (ne (match_dup 6) (const_int 0))
3324 (parallel [(set (match_dup 7)
3325 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3327 (use (const_int 1))]))
3329 ;; d3 = a - G3 * G3 in f9
3330 (cond_exec (ne (match_dup 6) (const_int 0))
3331 (parallel [(set (match_dup 4)
3332 (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
3334 (use (const_int 1))]))
3336 ;; S = G3 + d3 * H2 in f7
3337 (cond_exec (ne (match_dup 6) (const_int 0))
3338 (parallel [(set (match_dup 0)
3340 (plus:XF (mult:XF (match_dup 4) (match_dup 3))
3342 (use (const_int 0))]))]
3344 /* Generate 82-bit versions of the input and output operands. */
3345 operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
3346 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
3347 /* Generate required floating-point constants. */
3348 operands[9] = CONST0_RTX (XFmode);
3350 [(set_attr "predicable" "no")])
3352 ;; ::::::::::::::::::::
3354 ;; :: 80 bit floating point arithmetic
3356 ;; ::::::::::::::::::::
3358 (define_insn "addxf3"
3359 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3360 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3361 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3363 "fadd %0 = %F1, %F2"
3364 [(set_attr "itanium_class" "fmac")])
3366 (define_insn "*addxf3_truncsf"
3367 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3369 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3370 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3372 "fadd.s %0 = %F1, %F2"
3373 [(set_attr "itanium_class" "fmac")])
3375 (define_insn "*addxf3_truncdf"
3376 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3378 (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3379 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3381 "fadd.d %0 = %F1, %F2"
3382 [(set_attr "itanium_class" "fmac")])
3384 (define_insn "subxf3"
3385 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3386 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3387 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3389 "fsub %0 = %F1, %F2"
3390 [(set_attr "itanium_class" "fmac")])
3392 (define_insn "*subxf3_truncsf"
3393 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3395 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3396 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3398 "fsub.s %0 = %F1, %F2"
3399 [(set_attr "itanium_class" "fmac")])
3401 (define_insn "*subxf3_truncdf"
3402 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3404 (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3405 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3407 "fsub.d %0 = %F1, %F2"
3408 [(set_attr "itanium_class" "fmac")])
3410 (define_insn "mulxf3"
3411 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3412 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3413 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3415 "fmpy %0 = %F1, %F2"
3416 [(set_attr "itanium_class" "fmac")])
3418 (define_insn "*mulxf3_truncsf"
3419 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3421 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3422 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3424 "fmpy.s %0 = %F1, %F2"
3425 [(set_attr "itanium_class" "fmac")])
3427 (define_insn "*mulxf3_truncdf"
3428 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3430 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3431 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3433 "fmpy.d %0 = %F1, %F2"
3434 [(set_attr "itanium_class" "fmac")])
3436 (define_insn "*mulxf3_alts"
3437 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3438 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3439 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3440 (use (match_operand:SI 3 "const_int_operand" ""))]
3442 "fmpy.s%3 %0 = %F1, %F2"
3443 [(set_attr "itanium_class" "fmac")])
3445 (define_insn "*mulxf3_truncsf_alts"
3446 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3448 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3449 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3450 (use (match_operand:SI 3 "const_int_operand" ""))]
3452 "fmpy.s.s%3 %0 = %F1, %F2"
3453 [(set_attr "itanium_class" "fmac")])
3455 (define_insn "*mulxf3_truncdf_alts"
3456 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3458 (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3459 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
3460 (use (match_operand:SI 3 "const_int_operand" ""))]
3462 "fmpy.d.s%3 %0 = %F1, %F2"
3463 [(set_attr "itanium_class" "fmac")])
3465 (define_insn "absxf2"
3466 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3467 (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3470 [(set_attr "itanium_class" "fmisc")])
3472 (define_insn "negxf2"
3473 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3474 (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
3477 [(set_attr "itanium_class" "fmisc")])
3479 (define_insn "*nabsxf2"
3480 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3481 (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
3484 [(set_attr "itanium_class" "fmisc")])
3486 (define_insn "minxf3"
3487 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3488 (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3489 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3491 "fmin %0 = %F1, %F2"
3492 [(set_attr "itanium_class" "fmisc")])
3494 (define_insn "maxxf3"
3495 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3496 (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3497 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
3499 "fmax %0 = %F1, %F2"
3500 [(set_attr "itanium_class" "fmisc")])
3502 (define_insn "*maddxf4"
3503 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3504 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3505 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3506 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3508 "fma %0 = %F1, %F2, %F3"
3509 [(set_attr "itanium_class" "fmac")])
3511 (define_insn "*maddxf4_truncsf"
3512 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3514 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3515 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3516 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3518 "fma.s %0 = %F1, %F2, %F3"
3519 [(set_attr "itanium_class" "fmac")])
3521 (define_insn "*maddxf4_truncdf"
3522 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3524 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3525 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3526 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3528 "fma.d %0 = %F1, %F2, %F3"
3529 [(set_attr "itanium_class" "fmac")])
3531 (define_insn "*maddxf4_alts"
3532 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3533 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3534 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3535 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
3536 (use (match_operand:SI 4 "const_int_operand" ""))]
3538 "fma.s%4 %0 = %F1, %F2, %F3"
3539 [(set_attr "itanium_class" "fmac")])
3541 (define_insn "*maddxf4_alts_truncsf"
3542 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3544 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3545 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3546 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3547 (use (match_operand:SI 4 "const_int_operand" ""))]
3549 "fma.s.s%4 %0 = %F1, %F2, %F3"
3550 [(set_attr "itanium_class" "fmac")])
3552 (define_insn "*maddxf4_alts_truncdf"
3553 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3555 (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3556 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3557 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3558 (use (match_operand:SI 4 "const_int_operand" ""))]
3560 "fma.d.s%4 %0 = %F1, %F2, %F3"
3561 [(set_attr "itanium_class" "fmac")])
3563 (define_insn "*msubxf4"
3564 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3565 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3566 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3567 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3569 "fms %0 = %F1, %F2, %F3"
3570 [(set_attr "itanium_class" "fmac")])
3572 (define_insn "*msubxf4_truncsf"
3573 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3575 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3576 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3577 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3579 "fms.s %0 = %F1, %F2, %F3"
3580 [(set_attr "itanium_class" "fmac")])
3582 (define_insn "*msubxf4_truncdf"
3583 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3585 (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3586 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
3587 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3589 "fms.d %0 = %F1, %F2, %F3"
3590 [(set_attr "itanium_class" "fmac")])
3592 (define_insn "*nmulxf3"
3593 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3594 (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3595 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
3597 "fnmpy %0 = %F1, %F2"
3598 [(set_attr "itanium_class" "fmac")])
3600 (define_insn "*nmulxf3_truncsf"
3601 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3604 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3605 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3607 "fnmpy.s %0 = %F1, %F2"
3608 [(set_attr "itanium_class" "fmac")])
3610 (define_insn "*nmulxf3_truncdf"
3611 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3614 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3615 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
3617 "fnmpy.d %0 = %F1, %F2"
3618 [(set_attr "itanium_class" "fmac")])
3620 ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
3622 (define_insn "*nmaddxf4"
3623 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3624 (plus:XF (neg:XF (mult:XF
3625 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3626 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3627 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
3629 "fnma %0 = %F1, %F2, %F3"
3630 [(set_attr "itanium_class" "fmac")])
3632 (define_insn "*nmaddxf4_truncsf"
3633 [(set (match_operand:SF 0 "fr_register_operand" "=f")
3635 (plus:XF (neg:XF (mult:XF
3636 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3637 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3638 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3640 "fnma.s %0 = %F1, %F2, %F3"
3641 [(set_attr "itanium_class" "fmac")])
3643 (define_insn "*nmaddxf4_truncdf"
3644 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3646 (plus:XF (neg:XF (mult:XF
3647 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3648 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3649 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
3651 "fnma.d %0 = %F1, %F2, %F3"
3652 [(set_attr "itanium_class" "fmac")])
3654 (define_insn "*nmaddxf4_alts"
3655 [(set (match_operand:XF 0 "fr_register_operand" "=f")
3656 (plus:XF (neg:XF (mult:XF
3657 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3658 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3659 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
3660 (use (match_operand:SI 4 "const_int_operand" ""))]
3662 "fnma.s%4 %0 = %F1, %F2, %F3"
3663 [(set_attr "itanium_class" "fmac")])
3665 (define_insn "*nmaddxf4_truncdf_alts"
3666 [(set (match_operand:DF 0 "fr_register_operand" "=f")
3670 (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
3671 (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
3672 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
3673 (use (match_operand:SI 4 "const_int_operand" ""))]
3675 "fnma.d.s%4 %0 = %F1, %F2, %F3"
3676 [(set_attr "itanium_class" "fmac")])
3678 (define_expand "divxf3"
3679 [(set (match_operand:XF 0 "fr_register_operand" "")
3680 (div:XF (match_operand:XF 1 "fr_register_operand" "")
3681 (match_operand:XF 2 "fr_register_operand" "")))]
3682 "TARGET_INLINE_FLOAT_DIV"
3685 if (TARGET_INLINE_FLOAT_DIV_LAT)
3686 insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
3688 insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
3693 (define_insn_and_split "divxf3_internal_lat"
3694 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3695 (div:XF (match_operand:XF 1 "fr_register_operand" "f")
3696 (match_operand:XF 2 "fr_register_operand" "f")))
3697 (clobber (match_scratch:XF 3 "=&f"))
3698 (clobber (match_scratch:XF 4 "=&f"))
3699 (clobber (match_scratch:XF 5 "=&f"))
3700 (clobber (match_scratch:XF 6 "=&f"))
3701 (clobber (match_scratch:BI 7 "=c"))]
3702 "TARGET_INLINE_FLOAT_DIV_LAT"
3704 "&& reload_completed"
3705 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
3706 (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
3707 UNSPEC_FR_RECIP_APPROX))
3708 (use (const_int 1))])
3709 (cond_exec (ne (match_dup 7) (const_int 0))
3710 (parallel [(set (match_dup 3)
3711 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3713 (use (const_int 1))]))
3714 (cond_exec (ne (match_dup 7) (const_int 0))
3715 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
3716 (use (const_int 1))]))
3717 (cond_exec (ne (match_dup 7) (const_int 0))
3718 (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
3719 (use (const_int 1))]))
3720 (cond_exec (ne (match_dup 7) (const_int 0))
3721 (parallel [(set (match_dup 6)
3722 (plus:XF (mult:XF (match_dup 3) (match_dup 3))
3724 (use (const_int 1))]))
3725 (cond_exec (ne (match_dup 7) (const_int 0))
3726 (parallel [(set (match_dup 3)
3727 (plus:XF (mult:XF (match_dup 5) (match_dup 5))
3729 (use (const_int 1))]))
3730 (cond_exec (ne (match_dup 7) (const_int 0))
3731 (parallel [(set (match_dup 5)
3732 (plus:XF (mult:XF (match_dup 6) (match_dup 0))
3734 (use (const_int 1))]))
3735 (cond_exec (ne (match_dup 7) (const_int 0))
3736 (parallel [(set (match_dup 0)
3737 (plus:XF (mult:XF (match_dup 5) (match_dup 3))
3739 (use (const_int 1))]))
3740 (cond_exec (ne (match_dup 7) (const_int 0))
3741 (parallel [(set (match_dup 4)
3742 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
3744 (use (const_int 1))]))
3745 (cond_exec (ne (match_dup 7) (const_int 0))
3746 (parallel [(set (match_dup 3)
3747 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
3749 (use (const_int 1))]))
3750 (cond_exec (ne (match_dup 7) (const_int 0))
3751 (parallel [(set (match_dup 5)
3752 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3754 (use (const_int 1))]))
3755 (cond_exec (ne (match_dup 7) (const_int 0))
3756 (parallel [(set (match_dup 0)
3757 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3759 (use (const_int 1))]))
3760 (cond_exec (ne (match_dup 7) (const_int 0))
3761 (parallel [(set (match_dup 4)
3762 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
3764 (use (const_int 1))]))
3765 (cond_exec (ne (match_dup 7) (const_int 0))
3767 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3770 "operands[8] = CONST1_RTX (XFmode);"
3771 [(set_attr "predicable" "no")])
3773 (define_insn_and_split "divxf3_internal_thr"
3774 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3775 (div:XF (match_operand:XF 1 "fr_register_operand" "f")
3776 (match_operand:XF 2 "fr_register_operand" "f")))
3777 (clobber (match_scratch:XF 3 "=&f"))
3778 (clobber (match_scratch:XF 4 "=&f"))
3779 (clobber (match_scratch:BI 5 "=c"))]
3780 "TARGET_INLINE_FLOAT_DIV_THR"
3782 "&& reload_completed"
3783 [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
3784 (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
3785 UNSPEC_FR_RECIP_APPROX))
3786 (use (const_int 1))])
3787 (cond_exec (ne (match_dup 5) (const_int 0))
3788 (parallel [(set (match_dup 3)
3789 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3791 (use (const_int 1))]))
3792 (cond_exec (ne (match_dup 5) (const_int 0))
3793 (parallel [(set (match_dup 4)
3794 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
3796 (use (const_int 1))]))
3797 (cond_exec (ne (match_dup 5) (const_int 0))
3798 (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
3799 (use (const_int 1))]))
3800 (cond_exec (ne (match_dup 5) (const_int 0))
3801 (parallel [(set (match_dup 3)
3802 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
3804 (use (const_int 1))]))
3805 (cond_exec (ne (match_dup 5) (const_int 0))
3806 (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
3807 (use (const_int 1))]))
3808 (cond_exec (ne (match_dup 5) (const_int 0))
3809 (parallel [(set (match_dup 0)
3810 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
3812 (use (const_int 1))]))
3813 (cond_exec (ne (match_dup 5) (const_int 0))
3814 (parallel [(set (match_dup 0)
3815 (plus:XF (mult:XF (match_dup 0) (match_dup 3))
3817 (use (const_int 1))]))
3818 (cond_exec (ne (match_dup 5) (const_int 0))
3819 (parallel [(set (match_dup 3)
3820 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
3822 (use (const_int 1))]))
3823 (cond_exec (ne (match_dup 5) (const_int 0))
3824 (parallel [(set (match_dup 3)
3825 (plus:XF (mult:XF (match_dup 3) (match_dup 0))
3827 (use (const_int 1))]))
3828 (cond_exec (ne (match_dup 5) (const_int 0))
3829 (parallel [(set (match_dup 4)
3830 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
3832 (use (const_int 1))]))
3833 (cond_exec (ne (match_dup 5) (const_int 0))
3834 (parallel [(set (match_dup 0)
3835 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3837 (use (const_int 1))]))
3838 (cond_exec (ne (match_dup 5) (const_int 0))
3839 (parallel [(set (match_dup 4)
3840 (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
3842 (use (const_int 1))]))
3843 (cond_exec (ne (match_dup 5) (const_int 0))
3845 (plus:XF (mult:XF (match_dup 4) (match_dup 0))
3848 "operands[6] = CONST1_RTX (XFmode);"
3849 [(set_attr "predicable" "no")])
3851 ;; Inline square root.
3853 (define_expand "sqrtxf2"
3854 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3855 (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))]
3856 "TARGET_INLINE_SQRT"
3859 if (TARGET_INLINE_SQRT_LAT)
3861 insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
3866 insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]);
3871 ;; Latency-optimized square root.
3872 ;; FIXME: Implement.
3874 ;; Throughput-optimized square root.
3876 (define_insn_and_split "sqrtxf2_internal_thr"
3877 [(set (match_operand:XF 0 "fr_register_operand" "=&f")
3878 (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))
3879 ;; Register r2 in optimization guide.
3880 (clobber (match_scratch:DI 2 "=r"))
3881 ;; Register f8 in optimization guide
3882 (clobber (match_scratch:XF 3 "=&f"))
3883 ;; Register f9 in optimization guide
3884 (clobber (match_scratch:XF 4 "=&f"))
3885 ;; Register f10 in optimization guide
3886 (clobber (match_scratch:XF 5 "=&f"))
3887 ;; Register f11 in optimization guide
3888 (clobber (match_scratch:XF 6 "=&f"))
3889 ;; Register p6 in optimization guide.
3890 (clobber (match_scratch:BI 7 "=c"))]
3891 "TARGET_INLINE_SQRT_THR"
3893 "&& reload_completed"
3894 [ ;; exponent of +1/2 in r2
3895 (set (match_dup 2) (const_int 65534))
3896 ;; +1/2 in f8. The Intel manual mistakenly specifies f10.
3898 (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
3900 ;; y0 = 1/sqrt(a) in f7
3901 (parallel [(set (match_dup 8)
3902 (div:XF (const_int 1)
3903 (sqrt:XF (match_dup 9))))
3905 (unspec:BI [(match_dup 9)]
3906 UNSPEC_FR_SQRT_RECIP_APPROX))
3907 (use (const_int 0))])
3909 ;; H0 = 1/2 * y0 in f9
3910 (cond_exec (ne (match_dup 7) (const_int 0))
3911 (parallel [(set (match_dup 4)
3912 (plus:XF (mult:XF (match_dup 3) (match_dup 8))
3914 (use (const_int 1))]))
3916 ;; S0 = a * y0 in f7
3917 (cond_exec (ne (match_dup 7) (const_int 0))
3918 (parallel [(set (match_dup 8)
3919 (plus:XF (mult:XF (match_dup 9) (match_dup 8))
3921 (use (const_int 1))]))
3923 ;; d0 = 1/2 - S0 * H0 in f10
3924 (cond_exec (ne (match_dup 7) (const_int 0))
3925 (parallel [(set (match_dup 5)
3926 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
3928 (use (const_int 1))]))
3930 ;; H1 = H0 + d0 * H0 in f9
3931 (cond_exec (ne (match_dup 7) (const_int 0))
3932 (parallel [(set (match_dup 4)
3933 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
3935 (use (const_int 1))]))
3937 ;; S1 = S0 + d0 * S0 in f7
3938 (cond_exec (ne (match_dup 7) (const_int 0))
3939 (parallel [(set (match_dup 8)
3940 (plus:XF (mult:XF (match_dup 5) (match_dup 8))
3942 (use (const_int 1))]))
3944 ;; d1 = 1/2 - S1 * H1 in f10
3945 (cond_exec (ne (match_dup 7) (const_int 0))
3946 (parallel [(set (match_dup 5)
3947 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
3949 (use (const_int 1))]))
3951 ;; H2 = H1 + d1 * H1 in f9
3952 (cond_exec (ne (match_dup 7) (const_int 0))
3953 (parallel [(set (match_dup 4)
3954 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
3956 (use (const_int 1))]))
3958 ;; S2 = S1 + d1 * S1 in f7
3959 (cond_exec (ne (match_dup 7) (const_int 0))
3960 (parallel [(set (match_dup 8)
3961 (plus:XF (mult:XF (match_dup 5) (match_dup 8))
3963 (use (const_int 1))]))
3965 ;; d2 = 1/2 - S2 * H2 in f10
3966 (cond_exec (ne (match_dup 7) (const_int 0))
3967 (parallel [(set (match_dup 5)
3968 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
3970 (use (const_int 1))]))
3972 ;; e2 = a - S2 * S2 in f8
3973 (cond_exec (ne (match_dup 7) (const_int 0))
3974 (parallel [(set (match_dup 3)
3975 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
3977 (use (const_int 1))]))
3979 ;; S3 = S2 + e2 * H2 in f7
3980 (cond_exec (ne (match_dup 7) (const_int 0))
3981 (parallel [(set (match_dup 8)
3982 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
3984 (use (const_int 1))]))
3986 ;; H3 = H2 + d2 * H2 in f9
3987 (cond_exec (ne (match_dup 7) (const_int 0))
3988 (parallel [(set (match_dup 4)
3989 (plus:XF (mult:XF (match_dup 5) (match_dup 4))
3991 (use (const_int 1))]))
3993 ;; e3 = a - S3 * S3 in f8
3994 (cond_exec (ne (match_dup 7) (const_int 0))
3995 (parallel [(set (match_dup 3)
3996 (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
3998 (use (const_int 1))]))
4000 ;; S = S3 + e3 * H3 in f7
4001 (cond_exec (ne (match_dup 7) (const_int 0))
4002 (parallel [(set (match_dup 0)
4003 (plus:XF (mult:XF (match_dup 3) (match_dup 4))
4005 (use (const_int 0))]))]
4007 /* Generate 82-bit versions of the input and output operands. */
4008 operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0]));
4009 operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1]));
4010 /* Generate required floating-point constants. */
4011 operands[10] = CONST0_RTX (XFmode);
4013 [(set_attr "predicable" "no")])
4015 ;; ??? frcpa works like cmp.foo.unc.
4017 (define_insn "*recip_approx"
4018 [(set (match_operand:XF 0 "fr_register_operand" "=f")
4019 (div:XF (const_int 1)
4020 (match_operand:XF 3 "fr_register_operand" "f")))
4021 (set (match_operand:BI 1 "register_operand" "=c")
4022 (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f")
4023 (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
4024 (use (match_operand:SI 4 "const_int_operand" ""))]
4026 "frcpa.s%4 %0, %1 = %2, %3"
4027 [(set_attr "itanium_class" "fmisc")
4028 (set_attr "predicable" "no")])
4030 ;; ::::::::::::::::::::
4032 ;; :: 32 bit Integer Shifts and Rotates
4034 ;; ::::::::::::::::::::
4036 (define_expand "ashlsi3"
4037 [(set (match_operand:SI 0 "gr_register_operand" "")
4038 (ashift:SI (match_operand:SI 1 "gr_register_operand" "")
4039 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4042 if (GET_CODE (operands[2]) != CONST_INT)
4044 /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now
4045 we've got to get rid of stray bits outside the SImode register. */
4046 rtx subshift = gen_reg_rtx (DImode);
4047 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4048 operands[2] = subshift;
4052 (define_insn "*ashlsi3_internal"
4053 [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r")
4054 (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r")
4055 (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))]
4058 shladd %0 = %1, %2, r0
4059 dep.z %0 = %1, %2, %E2
4061 [(set_attr "itanium_class" "ialu,ishf,mmshf")])
4063 (define_expand "ashrsi3"
4064 [(set (match_operand:SI 0 "gr_register_operand" "")
4065 (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
4066 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4069 rtx subtarget = gen_reg_rtx (DImode);
4070 if (GET_CODE (operands[2]) == CONST_INT)
4071 emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
4072 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
4075 rtx subshift = gen_reg_rtx (DImode);
4076 emit_insn (gen_extendsidi2 (subtarget, operands[1]));
4077 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4078 emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift));
4080 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
4084 (define_expand "lshrsi3"
4085 [(set (match_operand:SI 0 "gr_register_operand" "")
4086 (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "")
4087 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4090 rtx subtarget = gen_reg_rtx (DImode);
4091 if (GET_CODE (operands[2]) == CONST_INT)
4092 emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
4093 GEN_INT (32 - INTVAL (operands[2])), operands[2]));
4096 rtx subshift = gen_reg_rtx (DImode);
4097 emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
4098 emit_insn (gen_zero_extendsidi2 (subshift, operands[2]));
4099 emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift));
4101 emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
4105 ;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
4106 ;; here, instead of 64 like the patterns above. Keep the pattern together
4107 ;; until after combine; otherwise it won't get matched often.
4109 (define_expand "rotrsi3"
4110 [(set (match_operand:SI 0 "gr_register_operand" "")
4111 (rotatert:SI (match_operand:SI 1 "gr_register_operand" "")
4112 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4115 if (GET_MODE (operands[2]) != VOIDmode)
4117 rtx tmp = gen_reg_rtx (DImode);
4118 emit_insn (gen_zero_extendsidi2 (tmp, operands[2]));
4123 (define_insn_and_split "*rotrsi3_internal"
4124 [(set (match_operand:SI 0 "gr_register_operand" "=&r")
4125 (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r")
4126 (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))]
4131 (ior:DI (zero_extend:DI (match_dup 1))
4132 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
4134 (lshiftrt:DI (match_dup 3) (match_dup 2)))]
4135 "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));")
4137 (define_expand "rotlsi3"
4138 [(set (match_operand:SI 0 "gr_register_operand" "")
4139 (rotate:SI (match_operand:SI 1 "gr_register_operand" "")
4140 (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))]
4143 if (! shift_32bit_count_operand (operands[2], SImode))
4145 rtx tmp = gen_reg_rtx (SImode);
4146 emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2]));
4147 emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp));
4152 (define_insn_and_split "*rotlsi3_internal"
4153 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4154 (rotate:SI (match_operand:SI 1 "gr_register_operand" "r")
4155 (match_operand:SI 2 "shift_32bit_count_operand" "n")))]
4160 (ior:DI (zero_extend:DI (match_dup 1))
4161 (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32))))
4163 (lshiftrt:DI (match_dup 3) (match_dup 2)))]
4165 operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
4166 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4169 ;; ::::::::::::::::::::
4171 ;; :: 64 bit Integer Shifts and Rotates
4173 ;; ::::::::::::::::::::
4175 (define_insn "ashldi3"
4176 [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r")
4177 (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r")
4178 (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))]
4181 shladd %0 = %1, %2, r0
4184 [(set_attr "itanium_class" "ialu,mmshf,mmshfi")])
4186 ;; ??? Maybe combine this with the multiply and add instruction?
4188 (define_insn "*shladd"
4189 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4190 (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
4191 (match_operand:DI 2 "shladd_operand" "n"))
4192 (match_operand:DI 3 "gr_register_operand" "r")))]
4194 "shladd %0 = %1, %S2, %3"
4195 [(set_attr "itanium_class" "ialu")])
4197 ;; This can be created by register elimination if operand3 of shladd is an
4198 ;; eliminable register or has reg_equiv_constant set.
4200 ;; We have to use nonmemory_operand for operand 4, to ensure that the
4201 ;; validate_changes call inside eliminate_regs will always succeed. If it
4202 ;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
4205 (define_insn_and_split "*shladd_elim"
4206 [(set (match_operand:DI 0 "gr_register_operand" "=&r")
4207 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r")
4208 (match_operand:DI 2 "shladd_operand" "n"))
4209 (match_operand:DI 3 "nonmemory_operand" "r"))
4210 (match_operand:DI 4 "nonmemory_operand" "rI")))]
4211 "reload_in_progress"
4214 [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
4216 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
4218 [(set_attr "itanium_class" "unknown")])
4220 (define_insn "ashrdi3"
4221 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4222 (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
4223 (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
4228 [(set_attr "itanium_class" "mmshf,mmshfi")])
4230 (define_insn "lshrdi3"
4231 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4232 (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r")
4233 (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))]
4238 [(set_attr "itanium_class" "mmshf,mmshfi")])
4240 ;; Using a predicate that accepts only constants doesn't work, because optabs
4241 ;; will load the operand into a register and call the pattern if the predicate
4242 ;; did not accept it on the first try. So we use nonmemory_operand and then
4243 ;; verify that we have an appropriate constant in the expander.
4245 (define_expand "rotrdi3"
4246 [(set (match_operand:DI 0 "gr_register_operand" "")
4247 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "")
4248 (match_operand:DI 2 "nonmemory_operand" "")))]
4251 if (! shift_count_operand (operands[2], DImode))
4255 (define_insn "*rotrdi3_internal"
4256 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4257 (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r")
4258 (match_operand:DI 2 "shift_count_operand" "M")))]
4260 "shrp %0 = %1, %1, %2"
4261 [(set_attr "itanium_class" "ishf")])
4263 (define_expand "rotldi3"
4264 [(set (match_operand:DI 0 "gr_register_operand" "")
4265 (rotate:DI (match_operand:DI 1 "gr_register_operand" "")
4266 (match_operand:DI 2 "nonmemory_operand" "")))]
4269 if (! shift_count_operand (operands[2], DImode))
4273 (define_insn "*rotldi3_internal"
4274 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4275 (rotate:DI (match_operand:DI 1 "gr_register_operand" "r")
4276 (match_operand:DI 2 "shift_count_operand" "M")))]
4278 "shrp %0 = %1, %1, %e2"
4279 [(set_attr "itanium_class" "ishf")])
4281 ;; ::::::::::::::::::::
4283 ;; :: 32 bit Integer Logical operations
4285 ;; ::::::::::::::::::::
4287 ;; We don't seem to need any other 32-bit logical operations, because gcc
4288 ;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to
4289 ;; DImode-op;zero-extend, and then we can optimize away the zero-extend.
4290 ;; This doesn't work for unary logical operations, because we don't call
4291 ;; apply_distributive_law for them.
4293 ;; ??? Likewise, this doesn't work for andnot, which isn't handled by
4294 ;; apply_distributive_law. We get inefficient code for
4295 ;; int sub4 (int i, int j) { return i & ~j; }
4296 ;; We could convert (and (not (sign_extend A)) (sign_extend B)) to
4297 ;; (zero_extend (and (not A) B)) in combine.
4298 ;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the
4299 ;; one_cmplsi2 pattern.
4301 (define_insn "one_cmplsi2"
4302 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4303 (not:SI (match_operand:SI 1 "gr_register_operand" "r")))]
4306 [(set_attr "itanium_class" "ilog")])
4308 ;; ::::::::::::::::::::
4310 ;; :: 64 bit Integer Logical operations
4312 ;; ::::::::::::::::::::
4314 (define_insn "anddi3"
4315 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4316 (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4317 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4322 [(set_attr "itanium_class" "ilog,fmisc")])
4324 (define_insn "*andnot"
4325 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4326 (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f"))
4327 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4332 [(set_attr "itanium_class" "ilog,fmisc")])
4334 (define_insn "iordi3"
4335 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4336 (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4337 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4342 [(set_attr "itanium_class" "ilog,fmisc")])
4344 (define_insn "xordi3"
4345 [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
4346 (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f")
4347 (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))]
4352 [(set_attr "itanium_class" "ilog,fmisc")])
4354 (define_insn "one_cmpldi2"
4355 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4356 (not:DI (match_operand:DI 1 "gr_register_operand" "r")))]
4359 [(set_attr "itanium_class" "ilog")])
4361 ;; ::::::::::::::::::::
4365 ;; ::::::::::::::::::::
4367 (define_expand "cmpbi"
4369 (compare (match_operand:BI 0 "register_operand" "")
4370 (match_operand:BI 1 "const_int_operand" "")))]
4373 ia64_compare_op0 = operands[0];
4374 ia64_compare_op1 = operands[1];
4378 (define_expand "cmpsi"
4380 (compare (match_operand:SI 0 "gr_register_operand" "")
4381 (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
4384 ia64_compare_op0 = operands[0];
4385 ia64_compare_op1 = operands[1];
4389 (define_expand "cmpdi"
4391 (compare (match_operand:DI 0 "gr_register_operand" "")
4392 (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
4395 ia64_compare_op0 = operands[0];
4396 ia64_compare_op1 = operands[1];
4400 (define_expand "cmpsf"
4402 (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
4403 (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
4406 ia64_compare_op0 = operands[0];
4407 ia64_compare_op1 = operands[1];
4411 (define_expand "cmpdf"
4413 (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
4414 (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
4417 ia64_compare_op0 = operands[0];
4418 ia64_compare_op1 = operands[1];
4422 (define_expand "cmpxf"
4424 (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
4425 (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
4428 ia64_compare_op0 = operands[0];
4429 ia64_compare_op1 = operands[1];
4433 (define_expand "cmptf"
4435 (compare (match_operand:TF 0 "gr_register_operand" "")
4436 (match_operand:TF 1 "gr_register_operand" "")))]
4439 ia64_compare_op0 = operands[0];
4440 ia64_compare_op1 = operands[1];
4444 (define_insn "*cmpsi_normal"
4445 [(set (match_operand:BI 0 "register_operand" "=c")
4446 (match_operator:BI 1 "normal_comparison_operator"
4447 [(match_operand:SI 2 "gr_register_operand" "r")
4448 (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
4450 "cmp4.%C1 %0, %I0 = %3, %2"
4451 [(set_attr "itanium_class" "icmp")])
4453 ;; We use %r3 because it is possible for us to match a 0, and two of the
4454 ;; unsigned comparisons don't accept immediate operands of zero.
4456 (define_insn "*cmpsi_adjusted"
4457 [(set (match_operand:BI 0 "register_operand" "=c")
4458 (match_operator:BI 1 "adjusted_comparison_operator"
4459 [(match_operand:SI 2 "gr_register_operand" "r")
4460 (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4462 "cmp4.%C1 %0, %I0 = %r3, %2"
4463 [(set_attr "itanium_class" "icmp")])
4465 (define_insn "*cmpdi_normal"
4466 [(set (match_operand:BI 0 "register_operand" "=c")
4467 (match_operator:BI 1 "normal_comparison_operator"
4468 [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
4469 (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
4471 "cmp.%C1 %0, %I0 = %3, %r2"
4472 [(set_attr "itanium_class" "icmp")])
4474 ;; We use %r3 because it is possible for us to match a 0, and two of the
4475 ;; unsigned comparisons don't accept immediate operands of zero.
4477 (define_insn "*cmpdi_adjusted"
4478 [(set (match_operand:BI 0 "register_operand" "=c")
4479 (match_operator:BI 1 "adjusted_comparison_operator"
4480 [(match_operand:DI 2 "gr_register_operand" "r")
4481 (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
4483 "cmp.%C1 %0, %I0 = %r3, %2"
4484 [(set_attr "itanium_class" "icmp")])
4486 (define_insn "*cmpsf_internal"
4487 [(set (match_operand:BI 0 "register_operand" "=c")
4488 (match_operator:BI 1 "comparison_operator"
4489 [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
4490 (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
4492 "fcmp.%D1 %0, %I0 = %F2, %F3"
4493 [(set_attr "itanium_class" "fcmp")])
4495 (define_insn "*cmpdf_internal"
4496 [(set (match_operand:BI 0 "register_operand" "=c")
4497 (match_operator:BI 1 "comparison_operator"
4498 [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
4499 (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
4501 "fcmp.%D1 %0, %I0 = %F2, %F3"
4502 [(set_attr "itanium_class" "fcmp")])
4504 (define_insn "*cmpxf_internal"
4505 [(set (match_operand:BI 0 "register_operand" "=c")
4506 (match_operator:BI 1 "comparison_operator"
4507 [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
4508 (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
4510 "fcmp.%D1 %0, %I0 = %F2, %F3"
4511 [(set_attr "itanium_class" "fcmp")])
4513 ;; ??? Can this pattern be generated?
4515 (define_insn "*bit_zero"
4516 [(set (match_operand:BI 0 "register_operand" "=c")
4517 (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4519 (match_operand:DI 2 "immediate_operand" "n"))
4522 "tbit.z %0, %I0 = %1, %2"
4523 [(set_attr "itanium_class" "tbit")])
4525 (define_insn "*bit_one"
4526 [(set (match_operand:BI 0 "register_operand" "=c")
4527 (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
4529 (match_operand:DI 2 "immediate_operand" "n"))
4532 "tbit.nz %0, %I0 = %1, %2"
4533 [(set_attr "itanium_class" "tbit")])
4535 ;; ::::::::::::::::::::
4539 ;; ::::::::::::::::::::
4541 (define_expand "beq"
4543 (if_then_else (match_dup 1)
4544 (label_ref (match_operand 0 "" ""))
4547 "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
4549 (define_expand "bne"
4551 (if_then_else (match_dup 1)
4552 (label_ref (match_operand 0 "" ""))
4555 "operands[1] = ia64_expand_compare (NE, VOIDmode);")
4557 (define_expand "blt"
4559 (if_then_else (match_dup 1)
4560 (label_ref (match_operand 0 "" ""))
4563 "operands[1] = ia64_expand_compare (LT, VOIDmode);")
4565 (define_expand "ble"
4567 (if_then_else (match_dup 1)
4568 (label_ref (match_operand 0 "" ""))
4571 "operands[1] = ia64_expand_compare (LE, VOIDmode);")
4573 (define_expand "bgt"
4575 (if_then_else (match_dup 1)
4576 (label_ref (match_operand 0 "" ""))
4579 "operands[1] = ia64_expand_compare (GT, VOIDmode);")
4581 (define_expand "bge"
4583 (if_then_else (match_dup 1)
4584 (label_ref (match_operand 0 "" ""))
4587 "operands[1] = ia64_expand_compare (GE, VOIDmode);")
4589 (define_expand "bltu"
4591 (if_then_else (match_dup 1)
4592 (label_ref (match_operand 0 "" ""))
4595 "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
4597 (define_expand "bleu"
4599 (if_then_else (match_dup 1)
4600 (label_ref (match_operand 0 "" ""))
4603 "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
4605 (define_expand "bgtu"
4607 (if_then_else (match_dup 1)
4608 (label_ref (match_operand 0 "" ""))
4611 "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
4613 (define_expand "bgeu"
4615 (if_then_else (match_dup 1)
4616 (label_ref (match_operand 0 "" ""))
4619 "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
4621 (define_expand "bunordered"
4623 (if_then_else (match_dup 1)
4624 (label_ref (match_operand 0 "" ""))
4627 "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
4629 (define_expand "bordered"
4631 (if_then_else (match_dup 1)
4632 (label_ref (match_operand 0 "" ""))
4635 "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
4637 (define_insn "*br_true"
4639 (if_then_else (match_operator 0 "predicate_operator"
4640 [(match_operand:BI 1 "register_operand" "c")
4642 (label_ref (match_operand 2 "" ""))
4645 "(%J0) br.cond%+ %l2"
4646 [(set_attr "itanium_class" "br")
4647 (set_attr "predicable" "no")])
4649 (define_insn "*br_false"
4651 (if_then_else (match_operator 0 "predicate_operator"
4652 [(match_operand:BI 1 "register_operand" "c")
4655 (label_ref (match_operand 2 "" ""))))]
4657 "(%j0) br.cond%+ %l2"
4658 [(set_attr "itanium_class" "br")
4659 (set_attr "predicable" "no")])
4661 ;; ::::::::::::::::::::
4663 ;; :: Counted loop operations
4665 ;; ::::::::::::::::::::
4667 (define_expand "doloop_end"
4668 [(use (match_operand 0 "" "")) ; loop pseudo
4669 (use (match_operand 1 "" "")) ; iterations; zero if unknown
4670 (use (match_operand 2 "" "")) ; max iterations
4671 (use (match_operand 3 "" "")) ; loop level
4672 (use (match_operand 4 "" ""))] ; label
4675 /* Only use cloop on innermost loops. */
4676 if (INTVAL (operands[3]) > 1)
4678 emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
4683 (define_insn "doloop_end_internal"
4684 [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
4686 (label_ref (match_operand 1 "" ""))
4688 (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
4689 (plus:DI (match_dup 0) (const_int -1))
4692 "br.cloop.sptk.few %l1"
4693 [(set_attr "itanium_class" "br")
4694 (set_attr "predicable" "no")])
4696 ;; ::::::::::::::::::::
4698 ;; :: Set flag operations
4700 ;; ::::::::::::::::::::
4702 (define_expand "seq"
4703 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4705 "operands[1] = ia64_expand_compare (EQ, DImode);")
4707 (define_expand "sne"
4708 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4710 "operands[1] = ia64_expand_compare (NE, DImode);")
4712 (define_expand "slt"
4713 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4715 "operands[1] = ia64_expand_compare (LT, DImode);")
4717 (define_expand "sle"
4718 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4720 "operands[1] = ia64_expand_compare (LE, DImode);")
4722 (define_expand "sgt"
4723 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4725 "operands[1] = ia64_expand_compare (GT, DImode);")
4727 (define_expand "sge"
4728 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4730 "operands[1] = ia64_expand_compare (GE, DImode);")
4732 (define_expand "sltu"
4733 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4735 "operands[1] = ia64_expand_compare (LTU, DImode);")
4737 (define_expand "sleu"
4738 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4740 "operands[1] = ia64_expand_compare (LEU, DImode);")
4742 (define_expand "sgtu"
4743 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4745 "operands[1] = ia64_expand_compare (GTU, DImode);")
4747 (define_expand "sgeu"
4748 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4750 "operands[1] = ia64_expand_compare (GEU, DImode);")
4752 (define_expand "sunordered"
4753 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4755 "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
4757 (define_expand "sordered"
4758 [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
4760 "operands[1] = ia64_expand_compare (ORDERED, DImode);")
4762 ;; Don't allow memory as destination here, because cmov/cmov/st is more
4763 ;; efficient than mov/mov/cst/cst.
4765 (define_insn_and_split "*sne_internal"
4766 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4767 (ne:DI (match_operand:BI 1 "register_operand" "c")
4772 [(cond_exec (ne (match_dup 1) (const_int 0))
4773 (set (match_dup 0) (const_int 1)))
4774 (cond_exec (eq (match_dup 1) (const_int 0))
4775 (set (match_dup 0) (const_int 0)))]
4777 [(set_attr "itanium_class" "unknown")])
4779 (define_insn_and_split "*seq_internal"
4780 [(set (match_operand:DI 0 "gr_register_operand" "=r")
4781 (eq:DI (match_operand:BI 1 "register_operand" "c")
4786 [(cond_exec (ne (match_dup 1) (const_int 0))
4787 (set (match_dup 0) (const_int 0)))
4788 (cond_exec (eq (match_dup 1) (const_int 0))
4789 (set (match_dup 0) (const_int 1)))]
4791 [(set_attr "itanium_class" "unknown")])
4793 ;; ::::::::::::::::::::
4795 ;; :: Conditional move instructions.
4797 ;; ::::::::::::::::::::
4799 ;; ??? Add movXXcc patterns?
4802 ;; DImode if_then_else patterns.
4805 (define_insn "*cmovdi_internal"
4806 [(set (match_operand:DI 0 "destination_operand"
4807 "= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e")
4809 (match_operator 4 "predicate_operator"
4810 [(match_operand:BI 1 "register_operand"
4811 "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
4813 (match_operand:DI 2 "move_operand"
4814 "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
4815 (match_operand:DI 3 "move_operand"
4816 "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
4817 "ia64_move_ok (operands[0], operands[2])
4818 && ia64_move_ok (operands[0], operands[3])"
4820 [(set_attr "predicable" "no")])
4823 [(set (match_operand 0 "destination_operand" "")
4825 (match_operator 4 "predicate_operator"
4826 [(match_operand:BI 1 "register_operand" "")
4828 (match_operand 2 "move_operand" "")
4829 (match_operand 3 "move_operand" "")))]
4833 bool emitted_something = false;
4834 rtx dest = operands[0];
4835 rtx srct = operands[2];
4836 rtx srcf = operands[3];
4837 rtx cond = operands[4];
4839 if (! rtx_equal_p (dest, srct))
4841 ia64_emit_cond_move (dest, srct, cond);
4842 emitted_something = true;
4844 if (! rtx_equal_p (dest, srcf))
4846 cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
4847 VOIDmode, operands[1], const0_rtx);
4848 ia64_emit_cond_move (dest, srcf, cond);
4849 emitted_something = true;
4851 if (! emitted_something)
4852 emit_note (NOTE_INSN_DELETED);
4856 ;; Absolute value pattern.
4858 (define_insn "*absdi2_internal"
4859 [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
4861 (match_operator 4 "predicate_operator"
4862 [(match_operand:BI 1 "register_operand" "c,c")
4864 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
4865 (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
4868 [(set_attr "itanium_class" "ialu,unknown")
4869 (set_attr "predicable" "no")])
4872 [(set (match_operand:DI 0 "register_operand" "")
4874 (match_operator 4 "predicate_operator"
4875 [(match_operand:BI 1 "register_operand" "c,c")
4877 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4878 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4879 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4883 (neg:DI (match_dup 2))))]
4887 [(set (match_operand:DI 0 "register_operand" "")
4889 (match_operator 4 "predicate_operator"
4890 [(match_operand:BI 1 "register_operand" "c,c")
4892 (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
4893 (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
4897 (set (match_dup 0) (neg:DI (match_dup 2))))
4900 (set (match_dup 0) (match_dup 3)))]
4902 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4903 VOIDmode, operands[1], const0_rtx);
4907 ;; SImode if_then_else patterns.
4910 (define_insn "*cmovsi_internal"
4911 [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
4913 (match_operator 4 "predicate_operator"
4914 [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
4916 (match_operand:SI 2 "move_operand"
4917 "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
4918 (match_operand:SI 3 "move_operand"
4919 "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
4920 "ia64_move_ok (operands[0], operands[2])
4921 && ia64_move_ok (operands[0], operands[3])"
4923 [(set_attr "predicable" "no")])
4925 (define_insn "*abssi2_internal"
4926 [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
4928 (match_operator 4 "predicate_operator"
4929 [(match_operand:BI 1 "register_operand" "c,c")
4931 (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
4932 (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
4935 [(set_attr "itanium_class" "ialu,unknown")
4936 (set_attr "predicable" "no")])
4939 [(set (match_operand:SI 0 "register_operand" "")
4941 (match_operator 4 "predicate_operator"
4942 [(match_operand:BI 1 "register_operand" "c,c")
4944 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4945 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4946 "reload_completed && rtx_equal_p (operands[0], operands[3])"
4950 (neg:SI (match_dup 2))))]
4954 [(set (match_operand:SI 0 "register_operand" "")
4956 (match_operator 4 "predicate_operator"
4957 [(match_operand:BI 1 "register_operand" "c,c")
4959 (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
4960 (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
4964 (set (match_dup 0) (neg:SI (match_dup 2))))
4967 (set (match_dup 0) (match_dup 3)))]
4969 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
4970 VOIDmode, operands[1], const0_rtx);
4973 (define_insn_and_split "*cond_opsi2_internal"
4974 [(set (match_operand:SI 0 "gr_register_operand" "=r")
4975 (match_operator:SI 5 "condop_operator"
4977 (match_operator 6 "predicate_operator"
4978 [(match_operand:BI 1 "register_operand" "c")
4980 (match_operand:SI 2 "gr_register_operand" "r")
4981 (match_operand:SI 3 "gr_register_operand" "r"))
4982 (match_operand:SI 4 "gr_register_operand" "r")]))]
4988 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)])))
4991 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))]
4993 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
4994 VOIDmode, operands[1], const0_rtx);
4996 [(set_attr "itanium_class" "ialu")
4997 (set_attr "predicable" "no")])
5000 (define_insn_and_split "*cond_opsi2_internal_b"
5001 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5002 (match_operator:SI 5 "condop_operator"
5003 [(match_operand:SI 4 "gr_register_operand" "r")
5005 (match_operator 6 "predicate_operator"
5006 [(match_operand:BI 1 "register_operand" "c")
5008 (match_operand:SI 2 "gr_register_operand" "r")
5009 (match_operand:SI 3 "gr_register_operand" "r"))]))]
5015 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)])))
5018 (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))]
5020 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5021 VOIDmode, operands[1], const0_rtx);
5023 [(set_attr "itanium_class" "ialu")
5024 (set_attr "predicable" "no")])
5027 ;; ::::::::::::::::::::
5029 ;; :: Call and branch instructions
5031 ;; ::::::::::::::::::::
5033 ;; Subroutine call instruction returning no value. Operand 0 is the function
5034 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
5035 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
5036 ;; registers used as operands.
5038 ;; On most machines, operand 2 is not actually stored into the RTL pattern. It
5039 ;; is supplied for the sake of some RISC machines which need to put this
5040 ;; information into the assembler code; they can put it in the RTL instead of
5043 (define_expand "call"
5044 [(use (match_operand:DI 0 "" ""))
5045 (use (match_operand 1 "" ""))
5046 (use (match_operand 2 "" ""))
5047 (use (match_operand 3 "" ""))]
5050 ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
5054 (define_expand "sibcall"
5055 [(use (match_operand:DI 0 "" ""))
5056 (use (match_operand 1 "" ""))
5057 (use (match_operand 2 "" ""))
5058 (use (match_operand 3 "" ""))]
5061 ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
5065 ;; Subroutine call instruction returning a value. Operand 0 is the hard
5066 ;; register in which the value is returned. There are three more operands,
5067 ;; the same as the three operands of the `call' instruction (but with numbers
5068 ;; increased by one).
5070 ;; Subroutines that return `BLKmode' objects use the `call' insn.
5072 (define_expand "call_value"
5073 [(use (match_operand 0 "" ""))
5074 (use (match_operand:DI 1 "" ""))
5075 (use (match_operand 2 "" ""))
5076 (use (match_operand 3 "" ""))
5077 (use (match_operand 4 "" ""))]
5080 ia64_expand_call (operands[0], operands[1], operands[3], false);
5084 (define_expand "sibcall_value"
5085 [(use (match_operand 0 "" ""))
5086 (use (match_operand:DI 1 "" ""))
5087 (use (match_operand 2 "" ""))
5088 (use (match_operand 3 "" ""))
5089 (use (match_operand 4 "" ""))]
5092 ia64_expand_call (operands[0], operands[1], operands[3], true);
5096 ;; Call subroutine returning any type.
5098 (define_expand "untyped_call"
5099 [(parallel [(call (match_operand 0 "" "")
5101 (match_operand 1 "" "")
5102 (match_operand 2 "" "")])]
5107 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
5109 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5111 rtx set = XVECEXP (operands[2], 0, i);
5112 emit_move_insn (SET_DEST (set), SET_SRC (set));
5115 /* The optimizer does not know that the call sets the function value
5116 registers we stored in the result block. We avoid problems by
5117 claiming that all hard registers are used and clobbered at this
5119 emit_insn (gen_blockage ());
5124 (define_insn "call_nogp"
5125 [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5127 (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
5129 "br.call%+.many %1 = %0"
5130 [(set_attr "itanium_class" "br,scall")])
5132 (define_insn "call_value_nogp"
5133 [(set (match_operand 0 "" "=X,X")
5134 (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
5136 (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
5138 "br.call%+.many %2 = %1"
5139 [(set_attr "itanium_class" "br,scall")])
5141 (define_insn "sibcall_nogp"
5142 [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
5146 [(set_attr "itanium_class" "br,scall")])
5148 (define_insn "call_gp"
5149 [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5151 (clobber (match_operand:DI 1 "register_operand" "=b,b"))
5152 (clobber (match_scratch:DI 2 "=&r,X"))
5153 (clobber (match_scratch:DI 3 "=b,X"))]
5156 [(set_attr "itanium_class" "br,scall")])
5158 ;; Irritatingly, we don't have access to INSN within the split body.
5159 ;; See commentary in ia64_split_call as to why these aren't peep2.
5161 [(call (mem (match_operand 0 "call_operand" ""))
5163 (clobber (match_operand:DI 1 "register_operand" ""))
5164 (clobber (match_scratch:DI 2 ""))
5165 (clobber (match_scratch:DI 3 ""))]
5166 "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5169 ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5170 operands[3], true, false);
5175 [(call (mem (match_operand 0 "call_operand" ""))
5177 (clobber (match_operand:DI 1 "register_operand" ""))
5178 (clobber (match_scratch:DI 2 ""))
5179 (clobber (match_scratch:DI 3 ""))]
5183 ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5184 operands[3], false, false);
5188 (define_insn "call_value_gp"
5189 [(set (match_operand 0 "" "=X,X")
5190 (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
5192 (clobber (match_operand:DI 2 "register_operand" "=b,b"))
5193 (clobber (match_scratch:DI 3 "=&r,X"))
5194 (clobber (match_scratch:DI 4 "=b,X"))]
5197 [(set_attr "itanium_class" "br,scall")])
5200 [(set (match_operand 0 "" "")
5201 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
5203 (clobber (match_operand:DI 2 "register_operand" ""))
5204 (clobber (match_scratch:DI 3 ""))
5205 (clobber (match_scratch:DI 4 ""))]
5206 "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5209 ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5210 operands[4], true, false);
5215 [(set (match_operand 0 "" "")
5216 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
5218 (clobber (match_operand:DI 2 "register_operand" ""))
5219 (clobber (match_scratch:DI 3 ""))
5220 (clobber (match_scratch:DI 4 ""))]
5224 ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5225 operands[4], false, false);
5229 (define_insn_and_split "sibcall_gp"
5230 [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
5232 (clobber (match_scratch:DI 1 "=&r,X"))
5233 (clobber (match_scratch:DI 2 "=b,X"))]
5239 ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
5240 operands[2], true, true);
5243 [(set_attr "itanium_class" "br")])
5245 (define_insn "return_internal"
5247 (use (match_operand:DI 0 "register_operand" "b"))]
5249 "br.ret.sptk.many %0"
5250 [(set_attr "itanium_class" "br")])
5252 (define_insn "return"
5254 "ia64_direct_return ()"
5255 "br.ret.sptk.many rp"
5256 [(set_attr "itanium_class" "br")])
5258 (define_insn "*return_true"
5260 (if_then_else (match_operator 0 "predicate_operator"
5261 [(match_operand:BI 1 "register_operand" "c")
5265 "ia64_direct_return ()"
5266 "(%J0) br.ret%+.many rp"
5267 [(set_attr "itanium_class" "br")
5268 (set_attr "predicable" "no")])
5270 (define_insn "*return_false"
5272 (if_then_else (match_operator 0 "predicate_operator"
5273 [(match_operand:BI 1 "register_operand" "c")
5277 "ia64_direct_return ()"
5278 "(%j0) br.ret%+.many rp"
5279 [(set_attr "itanium_class" "br")
5280 (set_attr "predicable" "no")])
5283 [(set (pc) (label_ref (match_operand 0 "" "")))]
5286 [(set_attr "itanium_class" "br")])
5288 (define_insn "indirect_jump"
5289 [(set (pc) (match_operand:DI 0 "register_operand" "b"))]
5292 [(set_attr "itanium_class" "br")])
5294 (define_expand "tablejump"
5295 [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
5296 (use (label_ref (match_operand 1 "" "")))])]
5299 rtx op0 = operands[0];
5302 /* ??? Bother -- do_tablejump is "helpful" and pulls the table
5303 element into a register without bothering to see whether that
5304 is necessary given the operand predicate. Check for MEM just
5305 in case someone fixes this. */
5306 if (GET_CODE (op0) == MEM)
5307 addr = XEXP (op0, 0);
5310 /* Otherwise, cheat and guess that the previous insn in the
5311 stream was the memory load. Grab the address from that.
5312 Note we have to momentarily pop out of the sequence started
5313 by the insn-emit wrapper in order to grab the last insn. */
5317 last = get_last_insn ();
5319 set = single_set (last);
5321 if (! rtx_equal_p (SET_DEST (set), op0)
5322 || GET_CODE (SET_SRC (set)) != MEM)
5324 addr = XEXP (SET_SRC (set), 0);
5325 if (rtx_equal_p (addr, op0))
5329 /* Jump table elements are stored pc-relative. That is, a displacement
5330 from the entry to the label. Thus to convert to an absolute address
5331 we add the address of the memory from which the value is loaded. */
5332 operands[0] = expand_simple_binop (DImode, PLUS, op0, addr,
5333 NULL_RTX, 1, OPTAB_DIRECT);
5336 (define_insn "*tablejump_internal"
5337 [(set (pc) (match_operand:DI 0 "register_operand" "b"))
5338 (use (label_ref (match_operand 1 "" "")))]
5341 [(set_attr "itanium_class" "br")])
5344 ;; ::::::::::::::::::::
5346 ;; :: Prologue and Epilogue instructions
5348 ;; ::::::::::::::::::::
5350 (define_expand "prologue"
5354 ia64_expand_prologue ();
5358 (define_expand "epilogue"
5362 ia64_expand_epilogue (0);
5366 (define_expand "sibcall_epilogue"
5370 ia64_expand_epilogue (1);
5374 ;; This prevents the scheduler from moving the SP decrement past FP-relative
5375 ;; stack accesses. This is the same as adddi3 plus the extra set.
5377 (define_insn "prologue_allocate_stack"
5378 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5379 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a")
5380 (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))
5381 (set (match_operand:DI 3 "register_operand" "+r,r,r")
5388 [(set_attr "itanium_class" "ialu")])
5390 ;; This prevents the scheduler from moving the SP restore past FP-relative
5391 ;; stack accesses. This is similar to movdi plus the extra set.
5393 (define_insn "epilogue_deallocate_stack"
5394 [(set (match_operand:DI 0 "register_operand" "=r")
5395 (match_operand:DI 1 "register_operand" "+r"))
5396 (set (match_dup 1) (match_dup 1))]
5399 [(set_attr "itanium_class" "ialu")])
5401 ;; As USE insns aren't meaningful after reload, this is used instead
5402 ;; to prevent deleting instructions setting registers for EH handling
5403 (define_insn "prologue_use"
5404 [(unspec:DI [(match_operand:DI 0 "register_operand" "")]
5405 UNSPEC_PROLOGUE_USE)]
5408 [(set_attr "itanium_class" "ignore")
5409 (set_attr "predicable" "no")
5410 (set_attr "empty" "yes")])
5412 ;; Allocate a new register frame.
5414 (define_insn "alloc"
5415 [(set (match_operand:DI 0 "register_operand" "=r")
5416 (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC))
5417 (use (match_operand:DI 1 "const_int_operand" "i"))
5418 (use (match_operand:DI 2 "const_int_operand" "i"))
5419 (use (match_operand:DI 3 "const_int_operand" "i"))
5420 (use (match_operand:DI 4 "const_int_operand" "i"))]
5422 "alloc %0 = ar.pfs, %1, %2, %3, %4"
5423 [(set_attr "itanium_class" "syst_m0")
5424 (set_attr "predicable" "no")])
5427 (define_expand "gr_spill"
5428 [(parallel [(set (match_operand:DI 0 "memory_operand" "=m")
5429 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5430 (match_operand:DI 2 "const_int_operand" "")]
5432 (clobber (match_dup 3))])]
5434 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5436 (define_insn "gr_spill_internal"
5437 [(set (match_operand:DI 0 "memory_operand" "=m")
5438 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5439 (match_operand:DI 2 "const_int_operand" "")]
5441 (clobber (match_operand:DI 3 "register_operand" ""))]
5444 /* Note that we use a C output pattern here to avoid the predicate
5445 being automatically added before the .mem.offset directive. */
5446 return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0";
5448 [(set_attr "itanium_class" "st")])
5451 (define_expand "gr_restore"
5452 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
5453 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5454 (match_operand:DI 2 "const_int_operand" "")]
5456 (use (match_dup 3))])]
5458 "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);")
5460 (define_insn "gr_restore_internal"
5461 [(set (match_operand:DI 0 "register_operand" "=r")
5462 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
5463 (match_operand:DI 2 "const_int_operand" "")]
5465 (use (match_operand:DI 3 "register_operand" ""))]
5467 { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; }
5468 [(set_attr "itanium_class" "ld")])
5470 (define_insn "fr_spill"
5471 [(set (match_operand:XF 0 "memory_operand" "=m")
5472 (unspec:XF [(match_operand:XF 1 "register_operand" "f")]
5475 "stf.spill %0 = %1%P0"
5476 [(set_attr "itanium_class" "stf")])
5478 (define_insn "fr_restore"
5479 [(set (match_operand:XF 0 "register_operand" "=f")
5480 (unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
5481 UNSPEC_FR_RESTORE))]
5483 "ldf.fill %0 = %1%P1"
5484 [(set_attr "itanium_class" "fld")])
5486 ;; ??? The explicit stop is not ideal. It would be better if
5487 ;; rtx_needs_barrier took care of this, but this is something that can be
5488 ;; fixed later. This avoids an RSE DV.
5490 (define_insn "bsp_value"
5491 [(set (match_operand:DI 0 "register_operand" "=r")
5492 (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
5496 return \";;\;%,mov %0 = ar.bsp\";
5498 [(set_attr "itanium_class" "frar_i")])
5500 (define_insn "set_bsp"
5501 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
5519 [(set_attr "itanium_class" "unknown")
5520 (set_attr "predicable" "no")])
5522 ;; ??? The explicit stops are not ideal. It would be better if
5523 ;; rtx_needs_barrier took care of this, but this is something that can be
5524 ;; fixed later. This avoids an RSE DV.
5526 (define_insn "flushrs"
5527 [(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
5530 [(set_attr "itanium_class" "rse_m")
5531 (set_attr "predicable" "no")])
5533 ;; ::::::::::::::::::::
5535 ;; :: Miscellaneous instructions
5537 ;; ::::::::::::::::::::
5539 ;; ??? Emitting a NOP instruction isn't very useful. This should probably
5540 ;; be emitting ";;" to force a break in the instruction packing.
5542 ;; No operation, needed in case the user uses -g but not -O.
5547 [(set_attr "itanium_class" "nop")])
5549 (define_insn "nop_m"
5553 [(set_attr "itanium_class" "nop_m")])
5555 (define_insn "nop_i"
5559 [(set_attr "itanium_class" "nop_i")])
5561 (define_insn "nop_f"
5565 [(set_attr "itanium_class" "nop_f")])
5567 (define_insn "nop_b"
5571 [(set_attr "itanium_class" "nop_b")])
5573 (define_insn "nop_x"
5577 [(set_attr "itanium_class" "nop_x")
5578 (set_attr "empty" "yes")])
5580 ;; The following insn will be never generated. It is used only by
5581 ;; insn scheduler to change state before advancing cycle.
5582 (define_insn "pre_cycle"
5586 [(set_attr "itanium_class" "pre_cycle")])
5588 (define_insn "bundle_selector"
5589 [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
5591 { return get_bundle_name (INTVAL (operands[0])); }
5592 [(set_attr "itanium_class" "ignore")
5593 (set_attr "predicable" "no")])
5595 ;; Pseudo instruction that prevents the scheduler from moving code above this
5597 (define_insn "blockage"
5598 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
5601 [(set_attr "itanium_class" "ignore")
5602 (set_attr "predicable" "no")])
5604 (define_insn "insn_group_barrier"
5605 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
5606 UNSPECV_INSN_GROUP_BARRIER)]
5609 [(set_attr "itanium_class" "stop_bit")
5610 (set_attr "predicable" "no")
5611 (set_attr "empty" "yes")])
5613 (define_expand "trap"
5614 [(trap_if (const_int 1) (const_int 0))]
5618 ;; ??? We don't have a match-any slot type. Setting the type to unknown
5619 ;; produces worse code that setting the slot type to A.
5621 (define_insn "*trap"
5622 [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))]
5625 [(set_attr "itanium_class" "chk_s")])
5627 (define_expand "conditional_trap"
5628 [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
5631 operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
5634 (define_insn "*conditional_trap"
5635 [(trap_if (match_operator 0 "predicate_operator"
5636 [(match_operand:BI 1 "register_operand" "c")
5638 (match_operand 2 "const_int_operand" ""))]
5641 [(set_attr "itanium_class" "chk_s")
5642 (set_attr "predicable" "no")])
5644 (define_insn "break_f"
5645 [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)]
5648 [(set_attr "itanium_class" "nop_f")])
5650 (define_insn "prefetch"
5651 [(prefetch (match_operand:DI 0 "address_operand" "p")
5652 (match_operand:DI 1 "const_int_operand" "n")
5653 (match_operand:DI 2 "const_int_operand" "n"))]
5656 static const char * const alt[2][4] = {
5658 "%,lfetch.nta [%0]",
5659 "%,lfetch.nt1 [%0]",
5660 "%,lfetch.nt2 [%0]",
5664 "%,lfetch.excl.nta [%0]",
5665 "%,lfetch.excl.nt1 [%0]",
5666 "%,lfetch.excl.nt2 [%0]",
5667 "%,lfetch.excl [%0]"
5670 int i = (INTVAL (operands[1]));
5671 int j = (INTVAL (operands[2]));
5673 if (i != 0 && i != 1)
5679 [(set_attr "itanium_class" "lfetch")])
5681 ;; Non-local goto support.
5683 (define_expand "save_stack_nonlocal"
5684 [(use (match_operand:OI 0 "memory_operand" ""))
5685 (use (match_operand:DI 1 "register_operand" ""))]
5688 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5689 \"__ia64_save_stack_nonlocal\"),
5690 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode,
5691 operands[1], Pmode);
5695 (define_expand "nonlocal_goto"
5696 [(use (match_operand 0 "general_operand" ""))
5697 (use (match_operand 1 "general_operand" ""))
5698 (use (match_operand 2 "general_operand" ""))
5699 (use (match_operand 3 "general_operand" ""))]
5702 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
5703 LCT_NORETURN, VOIDmode, 3,
5705 copy_to_reg (XEXP (operands[2], 0)), Pmode,
5706 operands[3], Pmode);
5711 (define_insn_and_split "builtin_setjmp_receiver"
5712 [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
5722 (define_expand "eh_epilogue"
5723 [(use (match_operand:DI 0 "register_operand" "r"))
5724 (use (match_operand:DI 1 "register_operand" "r"))
5725 (use (match_operand:DI 2 "register_operand" "r"))]
5728 rtx bsp = gen_rtx_REG (Pmode, 10);
5729 rtx sp = gen_rtx_REG (Pmode, 9);
5731 if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10)
5733 emit_move_insn (bsp, operands[0]);
5736 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9)
5738 emit_move_insn (sp, operands[2]);
5741 emit_insn (gen_rtx_USE (VOIDmode, sp));
5742 emit_insn (gen_rtx_USE (VOIDmode, bsp));
5744 cfun->machine->ia64_eh_epilogue_sp = sp;
5745 cfun->machine->ia64_eh_epilogue_bsp = bsp;
5748 ;; Builtin apply support.
5750 (define_expand "restore_stack_nonlocal"
5751 [(use (match_operand:DI 0 "register_operand" ""))
5752 (use (match_operand:OI 1 "memory_operand" ""))]
5755 emit_library_call (gen_rtx_SYMBOL_REF (Pmode,
5756 "__ia64_restore_stack_nonlocal"),
5758 copy_to_reg (XEXP (operands[1], 0)), Pmode);
5763 ;;; Intrinsics support.
5766 [(set (mem:BLK (match_dup 0))
5767 (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
5770 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
5771 MEM_VOLATILE_P (operands[0]) = 1;
5774 (define_insn "*mf_internal"
5775 [(set (match_operand:BLK 0 "" "")
5776 (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))]
5779 [(set_attr "itanium_class" "syst_m")])
5781 (define_insn "fetchadd_acq_si"
5782 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5783 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5785 (unspec:SI [(match_dup 1)
5786 (match_operand:SI 2 "fetchadd_operand" "n")]
5787 UNSPEC_FETCHADD_ACQ))]
5789 "fetchadd4.acq %0 = %1, %2"
5790 [(set_attr "itanium_class" "sem")])
5792 (define_insn "fetchadd_acq_di"
5793 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5794 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5796 (unspec:DI [(match_dup 1)
5797 (match_operand:DI 2 "fetchadd_operand" "n")]
5798 UNSPEC_FETCHADD_ACQ))]
5800 "fetchadd8.acq %0 = %1, %2"
5801 [(set_attr "itanium_class" "sem")])
5803 (define_insn "cmpxchg_acq_si"
5804 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5805 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5807 (unspec:SI [(match_dup 1)
5808 (match_operand:SI 2 "gr_register_operand" "r")
5809 (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5810 UNSPEC_CMPXCHG_ACQ))]
5812 "cmpxchg4.acq %0 = %1, %2, %3"
5813 [(set_attr "itanium_class" "sem")])
5815 (define_insn "cmpxchg_acq_di"
5816 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5817 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5819 (unspec:DI [(match_dup 1)
5820 (match_operand:DI 2 "gr_register_operand" "r")
5821 (match_operand:DI 3 "ar_ccv_reg_operand" "")]
5822 UNSPEC_CMPXCHG_ACQ))]
5824 "cmpxchg8.acq %0 = %1, %2, %3"
5825 [(set_attr "itanium_class" "sem")])
5827 (define_insn "xchgsi"
5828 [(set (match_operand:SI 0 "gr_register_operand" "=r")
5829 (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
5831 (match_operand:SI 2 "gr_register_operand" "r"))]
5834 [(set_attr "itanium_class" "sem")])
5836 (define_insn "xchgdi"
5837 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5838 (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
5840 (match_operand:DI 2 "gr_register_operand" "r"))]
5843 [(set_attr "itanium_class" "sem")])
5848 [(match_operator 0 "predicate_operator"
5849 [(match_operand:BI 1 "register_operand" "c")
5854 (define_insn "pred_rel_mutex"
5855 [(set (match_operand:BI 0 "register_operand" "+c")
5856 (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))]
5858 ".pred.rel.mutex %0, %I0"
5859 [(set_attr "itanium_class" "ignore")
5860 (set_attr "predicable" "no")])
5862 (define_insn "safe_across_calls_all"
5863 [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)]
5865 ".pred.safe_across_calls p1-p63"
5866 [(set_attr "itanium_class" "ignore")
5867 (set_attr "predicable" "no")])
5869 (define_insn "safe_across_calls_normal"
5870 [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
5873 emit_safe_across_calls ();
5876 [(set_attr "itanium_class" "ignore")
5877 (set_attr "predicable" "no")])
5879 ;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
5880 ;; pointer. This is used by the HP-UX 32 bit mode.
5882 (define_insn "ptr_extend"
5883 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5884 (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")]
5888 [(set_attr "itanium_class" "ialu")])
5891 ;; Optimizations for ptr_extend
5893 (define_insn "ptr_extend_plus_imm"
5894 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5896 [(plus:SI (match_operand:SI 1 "basereg_operand" "r")
5897 (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
5899 "addp4_optimize_ok (operands[1], operands[2])"
5901 [(set_attr "itanium_class" "ialu")])
5903 (define_insn "*ptr_extend_plus_2"
5904 [(set (match_operand:DI 0 "gr_register_operand" "=r")
5906 [(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
5907 (match_operand:SI 2 "basereg_operand" "r"))]
5909 "addp4_optimize_ok (operands[1], operands[2])"
5911 [(set_attr "itanium_class" "ialu")])