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