OSDN Git Service

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