OSDN Git Service

4b9a4b95b3227131fef6ed8ec771f9642483d3b4
[pf3gnuchains/gcc-fork.git] / gcc / config / ia64 / ia64.md
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>.
6
7 ;; This file is part of GCC.
8
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.
13
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.
18
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.
23
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25
26 ;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later
27 ;; reload.  This will be fixed once scheduling support is turned on.
28
29 ;; ??? Optimize for post-increment addressing modes.
30
31 ;; ??? fselect is not supported, because there is no integer register
32 ;; equivalent.
33
34 ;; ??? fp abs/min/max instructions may also work for integer values.
35
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.
38
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.
41
42 ;; ??? Go through list of documented named patterns and look for more to
43 ;; implement.
44
45 ;; ??? Go through instruction manual and look for more instructions that
46 ;; can be emitted.
47
48 ;; ??? Add function unit scheduling info for Itanium (TM) processor.
49
50 ;; ??? Need a better way to describe alternate fp status registers.
51
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)
59
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   ])
81
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   ])
92 \f
93 ;; ::::::::::::::::::::
94 ;; ::
95 ;; :: Predicates
96 ;; ::
97 ;; ::::::::::::::::::::
98
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")))
103
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"))
109
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)")))
114
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" "")
118 {
119   switch (GET_CODE (op))
120     {
121     case LABEL_REF:
122       return true;
123
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);
127
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;
135
136       /* Ok if we're not using GOT entries at all.  */
137       if (TARGET_NO_PIC || TARGET_AUTO_PIC)
138         return true;
139
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;
145
146     default:
147       abort ();
148     }
149 })
150
151 ;; True if OP refers to a symbol in the sdata section.
152 (define_predicate "sdata_symbolic_operand" 
153   (match_code "symbol_ref,const")
154 {
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 */
164
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);
170
171     default:
172       abort ();
173     }
174 })
175
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")))
183
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")))
188
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)"))))
194
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")
198 {
199   unsigned int regno;
200   if (GET_CODE (op) == SUBREG)
201     op = SUBREG_REG (op);
202
203   regno = REGNO (op);
204   return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno));
205 })
206
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")
210 {
211   unsigned int regno;
212   if (GET_CODE (op) == SUBREG)
213     op = SUBREG_REG (op);
214
215   regno = REGNO (op);
216   return (regno >= FIRST_PSEUDO_REGISTER || FR_REGNO_P (regno));
217 })
218
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")
222 {
223   unsigned int regno;
224   if (GET_CODE (op) == SUBREG)
225     op = SUBREG_REG (op);
226
227   regno = REGNO (op);
228   return (regno >= FIRST_PSEUDO_REGISTER
229           || GENERAL_REGNO_P (regno)
230           || FR_REGNO_P (regno));
231 })
232
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")
236 {
237   unsigned int regno;
238
239   if (GET_CODE (op) == MEM)
240     return true;
241   if (GET_CODE (op) == SUBREG)
242     op = SUBREG_REG (op);
243
244   regno = REGNO (op);
245   return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno));
246 })
247
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")
251 {
252   unsigned int regno;
253
254   if (GET_CODE (op) == MEM)
255     return true;
256   if (GET_CODE (op) == SUBREG)
257     op = SUBREG_REG (op);
258
259   regno = REGNO (op);
260   return (regno >= FIRST_PSEUDO_REGISTER || FR_REGNO_P (regno));
261 })
262
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")
266 {
267   unsigned int regno;
268
269   if (GET_CODE (op) == MEM)
270     return true;
271   if (GET_CODE (op) == SUBREG)
272     op = SUBREG_REG (op);
273
274   regno = REGNO (op);
275   return (regno >= FIRST_PSEUDO_REGISTER
276           || GENERAL_REGNO_P (regno)
277           || FR_REGNO_P (regno));
278 })
279
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"))))
285
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"))))
291
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))"))))
297
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))"))))
303
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))"))))
309
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))"))))
315
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))"))))
325
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))"))))
331
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))"))))
337
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))")))
342
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")))
347
348 ;; True if OP is one of the immediate valuse 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")))
353
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")))
361
362
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)"))))
368
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"))))
373
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"))
378
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"))
383
384 ;; True if this is a signed inequality operator.
385 (define_predicate "signed_inequality_operator"
386   (match_code "ge,gt,le,lt"))
387
388 ;; True if this operator is valid for predication.
389 (define_predicate "predicate_operator"
390   (match_code "eq,ne"))
391
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"))
395
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.
400
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")))
405
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")))
410
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")))
415
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")
422 {
423   if (GET_CODE (op) == SUBREG)
424     op = SUBREG_REG (op);
425   return REG_POINTER (op);
426 })
427
428 \f
429 ;; ::::::::::::::::::::
430 ;; ::
431 ;; :: Attributes
432 ;; ::
433 ;; ::::::::::::::::::::
434
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")))
438
439 ;; Instruction type.  This primarily determines how instructions can be
440 ;; packed in bundles, and secondarily affects scheduling to function units.
441
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
449
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).
454
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"))
461
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")))
479
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")))
488
489 ;; Predication.  True iff this instruction can be predicated.
490
491 (define_attr "predicable" "no,yes" (const_string "yes"))
492
493 ;; Empty.  True iff this insn does not generate any code.
494
495 (define_attr "empty" "no,yes" (const_string "no"))
496
497 \f
498
499 ;; DFA descriptions of ia64 processors used for insn scheduling and
500 ;; bundling.
501
502 (automata_option "ndfa")
503
504 ;; Uncomment the following line to output automata for debugging.
505 ;; (automata_option "v")
506
507 (automata_option "w")
508
509 ;;(automata_option "no-minimization")
510
511
512 (include "itanium1.md")
513 (include "itanium2.md")
514
515 \f
516 ;; ::::::::::::::::::::
517 ;; ::
518 ;; :: Moves
519 ;; ::
520 ;; ::::::::::::::::::::
521
522 ;; Set of a single predicate register.  This is only used to implement
523 ;; pr-to-pr move and complement.
524
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")])
535
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")])
551
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   "")
563
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);")
577
578 (define_expand "movqi"
579   [(set (match_operand:QI 0 "general_operand" "")
580         (match_operand:QI 1 "general_operand" ""))]
581   ""
582 {
583   rtx op1 = ia64_expand_move (operands[0], operands[1]);
584   if (!op1)
585     DONE;
586   operands[1] = op1;
587 })
588
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")])
602
603 (define_expand "movhi"
604   [(set (match_operand:HI 0 "general_operand" "")
605         (match_operand:HI 1 "general_operand" ""))]
606   ""
607 {
608   rtx op1 = ia64_expand_move (operands[0], operands[1]);
609   if (!op1)
610     DONE;
611   operands[1] = op1;
612 })
613
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")])
627
628 (define_expand "movsi"
629   [(set (match_operand:SI 0 "general_operand" "")
630         (match_operand:SI 1 "general_operand" ""))]
631   ""
632 {
633   rtx op1 = ia64_expand_move (operands[0], operands[1]);
634   if (!op1)
635     DONE;
636   operands[1] = op1;
637 })
638
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")])
656
657 (define_expand "movdi"
658   [(set (match_operand:DI 0 "general_operand" "")
659         (match_operand:DI 1 "general_operand" ""))]
660   ""
661 {
662   rtx op1 = ia64_expand_move (operands[0], operands[1]);
663   if (!op1)
664     DONE;
665   operands[1] = op1;
666 })
667
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])"
674 {
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   };
695
696   if (which_alternative == 2 && ! TARGET_NO_PIC
697       && symbolic_operand (operands[1], VOIDmode))
698     abort ();
699
700   return alt[which_alternative];
701 }
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")])
703
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)]
709 {
710   ia64_expand_load_address (operands[0], operands[1]);
711   DONE;
712 })
713
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   ""
719 {
720   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
721   operands[3] = gen_const_mem (DImode, operands[2]);
722 })
723
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")])
730
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")])
737
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")])
744
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   ""
751 {
752   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
753   operands[3] = pic_offset_table_rtx;
754 })
755
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.
761
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)]
769 {
770   ia64_split_return_addr_rtx (operands[0]);
771   DONE;
772 }
773   [(set_attr "itanium_class" "ialu")])
774
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   ""
780 {
781   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
782     return "%,addl %0 = @ltoffx(%1), %2";
783   else
784     return "%,addl %0 = @ltoff(%1), %2";
785 }
786   [(set_attr "itanium_class" "ialu")])
787
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   ""
793 {
794   if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
795     return "%,ld8.mov %0 = [%1], %2";
796   else
797     return "%,ld8 %0 = [%1]";
798 }
799   [(set_attr "itanium_class" "ld")])
800
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")])
809
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")])
818
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   "")
825
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")])
833
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")])
841
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   "")
849
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")])
858
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")])
867
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")])
876
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   "")
883
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")])
891
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")])
899
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   "")
907
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")])
916
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")])
925
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   ""
934 {
935   rtx op1 = ia64_expand_move (operands[0], operands[1]);
936   if (!op1)
937     DONE;
938   operands[1] = op1;
939 })
940
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)]
948 {
949   ia64_split_tmode_move (operands);
950   DONE;
951 }
952   [(set_attr "itanium_class" "unknown")
953    (set_attr "predicable" "no")])
954
955 ;; Floating Point Moves
956 ;;
957 ;; Note - Patterns for SF mode moves are compulsory, but
958 ;; patterns for DF are optional, as GCC can synthesize them.
959
960 (define_expand "movsf"
961   [(set (match_operand:SF 0 "general_operand" "")
962         (match_operand:SF 1 "general_operand" ""))]
963   ""
964 {
965   rtx op1 = ia64_expand_move (operands[0], operands[1]);
966   if (!op1)
967     DONE;
968   operands[1] = op1;
969 })
970
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")])
985
986 (define_expand "movdf"
987   [(set (match_operand:DF 0 "general_operand" "")
988         (match_operand:DF 1 "general_operand" ""))]
989   ""
990 {
991   rtx op1 = ia64_expand_move (operands[0], operands[1]);
992   if (!op1)
993     DONE;
994   operands[1] = op1;
995 })
996
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")])
1011
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   ""
1018 {
1019   rtx op0 = operands[0];
1020
1021   if (GET_CODE (op0) == SUBREG)
1022     op0 = SUBREG_REG (op0);
1023
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.  */
1028
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 ();
1035
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];
1043
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));
1049
1050           emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
1051           DONE;
1052         }
1053
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         }
1062
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);
1066
1067       if (GET_CODE (operands[1]) == MEM)
1068         {
1069           rtx out[2];
1070
1071           out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0));
1072           out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0) + 1);
1073
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         }
1078
1079       abort ();
1080     }
1081
1082   if (! reload_in_progress && ! reload_completed)
1083     {
1084       operands[1] = spill_xfmode_operand (operands[1], 0);
1085
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         }
1102
1103       if (! ia64_move_ok (operands[0], operands[1]))
1104         operands[1] = force_reg (XFmode, operands[1]);
1105     }
1106 })
1107
1108 ;; ??? There's no easy way to mind volatile acquire/release semantics.
1109
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")])
1119
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   ""
1126 {
1127   rtx op1 = ia64_expand_move (operands[0], operands[1]);
1128   if (!op1)
1129     DONE;
1130   operands[1] = op1;
1131 })
1132
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)]
1140 {
1141   ia64_split_tmode_move (operands);
1142   DONE;
1143 }
1144   [(set_attr "itanium_class" "unknown")
1145    (set_attr "predicable" "no")])
1146
1147 \f
1148 ;; ::::::::::::::::::::
1149 ;; ::
1150 ;; :: Conversions
1151 ;; ::
1152 ;; ::::::::::::::::::::
1153
1154 ;; Signed conversions from a smaller integer to a larger integer
1155
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")])
1162
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")])
1169
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")])
1178
1179 ;; Unsigned conversions from a smaller integer to a larger integer
1180
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")])
1189
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")])
1198
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")])
1209
1210 ;; Convert between floating point types of different sizes.
1211
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.
1218
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.
1225
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")])
1232
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")])
1239
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")])
1246
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")])
1253
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")])
1260
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")])
1267
1268 ;; Convert between signed integer types and floating point.
1269
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")])
1276
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")])
1283
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")])
1290
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")])
1297
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")])
1305
1306 ;; Convert between unsigned integer types and floating point.
1307
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")])
1314
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")])
1321
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")])
1328
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")])
1335
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")])
1342
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")])
1349
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")])
1357 \f
1358 ;; ::::::::::::::::::::
1359 ;; ::
1360 ;; :: Bit field extraction
1361 ;; ::
1362 ;; ::::::::::::::::::::
1363
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")])
1372
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")])
1381
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.
1386
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.
1390
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   ""
1397 {
1398   int width = INTVAL (operands[1]);
1399   int shift = INTVAL (operands[2]);
1400
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]);
1406
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         }
1427
1428       /* We could handle remaining cases by emitting multiple dep
1429          instructions.
1430
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.
1436
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.  */
1442
1443       FAIL;
1444
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;
1451
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     }
1464 })
1465
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")])
1475
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"
1484 {
1485   operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
1486   return "%,dep.z %0 = %1, %2, %3";
1487 }
1488   [(set_attr "itanium_class" "ishf")])
1489
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")])
1498
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];")
1509
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")])
1518
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")])
1526
1527 ;; This is used by the rotrsi3 pattern.
1528
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")])
1538
1539 \f
1540 ;; ::::::::::::::::::::
1541 ;; ::
1542 ;; :: 1 bit Integer arithmetic
1543 ;; ::
1544 ;; ::::::::::::::::::::
1545
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")])
1563
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")])
1581
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")])
1599
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")])
1616
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")])
1628
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]));")
1643
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   "")
1658
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")])
1668
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")])
1678
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")])
1688
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")])
1698
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")])
1708
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")])
1718
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")])
1728
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")])
1738
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")])
1748
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")])
1758
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")])
1770
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")])
1782
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")])
1792
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")])
1802
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")])
1812
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")])
1822
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")])
1832
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")])
1842
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")])
1852
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")])
1862
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")])
1872
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")])
1882
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")])
1894
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")])
1906
1907 ;; Transform test of and/or of setcc into parallel comparisons.
1908
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   "")
1920
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   "")
1934
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   "")
1946
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   "")
1960
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.
1964 ;;
1965 ;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
1966 ;; that we're doing height reduction.
1967 ;
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 ;  "")
1983 ;
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 ;  "")
1999 ;
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 ;  "")
2015 ;
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 ;  "")
2031
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.
2035
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]);")
2052 \f
2053 ;; ::::::::::::::::::::
2054 ;; ::
2055 ;; :: 16 bit Integer arithmetic
2056 ;; ::
2057 ;; ::::::::::::::::::::
2058
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")])
2066
2067 \f
2068 ;; ::::::::::::::::::::
2069 ;; ::
2070 ;; :: 32 bit Integer arithmetic
2071 ;; ::
2072 ;; ::::::::::::::::::::
2073
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")])
2084
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")])
2093
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")])
2102
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")])
2111
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")])
2119
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")])
2127
2128 ;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns.
2129
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")])
2137
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")])
2146
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")])
2153
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); })
2163
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); })
2173
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); })
2183
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); })
2193
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); })
2203
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"
2209 {
2210   rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
2211
2212   op0_xf = gen_reg_rtx (XFmode);
2213   op0_di = gen_reg_rtx (DImode);
2214
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);
2219
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);
2224
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));
2230
2231   emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
2232
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;
2236 })
2237
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"
2243 {
2244   rtx op2_neg, op1_di, div;
2245
2246   div = gen_reg_rtx (SImode);
2247   emit_insn (gen_divsi3 (div, operands[1], operands[2]));
2248
2249   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2250
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);
2255
2256   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2257                           gen_lowpart (SImode, op1_di)));
2258   DONE;
2259 })
2260
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"
2266 {
2267   rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
2268
2269   op0_xf = gen_reg_rtx (XFmode);
2270   op0_di = gen_reg_rtx (DImode);
2271
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);
2276
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);
2281
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));
2287
2288   emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
2289
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;
2293 })
2294
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"
2300 {
2301   rtx op2_neg, op1_di, div;
2302
2303   div = gen_reg_rtx (SImode);
2304   emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
2305
2306   op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
2307
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);
2312
2313   emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
2314                           gen_lowpart (SImode, op1_di)));
2315   DONE;
2316 })
2317
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")])
2359 \f
2360 ;; ::::::::::::::::::::
2361 ;; ::
2362 ;; :: 64 bit Integer arithmetic
2363 ;; ::
2364 ;; ::::::::::::::::::::
2365
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")])
2376
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")])
2385
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")])
2397
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")])
2405
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")])
2413
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")])
2423
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.
2430
2431 ;; ??? Maybe validate_changes should try adding match_scratch clobbers?
2432
2433 ;; ??? Maybe we should change how adds are canonicalized.
2434
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")])
2444
2445 ;; This can be created by register elimination if operand3 of shladd is an
2446 ;; eliminable register or has reg_equiv_constant set.
2447
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.
2452
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")])
2463
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   "")
2478
2479 ;; ??? There are highpart multiply and add instructions, but we have no way
2480 ;; to generate them.
2481
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")])
2494
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")])
2507
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")])
2514
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); })
2524
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); })
2534
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); })
2544
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); })
2554
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); })
2564
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   ""
2576 {
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);
2582 })
2583
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   ""
2592 {
2593   operands[2] = gen_reg_rtx (DImode);
2594   operands[3] = gen_reg_rtx (DImode);
2595   operands[4] = gen_reg_rtx (DImode);
2596 })
2597
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   ""
2608 {
2609   operands[2] = gen_reg_rtx (XFmode);
2610   operands[3] = gen_reg_rtx (DImode);
2611   operands[4] = gen_reg_rtx (DImode);
2612 })
2613
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")])
2620
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")])
2628
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"
2634 {
2635   rtx op1_xf, op2_xf, op0_xf;
2636
2637   op0_xf = gen_reg_rtx (XFmode);
2638
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);
2643
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);
2648
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));
2653
2654   emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2655   DONE;
2656 })
2657
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"
2663 {
2664   rtx op2_neg, div;
2665
2666   div = gen_reg_rtx (DImode);
2667   emit_insn (gen_divdi3 (div, operands[1], operands[2]));
2668
2669   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2670
2671   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2672   DONE;
2673 })
2674
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"
2680 {
2681   rtx op1_xf, op2_xf, op0_xf;
2682
2683   op0_xf = gen_reg_rtx (XFmode);
2684
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);
2689
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);
2694
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));
2699
2700   emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
2701   DONE;
2702 })
2703
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"
2709 {
2710   rtx op2_neg, div;
2711
2712   div = gen_reg_rtx (DImode);
2713   emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
2714
2715   op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
2716
2717   emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
2718   DONE;
2719 })
2720
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")])
2780
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")])
2829 \f
2830 ;; ::::::::::::::::::::
2831 ;; ::
2832 ;; :: 32 bit floating point arithmetic
2833 ;; ::
2834 ;; ::::::::::::::::::::
2835
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")])
2843
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")])
2851
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")])
2859
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")])
2866
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")])
2873
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")])
2880
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")])
2888
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")])
2896
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")])
2905
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")])
2914
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")])
2922
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")])
2931
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")])
2941
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"
2947 {
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;
2955 })
2956
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   ] 
3005 {
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);
3011 }
3012   [(set_attr "predicable" "no")])
3013
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   ] 
3059 {
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);
3065 }
3066   [(set_attr "predicable" "no")])
3067
3068 ;; Inline square root.
3069
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")])
3081
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")])
3089
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"
3094 {
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;
3106 })
3107
3108 ;; Latency-optimized square root.
3109 ;; FIXME: Implement.
3110
3111 ;; Throughput-optimized square root.
3112
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))]))]
3208 {
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);
3214 }
3215   [(set_attr "predicable" "no")])
3216 \f
3217 ;; ::::::::::::::::::::
3218 ;; ::
3219 ;; :: 64 bit floating point arithmetic
3220 ;; ::
3221 ;; ::::::::::::::::::::
3222
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")])
3230
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")])
3239
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")])
3247
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")])
3256
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")])
3264
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")])
3273
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")])
3280
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")])
3287
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")])
3294
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")])
3302
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")])
3310
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")])
3319
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")])
3329
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")])
3338
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")])
3348
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")])
3356
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")])
3365
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")])
3374
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")])
3384
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")])
3394
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")])
3405
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"
3411 {
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;
3419 })
3420
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   ] 
3492 {
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);
3499 }
3500   [(set_attr "predicable" "no")])
3501
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   ] 
3559 {
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);
3565 }
3566   [(set_attr "predicable" "no")])
3567
3568 ;; Inline square root.
3569
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"
3574 {
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;
3586 })
3587
3588 ;; Latency-optimized square root.
3589 ;; FIXME: Implement.
3590
3591 ;; Throughput-optimized square root.
3592
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))]))]
3708 {
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);
3714 }
3715   [(set_attr "predicable" "no")])
3716 \f
3717 ;; ::::::::::::::::::::
3718 ;; ::
3719 ;; :: 80 bit floating point arithmetic
3720 ;; ::
3721 ;; ::::::::::::::::::::
3722
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")])
3730
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")])
3739
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")])
3748
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")])
3756
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")])
3765
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")])
3774
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")])
3782
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")])
3791
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")])
3800
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")])
3809
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")])
3819
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")])
3829
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")])
3836
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")])
3843
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")])
3850
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")])
3858
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")])
3866
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")])
3875
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")])
3885
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")])
3895
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")])
3905
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")])
3916
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")])
3927
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")])
3936
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")])
3946
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")])
3956
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")])
3964
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")])
3974
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")])
3984
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")])
3994
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")])
4005
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")])
4016
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")])
4027
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")])
4039
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")])
4051
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"
4057 {
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;
4065 })
4066
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")])
4146
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")])
4224
4225 ;; Inline square root.
4226
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"
4231 {
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;
4243 })
4244
4245 ;; Latency-optimized square root.
4246 ;; FIXME: Implement.
4247
4248 ;; Throughput-optimized square root.
4249
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))]))]
4380 {
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);
4386 }
4387   [(set_attr "predicable" "no")])
4388
4389 ;; ??? frcpa works like cmp.foo.unc.
4390
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")])
4403 \f
4404 ;; ::::::::::::::::::::
4405 ;; ::
4406 ;; :: 32 bit Integer Shifts and Rotates
4407 ;; ::
4408 ;; ::::::::::::::::::::
4409
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   ""
4415 {
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     }
4424 })
4425
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")])
4436
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   ""
4442 {
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;
4456 })
4457
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   ""
4463 {
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;
4477 })
4478
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.
4482
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   ""
4488 {
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     }
4495 })
4496
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]));")
4510
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   ""
4516 {
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     }
4524 })
4525
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)))]
4538 {
4539   operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));
4540   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
4541 })
4542 \f
4543 ;; ::::::::::::::::::::
4544 ;; ::
4545 ;; :: 64 bit Integer Shifts and Rotates
4546 ;; ::
4547 ;; ::::::::::::::::::::
4548
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")])
4559
4560 ;; ??? Maybe combine this with the multiply and add instruction?
4561
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")])
4570
4571 ;; This can be created by register elimination if operand3 of shladd is an
4572 ;; eliminable register or has reg_equiv_constant set.
4573
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.
4578
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")])
4593
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")])
4603
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")])
4613
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.
4618
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   ""
4624 {
4625   if (! shift_count_operand (operands[2], DImode))
4626     FAIL;
4627 })
4628
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")])
4636
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   ""
4642 {
4643   if (! shift_count_operand (operands[2], DImode))
4644     FAIL;
4645 })
4646
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")])
4654 \f
4655 ;; ::::::::::::::::::::
4656 ;; ::
4657 ;; :: 32 bit Integer Logical operations
4658 ;; ::
4659 ;; ::::::::::::::::::::
4660
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.
4666
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.
4674
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")])
4681 \f
4682 ;; ::::::::::::::::::::
4683 ;; ::
4684 ;; :: 64 bit Integer Logical operations
4685 ;; ::
4686 ;; ::::::::::::::::::::
4687
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")])
4697
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")])
4707
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")])
4717
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")])
4727
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")])
4734 \f
4735 ;; ::::::::::::::::::::
4736 ;; ::
4737 ;; :: Comparisons
4738 ;; ::
4739 ;; ::::::::::::::::::::
4740
4741 (define_expand "cmpbi"
4742   [(set (cc0)
4743         (compare (match_operand:BI 0 "register_operand" "")
4744                  (match_operand:BI 1 "const_int_operand" "")))]
4745   ""
4746 {
4747   ia64_compare_op0 = operands[0];
4748   ia64_compare_op1 = operands[1];
4749   DONE;
4750 })
4751
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   ""
4757 {
4758   ia64_compare_op0 = operands[0];
4759   ia64_compare_op1 = operands[1];
4760   DONE;
4761 })
4762
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   ""
4768 {
4769   ia64_compare_op0 = operands[0];
4770   ia64_compare_op1 = operands[1];
4771   DONE;
4772 })
4773
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   ""
4779 {
4780   ia64_compare_op0 = operands[0];
4781   ia64_compare_op1 = operands[1];
4782   DONE;
4783 })
4784
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   ""
4790 {
4791   ia64_compare_op0 = operands[0];
4792   ia64_compare_op1 = operands[1];
4793   DONE;
4794 })
4795
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   ""
4801 {
4802   ia64_compare_op0 = operands[0];
4803   ia64_compare_op1 = operands[1];
4804   DONE;
4805 })
4806
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"
4812 {
4813   ia64_compare_op0 = operands[0];
4814   ia64_compare_op1 = operands[1];
4815   DONE;
4816 })
4817
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")])
4826
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.
4829
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")])
4838
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")])
4847
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.
4850
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")])
4859
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")])
4868
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")])
4877
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")])
4886
4887 ;; ??? Can this pattern be generated?
4888
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")])
4898
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")])
4908 \f
4909 ;; ::::::::::::::::::::
4910 ;; ::
4911 ;; :: Branches
4912 ;; ::
4913 ;; ::::::::::::::::::::
4914
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);")
4922
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);")
4930
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);")
4938
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);")
4946
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);")
4954
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);")
4962
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);")
4970
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);")
4978
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);")
4986
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);")
4994
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);")
5002
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);")
5010
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")])
5022
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")])
5034 \f
5035 ;; ::::::::::::::::::::
5036 ;; ::
5037 ;; :: Counted loop operations
5038 ;; ::
5039 ;; ::::::::::::::::::::
5040
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   ""
5048 {
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;
5055 })
5056
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")])
5069 \f
5070 ;; ::::::::::::::::::::
5071 ;; ::
5072 ;; :: Set flag operations
5073 ;; ::
5074 ;; ::::::::::::::::::::
5075
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);")
5080
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);")
5085
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);")
5090
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);")
5095
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);")
5100
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);")
5105
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);")
5110
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);")
5115
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);")
5120
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);")
5125
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);")
5130
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);")
5135
5136 ;; Don't allow memory as destination here, because cmov/cmov/st is more
5137 ;; efficient than mov/mov/cst/cst.
5138
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")])
5152
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")])
5166 \f
5167 ;; ::::::::::::::::::::
5168 ;; ::
5169 ;; :: Conditional move instructions.
5170 ;; ::
5171 ;; ::::::::::::::::::::
5172
5173 ;; ??? Add movXXcc patterns?
5174
5175 ;;
5176 ;; DImode if_then_else patterns.
5177 ;;
5178
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")])
5195
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)]
5206 {
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];
5212
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;
5228 })
5229
5230 ;; Absolute value pattern.
5231
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")])
5244
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   "")
5259
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)))]
5275 {
5276   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
5277                                 VOIDmode, operands[1], const0_rtx);
5278 })
5279
5280 ;;
5281 ;; SImode if_then_else patterns.
5282 ;;
5283
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")])
5298
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")])
5311
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   "")
5326
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)))]
5342 {
5343   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
5344                                 VOIDmode, operands[1], const0_rtx);
5345 })
5346
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)])))]
5366 {
5367   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5368                                 VOIDmode, operands[1], const0_rtx);
5369 }
5370   [(set_attr "itanium_class" "ialu")
5371    (set_attr "predicable" "no")])
5372
5373
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)])))]
5393 {
5394   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE,
5395                                 VOIDmode, operands[1], const0_rtx);
5396 }
5397   [(set_attr "itanium_class" "ialu")
5398    (set_attr "predicable" "no")])
5399
5400 \f
5401 ;; ::::::::::::::::::::
5402 ;; ::
5403 ;; :: Call and branch instructions
5404 ;; ::
5405 ;; ::::::::::::::::::::
5406
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.
5411
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.
5416
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   ""
5423 {
5424   ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
5425   DONE;
5426 })
5427
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   ""
5434 {
5435   ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
5436   DONE;
5437 })
5438
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).
5443 ;;
5444 ;; Subroutines that return `BLKmode' objects use the `call' insn.
5445
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   ""
5453 {
5454   ia64_expand_call (operands[0], operands[1], operands[3], false);
5455   DONE;
5456 })
5457
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   ""
5465 {
5466   ia64_expand_call (operands[0], operands[1], operands[3], true);
5467   DONE;
5468 })
5469
5470 ;; Call subroutine returning any type.
5471
5472 (define_expand "untyped_call"
5473   [(parallel [(call (match_operand 0 "" "")
5474                     (const_int 0))
5475               (match_operand 1 "" "")
5476               (match_operand 2 "" "")])]
5477   ""
5478 {
5479   int i;
5480
5481   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
5482
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     }
5488
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 ());
5494
5495   DONE;
5496 })
5497
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")])
5505
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")])
5514
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")])
5521
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")])
5531
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)]
5542 {
5543   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5544                    operands[3], true, false);
5545   DONE;
5546 })
5547
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)]
5556 {
5557   ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
5558                    operands[3], false, false);
5559   DONE;
5560 })
5561
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")])
5572
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)]
5582 {
5583   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5584                    operands[4], true, false);
5585   DONE;
5586 })
5587
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)]
5597 {
5598   ia64_split_call (operands[0], operands[1], operands[2], operands[3],
5599                    operands[4], false, false);
5600   DONE;
5601 })
5602
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)]
5612 {
5613   ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
5614                    operands[2], true, true);
5615   DONE;
5616 }
5617   [(set_attr "itanium_class" "br")])
5618
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")])
5625
5626 (define_insn "return"
5627   [(return)]
5628   "ia64_direct_return ()"
5629   "br.ret.sptk.many rp"
5630   [(set_attr "itanium_class" "br")])
5631
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")])
5643
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")])
5655
5656 (define_insn "jump"
5657   [(set (pc) (label_ref (match_operand 0 "" "")))]
5658   ""
5659   "br %l0"
5660   [(set_attr "itanium_class" "br")])
5661
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")])
5667
5668 (define_expand "tablejump"
5669   [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" ""))
5670               (use (label_ref (match_operand 1 "" "")))])]
5671   ""
5672 {
5673   rtx op0 = operands[0];
5674   rtx addr;
5675
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;
5689
5690       end_sequence ();
5691       last = get_last_insn ();
5692       start_sequence ();
5693       set = single_set (last);
5694
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     }
5702
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);
5708 })
5709
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")])
5716
5717 \f
5718 ;; ::::::::::::::::::::
5719 ;; ::
5720 ;; :: Prologue and Epilogue instructions
5721 ;; ::
5722 ;; ::::::::::::::::::::
5723
5724 (define_expand "prologue"
5725   [(const_int 1)]
5726   ""
5727 {
5728   ia64_expand_prologue ();
5729   DONE;
5730 })
5731
5732 (define_expand "epilogue"
5733   [(return)]
5734   ""
5735 {
5736   ia64_expand_epilogue (0);
5737   DONE;
5738 })
5739
5740 (define_expand "sibcall_epilogue"
5741   [(return)]
5742   ""
5743 {
5744   ia64_expand_epilogue (1);
5745   DONE;
5746 })
5747
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.
5750
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")])
5763
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.
5766
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")])
5774
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")])
5785
5786 ;; Allocate a new register frame.
5787
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")])
5799
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);")
5809
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   ""
5817 {
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";
5821 }
5822   [(set_attr "itanium_class" "st")])
5823
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);")
5833
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")])
5843
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")])
5851
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")])
5859
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.
5863
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   "*
5869 {
5870   return \";;\;%,mov %0 = ar.bsp\";
5871 }"
5872   [(set_attr "itanium_class" "frar_i")])
5873
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")])
5895
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.
5899
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")])
5906 \f
5907 ;; ::::::::::::::::::::
5908 ;; ::
5909 ;; :: Miscellaneous instructions
5910 ;; ::
5911 ;; ::::::::::::::::::::
5912
5913 ;; ??? Emitting a NOP instruction isn't very useful.  This should probably
5914 ;; be emitting ";;" to force a break in the instruction packing.
5915
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")])
5922
5923 (define_insn "nop_m"
5924   [(const_int 1)]
5925   ""
5926   "nop.m 0"
5927   [(set_attr "itanium_class" "nop_m")])
5928
5929 (define_insn "nop_i"
5930   [(const_int 2)]
5931   ""
5932   "nop.i 0"
5933   [(set_attr "itanium_class" "nop_i")])
5934
5935 (define_insn "nop_f"
5936   [(const_int 3)]
5937   ""
5938   "nop.f 0"
5939   [(set_attr "itanium_class" "nop_f")])
5940
5941 (define_insn "nop_b"
5942   [(const_int 4)]
5943   ""
5944   "nop.b 0"
5945   [(set_attr "itanium_class" "nop_b")])
5946
5947 (define_insn "nop_x"
5948   [(const_int 5)]
5949   ""
5950   ""
5951   [(set_attr "itanium_class" "nop_x")
5952    (set_attr "empty" "yes")])
5953
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")])
5961
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")])
5968
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")])
5977
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")])
5986
5987 (define_expand "trap"
5988   [(trap_if (const_int 1) (const_int 0))]
5989   ""
5990   "")
5991
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.
5994
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")])
6000
6001 (define_expand "conditional_trap"
6002   [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
6003   ""
6004 {
6005   operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
6006 })
6007
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")])
6017
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")])
6023
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   ""
6029 {
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]));
6046
6047   if (i != 0 && i != 1)
6048     abort ();
6049   if (j < 0 || j > 3)
6050     abort ();
6051   return alt[i][j];
6052 }
6053   [(set_attr "itanium_class" "lfetch")])
6054 \f
6055 ;; Non-local goto support.
6056
6057 (define_expand "save_stack_nonlocal"
6058   [(use (match_operand:OI 0 "memory_operand" ""))
6059    (use (match_operand:DI 1 "register_operand" ""))]
6060   ""
6061 {
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;
6067 })
6068
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   ""
6075 {
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;
6083 })
6084
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)]
6091 {
6092   ia64_reload_gp ();
6093   DONE;
6094 })
6095
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   ""
6101 {
6102   rtx bsp = gen_rtx_REG (Pmode, 10);
6103   rtx sp = gen_rtx_REG (Pmode, 9);
6104
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));
6117
6118   cfun->machine->ia64_eh_epilogue_sp = sp;
6119   cfun->machine->ia64_eh_epilogue_bsp = bsp;
6120 })
6121 \f
6122 ;; Builtin apply support.
6123
6124 (define_expand "restore_stack_nonlocal"
6125   [(use (match_operand:DI 0 "register_operand" ""))
6126    (use (match_operand:OI 1 "memory_operand" ""))]
6127   ""
6128 {
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;
6134 })
6135
6136 \f
6137 ;;; Intrinsics support.
6138
6139 (define_expand "mf"
6140   [(set (mem:BLK (match_dup 0))
6141         (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))]
6142   ""
6143 {
6144   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
6145   MEM_VOLATILE_P (operands[0]) = 1;
6146 })
6147
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")])
6154
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")])
6165
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")])
6176
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")])
6188
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")])
6200
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")])
6209
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")])
6218 \f
6219 ;; Predication.
6220
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)")
6227
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")])
6235
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")])
6242
6243 (define_insn "safe_across_calls_normal"
6244   [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
6245   ""
6246 {
6247   emit_safe_across_calls ();
6248   return "";
6249 }
6250   [(set_attr "itanium_class" "ignore")
6251    (set_attr "predicable" "no")])
6252
6253 ;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit
6254 ;; pointer.  This is used by the HP-UX 32 bit mode.
6255
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")])
6263
6264 ;;
6265 ;; Optimizations for ptr_extend
6266
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")])
6276
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")])