OSDN Git Service

2002-04-29 Vladimir Makarov <vmakarov@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;; Machine description for SPARC chip for GNU C compiler
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;;  64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6 ;;  at Cygnus Support.
7
8 ;; This file is part of GNU CC.
9
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
28 ;;
29 ;; UNSPEC:              0       movsi_{lo_sum,high}_pic
30 ;;                              pic_lo_sum_di
31 ;;                              pic_sethi_di
32 ;;                      1       update_return
33 ;;                      2       get_pc
34 ;;                      5       movsi_{,lo_sum_,high_}pic_label_ref
35 ;;                      6       seth44
36 ;;                      7       setm44
37 ;;                      8       setl44
38 ;;                      9       sethh
39 ;;                      10      setlm
40 ;;                      11      embmedany_sethi, embmedany_brsum
41 ;;                      13      embmedany_textuhi
42 ;;                      14      embmedany_texthi
43 ;;                      15      embmedany_textulo
44 ;;                      16      embmedany_textlo
45 ;;                      18      sethm
46 ;;                      19      setlo
47 ;;                      20      cycle_display
48 ;;
49 ;; UNSPEC_VOLATILE:     0       blockage
50 ;;                      1       flush_register_windows
51 ;;                      2       goto_handler_and_restore
52 ;;                      3       goto_handler_and_restore_v9*
53 ;;                      4       flush
54 ;;                      5       do_builtin_setjmp_setup
55 ;;
56
57 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
58 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
59 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
60 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
61 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62
63 ;; Attribute for cpu type.
64 ;; These must match the values for enum processor_type in sparc.h.
65 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc,ultrasparc3"
66   (const (symbol_ref "sparc_cpu_attr")))
67
68 ;; Attribute for the instruction set.
69 ;; At present we only need to distinguish v9/!v9, but for clarity we
70 ;; test TARGET_V8 too.
71 (define_attr "isa" "v6,v8,v9,sparclet"
72  (const
73   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
74          (symbol_ref "TARGET_V8") (const_string "v8")
75          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
76         (const_string "v6"))))
77
78 ;; Architecture size.
79 (define_attr "arch" "arch32bit,arch64bit"
80  (const
81   (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
82         (const_string "arch32bit"))))
83
84 ;; Insn type.
85
86 (define_attr "type"
87   "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcrmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
88   (const_string "ialu"))
89
90 ;; true if branch/call has empty delay slot and will emit a nop in it
91 (define_attr "empty_delay_slot" "false,true"
92   (symbol_ref "empty_delay_slot (insn)"))
93
94 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
95
96 (define_attr "pic" "false,true"
97   (symbol_ref "flag_pic != 0"))
98
99 ;; Length (in # of insns).
100 (define_attr "length" ""
101   (cond [(eq_attr "type" "uncond_branch,call,sibcall")
102            (if_then_else (eq_attr "empty_delay_slot" "true")
103              (const_int 2)
104              (const_int 1))
105          (eq_attr "branch_type" "icc")
106            (if_then_else (match_operand 0 "noov_compare64_op" "")
107              (if_then_else (lt (pc) (match_dup 1))
108                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
109                  (if_then_else (eq_attr "empty_delay_slot" "true")
110                    (const_int 2)
111                    (const_int 1))
112                  (if_then_else (eq_attr "empty_delay_slot" "true")
113                    (const_int 4)
114                    (const_int 3)))
115                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
116                  (if_then_else (eq_attr "empty_delay_slot" "true")
117                    (const_int 2)
118                    (const_int 1))
119                  (if_then_else (eq_attr "empty_delay_slot" "true")
120                    (const_int 4)
121                    (const_int 3))))
122              (if_then_else (eq_attr "empty_delay_slot" "true")
123                (const_int 2)
124                (const_int 1)))
125          (eq_attr "branch_type" "fcc")
126            (if_then_else (match_operand 0 "fcc0_reg_operand" "")
127              (if_then_else (eq_attr "empty_delay_slot" "true")
128                (const_int 2)
129                (const_int 1))
130              (if_then_else (lt (pc) (match_dup 2))
131                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
132                  (if_then_else (eq_attr "empty_delay_slot" "true")
133                    (const_int 2)
134                    (const_int 1))
135                  (if_then_else (eq_attr "empty_delay_slot" "true")
136                    (const_int 4)
137                    (const_int 3)))
138                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
139                  (if_then_else (eq_attr "empty_delay_slot" "true")
140                    (const_int 2)
141                    (const_int 1))
142                  (if_then_else (eq_attr "empty_delay_slot" "true")
143                    (const_int 4)
144                    (const_int 3)))))
145          (eq_attr "branch_type" "reg")
146            (if_then_else (lt (pc) (match_dup 2))
147              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
148                (if_then_else (eq_attr "empty_delay_slot" "true")
149                  (const_int 2)
150                  (const_int 1))
151                (if_then_else (eq_attr "empty_delay_slot" "true")
152                  (const_int 4)
153                  (const_int 3)))
154              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
155                (if_then_else (eq_attr "empty_delay_slot" "true")
156                  (const_int 2)
157                  (const_int 1))
158                (if_then_else (eq_attr "empty_delay_slot" "true")
159                  (const_int 4)
160                  (const_int 3))))
161          ] (const_int 1)))
162
163 ;; FP precision.
164 (define_attr "fptype" "single,double" (const_string "single"))
165
166 ;; UltraSPARC-III integer load type.
167 (define_attr "us3load_type" "2cycle,3cycle" (const_string "2cycle"))
168
169 (define_asm_attributes
170   [(set_attr "length" "2")
171    (set_attr "type" "multi")])
172
173 ;; Attributes for instruction and branch scheduling
174
175 (define_attr "in_call_delay" "false,true"
176   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
177                 (const_string "false")
178          (eq_attr "type" "load,fpload,store,fpstore")
179                 (if_then_else (eq_attr "length" "1")
180                               (const_string "true")
181                               (const_string "false"))]
182         (if_then_else (eq_attr "length" "1")
183                       (const_string "true")
184                       (const_string "false"))))
185
186 (define_delay (eq_attr "type" "call")
187   [(eq_attr "in_call_delay" "true") (nil) (nil)])
188
189 (define_attr "eligible_for_sibcall_delay" "false,true"
190   (symbol_ref "eligible_for_sibcall_delay (insn)"))
191
192 (define_delay (eq_attr "type" "sibcall")
193   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
194
195 (define_attr "leaf_function" "false,true"
196   (const (symbol_ref "current_function_uses_only_leaf_regs")))
197
198 (define_attr "eligible_for_return_delay" "false,true"
199   (symbol_ref "eligible_for_return_delay (insn)"))
200
201 (define_attr "in_return_delay" "false,true"
202   (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
203                                (eq_attr "length" "1"))
204                           (eq_attr "leaf_function" "false"))
205                      (eq_attr "eligible_for_return_delay" "false"))
206                 (const_string "true")
207                 (const_string "false")))
208
209 (define_delay (and (eq_attr "type" "return")
210                    (eq_attr "isa" "v9"))
211   [(eq_attr "in_return_delay" "true") (nil) (nil)])
212
213 ;; ??? Should implement the notion of predelay slots for floating point
214 ;; branches.  This would allow us to remove the nop always inserted before
215 ;; a floating point branch.
216
217 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
218 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
219 ;; This is because doing so will add several pipeline stalls to the path
220 ;; that the load/store did not come from.  Unfortunately, there is no way
221 ;; to prevent fill_eager_delay_slots from using load/store without completely
222 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
223 ;; because it prevents us from moving back the final store of inner loops.
224
225 (define_attr "in_branch_delay" "false,true"
226   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
227                      (eq_attr "length" "1"))
228                 (const_string "true")
229                 (const_string "false")))
230
231 (define_attr "in_uncond_branch_delay" "false,true"
232   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
233                      (eq_attr "length" "1"))
234                 (const_string "true")
235                 (const_string "false")))
236
237 (define_attr "in_annul_branch_delay" "false,true"
238   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
239                      (eq_attr "length" "1"))
240                 (const_string "true")
241                 (const_string "false")))
242
243 (define_delay (eq_attr "type" "branch")
244   [(eq_attr "in_branch_delay" "true")
245    (nil) (eq_attr "in_annul_branch_delay" "true")])
246
247 (define_delay (eq_attr "type" "uncond_branch")
248   [(eq_attr "in_uncond_branch_delay" "true")
249    (nil) (nil)])
250    
251 ;; DFA scheduling on the SPARC
252
253 (define_automaton "cypress_0,cypress_1,supersparc_0,supersparc_1,hypersparc_0,hypersparc_1,sparclet,ultrasparc_0,ultrasparc_1,ultrasparc3_0,ultrasparc3_1")
254
255 ;; Cypress scheduling
256
257 (define_cpu_unit "cyp_memory, cyp_fpalu" "cypress_0")
258 (define_cpu_unit "cyp_fpmds" "cypress_1")
259
260 (define_insn_reservation "cyp_load" 2
261   (and (eq_attr "cpu" "cypress")
262     (eq_attr "type" "load,sload,fpload"))
263   "cyp_memory, nothing")
264
265 (define_insn_reservation "cyp_fp_alu" 5
266   (and (eq_attr "cpu" "cypress")
267     (eq_attr "type" "fp,fpmove"))
268   "cyp_fpalu, nothing*3")
269
270 (define_insn_reservation "cyp_fp_mult" 7
271   (and (eq_attr "cpu" "cypress")
272     (eq_attr "type" "fpmul"))
273   "cyp_fpmds, nothing*5")
274
275 (define_insn_reservation "cyp_fp_div" 37
276   (and (eq_attr "cpu" "cypress")
277     (eq_attr "type" "fpdivs,fpdivd"))
278   "cyp_fpmds, nothing*35")
279
280 (define_insn_reservation "cyp_fp_sqrt" 63
281   (and (eq_attr "cpu" "cypress")
282     (eq_attr "type" "fpsqrts,fpsqrtd"))
283   "cyp_fpmds, nothing*61")
284
285 ;; SuperSPARC scheduling
286
287 (define_cpu_unit "ss_memory, ss_shift, ss_iwport0, ss_iwport1" "supersparc_0")
288 (define_cpu_unit "ss_fpalu" "supersparc_0")
289 (define_cpu_unit "ss_fpmds" "supersparc_1")
290
291 (define_reservation "ss_iwport" "(ss_iwport0 | ss_iwport1)")
292
293 (define_insn_reservation "ss_iuload" 1
294   (and (eq_attr "cpu" "supersparc")
295     (eq_attr "type" "load,sload"))
296   "ss_memory")
297
298 ;; Ok, fpu loads deliver the result in zero cycles.  But we
299 ;; have to show the ss_memory reservation somehow, thus...
300 (define_insn_reservation "ss_fpload" 0
301   (and (eq_attr "cpu" "supersparc")
302     (eq_attr "type" "fpload"))
303   "ss_memory")
304
305 (define_bypass 0 "ss_fpload" "ss_fp_alu,ss_fp_mult,ss_fp_divs,ss_fp_divd,ss_fp_sqrt")
306
307 (define_insn_reservation "ss_store" 1
308   (and (eq_attr "cpu" "supersparc")
309     (eq_attr "type" "store,fpstore"))
310   "ss_memory")
311
312 (define_insn_reservation "ss_ialu_shift" 1
313   (and (eq_attr "cpu" "supersparc")
314     (eq_attr "type" "shift"))
315   "ss_shift + ss_iwport")
316
317 (define_insn_reservation "ss_ialu_any" 1
318   (and (eq_attr "cpu" "supersparc")
319     (eq_attr "type" "load,sload,store,shift,ialu"))
320   "ss_iwport")
321
322 (define_insn_reservation "ss_fp_alu" 3
323   (and (eq_attr "cpu" "supersparc")
324     (eq_attr "type" "fp,fpmove,fpcmp"))
325   "ss_fpalu, nothing*2")
326
327 (define_insn_reservation "ss_fp_mult" 3
328   (and (eq_attr "cpu" "supersparc")
329     (eq_attr "type" "fpmul"))
330   "ss_fpmds, nothing*2")
331
332 (define_insn_reservation "ss_fp_divs" 6
333   (and (eq_attr "cpu" "supersparc")
334     (eq_attr "type" "fpdivs"))
335   "ss_fpmds*4, nothing*2")
336
337 (define_insn_reservation "ss_fp_divd" 9
338   (and (eq_attr "cpu" "supersparc")
339     (eq_attr "type" "fpdivd"))
340   "ss_fpmds*7, nothing*2")
341
342 (define_insn_reservation "ss_fp_sqrt" 12
343   (and (eq_attr "cpu" "supersparc")
344     (eq_attr "type" "fpsqrts,fpsqrtd"))
345   "ss_fpmds*10, nothing*2")
346
347 (define_insn_reservation "ss_imul" 4
348   (and (eq_attr "cpu" "supersparc")
349     (eq_attr "type" "imul"))
350   "ss_fpmds*4")
351
352 ;; HyperSPARC/sparclite86x scheduling
353
354 (define_cpu_unit "hs_memory,hs_branch,hs_shift,hs_fpalu" "hypersparc_0")
355 (define_cpu_unit "hs_fpmds" "hypersparc_1")
356
357 (define_insn_reservation "hs_load" 1
358   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
359     (eq_attr "type" "load,sload,fpload"))
360   "hs_memory")
361
362 (define_insn_reservation "hs_store" 2
363   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
364     (eq_attr "type" "store,fpstore"))
365   "hs_memory, nothing")
366
367 (define_insn_reservation "hs_slbranch" 1
368   (and (eq_attr "cpu" "sparclite86x")
369     (eq_attr "type" "branch"))
370   "hs_branch")
371
372 (define_insn_reservation "hs_slshift" 1
373   (and (eq_attr "cpu" "sparclite86x")
374     (eq_attr "type" "shift"))
375   "hs_shift")
376
377 (define_insn_reservation "hs_fp_alu" 1
378   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
379     (eq_attr "type" "fp,fpmove,fpcmp"))
380   "hs_fpalu")
381
382 (define_insn_reservation "hs_fp_mult" 1
383   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
384     (eq_attr "type" "fpmul"))
385   "hs_fpmds")
386
387 (define_insn_reservation "hs_fp_divs" 8
388   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
389     (eq_attr "type" "fpdivs"))
390   "hs_fpmds*6, nothing*2")
391
392 (define_insn_reservation "hs_fp_divd" 12
393   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
394     (eq_attr "type" "fpdivd"))
395   "hs_fpmds*10, nothing*2")
396
397 (define_insn_reservation "hs_fp_sqrt" 17
398   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
399     (eq_attr "type" "fpsqrts,fpsqrtd"))
400   "hs_fpmds*15, nothing*2")
401
402 (define_insn_reservation "hs_imul" 17
403   (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
404     (eq_attr "type" "imul"))
405   "hs_fpmds*15, nothing*2")
406
407 ;; Sparclet tsc701 scheduling
408
409 (define_cpu_unit "sl_load0,sl_load1,sl_load2,sl_load3" "sparclet")
410 (define_cpu_unit "sl_store,sl_imul" "sparclet")
411
412 (define_reservation "sl_load_any" "(sl_load0 | sl_load1 | sl_load2 | sl_load3)")
413 (define_reservation "sl_load_all" "(sl_load0 + sl_load1 + sl_load2 + sl_load3)")
414
415 (define_insn_reservation "sl_ld" 3
416   (and (eq_attr "cpu" "tsc701")
417    (eq_attr "type" "load,sload"))
418   "sl_load_any, sl_load_any, sl_load_any")
419
420 (define_insn_reservation "sl_st" 3
421   (and (eq_attr "cpu" "tsc701")
422     (eq_attr "type" "store"))
423   "(sl_store+sl_load_all)*3")
424
425 (define_insn_reservation "sl_imul" 5
426   (and (eq_attr "cpu" "tsc701")
427     (eq_attr "type" "imul"))
428   "sl_imul*5")
429
430 ;; UltraSPARC-I/II scheduling
431
432 (define_cpu_unit "us1_fdivider,us1_fpm" "ultrasparc_0");
433 (define_cpu_unit "us1_fpa,us1_load_writeback" "ultrasparc_1")
434 (define_cpu_unit "us1_fps_0,us1_fps_1,us1_fpd_0,us1_fpd_1" "ultrasparc_1")
435 (define_cpu_unit "us1_slot0,us1_slot1,us1_slot2,us1_slot3" "ultrasparc_1")
436 (define_cpu_unit "us1_ieu0,us1_ieu1,us1_cti,us1_lsu" "ultrasparc_1")
437
438 (define_reservation "us1_slot012" "(us1_slot0 | us1_slot1 | us1_slot2)")
439 (define_reservation "us1_slotany" "(us1_slot0 | us1_slot1 | us1_slot2 | us1_slot3)")
440 (define_reservation "us1_single_issue" "us1_slot0 + us1_slot1 + us1_slot2 + us1_slot3")
441
442 (define_reservation "us1_fp_single" "(us1_fps_0 | us1_fps_1)")
443 (define_reservation "us1_fp_double" "(us1_fpd_0 | us1_fpd_1)")
444 ;; This is a simplified representation of the issue at hand.
445 ;; For most cases, going from one FP precision type insn to another
446 ;; just breaks up the insn group.  However for some cases, such
447 ;; a situation causes the second insn to stall 2 more cycles.
448 (exclusion_set "us1_fps_0,us1_fps_1" "us1_fpd_0,us1_fpd_1")
449
450 ;; If we have to schedule an ieu1 specific instruction and we want
451 ;; to reserve the ieu0 unit as well, we must reserve it first.  So for
452 ;; example we could not schedule this sequence:
453 ;;      COMPARE         IEU1
454 ;;      IALU            IEU0
455 ;; but we could schedule them together like this:
456 ;;      IALU            IEU0
457 ;;      COMPARE         IEU1
458 ;; This basically requires that ieu0 is reserved before ieu1 when
459 ;; it is required that both be reserved.
460 (absence_set "us1_ieu0" "us1_ieu1")
461
462 ;; This defines the slotting order.  Most IEU instructions can only
463 ;; execute in the first three slots, FPU and branches can go into
464 ;; any slot.  We represent instructions which "break the group"
465 ;; as requiring reservation of us1_slot0.
466 (absence_set "us1_slot0" "us1_slot1,us1_slot2,us1_slot3")
467 (absence_set "us1_slot1" "us1_slot2,us1_slot3")
468 (absence_set "us1_slot2" "us1_slot3")
469
470 (define_insn_reservation "us1_simple_ieuN" 1
471   (and (eq_attr "cpu" "ultrasparc")
472     (eq_attr "type" "ialu"))
473   "(us1_ieu0 | us1_ieu1) + us1_slot012")
474
475 (define_insn_reservation "us1_simple_ieu0" 1
476   (and (eq_attr "cpu" "ultrasparc")
477     (eq_attr "type" "shift"))
478   "us1_ieu0 + us1_slot012")
479
480 (define_insn_reservation "us1_simple_ieu1" 1
481   (and (eq_attr "cpu" "ultrasparc")
482     (eq_attr "type" "compare"))
483   "us1_ieu1 + us1_slot012")
484
485 (define_insn_reservation "us1_cmove" 2
486   (and (eq_attr "cpu" "ultrasparc")
487     (eq_attr "type" "cmove"))
488   "us1_single_issue, nothing")
489
490 (define_insn_reservation "us1_imul" 1
491   (and (eq_attr "cpu" "ultrasparc")
492     (eq_attr "type" "imul"))
493   "us1_single_issue")
494
495 (define_insn_reservation "us1_idiv" 1
496   (and (eq_attr "cpu" "ultrasparc")
497     (eq_attr "type" "idiv"))
498   "us1_single_issue")
499
500 ;; For loads, the "delayed return mode" behavior of the chip
501 ;; is represented using the us1_load_writeback resource.
502 (define_insn_reservation "us1_load" 2
503   (and (eq_attr "cpu" "ultrasparc")
504     (eq_attr "type" "load,fpload"))
505   "us1_lsu + us1_slot012, us1_load_writeback")
506
507 (define_insn_reservation "us1_load_signed" 3
508   (and (eq_attr "cpu" "ultrasparc")
509     (eq_attr "type" "sload"))
510   "us1_lsu + us1_slot012, nothing, us1_load_writeback")
511
512 (define_insn_reservation "us1_store" 1
513   (and (eq_attr "cpu" "ultrasparc")
514     (eq_attr "type" "store,fpstore"))
515   "us1_lsu + us1_slot012")
516
517 (define_insn_reservation "us1_branch" 1
518   (and (eq_attr "cpu" "ultrasparc")
519     (eq_attr "type" "branch"))
520   "us1_cti + us1_slotany")
521
522 (define_insn_reservation "us1_call_jmpl" 1
523   (and (eq_attr "cpu" "ultrasparc")
524     (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch"))
525   "us1_cti + us1_ieu1 + us1_slot0")
526
527 (define_insn_reservation "us1_fmov_single" 1
528   (and (and (eq_attr "cpu" "ultrasparc")
529             (eq_attr "type" "fpmove"))
530        (eq_attr "fptype" "single"))
531   "us1_fpa + us1_fp_single + us1_slotany")
532
533 (define_insn_reservation "us1_fmov_double" 1
534   (and (and (eq_attr "cpu" "ultrasparc")
535             (eq_attr "type" "fpmove"))
536        (eq_attr "fptype" "double"))
537   "us1_fpa + us1_fp_double + us1_slotany")
538
539 (define_insn_reservation "us1_fcmov_single" 2
540   (and (and (eq_attr "cpu" "ultrasparc")
541             (eq_attr "type" "fpcmove,fpcrmove"))
542        (eq_attr "fptype" "single"))
543   "us1_fpa + us1_fp_single + us1_slotany, nothing")
544
545 (define_insn_reservation "us1_fcmov_double" 2
546   (and (and (eq_attr "cpu" "ultrasparc")
547             (eq_attr "type" "fpcmove,fpcrmove"))
548        (eq_attr "fptype" "double"))
549   "us1_fpa + us1_fp_double + us1_slotany, nothing")
550
551 (define_insn_reservation "us1_faddsub_single" 4
552   (and (and (eq_attr "cpu" "ultrasparc")
553             (eq_attr "type" "fp"))
554        (eq_attr "fptype" "single"))
555   "us1_fpa + us1_fp_single + us1_slotany, nothing*3")
556
557 (define_insn_reservation "us1_faddsub_double" 4
558   (and (and (eq_attr "cpu" "ultrasparc")
559             (eq_attr "type" "fp"))
560        (eq_attr "fptype" "double"))
561   "us1_fpa + us1_fp_double + us1_slotany, nothing*3")
562
563 (define_insn_reservation "us1_fpcmp_single" 1
564   (and (and (eq_attr "cpu" "ultrasparc")
565             (eq_attr "type" "fpcmp"))
566        (eq_attr "fptype" "single"))
567   "us1_fpa + us1_fp_single + us1_slotany")
568
569 (define_insn_reservation "us1_fpcmp_double" 1
570   (and (and (eq_attr "cpu" "ultrasparc")
571             (eq_attr "type" "fpcmp"))
572        (eq_attr "fptype" "double"))
573   "us1_fpa + us1_fp_double + us1_slotany")
574
575 (define_insn_reservation "us1_fmult_single" 4
576   (and (and (eq_attr "cpu" "ultrasparc")
577             (eq_attr "type" "fpmul"))
578        (eq_attr "fptype" "single"))
579   "us1_fpm + us1_fp_single + us1_slotany, nothing*3")
580
581 (define_insn_reservation "us1_fmult_double" 4
582   (and (and (eq_attr "cpu" "ultrasparc")
583             (eq_attr "type" "fpmul"))
584        (eq_attr "fptype" "double"))
585   "us1_fpm + us1_fp_double + us1_slotany, nothing*3")
586
587 ;; This is actually in theory dangerous, because it is possible
588 ;; for the chip to prematurely dispatch the dependant instruction
589 ;; in the G stage, resulting in a 9 cycle stall.  However I have never
590 ;; been able to trigger this case myself even with hand written code,
591 ;; so it must require some rare complicated pipeline state.
592 (define_bypass 3
593    "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double"
594    "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
595
596 ;; Floating point divide and square root use the multiplier unit
597 ;; for final rounding 3 cycles before the divide/sqrt is complete.
598
599 (define_insn_reservation "us1_fdivs"
600   13
601   (and (eq_attr "cpu" "ultrasparc")
602     (eq_attr "type" "fpdivs,fpsqrts"))
603   "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*8, (us1_fpm + us1_fdivider), us1_fdivider*2"
604   )
605
606 (define_bypass
607   12
608   "us1_fdivs"
609   "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
610
611 (define_insn_reservation "us1_fdivd"
612   23
613   (and (eq_attr "cpu" "ultrasparc")
614     (eq_attr "type" "fpdivd,fpsqrtd"))
615   "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*18, (us1_fpm + us1_fdivider), us1_fdivider*2"
616   )
617 (define_bypass
618   22
619   "us1_fdivd"
620   "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double")
621
622 ;; Any store may multi issue with the insn creating the source
623 ;; data as long as that creating insn is not an FPU div/sqrt.
624 ;; We need a special guard function because this bypass does
625 ;; not apply to the address inputs of the store.
626 (define_bypass 0 "us1_simple_ieuN,us1_simple_ieu1,us1_simple_ieu0,us1_faddsub_single,us1_faddsub_double,us1_fmov_single,us1_fmov_double,us1_fcmov_single,us1_fcmov_double,us1_fmult_single,us1_fmult_double" "us1_store"
627    "ultrasparc_store_bypass_p")
628
629 ;; An integer branch may execute in the same cycle as the compare
630 ;; creating the condition codes.
631 (define_bypass 0 "us1_simple_ieu1" "us1_branch")
632
633 ;; UltraSPARC-III scheduling
634 ;;
635 ;; A much simpler beast, no silly slotting rules and both
636 ;; integer units are fully symmetric.  It does still have
637 ;; single-issue instructions though.
638
639 (define_cpu_unit "us3_a0,us3_a1,us3_ms,us3_br,us3_fpm" "ultrasparc3_0")
640 (define_cpu_unit "us3_slot0,us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1")
641 (define_cpu_unit "us3_load_writeback" "ultrasparc3_1")
642
643 (define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)")
644 (define_reservation "us3_single_issue" "us3_slot0 + us3_slot1 + us3_slot2 + us3_slot3")
645 (define_reservation "us3_ax" "(us3_a0 | us3_a1)")
646
647 (define_insn_reservation "us3_integer" 1
648   (and (eq_attr "cpu" "ultrasparc3")
649     (eq_attr "type" "ialu,shift,compare"))
650   "us3_ax + us3_slotany")
651
652 (define_insn_reservation "us3_cmove" 2
653   (and (eq_attr "cpu" "ultrasparc3")
654     (eq_attr "type" "cmove"))
655   "us3_ms + us3_br + us3_slotany, nothing")
656
657 ;; ??? Not entirely accurate.
658 ;; ??? It can run from 6 to 9 cycles.  The first cycle the MS pipe
659 ;; ??? is needed, and the instruction group is broken right after
660 ;; ??? the imul.  Then 'helper' instructions are generated to perform
661 ;; ??? each further stage of the multiplication, each such 'helper' is
662 ;; ??? single group.  So, the reservation aspect is represented accurately
663 ;; ??? here, but the variable cycles are not.
664 ;; ??? Currently I have no idea how to determine the variability, but once
665 ;; ??? known we can simply add a define_bypass or similar to model it.
666 (define_insn_reservation "us3_imul" 6
667   (and (eq_attr "cpu" "ultrasparc3")
668     (eq_attr "type" "imul"))
669   "us3_ms + us3_slotany, us3_single_issue*5")
670
671 (define_insn_reservation "us3_idiv" 71
672   (and (eq_attr "cpu" "ultrasparc3")
673     (eq_attr "type" "idiv"))
674   "us3_ms + us3_slotany, us3_single_issue*70")
675
676 ;; UltraSPARC-III has a similar load delay as UltraSPARC-I/II except
677 ;; that all loads except 32-bit/64-bit unsigned loads take the extra
678 ;; delay for sign/zero extension.
679 (define_insn_reservation "us3_2cycle_load" 2
680   (and (eq_attr "cpu" "ultrasparc3")
681     (and (eq_attr "type" "load,fpload")
682       (eq_attr "us3load_type" "2cycle")))
683   "us3_ms + us3_slotany, us3_load_writeback")
684
685 (define_insn_reservation "us3_load_delayed" 3
686   (and (eq_attr "cpu" "ultrasparc3")
687     (and (eq_attr "type" "load,sload")
688       (eq_attr "us3load_type" "3cycle")))
689   "us3_ms + us3_slotany, nothing, us3_load_writeback")
690
691 (define_insn_reservation "us3_store" 1
692   (and (eq_attr "cpu" "ultrasparc3")
693     (eq_attr "type" "store,fpstore"))
694   "us3_ms + us3_slotany")
695
696 (define_insn_reservation "us3_branch" 1
697   (and (eq_attr "cpu" "ultrasparc3")
698     (eq_attr "type" "branch"))
699   "us3_br + us3_slotany")
700
701 (define_insn_reservation "us3_call_jmpl" 1
702   (and (eq_attr "cpu" "ultrasparc3")
703     (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch"))
704   "us3_br + us3_ms + us3_slotany")
705
706 (define_insn_reservation "us3_fmov" 3
707   (and (eq_attr "cpu" "ultrasparc3")
708     (eq_attr "type" "fpmove"))
709   "us3_fpa + us3_slotany, nothing*2")
710
711 (define_insn_reservation "us3_fcmov" 3
712   (and (eq_attr "cpu" "ultrasparc3")
713     (eq_attr "type" "fpcmove"))
714   "us3_fpa + us3_br + us3_slotany, nothing*2")
715
716 (define_insn_reservation "us3_fcrmov" 3
717   (and (eq_attr "cpu" "ultrasparc3")
718     (eq_attr "type" "fpcrmove"))
719   "us3_fpa + us3_ms + us3_slotany, nothing*2")
720
721 (define_insn_reservation "us3_faddsub" 4
722   (and (eq_attr "cpu" "ultrasparc3")
723     (eq_attr "type" "fp"))
724   "us3_fpa + us3_slotany, nothing*3")
725
726 (define_insn_reservation "us3_fpcmp" 5
727   (and (eq_attr "cpu" "ultrasparc3")
728     (eq_attr "type" "fpcmp"))
729   "us3_fpa + us3_slotany, nothing*4")
730
731 (define_insn_reservation "us3_fmult" 4
732  (and (eq_attr "cpu" "ultrasparc3")
733     (eq_attr "type" "fpmul"))
734   "us3_fpm + us3_slotany, nothing*3")
735
736 (define_insn_reservation "us3_fdivs" 17
737   (and (eq_attr "cpu" "ultrasparc3")
738     (eq_attr "type" "fpdivs"))
739   "(us3_fpm + us3_slotany), us3_fpm*14, nothing*2")
740
741 (define_insn_reservation "us3_fsqrts" 20
742   (and (eq_attr "cpu" "ultrasparc3")
743     (eq_attr "type" "fpsqrts"))
744   "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2")
745
746 (define_insn_reservation "us3_fdivd" 20
747   (and (eq_attr "cpu" "ultrasparc3")
748     (eq_attr "type" "fpdivd"))
749   "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2")
750
751 (define_insn_reservation "us3_fsqrtd" 29
752   (and (eq_attr "cpu" "ultrasparc3")
753     (eq_attr "type" "fpsqrtd"))
754   "(us3_fpm + us3_slotany), us3_fpm*26, nothing*2")
755
756 ;; Any store may multi issue with the insn creating the source
757 ;; data as long as that creating insn is not an FPU div/sqrt.
758 ;; We need a special guard function because this bypass does
759 ;; not apply to the address inputs of the store.
760 (define_bypass 0 "us3_integer,us3_faddsub,us3_fmov,us3_fcmov,us3_fmult" "us3_store"
761    "ultrasparc_store_bypass_p")
762
763 ;; An integer branch may execute in the same cycle as the compare
764 ;; creating the condition codes.
765 (define_bypass 0 "us3_integer" "us3_branch")
766
767 ;; If FMOVfcc is user of FPCMP, latency is only 1 cycle.
768 (define_bypass 1 "us3_fpcmp" "us3_fcmov")
769
770 \f
771 ;; Compare instructions.
772 ;; This controls RTL generation and register allocation.
773
774 ;; We generate RTL for comparisons and branches by having the cmpxx 
775 ;; patterns store away the operands.  Then, the scc and bcc patterns
776 ;; emit RTL for both the compare and the branch.
777 ;;
778 ;; We do this because we want to generate different code for an sne and
779 ;; seq insn.  In those cases, if the second operand of the compare is not
780 ;; const0_rtx, we want to compute the xor of the two operands and test
781 ;; it against zero.
782 ;;
783 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
784 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
785 ;; insns that actually require more than one machine instruction.
786
787 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
788
789 (define_expand "cmpsi"
790   [(set (reg:CC 100)
791         (compare:CC (match_operand:SI 0 "register_operand" "")
792                     (match_operand:SI 1 "arith_operand" "")))]
793   ""
794   "
795 {
796   sparc_compare_op0 = operands[0];
797   sparc_compare_op1 = operands[1];
798   DONE;
799 }")
800
801 (define_expand "cmpdi"
802   [(set (reg:CCX 100)
803         (compare:CCX (match_operand:DI 0 "register_operand" "")
804                      (match_operand:DI 1 "arith_double_operand" "")))]
805   "TARGET_ARCH64"
806   "
807 {
808   sparc_compare_op0 = operands[0];
809   sparc_compare_op1 = operands[1];
810   DONE;
811 }")
812
813 (define_expand "cmpsf"
814   ;; The 96 here isn't ever used by anyone.
815   [(set (reg:CCFP 96)
816         (compare:CCFP (match_operand:SF 0 "register_operand" "")
817                       (match_operand:SF 1 "register_operand" "")))]
818   "TARGET_FPU"
819   "
820 {
821   sparc_compare_op0 = operands[0];
822   sparc_compare_op1 = operands[1];
823   DONE;
824 }")
825
826 (define_expand "cmpdf"
827   ;; The 96 here isn't ever used by anyone.
828   [(set (reg:CCFP 96)
829         (compare:CCFP (match_operand:DF 0 "register_operand" "")
830                       (match_operand:DF 1 "register_operand" "")))]
831   "TARGET_FPU"
832   "
833 {
834   sparc_compare_op0 = operands[0];
835   sparc_compare_op1 = operands[1];
836   DONE;
837 }")
838
839 (define_expand "cmptf"
840   ;; The 96 here isn't ever used by anyone.
841   [(set (reg:CCFP 96)
842         (compare:CCFP (match_operand:TF 0 "register_operand" "")
843                       (match_operand:TF 1 "register_operand" "")))]
844   "TARGET_FPU"
845   "
846 {
847   sparc_compare_op0 = operands[0];
848   sparc_compare_op1 = operands[1];
849   DONE;
850 }")
851
852 ;; Now the compare DEFINE_INSNs.
853
854 (define_insn "*cmpsi_insn"
855   [(set (reg:CC 100)
856         (compare:CC (match_operand:SI 0 "register_operand" "r")
857                     (match_operand:SI 1 "arith_operand" "rI")))]
858   ""
859   "cmp\\t%0, %1"
860   [(set_attr "type" "compare")])
861
862 (define_insn "*cmpdi_sp64"
863   [(set (reg:CCX 100)
864         (compare:CCX (match_operand:DI 0 "register_operand" "r")
865                      (match_operand:DI 1 "arith_double_operand" "rHI")))]
866   "TARGET_ARCH64"
867   "cmp\\t%0, %1"
868   [(set_attr "type" "compare")])
869
870 (define_insn "*cmpsf_fpe"
871   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
872         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
873                        (match_operand:SF 2 "register_operand" "f")))]
874   "TARGET_FPU"
875   "*
876 {
877   if (TARGET_V9)
878     return \"fcmpes\\t%0, %1, %2\";
879   return \"fcmpes\\t%1, %2\";
880 }"
881   [(set_attr "type" "fpcmp")])
882
883 (define_insn "*cmpdf_fpe"
884   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
885         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
886                        (match_operand:DF 2 "register_operand" "e")))]
887   "TARGET_FPU"
888   "*
889 {
890   if (TARGET_V9)
891     return \"fcmped\\t%0, %1, %2\";
892   return \"fcmped\\t%1, %2\";
893 }"
894   [(set_attr "type" "fpcmp")
895    (set_attr "fptype" "double")])
896
897 (define_insn "*cmptf_fpe"
898   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
899         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
900                        (match_operand:TF 2 "register_operand" "e")))]
901   "TARGET_FPU && TARGET_HARD_QUAD"
902   "*
903 {
904   if (TARGET_V9)
905     return \"fcmpeq\\t%0, %1, %2\";
906   return \"fcmpeq\\t%1, %2\";
907 }"
908   [(set_attr "type" "fpcmp")])
909
910 (define_insn "*cmpsf_fp"
911   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
912         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
913                       (match_operand:SF 2 "register_operand" "f")))]
914   "TARGET_FPU"
915   "*
916 {
917   if (TARGET_V9)
918     return \"fcmps\\t%0, %1, %2\";
919   return \"fcmps\\t%1, %2\";
920 }"
921   [(set_attr "type" "fpcmp")])
922
923 (define_insn "*cmpdf_fp"
924   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
925         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
926                       (match_operand:DF 2 "register_operand" "e")))]
927   "TARGET_FPU"
928   "*
929 {
930   if (TARGET_V9)
931     return \"fcmpd\\t%0, %1, %2\";
932   return \"fcmpd\\t%1, %2\";
933 }"
934   [(set_attr "type" "fpcmp")
935    (set_attr "fptype" "double")])
936
937 (define_insn "*cmptf_fp"
938   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
939         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
940                       (match_operand:TF 2 "register_operand" "e")))]
941   "TARGET_FPU && TARGET_HARD_QUAD"
942   "*
943 {
944   if (TARGET_V9)
945     return \"fcmpq\\t%0, %1, %2\";
946   return \"fcmpq\\t%1, %2\";
947 }"
948   [(set_attr "type" "fpcmp")])
949 \f
950 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
951 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
952 ;; the same code as v8 (the addx/subx method has more applications).  The
953 ;; exception to this is "reg != 0" which can be done in one instruction on v9
954 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
955 ;; branches.
956
957 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
958 ;; generate addcc/subcc instructions.
959
960 (define_expand "seqsi_special"
961   [(set (match_dup 3)
962         (xor:SI (match_operand:SI 1 "register_operand" "")
963                 (match_operand:SI 2 "register_operand" "")))
964    (parallel [(set (match_operand:SI 0 "register_operand" "")
965                    (eq:SI (match_dup 3) (const_int 0)))
966               (clobber (reg:CC 100))])]
967   ""
968   "{ operands[3] = gen_reg_rtx (SImode); }")
969
970 (define_expand "seqdi_special"
971   [(set (match_dup 3)
972         (xor:DI (match_operand:DI 1 "register_operand" "")
973                 (match_operand:DI 2 "register_operand" "")))
974    (set (match_operand:DI 0 "register_operand" "")
975         (eq:DI (match_dup 3) (const_int 0)))]
976   "TARGET_ARCH64"
977   "{ operands[3] = gen_reg_rtx (DImode); }")
978
979 (define_expand "snesi_special"
980   [(set (match_dup 3)
981         (xor:SI (match_operand:SI 1 "register_operand" "")
982                 (match_operand:SI 2 "register_operand" "")))
983    (parallel [(set (match_operand:SI 0 "register_operand" "")
984                    (ne:SI (match_dup 3) (const_int 0)))
985               (clobber (reg:CC 100))])]
986   ""
987   "{ operands[3] = gen_reg_rtx (SImode); }")
988
989 (define_expand "snedi_special"
990   [(set (match_dup 3)
991         (xor:DI (match_operand:DI 1 "register_operand" "")
992                 (match_operand:DI 2 "register_operand" "")))
993    (set (match_operand:DI 0 "register_operand" "")
994         (ne:DI (match_dup 3) (const_int 0)))]
995   "TARGET_ARCH64"
996   "{ operands[3] = gen_reg_rtx (DImode); }")
997
998 (define_expand "seqdi_special_trunc"
999   [(set (match_dup 3)
1000         (xor:DI (match_operand:DI 1 "register_operand" "")
1001                 (match_operand:DI 2 "register_operand" "")))
1002    (set (match_operand:SI 0 "register_operand" "")
1003         (eq:SI (match_dup 3) (const_int 0)))]
1004   "TARGET_ARCH64"
1005   "{ operands[3] = gen_reg_rtx (DImode); }")
1006
1007 (define_expand "snedi_special_trunc"
1008   [(set (match_dup 3)
1009         (xor:DI (match_operand:DI 1 "register_operand" "")
1010                 (match_operand:DI 2 "register_operand" "")))
1011    (set (match_operand:SI 0 "register_operand" "")
1012         (ne:SI (match_dup 3) (const_int 0)))]
1013   "TARGET_ARCH64"
1014   "{ operands[3] = gen_reg_rtx (DImode); }")
1015
1016 (define_expand "seqsi_special_extend"
1017   [(set (match_dup 3)
1018         (xor:SI (match_operand:SI 1 "register_operand" "")
1019                 (match_operand:SI 2 "register_operand" "")))
1020    (parallel [(set (match_operand:DI 0 "register_operand" "")
1021                    (eq:DI (match_dup 3) (const_int 0)))
1022               (clobber (reg:CC 100))])]
1023   "TARGET_ARCH64"
1024   "{ operands[3] = gen_reg_rtx (SImode); }")
1025
1026 (define_expand "snesi_special_extend"
1027   [(set (match_dup 3)
1028         (xor:SI (match_operand:SI 1 "register_operand" "")
1029                 (match_operand:SI 2 "register_operand" "")))
1030    (parallel [(set (match_operand:DI 0 "register_operand" "")
1031                    (ne:DI (match_dup 3) (const_int 0)))
1032               (clobber (reg:CC 100))])]
1033   "TARGET_ARCH64"
1034   "{ operands[3] = gen_reg_rtx (SImode); }")
1035
1036 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
1037 ;; However, the code handles both SImode and DImode.
1038 (define_expand "seq"
1039   [(set (match_operand:SI 0 "intreg_operand" "")
1040         (eq:SI (match_dup 1) (const_int 0)))]
1041   ""
1042   "
1043 {
1044   if (GET_MODE (sparc_compare_op0) == SImode)
1045     {
1046       rtx pat;
1047
1048       if (GET_MODE (operands[0]) == SImode)
1049         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
1050                                  sparc_compare_op1);
1051       else if (! TARGET_ARCH64)
1052         FAIL;
1053       else
1054         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
1055                                         sparc_compare_op1);
1056       emit_insn (pat);
1057       DONE;
1058     }
1059   else if (GET_MODE (sparc_compare_op0) == DImode)
1060     {
1061       rtx pat;
1062
1063       if (! TARGET_ARCH64)
1064         FAIL;
1065       else if (GET_MODE (operands[0]) == SImode)
1066         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
1067                                        sparc_compare_op1);
1068       else
1069         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
1070                                  sparc_compare_op1);
1071       emit_insn (pat);
1072       DONE;
1073     }
1074   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1075     {
1076       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1077       emit_jump_insn (gen_sne (operands[0]));
1078       DONE;
1079     }
1080   else if (TARGET_V9)
1081     {
1082       if (gen_v9_scc (EQ, operands))
1083         DONE;
1084       /* fall through */
1085     }
1086   FAIL;
1087 }")
1088
1089 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
1090 ;; However, the code handles both SImode and DImode.
1091 (define_expand "sne"
1092   [(set (match_operand:SI 0 "intreg_operand" "")
1093         (ne:SI (match_dup 1) (const_int 0)))]
1094   ""
1095   "
1096 {
1097   if (GET_MODE (sparc_compare_op0) == SImode)
1098     {
1099       rtx pat;
1100
1101       if (GET_MODE (operands[0]) == SImode)
1102         pat = gen_snesi_special (operands[0], sparc_compare_op0,
1103                                  sparc_compare_op1);
1104       else if (! TARGET_ARCH64)
1105         FAIL;
1106       else
1107         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
1108                                         sparc_compare_op1);
1109       emit_insn (pat);
1110       DONE;
1111     }
1112   else if (GET_MODE (sparc_compare_op0) == DImode)
1113     {
1114       rtx pat;
1115
1116       if (! TARGET_ARCH64)
1117         FAIL;
1118       else if (GET_MODE (operands[0]) == SImode)
1119         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
1120                                        sparc_compare_op1);
1121       else
1122         pat = gen_snedi_special (operands[0], sparc_compare_op0,
1123                                  sparc_compare_op1);
1124       emit_insn (pat);
1125       DONE;
1126     }
1127   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1128     {
1129       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1130       emit_jump_insn (gen_sne (operands[0]));
1131       DONE;
1132     }
1133   else if (TARGET_V9)
1134     {
1135       if (gen_v9_scc (NE, operands))
1136         DONE;
1137       /* fall through */
1138     }
1139   FAIL;
1140 }")
1141
1142 (define_expand "sgt"
1143   [(set (match_operand:SI 0 "intreg_operand" "")
1144         (gt:SI (match_dup 1) (const_int 0)))]
1145   ""
1146   "
1147 {
1148   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1149     {
1150       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1151       emit_jump_insn (gen_sne (operands[0]));
1152       DONE;
1153     }
1154   else if (TARGET_V9)
1155     {
1156       if (gen_v9_scc (GT, operands))
1157         DONE;
1158       /* fall through */
1159     }
1160   FAIL;
1161 }")
1162
1163 (define_expand "slt"
1164   [(set (match_operand:SI 0 "intreg_operand" "")
1165         (lt:SI (match_dup 1) (const_int 0)))]
1166   ""
1167   "
1168 {
1169   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1170     {
1171       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1172       emit_jump_insn (gen_sne (operands[0]));
1173       DONE;
1174     }
1175   else if (TARGET_V9)
1176     {
1177       if (gen_v9_scc (LT, operands))
1178         DONE;
1179       /* fall through */
1180     }
1181   FAIL;
1182 }")
1183
1184 (define_expand "sge"
1185   [(set (match_operand:SI 0 "intreg_operand" "")
1186         (ge:SI (match_dup 1) (const_int 0)))]
1187   ""
1188   "
1189 {
1190   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1191     {
1192       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1193       emit_jump_insn (gen_sne (operands[0]));
1194       DONE;
1195     }
1196   else if (TARGET_V9)
1197     {
1198       if (gen_v9_scc (GE, operands))
1199         DONE;
1200       /* fall through */
1201     }
1202   FAIL;
1203 }")
1204
1205 (define_expand "sle"
1206   [(set (match_operand:SI 0 "intreg_operand" "")
1207         (le:SI (match_dup 1) (const_int 0)))]
1208   ""
1209   "
1210 {
1211   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1212     {
1213       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1214       emit_jump_insn (gen_sne (operands[0]));
1215       DONE;
1216     }
1217   else if (TARGET_V9)
1218     {
1219       if (gen_v9_scc (LE, operands))
1220         DONE;
1221       /* fall through */
1222     }
1223   FAIL;
1224 }")
1225
1226 (define_expand "sgtu"
1227   [(set (match_operand:SI 0 "intreg_operand" "")
1228         (gtu:SI (match_dup 1) (const_int 0)))]
1229   ""
1230   "
1231 {
1232   if (! TARGET_V9)
1233     {
1234       rtx tem, pat;
1235
1236       /* We can do ltu easily, so if both operands are registers, swap them and
1237          do a LTU.  */
1238       if ((GET_CODE (sparc_compare_op0) == REG
1239            || GET_CODE (sparc_compare_op0) == SUBREG)
1240           && (GET_CODE (sparc_compare_op1) == REG
1241               || GET_CODE (sparc_compare_op1) == SUBREG))
1242         {
1243           tem = sparc_compare_op0;
1244           sparc_compare_op0 = sparc_compare_op1;
1245           sparc_compare_op1 = tem;
1246           pat = gen_sltu (operands[0]);
1247           if (pat == NULL_RTX)
1248             FAIL;
1249           emit_insn (pat);
1250           DONE;
1251         }
1252     }
1253   else
1254     {
1255       if (gen_v9_scc (GTU, operands))
1256         DONE;
1257     }
1258   FAIL;
1259 }")
1260
1261 (define_expand "sltu"
1262   [(set (match_operand:SI 0 "intreg_operand" "")
1263         (ltu:SI (match_dup 1) (const_int 0)))]
1264   ""
1265   "
1266 {
1267   if (TARGET_V9)
1268     {
1269       if (gen_v9_scc (LTU, operands))
1270         DONE;
1271     }
1272   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1273 }")
1274
1275 (define_expand "sgeu"
1276   [(set (match_operand:SI 0 "intreg_operand" "")
1277         (geu:SI (match_dup 1) (const_int 0)))]
1278   ""
1279   "
1280 {
1281   if (TARGET_V9)
1282     {
1283       if (gen_v9_scc (GEU, operands))
1284         DONE;
1285     }
1286   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1287 }")
1288
1289 (define_expand "sleu"
1290   [(set (match_operand:SI 0 "intreg_operand" "")
1291         (leu:SI (match_dup 1) (const_int 0)))]
1292   ""
1293   "
1294 {
1295   if (! TARGET_V9)
1296     {
1297       rtx tem, pat;
1298
1299       /* We can do geu easily, so if both operands are registers, swap them and
1300          do a GEU.  */
1301       if ((GET_CODE (sparc_compare_op0) == REG
1302            || GET_CODE (sparc_compare_op0) == SUBREG)
1303           && (GET_CODE (sparc_compare_op1) == REG
1304               || GET_CODE (sparc_compare_op1) == SUBREG))
1305         {
1306           tem = sparc_compare_op0;
1307           sparc_compare_op0 = sparc_compare_op1;
1308           sparc_compare_op1 = tem;
1309           pat = gen_sgeu (operands[0]);
1310           if (pat == NULL_RTX)
1311             FAIL;
1312           emit_insn (pat);
1313           DONE;
1314         }
1315     }
1316   else
1317     {
1318       if (gen_v9_scc (LEU, operands))
1319         DONE;
1320     }
1321   FAIL;
1322 }")
1323
1324 ;; Now the DEFINE_INSNs for the scc cases.
1325
1326 ;; The SEQ and SNE patterns are special because they can be done
1327 ;; without any branching and do not involve a COMPARE.  We want
1328 ;; them to always use the splitz below so the results can be
1329 ;; scheduled.
1330
1331 (define_insn "*snesi_zero"
1332   [(set (match_operand:SI 0 "register_operand" "=r")
1333         (ne:SI (match_operand:SI 1 "register_operand" "r")
1334                (const_int 0)))
1335    (clobber (reg:CC 100))]
1336   ""
1337   "#"
1338   [(set_attr "length" "2")])
1339
1340 (define_split
1341   [(set (match_operand:SI 0 "register_operand" "")
1342         (ne:SI (match_operand:SI 1 "register_operand" "")
1343                (const_int 0)))
1344    (clobber (reg:CC 100))]
1345   ""
1346   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1347                                            (const_int 0)))
1348    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1349   "")
1350
1351 (define_insn "*neg_snesi_zero"
1352   [(set (match_operand:SI 0 "register_operand" "=r")
1353         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1354                        (const_int 0))))
1355    (clobber (reg:CC 100))]
1356   ""
1357   "#"
1358   [(set_attr "length" "2")])
1359
1360 (define_split
1361   [(set (match_operand:SI 0 "register_operand" "")
1362         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1363                        (const_int 0))))
1364    (clobber (reg:CC 100))]
1365   ""
1366   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1367                                            (const_int 0)))
1368    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1369   "")
1370
1371 (define_insn "*snesi_zero_extend"
1372   [(set (match_operand:DI 0 "register_operand" "=r")
1373         (ne:DI (match_operand:SI 1 "register_operand" "r")
1374                (const_int 0)))
1375    (clobber (reg:CC 100))]
1376   "TARGET_ARCH64"
1377   "#"
1378   [(set_attr "length" "2")])
1379
1380 (define_split
1381   [(set (match_operand:DI 0 "register_operand" "")
1382         (ne:DI (match_operand:SI 1 "register_operand" "")
1383                (const_int 0)))
1384    (clobber (reg:CC 100))]
1385   "TARGET_ARCH64"
1386   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1387                                            (const_int 0)))
1388    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1389                                                         (const_int 0))
1390                                                (ltu:SI (reg:CC_NOOV 100)
1391                                                        (const_int 0)))))]
1392   "")
1393
1394 (define_insn "*snedi_zero"
1395   [(set (match_operand:DI 0 "register_operand" "=&r")
1396         (ne:DI (match_operand:DI 1 "register_operand" "r")
1397                (const_int 0)))]
1398   "TARGET_ARCH64"
1399   "#"
1400   [(set_attr "length" "2")])
1401
1402 (define_split
1403   [(set (match_operand:DI 0 "register_operand" "")
1404         (ne:DI (match_operand:DI 1 "register_operand" "")
1405                (const_int 0)))]
1406   "TARGET_ARCH64
1407    && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1408   [(set (match_dup 0) (const_int 0))
1409    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1410                                               (const_int 0))
1411                                        (const_int 1)
1412                                        (match_dup 0)))]
1413   "")
1414
1415 (define_insn "*neg_snedi_zero"
1416   [(set (match_operand:DI 0 "register_operand" "=&r")
1417         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1418                        (const_int 0))))]
1419   "TARGET_ARCH64"
1420   "#"
1421   [(set_attr "length" "2")])
1422
1423 (define_split
1424   [(set (match_operand:DI 0 "register_operand" "")
1425         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1426                        (const_int 0))))]
1427   "TARGET_ARCH64
1428    && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1429   [(set (match_dup 0) (const_int 0))
1430    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1431                                               (const_int 0))
1432                                        (const_int -1)
1433                                        (match_dup 0)))]
1434   "")
1435
1436 (define_insn "*snedi_zero_trunc"
1437   [(set (match_operand:SI 0 "register_operand" "=&r")
1438         (ne:SI (match_operand:DI 1 "register_operand" "r")
1439                (const_int 0)))]
1440   "TARGET_ARCH64"
1441   "#"
1442   [(set_attr "length" "2")])
1443
1444 (define_split
1445   [(set (match_operand:SI 0 "register_operand" "")
1446         (ne:SI (match_operand:DI 1 "register_operand" "")
1447                (const_int 0)))]
1448   "TARGET_ARCH64
1449    && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1450   [(set (match_dup 0) (const_int 0))
1451    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1452                                               (const_int 0))
1453                                        (const_int 1)
1454                                        (match_dup 0)))]
1455   "")
1456
1457 (define_insn "*seqsi_zero"
1458   [(set (match_operand:SI 0 "register_operand" "=r")
1459         (eq:SI (match_operand:SI 1 "register_operand" "r")
1460                (const_int 0)))
1461    (clobber (reg:CC 100))]
1462   ""
1463   "#"
1464   [(set_attr "length" "2")])
1465
1466 (define_split
1467   [(set (match_operand:SI 0 "register_operand" "")
1468         (eq:SI (match_operand:SI 1 "register_operand" "")
1469                (const_int 0)))
1470    (clobber (reg:CC 100))]
1471   ""
1472   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1473                                            (const_int 0)))
1474    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1475   "")
1476
1477 (define_insn "*neg_seqsi_zero"
1478   [(set (match_operand:SI 0 "register_operand" "=r")
1479         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1480                        (const_int 0))))
1481    (clobber (reg:CC 100))]
1482   ""
1483   "#"
1484   [(set_attr "length" "2")])
1485
1486 (define_split
1487   [(set (match_operand:SI 0 "register_operand" "")
1488         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1489                        (const_int 0))))
1490    (clobber (reg:CC 100))]
1491   ""
1492   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1493                                            (const_int 0)))
1494    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1495   "")
1496
1497 (define_insn "*seqsi_zero_extend"
1498   [(set (match_operand:DI 0 "register_operand" "=r")
1499         (eq:DI (match_operand:SI 1 "register_operand" "r")
1500                (const_int 0)))
1501    (clobber (reg:CC 100))]
1502   "TARGET_ARCH64"
1503   "#"
1504   [(set_attr "length" "2")])
1505
1506 (define_split
1507   [(set (match_operand:DI 0 "register_operand" "")
1508         (eq:DI (match_operand:SI 1 "register_operand" "")
1509                (const_int 0)))
1510    (clobber (reg:CC 100))]
1511   "TARGET_ARCH64"
1512   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1513                                            (const_int 0)))
1514    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1515                                                           (const_int -1))
1516                                                 (ltu:SI (reg:CC_NOOV 100)
1517                                                         (const_int 0)))))]
1518   "")
1519
1520 (define_insn "*seqdi_zero"
1521   [(set (match_operand:DI 0 "register_operand" "=&r")
1522         (eq:DI (match_operand:DI 1 "register_operand" "r")
1523                (const_int 0)))]
1524   "TARGET_ARCH64"
1525   "#"
1526   [(set_attr "length" "2")])
1527
1528 (define_split
1529   [(set (match_operand:DI 0 "register_operand" "")
1530         (eq:DI (match_operand:DI 1 "register_operand" "")
1531                (const_int 0)))]
1532   "TARGET_ARCH64
1533    && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1534   [(set (match_dup 0) (const_int 0))
1535    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1536                                               (const_int 0))
1537                                        (const_int 1)
1538                                        (match_dup 0)))]
1539   "")
1540
1541 (define_insn "*neg_seqdi_zero"
1542   [(set (match_operand:DI 0 "register_operand" "=&r")
1543         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1544                        (const_int 0))))]
1545   "TARGET_ARCH64"
1546   "#"
1547   [(set_attr "length" "2")]) 
1548
1549 (define_split
1550   [(set (match_operand:DI 0 "register_operand" "")
1551         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1552                        (const_int 0))))]
1553   "TARGET_ARCH64
1554    && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1555   [(set (match_dup 0) (const_int 0))
1556    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1557                                               (const_int 0))
1558                                        (const_int -1)
1559                                        (match_dup 0)))]
1560   "")
1561
1562 (define_insn "*seqdi_zero_trunc"
1563   [(set (match_operand:SI 0 "register_operand" "=&r")
1564         (eq:SI (match_operand:DI 1 "register_operand" "r")
1565                (const_int 0)))]
1566   "TARGET_ARCH64"
1567   "#"
1568   [(set_attr "length" "2")])
1569
1570 (define_split
1571   [(set (match_operand:SI 0 "register_operand" "")
1572         (eq:SI (match_operand:DI 1 "register_operand" "")
1573                (const_int 0)))]
1574   "TARGET_ARCH64
1575    && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1576   [(set (match_dup 0) (const_int 0))
1577    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1578                                               (const_int 0))
1579                                        (const_int 1)
1580                                        (match_dup 0)))]
1581   "")
1582
1583 ;; We can also do (x + (i == 0)) and related, so put them in.
1584 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1585 ;; versions for v9.
1586
1587 (define_insn "*x_plus_i_ne_0"
1588   [(set (match_operand:SI 0 "register_operand" "=r")
1589         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1590                         (const_int 0))
1591                  (match_operand:SI 2 "register_operand" "r")))
1592    (clobber (reg:CC 100))]
1593   ""
1594   "#"
1595   [(set_attr "length" "2")])
1596
1597 (define_split
1598   [(set (match_operand:SI 0 "register_operand" "")
1599         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1600                         (const_int 0))
1601                  (match_operand:SI 2 "register_operand" "")))
1602    (clobber (reg:CC 100))]
1603   ""
1604   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1605                                            (const_int 0)))
1606    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1607                                (match_dup 2)))]
1608   "")
1609
1610 (define_insn "*x_minus_i_ne_0"
1611   [(set (match_operand:SI 0 "register_operand" "=r")
1612         (minus:SI (match_operand:SI 2 "register_operand" "r")
1613                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1614                          (const_int 0))))
1615    (clobber (reg:CC 100))]
1616   ""
1617   "#"
1618   [(set_attr "length" "2")])
1619
1620 (define_split
1621   [(set (match_operand:SI 0 "register_operand" "")
1622         (minus:SI (match_operand:SI 2 "register_operand" "")
1623                   (ne:SI (match_operand:SI 1 "register_operand" "")
1624                          (const_int 0))))
1625    (clobber (reg:CC 100))]
1626   ""
1627   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1628                                            (const_int 0)))
1629    (set (match_dup 0) (minus:SI (match_dup 2)
1630                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1631   "")
1632
1633 (define_insn "*x_plus_i_eq_0"
1634   [(set (match_operand:SI 0 "register_operand" "=r")
1635         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1636                         (const_int 0))
1637                  (match_operand:SI 2 "register_operand" "r")))
1638    (clobber (reg:CC 100))]
1639   ""
1640   "#"
1641   [(set_attr "length" "2")])
1642
1643 (define_split
1644   [(set (match_operand:SI 0 "register_operand" "")
1645         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1646                         (const_int 0))
1647                  (match_operand:SI 2 "register_operand" "")))
1648    (clobber (reg:CC 100))]
1649   ""
1650   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1651                                            (const_int 0)))
1652    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1653                                (match_dup 2)))]
1654   "")
1655
1656 (define_insn "*x_minus_i_eq_0"
1657   [(set (match_operand:SI 0 "register_operand" "=r")
1658         (minus:SI (match_operand:SI 2 "register_operand" "r")
1659                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1660                          (const_int 0))))
1661    (clobber (reg:CC 100))]
1662   ""
1663   "#"
1664   [(set_attr "length" "2")])
1665
1666 (define_split
1667   [(set (match_operand:SI 0 "register_operand" "")
1668         (minus:SI (match_operand:SI 2 "register_operand" "")
1669                   (eq:SI (match_operand:SI 1 "register_operand" "")
1670                          (const_int 0))))
1671    (clobber (reg:CC 100))]
1672   ""
1673   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1674                                            (const_int 0)))
1675    (set (match_dup 0) (minus:SI (match_dup 2)
1676                                 (geu:SI (reg:CC 100) (const_int 0))))]
1677   "")
1678
1679 ;; We can also do GEU and LTU directly, but these operate after a compare.
1680 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1681 ;; versions for v9.
1682
1683 (define_insn "*sltu_insn"
1684   [(set (match_operand:SI 0 "register_operand" "=r")
1685         (ltu:SI (reg:CC 100) (const_int 0)))]
1686   ""
1687   "addx\\t%%g0, 0, %0"
1688   [(set_attr "type" "misc")])
1689
1690 (define_insn "*neg_sltu_insn"
1691   [(set (match_operand:SI 0 "register_operand" "=r")
1692         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1693   ""
1694   "subx\\t%%g0, 0, %0"
1695   [(set_attr "type" "misc")])
1696
1697 ;; ??? Combine should canonicalize these next two to the same pattern.
1698 (define_insn "*neg_sltu_minus_x"
1699   [(set (match_operand:SI 0 "register_operand" "=r")
1700         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1701                   (match_operand:SI 1 "arith_operand" "rI")))]
1702   ""
1703   "subx\\t%%g0, %1, %0"
1704   [(set_attr "type" "misc")])
1705
1706 (define_insn "*neg_sltu_plus_x"
1707   [(set (match_operand:SI 0 "register_operand" "=r")
1708         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1709                          (match_operand:SI 1 "arith_operand" "rI"))))]
1710   ""
1711   "subx\\t%%g0, %1, %0"
1712   [(set_attr "type" "misc")])
1713
1714 (define_insn "*sgeu_insn"
1715   [(set (match_operand:SI 0 "register_operand" "=r")
1716         (geu:SI (reg:CC 100) (const_int 0)))]
1717   ""
1718   "subx\\t%%g0, -1, %0"
1719   [(set_attr "type" "misc")])
1720
1721 (define_insn "*neg_sgeu_insn"
1722   [(set (match_operand:SI 0 "register_operand" "=r")
1723         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1724   ""
1725   "addx\\t%%g0, -1, %0"
1726   [(set_attr "type" "misc")])
1727
1728 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1729 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1730 ;; versions for v9.
1731
1732 (define_insn "*sltu_plus_x"
1733   [(set (match_operand:SI 0 "register_operand" "=r")
1734         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1735                  (match_operand:SI 1 "arith_operand" "rI")))]
1736   ""
1737   "addx\\t%%g0, %1, %0"
1738   [(set_attr "type" "misc")])
1739
1740 (define_insn "*sltu_plus_x_plus_y"
1741   [(set (match_operand:SI 0 "register_operand" "=r")
1742         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1743                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1744                           (match_operand:SI 2 "arith_operand" "rI"))))]
1745   ""
1746   "addx\\t%1, %2, %0"
1747   [(set_attr "type" "misc")])
1748
1749 (define_insn "*x_minus_sltu"
1750   [(set (match_operand:SI 0 "register_operand" "=r")
1751         (minus:SI (match_operand:SI 1 "register_operand" "r")
1752                   (ltu:SI (reg:CC 100) (const_int 0))))]
1753   ""
1754   "subx\\t%1, 0, %0"
1755   [(set_attr "type" "misc")])
1756
1757 ;; ??? Combine should canonicalize these next two to the same pattern.
1758 (define_insn "*x_minus_y_minus_sltu"
1759   [(set (match_operand:SI 0 "register_operand" "=r")
1760         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1761                             (match_operand:SI 2 "arith_operand" "rI"))
1762                   (ltu:SI (reg:CC 100) (const_int 0))))]
1763   ""
1764   "subx\\t%r1, %2, %0"
1765   [(set_attr "type" "misc")])
1766
1767 (define_insn "*x_minus_sltu_plus_y"
1768   [(set (match_operand:SI 0 "register_operand" "=r")
1769         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1770                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1771                            (match_operand:SI 2 "arith_operand" "rI"))))]
1772   ""
1773   "subx\\t%r1, %2, %0"
1774   [(set_attr "type" "misc")])
1775
1776 (define_insn "*sgeu_plus_x"
1777   [(set (match_operand:SI 0 "register_operand" "=r")
1778         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1779                  (match_operand:SI 1 "register_operand" "r")))]
1780   ""
1781   "subx\\t%1, -1, %0"
1782   [(set_attr "type" "misc")])
1783
1784 (define_insn "*x_minus_sgeu"
1785   [(set (match_operand:SI 0 "register_operand" "=r")
1786         (minus:SI (match_operand:SI 1 "register_operand" "r")
1787                   (geu:SI (reg:CC 100) (const_int 0))))]
1788   ""
1789   "addx\\t%1, -1, %0"
1790   [(set_attr "type" "misc")])
1791
1792 (define_split
1793   [(set (match_operand:SI 0 "register_operand" "")
1794         (match_operator:SI 2 "noov_compare_op"
1795                            [(match_operand 1 "icc_or_fcc_reg_operand" "")
1796                             (const_int 0)]))]
1797   ;; 32 bit LTU/GEU are better implemented using addx/subx
1798   "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1799    && (GET_MODE (operands[1]) == CCXmode
1800        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1801   [(set (match_dup 0) (const_int 0))
1802    (set (match_dup 0)
1803         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1804                          (const_int 1)
1805                          (match_dup 0)))]
1806   "")
1807
1808 \f
1809 ;; These control RTL generation for conditional jump insns
1810
1811 ;; The quad-word fp compare library routines all return nonzero to indicate
1812 ;; true, which is different from the equivalent libgcc routines, so we must
1813 ;; handle them specially here.
1814
1815 (define_expand "beq"
1816   [(set (pc)
1817         (if_then_else (eq (match_dup 1) (const_int 0))
1818                       (label_ref (match_operand 0 "" ""))
1819                       (pc)))]
1820   ""
1821   "
1822 {
1823   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1824       && GET_CODE (sparc_compare_op0) == REG
1825       && GET_MODE (sparc_compare_op0) == DImode)
1826     {
1827       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1828       DONE;
1829     }
1830   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1831     {
1832       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1833       emit_jump_insn (gen_bne (operands[0]));
1834       DONE;
1835     }
1836   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1837 }")
1838
1839 (define_expand "bne"
1840   [(set (pc)
1841         (if_then_else (ne (match_dup 1) (const_int 0))
1842                       (label_ref (match_operand 0 "" ""))
1843                       (pc)))]
1844   ""
1845   "
1846 {
1847   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1848       && GET_CODE (sparc_compare_op0) == REG
1849       && GET_MODE (sparc_compare_op0) == DImode)
1850     {
1851       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1852       DONE;
1853     }
1854   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1855     {
1856       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1857       emit_jump_insn (gen_bne (operands[0]));
1858       DONE;
1859     }
1860   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1861 }")
1862
1863 (define_expand "bgt"
1864   [(set (pc)
1865         (if_then_else (gt (match_dup 1) (const_int 0))
1866                       (label_ref (match_operand 0 "" ""))
1867                       (pc)))]
1868   ""
1869   "
1870 {
1871   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1872       && GET_CODE (sparc_compare_op0) == REG
1873       && GET_MODE (sparc_compare_op0) == DImode)
1874     {
1875       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1876       DONE;
1877     }
1878   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1879     {
1880       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1881       emit_jump_insn (gen_bne (operands[0]));
1882       DONE;
1883     }
1884   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1885 }")
1886
1887 (define_expand "bgtu"
1888   [(set (pc)
1889         (if_then_else (gtu (match_dup 1) (const_int 0))
1890                       (label_ref (match_operand 0 "" ""))
1891                       (pc)))]
1892   ""
1893   "
1894 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1895 }")
1896
1897 (define_expand "blt"
1898   [(set (pc)
1899         (if_then_else (lt (match_dup 1) (const_int 0))
1900                       (label_ref (match_operand 0 "" ""))
1901                       (pc)))]
1902   ""
1903   "
1904 {
1905   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1906       && GET_CODE (sparc_compare_op0) == REG
1907       && GET_MODE (sparc_compare_op0) == DImode)
1908     {
1909       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1910       DONE;
1911     }
1912   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1913     {
1914       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1915       emit_jump_insn (gen_bne (operands[0]));
1916       DONE;
1917     }
1918   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1919 }")
1920
1921 (define_expand "bltu"
1922   [(set (pc)
1923         (if_then_else (ltu (match_dup 1) (const_int 0))
1924                       (label_ref (match_operand 0 "" ""))
1925                       (pc)))]
1926   ""
1927   "
1928 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1929 }")
1930
1931 (define_expand "bge"
1932   [(set (pc)
1933         (if_then_else (ge (match_dup 1) (const_int 0))
1934                       (label_ref (match_operand 0 "" ""))
1935                       (pc)))]
1936   ""
1937   "
1938 {
1939   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1940       && GET_CODE (sparc_compare_op0) == REG
1941       && GET_MODE (sparc_compare_op0) == DImode)
1942     {
1943       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1944       DONE;
1945     }
1946   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1947     {
1948       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1949       emit_jump_insn (gen_bne (operands[0]));
1950       DONE;
1951     }
1952   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1953 }")
1954
1955 (define_expand "bgeu"
1956   [(set (pc)
1957         (if_then_else (geu (match_dup 1) (const_int 0))
1958                       (label_ref (match_operand 0 "" ""))
1959                       (pc)))]
1960   ""
1961   "
1962 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1963 }")
1964
1965 (define_expand "ble"
1966   [(set (pc)
1967         (if_then_else (le (match_dup 1) (const_int 0))
1968                       (label_ref (match_operand 0 "" ""))
1969                       (pc)))]
1970   ""
1971   "
1972 {
1973   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1974       && GET_CODE (sparc_compare_op0) == REG
1975       && GET_MODE (sparc_compare_op0) == DImode)
1976     {
1977       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1978       DONE;
1979     }
1980   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1981     {
1982       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1983       emit_jump_insn (gen_bne (operands[0]));
1984       DONE;
1985     }
1986   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1987 }")
1988
1989 (define_expand "bleu"
1990   [(set (pc)
1991         (if_then_else (leu (match_dup 1) (const_int 0))
1992                       (label_ref (match_operand 0 "" ""))
1993                       (pc)))]
1994   ""
1995   "
1996 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1997 }")
1998
1999 (define_expand "bunordered"
2000   [(set (pc)
2001         (if_then_else (unordered (match_dup 1) (const_int 0))
2002                       (label_ref (match_operand 0 "" ""))
2003                       (pc)))]
2004   ""
2005   "
2006 {
2007   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2008     {
2009       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
2010                                 UNORDERED);
2011       emit_jump_insn (gen_beq (operands[0]));
2012       DONE;
2013     }
2014   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
2015                                  sparc_compare_op1);
2016 }")
2017
2018 (define_expand "bordered"
2019   [(set (pc)
2020         (if_then_else (ordered (match_dup 1) (const_int 0))
2021                       (label_ref (match_operand 0 "" ""))
2022                       (pc)))]
2023   ""
2024   "
2025 {
2026   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2027     {
2028       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
2029       emit_jump_insn (gen_bne (operands[0]));
2030       DONE;
2031     }
2032   operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
2033                                  sparc_compare_op1);
2034 }")
2035
2036 (define_expand "bungt"
2037   [(set (pc)
2038         (if_then_else (ungt (match_dup 1) (const_int 0))
2039                       (label_ref (match_operand 0 "" ""))
2040                       (pc)))]
2041   ""
2042   "
2043 {
2044   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2045     {
2046       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
2047       emit_jump_insn (gen_bgt (operands[0]));
2048       DONE;
2049     }
2050   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
2051 }")
2052
2053 (define_expand "bunlt"
2054   [(set (pc)
2055         (if_then_else (unlt (match_dup 1) (const_int 0))
2056                       (label_ref (match_operand 0 "" ""))
2057                       (pc)))]
2058   ""
2059   "
2060 {
2061   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2062     {
2063       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
2064       emit_jump_insn (gen_bne (operands[0]));
2065       DONE;
2066     }
2067   operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
2068 }")
2069
2070 (define_expand "buneq"
2071   [(set (pc)
2072         (if_then_else (uneq (match_dup 1) (const_int 0))
2073                       (label_ref (match_operand 0 "" ""))
2074                       (pc)))]
2075   ""
2076   "
2077 {
2078   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2079     {
2080       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
2081       emit_jump_insn (gen_beq (operands[0]));
2082       DONE;
2083     }
2084   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
2085 }")
2086
2087 (define_expand "bunge"
2088   [(set (pc)
2089         (if_then_else (unge (match_dup 1) (const_int 0))
2090                       (label_ref (match_operand 0 "" ""))
2091                       (pc)))]
2092   ""
2093   "
2094 {
2095   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2096     {
2097       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
2098       emit_jump_insn (gen_bne (operands[0]));
2099       DONE;
2100     }
2101   operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
2102 }")
2103
2104 (define_expand "bunle"
2105   [(set (pc)
2106         (if_then_else (unle (match_dup 1) (const_int 0))
2107                       (label_ref (match_operand 0 "" ""))
2108                       (pc)))]
2109   ""
2110   "
2111 {
2112   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2113     {
2114       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
2115       emit_jump_insn (gen_bne (operands[0]));
2116       DONE;
2117     }
2118   operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
2119 }")
2120
2121 (define_expand "bltgt"
2122   [(set (pc)
2123         (if_then_else (ltgt (match_dup 1) (const_int 0))
2124                       (label_ref (match_operand 0 "" ""))
2125                       (pc)))]
2126   ""
2127   "
2128 {
2129   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
2130     {
2131       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
2132       emit_jump_insn (gen_bne (operands[0]));
2133       DONE;
2134     }
2135   operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
2136 }")
2137 \f
2138 ;; Now match both normal and inverted jump.
2139
2140 ;; XXX fpcmp nop braindamage
2141 (define_insn "*normal_branch"
2142   [(set (pc)
2143         (if_then_else (match_operator 0 "noov_compare_op"
2144                                       [(reg 100) (const_int 0)])
2145                       (label_ref (match_operand 1 "" ""))
2146                       (pc)))]
2147   ""
2148   "*
2149 {
2150   return output_cbranch (operands[0], operands[1], 1, 0,
2151                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2152                          ! final_sequence, insn);
2153 }"
2154   [(set_attr "type" "branch")
2155    (set_attr "branch_type" "icc")])
2156
2157 ;; XXX fpcmp nop braindamage
2158 (define_insn "*inverted_branch"
2159   [(set (pc)
2160         (if_then_else (match_operator 0 "noov_compare_op"
2161                                       [(reg 100) (const_int 0)])
2162                       (pc)
2163                       (label_ref (match_operand 1 "" ""))))]
2164   ""
2165   "*
2166 {
2167   return output_cbranch (operands[0], operands[1], 1, 1,
2168                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2169                          ! final_sequence, insn);
2170 }"
2171   [(set_attr "type" "branch")
2172    (set_attr "branch_type" "icc")])
2173
2174 ;; XXX fpcmp nop braindamage
2175 (define_insn "*normal_fp_branch"
2176   [(set (pc)
2177         (if_then_else (match_operator 1 "comparison_operator"
2178                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2179                                        (const_int 0)])
2180                       (label_ref (match_operand 2 "" ""))
2181                       (pc)))]
2182   ""
2183   "*
2184 {
2185   return output_cbranch (operands[1], operands[2], 2, 0,
2186                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2187                          ! final_sequence, insn);
2188 }"
2189   [(set_attr "type" "branch")
2190    (set_attr "branch_type" "fcc")])
2191
2192 ;; XXX fpcmp nop braindamage
2193 (define_insn "*inverted_fp_branch"
2194   [(set (pc)
2195         (if_then_else (match_operator 1 "comparison_operator"
2196                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2197                                        (const_int 0)])
2198                       (pc)
2199                       (label_ref (match_operand 2 "" ""))))]
2200   ""
2201   "*
2202 {
2203   return output_cbranch (operands[1], operands[2], 2, 1,
2204                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2205                          ! final_sequence, insn);
2206 }"
2207   [(set_attr "type" "branch")
2208    (set_attr "branch_type" "fcc")])
2209
2210 ;; XXX fpcmp nop braindamage
2211 (define_insn "*normal_fpe_branch"
2212   [(set (pc)
2213         (if_then_else (match_operator 1 "comparison_operator"
2214                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2215                                        (const_int 0)])
2216                       (label_ref (match_operand 2 "" ""))
2217                       (pc)))]
2218   ""
2219   "*
2220 {
2221   return output_cbranch (operands[1], operands[2], 2, 0,
2222                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2223                          ! final_sequence, insn);
2224 }"
2225   [(set_attr "type" "branch")
2226    (set_attr "branch_type" "fcc")])
2227
2228 ;; XXX fpcmp nop braindamage
2229 (define_insn "*inverted_fpe_branch"
2230   [(set (pc)
2231         (if_then_else (match_operator 1 "comparison_operator"
2232                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2233                                        (const_int 0)])
2234                       (pc)
2235                       (label_ref (match_operand 2 "" ""))))]
2236   ""
2237   "*
2238 {
2239   return output_cbranch (operands[1], operands[2], 2, 1,
2240                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2241                          ! final_sequence, insn);
2242 }"
2243   [(set_attr "type" "branch")
2244    (set_attr "branch_type" "fcc")])
2245
2246 ;; Sparc V9-specific jump insns.  None of these are guaranteed to be
2247 ;; in the architecture.
2248
2249 ;; There are no 32 bit brreg insns.
2250
2251 ;; XXX
2252 (define_insn "*normal_int_branch_sp64"
2253   [(set (pc)
2254         (if_then_else (match_operator 0 "v9_regcmp_op"
2255                                       [(match_operand:DI 1 "register_operand" "r")
2256                                        (const_int 0)])
2257                       (label_ref (match_operand 2 "" ""))
2258                       (pc)))]
2259   "TARGET_ARCH64"
2260   "*
2261 {
2262   return output_v9branch (operands[0], operands[2], 1, 2, 0,
2263                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2264                           ! final_sequence, insn);
2265 }"
2266   [(set_attr "type" "branch")
2267    (set_attr "branch_type" "reg")])
2268
2269 ;; XXX
2270 (define_insn "*inverted_int_branch_sp64"
2271   [(set (pc)
2272         (if_then_else (match_operator 0 "v9_regcmp_op"
2273                                       [(match_operand:DI 1 "register_operand" "r")
2274                                        (const_int 0)])
2275                       (pc)
2276                       (label_ref (match_operand 2 "" ""))))]
2277   "TARGET_ARCH64"
2278   "*
2279 {
2280   return output_v9branch (operands[0], operands[2], 1, 2, 1,
2281                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2282                           ! final_sequence, insn);
2283 }"
2284   [(set_attr "type" "branch")
2285    (set_attr "branch_type" "reg")])
2286 \f
2287 ;; Load program counter insns.
2288
2289 (define_insn "get_pc"
2290   [(clobber (reg:SI 15))
2291    (set (match_operand 0 "register_operand" "=r")
2292         (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2293   "flag_pic && REGNO (operands[0]) == 23"
2294   "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2295   [(set_attr "type" "multi")
2296    (set_attr "length" "3")])
2297
2298 ;; Currently unused...
2299 ;; (define_insn "get_pc_via_rdpc"
2300 ;;   [(set (match_operand 0 "register_operand" "=r") (pc))]
2301 ;;   "TARGET_V9"
2302 ;;   "rd\\t%%pc, %0"
2303 ;;   [(set_attr "type" "misc")])
2304
2305 \f
2306 ;; Move instructions
2307
2308 (define_expand "movqi"
2309   [(set (match_operand:QI 0 "general_operand" "")
2310         (match_operand:QI 1 "general_operand" ""))]
2311   ""
2312   "
2313 {
2314   /* Working with CONST_INTs is easier, so convert
2315      a double if needed.  */
2316   if (GET_CODE (operands[1]) == CONST_DOUBLE)
2317     {
2318       operands[1] = GEN_INT (trunc_int_for_mode
2319                              (CONST_DOUBLE_LOW (operands[1]), QImode));
2320     }
2321
2322   /* Handle sets of MEM first.  */
2323   if (GET_CODE (operands[0]) == MEM)
2324     {
2325       if (reg_or_0_operand (operands[1], QImode))
2326         goto movqi_is_ok;
2327
2328       if (! reload_in_progress)
2329         {
2330           operands[0] = validize_mem (operands[0]);
2331           operands[1] = force_reg (QImode, operands[1]);
2332         }
2333     }
2334
2335   /* Fixup PIC cases.  */
2336   if (flag_pic)
2337     {
2338       if (CONSTANT_P (operands[1])
2339           && pic_address_needs_scratch (operands[1]))
2340         operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2341
2342       if (symbolic_operand (operands[1], QImode))
2343         {
2344           operands[1] = legitimize_pic_address (operands[1],
2345                                                 QImode,
2346                                                 (reload_in_progress ?
2347                                                  operands[0] :
2348                                                  NULL_RTX));
2349           goto movqi_is_ok;
2350         }
2351     }
2352
2353   /* All QI constants require only one insn, so proceed.  */
2354
2355  movqi_is_ok:
2356   ;
2357 }")
2358
2359 (define_insn "*movqi_insn"
2360   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2361         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
2362   "(register_operand (operands[0], QImode)
2363     || reg_or_0_operand (operands[1], QImode))"
2364   "@
2365    mov\\t%1, %0
2366    ldub\\t%1, %0
2367    stb\\t%r1, %0"
2368   [(set_attr "type" "*,load,store")
2369    (set_attr "us3load_type" "*,3cycle,*")])
2370
2371 (define_expand "movhi"
2372   [(set (match_operand:HI 0 "general_operand" "")
2373         (match_operand:HI 1 "general_operand" ""))]
2374   ""
2375   "
2376 {
2377   /* Working with CONST_INTs is easier, so convert
2378      a double if needed.  */
2379   if (GET_CODE (operands[1]) == CONST_DOUBLE)
2380     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2381
2382   /* Handle sets of MEM first.  */
2383   if (GET_CODE (operands[0]) == MEM)
2384     {
2385       if (reg_or_0_operand (operands[1], HImode))
2386         goto movhi_is_ok;
2387
2388       if (! reload_in_progress)
2389         {
2390           operands[0] = validize_mem (operands[0]);
2391           operands[1] = force_reg (HImode, operands[1]);
2392         }
2393     }
2394
2395   /* Fixup PIC cases.  */
2396   if (flag_pic)
2397     {
2398       if (CONSTANT_P (operands[1])
2399           && pic_address_needs_scratch (operands[1]))
2400         operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2401
2402       if (symbolic_operand (operands[1], HImode))
2403         {
2404           operands[1] = legitimize_pic_address (operands[1],
2405                                                 HImode,
2406                                                 (reload_in_progress ?
2407                                                  operands[0] :
2408                                                  NULL_RTX));
2409           goto movhi_is_ok;
2410         }
2411     }
2412
2413   /* This makes sure we will not get rematched due to splittage.  */
2414   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2415     ;
2416   else if (CONSTANT_P (operands[1])
2417            && GET_CODE (operands[1]) != HIGH
2418            && GET_CODE (operands[1]) != LO_SUM)
2419     {
2420       sparc_emit_set_const32 (operands[0], operands[1]);
2421       DONE;
2422     }
2423  movhi_is_ok:
2424   ;
2425 }")
2426
2427 (define_insn "*movhi_const64_special"
2428   [(set (match_operand:HI 0 "register_operand" "=r")
2429         (match_operand:HI 1 "const64_high_operand" ""))]
2430   "TARGET_ARCH64"
2431   "sethi\\t%%hi(%a1), %0")
2432
2433 (define_insn "*movhi_insn"
2434   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2435         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
2436   "(register_operand (operands[0], HImode)
2437     || reg_or_0_operand (operands[1], HImode))"
2438   "@
2439    mov\\t%1, %0
2440    sethi\\t%%hi(%a1), %0
2441    lduh\\t%1, %0
2442    sth\\t%r1, %0"
2443   [(set_attr "type" "*,*,load,store")
2444    (set_attr "us3load_type" "*,*,3cycle,*")])
2445
2446 ;; We always work with constants here.
2447 (define_insn "*movhi_lo_sum"
2448   [(set (match_operand:HI 0 "register_operand" "=r")
2449         (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2450                 (match_operand:HI 2 "arith_operand" "I")))]
2451   ""
2452   "or\\t%1, %2, %0")
2453
2454 (define_expand "movsi"
2455   [(set (match_operand:SI 0 "general_operand" "")
2456         (match_operand:SI 1 "general_operand" ""))]
2457   ""
2458   "
2459 {
2460   /* Working with CONST_INTs is easier, so convert
2461      a double if needed.  */
2462   if (GET_CODE (operands[1]) == CONST_DOUBLE)
2463     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2464
2465   /* Handle sets of MEM first.  */
2466   if (GET_CODE (operands[0]) == MEM)
2467     {
2468       if (reg_or_0_operand (operands[1], SImode))
2469         goto movsi_is_ok;
2470
2471       if (! reload_in_progress)
2472         {
2473           operands[0] = validize_mem (operands[0]);
2474           operands[1] = force_reg (SImode, operands[1]);
2475         }
2476     }
2477
2478   /* Fixup PIC cases.  */
2479   if (flag_pic)
2480     {
2481       if (CONSTANT_P (operands[1])
2482           && pic_address_needs_scratch (operands[1]))
2483         operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2484
2485       if (GET_CODE (operands[1]) == LABEL_REF)
2486         {
2487           /* shit */
2488           emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2489           DONE;
2490         }
2491
2492       if (symbolic_operand (operands[1], SImode))
2493         {
2494           operands[1] = legitimize_pic_address (operands[1],
2495                                                 SImode,
2496                                                 (reload_in_progress ?
2497                                                  operands[0] :
2498                                                  NULL_RTX));
2499           goto movsi_is_ok;
2500         }
2501     }
2502
2503   /* If we are trying to toss an integer constant into the
2504      FPU registers, force it into memory.  */
2505   if (GET_CODE (operands[0]) == REG
2506       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2507       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2508       && CONSTANT_P (operands[1]))
2509     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2510                                                  operands[1]));
2511
2512   /* This makes sure we will not get rematched due to splittage.  */
2513   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2514     ;
2515   else if (CONSTANT_P (operands[1])
2516            && GET_CODE (operands[1]) != HIGH
2517            && GET_CODE (operands[1]) != LO_SUM)
2518     {
2519       sparc_emit_set_const32 (operands[0], operands[1]);
2520       DONE;
2521     }
2522  movsi_is_ok:
2523   ;
2524 }")
2525
2526 ;; This is needed to show CSE exactly which bits are set
2527 ;; in a 64-bit register by sethi instructions.
2528 (define_insn "*movsi_const64_special"
2529   [(set (match_operand:SI 0 "register_operand" "=r")
2530         (match_operand:SI 1 "const64_high_operand" ""))]
2531   "TARGET_ARCH64"
2532   "sethi\\t%%hi(%a1), %0")
2533
2534 (define_insn "*movsi_insn"
2535   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2536         (match_operand:SI 1 "input_operand"   "rI,!f,K,J,m,!m,rJ,!f,J"))]
2537   "(register_operand (operands[0], SImode)
2538     || reg_or_0_operand (operands[1], SImode))"
2539   "@
2540    mov\\t%1, %0
2541    fmovs\\t%1, %0
2542    sethi\\t%%hi(%a1), %0
2543    clr\\t%0
2544    ld\\t%1, %0
2545    ld\\t%1, %0
2546    st\\t%r1, %0
2547    st\\t%1, %0
2548    fzeros\\t%0"
2549   [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2550
2551 (define_insn "*movsi_lo_sum"
2552   [(set (match_operand:SI 0 "register_operand" "=r")
2553         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2554                    (match_operand:SI 2 "immediate_operand" "in")))]
2555   ""
2556   "or\\t%1, %%lo(%a2), %0")
2557
2558 (define_insn "*movsi_high"
2559   [(set (match_operand:SI 0 "register_operand" "=r")
2560         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2561   ""
2562   "sethi\\t%%hi(%a1), %0")
2563
2564 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2565 ;; so that CSE won't optimize the address computation away.
2566 (define_insn "movsi_lo_sum_pic"
2567   [(set (match_operand:SI 0 "register_operand" "=r")
2568         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2569                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2570   "flag_pic"
2571   "or\\t%1, %%lo(%a2), %0")
2572
2573 (define_insn "movsi_high_pic"
2574   [(set (match_operand:SI 0 "register_operand" "=r")
2575         (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2576   "flag_pic && check_pic (1)"
2577   "sethi\\t%%hi(%a1), %0")
2578
2579 (define_expand "movsi_pic_label_ref"
2580   [(set (match_dup 3) (high:SI
2581      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2582                  (match_dup 2)] 5)))
2583    (set (match_dup 4) (lo_sum:SI (match_dup 3)
2584      (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2585    (set (match_operand:SI 0 "register_operand" "=r")
2586         (minus:SI (match_dup 5) (match_dup 4)))]
2587   "flag_pic"
2588   "
2589 {
2590   current_function_uses_pic_offset_table = 1;
2591   operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2592   if (no_new_pseudos)
2593     {
2594       operands[3] = operands[0];
2595       operands[4] = operands[0];
2596     }
2597   else
2598     {
2599       operands[3] = gen_reg_rtx (SImode);
2600       operands[4] = gen_reg_rtx (SImode);
2601     }
2602   operands[5] = pic_offset_table_rtx;
2603 }")
2604
2605 (define_insn "*movsi_high_pic_label_ref"
2606   [(set (match_operand:SI 0 "register_operand" "=r")
2607       (high:SI
2608         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2609                     (match_operand:SI 2 "" "")] 5)))]
2610   "flag_pic"
2611   "sethi\\t%%hi(%a2-(%a1-.)), %0")
2612
2613 (define_insn "*movsi_lo_sum_pic_label_ref"
2614   [(set (match_operand:SI 0 "register_operand" "=r")
2615       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2616         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2617                     (match_operand:SI 3 "" "")] 5)))]
2618   "flag_pic"
2619   "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2620
2621 (define_expand "movdi"
2622   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2623         (match_operand:DI 1 "general_operand" ""))]
2624   ""
2625   "
2626 {
2627   /* Where possible, convert CONST_DOUBLE into a CONST_INT.  */
2628   if (GET_CODE (operands[1]) == CONST_DOUBLE
2629 #if HOST_BITS_PER_WIDE_INT == 32
2630       && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2631            && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2632           || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2633               && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2634 #endif
2635       )
2636     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2637
2638   /* Handle MEM cases first.  */
2639   if (GET_CODE (operands[0]) == MEM)
2640     {
2641       /* If it's a REG, we can always do it.
2642          The const zero case is more complex, on v9
2643          we can always perform it.  */
2644       if (register_operand (operands[1], DImode)
2645           || (TARGET_V9
2646               && (operands[1] == const0_rtx)))
2647         goto movdi_is_ok;
2648
2649       if (! reload_in_progress)
2650         {
2651           operands[0] = validize_mem (operands[0]);
2652           operands[1] = force_reg (DImode, operands[1]);
2653         }
2654     }
2655
2656   if (flag_pic)
2657     {
2658       if (CONSTANT_P (operands[1])
2659           && pic_address_needs_scratch (operands[1]))
2660         operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2661
2662       if (GET_CODE (operands[1]) == LABEL_REF)
2663         {
2664           if (! TARGET_ARCH64)
2665             abort ();
2666           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2667           DONE;
2668         }
2669
2670       if (symbolic_operand (operands[1], DImode))
2671         {
2672           operands[1] = legitimize_pic_address (operands[1],
2673                                                 DImode,
2674                                                 (reload_in_progress ?
2675                                                  operands[0] :
2676                                                  NULL_RTX));
2677           goto movdi_is_ok;
2678         }
2679     }
2680
2681   /* If we are trying to toss an integer constant into the
2682      FPU registers, force it into memory.  */
2683   if (GET_CODE (operands[0]) == REG
2684       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2685       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2686       && CONSTANT_P (operands[1]))
2687     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2688                                                  operands[1]));
2689
2690   /* This makes sure we will not get rematched due to splittage.  */
2691   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2692     ;
2693   else if (TARGET_ARCH64
2694            && CONSTANT_P (operands[1])
2695            && GET_CODE (operands[1]) != HIGH
2696            && GET_CODE (operands[1]) != LO_SUM)
2697     {
2698       sparc_emit_set_const64 (operands[0], operands[1]);
2699       DONE;
2700     }
2701
2702  movdi_is_ok:
2703   ;
2704 }")
2705
2706 ;; Be careful, fmovd does not exist when !arch64.
2707 ;; We match MEM moves directly when we have correct even
2708 ;; numbered registers, but fall into splits otherwise.
2709 ;; The constraint ordering here is really important to
2710 ;; avoid insane problems in reload, especially for patterns
2711 ;; of the form:
2712 ;;
2713 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2714 ;;                       (const_int -5016)))
2715 ;;      (reg:DI 2 %g2))
2716 ;;
2717
2718 (define_insn "*movdi_insn_sp32_v9"
2719   [(set (match_operand:DI 0 "nonimmediate_operand"
2720                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2721         (match_operand:DI 1 "input_operand"
2722                                         " J,J,U,T,r,o,i,r, f, T, o, f, f"))]
2723   "! TARGET_ARCH64 && TARGET_V9
2724    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2725   "@
2726    stx\\t%%g0, %0
2727    #
2728    std\\t%1, %0
2729    ldd\\t%1, %0
2730    #
2731    #
2732    #
2733    #
2734    std\\t%1, %0
2735    ldd\\t%1, %0
2736    #
2737    #
2738    #"
2739   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2740    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2741
2742 (define_insn "*movdi_insn_sp32"
2743   [(set (match_operand:DI 0 "nonimmediate_operand"
2744                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2745         (match_operand:DI 1 "input_operand"
2746                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2747   "! TARGET_ARCH64
2748    && (register_operand (operands[0], DImode)
2749        || register_operand (operands[1], DImode))"
2750   "@
2751    #
2752    std\\t%1, %0
2753    ldd\\t%1, %0
2754    #
2755    #
2756    #
2757    #
2758    std\\t%1, %0
2759    ldd\\t%1, %0
2760    #
2761    #
2762    #"
2763   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2764    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2765
2766 ;; The following are generated by sparc_emit_set_const64
2767 (define_insn "*movdi_sp64_dbl"
2768   [(set (match_operand:DI 0 "register_operand" "=r")
2769         (match_operand:DI 1 "const64_operand" ""))]
2770   "(TARGET_ARCH64
2771     && HOST_BITS_PER_WIDE_INT != 64)"
2772   "mov\\t%1, %0")
2773
2774 ;; This is needed to show CSE exactly which bits are set
2775 ;; in a 64-bit register by sethi instructions.
2776 (define_insn "*movdi_const64_special"
2777   [(set (match_operand:DI 0 "register_operand" "=r")
2778         (match_operand:DI 1 "const64_high_operand" ""))]
2779   "TARGET_ARCH64"
2780   "sethi\\t%%hi(%a1), %0")
2781
2782 (define_insn "*movdi_insn_sp64_novis"
2783   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2784         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e"))]
2785   "TARGET_ARCH64 && ! TARGET_VIS
2786    && (register_operand (operands[0], DImode)
2787        || reg_or_0_operand (operands[1], DImode))"
2788   "@
2789    mov\\t%1, %0
2790    sethi\\t%%hi(%a1), %0
2791    clr\\t%0
2792    ldx\\t%1, %0
2793    stx\\t%r1, %0
2794    fmovd\\t%1, %0
2795    ldd\\t%1, %0
2796    std\\t%1, %0"
2797   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2798    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2799
2800 (define_insn "*movdi_insn_sp64_vis"
2801   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2802         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
2803   "TARGET_ARCH64 && TARGET_VIS &&
2804    (register_operand (operands[0], DImode)
2805     || reg_or_0_operand (operands[1], DImode))"
2806   "@
2807    mov\\t%1, %0
2808    sethi\\t%%hi(%a1), %0
2809    clr\\t%0
2810    ldx\\t%1, %0
2811    stx\\t%r1, %0
2812    fmovd\\t%1, %0
2813    ldd\\t%1, %0
2814    std\\t%1, %0
2815    fzero\\t%0"
2816   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2817    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2818
2819 (define_expand "movdi_pic_label_ref"
2820   [(set (match_dup 3) (high:DI
2821      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2822                  (match_dup 2)] 5)))
2823    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2824      (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2825    (set (match_operand:DI 0 "register_operand" "=r")
2826         (minus:DI (match_dup 5) (match_dup 4)))]
2827   "TARGET_ARCH64 && flag_pic"
2828   "
2829 {
2830   current_function_uses_pic_offset_table = 1;
2831   operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2832   if (no_new_pseudos)
2833     {
2834       operands[3] = operands[0];
2835       operands[4] = operands[0];
2836     }
2837   else
2838     {
2839       operands[3] = gen_reg_rtx (DImode);
2840       operands[4] = gen_reg_rtx (DImode);
2841     }
2842   operands[5] = pic_offset_table_rtx;
2843 }")
2844
2845 (define_insn "*movdi_high_pic_label_ref"
2846   [(set (match_operand:DI 0 "register_operand" "=r")
2847         (high:DI
2848           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2849                       (match_operand:DI 2 "" "")] 5)))]
2850   "TARGET_ARCH64 && flag_pic"
2851   "sethi\\t%%hi(%a2-(%a1-.)), %0")
2852
2853 (define_insn "*movdi_lo_sum_pic_label_ref"
2854   [(set (match_operand:DI 0 "register_operand" "=r")
2855       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2856         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2857                     (match_operand:DI 3 "" "")] 5)))]
2858   "TARGET_ARCH64 && flag_pic"
2859   "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2860
2861 ;; Sparc-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2862 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2863
2864 (define_insn "movdi_lo_sum_pic"
2865   [(set (match_operand:DI 0 "register_operand" "=r")
2866         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2867                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2868   "TARGET_ARCH64 && flag_pic"
2869   "or\\t%1, %%lo(%a2), %0")
2870
2871 (define_insn "movdi_high_pic"
2872   [(set (match_operand:DI 0 "register_operand" "=r")
2873         (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2874   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2875   "sethi\\t%%hi(%a1), %0")
2876
2877 (define_insn "*sethi_di_medlow_embmedany_pic"
2878   [(set (match_operand:DI 0 "register_operand" "=r")
2879         (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2880   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2881   "sethi\\t%%hi(%a1), %0")
2882
2883 (define_insn "*sethi_di_medlow"
2884   [(set (match_operand:DI 0 "register_operand" "=r")
2885         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2886   "TARGET_CM_MEDLOW && check_pic (1)"
2887   "sethi\\t%%hi(%a1), %0")
2888
2889 (define_insn "*losum_di_medlow"
2890   [(set (match_operand:DI 0 "register_operand" "=r")
2891         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2892                    (match_operand:DI 2 "symbolic_operand" "")))]
2893   "TARGET_CM_MEDLOW"
2894   "or\\t%1, %%lo(%a2), %0")
2895
2896 (define_insn "seth44"
2897   [(set (match_operand:DI 0 "register_operand" "=r")
2898         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2899   "TARGET_CM_MEDMID"
2900   "sethi\\t%%h44(%a1), %0")
2901
2902 (define_insn "setm44"
2903   [(set (match_operand:DI 0 "register_operand" "=r")
2904         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2905                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2906   "TARGET_CM_MEDMID"
2907   "or\\t%1, %%m44(%a2), %0")
2908
2909 (define_insn "setl44"
2910   [(set (match_operand:DI 0 "register_operand" "=r")
2911         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2912                    (match_operand:DI 2 "symbolic_operand" "")))]
2913   "TARGET_CM_MEDMID"
2914   "or\\t%1, %%l44(%a2), %0")
2915
2916 (define_insn "sethh"
2917   [(set (match_operand:DI 0 "register_operand" "=r")
2918         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2919   "TARGET_CM_MEDANY"
2920   "sethi\\t%%hh(%a1), %0")
2921
2922 (define_insn "setlm"
2923   [(set (match_operand:DI 0 "register_operand" "=r")
2924         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2925   "TARGET_CM_MEDANY"
2926   "sethi\\t%%lm(%a1), %0")
2927
2928 (define_insn "sethm"
2929   [(set (match_operand:DI 0 "register_operand" "=r")
2930         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2931                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2932   "TARGET_CM_MEDANY"
2933   "or\\t%1, %%hm(%a2), %0")
2934
2935 (define_insn "setlo"
2936   [(set (match_operand:DI 0 "register_operand" "=r")
2937         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2938                    (match_operand:DI 2 "symbolic_operand" "")))]
2939   "TARGET_CM_MEDANY"
2940   "or\\t%1, %%lo(%a2), %0")
2941
2942 (define_insn "embmedany_sethi"
2943   [(set (match_operand:DI 0 "register_operand" "=r")
2944         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2945   "TARGET_CM_EMBMEDANY && check_pic (1)"
2946   "sethi\\t%%hi(%a1), %0")
2947
2948 (define_insn "embmedany_losum"
2949   [(set (match_operand:DI 0 "register_operand" "=r")
2950         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2951                    (match_operand:DI 2 "data_segment_operand" "")))]
2952   "TARGET_CM_EMBMEDANY"
2953   "add\\t%1, %%lo(%a2), %0")
2954
2955 (define_insn "embmedany_brsum"
2956   [(set (match_operand:DI 0 "register_operand" "=r")
2957         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2958   "TARGET_CM_EMBMEDANY"
2959   "add\\t%1, %_, %0")
2960
2961 (define_insn "embmedany_textuhi"
2962   [(set (match_operand:DI 0 "register_operand" "=r")
2963         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2964   "TARGET_CM_EMBMEDANY && check_pic (1)"
2965   "sethi\\t%%uhi(%a1), %0")
2966
2967 (define_insn "embmedany_texthi"
2968   [(set (match_operand:DI 0 "register_operand" "=r")
2969         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2970   "TARGET_CM_EMBMEDANY && check_pic (1)"
2971   "sethi\\t%%hi(%a1), %0")
2972
2973 (define_insn "embmedany_textulo"
2974   [(set (match_operand:DI 0 "register_operand" "=r")
2975         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2976                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2977   "TARGET_CM_EMBMEDANY"
2978   "or\\t%1, %%ulo(%a2), %0")
2979
2980 (define_insn "embmedany_textlo"
2981   [(set (match_operand:DI 0 "register_operand" "=r")
2982         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2983                    (match_operand:DI 2 "text_segment_operand" "")))]
2984   "TARGET_CM_EMBMEDANY"
2985   "or\\t%1, %%lo(%a2), %0")
2986
2987 ;; Now some patterns to help reload out a bit.
2988 (define_expand "reload_indi"
2989   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2990               (match_operand:DI 1 "immediate_operand" "")
2991               (match_operand:TI 2 "register_operand" "=&r")])]
2992   "(TARGET_CM_MEDANY
2993     || TARGET_CM_EMBMEDANY)
2994    && ! flag_pic"
2995   "
2996 {
2997   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2998   DONE;
2999 }")
3000
3001 (define_expand "reload_outdi"
3002   [(parallel [(match_operand:DI 0 "register_operand" "=r")
3003               (match_operand:DI 1 "immediate_operand" "")
3004               (match_operand:TI 2 "register_operand" "=&r")])]
3005   "(TARGET_CM_MEDANY
3006     || TARGET_CM_EMBMEDANY)
3007    && ! flag_pic"
3008   "
3009 {
3010   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
3011   DONE;
3012 }")
3013
3014 ;; Split up putting CONSTs and REGs into DI regs when !arch64
3015 (define_split
3016   [(set (match_operand:DI 0 "register_operand" "")
3017         (match_operand:DI 1 "const_int_operand" ""))]
3018   "! TARGET_ARCH64 && reload_completed"
3019   [(clobber (const_int 0))]
3020   "
3021 {
3022 #if HOST_BITS_PER_WIDE_INT == 32
3023   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3024                         (INTVAL (operands[1]) < 0) ?
3025                         constm1_rtx :
3026                         const0_rtx));
3027   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3028                         operands[1]));
3029 #else
3030   unsigned int low, high;
3031
3032   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
3033   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
3034   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
3035
3036   /* Slick... but this trick loses if this subreg constant part
3037      can be done in one insn.  */
3038   if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
3039     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3040                           gen_highpart (SImode, operands[0])));
3041   else
3042     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
3043 #endif
3044   DONE;
3045 }")
3046
3047 (define_split
3048   [(set (match_operand:DI 0 "register_operand" "")
3049         (match_operand:DI 1 "const_double_operand" ""))]
3050   "! TARGET_ARCH64 && reload_completed"
3051   [(clobber (const_int 0))]
3052   "
3053 {
3054   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3055                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
3056
3057   /* Slick... but this trick loses if this subreg constant part
3058      can be done in one insn.  */
3059   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
3060       && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
3061            || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
3062     {
3063       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3064                             gen_highpart (SImode, operands[0])));
3065     }
3066   else
3067     {
3068       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3069                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
3070     }
3071   DONE;
3072 }")
3073
3074 (define_split
3075   [(set (match_operand:DI 0 "register_operand" "")
3076         (match_operand:DI 1 "register_operand" ""))]
3077   "! TARGET_ARCH64 && reload_completed"
3078   [(clobber (const_int 0))]
3079   "
3080 {
3081   rtx set_dest = operands[0];
3082   rtx set_src = operands[1];
3083   rtx dest1, dest2;
3084   rtx src1, src2;
3085
3086   dest1 = gen_highpart (SImode, set_dest);
3087   dest2 = gen_lowpart (SImode, set_dest);
3088   src1 = gen_highpart (SImode, set_src);
3089   src2 = gen_lowpart (SImode, set_src);
3090
3091   /* Now emit using the real source and destination we found, swapping
3092      the order if we detect overlap.  */
3093   if (reg_overlap_mentioned_p (dest1, src2))
3094     {
3095       emit_insn (gen_movsi (dest2, src2));
3096       emit_insn (gen_movsi (dest1, src1));
3097     }
3098   else
3099     {
3100       emit_insn (gen_movsi (dest1, src1));
3101       emit_insn (gen_movsi (dest2, src2));
3102     }
3103   DONE;
3104 }")
3105
3106 ;; Now handle the cases of memory moves from/to non-even
3107 ;; DI mode register pairs.
3108 (define_split
3109   [(set (match_operand:DI 0 "register_operand" "")
3110         (match_operand:DI 1 "memory_operand" ""))]
3111   "(! TARGET_ARCH64
3112     && reload_completed
3113     && sparc_splitdi_legitimate (operands[0], operands[1]))"
3114   [(clobber (const_int 0))]
3115   "
3116 {
3117   rtx word0 = adjust_address (operands[1], SImode, 0);
3118   rtx word1 = adjust_address (operands[1], SImode, 4);
3119   rtx high_part = gen_highpart (SImode, operands[0]);
3120   rtx low_part = gen_lowpart (SImode, operands[0]);
3121
3122   if (reg_overlap_mentioned_p (high_part, word1))
3123     {
3124       emit_insn (gen_movsi (low_part, word1));
3125       emit_insn (gen_movsi (high_part, word0));
3126     }
3127   else
3128     {
3129       emit_insn (gen_movsi (high_part, word0));
3130       emit_insn (gen_movsi (low_part, word1));
3131     }
3132   DONE;
3133 }")
3134
3135 (define_split
3136   [(set (match_operand:DI 0 "memory_operand" "")
3137         (match_operand:DI 1 "register_operand" ""))]
3138   "(! TARGET_ARCH64
3139     && reload_completed
3140     && sparc_splitdi_legitimate (operands[1], operands[0]))"
3141   [(clobber (const_int 0))]
3142   "
3143 {
3144   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
3145                         gen_highpart (SImode, operands[1])));
3146   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
3147                         gen_lowpart (SImode, operands[1])));
3148   DONE;
3149 }")
3150
3151 (define_split
3152   [(set (match_operand:DI 0 "memory_operand" "")
3153         (const_int 0))]
3154   "reload_completed
3155    && (! TARGET_V9
3156        || (! TARGET_ARCH64
3157            && ! mem_min_alignment (operands[0], 8)))
3158    && offsettable_memref_p (operands[0])"
3159   [(clobber (const_int 0))]
3160   "
3161 {
3162   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
3163   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
3164   DONE;
3165 }")
3166 \f
3167 ;; Floating point move insns
3168
3169 (define_insn "*movsf_insn_novis"
3170   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
3171         (match_operand:SF 1 "input_operand"         "f,G,Q,*rR,S,m,m,f,*rG"))]
3172   "(TARGET_FPU && ! TARGET_VIS)
3173    && (register_operand (operands[0], SFmode)
3174        || register_operand (operands[1], SFmode)
3175        || fp_zero_operand (operands[1], SFmode))"
3176   "*
3177 {
3178   if (GET_CODE (operands[1]) == CONST_DOUBLE
3179       && (which_alternative == 2
3180           || which_alternative == 3
3181           || which_alternative == 4))
3182     {
3183       REAL_VALUE_TYPE r;
3184       long i;
3185
3186       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3187       REAL_VALUE_TO_TARGET_SINGLE (r, i);
3188       operands[1] = GEN_INT (i);
3189     }
3190
3191   switch (which_alternative)
3192     {
3193     case 0:
3194       return \"fmovs\\t%1, %0\";
3195     case 1:
3196       return \"clr\\t%0\";
3197     case 2:
3198       return \"sethi\\t%%hi(%a1), %0\";
3199     case 3:
3200       return \"mov\\t%1, %0\";
3201     case 4:
3202       return \"#\";
3203     case 5:
3204     case 6:
3205       return \"ld\\t%1, %0\";
3206     case 7:
3207     case 8:
3208       return \"st\\t%r1, %0\";
3209     default:
3210       abort();
3211     }
3212 }"
3213   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3214
3215 (define_insn "*movsf_insn_vis"
3216   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3217         (match_operand:SF 1 "input_operand"         "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3218   "(TARGET_FPU && TARGET_VIS)
3219    && (register_operand (operands[0], SFmode)
3220        || register_operand (operands[1], SFmode)
3221        || fp_zero_operand (operands[1], SFmode))"
3222   "*
3223 {
3224   if (GET_CODE (operands[1]) == CONST_DOUBLE
3225       && (which_alternative == 3
3226           || which_alternative == 4
3227           || which_alternative == 5))
3228     {
3229       REAL_VALUE_TYPE r;
3230       long i;
3231
3232       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3233       REAL_VALUE_TO_TARGET_SINGLE (r, i);
3234       operands[1] = GEN_INT (i);
3235     }
3236
3237   switch (which_alternative)
3238     {
3239     case 0:
3240       return \"fmovs\\t%1, %0\";
3241     case 1:
3242       return \"fzeros\\t%0\";
3243     case 2:
3244       return \"clr\\t%0\";
3245     case 3:
3246       return \"sethi\\t%%hi(%a1), %0\";
3247     case 4:
3248       return \"mov\\t%1, %0\";
3249     case 5:
3250       return \"#\";
3251     case 6:
3252     case 7:
3253       return \"ld\\t%1, %0\";
3254     case 8:
3255     case 9:
3256       return \"st\\t%r1, %0\";
3257     default:
3258       abort();
3259     }
3260 }"
3261   [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3262
3263 ;; Exactly the same as above, except that all `f' cases are deleted.
3264 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3265 ;; when -mno-fpu.
3266
3267 (define_insn "*movsf_no_f_insn"
3268   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3269         (match_operand:SF 1 "input_operand"    "G,Q,rR,S,m,rG"))]
3270   "! TARGET_FPU
3271    && (register_operand (operands[0], SFmode)
3272        || register_operand (operands[1], SFmode)
3273        || fp_zero_operand (operands[1], SFmode))"
3274   "*
3275 {
3276   if (GET_CODE (operands[1]) == CONST_DOUBLE
3277       && (which_alternative == 1
3278           || which_alternative == 2
3279           || which_alternative == 3))
3280     {
3281       REAL_VALUE_TYPE r;
3282       long i;
3283
3284       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3285       REAL_VALUE_TO_TARGET_SINGLE (r, i);
3286       operands[1] = GEN_INT (i);
3287     }
3288
3289   switch (which_alternative)
3290     {
3291     case 0:
3292       return \"clr\\t%0\";
3293     case 1:
3294       return \"sethi\\t%%hi(%a1), %0\";
3295     case 2:
3296       return \"mov\\t%1, %0\";
3297     case 3:
3298       return \"#\";
3299     case 4:
3300       return \"ld\\t%1, %0\";
3301     case 5:
3302       return \"st\\t%r1, %0\";
3303     default:
3304       abort();
3305     }
3306 }"
3307   [(set_attr "type" "*,*,*,*,load,store")])
3308
3309 (define_insn "*movsf_lo_sum"
3310   [(set (match_operand:SF 0 "register_operand" "=r")
3311         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3312                    (match_operand:SF 2 "const_double_operand" "S")))]
3313   "fp_high_losum_p (operands[2])"
3314   "*
3315 {
3316   REAL_VALUE_TYPE r;
3317   long i;
3318
3319   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3320   REAL_VALUE_TO_TARGET_SINGLE (r, i);
3321   operands[2] = GEN_INT (i);
3322   return \"or\\t%1, %%lo(%a2), %0\";
3323 }")
3324
3325 (define_insn "*movsf_high"
3326   [(set (match_operand:SF 0 "register_operand" "=r")
3327         (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3328   "fp_high_losum_p (operands[1])"
3329   "*
3330 {
3331   REAL_VALUE_TYPE r;
3332   long i;
3333
3334   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3335   REAL_VALUE_TO_TARGET_SINGLE (r, i);
3336   operands[1] = GEN_INT (i);
3337   return \"sethi\\t%%hi(%1), %0\";
3338 }")
3339
3340 (define_split
3341   [(set (match_operand:SF 0 "register_operand" "")
3342         (match_operand:SF 1 "const_double_operand" ""))]
3343   "fp_high_losum_p (operands[1])
3344    && (GET_CODE (operands[0]) == REG
3345        && REGNO (operands[0]) < 32)"
3346   [(set (match_dup 0) (high:SF (match_dup 1)))
3347    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3348
3349 (define_expand "movsf"
3350   [(set (match_operand:SF 0 "general_operand" "")
3351         (match_operand:SF 1 "general_operand" ""))]
3352   ""
3353   "
3354 {
3355   /* Force SFmode constants into memory.  */
3356   if (GET_CODE (operands[0]) == REG
3357       && CONSTANT_P (operands[1]))
3358     {
3359       /* emit_group_store will send such bogosity to us when it is
3360          not storing directly into memory.  So fix this up to avoid
3361          crashes in output_constant_pool.  */
3362       if (operands [1] == const0_rtx)
3363         operands[1] = CONST0_RTX (SFmode);
3364
3365       if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3366         goto movsf_is_ok;
3367
3368       /* We are able to build any SF constant in integer registers
3369          with at most 2 instructions.  */
3370       if (REGNO (operands[0]) < 32)
3371         goto movsf_is_ok;
3372
3373       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3374                                                    operands[1]));
3375     }
3376
3377   /* Handle sets of MEM first.  */
3378   if (GET_CODE (operands[0]) == MEM)
3379     {
3380       if (register_operand (operands[1], SFmode)
3381           || fp_zero_operand (operands[1], SFmode))
3382         goto movsf_is_ok;
3383
3384       if (! reload_in_progress)
3385         {
3386           operands[0] = validize_mem (operands[0]);
3387           operands[1] = force_reg (SFmode, operands[1]);
3388         }
3389     }
3390
3391   /* Fixup PIC cases.  */
3392   if (flag_pic)
3393     {
3394       if (CONSTANT_P (operands[1])
3395           && pic_address_needs_scratch (operands[1]))
3396         operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3397
3398       if (symbolic_operand (operands[1], SFmode))
3399         {
3400           operands[1] = legitimize_pic_address (operands[1],
3401                                                 SFmode,
3402                                                 (reload_in_progress ?
3403                                                  operands[0] :
3404                                                  NULL_RTX));
3405         }
3406     }
3407
3408  movsf_is_ok:
3409   ;
3410 }")
3411
3412 (define_expand "movdf"
3413   [(set (match_operand:DF 0 "general_operand" "")
3414         (match_operand:DF 1 "general_operand" ""))]
3415   ""
3416   "
3417 {
3418   /* Force DFmode constants into memory.  */
3419   if (GET_CODE (operands[0]) == REG
3420       && CONSTANT_P (operands[1]))
3421     {
3422       /* emit_group_store will send such bogosity to us when it is
3423          not storing directly into memory.  So fix this up to avoid
3424          crashes in output_constant_pool.  */
3425       if (operands [1] == const0_rtx)
3426         operands[1] = CONST0_RTX (DFmode);
3427
3428       if ((TARGET_VIS || REGNO (operands[0]) < 32)
3429           && fp_zero_operand (operands[1], DFmode))
3430         goto movdf_is_ok;
3431
3432       /* We are able to build any DF constant in integer registers.  */
3433       if (REGNO (operands[0]) < 32
3434           && (reload_completed || reload_in_progress))
3435         goto movdf_is_ok;
3436
3437       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3438                                                    operands[1]));
3439     }
3440
3441   /* Handle MEM cases first.  */
3442   if (GET_CODE (operands[0]) == MEM)
3443     {
3444       if (register_operand (operands[1], DFmode)
3445           || fp_zero_operand (operands[1], DFmode))
3446         goto movdf_is_ok;
3447
3448       if (! reload_in_progress)
3449         {
3450           operands[0] = validize_mem (operands[0]);
3451           operands[1] = force_reg (DFmode, operands[1]);
3452         }
3453     }
3454
3455   /* Fixup PIC cases.  */
3456   if (flag_pic)
3457     {
3458       if (CONSTANT_P (operands[1])
3459           && pic_address_needs_scratch (operands[1]))
3460         operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3461
3462       if (symbolic_operand (operands[1], DFmode))
3463         {
3464           operands[1] = legitimize_pic_address (operands[1],
3465                                                 DFmode,
3466                                                 (reload_in_progress ?
3467                                                  operands[0] :
3468                                                  NULL_RTX));
3469         }
3470     }
3471
3472  movdf_is_ok:
3473   ;
3474 }")
3475
3476 ;; Be careful, fmovd does not exist when !v9.
3477 (define_insn "*movdf_insn_sp32"
3478   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
3479         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3480   "TARGET_FPU
3481    && ! TARGET_V9
3482    && (register_operand (operands[0], DFmode)
3483        || register_operand (operands[1], DFmode)
3484        || fp_zero_operand (operands[1], DFmode))"
3485   "@
3486   ldd\\t%1, %0
3487   std\\t%1, %0
3488   ldd\\t%1, %0
3489   std\\t%1, %0
3490   #
3491   #
3492   #
3493   #
3494   #
3495   #"
3496  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3497   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3498
3499 (define_insn "*movdf_no_e_insn_sp32"
3500   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3501         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
3502   "! TARGET_FPU
3503    && ! TARGET_V9
3504    && ! TARGET_ARCH64
3505    && (register_operand (operands[0], DFmode)
3506        || register_operand (operands[1], DFmode)
3507        || fp_zero_operand (operands[1], DFmode))"
3508   "@
3509   ldd\\t%1, %0
3510   std\\t%1, %0
3511   #
3512   #
3513   #"
3514   [(set_attr "type" "load,store,*,*,*")
3515    (set_attr "length" "*,*,2,2,2")])
3516
3517 (define_insn "*movdf_no_e_insn_v9_sp32"
3518   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3519         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
3520   "! TARGET_FPU
3521    && TARGET_V9
3522    && ! TARGET_ARCH64
3523    && (register_operand (operands[0], DFmode)
3524        || register_operand (operands[1], DFmode)
3525        || fp_zero_operand (operands[1], DFmode))"
3526   "@
3527   ldd\\t%1, %0
3528   std\\t%1, %0
3529   stx\\t%r1, %0
3530   #
3531   #"
3532   [(set_attr "type" "load,store,store,*,*")
3533    (set_attr "length" "*,*,*,2,2")])
3534
3535 ;; We have available v9 double floats but not 64-bit
3536 ;; integer registers and no VIS.
3537 (define_insn "*movdf_insn_v9only_novis"
3538   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,e,*r,o")
3539         (match_operand:DF 1 "input_operand"    "e,W#F,G,e,T,U,o#F,*roF,*rGe"))]
3540   "TARGET_FPU
3541    && TARGET_V9
3542    && ! TARGET_VIS
3543    && ! TARGET_ARCH64
3544    && (register_operand (operands[0], DFmode)
3545        || register_operand (operands[1], DFmode)
3546        || fp_zero_operand (operands[1], DFmode))"
3547   "@
3548   fmovd\\t%1, %0
3549   ldd\\t%1, %0
3550   stx\\t%r1, %0
3551   std\\t%1, %0
3552   ldd\\t%1, %0
3553   std\\t%1, %0
3554   #
3555   #
3556   #"
3557   [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3558    (set_attr "length" "*,*,*,*,*,*,2,2,2")
3559    (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3560
3561 ;; We have available v9 double floats but not 64-bit
3562 ;; integer registers but we have VIS.
3563 (define_insn "*movdf_insn_v9only_vis"
3564   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,e,*r,o")
3565         (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGe"))]
3566   "TARGET_FPU
3567    && TARGET_VIS
3568    && ! TARGET_ARCH64
3569    && (register_operand (operands[0], DFmode)
3570        || register_operand (operands[1], DFmode)
3571        || fp_zero_operand (operands[1], DFmode))"
3572   "@
3573   fzero\\t%0
3574   fmovd\\t%1, %0
3575   ldd\\t%1, %0
3576   stx\\t%r1, %0
3577   std\\t%1, %0
3578   ldd\\t%1, %0
3579   std\\t%1, %0
3580   #
3581   #
3582   #"
3583   [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3584    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3585    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3586
3587 ;; We have available both v9 double floats and 64-bit
3588 ;; integer registers. No VIS though.
3589 (define_insn "*movdf_insn_sp64_novis"
3590   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3591         (match_operand:DF 1 "input_operand"    "e,W#F,e,*rG,m,*rG,F"))]
3592   "TARGET_FPU
3593    && ! TARGET_VIS
3594    && TARGET_ARCH64
3595    && (register_operand (operands[0], DFmode)
3596        || register_operand (operands[1], DFmode)
3597        || fp_zero_operand (operands[1], DFmode))"
3598   "@
3599   fmovd\\t%1, %0
3600   ldd\\t%1, %0
3601   std\\t%1, %0
3602   mov\\t%r1, %0
3603   ldx\\t%1, %0
3604   stx\\t%r1, %0
3605   #"
3606   [(set_attr "type" "fpmove,load,store,*,load,store,*")
3607    (set_attr "length" "*,*,*,*,*,*,2")
3608    (set_attr "fptype" "double,*,*,*,*,*,*")])
3609
3610 ;; We have available both v9 double floats and 64-bit
3611 ;; integer registers. And we have VIS.
3612 (define_insn "*movdf_insn_sp64_vis"
3613   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3614         (match_operand:DF 1 "input_operand"    "G,e,W#F,e,*rG,m,*rG,F"))]
3615   "TARGET_FPU
3616    && TARGET_VIS
3617    && TARGET_ARCH64
3618    && (register_operand (operands[0], DFmode)
3619        || register_operand (operands[1], DFmode)
3620        || fp_zero_operand (operands[1], DFmode))"
3621   "@
3622   fzero\\t%0
3623   fmovd\\t%1, %0
3624   ldd\\t%1, %0
3625   std\\t%1, %0
3626   mov\\t%r1, %0
3627   ldx\\t%1, %0
3628   stx\\t%r1, %0
3629   #"
3630   [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3631    (set_attr "length" "*,*,*,*,*,*,*,2")
3632    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3633
3634 (define_insn "*movdf_no_e_insn_sp64"
3635   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3636         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
3637   "! TARGET_FPU
3638    && TARGET_ARCH64
3639    && (register_operand (operands[0], DFmode)
3640        || register_operand (operands[1], DFmode)
3641        || fp_zero_operand (operands[1], DFmode))"
3642   "@
3643   mov\\t%1, %0
3644   ldx\\t%1, %0
3645   stx\\t%r1, %0"
3646   [(set_attr "type" "*,load,store")])
3647
3648 (define_split
3649   [(set (match_operand:DF 0 "register_operand" "")
3650         (match_operand:DF 1 "const_double_operand" ""))]
3651   "TARGET_FPU
3652    && (GET_CODE (operands[0]) == REG
3653        && REGNO (operands[0]) < 32)
3654    && ! fp_zero_operand(operands[1], DFmode)
3655    && reload_completed"
3656   [(clobber (const_int 0))]
3657   "
3658 {
3659   REAL_VALUE_TYPE r;
3660   long l[2];
3661
3662   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3663   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3664   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3665
3666   if (TARGET_ARCH64)
3667     {
3668 #if HOST_BITS_PER_WIDE_INT == 64
3669       HOST_WIDE_INT val;
3670
3671       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3672              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3673       emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3674 #else
3675       emit_insn (gen_movdi (operands[0],
3676                             gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3677 #endif
3678     }
3679   else
3680     {
3681       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3682                             GEN_INT (l[0])));
3683
3684       /* Slick... but this trick loses if this subreg constant part
3685          can be done in one insn.  */
3686       if (l[1] == l[0]
3687           && !(SPARC_SETHI32_P (l[0])
3688                || SPARC_SIMM13_P (l[0])))
3689         {
3690           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3691                                 gen_highpart (SImode, operands[0])));
3692         }
3693       else
3694         {
3695           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3696                                 GEN_INT (l[1])));
3697         }
3698     }
3699   DONE;
3700 }")
3701
3702 ;; Ok, now the splits to handle all the multi insn and
3703 ;; mis-aligned memory address cases.
3704 ;; In these splits please take note that we must be
3705 ;; careful when V9 but not ARCH64 because the integer
3706 ;; register DFmode cases must be handled.
3707 (define_split
3708   [(set (match_operand:DF 0 "register_operand" "")
3709         (match_operand:DF 1 "register_operand" ""))]
3710   "(! TARGET_V9
3711     || (! TARGET_ARCH64
3712         && ((GET_CODE (operands[0]) == REG
3713              && REGNO (operands[0]) < 32)
3714             || (GET_CODE (operands[0]) == SUBREG
3715                 && GET_CODE (SUBREG_REG (operands[0])) == REG
3716                 && REGNO (SUBREG_REG (operands[0])) < 32))))
3717    && reload_completed"
3718   [(clobber (const_int 0))]
3719   "
3720 {
3721   rtx set_dest = operands[0];
3722   rtx set_src = operands[1];
3723   rtx dest1, dest2;
3724   rtx src1, src2;
3725
3726   dest1 = gen_highpart (SFmode, set_dest);
3727   dest2 = gen_lowpart (SFmode, set_dest);
3728   src1 = gen_highpart (SFmode, set_src);
3729   src2 = gen_lowpart (SFmode, set_src);
3730
3731   /* Now emit using the real source and destination we found, swapping
3732      the order if we detect overlap.  */
3733   if (reg_overlap_mentioned_p (dest1, src2))
3734     {
3735       emit_insn (gen_movsf (dest2, src2));
3736       emit_insn (gen_movsf (dest1, src1));
3737     }
3738   else
3739     {
3740       emit_insn (gen_movsf (dest1, src1));
3741       emit_insn (gen_movsf (dest2, src2));
3742     }
3743   DONE;
3744 }")
3745
3746 (define_split
3747   [(set (match_operand:DF 0 "register_operand" "")
3748         (match_operand:DF 1 "memory_operand" ""))]
3749   "reload_completed
3750    && ! TARGET_ARCH64
3751    && (((REGNO (operands[0]) % 2) != 0)
3752        || ! mem_min_alignment (operands[1], 8))
3753    && offsettable_memref_p (operands[1])"
3754   [(clobber (const_int 0))]
3755   "
3756 {
3757   rtx word0 = adjust_address (operands[1], SFmode, 0);
3758   rtx word1 = adjust_address (operands[1], SFmode, 4);
3759
3760   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3761     {
3762       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3763                             word1));
3764       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3765                             word0));
3766     }
3767   else
3768     {
3769       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3770                             word0));
3771       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3772                             word1));
3773     }
3774   DONE;
3775 }")
3776
3777 (define_split
3778   [(set (match_operand:DF 0 "memory_operand" "")
3779         (match_operand:DF 1 "register_operand" ""))]
3780   "reload_completed
3781    && ! TARGET_ARCH64
3782    && (((REGNO (operands[1]) % 2) != 0)
3783        || ! mem_min_alignment (operands[0], 8))
3784    && offsettable_memref_p (operands[0])"
3785   [(clobber (const_int 0))]
3786   "
3787 {
3788   rtx word0 = adjust_address (operands[0], SFmode, 0);
3789   rtx word1 = adjust_address (operands[0], SFmode, 4);
3790
3791   emit_insn (gen_movsf (word0,
3792                         gen_highpart (SFmode, operands[1])));
3793   emit_insn (gen_movsf (word1,
3794                         gen_lowpart (SFmode, operands[1])));
3795   DONE;
3796 }")
3797
3798 (define_split
3799   [(set (match_operand:DF 0 "memory_operand" "")
3800         (match_operand:DF 1 "fp_zero_operand" ""))]
3801   "reload_completed
3802    && (! TARGET_V9
3803        || (! TARGET_ARCH64
3804            && ! mem_min_alignment (operands[0], 8)))
3805    && offsettable_memref_p (operands[0])"
3806   [(clobber (const_int 0))]
3807   "
3808 {
3809   rtx dest1, dest2;
3810
3811   dest1 = adjust_address (operands[0], SFmode, 0);
3812   dest2 = adjust_address (operands[0], SFmode, 4);
3813
3814   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3815   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3816   DONE;
3817 }")
3818
3819 (define_split
3820   [(set (match_operand:DF 0 "register_operand" "")
3821         (match_operand:DF 1 "fp_zero_operand" ""))]
3822   "reload_completed
3823    && ! TARGET_ARCH64
3824    && ((GET_CODE (operands[0]) == REG
3825         && REGNO (operands[0]) < 32)
3826        || (GET_CODE (operands[0]) == SUBREG
3827            && GET_CODE (SUBREG_REG (operands[0])) == REG
3828            && REGNO (SUBREG_REG (operands[0])) < 32))"
3829   [(clobber (const_int 0))]
3830   "
3831 {
3832   rtx set_dest = operands[0];
3833   rtx dest1, dest2;
3834
3835   dest1 = gen_highpart (SFmode, set_dest);
3836   dest2 = gen_lowpart (SFmode, set_dest);
3837   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3838   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3839   DONE;
3840 }")
3841
3842 (define_expand "movtf"
3843   [(set (match_operand:TF 0 "general_operand" "")
3844         (match_operand:TF 1 "general_operand" ""))]
3845   ""
3846   "
3847 {
3848   /* Force TFmode constants into memory.  */
3849   if (GET_CODE (operands[0]) == REG
3850       && CONSTANT_P (operands[1]))
3851     {
3852       /* emit_group_store will send such bogosity to us when it is
3853          not storing directly into memory.  So fix this up to avoid
3854          crashes in output_constant_pool.  */
3855       if (operands [1] == const0_rtx)
3856         operands[1] = CONST0_RTX (TFmode);
3857
3858       if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3859         goto movtf_is_ok;
3860
3861       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3862                                                    operands[1]));
3863     }
3864
3865   /* Handle MEM cases first, note that only v9 guarentees
3866      full 16-byte alignment for quads.  */
3867   if (GET_CODE (operands[0]) == MEM)
3868     {
3869       if (register_operand (operands[1], TFmode)
3870           || fp_zero_operand (operands[1], TFmode))
3871         goto movtf_is_ok;
3872
3873       if (! reload_in_progress)
3874         {
3875           operands[0] = validize_mem (operands[0]);
3876           operands[1] = force_reg (TFmode, operands[1]);
3877         }
3878     }
3879
3880   /* Fixup PIC cases.  */
3881   if (flag_pic)
3882     {
3883       if (CONSTANT_P (operands[1])
3884           && pic_address_needs_scratch (operands[1]))
3885         operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3886
3887       if (symbolic_operand (operands[1], TFmode))
3888         {
3889           operands[1] = legitimize_pic_address (operands[1],
3890                                                 TFmode,
3891                                                 (reload_in_progress ?
3892                                                  operands[0] :
3893                                                  NULL_RTX));
3894         }
3895     }
3896
3897  movtf_is_ok:
3898   ;
3899 }")
3900
3901 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3902 ;; we must split them all.  :-(
3903 (define_insn "*movtf_insn_sp32"
3904   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3905         (match_operand:TF 1 "input_operand"    "oe,GeUr,o,roG"))]
3906   "TARGET_FPU
3907    && ! TARGET_VIS
3908    && ! TARGET_ARCH64
3909    && (register_operand (operands[0], TFmode)
3910        || register_operand (operands[1], TFmode)
3911        || fp_zero_operand (operands[1], TFmode))"
3912   "#"
3913   [(set_attr "length" "4")])
3914
3915 (define_insn "*movtf_insn_vis_sp32"
3916   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3917         (match_operand:TF 1 "input_operand"    "Goe,GeUr,o,roG"))]
3918   "TARGET_FPU
3919    && TARGET_VIS
3920    && ! TARGET_ARCH64
3921    && (register_operand (operands[0], TFmode)
3922        || register_operand (operands[1], TFmode)
3923        || fp_zero_operand (operands[1], TFmode))"
3924   "#"
3925   [(set_attr "length" "4")])
3926
3927 ;; Exactly the same as above, except that all `e' cases are deleted.
3928 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3929 ;; when -mno-fpu.
3930
3931 (define_insn "*movtf_no_e_insn_sp32"
3932   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3933         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
3934   "! TARGET_FPU
3935    && ! TARGET_ARCH64
3936    && (register_operand (operands[0], TFmode)
3937        || register_operand (operands[1], TFmode)
3938        || fp_zero_operand (operands[1], TFmode))"
3939   "#"
3940   [(set_attr "length" "4")])
3941
3942 ;; Now handle the float reg cases directly when arch64,
3943 ;; hard_quad, and proper reg number alignment are all true.
3944 (define_insn "*movtf_insn_hq_sp64"
3945   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3946         (match_operand:TF 1 "input_operand"    "e,m,e,Gr,roG"))]
3947   "TARGET_FPU
3948    && ! TARGET_VIS
3949    && TARGET_ARCH64
3950    && TARGET_HARD_QUAD
3951    && (register_operand (operands[0], TFmode)
3952        || register_operand (operands[1], TFmode)
3953        || fp_zero_operand (operands[1], TFmode))"
3954   "@
3955   fmovq\\t%1, %0
3956   ldq\\t%1, %0
3957   stq\\t%1, %0
3958   #
3959   #"
3960   [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3961    (set_attr "length" "*,*,*,2,2")])
3962
3963 (define_insn "*movtf_insn_hq_vis_sp64"
3964   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3965         (match_operand:TF 1 "input_operand"    "e,m,e,G,roG,r"))]
3966   "TARGET_FPU
3967    && TARGET_VIS
3968    && TARGET_ARCH64
3969    && TARGET_HARD_QUAD
3970    && (register_operand (operands[0], TFmode)
3971        || register_operand (operands[1], TFmode)
3972        || fp_zero_operand (operands[1], TFmode))"
3973   "@
3974   fmovq\\t%1, %0
3975   ldq\\t%1, %0
3976   stq\\t%1, %0
3977   #
3978   #
3979   #"
3980   [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3981    (set_attr "length" "*,*,*,2,2,2")])
3982
3983 ;; Now we allow the integer register cases even when
3984 ;; only arch64 is true.
3985 (define_insn "*movtf_insn_sp64"
3986   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3987         (match_operand:TF 1 "input_operand"    "oe,Ger,orG"))]
3988   "TARGET_FPU
3989    && ! TARGET_VIS
3990    && TARGET_ARCH64
3991    && ! TARGET_HARD_QUAD
3992    && (register_operand (operands[0], TFmode)
3993        || register_operand (operands[1], TFmode)
3994        || fp_zero_operand (operands[1], TFmode))"
3995   "#"
3996   [(set_attr "length" "2")])
3997
3998 (define_insn "*movtf_insn_vis_sp64"
3999   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
4000         (match_operand:TF 1 "input_operand"    "Goe,Ger,orG"))]
4001   "TARGET_FPU
4002    && TARGET_VIS
4003    && TARGET_ARCH64
4004    && ! TARGET_HARD_QUAD
4005    && (register_operand (operands[0], TFmode)
4006        || register_operand (operands[1], TFmode)
4007        || fp_zero_operand (operands[1], TFmode))"
4008   "#"
4009   [(set_attr "length" "2")])
4010
4011 (define_insn "*movtf_no_e_insn_sp64"
4012   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
4013         (match_operand:TF 1 "input_operand"    "orG,rG"))]
4014   "! TARGET_FPU
4015    && TARGET_ARCH64
4016    && (register_operand (operands[0], TFmode)
4017        || register_operand (operands[1], TFmode)
4018        || fp_zero_operand (operands[1], TFmode))"
4019   "#"
4020   [(set_attr "length" "2")])
4021
4022 ;; Now all the splits to handle multi-insn TF mode moves.
4023 (define_split
4024   [(set (match_operand:TF 0 "register_operand" "")
4025         (match_operand:TF 1 "register_operand" ""))]
4026   "reload_completed
4027    && (! TARGET_ARCH64
4028        || (TARGET_FPU
4029            && ! TARGET_HARD_QUAD)
4030        || ! fp_register_operand (operands[0], TFmode))"
4031   [(clobber (const_int 0))]
4032   "
4033 {
4034   rtx set_dest = operands[0];
4035   rtx set_src = operands[1];
4036   rtx dest1, dest2;
4037   rtx src1, src2;
4038
4039   dest1 = gen_df_reg (set_dest, 0);
4040   dest2 = gen_df_reg (set_dest, 1);
4041   src1 = gen_df_reg (set_src, 0);
4042   src2 = gen_df_reg (set_src, 1);
4043
4044   /* Now emit using the real source and destination we found, swapping
4045      the order if we detect overlap.  */
4046   if (reg_overlap_mentioned_p (dest1, src2))
4047     {
4048       emit_insn (gen_movdf (dest2, src2));
4049       emit_insn (gen_movdf (dest1, src1));
4050     }
4051   else
4052     {
4053       emit_insn (gen_movdf (dest1, src1));
4054       emit_insn (gen_movdf (dest2, src2));
4055     }
4056   DONE;
4057 }")
4058
4059 (define_split
4060   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4061         (match_operand:TF 1 "fp_zero_operand" ""))]
4062   "reload_completed"
4063   [(clobber (const_int 0))]
4064   "
4065 {
4066   rtx set_dest = operands[0];
4067   rtx dest1, dest2;
4068
4069   switch (GET_CODE (set_dest))
4070     {
4071     case REG:
4072       dest1 = gen_df_reg (set_dest, 0);
4073       dest2 = gen_df_reg (set_dest, 1);
4074       break;
4075     case MEM:
4076       dest1 = adjust_address (set_dest, DFmode, 0);
4077       dest2 = adjust_address (set_dest, DFmode, 8);
4078       break;
4079     default:
4080       abort ();      
4081     }
4082
4083   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
4084   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
4085   DONE;
4086 }")
4087
4088 (define_split
4089   [(set (match_operand:TF 0 "register_operand" "")
4090         (match_operand:TF 1 "memory_operand" ""))]
4091   "(reload_completed
4092     && offsettable_memref_p (operands[1])
4093     && (! TARGET_ARCH64
4094         || ! TARGET_HARD_QUAD
4095         || ! fp_register_operand (operands[0], TFmode)))"
4096   [(clobber (const_int 0))]
4097   "
4098 {
4099   rtx word0 = adjust_address (operands[1], DFmode, 0);
4100   rtx word1 = adjust_address (operands[1], DFmode, 8);
4101   rtx set_dest, dest1, dest2;
4102
4103   set_dest = operands[0];
4104
4105   dest1 = gen_df_reg (set_dest, 0);
4106   dest2 = gen_df_reg (set_dest, 1);
4107
4108   /* Now output, ordering such that we don't clobber any registers
4109      mentioned in the address.  */
4110   if (reg_overlap_mentioned_p (dest1, word1))
4111
4112     {
4113       emit_insn (gen_movdf (dest2, word1));
4114       emit_insn (gen_movdf (dest1, word0));
4115     }
4116   else
4117    {
4118       emit_insn (gen_movdf (dest1, word0));
4119       emit_insn (gen_movdf (dest2, word1));
4120    }
4121   DONE;
4122 }")
4123
4124 (define_split
4125   [(set (match_operand:TF 0 "memory_operand" "")
4126         (match_operand:TF 1 "register_operand" ""))]
4127   "(reload_completed
4128     && offsettable_memref_p (operands[0])
4129     && (! TARGET_ARCH64
4130         || ! TARGET_HARD_QUAD
4131         || ! fp_register_operand (operands[1], TFmode)))"
4132   [(clobber (const_int 0))]
4133   "
4134 {
4135   rtx set_src = operands[1];
4136
4137   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
4138                         gen_df_reg (set_src, 0)));
4139   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
4140                         gen_df_reg (set_src, 1)));
4141   DONE;
4142 }")
4143 \f
4144 ;; Sparc V9 conditional move instructions.
4145
4146 ;; We can handle larger constants here for some flavors, but for now we keep
4147 ;; it simple and only allow those constants supported by all flavours.
4148 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
4149 ;; 3 contains the constant if one is present, but we handle either for
4150 ;; generality (sparc.c puts a constant in operand 2).
4151
4152 (define_expand "movqicc"
4153   [(set (match_operand:QI 0 "register_operand" "")
4154         (if_then_else:QI (match_operand 1 "comparison_operator" "")
4155                          (match_operand:QI 2 "arith10_operand" "")
4156                          (match_operand:QI 3 "arith10_operand" "")))]
4157   "TARGET_V9"
4158   "
4159 {
4160   enum rtx_code code = GET_CODE (operands[1]);
4161
4162   if (GET_MODE (sparc_compare_op0) == DImode
4163       && ! TARGET_ARCH64)
4164     FAIL;
4165
4166   if (sparc_compare_op1 == const0_rtx
4167       && GET_CODE (sparc_compare_op0) == REG
4168       && GET_MODE (sparc_compare_op0) == DImode
4169       && v9_regcmp_p (code))
4170     {
4171       operands[1] = gen_rtx_fmt_ee (code, DImode,
4172                              sparc_compare_op0, sparc_compare_op1);
4173     }
4174   else
4175     {
4176       rtx cc_reg = gen_compare_reg (code,
4177                                     sparc_compare_op0, sparc_compare_op1);
4178       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4179     }
4180 }")
4181
4182 (define_expand "movhicc"
4183   [(set (match_operand:HI 0 "register_operand" "")
4184         (if_then_else:HI (match_operand 1 "comparison_operator" "")
4185                          (match_operand:HI 2 "arith10_operand" "")
4186                          (match_operand:HI 3 "arith10_operand" "")))]
4187   "TARGET_V9"
4188   "
4189 {
4190   enum rtx_code code = GET_CODE (operands[1]);
4191
4192   if (GET_MODE (sparc_compare_op0) == DImode
4193       && ! TARGET_ARCH64)
4194     FAIL;
4195
4196   if (sparc_compare_op1 == const0_rtx
4197       && GET_CODE (sparc_compare_op0) == REG
4198       && GET_MODE (sparc_compare_op0) == DImode
4199       && v9_regcmp_p (code))
4200     {
4201       operands[1] = gen_rtx_fmt_ee (code, DImode,
4202                              sparc_compare_op0, sparc_compare_op1);
4203     }
4204   else
4205     {
4206       rtx cc_reg = gen_compare_reg (code,
4207                                     sparc_compare_op0, sparc_compare_op1);
4208       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4209     }
4210 }")
4211
4212 (define_expand "movsicc"
4213   [(set (match_operand:SI 0 "register_operand" "")
4214         (if_then_else:SI (match_operand 1 "comparison_operator" "")
4215                          (match_operand:SI 2 "arith10_operand" "")
4216                          (match_operand:SI 3 "arith10_operand" "")))]
4217   "TARGET_V9"
4218   "
4219 {
4220   enum rtx_code code = GET_CODE (operands[1]);
4221   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4222
4223   if (sparc_compare_op1 == const0_rtx
4224       && GET_CODE (sparc_compare_op0) == REG
4225       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4226     {
4227       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4228                              sparc_compare_op0, sparc_compare_op1);
4229     }
4230   else
4231     {
4232       rtx cc_reg = gen_compare_reg (code,
4233                                     sparc_compare_op0, sparc_compare_op1);
4234       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4235                                     cc_reg, const0_rtx);
4236     }
4237 }")
4238
4239 (define_expand "movdicc"
4240   [(set (match_operand:DI 0 "register_operand" "")
4241         (if_then_else:DI (match_operand 1 "comparison_operator" "")
4242                          (match_operand:DI 2 "arith10_double_operand" "")
4243                          (match_operand:DI 3 "arith10_double_operand" "")))]
4244   "TARGET_ARCH64"
4245   "
4246 {
4247   enum rtx_code code = GET_CODE (operands[1]);
4248
4249   if (sparc_compare_op1 == const0_rtx
4250       && GET_CODE (sparc_compare_op0) == REG
4251       && GET_MODE (sparc_compare_op0) == DImode
4252       && v9_regcmp_p (code))
4253     {
4254       operands[1] = gen_rtx_fmt_ee (code, DImode,
4255                              sparc_compare_op0, sparc_compare_op1);
4256     }
4257   else
4258     {
4259       rtx cc_reg = gen_compare_reg (code,
4260                                     sparc_compare_op0, sparc_compare_op1);
4261       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4262                                     cc_reg, const0_rtx);
4263     }
4264 }")
4265
4266 (define_expand "movsfcc"
4267   [(set (match_operand:SF 0 "register_operand" "")
4268         (if_then_else:SF (match_operand 1 "comparison_operator" "")
4269                          (match_operand:SF 2 "register_operand" "")
4270                          (match_operand:SF 3 "register_operand" "")))]
4271   "TARGET_V9 && TARGET_FPU"
4272   "
4273 {
4274   enum rtx_code code = GET_CODE (operands[1]);
4275
4276   if (GET_MODE (sparc_compare_op0) == DImode
4277       && ! TARGET_ARCH64)
4278     FAIL;
4279
4280   if (sparc_compare_op1 == const0_rtx
4281       && GET_CODE (sparc_compare_op0) == REG
4282       && GET_MODE (sparc_compare_op0) == DImode
4283       && v9_regcmp_p (code))
4284     {
4285       operands[1] = gen_rtx_fmt_ee (code, DImode,
4286                              sparc_compare_op0, sparc_compare_op1);
4287     }
4288   else
4289     {
4290       rtx cc_reg = gen_compare_reg (code,
4291                                     sparc_compare_op0, sparc_compare_op1);
4292       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4293     }
4294 }")
4295
4296 (define_expand "movdfcc"
4297   [(set (match_operand:DF 0 "register_operand" "")
4298         (if_then_else:DF (match_operand 1 "comparison_operator" "")
4299                          (match_operand:DF 2 "register_operand" "")
4300                          (match_operand:DF 3 "register_operand" "")))]
4301   "TARGET_V9 && TARGET_FPU"
4302   "
4303 {
4304   enum rtx_code code = GET_CODE (operands[1]);
4305
4306   if (GET_MODE (sparc_compare_op0) == DImode
4307       && ! TARGET_ARCH64)
4308     FAIL;
4309
4310   if (sparc_compare_op1 == const0_rtx
4311       && GET_CODE (sparc_compare_op0) == REG
4312       && GET_MODE (sparc_compare_op0) == DImode
4313       && v9_regcmp_p (code))
4314     {
4315       operands[1] = gen_rtx_fmt_ee (code, DImode,
4316                              sparc_compare_op0, sparc_compare_op1);
4317     }
4318   else
4319     {
4320       rtx cc_reg = gen_compare_reg (code,
4321                                     sparc_compare_op0, sparc_compare_op1);
4322       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4323     }
4324 }")
4325
4326 (define_expand "movtfcc"
4327   [(set (match_operand:TF 0 "register_operand" "")
4328         (if_then_else:TF (match_operand 1 "comparison_operator" "")
4329                          (match_operand:TF 2 "register_operand" "")
4330                          (match_operand:TF 3 "register_operand" "")))]
4331   "TARGET_V9 && TARGET_FPU"
4332   "
4333 {
4334   enum rtx_code code = GET_CODE (operands[1]);
4335
4336   if (GET_MODE (sparc_compare_op0) == DImode
4337       && ! TARGET_ARCH64)
4338     FAIL;
4339
4340   if (sparc_compare_op1 == const0_rtx
4341       && GET_CODE (sparc_compare_op0) == REG
4342       && GET_MODE (sparc_compare_op0) == DImode
4343       && v9_regcmp_p (code))
4344     {
4345       operands[1] = gen_rtx_fmt_ee (code, DImode,
4346                              sparc_compare_op0, sparc_compare_op1);
4347     }
4348   else
4349     {
4350       rtx cc_reg = gen_compare_reg (code,
4351                                     sparc_compare_op0, sparc_compare_op1);
4352       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4353     }
4354 }")
4355
4356 ;; Conditional move define_insns.
4357
4358 (define_insn "*movqi_cc_sp64"
4359   [(set (match_operand:QI 0 "register_operand" "=r,r")
4360         (if_then_else:QI (match_operator 1 "comparison_operator"
4361                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4362                                  (const_int 0)])
4363                          (match_operand:QI 3 "arith11_operand" "rL,0")
4364                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
4365   "TARGET_V9"
4366   "@
4367    mov%C1\\t%x2, %3, %0
4368    mov%c1\\t%x2, %4, %0"
4369   [(set_attr "type" "cmove")])
4370
4371 (define_insn "*movhi_cc_sp64"
4372   [(set (match_operand:HI 0 "register_operand" "=r,r")
4373         (if_then_else:HI (match_operator 1 "comparison_operator"
4374                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4375                                  (const_int 0)])
4376                          (match_operand:HI 3 "arith11_operand" "rL,0")
4377                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
4378   "TARGET_V9"
4379   "@
4380    mov%C1\\t%x2, %3, %0
4381    mov%c1\\t%x2, %4, %0"
4382   [(set_attr "type" "cmove")])
4383
4384 (define_insn "*movsi_cc_sp64"
4385   [(set (match_operand:SI 0 "register_operand" "=r,r")
4386         (if_then_else:SI (match_operator 1 "comparison_operator"
4387                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4388                                  (const_int 0)])
4389                          (match_operand:SI 3 "arith11_operand" "rL,0")
4390                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
4391   "TARGET_V9"
4392   "@
4393    mov%C1\\t%x2, %3, %0
4394    mov%c1\\t%x2, %4, %0"
4395   [(set_attr "type" "cmove")])
4396
4397 ;; ??? The constraints of operands 3,4 need work.
4398 (define_insn "*movdi_cc_sp64"
4399   [(set (match_operand:DI 0 "register_operand" "=r,r")
4400         (if_then_else:DI (match_operator 1 "comparison_operator"
4401                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4402                                  (const_int 0)])
4403                          (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4404                          (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4405   "TARGET_ARCH64"
4406   "@
4407    mov%C1\\t%x2, %3, %0
4408    mov%c1\\t%x2, %4, %0"
4409   [(set_attr "type" "cmove")])
4410
4411 (define_insn "*movdi_cc_sp64_trunc"
4412   [(set (match_operand:SI 0 "register_operand" "=r,r")
4413         (if_then_else:SI (match_operator 1 "comparison_operator"
4414                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4415                                  (const_int 0)])
4416                          (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4417                          (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4418   "TARGET_ARCH64"
4419   "@
4420    mov%C1\\t%x2, %3, %0
4421    mov%c1\\t%x2, %4, %0"
4422   [(set_attr "type" "cmove")])
4423
4424 (define_insn "*movsf_cc_sp64"
4425   [(set (match_operand:SF 0 "register_operand" "=f,f")
4426         (if_then_else:SF (match_operator 1 "comparison_operator"
4427                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4428                                  (const_int 0)])
4429                          (match_operand:SF 3 "register_operand" "f,0")
4430                          (match_operand:SF 4 "register_operand" "0,f")))]
4431   "TARGET_V9 && TARGET_FPU"
4432   "@
4433    fmovs%C1\\t%x2, %3, %0
4434    fmovs%c1\\t%x2, %4, %0"
4435   [(set_attr "type" "fpcmove")])
4436
4437 (define_insn "movdf_cc_sp64"
4438   [(set (match_operand:DF 0 "register_operand" "=e,e")
4439         (if_then_else:DF (match_operator 1 "comparison_operator"
4440                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4441                                  (const_int 0)])
4442                          (match_operand:DF 3 "register_operand" "e,0")
4443                          (match_operand:DF 4 "register_operand" "0,e")))]
4444   "TARGET_V9 && TARGET_FPU"
4445   "@
4446    fmovd%C1\\t%x2, %3, %0
4447    fmovd%c1\\t%x2, %4, %0"
4448   [(set_attr "type" "fpcmove")
4449    (set_attr "fptype" "double")])
4450
4451 (define_insn "*movtf_cc_hq_sp64"
4452   [(set (match_operand:TF 0 "register_operand" "=e,e")
4453         (if_then_else:TF (match_operator 1 "comparison_operator"
4454                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4455                                  (const_int 0)])
4456                          (match_operand:TF 3 "register_operand" "e,0")
4457                          (match_operand:TF 4 "register_operand" "0,e")))]
4458   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4459   "@
4460    fmovq%C1\\t%x2, %3, %0
4461    fmovq%c1\\t%x2, %4, %0"
4462   [(set_attr "type" "fpcmove")])
4463
4464 (define_insn "*movtf_cc_sp64"
4465   [(set (match_operand:TF 0 "register_operand" "=e,e")
4466         (if_then_else:TF (match_operator 1 "comparison_operator"
4467                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4468                                  (const_int 0)])
4469                          (match_operand:TF 3 "register_operand" "e,0")
4470                          (match_operand:TF 4 "register_operand" "0,e")))]
4471   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4472   "#"
4473   [(set_attr "length" "2")])
4474
4475 (define_split
4476   [(set (match_operand:TF 0 "register_operand" "")
4477         (if_then_else:TF (match_operator 1 "comparison_operator"
4478                                 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4479                                  (const_int 0)])
4480                          (match_operand:TF 3 "register_operand" "")
4481                          (match_operand:TF 4 "register_operand" "")))]
4482   "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4483   [(clobber (const_int 0))]
4484   "
4485 {
4486   rtx set_dest = operands[0];
4487   rtx set_srca = operands[3];
4488   rtx set_srcb = operands[4];
4489   int third = rtx_equal_p (set_dest, set_srca);
4490   rtx dest1, dest2;
4491   rtx srca1, srca2, srcb1, srcb2;
4492
4493   dest1 = gen_df_reg (set_dest, 0);
4494   dest2 = gen_df_reg (set_dest, 1);
4495   srca1 = gen_df_reg (set_srca, 0);
4496   srca2 = gen_df_reg (set_srca, 1);
4497   srcb1 = gen_df_reg (set_srcb, 0);
4498   srcb2 = gen_df_reg (set_srcb, 1);
4499
4500   /* Now emit using the real source and destination we found, swapping
4501      the order if we detect overlap.  */
4502   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4503       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4504     {
4505       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4506       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4507     }
4508   else
4509     {
4510       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4511       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4512     }
4513   DONE;
4514 }")
4515
4516 (define_insn "*movqi_cc_reg_sp64"
4517   [(set (match_operand:QI 0 "register_operand" "=r,r")
4518         (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4519                                 [(match_operand:DI 2 "register_operand" "r,r")
4520                                  (const_int 0)])
4521                          (match_operand:QI 3 "arith10_operand" "rM,0")
4522                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
4523   "TARGET_ARCH64"
4524   "@
4525    movr%D1\\t%2, %r3, %0
4526    movr%d1\\t%2, %r4, %0"
4527   [(set_attr "type" "cmove")])
4528
4529 (define_insn "*movhi_cc_reg_sp64"
4530   [(set (match_operand:HI 0 "register_operand" "=r,r")
4531         (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4532                                 [(match_operand:DI 2 "register_operand" "r,r")
4533                                  (const_int 0)])
4534                          (match_operand:HI 3 "arith10_operand" "rM,0")
4535                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
4536   "TARGET_ARCH64"
4537   "@
4538    movr%D1\\t%2, %r3, %0
4539    movr%d1\\t%2, %r4, %0"
4540   [(set_attr "type" "cmove")])
4541
4542 (define_insn "*movsi_cc_reg_sp64"
4543   [(set (match_operand:SI 0 "register_operand" "=r,r")
4544         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4545                                 [(match_operand:DI 2 "register_operand" "r,r")
4546                                  (const_int 0)])
4547                          (match_operand:SI 3 "arith10_operand" "rM,0")
4548                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
4549   "TARGET_ARCH64"
4550   "@
4551    movr%D1\\t%2, %r3, %0
4552    movr%d1\\t%2, %r4, %0"
4553   [(set_attr "type" "cmove")])
4554
4555 ;; ??? The constraints of operands 3,4 need work.
4556 (define_insn "*movdi_cc_reg_sp64"
4557   [(set (match_operand:DI 0 "register_operand" "=r,r")
4558         (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4559                                 [(match_operand:DI 2 "register_operand" "r,r")
4560                                  (const_int 0)])
4561                          (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4562                          (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4563   "TARGET_ARCH64"
4564   "@
4565    movr%D1\\t%2, %r3, %0
4566    movr%d1\\t%2, %r4, %0"
4567   [(set_attr "type" "cmove")])
4568
4569 (define_insn "*movdi_cc_reg_sp64_trunc"
4570   [(set (match_operand:SI 0 "register_operand" "=r,r")
4571         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4572                                 [(match_operand:DI 2 "register_operand" "r,r")
4573                                  (const_int 0)])
4574                          (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4575                          (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4576   "TARGET_ARCH64"
4577   "@
4578    movr%D1\\t%2, %r3, %0
4579    movr%d1\\t%2, %r4, %0"
4580   [(set_attr "type" "cmove")])
4581
4582 (define_insn "*movsf_cc_reg_sp64"
4583   [(set (match_operand:SF 0 "register_operand" "=f,f")
4584         (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4585                                 [(match_operand:DI 2 "register_operand" "r,r")
4586                                  (const_int 0)])
4587                          (match_operand:SF 3 "register_operand" "f,0")
4588                          (match_operand:SF 4 "register_operand" "0,f")))]
4589   "TARGET_ARCH64 && TARGET_FPU"
4590   "@
4591    fmovrs%D1\\t%2, %3, %0
4592    fmovrs%d1\\t%2, %4, %0"
4593   [(set_attr "type" "fpcrmove")])
4594
4595 (define_insn "movdf_cc_reg_sp64"
4596   [(set (match_operand:DF 0 "register_operand" "=e,e")
4597         (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4598                                 [(match_operand:DI 2 "register_operand" "r,r")
4599                                  (const_int 0)])
4600                          (match_operand:DF 3 "register_operand" "e,0")
4601                          (match_operand:DF 4 "register_operand" "0,e")))]
4602   "TARGET_ARCH64 && TARGET_FPU"
4603   "@
4604    fmovrd%D1\\t%2, %3, %0
4605    fmovrd%d1\\t%2, %4, %0"
4606   [(set_attr "type" "fpcrmove")
4607    (set_attr "fptype" "double")])
4608
4609 (define_insn "*movtf_cc_reg_hq_sp64"
4610   [(set (match_operand:TF 0 "register_operand" "=e,e")
4611         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4612                                 [(match_operand:DI 2 "register_operand" "r,r")
4613                                  (const_int 0)])
4614                          (match_operand:TF 3 "register_operand" "e,0")
4615                          (match_operand:TF 4 "register_operand" "0,e")))]
4616   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4617   "@
4618    fmovrq%D1\\t%2, %3, %0
4619    fmovrq%d1\\t%2, %4, %0"
4620   [(set_attr "type" "fpcrmove")])
4621
4622 (define_insn "*movtf_cc_reg_sp64"
4623   [(set (match_operand:TF 0 "register_operand" "=e,e")
4624         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4625                                 [(match_operand:DI 2 "register_operand" "r,r")
4626                                  (const_int 0)])
4627                          (match_operand:TF 3 "register_operand" "e,0")
4628                          (match_operand:TF 4 "register_operand" "0,e")))]
4629   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4630   "#"
4631   [(set_attr "length" "2")])
4632
4633 (define_split
4634   [(set (match_operand:TF 0 "register_operand" "")
4635         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4636                                 [(match_operand:DI 2 "register_operand" "")
4637                                  (const_int 0)])
4638                          (match_operand:TF 3 "register_operand" "")
4639                          (match_operand:TF 4 "register_operand" "")))]
4640   "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4641   [(clobber (const_int 0))]
4642   "
4643 {
4644   rtx set_dest = operands[0];
4645   rtx set_srca = operands[3];
4646   rtx set_srcb = operands[4];
4647   int third = rtx_equal_p (set_dest, set_srca);
4648   rtx dest1, dest2;
4649   rtx srca1, srca2, srcb1, srcb2;
4650
4651   dest1 = gen_df_reg (set_dest, 0);
4652   dest2 = gen_df_reg (set_dest, 1);
4653   srca1 = gen_df_reg (set_srca, 0);
4654   srca2 = gen_df_reg (set_srca, 1);
4655   srcb1 = gen_df_reg (set_srcb, 0);
4656   srcb2 = gen_df_reg (set_srcb, 1);
4657
4658   /* Now emit using the real source and destination we found, swapping
4659      the order if we detect overlap.  */
4660   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4661       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4662     {
4663       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4664       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4665     }
4666   else
4667     {
4668       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4669       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4670     }
4671   DONE;
4672 }")
4673
4674 \f
4675 ;;- zero extension instructions
4676
4677 ;; These patterns originally accepted general_operands, however, slightly
4678 ;; better code is generated by only accepting register_operands, and then
4679 ;; letting combine generate the ldu[hb] insns.
4680
4681 (define_expand "zero_extendhisi2"
4682   [(set (match_operand:SI 0 "register_operand" "")
4683         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4684   ""
4685   "
4686 {
4687   rtx temp = gen_reg_rtx (SImode);
4688   rtx shift_16 = GEN_INT (16);
4689   int op1_subbyte = 0;
4690
4691   if (GET_CODE (operand1) == SUBREG)
4692     {
4693       op1_subbyte = SUBREG_BYTE (operand1);
4694       op1_subbyte /= GET_MODE_SIZE (SImode);
4695       op1_subbyte *= GET_MODE_SIZE (SImode);
4696       operand1 = XEXP (operand1, 0);
4697     }
4698
4699   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4700                           shift_16));
4701   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4702   DONE;
4703 }")
4704
4705 (define_insn "*zero_extendhisi2_insn"
4706   [(set (match_operand:SI 0 "register_operand" "=r")
4707         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4708   ""
4709   "lduh\\t%1, %0"
4710   [(set_attr "type" "load")
4711    (set_attr "us3load_type" "3cycle")])
4712
4713 (define_expand "zero_extendqihi2"
4714   [(set (match_operand:HI 0 "register_operand" "")
4715         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4716   ""
4717   "")
4718
4719 (define_insn "*zero_extendqihi2_insn"
4720   [(set (match_operand:HI 0 "register_operand" "=r,r")
4721         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4722   "GET_CODE (operands[1]) != CONST_INT"
4723   "@
4724    and\\t%1, 0xff, %0
4725    ldub\\t%1, %0"
4726   [(set_attr "type" "*,load")
4727    (set_attr "us3load_type" "*,3cycle")])
4728
4729 (define_expand "zero_extendqisi2"
4730   [(set (match_operand:SI 0 "register_operand" "")
4731         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4732   ""
4733   "")
4734
4735 (define_insn "*zero_extendqisi2_insn"
4736   [(set (match_operand:SI 0 "register_operand" "=r,r")
4737         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4738   "GET_CODE (operands[1]) != CONST_INT"
4739   "@
4740    and\\t%1, 0xff, %0
4741    ldub\\t%1, %0"
4742   [(set_attr "type" "*,load")
4743    (set_attr "us3load_type" "*,3cycle")])
4744
4745 (define_expand "zero_extendqidi2"
4746   [(set (match_operand:DI 0 "register_operand" "")
4747         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4748   "TARGET_ARCH64"
4749   "")
4750
4751 (define_insn "*zero_extendqidi2_insn"
4752   [(set (match_operand:DI 0 "register_operand" "=r,r")
4753         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4754   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4755   "@
4756    and\\t%1, 0xff, %0
4757    ldub\\t%1, %0"
4758   [(set_attr "type" "*,load")
4759    (set_attr "us3load_type" "*,3cycle")])
4760
4761 (define_expand "zero_extendhidi2"
4762   [(set (match_operand:DI 0 "register_operand" "")
4763         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4764   "TARGET_ARCH64"
4765   "
4766 {
4767   rtx temp = gen_reg_rtx (DImode);
4768   rtx shift_48 = GEN_INT (48);
4769   int op1_subbyte = 0;
4770
4771   if (GET_CODE (operand1) == SUBREG)
4772     {
4773       op1_subbyte = SUBREG_BYTE (operand1);
4774       op1_subbyte /= GET_MODE_SIZE (DImode);
4775       op1_subbyte *= GET_MODE_SIZE (DImode);
4776       operand1 = XEXP (operand1, 0);
4777     }
4778
4779   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4780                           shift_48));
4781   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4782   DONE;
4783 }")
4784
4785 (define_insn "*zero_extendhidi2_insn"
4786   [(set (match_operand:DI 0 "register_operand" "=r")
4787         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4788   "TARGET_ARCH64"
4789   "lduh\\t%1, %0"
4790   [(set_attr "type" "load")
4791    (set_attr "us3load_type" "3cycle")])
4792
4793
4794 ;; ??? Write truncdisi pattern using sra?
4795
4796 (define_expand "zero_extendsidi2"
4797   [(set (match_operand:DI 0 "register_operand" "")
4798         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4799   ""
4800   "")
4801
4802 (define_insn "*zero_extendsidi2_insn_sp64"
4803   [(set (match_operand:DI 0 "register_operand" "=r,r")
4804         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4805   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4806   "@
4807    srl\\t%1, 0, %0
4808    lduw\\t%1, %0"
4809   [(set_attr "type" "shift,load")])
4810
4811 (define_insn "*zero_extendsidi2_insn_sp32"
4812   [(set (match_operand:DI 0 "register_operand" "=r")
4813         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4814   "! TARGET_ARCH64"
4815   "#"
4816   [(set_attr "length" "2")])
4817
4818 (define_split
4819   [(set (match_operand:DI 0 "register_operand" "")
4820         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4821   "! TARGET_ARCH64 && reload_completed"
4822   [(set (match_dup 2) (match_dup 3))
4823    (set (match_dup 4) (match_dup 5))]
4824   "
4825 {
4826   rtx dest1, dest2;
4827
4828   dest1 = gen_highpart (SImode, operands[0]);
4829   dest2 = gen_lowpart (SImode, operands[0]);
4830
4831   /* Swap the order in case of overlap.  */
4832   if (REGNO (dest1) == REGNO (operands[1]))
4833     {
4834       operands[2] = dest2;
4835       operands[3] = operands[1];
4836       operands[4] = dest1;
4837       operands[5] = const0_rtx;
4838     }
4839   else
4840     {
4841       operands[2] = dest1;
4842       operands[3] = const0_rtx;
4843       operands[4] = dest2;
4844       operands[5] = operands[1];
4845     }
4846 }")
4847
4848 ;; Simplify comparisons of extended values.
4849
4850 (define_insn "*cmp_zero_extendqisi2"
4851   [(set (reg:CC 100)
4852         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4853                     (const_int 0)))]
4854   ""
4855   "andcc\\t%0, 0xff, %%g0"
4856   [(set_attr "type" "compare")])
4857
4858 (define_insn "*cmp_zero_qi"
4859   [(set (reg:CC 100)
4860         (compare:CC (match_operand:QI 0 "register_operand" "r")
4861                     (const_int 0)))]
4862   ""
4863   "andcc\\t%0, 0xff, %%g0"
4864   [(set_attr "type" "compare")])
4865
4866 (define_insn "*cmp_zero_extendqisi2_set"
4867   [(set (reg:CC 100)
4868         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4869                     (const_int 0)))
4870    (set (match_operand:SI 0 "register_operand" "=r")
4871         (zero_extend:SI (match_dup 1)))]
4872   ""
4873   "andcc\\t%1, 0xff, %0"
4874   [(set_attr "type" "compare")])
4875
4876 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4877   [(set (reg:CC 100)
4878         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4879                             (const_int 255))
4880                     (const_int 0)))
4881    (set (match_operand:SI 0 "register_operand" "=r")
4882         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4883   ""
4884   "andcc\\t%1, 0xff, %0"
4885   [(set_attr "type" "compare")])
4886
4887 (define_insn "*cmp_zero_extendqidi2"
4888   [(set (reg:CCX 100)
4889         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4890                      (const_int 0)))]
4891   "TARGET_ARCH64"
4892   "andcc\\t%0, 0xff, %%g0"
4893   [(set_attr "type" "compare")])
4894
4895 (define_insn "*cmp_zero_qi_sp64"
4896   [(set (reg:CCX 100)
4897         (compare:CCX (match_operand:QI 0 "register_operand" "r")
4898                      (const_int 0)))]
4899   "TARGET_ARCH64"
4900   "andcc\\t%0, 0xff, %%g0"
4901   [(set_attr "type" "compare")])
4902
4903 (define_insn "*cmp_zero_extendqidi2_set"
4904   [(set (reg:CCX 100)
4905         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4906                      (const_int 0)))
4907    (set (match_operand:DI 0 "register_operand" "=r")
4908         (zero_extend:DI (match_dup 1)))]
4909   "TARGET_ARCH64"
4910   "andcc\\t%1, 0xff, %0"
4911   [(set_attr "type" "compare")])
4912
4913 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4914   [(set (reg:CCX 100)
4915         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4916                              (const_int 255))
4917                      (const_int 0)))
4918    (set (match_operand:DI 0 "register_operand" "=r")
4919         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4920   "TARGET_ARCH64"
4921   "andcc\\t%1, 0xff, %0"
4922   [(set_attr "type" "compare")])
4923
4924 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4925
4926 (define_insn "*cmp_siqi_trunc"
4927   [(set (reg:CC 100)
4928         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4929                     (const_int 0)))]
4930   ""
4931   "andcc\\t%0, 0xff, %%g0"
4932   [(set_attr "type" "compare")])
4933
4934 (define_insn "*cmp_siqi_trunc_set"
4935   [(set (reg:CC 100)
4936         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4937                     (const_int 0)))
4938    (set (match_operand:QI 0 "register_operand" "=r")
4939         (subreg:QI (match_dup 1) 3))]
4940   ""
4941   "andcc\\t%1, 0xff, %0"
4942   [(set_attr "type" "compare")])
4943
4944 (define_insn "*cmp_diqi_trunc"
4945   [(set (reg:CC 100)
4946         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4947                     (const_int 0)))]
4948   "TARGET_ARCH64"
4949   "andcc\\t%0, 0xff, %%g0"
4950   [(set_attr "type" "compare")])
4951
4952 (define_insn "*cmp_diqi_trunc_set"
4953   [(set (reg:CC 100)
4954         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4955                     (const_int 0)))
4956    (set (match_operand:QI 0 "register_operand" "=r")
4957         (subreg:QI (match_dup 1) 7))]
4958   "TARGET_ARCH64"
4959   "andcc\\t%1, 0xff, %0"
4960   [(set_attr "type" "compare")])
4961 \f
4962 ;;- sign extension instructions
4963
4964 ;; These patterns originally accepted general_operands, however, slightly
4965 ;; better code is generated by only accepting register_operands, and then
4966 ;; letting combine generate the lds[hb] insns.
4967
4968 (define_expand "extendhisi2"
4969   [(set (match_operand:SI 0 "register_operand" "")
4970         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4971   ""
4972   "
4973 {
4974   rtx temp = gen_reg_rtx (SImode);
4975   rtx shift_16 = GEN_INT (16);
4976   int op1_subbyte = 0;
4977
4978   if (GET_CODE (operand1) == SUBREG)
4979     {
4980       op1_subbyte = SUBREG_BYTE (operand1);
4981       op1_subbyte /= GET_MODE_SIZE (SImode);
4982       op1_subbyte *= GET_MODE_SIZE (SImode);
4983       operand1 = XEXP (operand1, 0);
4984     }
4985
4986   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4987                           shift_16));
4988   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4989   DONE;
4990 }")
4991
4992 (define_insn "*sign_extendhisi2_insn"
4993   [(set (match_operand:SI 0 "register_operand" "=r")
4994         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4995   ""
4996   "ldsh\\t%1, %0"
4997   [(set_attr "type" "sload")
4998    (set_attr "us3load_type" "3cycle")])
4999
5000 (define_expand "extendqihi2"
5001   [(set (match_operand:HI 0 "register_operand" "")
5002         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
5003   ""
5004   "
5005 {
5006   rtx temp = gen_reg_rtx (SImode);
5007   rtx shift_24 = GEN_INT (24);
5008   int op1_subbyte = 0;
5009   int op0_subbyte = 0;
5010
5011   if (GET_CODE (operand1) == SUBREG)
5012     {
5013       op1_subbyte = SUBREG_BYTE (operand1);
5014       op1_subbyte /= GET_MODE_SIZE (SImode);
5015       op1_subbyte *= GET_MODE_SIZE (SImode);
5016       operand1 = XEXP (operand1, 0);
5017     }
5018   if (GET_CODE (operand0) == SUBREG)
5019     {
5020       op0_subbyte = SUBREG_BYTE (operand0);
5021       op0_subbyte /= GET_MODE_SIZE (SImode);
5022       op0_subbyte *= GET_MODE_SIZE (SImode);
5023       operand0 = XEXP (operand0, 0);
5024     }
5025   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
5026                           shift_24));
5027   if (GET_MODE (operand0) != SImode)
5028     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
5029   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
5030   DONE;
5031 }")
5032
5033 (define_insn "*sign_extendqihi2_insn"
5034   [(set (match_operand:HI 0 "register_operand" "=r")
5035         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
5036   ""
5037   "ldsb\\t%1, %0"
5038   [(set_attr "type" "sload")
5039    (set_attr "us3load_type" "3cycle")])
5040
5041 (define_expand "extendqisi2"
5042   [(set (match_operand:SI 0 "register_operand" "")
5043         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5044   ""
5045   "
5046 {
5047   rtx temp = gen_reg_rtx (SImode);
5048   rtx shift_24 = GEN_INT (24);
5049   int op1_subbyte = 0;
5050
5051   if (GET_CODE (operand1) == SUBREG)
5052     {
5053       op1_subbyte = SUBREG_BYTE (operand1);
5054       op1_subbyte /= GET_MODE_SIZE (SImode);
5055       op1_subbyte *= GET_MODE_SIZE (SImode);
5056       operand1 = XEXP (operand1, 0);
5057     }
5058
5059   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
5060                           shift_24));
5061   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
5062   DONE;
5063 }")
5064
5065 (define_insn "*sign_extendqisi2_insn"
5066   [(set (match_operand:SI 0 "register_operand" "=r")
5067         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
5068   ""
5069   "ldsb\\t%1, %0"
5070   [(set_attr "type" "sload")
5071    (set_attr "us3load_type" "3cycle")])
5072
5073 (define_expand "extendqidi2"
5074   [(set (match_operand:DI 0 "register_operand" "")
5075         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
5076   "TARGET_ARCH64"
5077   "
5078 {
5079   rtx temp = gen_reg_rtx (DImode);
5080   rtx shift_56 = GEN_INT (56);
5081   int op1_subbyte = 0;
5082
5083   if (GET_CODE (operand1) == SUBREG)
5084     {
5085       op1_subbyte = SUBREG_BYTE (operand1);
5086       op1_subbyte /= GET_MODE_SIZE (DImode);
5087       op1_subbyte *= GET_MODE_SIZE (DImode);
5088       operand1 = XEXP (operand1, 0);
5089     }
5090
5091   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
5092                           shift_56));
5093   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
5094   DONE;
5095 }")
5096
5097 (define_insn "*sign_extendqidi2_insn"
5098   [(set (match_operand:DI 0 "register_operand" "=r")
5099         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
5100   "TARGET_ARCH64"
5101   "ldsb\\t%1, %0"
5102   [(set_attr "type" "sload")
5103    (set_attr "us3load_type" "3cycle")])
5104
5105 (define_expand "extendhidi2"
5106   [(set (match_operand:DI 0 "register_operand" "")
5107         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
5108   "TARGET_ARCH64"
5109   "
5110 {
5111   rtx temp = gen_reg_rtx (DImode);
5112   rtx shift_48 = GEN_INT (48);
5113   int op1_subbyte = 0;
5114
5115   if (GET_CODE (operand1) == SUBREG)
5116     {
5117       op1_subbyte = SUBREG_BYTE (operand1);
5118       op1_subbyte /= GET_MODE_SIZE (DImode);
5119       op1_subbyte *= GET_MODE_SIZE (DImode);
5120       operand1 = XEXP (operand1, 0);
5121     }
5122
5123   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
5124                           shift_48));
5125   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
5126   DONE;
5127 }")
5128
5129 (define_insn "*sign_extendhidi2_insn"
5130   [(set (match_operand:DI 0 "register_operand" "=r")
5131         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
5132   "TARGET_ARCH64"
5133   "ldsh\\t%1, %0"
5134   [(set_attr "type" "sload")
5135    (set_attr "us3load_type" "3cycle")])
5136
5137 (define_expand "extendsidi2"
5138   [(set (match_operand:DI 0 "register_operand" "")
5139         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
5140   "TARGET_ARCH64"
5141   "")
5142
5143 (define_insn "*sign_extendsidi2_insn"
5144   [(set (match_operand:DI 0 "register_operand" "=r,r")
5145         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
5146   "TARGET_ARCH64"
5147   "@
5148   sra\\t%1, 0, %0
5149   ldsw\\t%1, %0"
5150   [(set_attr "type" "shift,sload")
5151    (set_attr "us3load_type" "*,3cycle")])
5152 \f
5153 ;; Special pattern for optimizing bit-field compares.  This is needed
5154 ;; because combine uses this as a canonical form.
5155
5156 (define_insn "*cmp_zero_extract"
5157   [(set (reg:CC 100)
5158         (compare:CC
5159          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5160                           (match_operand:SI 1 "small_int_or_double" "n")
5161                           (match_operand:SI 2 "small_int_or_double" "n"))
5162          (const_int 0)))]
5163   "(GET_CODE (operands[2]) == CONST_INT
5164     && INTVAL (operands[2]) > 19)
5165    || (GET_CODE (operands[2]) == CONST_DOUBLE
5166        && CONST_DOUBLE_LOW (operands[2]) > 19)"
5167   "*
5168 {
5169   int len = (GET_CODE (operands[1]) == CONST_INT
5170              ? INTVAL (operands[1])
5171              : CONST_DOUBLE_LOW (operands[1]));
5172   int pos = 32 -
5173             (GET_CODE (operands[2]) == CONST_INT
5174              ? INTVAL (operands[2])
5175              : CONST_DOUBLE_LOW (operands[2])) - len;
5176   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5177
5178   operands[1] = GEN_INT (mask);
5179   return \"andcc\\t%0, %1, %%g0\";
5180 }"
5181   [(set_attr "type" "compare")])
5182
5183 (define_insn "*cmp_zero_extract_sp64"
5184   [(set (reg:CCX 100)
5185         (compare:CCX
5186          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5187                           (match_operand:SI 1 "small_int_or_double" "n")
5188                           (match_operand:SI 2 "small_int_or_double" "n"))
5189          (const_int 0)))]
5190   "TARGET_ARCH64
5191    && ((GET_CODE (operands[2]) == CONST_INT
5192         && INTVAL (operands[2]) > 51)
5193        || (GET_CODE (operands[2]) == CONST_DOUBLE
5194            && CONST_DOUBLE_LOW (operands[2]) > 51))"
5195   "*
5196 {
5197   int len = (GET_CODE (operands[1]) == CONST_INT
5198              ? INTVAL (operands[1])
5199              : CONST_DOUBLE_LOW (operands[1]));
5200   int pos = 64 -
5201             (GET_CODE (operands[2]) == CONST_INT
5202              ? INTVAL (operands[2])
5203              : CONST_DOUBLE_LOW (operands[2])) - len;
5204   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5205
5206   operands[1] = GEN_INT (mask);
5207   return \"andcc\\t%0, %1, %%g0\";
5208 }"
5209   [(set_attr "type" "compare")])
5210 \f
5211 ;; Conversions between float, double and long double.
5212
5213 (define_insn "extendsfdf2"
5214   [(set (match_operand:DF 0 "register_operand" "=e")
5215         (float_extend:DF
5216          (match_operand:SF 1 "register_operand" "f")))]
5217   "TARGET_FPU"
5218   "fstod\\t%1, %0"
5219   [(set_attr "type" "fp")
5220    (set_attr "fptype" "double")])
5221
5222 (define_expand "extendsftf2"
5223   [(set (match_operand:TF 0 "register_operand" "=e")
5224         (float_extend:TF
5225          (match_operand:SF 1 "register_operand" "f")))]
5226   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5227   "
5228 {
5229   if (! TARGET_HARD_QUAD)
5230     {
5231       rtx slot0;
5232
5233       if (GET_CODE (operands[0]) != MEM)
5234         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5235       else
5236         slot0 = operands[0];
5237
5238       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), LCT_NORMAL,
5239                          VOIDmode, 2,
5240                          XEXP (slot0, 0), Pmode,
5241                          operands[1], SFmode);
5242
5243       if (GET_CODE (operands[0]) != MEM)
5244         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5245       DONE;
5246     }
5247 }")
5248
5249 (define_insn "*extendsftf2_hq"
5250   [(set (match_operand:TF 0 "register_operand" "=e")
5251         (float_extend:TF
5252          (match_operand:SF 1 "register_operand" "f")))]
5253   "TARGET_FPU && TARGET_HARD_QUAD"
5254   "fstoq\\t%1, %0"
5255   [(set_attr "type" "fp")])
5256
5257 (define_expand "extenddftf2"
5258   [(set (match_operand:TF 0 "register_operand" "=e")
5259         (float_extend:TF
5260          (match_operand:DF 1 "register_operand" "e")))]
5261   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5262   "
5263 {
5264   if (! TARGET_HARD_QUAD)
5265     {
5266       rtx slot0;
5267
5268       if (GET_CODE (operands[0]) != MEM)
5269         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5270       else
5271         slot0 = operands[0];
5272
5273       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), LCT_NORMAL,
5274                          VOIDmode, 2,
5275                          XEXP (slot0, 0), Pmode,
5276                          operands[1], DFmode);
5277
5278       if (GET_CODE (operands[0]) != MEM)
5279         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5280       DONE;
5281     }
5282 }")
5283
5284 (define_insn "*extenddftf2_hq"
5285   [(set (match_operand:TF 0 "register_operand" "=e")
5286         (float_extend:TF
5287          (match_operand:DF 1 "register_operand" "e")))]
5288   "TARGET_FPU && TARGET_HARD_QUAD"
5289   "fdtoq\\t%1, %0"
5290   [(set_attr "type" "fp")])
5291
5292 (define_insn "truncdfsf2"
5293   [(set (match_operand:SF 0 "register_operand" "=f")
5294         (float_truncate:SF
5295          (match_operand:DF 1 "register_operand" "e")))]
5296   "TARGET_FPU"
5297   "fdtos\\t%1, %0"
5298   [(set_attr "type" "fp")
5299    (set_attr "fptype" "double")])
5300
5301 (define_expand "trunctfsf2"
5302   [(set (match_operand:SF 0 "register_operand" "=f")
5303         (float_truncate:SF
5304          (match_operand:TF 1 "register_operand" "e")))]
5305   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5306   "
5307 {
5308   if (! TARGET_HARD_QUAD)
5309     {
5310       rtx slot0;
5311
5312       if (GET_CODE (operands[1]) != MEM)
5313         {
5314           slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5315           emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5316         }
5317       else
5318         slot0 = operands[1];
5319
5320       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5321                                operands[0], LCT_NORMAL, SFmode, 1,
5322                                XEXP (slot0, 0), Pmode);
5323       DONE;
5324     }
5325 }")
5326
5327 (define_insn "*trunctfsf2_hq"
5328   [(set (match_operand:SF 0 "register_operand" "=f")
5329         (float_truncate:SF
5330          (match_operand:TF 1 "register_operand" "e")))]
5331   "TARGET_FPU && TARGET_HARD_QUAD"
5332   "fqtos\\t%1, %0"
5333   [(set_attr "type" "fp")])
5334
5335 (define_expand "trunctfdf2"
5336   [(set (match_operand:DF 0 "register_operand" "=f")
5337         (float_truncate:DF
5338          (match_operand:TF 1 "register_operand" "e")))]
5339   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5340   "
5341 {
5342   if (! TARGET_HARD_QUAD)
5343     {
5344       rtx slot0;
5345
5346       if (GET_CODE (operands[1]) != MEM)
5347         {
5348           slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5349           emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5350         }
5351       else
5352         slot0 = operands[1];
5353
5354       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5355                                operands[0], LCT_NORMAL, DFmode, 1,
5356                                XEXP (slot0, 0), Pmode);
5357       DONE;
5358     }
5359 }")
5360
5361 (define_insn "*trunctfdf2_hq"
5362   [(set (match_operand:DF 0 "register_operand" "=e")
5363         (float_truncate:DF
5364          (match_operand:TF 1 "register_operand" "e")))]
5365   "TARGET_FPU && TARGET_HARD_QUAD"
5366   "fqtod\\t%1, %0"
5367   [(set_attr "type" "fp")])
5368 \f
5369 ;; Conversion between fixed point and floating point.
5370
5371 (define_insn "floatsisf2"
5372   [(set (match_operand:SF 0 "register_operand" "=f")
5373         (float:SF (match_operand:SI 1 "register_operand" "f")))]
5374   "TARGET_FPU"
5375   "fitos\\t%1, %0"
5376   [(set_attr "type" "fp")
5377    (set_attr "fptype" "double")])
5378
5379 (define_insn "floatsidf2"
5380   [(set (match_operand:DF 0 "register_operand" "=e")
5381         (float:DF (match_operand:SI 1 "register_operand" "f")))]
5382   "TARGET_FPU"
5383   "fitod\\t%1, %0"
5384   [(set_attr "type" "fp")
5385    (set_attr "fptype" "double")])
5386
5387 (define_expand "floatsitf2"
5388   [(set (match_operand:TF 0 "register_operand" "=e")
5389         (float:TF (match_operand:SI 1 "register_operand" "f")))]
5390   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5391   "
5392 {
5393   if (! TARGET_HARD_QUAD)
5394     {
5395       rtx slot0;
5396
5397       if (GET_CODE (operands[1]) != MEM)
5398         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5399       else
5400         slot0 = operands[1];
5401
5402       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5403                          VOIDmode, 2,
5404                          XEXP (slot0, 0), Pmode,
5405                          operands[1], SImode);
5406
5407       if (GET_CODE (operands[0]) != MEM)
5408         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5409       DONE;
5410     }
5411 }")
5412
5413 (define_insn "*floatsitf2_hq"
5414   [(set (match_operand:TF 0 "register_operand" "=e")
5415         (float:TF (match_operand:SI 1 "register_operand" "f")))]
5416   "TARGET_FPU && TARGET_HARD_QUAD"
5417   "fitoq\\t%1, %0"
5418   [(set_attr "type" "fp")])
5419
5420 (define_expand "floatunssitf2"
5421   [(set (match_operand:TF 0 "register_operand" "=e")
5422         (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5423   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5424   "
5425 {
5426   rtx slot0;
5427
5428   if (GET_CODE (operands[1]) != MEM)
5429     slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5430   else
5431     slot0 = operands[1];
5432
5433   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5434                      VOIDmode, 2,
5435                      XEXP (slot0, 0), Pmode,
5436                      operands[1], SImode);
5437
5438   if (GET_CODE (operands[0]) != MEM)
5439     emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5440   DONE;
5441 }")
5442
5443 ;; Now the same for 64 bit sources.
5444
5445 (define_insn "floatdisf2"
5446   [(set (match_operand:SF 0 "register_operand" "=f")
5447         (float:SF (match_operand:DI 1 "register_operand" "e")))]
5448   "TARGET_V9 && TARGET_FPU"
5449   "fxtos\\t%1, %0"
5450   [(set_attr "type" "fp")
5451    (set_attr "fptype" "double")])
5452
5453 (define_expand "floatunsdisf2"
5454   [(use (match_operand:SF 0 "register_operand" ""))
5455    (use (match_operand:DI 1 "register_operand" ""))]
5456   "TARGET_ARCH64 && TARGET_FPU"
5457   "sparc_emit_floatunsdi (operands); DONE;")
5458
5459 (define_insn "floatdidf2"
5460   [(set (match_operand:DF 0 "register_operand" "=e")
5461         (float:DF (match_operand:DI 1 "register_operand" "e")))]
5462   "TARGET_V9 && TARGET_FPU"
5463   "fxtod\\t%1, %0"
5464   [(set_attr "type" "fp")
5465    (set_attr "fptype" "double")])
5466
5467 (define_expand "floatunsdidf2"
5468   [(use (match_operand:DF 0 "register_operand" ""))
5469    (use (match_operand:DI 1 "register_operand" ""))]
5470   "TARGET_ARCH64 && TARGET_FPU"
5471   "sparc_emit_floatunsdi (operands); DONE;")
5472
5473 (define_expand "floatditf2"
5474   [(set (match_operand:TF 0 "register_operand" "=e")
5475         (float:TF (match_operand:DI 1 "register_operand" "e")))]
5476   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5477   "
5478 {
5479   if (! TARGET_HARD_QUAD)
5480     {
5481       rtx slot0;
5482
5483       if (GET_CODE (operands[1]) != MEM)
5484         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5485       else
5486         slot0 = operands[1];
5487
5488       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5489                          VOIDmode, 2,
5490                          XEXP (slot0, 0), Pmode,
5491                          operands[1], DImode);
5492
5493       if (GET_CODE (operands[0]) != MEM)
5494         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5495       DONE;
5496     }
5497 }")
5498
5499 (define_insn "*floatditf2_hq"
5500   [(set (match_operand:TF 0 "register_operand" "=e")
5501         (float:TF (match_operand:DI 1 "register_operand" "e")))]
5502   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5503   "fxtoq\\t%1, %0"
5504   [(set_attr "type" "fp")])
5505
5506 (define_expand "floatunsditf2"
5507   [(set (match_operand:TF 0 "register_operand" "=e")
5508         (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5509   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5510   "
5511 {
5512   rtx slot0;
5513
5514   if (GET_CODE (operands[1]) != MEM)
5515     slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5516   else
5517     slot0 = operands[1];
5518
5519   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5520                      VOIDmode, 2,
5521                      XEXP (slot0, 0), Pmode,
5522                      operands[1], DImode);
5523
5524   if (GET_CODE (operands[0]) != MEM)
5525     emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5526   DONE;
5527 }")
5528
5529 ;; Convert a float to an actual integer.
5530 ;; Truncation is performed as part of the conversion.
5531
5532 (define_insn "fix_truncsfsi2"
5533   [(set (match_operand:SI 0 "register_operand" "=f")
5534         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5535   "TARGET_FPU"
5536   "fstoi\\t%1, %0"
5537   [(set_attr "type" "fp")
5538    (set_attr "fptype" "double")])
5539
5540 (define_insn "fix_truncdfsi2"
5541   [(set (match_operand:SI 0 "register_operand" "=f")
5542         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5543   "TARGET_FPU"
5544   "fdtoi\\t%1, %0"
5545   [(set_attr "type" "fp")
5546    (set_attr "fptype" "double")])
5547
5548 (define_expand "fix_trunctfsi2"
5549   [(set (match_operand:SI 0 "register_operand" "=f")
5550         (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5551   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5552   "
5553 {
5554   if (! TARGET_HARD_QUAD)
5555     {
5556       rtx slot0;
5557
5558       if (GET_CODE (operands[1]) != MEM)
5559         {
5560           slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5561           emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5562         }
5563       else
5564         slot0 = operands[1];
5565
5566       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5567                                operands[0], LCT_NORMAL, SImode, 1,
5568                                XEXP (slot0, 0), Pmode);
5569       DONE;
5570     }
5571 }")
5572
5573 (define_insn "*fix_trunctfsi2_hq"
5574   [(set (match_operand:SI 0 "register_operand" "=f")
5575         (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5576   "TARGET_FPU && TARGET_HARD_QUAD"
5577   "fqtoi\\t%1, %0"
5578   [(set_attr "type" "fp")])
5579
5580 (define_expand "fixuns_trunctfsi2"
5581   [(set (match_operand:SI 0 "register_operand" "=f")
5582         (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5583   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5584   "
5585 {
5586   rtx slot0;
5587
5588   if (GET_CODE (operands[1]) != MEM)
5589     {
5590       slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5591       emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5592     }
5593   else
5594     slot0 = operands[1];
5595
5596   emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5597                            operands[0], LCT_NORMAL, SImode, 1,
5598                            XEXP (slot0, 0), Pmode);
5599   DONE;
5600 }")
5601
5602 ;; Now the same, for V9 targets
5603
5604 (define_insn "fix_truncsfdi2"
5605   [(set (match_operand:DI 0 "register_operand" "=e")
5606         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5607   "TARGET_V9 && TARGET_FPU"
5608   "fstox\\t%1, %0"
5609   [(set_attr "type" "fp")
5610    (set_attr "fptype" "double")])
5611
5612 (define_insn "fix_truncdfdi2"
5613   [(set (match_operand:DI 0 "register_operand" "=e")
5614         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5615   "TARGET_V9 && TARGET_FPU"
5616   "fdtox\\t%1, %0"
5617   [(set_attr "type" "fp")
5618    (set_attr "fptype" "double")])
5619
5620 (define_expand "fix_trunctfdi2"
5621   [(set (match_operand:DI 0 "register_operand" "=e")
5622         (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5623   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5624   "
5625 {
5626   if (! TARGET_HARD_QUAD)
5627     {
5628       rtx slot0;
5629
5630       if (GET_CODE (operands[1]) != MEM)
5631         {
5632           slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5633           emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5634         }
5635       else
5636         slot0 = operands[1];
5637
5638       emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5639                                operands[0], LCT_NORMAL, DImode, 1,
5640                                XEXP (slot0, 0), Pmode);
5641       DONE;
5642     }
5643 }")
5644
5645 (define_insn "*fix_trunctfdi2_hq"
5646   [(set (match_operand:DI 0 "register_operand" "=e")
5647         (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5648   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5649   "fqtox\\t%1, %0"
5650   [(set_attr "type" "fp")])
5651
5652 (define_expand "fixuns_trunctfdi2"
5653   [(set (match_operand:DI 0 "register_operand" "=f")
5654         (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5655   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5656   "
5657 {
5658   rtx slot0;
5659
5660   if (GET_CODE (operands[1]) != MEM)
5661     {
5662       slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5663       emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5664     }
5665   else
5666     slot0 = operands[1];
5667
5668   emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5669                            operands[0], LCT_NORMAL, DImode, 1,
5670                            XEXP (slot0, 0), Pmode);
5671   DONE;
5672 }")
5673
5674 \f
5675 ;;- arithmetic instructions
5676
5677 (define_expand "adddi3"
5678   [(set (match_operand:DI 0 "register_operand" "=r")
5679         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5680                  (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5681   ""
5682   "
5683 {
5684   HOST_WIDE_INT i;
5685
5686   if (! TARGET_ARCH64)
5687     {
5688       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5689                           gen_rtx_SET (VOIDmode, operands[0],
5690                                    gen_rtx_PLUS (DImode, operands[1],
5691                                                  operands[2])),
5692                           gen_rtx_CLOBBER (VOIDmode,
5693                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5694       DONE;
5695     }
5696   if (arith_double_4096_operand(operands[2], DImode))
5697     {
5698       switch (GET_CODE (operands[1]))
5699         {
5700         case CONST_INT: i = INTVAL (operands[1]); break;
5701         case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5702         default:
5703           emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5704                                   gen_rtx_MINUS (DImode, operands[1],
5705                                                  GEN_INT(-4096))));
5706           DONE;
5707         }
5708       emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5709       DONE;
5710     }
5711 }")
5712
5713 (define_insn "adddi3_insn_sp32"
5714   [(set (match_operand:DI 0 "register_operand" "=r")
5715         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5716                  (match_operand:DI 2 "arith_double_operand" "rHI")))
5717    (clobber (reg:CC 100))]
5718   "! TARGET_ARCH64"
5719   "#"
5720   [(set_attr "length" "2")])
5721
5722 (define_split
5723   [(set (match_operand:DI 0 "register_operand" "")
5724         (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5725                  (match_operand:DI 2 "arith_double_operand" "")))
5726    (clobber (reg:CC 100))]
5727   "! TARGET_ARCH64 && reload_completed"
5728   [(parallel [(set (reg:CC_NOOV 100)
5729                    (compare:CC_NOOV (plus:SI (match_dup 4)
5730                                              (match_dup 5))
5731                                     (const_int 0)))
5732               (set (match_dup 3)
5733                    (plus:SI (match_dup 4) (match_dup 5)))])
5734    (set (match_dup 6)
5735         (plus:SI (plus:SI (match_dup 7)
5736                           (match_dup 8))
5737                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5738   "
5739 {
5740   operands[3] = gen_lowpart (SImode, operands[0]);
5741   operands[4] = gen_lowpart (SImode, operands[1]);
5742   operands[5] = gen_lowpart (SImode, operands[2]);
5743   operands[6] = gen_highpart (SImode, operands[0]);
5744   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5745 #if HOST_BITS_PER_WIDE_INT == 32
5746   if (GET_CODE (operands[2]) == CONST_INT)
5747     {
5748       if (INTVAL (operands[2]) < 0)
5749         operands[8] = constm1_rtx;
5750       else
5751         operands[8] = const0_rtx;
5752     }
5753   else
5754 #endif
5755     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5756 }")
5757
5758 (define_split
5759   [(set (match_operand:DI 0 "register_operand" "")
5760         (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5761                   (match_operand:DI 2 "arith_double_operand" "")))
5762    (clobber (reg:CC 100))]
5763   "! TARGET_ARCH64 && reload_completed"
5764   [(parallel [(set (reg:CC_NOOV 100)
5765                    (compare:CC_NOOV (minus:SI (match_dup 4)
5766                                               (match_dup 5))
5767                                     (const_int 0)))
5768               (set (match_dup 3)
5769                    (minus:SI (match_dup 4) (match_dup 5)))])
5770    (set (match_dup 6)
5771         (minus:SI (minus:SI (match_dup 7)
5772                             (match_dup 8))
5773                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5774   "
5775 {
5776   operands[3] = gen_lowpart (SImode, operands[0]);
5777   operands[4] = gen_lowpart (SImode, operands[1]);
5778   operands[5] = gen_lowpart (SImode, operands[2]);
5779   operands[6] = gen_highpart (SImode, operands[0]);
5780   operands[7] = gen_highpart (SImode, operands[1]);
5781 #if HOST_BITS_PER_WIDE_INT == 32
5782   if (GET_CODE (operands[2]) == CONST_INT)
5783     {
5784       if (INTVAL (operands[2]) < 0)
5785         operands[8] = constm1_rtx;
5786       else
5787         operands[8] = const0_rtx;
5788     }
5789   else
5790 #endif
5791     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5792 }")
5793
5794 ;; LTU here means "carry set"
5795 (define_insn "addx"
5796   [(set (match_operand:SI 0 "register_operand" "=r")
5797         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5798                           (match_operand:SI 2 "arith_operand" "rI"))
5799                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5800   ""
5801   "addx\\t%1, %2, %0"
5802   [(set_attr "type" "misc")])
5803
5804 (define_insn "*addx_extend_sp32"
5805   [(set (match_operand:DI 0 "register_operand" "=r")
5806         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5807                                           (match_operand:SI 2 "arith_operand" "rI"))
5808                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5809   "! TARGET_ARCH64"
5810   "#"
5811   [(set_attr "length" "2")])
5812
5813 (define_split
5814   [(set (match_operand:DI 0 "register_operand" "")
5815         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5816                                           (match_operand:SI 2 "arith_operand" ""))
5817                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5818   "! TARGET_ARCH64 && reload_completed"
5819   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5820                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5821    (set (match_dup 4) (const_int 0))]
5822   "operands[3] = gen_lowpart (SImode, operands[0]);
5823    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5824
5825 (define_insn "*addx_extend_sp64"
5826   [(set (match_operand:DI 0 "register_operand" "=r")
5827         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5828                                           (match_operand:SI 2 "arith_operand" "rI"))
5829                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5830   "TARGET_ARCH64"
5831   "addx\\t%r1, %2, %0"
5832   [(set_attr "type" "misc")])
5833
5834 (define_insn "subx"
5835   [(set (match_operand:SI 0 "register_operand" "=r")
5836         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5837                             (match_operand:SI 2 "arith_operand" "rI"))
5838                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5839   ""
5840   "subx\\t%r1, %2, %0"
5841   [(set_attr "type" "misc")])
5842
5843 (define_insn "*subx_extend_sp64"
5844   [(set (match_operand:DI 0 "register_operand" "=r")
5845         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5846                                             (match_operand:SI 2 "arith_operand" "rI"))
5847                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5848   "TARGET_ARCH64"
5849   "subx\\t%r1, %2, %0"
5850   [(set_attr "type" "misc")])
5851
5852 (define_insn "*subx_extend"
5853   [(set (match_operand:DI 0 "register_operand" "=r")
5854         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5855                                             (match_operand:SI 2 "arith_operand" "rI"))
5856                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5857   "! TARGET_ARCH64"
5858   "#"
5859   [(set_attr "length" "2")])
5860
5861 (define_split
5862   [(set (match_operand:DI 0 "register_operand" "")
5863         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5864                                             (match_operand:SI 2 "arith_operand" ""))
5865                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5866   "! TARGET_ARCH64 && reload_completed"
5867   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5868                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5869    (set (match_dup 4) (const_int 0))]
5870   "operands[3] = gen_lowpart (SImode, operands[0]);
5871    operands[4] = gen_highpart (SImode, operands[0]);")
5872
5873 (define_insn ""
5874   [(set (match_operand:DI 0 "register_operand" "=r")
5875         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5876                  (match_operand:DI 2 "register_operand" "r")))
5877    (clobber (reg:CC 100))]
5878   "! TARGET_ARCH64"
5879   "#"
5880   [(set_attr "length" "2")])
5881
5882 (define_split
5883   [(set (match_operand:DI 0 "register_operand" "")
5884         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5885                  (match_operand:DI 2 "register_operand" "")))
5886    (clobber (reg:CC 100))]
5887   "! TARGET_ARCH64 && reload_completed"
5888   [(parallel [(set (reg:CC_NOOV 100)
5889                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5890                                     (const_int 0)))
5891               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5892    (set (match_dup 6)
5893         (plus:SI (plus:SI (match_dup 4) (const_int 0))
5894                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5895   "operands[3] = gen_lowpart (SImode, operands[2]);
5896    operands[4] = gen_highpart (SImode, operands[2]);
5897    operands[5] = gen_lowpart (SImode, operands[0]);
5898    operands[6] = gen_highpart (SImode, operands[0]);")
5899
5900 (define_insn "*adddi3_sp64"
5901   [(set (match_operand:DI 0 "register_operand" "=r")
5902         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5903                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5904   "TARGET_ARCH64"
5905   "add\\t%1, %2, %0")
5906
5907 (define_expand "addsi3"
5908   [(set (match_operand:SI 0 "register_operand" "=r,d")
5909         (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5910                  (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5911   ""
5912   "
5913 {
5914   if (arith_4096_operand(operands[2], SImode))
5915     {
5916       if (GET_CODE (operands[1]) == CONST_INT)
5917         emit_insn (gen_movsi (operands[0],
5918                               GEN_INT (INTVAL (operands[1]) + 4096)));
5919       else
5920         emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5921                                 gen_rtx_MINUS (SImode, operands[1],
5922                                                GEN_INT(-4096))));
5923       DONE;
5924     }
5925 }")
5926
5927 (define_insn "*addsi3"
5928   [(set (match_operand:SI 0 "register_operand" "=r,d")
5929         (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5930                  (match_operand:SI 2 "arith_operand" "rI,d")))]
5931   ""
5932   "@
5933    add\\t%1, %2, %0
5934    fpadd32s\\t%1, %2, %0"
5935   [(set_attr "type" "*,fp")])
5936
5937 (define_insn "*cmp_cc_plus"
5938   [(set (reg:CC_NOOV 100)
5939         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5940                                   (match_operand:SI 1 "arith_operand" "rI"))
5941                          (const_int 0)))]
5942   ""
5943   "addcc\\t%0, %1, %%g0"
5944   [(set_attr "type" "compare")])
5945
5946 (define_insn "*cmp_ccx_plus"
5947   [(set (reg:CCX_NOOV 100)
5948         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5949                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
5950                           (const_int 0)))]
5951   "TARGET_ARCH64"
5952   "addcc\\t%0, %1, %%g0"
5953   [(set_attr "type" "compare")])
5954
5955 (define_insn "*cmp_cc_plus_set"
5956   [(set (reg:CC_NOOV 100)
5957         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5958                                   (match_operand:SI 2 "arith_operand" "rI"))
5959                          (const_int 0)))
5960    (set (match_operand:SI 0 "register_operand" "=r")
5961         (plus:SI (match_dup 1) (match_dup 2)))]
5962   ""
5963   "addcc\\t%1, %2, %0"
5964   [(set_attr "type" "compare")])
5965
5966 (define_insn "*cmp_ccx_plus_set"
5967   [(set (reg:CCX_NOOV 100)
5968         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5969                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
5970                           (const_int 0)))
5971    (set (match_operand:DI 0 "register_operand" "=r")
5972         (plus:DI (match_dup 1) (match_dup 2)))]
5973   "TARGET_ARCH64"
5974   "addcc\\t%1, %2, %0"
5975   [(set_attr "type" "compare")])
5976
5977 (define_expand "subdi3"
5978   [(set (match_operand:DI 0 "register_operand" "=r")
5979         (minus:DI (match_operand:DI 1 "register_operand" "r")
5980                   (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5981   ""
5982   "
5983 {
5984   if (! TARGET_ARCH64)
5985     {
5986       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5987                           gen_rtx_SET (VOIDmode, operands[0],
5988                                    gen_rtx_MINUS (DImode, operands[1],
5989                                                   operands[2])),
5990                           gen_rtx_CLOBBER (VOIDmode,
5991                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5992       DONE;
5993     }
5994   if (arith_double_4096_operand(operands[2], DImode))
5995     {
5996       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5997                               gen_rtx_PLUS (DImode, operands[1],
5998                                             GEN_INT(-4096))));
5999       DONE;
6000     }
6001 }")
6002
6003 (define_insn "*subdi3_sp32"
6004   [(set (match_operand:DI 0 "register_operand" "=r")
6005         (minus:DI (match_operand:DI 1 "register_operand" "r")
6006                   (match_operand:DI 2 "arith_double_operand" "rHI")))
6007    (clobber (reg:CC 100))]
6008   "! TARGET_ARCH64"
6009   "#"
6010   [(set_attr "length" "2")])
6011
6012 (define_split
6013   [(set (match_operand:DI 0 "register_operand" "")
6014         (minus:DI (match_operand:DI 1 "register_operand" "")
6015                   (match_operand:DI 2 "arith_double_operand" "")))
6016    (clobber (reg:CC 100))]
6017   "! TARGET_ARCH64
6018    && reload_completed
6019    && (GET_CODE (operands[2]) == CONST_INT
6020        || GET_CODE (operands[2]) == CONST_DOUBLE)"
6021   [(clobber (const_int 0))]
6022   "
6023 {
6024   rtx highp, lowp;
6025
6026   highp = gen_highpart_mode (SImode, DImode, operands[2]);
6027   lowp = gen_lowpart (SImode, operands[2]);
6028   if ((lowp == const0_rtx)
6029       && (operands[0] == operands[1]))
6030     {
6031       emit_insn (gen_rtx_SET (VOIDmode,
6032                               gen_highpart (SImode, operands[0]),
6033                               gen_rtx_MINUS (SImode,
6034                                              gen_highpart_mode (SImode, DImode,
6035                                                                 operands[1]),
6036                                              highp)));
6037     }
6038   else
6039     {
6040       emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
6041                                        gen_lowpart (SImode, operands[1]),
6042                                        lowp));
6043       emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
6044                            gen_highpart_mode (SImode, DImode, operands[1]),
6045                            highp));
6046     }
6047   DONE;
6048 }")
6049
6050 (define_split
6051   [(set (match_operand:DI 0 "register_operand" "")
6052         (minus:DI (match_operand:DI 1 "register_operand" "")
6053                   (match_operand:DI 2 "register_operand" "")))
6054    (clobber (reg:CC 100))]
6055   "! TARGET_ARCH64
6056    && reload_completed"
6057   [(clobber (const_int 0))]
6058   "
6059 {
6060   emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
6061                                    gen_lowpart (SImode, operands[1]),
6062                                    gen_lowpart (SImode, operands[2])));
6063   emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
6064                        gen_highpart (SImode, operands[1]),
6065                        gen_highpart (SImode, operands[2])));
6066   DONE;
6067 }")
6068
6069 (define_insn ""
6070   [(set (match_operand:DI 0 "register_operand" "=r")
6071       (minus:DI (match_operand:DI 1 "register_operand" "r")
6072                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
6073    (clobber (reg:CC 100))]
6074   "! TARGET_ARCH64"
6075   "#"
6076   [(set_attr "length" "2")])
6077
6078 (define_split
6079   [(set (match_operand:DI 0 "register_operand" "")
6080         (minus:DI (match_operand:DI 1 "register_operand" "")
6081                   (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
6082    (clobber (reg:CC 100))]
6083   "! TARGET_ARCH64 && reload_completed"
6084   [(parallel [(set (reg:CC_NOOV 100)
6085                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
6086                                     (const_int 0)))
6087               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
6088    (set (match_dup 6)
6089         (minus:SI (minus:SI (match_dup 4) (const_int 0))
6090                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
6091   "operands[3] = gen_lowpart (SImode, operands[1]);
6092    operands[4] = gen_highpart (SImode, operands[1]);
6093    operands[5] = gen_lowpart (SImode, operands[0]);
6094    operands[6] = gen_highpart (SImode, operands[0]);")
6095
6096 (define_insn "*subdi3_sp64"
6097   [(set (match_operand:DI 0 "register_operand" "=r")
6098         (minus:DI (match_operand:DI 1 "register_operand" "r")
6099                   (match_operand:DI 2 "arith_double_operand" "rHI")))]
6100   "TARGET_ARCH64"
6101   "sub\\t%1, %2, %0")
6102
6103 (define_expand "subsi3"
6104   [(set (match_operand:SI 0 "register_operand" "=r,d")
6105         (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6106                   (match_operand:SI 2 "arith_add_operand" "rI,d")))]
6107   ""
6108   "
6109 {
6110   if (arith_4096_operand(operands[2], SImode))
6111     {
6112       emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6113                               gen_rtx_PLUS (SImode, operands[1],
6114                                             GEN_INT(-4096))));
6115       DONE;
6116     }
6117 }")
6118
6119 (define_insn "*subsi3"
6120   [(set (match_operand:SI 0 "register_operand" "=r,d")
6121         (minus:SI (match_operand:SI 1 "register_operand" "r,d")
6122                   (match_operand:SI 2 "arith_operand" "rI,d")))]
6123   ""
6124   "@
6125    sub\\t%1, %2, %0
6126    fpsub32s\\t%1, %2, %0"
6127   [(set_attr "type" "*,fp")])
6128
6129 (define_insn "*cmp_minus_cc"
6130   [(set (reg:CC_NOOV 100)
6131         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
6132                                    (match_operand:SI 1 "arith_operand" "rI"))
6133                          (const_int 0)))]
6134   ""
6135   "subcc\\t%r0, %1, %%g0"
6136   [(set_attr "type" "compare")])
6137
6138 (define_insn "*cmp_minus_ccx"
6139   [(set (reg:CCX_NOOV 100)
6140         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
6141                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
6142                           (const_int 0)))]
6143   "TARGET_ARCH64"
6144   "subcc\\t%0, %1, %%g0"
6145   [(set_attr "type" "compare")])
6146
6147 (define_insn "cmp_minus_cc_set"
6148   [(set (reg:CC_NOOV 100)
6149         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6150                                    (match_operand:SI 2 "arith_operand" "rI"))
6151                          (const_int 0)))
6152    (set (match_operand:SI 0 "register_operand" "=r")
6153         (minus:SI (match_dup 1) (match_dup 2)))]
6154   ""
6155   "subcc\\t%r1, %2, %0"
6156   [(set_attr "type" "compare")])
6157
6158 (define_insn "*cmp_minus_ccx_set"
6159   [(set (reg:CCX_NOOV 100)
6160         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6161                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
6162                           (const_int 0)))
6163    (set (match_operand:DI 0 "register_operand" "=r")
6164         (minus:DI (match_dup 1) (match_dup 2)))]
6165   "TARGET_ARCH64"
6166   "subcc\\t%1, %2, %0"
6167   [(set_attr "type" "compare")])
6168 \f
6169 ;; Integer Multiply/Divide.
6170
6171 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6172 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6173
6174 (define_insn "mulsi3"
6175   [(set (match_operand:SI 0 "register_operand" "=r")
6176         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6177                  (match_operand:SI 2 "arith_operand" "rI")))]
6178   "TARGET_HARD_MUL"
6179   "smul\\t%1, %2, %0"
6180   [(set_attr "type" "imul")])
6181
6182 (define_expand "muldi3"
6183   [(set (match_operand:DI 0 "register_operand" "=r")
6184         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6185                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
6186   "TARGET_ARCH64 || TARGET_V8PLUS"
6187   "
6188 {
6189   if (TARGET_V8PLUS)
6190     {
6191       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6192       DONE;
6193     }
6194 }")
6195
6196 (define_insn "*muldi3_sp64"
6197   [(set (match_operand:DI 0 "register_operand" "=r")
6198         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6199                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
6200   "TARGET_ARCH64"
6201   "mulx\\t%1, %2, %0"
6202   [(set_attr "type" "imul")])
6203
6204 ;; V8plus wide multiply.
6205 ;; XXX
6206 (define_insn "muldi3_v8plus"
6207   [(set (match_operand:DI 0 "register_operand" "=r,h")
6208         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6209                  (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6210    (clobber (match_scratch:SI 3 "=&h,X"))
6211    (clobber (match_scratch:SI 4 "=&h,X"))]
6212   "TARGET_V8PLUS"
6213   "*
6214 {
6215   if (sparc_check_64 (operands[1], insn) <= 0)
6216     output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6217   if (which_alternative == 1)
6218     output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6219   if (GET_CODE (operands[2]) == CONST_INT)
6220     {
6221       if (which_alternative == 1)
6222         return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6223       else
6224         return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
6225     }
6226   if (sparc_check_64 (operands[2], insn) <= 0)
6227     output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6228   if (which_alternative == 1)
6229     return \"or\\t%L1, %H1, %H1\\n\\tsllx\\t%H2, 32, %L1\\n\\tor\\t%L2, %L1, %L1\\n\\tmulx\\t%H1, %L1, %L0\;srlx\\t%L0, 32, %H0\";
6230   else
6231     return \"sllx\\t%H1, 32, %3\\n\\tsllx\\t%H2, 32, %4\\n\\tor\\t%L1, %3, %3\\n\\tor\\t%L2, %4, %4\\n\\tmulx\\t%3, %4, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
6232 }"
6233   [(set_attr "type" "multi")
6234    (set_attr "length" "9,8")])
6235
6236 (define_insn "*cmp_mul_set"
6237   [(set (reg:CC 100)
6238         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6239                     (match_operand:SI 2 "arith_operand" "rI"))
6240                     (const_int 0)))
6241    (set (match_operand:SI 0 "register_operand" "=r")
6242         (mult:SI (match_dup 1) (match_dup 2)))]
6243   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6244   "smulcc\\t%1, %2, %0"
6245   [(set_attr "type" "imul")])
6246
6247 (define_expand "mulsidi3"
6248   [(set (match_operand:DI 0 "register_operand" "")
6249         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6250                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6251   "TARGET_HARD_MUL"
6252   "
6253 {
6254   if (CONSTANT_P (operands[2]))
6255     {
6256       if (TARGET_V8PLUS)
6257         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6258                                               operands[2]));
6259       else
6260         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6261                                             operands[2]));
6262       DONE;
6263     }
6264   if (TARGET_V8PLUS)
6265     {
6266       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6267       DONE;
6268     }
6269 }")
6270
6271 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
6272 ;; registers can hold 64 bit values in the V8plus environment.
6273 ;; XXX
6274 (define_insn "mulsidi3_v8plus"
6275   [(set (match_operand:DI 0 "register_operand" "=h,r")
6276         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6277                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6278    (clobber (match_scratch:SI 3 "=X,&h"))]
6279   "TARGET_V8PLUS"
6280   "@
6281    smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6282    smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6283   [(set_attr "type" "multi")
6284    (set_attr "length" "2,3")])
6285
6286 ;; XXX
6287 (define_insn "const_mulsidi3_v8plus"
6288   [(set (match_operand:DI 0 "register_operand" "=h,r")
6289         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6290                  (match_operand:SI 2 "small_int" "I,I")))
6291    (clobber (match_scratch:SI 3 "=X,&h"))]
6292   "TARGET_V8PLUS"
6293   "@
6294    smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6295    smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6296   [(set_attr "type" "multi")
6297    (set_attr "length" "2,3")])
6298
6299 ;; XXX
6300 (define_insn "*mulsidi3_sp32"
6301   [(set (match_operand:DI 0 "register_operand" "=r")
6302         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6303                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6304   "TARGET_HARD_MUL32"
6305   "*
6306 {
6307   return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6308 }"
6309   [(set (attr "type")
6310         (if_then_else (eq_attr "isa" "sparclet")
6311                       (const_string "imul") (const_string "multi")))
6312    (set (attr "length")
6313         (if_then_else (eq_attr "isa" "sparclet")
6314                       (const_int 1) (const_int 2)))])
6315
6316 (define_insn "*mulsidi3_sp64"
6317   [(set (match_operand:DI 0 "register_operand" "=r")
6318         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6319                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6320   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6321   "smul\\t%1, %2, %0"
6322   [(set_attr "type" "imul")])
6323
6324 ;; Extra pattern, because sign_extend of a constant isn't valid.
6325
6326 ;; XXX
6327 (define_insn "const_mulsidi3_sp32"
6328   [(set (match_operand:DI 0 "register_operand" "=r")
6329         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6330                  (match_operand:SI 2 "small_int" "I")))]
6331   "TARGET_HARD_MUL32"
6332   "*
6333 {
6334   return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6335 }"
6336   [(set (attr "type")
6337         (if_then_else (eq_attr "isa" "sparclet")
6338                       (const_string "imul") (const_string "multi")))
6339    (set (attr "length")
6340         (if_then_else (eq_attr "isa" "sparclet")
6341                       (const_int 1) (const_int 2)))])
6342
6343 (define_insn "const_mulsidi3_sp64"
6344   [(set (match_operand:DI 0 "register_operand" "=r")
6345         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6346                  (match_operand:SI 2 "small_int" "I")))]
6347   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6348   "smul\\t%1, %2, %0"
6349   [(set_attr "type" "imul")])
6350
6351 (define_expand "smulsi3_highpart"
6352   [(set (match_operand:SI 0 "register_operand" "")
6353         (truncate:SI
6354          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6355                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6356                       (const_int 32))))]
6357   "TARGET_HARD_MUL && TARGET_ARCH32"
6358   "
6359 {
6360   if (CONSTANT_P (operands[2]))
6361     {
6362       if (TARGET_V8PLUS)
6363         {
6364           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6365                                                         operands[1],
6366                                                         operands[2],
6367                                                         GEN_INT (32)));
6368           DONE;
6369         }
6370       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6371       DONE;
6372     }
6373   if (TARGET_V8PLUS)
6374     {
6375       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6376                                               operands[2], GEN_INT (32)));
6377       DONE;
6378     }
6379 }")
6380
6381 ;; XXX
6382 (define_insn "smulsi3_highpart_v8plus"
6383   [(set (match_operand:SI 0 "register_operand" "=h,r")
6384         (truncate:SI
6385          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6386                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6387                       (match_operand:SI 3 "const_int_operand" "i,i"))))
6388    (clobber (match_scratch:SI 4 "=X,&h"))]
6389   "TARGET_V8PLUS"
6390   "@
6391    smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6392    smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6393   [(set_attr "type" "multi")
6394    (set_attr "length" "2")])
6395
6396 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6397 ;; XXX
6398 (define_insn ""
6399   [(set (match_operand:SI 0 "register_operand" "=h,r")
6400         (subreg:SI
6401          (lshiftrt:DI
6402           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6403                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6404           (match_operand:SI 3 "const_int_operand" "i,i"))
6405          4))
6406    (clobber (match_scratch:SI 4 "=X,&h"))]
6407   "TARGET_V8PLUS"
6408   "@
6409    smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6410    smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6411   [(set_attr "type" "multi")
6412    (set_attr "length" "2")])
6413
6414 ;; XXX
6415 (define_insn "const_smulsi3_highpart_v8plus"
6416   [(set (match_operand:SI 0 "register_operand" "=h,r")
6417         (truncate:SI
6418          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6419                                (match_operand 2 "small_int" "i,i"))
6420                       (match_operand:SI 3 "const_int_operand" "i,i"))))
6421    (clobber (match_scratch:SI 4 "=X,&h"))]
6422   "TARGET_V8PLUS"
6423   "@
6424    smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6425    smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6426   [(set_attr "type" "multi")
6427    (set_attr "length" "2")])
6428
6429 ;; XXX
6430 (define_insn "*smulsi3_highpart_sp32"
6431   [(set (match_operand:SI 0 "register_operand" "=r")
6432         (truncate:SI
6433          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6434                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6435                       (const_int 32))))]
6436   "TARGET_HARD_MUL32"
6437   "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6438   [(set_attr "type" "multi")
6439    (set_attr "length" "2")])
6440
6441 ;; XXX
6442 (define_insn "const_smulsi3_highpart"
6443   [(set (match_operand:SI 0 "register_operand" "=r")
6444         (truncate:SI
6445          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6446                                (match_operand:SI 2 "register_operand" "r"))
6447                       (const_int 32))))]
6448   "TARGET_HARD_MUL32"
6449   "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6450   [(set_attr "type" "multi")
6451    (set_attr "length" "2")])
6452
6453 (define_expand "umulsidi3"
6454   [(set (match_operand:DI 0 "register_operand" "")
6455         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6456                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6457   "TARGET_HARD_MUL"
6458   "
6459 {
6460   if (CONSTANT_P (operands[2]))
6461     {
6462       if (TARGET_V8PLUS)
6463         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6464                                                operands[2]));
6465       else
6466         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6467                                              operands[2]));
6468       DONE;
6469     }
6470   if (TARGET_V8PLUS)
6471     {
6472       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6473       DONE;
6474     }
6475 }")
6476
6477 ;; XXX
6478 (define_insn "umulsidi3_v8plus"
6479   [(set (match_operand:DI 0 "register_operand" "=h,r")
6480         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6481                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6482    (clobber (match_scratch:SI 3 "=X,&h"))]
6483   "TARGET_V8PLUS"
6484   "@
6485    umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6486    umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6487   [(set_attr "type" "multi")
6488    (set_attr "length" "2,3")])
6489
6490 ;; XXX
6491 (define_insn "*umulsidi3_sp32"
6492   [(set (match_operand:DI 0 "register_operand" "=r")
6493         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6494                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6495   "TARGET_HARD_MUL32"
6496   "*
6497 {
6498   return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6499 }"
6500   [(set (attr "type")
6501         (if_then_else (eq_attr "isa" "sparclet")
6502                       (const_string "imul") (const_string "multi")))
6503    (set (attr "length")
6504         (if_then_else (eq_attr "isa" "sparclet")
6505                       (const_int 1) (const_int 2)))])
6506
6507 (define_insn "*umulsidi3_sp64"
6508   [(set (match_operand:DI 0 "register_operand" "=r")
6509         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6510                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6511   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6512   "umul\\t%1, %2, %0"
6513   [(set_attr "type" "imul")])
6514
6515 ;; Extra pattern, because sign_extend of a constant isn't valid.
6516
6517 ;; XXX
6518 (define_insn "const_umulsidi3_sp32"
6519   [(set (match_operand:DI 0 "register_operand" "=r")
6520         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6521                  (match_operand:SI 2 "uns_small_int" "")))]
6522   "TARGET_HARD_MUL32"
6523   "*
6524 {
6525   return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6526 }"
6527   [(set (attr "type")
6528         (if_then_else (eq_attr "isa" "sparclet")
6529                       (const_string "imul") (const_string "multi")))
6530    (set (attr "length")
6531         (if_then_else (eq_attr "isa" "sparclet")
6532                       (const_int 1) (const_int 2)))])
6533
6534 (define_insn "const_umulsidi3_sp64"
6535   [(set (match_operand:DI 0 "register_operand" "=r")
6536         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6537                  (match_operand:SI 2 "uns_small_int" "")))]
6538   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6539   "umul\\t%1, %2, %0"
6540   [(set_attr "type" "imul")])
6541
6542 ;; XXX
6543 (define_insn "const_umulsidi3_v8plus"
6544   [(set (match_operand:DI 0 "register_operand" "=h,r")
6545         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6546                  (match_operand:SI 2 "uns_small_int" "")))
6547    (clobber (match_scratch:SI 3 "=X,h"))]
6548   "TARGET_V8PLUS"
6549   "@
6550    umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6551    umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6552   [(set_attr "type" "multi")
6553    (set_attr "length" "2,3")])
6554
6555 (define_expand "umulsi3_highpart"
6556   [(set (match_operand:SI 0 "register_operand" "")
6557         (truncate:SI
6558          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6559                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6560                       (const_int 32))))]
6561   "TARGET_HARD_MUL && TARGET_ARCH32"
6562   "
6563 {
6564   if (CONSTANT_P (operands[2]))
6565     {
6566       if (TARGET_V8PLUS)
6567         {
6568           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6569                                                         operands[1],
6570                                                         operands[2],
6571                                                         GEN_INT (32)));
6572           DONE;
6573         }
6574       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6575       DONE;
6576     }
6577   if (TARGET_V8PLUS)
6578     {
6579       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6580                                               operands[2], GEN_INT (32)));
6581       DONE;
6582     }
6583 }")
6584
6585 ;; XXX
6586 (define_insn "umulsi3_highpart_v8plus"
6587   [(set (match_operand:SI 0 "register_operand" "=h,r")
6588         (truncate:SI
6589          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6590                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6591                       (match_operand:SI 3 "const_int_operand" "i,i"))))
6592    (clobber (match_scratch:SI 4 "=X,h"))]
6593   "TARGET_V8PLUS"
6594   "@
6595    umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6596    umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6597   [(set_attr "type" "multi")
6598    (set_attr "length" "2")])
6599
6600 ;; XXX
6601 (define_insn "const_umulsi3_highpart_v8plus"
6602   [(set (match_operand:SI 0 "register_operand" "=h,r")
6603         (truncate:SI
6604          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6605                                (match_operand:SI 2 "uns_small_int" ""))
6606                       (match_operand:SI 3 "const_int_operand" "i,i"))))
6607    (clobber (match_scratch:SI 4 "=X,h"))]
6608   "TARGET_V8PLUS"
6609   "@
6610    umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6611    umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6612   [(set_attr "type" "multi")
6613    (set_attr "length" "2")])
6614
6615 ;; XXX
6616 (define_insn "*umulsi3_highpart_sp32"
6617   [(set (match_operand:SI 0 "register_operand" "=r")
6618         (truncate:SI
6619          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6620                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6621                       (const_int 32))))]
6622   "TARGET_HARD_MUL32"
6623   "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6624   [(set_attr "type" "multi")
6625    (set_attr "length" "2")])
6626
6627 ;; XXX
6628 (define_insn "const_umulsi3_highpart"
6629   [(set (match_operand:SI 0 "register_operand" "=r")
6630         (truncate:SI
6631          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6632                                (match_operand:SI 2 "uns_small_int" ""))
6633                       (const_int 32))))]
6634   "TARGET_HARD_MUL32"
6635   "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6636   [(set_attr "type" "multi")
6637    (set_attr "length" "2")])
6638
6639 ;; The v8 architecture specifies that there must be 3 instructions between
6640 ;; a y register write and a use of it for correct results.
6641
6642 (define_expand "divsi3"
6643   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6644                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
6645                            (match_operand:SI 2 "input_operand" "rI,m")))
6646               (clobber (match_scratch:SI 3 "=&r,&r"))])]
6647   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6648   "
6649 {
6650   if (TARGET_ARCH64)
6651     {
6652       operands[3] = gen_reg_rtx(SImode);
6653       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6654       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6655                                   operands[3]));
6656       DONE;
6657     }
6658 }")
6659
6660 (define_insn "divsi3_sp32"
6661   [(set (match_operand:SI 0 "register_operand" "=r,r")
6662         (div:SI (match_operand:SI 1 "register_operand" "r,r")
6663                 (match_operand:SI 2 "input_operand" "rI,m")))
6664    (clobber (match_scratch:SI 3 "=&r,&r"))]
6665   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6666    && TARGET_ARCH32"
6667   "*
6668 {
6669   if (which_alternative == 0)
6670     if (TARGET_V9)
6671       return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6672     else
6673       return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6674   else
6675     if (TARGET_V9)
6676       return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6677     else
6678       return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
6679 }"
6680   [(set_attr "type" "multi")
6681    (set (attr "length")
6682         (if_then_else (eq_attr "isa" "v9")
6683                       (const_int 4) (const_int 6)))])
6684
6685 (define_insn "divsi3_sp64"
6686   [(set (match_operand:SI 0 "register_operand" "=r")
6687         (div:SI (match_operand:SI 1 "register_operand" "r")
6688                 (match_operand:SI 2 "input_operand" "rI")))
6689    (use (match_operand:SI 3 "register_operand" "r"))]
6690   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6691   "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6692   [(set_attr "type" "multi")
6693    (set_attr "length" "2")])
6694
6695 (define_insn "divdi3"
6696   [(set (match_operand:DI 0 "register_operand" "=r")
6697         (div:DI (match_operand:DI 1 "register_operand" "r")
6698                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6699   "TARGET_ARCH64"
6700   "sdivx\\t%1, %2, %0"
6701   [(set_attr "type" "idiv")])
6702
6703 (define_insn "*cmp_sdiv_cc_set"
6704   [(set (reg:CC 100)
6705         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6706                             (match_operand:SI 2 "arith_operand" "rI"))
6707                     (const_int 0)))
6708    (set (match_operand:SI 0 "register_operand" "=r")
6709         (div:SI (match_dup 1) (match_dup 2)))
6710    (clobber (match_scratch:SI 3 "=&r"))]
6711   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6712   "*
6713 {
6714   if (TARGET_V9)
6715     return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6716   else
6717     return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6718 }"
6719   [(set_attr "type" "multi")
6720    (set (attr "length")
6721         (if_then_else (eq_attr "isa" "v9")
6722                       (const_int 3) (const_int 6)))])
6723
6724 ;; XXX
6725 (define_expand "udivsi3"
6726   [(set (match_operand:SI 0 "register_operand" "")
6727         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6728                  (match_operand:SI 2 "input_operand" "")))]
6729   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6730   "")
6731
6732 (define_insn "udivsi3_sp32"
6733   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6734         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6735                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
6736   "(TARGET_V8
6737     || TARGET_DEPRECATED_V8_INSNS)
6738    && TARGET_ARCH32"
6739   "*
6740 {
6741   output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6742   switch (which_alternative)
6743     {
6744     default:
6745       return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6746     case 1:
6747       return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6748     case 2:
6749       return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6750     }
6751 }"
6752   [(set_attr "type" "multi")
6753    (set_attr "length" "5")])
6754
6755 (define_insn "udivsi3_sp64"
6756   [(set (match_operand:SI 0 "register_operand" "=r")
6757         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6758                  (match_operand:SI 2 "input_operand" "rI")))]
6759   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6760   "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6761   [(set_attr "type" "multi")
6762    (set_attr "length" "2")])
6763
6764 (define_insn "udivdi3"
6765   [(set (match_operand:DI 0 "register_operand" "=r")
6766         (udiv:DI (match_operand:DI 1 "register_operand" "r")
6767                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
6768   "TARGET_ARCH64"
6769   "udivx\\t%1, %2, %0"
6770   [(set_attr "type" "idiv")])
6771
6772 (define_insn "*cmp_udiv_cc_set"
6773   [(set (reg:CC 100)
6774         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6775                              (match_operand:SI 2 "arith_operand" "rI"))
6776                     (const_int 0)))
6777    (set (match_operand:SI 0 "register_operand" "=r")
6778         (udiv:SI (match_dup 1) (match_dup 2)))]
6779   "TARGET_V8
6780    || TARGET_DEPRECATED_V8_INSNS"
6781   "*
6782 {
6783   if (TARGET_V9)
6784     return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6785   else
6786     return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6787 }"
6788   [(set_attr "type" "multi")
6789    (set (attr "length")
6790         (if_then_else (eq_attr "isa" "v9")
6791                       (const_int 2) (const_int 5)))])
6792
6793 ; sparclet multiply/accumulate insns
6794
6795 (define_insn "*smacsi"
6796   [(set (match_operand:SI 0 "register_operand" "=r")
6797         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6798                           (match_operand:SI 2 "arith_operand" "rI"))
6799                  (match_operand:SI 3 "register_operand" "0")))]
6800   "TARGET_SPARCLET"
6801   "smac\\t%1, %2, %0"
6802   [(set_attr "type" "imul")])
6803
6804 (define_insn "*smacdi"
6805   [(set (match_operand:DI 0 "register_operand" "=r")
6806         (plus:DI (mult:DI (sign_extend:DI
6807                            (match_operand:SI 1 "register_operand" "%r"))
6808                           (sign_extend:DI
6809                            (match_operand:SI 2 "register_operand" "r")))
6810                  (match_operand:DI 3 "register_operand" "0")))]
6811   "TARGET_SPARCLET"
6812   "smacd\\t%1, %2, %L0"
6813   [(set_attr "type" "imul")])
6814
6815 (define_insn "*umacdi"
6816   [(set (match_operand:DI 0 "register_operand" "=r")
6817         (plus:DI (mult:DI (zero_extend:DI
6818                            (match_operand:SI 1 "register_operand" "%r"))
6819                           (zero_extend:DI
6820                            (match_operand:SI 2 "register_operand" "r")))
6821                  (match_operand:DI 3 "register_operand" "0")))]
6822   "TARGET_SPARCLET"
6823   "umacd\\t%1, %2, %L0"
6824   [(set_attr "type" "imul")])
6825 \f
6826 ;;- Boolean instructions
6827 ;; We define DImode `and' so with DImode `not' we can get
6828 ;; DImode `andn'.  Other combinations are possible.
6829
6830 (define_expand "anddi3"
6831   [(set (match_operand:DI 0 "register_operand" "")
6832         (and:DI (match_operand:DI 1 "arith_double_operand" "")
6833                 (match_operand:DI 2 "arith_double_operand" "")))]
6834   ""
6835   "")
6836
6837 (define_insn "*anddi3_sp32"
6838   [(set (match_operand:DI 0 "register_operand" "=r,b")
6839         (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6840                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6841   "! TARGET_ARCH64"
6842   "@
6843   #
6844   fand\\t%1, %2, %0"
6845   [(set_attr "type" "*,fp")
6846    (set_attr "length" "2,*")
6847    (set_attr "fptype" "double")])
6848
6849 (define_insn "*anddi3_sp64"
6850   [(set (match_operand:DI 0 "register_operand" "=r,b")
6851         (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6852                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6853   "TARGET_ARCH64"
6854   "@
6855    and\\t%1, %2, %0
6856    fand\\t%1, %2, %0"
6857   [(set_attr "type" "*,fp")
6858    (set_attr "fptype" "double")])
6859
6860 (define_insn "andsi3"
6861   [(set (match_operand:SI 0 "register_operand" "=r,d")
6862         (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6863                 (match_operand:SI 2 "arith_operand" "rI,d")))]
6864   ""
6865   "@
6866    and\\t%1, %2, %0
6867    fands\\t%1, %2, %0"
6868   [(set_attr "type" "*,fp")])
6869
6870 (define_split
6871   [(set (match_operand:SI 0 "register_operand" "")
6872         (and:SI (match_operand:SI 1 "register_operand" "")
6873                 (match_operand:SI 2 "" "")))
6874    (clobber (match_operand:SI 3 "register_operand" ""))]
6875   "GET_CODE (operands[2]) == CONST_INT
6876    && !SMALL_INT32 (operands[2])
6877    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6878   [(set (match_dup 3) (match_dup 4))
6879    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6880   "
6881 {
6882   operands[4] = GEN_INT (~INTVAL (operands[2]));
6883 }")
6884
6885 ;; Split DImode logical operations requiring two instructions.
6886 (define_split
6887   [(set (match_operand:DI 0 "register_operand" "")
6888         (match_operator:DI 1 "cc_arithop"       ; AND, IOR, XOR
6889                            [(match_operand:DI 2 "register_operand" "")
6890                             (match_operand:DI 3 "arith_double_operand" "")]))]
6891   "! TARGET_ARCH64
6892    && reload_completed
6893    && ((GET_CODE (operands[0]) == REG
6894         && REGNO (operands[0]) < 32)
6895        || (GET_CODE (operands[0]) == SUBREG
6896            && GET_CODE (SUBREG_REG (operands[0])) == REG
6897            && REGNO (SUBREG_REG (operands[0])) < 32))"
6898   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6899    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6900   "
6901 {
6902   operands[4] = gen_highpart (SImode, operands[0]);
6903   operands[5] = gen_lowpart (SImode, operands[0]);
6904   operands[6] = gen_highpart (SImode, operands[2]);
6905   operands[7] = gen_lowpart (SImode, operands[2]);
6906 #if HOST_BITS_PER_WIDE_INT == 32
6907   if (GET_CODE (operands[3]) == CONST_INT)
6908     {
6909       if (INTVAL (operands[3]) < 0)
6910         operands[8] = constm1_rtx;
6911       else
6912         operands[8] = const0_rtx;
6913     }
6914   else
6915 #endif
6916     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6917   operands[9] = gen_lowpart (SImode, operands[3]);
6918 }")
6919
6920 (define_insn "*and_not_di_sp32"
6921   [(set (match_operand:DI 0 "register_operand" "=r,b")
6922         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6923                 (match_operand:DI 2 "register_operand" "r,b")))]
6924   "! TARGET_ARCH64"
6925   "@
6926    #
6927    fandnot1\\t%1, %2, %0"
6928   [(set_attr "type" "*,fp")
6929    (set_attr "length" "2,*")
6930    (set_attr "fptype" "double")])
6931
6932 (define_split
6933   [(set (match_operand:DI 0 "register_operand" "")
6934         (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6935                 (match_operand:DI 2 "register_operand" "")))]
6936   "! TARGET_ARCH64
6937    && reload_completed
6938    && ((GET_CODE (operands[0]) == REG
6939         && REGNO (operands[0]) < 32)
6940        || (GET_CODE (operands[0]) == SUBREG
6941            && GET_CODE (SUBREG_REG (operands[0])) == REG
6942            && REGNO (SUBREG_REG (operands[0])) < 32))"
6943   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6944    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6945   "operands[3] = gen_highpart (SImode, operands[0]);
6946    operands[4] = gen_highpart (SImode, operands[1]);
6947    operands[5] = gen_highpart (SImode, operands[2]);
6948    operands[6] = gen_lowpart (SImode, operands[0]);
6949    operands[7] = gen_lowpart (SImode, operands[1]);
6950    operands[8] = gen_lowpart (SImode, operands[2]);")
6951
6952 (define_insn "*and_not_di_sp64"
6953   [(set (match_operand:DI 0 "register_operand" "=r,b")
6954         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6955                 (match_operand:DI 2 "register_operand" "r,b")))]
6956   "TARGET_ARCH64"
6957   "@
6958    andn\\t%2, %1, %0
6959    fandnot1\\t%1, %2, %0"
6960   [(set_attr "type" "*,fp")
6961    (set_attr "fptype" "double")])
6962
6963 (define_insn "*and_not_si"
6964   [(set (match_operand:SI 0 "register_operand" "=r,d")
6965         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6966                 (match_operand:SI 2 "register_operand" "r,d")))]
6967   ""
6968   "@
6969    andn\\t%2, %1, %0
6970    fandnot1s\\t%1, %2, %0"
6971   [(set_attr "type" "*,fp")])
6972
6973 (define_expand "iordi3"
6974   [(set (match_operand:DI 0 "register_operand" "")
6975         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6976                 (match_operand:DI 2 "arith_double_operand" "")))]
6977   ""
6978   "")
6979
6980 (define_insn "*iordi3_sp32"
6981   [(set (match_operand:DI 0 "register_operand" "=r,b")
6982         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6983                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6984   "! TARGET_ARCH64"
6985   "@
6986   #
6987   for\\t%1, %2, %0"
6988   [(set_attr "type" "*,fp")
6989    (set_attr "length" "2,*")
6990    (set_attr "fptype" "double")])
6991
6992 (define_insn "*iordi3_sp64"
6993   [(set (match_operand:DI 0 "register_operand" "=r,b")
6994         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6995                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6996   "TARGET_ARCH64"
6997   "@
6998   or\\t%1, %2, %0
6999   for\\t%1, %2, %0"
7000   [(set_attr "type" "*,fp")
7001    (set_attr "fptype" "double")])
7002
7003 (define_insn "iorsi3"
7004   [(set (match_operand:SI 0 "register_operand" "=r,d")
7005         (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
7006                 (match_operand:SI 2 "arith_operand" "rI,d")))]
7007   ""
7008   "@
7009    or\\t%1, %2, %0
7010    fors\\t%1, %2, %0"
7011   [(set_attr "type" "*,fp")])
7012
7013 (define_split
7014   [(set (match_operand:SI 0 "register_operand" "")
7015         (ior:SI (match_operand:SI 1 "register_operand" "")
7016                 (match_operand:SI 2 "" "")))
7017    (clobber (match_operand:SI 3 "register_operand" ""))]
7018   "GET_CODE (operands[2]) == CONST_INT
7019    && !SMALL_INT32 (operands[2])
7020    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7021   [(set (match_dup 3) (match_dup 4))
7022    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
7023   "
7024 {
7025   operands[4] = GEN_INT (~INTVAL (operands[2]));
7026 }")
7027
7028 (define_insn "*or_not_di_sp32"
7029   [(set (match_operand:DI 0 "register_operand" "=r,b")
7030         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
7031                 (match_operand:DI 2 "register_operand" "r,b")))]
7032   "! TARGET_ARCH64"
7033   "@
7034    #
7035    fornot1\\t%1, %2, %0"
7036   [(set_attr "type" "*,fp")
7037    (set_attr "length" "2,*")
7038    (set_attr "fptype" "double")])
7039
7040 (define_split
7041   [(set (match_operand:DI 0 "register_operand" "")
7042         (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
7043                 (match_operand:DI 2 "register_operand" "")))]
7044   "! TARGET_ARCH64
7045    && reload_completed
7046    && ((GET_CODE (operands[0]) == REG
7047         && REGNO (operands[0]) < 32)
7048        || (GET_CODE (operands[0]) == SUBREG
7049            && GET_CODE (SUBREG_REG (operands[0])) == REG
7050            && REGNO (SUBREG_REG (operands[0])) < 32))"
7051   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
7052    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
7053   "operands[3] = gen_highpart (SImode, operands[0]);
7054    operands[4] = gen_highpart (SImode, operands[1]);
7055    operands[5] = gen_highpart (SImode, operands[2]);
7056    operands[6] = gen_lowpart (SImode, operands[0]);
7057    operands[7] = gen_lowpart (SImode, operands[1]);
7058    operands[8] = gen_lowpart (SImode, operands[2]);")
7059
7060 (define_insn "*or_not_di_sp64"
7061   [(set (match_operand:DI 0 "register_operand" "=r,b")
7062         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
7063                 (match_operand:DI 2 "register_operand" "r,b")))]
7064   "TARGET_ARCH64"
7065   "@
7066   orn\\t%2, %1, %0
7067   fornot1\\t%1, %2, %0"
7068   [(set_attr "type" "*,fp")
7069    (set_attr "fptype" "double")])
7070
7071 (define_insn "*or_not_si"
7072   [(set (match_operand:SI 0 "register_operand" "=r,d")
7073         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
7074                 (match_operand:SI 2 "register_operand" "r,d")))]
7075   ""
7076   "@
7077    orn\\t%2, %1, %0
7078    fornot1s\\t%1, %2, %0"
7079   [(set_attr "type" "*,fp")])
7080
7081 (define_expand "xordi3"
7082   [(set (match_operand:DI 0 "register_operand" "")
7083         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
7084                 (match_operand:DI 2 "arith_double_operand" "")))]
7085   ""
7086   "")
7087
7088 (define_insn "*xordi3_sp32"
7089   [(set (match_operand:DI 0 "register_operand" "=r,b")
7090         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
7091                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
7092   "! TARGET_ARCH64"
7093   "@
7094   #
7095   fxor\\t%1, %2, %0"
7096   [(set_attr "type" "*,fp")
7097    (set_attr "length" "2,*")
7098    (set_attr "fptype" "double")])
7099
7100 (define_insn "*xordi3_sp64"
7101   [(set (match_operand:DI 0 "register_operand" "=r,b")
7102         (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
7103                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
7104   "TARGET_ARCH64"
7105   "@
7106   xor\\t%r1, %2, %0
7107   fxor\\t%1, %2, %0"
7108   [(set_attr "type" "*,fp")
7109    (set_attr "fptype" "double")])
7110
7111 (define_insn "*xordi3_sp64_dbl"
7112   [(set (match_operand:DI 0 "register_operand" "=r")
7113         (xor:DI (match_operand:DI 1 "register_operand" "r")
7114                 (match_operand:DI 2 "const64_operand" "")))]
7115   "(TARGET_ARCH64
7116     && HOST_BITS_PER_WIDE_INT != 64)"
7117   "xor\\t%1, %2, %0")
7118
7119 (define_insn "xorsi3"
7120   [(set (match_operand:SI 0 "register_operand" "=r,d")
7121         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
7122                 (match_operand:SI 2 "arith_operand" "rI,d")))]
7123   ""
7124   "@
7125    xor\\t%r1, %2, %0
7126    fxors\\t%1, %2, %0"
7127   [(set_attr "type" "*,fp")])
7128
7129 (define_split
7130   [(set (match_operand:SI 0 "register_operand" "")
7131         (xor:SI (match_operand:SI 1 "register_operand" "")
7132                 (match_operand:SI 2 "" "")))
7133    (clobber (match_operand:SI 3 "register_operand" ""))]
7134   "GET_CODE (operands[2]) == CONST_INT
7135    && !SMALL_INT32 (operands[2])
7136    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7137   [(set (match_dup 3) (match_dup 4))
7138    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
7139   "
7140 {
7141   operands[4] = GEN_INT (~INTVAL (operands[2]));
7142 }")
7143
7144 (define_split
7145   [(set (match_operand:SI 0 "register_operand" "")
7146         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
7147                         (match_operand:SI 2 "" ""))))
7148    (clobber (match_operand:SI 3 "register_operand" ""))]
7149   "GET_CODE (operands[2]) == CONST_INT
7150    && !SMALL_INT32 (operands[2])
7151    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
7152   [(set (match_dup 3) (match_dup 4))
7153    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
7154   "
7155 {
7156   operands[4] = GEN_INT (~INTVAL (operands[2]));
7157 }")
7158
7159 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
7160 ;; Combine now canonicalizes to the rightmost expression.
7161 (define_insn "*xor_not_di_sp32"
7162   [(set (match_operand:DI 0 "register_operand" "=r,b")
7163         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
7164                         (match_operand:DI 2 "register_operand" "r,b"))))]
7165   "! TARGET_ARCH64"
7166   "@
7167    #
7168    fxnor\\t%1, %2, %0"
7169   [(set_attr "type" "*,fp")
7170    (set_attr "length" "2,*")
7171    (set_attr "fptype" "double")])
7172
7173 (define_split
7174   [(set (match_operand:DI 0 "register_operand" "")
7175         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
7176                         (match_operand:DI 2 "register_operand" ""))))]
7177   "! TARGET_ARCH64
7178    && reload_completed
7179    && ((GET_CODE (operands[0]) == REG
7180         && REGNO (operands[0]) < 32)
7181        || (GET_CODE (operands[0]) == SUBREG
7182            && GET_CODE (SUBREG_REG (operands[0])) == REG
7183            && REGNO (SUBREG_REG (operands[0])) < 32))"
7184   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
7185    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
7186   "operands[3] = gen_highpart (SImode, operands[0]);
7187    operands[4] = gen_highpart (SImode, operands[1]);
7188    operands[5] = gen_highpart (SImode, operands[2]);
7189    operands[6] = gen_lowpart (SImode, operands[0]);
7190    operands[7] = gen_lowpart (SImode, operands[1]);
7191    operands[8] = gen_lowpart (SImode, operands[2]);")
7192
7193 (define_insn "*xor_not_di_sp64"
7194   [(set (match_operand:DI 0 "register_operand" "=r,b")
7195         (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7196                         (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7197   "TARGET_ARCH64"
7198   "@
7199   xnor\\t%r1, %2, %0
7200   fxnor\\t%1, %2, %0"
7201   [(set_attr "type" "*,fp")
7202    (set_attr "fptype" "double")])
7203
7204 (define_insn "*xor_not_si"
7205   [(set (match_operand:SI 0 "register_operand" "=r,d")
7206         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7207                         (match_operand:SI 2 "arith_operand" "rI,d"))))]
7208   ""
7209   "@
7210    xnor\\t%r1, %2, %0
7211    fxnors\\t%1, %2, %0"
7212   [(set_attr "type" "*,fp")])
7213
7214 ;; These correspond to the above in the case where we also (or only)
7215 ;; want to set the condition code.  
7216
7217 (define_insn "*cmp_cc_arith_op"
7218   [(set (reg:CC 100)
7219         (compare:CC
7220          (match_operator:SI 2 "cc_arithop"
7221                             [(match_operand:SI 0 "arith_operand" "%r")
7222                              (match_operand:SI 1 "arith_operand" "rI")])
7223          (const_int 0)))]
7224   ""
7225   "%A2cc\\t%0, %1, %%g0"
7226   [(set_attr "type" "compare")])
7227
7228 (define_insn "*cmp_ccx_arith_op"
7229   [(set (reg:CCX 100)
7230         (compare:CCX
7231          (match_operator:DI 2 "cc_arithop"
7232                             [(match_operand:DI 0 "arith_double_operand" "%r")
7233                              (match_operand:DI 1 "arith_double_operand" "rHI")])
7234          (const_int 0)))]
7235   "TARGET_ARCH64"
7236   "%A2cc\\t%0, %1, %%g0"
7237   [(set_attr "type" "compare")])
7238
7239 (define_insn "*cmp_cc_arith_op_set"
7240   [(set (reg:CC 100)
7241         (compare:CC
7242          (match_operator:SI 3 "cc_arithop"
7243                             [(match_operand:SI 1 "arith_operand" "%r")
7244                              (match_operand:SI 2 "arith_operand" "rI")])
7245          (const_int 0)))
7246    (set (match_operand:SI 0 "register_operand" "=r")
7247         (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7248   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7249   "%A3cc\\t%1, %2, %0"
7250   [(set_attr "type" "compare")])
7251
7252 (define_insn "*cmp_ccx_arith_op_set"
7253   [(set (reg:CCX 100)
7254         (compare:CCX
7255          (match_operator:DI 3 "cc_arithop"
7256                             [(match_operand:DI 1 "arith_double_operand" "%r")
7257                              (match_operand:DI 2 "arith_double_operand" "rHI")])
7258          (const_int 0)))
7259    (set (match_operand:DI 0 "register_operand" "=r")
7260         (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7261   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7262   "%A3cc\\t%1, %2, %0"
7263   [(set_attr "type" "compare")])
7264
7265 (define_insn "*cmp_cc_xor_not"
7266   [(set (reg:CC 100)
7267         (compare:CC
7268          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7269                          (match_operand:SI 1 "arith_operand" "rI")))
7270          (const_int 0)))]
7271   ""
7272   "xnorcc\\t%r0, %1, %%g0"
7273   [(set_attr "type" "compare")])
7274
7275 (define_insn "*cmp_ccx_xor_not"
7276   [(set (reg:CCX 100)
7277         (compare:CCX
7278          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7279                          (match_operand:DI 1 "arith_double_operand" "rHI")))
7280          (const_int 0)))]
7281   "TARGET_ARCH64"
7282   "xnorcc\\t%r0, %1, %%g0"
7283   [(set_attr "type" "compare")])
7284
7285 (define_insn "*cmp_cc_xor_not_set"
7286   [(set (reg:CC 100)
7287         (compare:CC
7288          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7289                          (match_operand:SI 2 "arith_operand" "rI")))
7290          (const_int 0)))
7291    (set (match_operand:SI 0 "register_operand" "=r")
7292         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7293   ""
7294   "xnorcc\\t%r1, %2, %0"
7295   [(set_attr "type" "compare")])
7296
7297 (define_insn "*cmp_ccx_xor_not_set"
7298   [(set (reg:CCX 100)
7299         (compare:CCX
7300          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7301                          (match_operand:DI 2 "arith_double_operand" "rHI")))
7302          (const_int 0)))
7303    (set (match_operand:DI 0 "register_operand" "=r")
7304         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7305   "TARGET_ARCH64"
7306   "xnorcc\\t%r1, %2, %0"
7307   [(set_attr "type" "compare")])
7308
7309 (define_insn "*cmp_cc_arith_op_not"
7310   [(set (reg:CC 100)
7311         (compare:CC
7312          (match_operator:SI 2 "cc_arithopn"
7313                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7314                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7315          (const_int 0)))]
7316   ""
7317   "%B2cc\\t%r1, %0, %%g0"
7318   [(set_attr "type" "compare")])
7319
7320 (define_insn "*cmp_ccx_arith_op_not"
7321   [(set (reg:CCX 100)
7322         (compare:CCX
7323          (match_operator:DI 2 "cc_arithopn"
7324                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7325                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7326          (const_int 0)))]
7327   "TARGET_ARCH64"
7328   "%B2cc\\t%r1, %0, %%g0"
7329   [(set_attr "type" "compare")])
7330
7331 (define_insn "*cmp_cc_arith_op_not_set"
7332   [(set (reg:CC 100)
7333         (compare:CC
7334          (match_operator:SI 3 "cc_arithopn"
7335                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7336                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7337          (const_int 0)))
7338    (set (match_operand:SI 0 "register_operand" "=r")
7339         (match_operator:SI 4 "cc_arithopn"
7340                             [(not:SI (match_dup 1)) (match_dup 2)]))]
7341   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7342   "%B3cc\\t%r2, %1, %0"
7343   [(set_attr "type" "compare")])
7344
7345 (define_insn "*cmp_ccx_arith_op_not_set"
7346   [(set (reg:CCX 100)
7347         (compare:CCX
7348          (match_operator:DI 3 "cc_arithopn"
7349                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7350                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7351          (const_int 0)))
7352    (set (match_operand:DI 0 "register_operand" "=r")
7353         (match_operator:DI 4 "cc_arithopn"
7354                             [(not:DI (match_dup 1)) (match_dup 2)]))]
7355   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7356   "%B3cc\\t%r2, %1, %0"
7357   [(set_attr "type" "compare")])
7358
7359 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7360 ;; does not know how to make it work for constants.
7361
7362 (define_expand "negdi2"
7363   [(set (match_operand:DI 0 "register_operand" "=r")
7364         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7365   ""
7366   "
7367 {
7368   if (! TARGET_ARCH64)
7369     {
7370       emit_insn (gen_rtx_PARALLEL
7371                  (VOIDmode,
7372                   gen_rtvec (2,
7373                              gen_rtx_SET (VOIDmode, operand0,
7374                                           gen_rtx_NEG (DImode, operand1)),
7375                              gen_rtx_CLOBBER (VOIDmode,
7376                                               gen_rtx_REG (CCmode,
7377                                                            SPARC_ICC_REG)))));
7378       DONE;
7379     }
7380 }")
7381
7382 (define_insn "*negdi2_sp32"
7383   [(set (match_operand:DI 0 "register_operand" "=r")
7384         (neg:DI (match_operand:DI 1 "register_operand" "r")))
7385    (clobber (reg:CC 100))]
7386   "TARGET_ARCH32"
7387   "#"
7388   [(set_attr "length" "2")])
7389
7390 (define_split
7391   [(set (match_operand:DI 0 "register_operand" "")
7392         (neg:DI (match_operand:DI 1 "register_operand" "")))
7393    (clobber (reg:CC 100))]
7394   "TARGET_ARCH32
7395    && reload_completed"
7396   [(parallel [(set (reg:CC_NOOV 100)
7397                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7398                                     (const_int 0)))
7399               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7400    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7401                                 (ltu:SI (reg:CC 100) (const_int 0))))]
7402   "operands[2] = gen_highpart (SImode, operands[0]);
7403    operands[3] = gen_highpart (SImode, operands[1]);
7404    operands[4] = gen_lowpart (SImode, operands[0]);
7405    operands[5] = gen_lowpart (SImode, operands[1]);")
7406
7407 (define_insn "*negdi2_sp64"
7408   [(set (match_operand:DI 0 "register_operand" "=r")
7409         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7410   "TARGET_ARCH64"
7411   "sub\\t%%g0, %1, %0")
7412
7413 (define_insn "negsi2"
7414   [(set (match_operand:SI 0 "register_operand" "=r")
7415         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7416   ""
7417   "sub\\t%%g0, %1, %0")
7418
7419 (define_insn "*cmp_cc_neg"
7420   [(set (reg:CC_NOOV 100)
7421         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7422                          (const_int 0)))]
7423   ""
7424   "subcc\\t%%g0, %0, %%g0"
7425   [(set_attr "type" "compare")])
7426
7427 (define_insn "*cmp_ccx_neg"
7428   [(set (reg:CCX_NOOV 100)
7429         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7430                           (const_int 0)))]
7431   "TARGET_ARCH64"
7432   "subcc\\t%%g0, %0, %%g0"
7433   [(set_attr "type" "compare")])
7434
7435 (define_insn "*cmp_cc_set_neg"
7436   [(set (reg:CC_NOOV 100)
7437         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7438                          (const_int 0)))
7439    (set (match_operand:SI 0 "register_operand" "=r")
7440         (neg:SI (match_dup 1)))]
7441   ""
7442   "subcc\\t%%g0, %1, %0"
7443   [(set_attr "type" "compare")])
7444
7445 (define_insn "*cmp_ccx_set_neg"
7446   [(set (reg:CCX_NOOV 100)
7447         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7448                           (const_int 0)))
7449    (set (match_operand:DI 0 "register_operand" "=r")
7450         (neg:DI (match_dup 1)))]
7451   "TARGET_ARCH64"
7452   "subcc\\t%%g0, %1, %0"
7453   [(set_attr "type" "compare")])
7454
7455 ;; We cannot use the "not" pseudo insn because the Sun assembler
7456 ;; does not know how to make it work for constants.
7457 (define_expand "one_cmpldi2"
7458   [(set (match_operand:DI 0 "register_operand" "")
7459         (not:DI (match_operand:DI 1 "register_operand" "")))]
7460   ""
7461   "")
7462
7463 (define_insn "*one_cmpldi2_sp32"
7464   [(set (match_operand:DI 0 "register_operand" "=r,b")
7465         (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7466   "! TARGET_ARCH64"
7467   "@
7468    #
7469    fnot1\\t%1, %0"
7470   [(set_attr "type" "*,fp")
7471    (set_attr "length" "2,*")
7472    (set_attr "fptype" "double")])
7473
7474 (define_split
7475   [(set (match_operand:DI 0 "register_operand" "")
7476         (not:DI (match_operand:DI 1 "register_operand" "")))]
7477   "! TARGET_ARCH64
7478    && reload_completed
7479    && ((GET_CODE (operands[0]) == REG
7480         && REGNO (operands[0]) < 32)
7481        || (GET_CODE (operands[0]) == SUBREG
7482            && GET_CODE (SUBREG_REG (operands[0])) == REG
7483            && REGNO (SUBREG_REG (operands[0])) < 32))"
7484   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7485    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7486   "operands[2] = gen_highpart (SImode, operands[0]);
7487    operands[3] = gen_highpart (SImode, operands[1]);
7488    operands[4] = gen_lowpart (SImode, operands[0]);
7489    operands[5] = gen_lowpart (SImode, operands[1]);")
7490
7491 (define_insn "*one_cmpldi2_sp64"
7492   [(set (match_operand:DI 0 "register_operand" "=r,b")
7493         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7494   "TARGET_ARCH64"
7495   "@
7496    xnor\\t%%g0, %1, %0
7497    fnot1\\t%1, %0"
7498   [(set_attr "type" "*,fp")
7499    (set_attr "fptype" "double")])
7500
7501 (define_insn "one_cmplsi2"
7502   [(set (match_operand:SI 0 "register_operand" "=r,d")
7503         (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7504   ""
7505   "@
7506   xnor\\t%%g0, %1, %0
7507   fnot1s\\t%1, %0"
7508   [(set_attr "type" "*,fp")])
7509
7510 (define_insn "*cmp_cc_not"
7511   [(set (reg:CC 100)
7512         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7513                     (const_int 0)))]
7514   ""
7515   "xnorcc\\t%%g0, %0, %%g0"
7516   [(set_attr "type" "compare")])
7517
7518 (define_insn "*cmp_ccx_not"
7519   [(set (reg:CCX 100)
7520         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7521                      (const_int 0)))]
7522   "TARGET_ARCH64"
7523   "xnorcc\\t%%g0, %0, %%g0"
7524   [(set_attr "type" "compare")])
7525
7526 (define_insn "*cmp_cc_set_not"
7527   [(set (reg:CC 100)
7528         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7529                     (const_int 0)))
7530    (set (match_operand:SI 0 "register_operand" "=r")
7531         (not:SI (match_dup 1)))]
7532   ""
7533   "xnorcc\\t%%g0, %1, %0"
7534   [(set_attr "type" "compare")])
7535
7536 (define_insn "*cmp_ccx_set_not"
7537   [(set (reg:CCX 100)
7538         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7539                     (const_int 0)))
7540    (set (match_operand:DI 0 "register_operand" "=r")
7541         (not:DI (match_dup 1)))]
7542   "TARGET_ARCH64"
7543   "xnorcc\\t%%g0, %1, %0"
7544   [(set_attr "type" "compare")])
7545
7546 (define_insn "*cmp_cc_set"
7547   [(set (match_operand:SI 0 "register_operand" "=r")
7548         (match_operand:SI 1 "register_operand" "r"))
7549    (set (reg:CC 100)
7550         (compare:CC (match_dup 1)
7551                     (const_int 0)))]
7552   ""
7553   "orcc\\t%1, 0, %0"
7554   [(set_attr "type" "compare")])
7555
7556 (define_insn "*cmp_ccx_set64"
7557   [(set (match_operand:DI 0 "register_operand" "=r")
7558         (match_operand:DI 1 "register_operand" "r"))
7559    (set (reg:CCX 100)
7560         (compare:CCX (match_dup 1)
7561                      (const_int 0)))]
7562   "TARGET_ARCH64"
7563   "orcc\\t%1, 0, %0"
7564    [(set_attr "type" "compare")])
7565 \f
7566 ;; Floating point arithmetic instructions.
7567
7568 (define_expand "addtf3"
7569   [(set (match_operand:TF 0 "nonimmediate_operand" "")
7570         (plus:TF (match_operand:TF 1 "general_operand" "")
7571                  (match_operand:TF 2 "general_operand" "")))]
7572   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7573   "
7574 {
7575   if (! TARGET_HARD_QUAD)
7576     {
7577       rtx slot0, slot1, slot2;
7578
7579       if (GET_CODE (operands[0]) != MEM)
7580         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7581       else
7582         slot0 = operands[0];
7583       if (GET_CODE (operands[1]) != MEM)
7584         {
7585           slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7586           emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7587         }
7588       else
7589         slot1 = operands[1];
7590       if (GET_CODE (operands[2]) != MEM)
7591         {
7592           slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7593           emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7594         }
7595       else
7596         slot2 = operands[2];
7597
7598       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7599                          VOIDmode, 3,
7600                          XEXP (slot0, 0), Pmode,
7601                          XEXP (slot1, 0), Pmode,
7602                          XEXP (slot2, 0), Pmode);
7603
7604       if (GET_CODE (operands[0]) != MEM)
7605         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7606       DONE;
7607     }
7608 }")
7609
7610 (define_insn "*addtf3_hq"
7611   [(set (match_operand:TF 0 "register_operand" "=e")
7612         (plus:TF (match_operand:TF 1 "register_operand" "e")
7613                  (match_operand:TF 2 "register_operand" "e")))]
7614   "TARGET_FPU && TARGET_HARD_QUAD"
7615   "faddq\\t%1, %2, %0"
7616   [(set_attr "type" "fp")])
7617
7618 (define_insn "adddf3"
7619   [(set (match_operand:DF 0 "register_operand" "=e")
7620         (plus:DF (match_operand:DF 1 "register_operand" "e")
7621                  (match_operand:DF 2 "register_operand" "e")))]
7622   "TARGET_FPU"
7623   "faddd\\t%1, %2, %0"
7624   [(set_attr "type" "fp")
7625    (set_attr "fptype" "double")])
7626
7627 (define_insn "addsf3"
7628   [(set (match_operand:SF 0 "register_operand" "=f")
7629         (plus:SF (match_operand:SF 1 "register_operand" "f")
7630                  (match_operand:SF 2 "register_operand" "f")))]
7631   "TARGET_FPU"
7632   "fadds\\t%1, %2, %0"
7633   [(set_attr "type" "fp")])
7634
7635 (define_expand "subtf3"
7636   [(set (match_operand:TF 0 "nonimmediate_operand" "")
7637         (minus:TF (match_operand:TF 1 "general_operand" "")
7638                   (match_operand:TF 2 "general_operand" "")))]
7639   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7640   "
7641 {
7642   if (! TARGET_HARD_QUAD)
7643     {
7644       rtx slot0, slot1, slot2;
7645
7646       if (GET_CODE (operands[0]) != MEM)
7647         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7648       else
7649         slot0 = operands[0];
7650       if (GET_CODE (operands[1]) != MEM)
7651         {
7652           slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7653           emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7654         }
7655       else
7656         slot1 = operands[1];
7657       if (GET_CODE (operands[2]) != MEM)
7658         {
7659           slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7660           emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7661         }
7662       else
7663         slot2 = operands[2];
7664
7665       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7666                          VOIDmode, 3,
7667                          XEXP (slot0, 0), Pmode,
7668                          XEXP (slot1, 0), Pmode,
7669                          XEXP (slot2, 0), Pmode);
7670
7671       if (GET_CODE (operands[0]) != MEM)
7672         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7673       DONE;
7674     }
7675 }")
7676
7677 (define_insn "*subtf3_hq"
7678   [(set (match_operand:TF 0 "register_operand" "=e")
7679         (minus:TF (match_operand:TF 1 "register_operand" "e")
7680                   (match_operand:TF 2 "register_operand" "e")))]
7681   "TARGET_FPU && TARGET_HARD_QUAD"
7682   "fsubq\\t%1, %2, %0"
7683   [(set_attr "type" "fp")])
7684
7685 (define_insn "subdf3"
7686   [(set (match_operand:DF 0 "register_operand" "=e")
7687         (minus:DF (match_operand:DF 1 "register_operand" "e")
7688                   (match_operand:DF 2 "register_operand" "e")))]
7689   "TARGET_FPU"
7690   "fsubd\\t%1, %2, %0"
7691   [(set_attr "type" "fp")
7692    (set_attr "fptype" "double")])
7693
7694 (define_insn "subsf3"
7695   [(set (match_operand:SF 0 "register_operand" "=f")
7696         (minus:SF (match_operand:SF 1 "register_operand" "f")
7697                   (match_operand:SF 2 "register_operand" "f")))]
7698   "TARGET_FPU"
7699   "fsubs\\t%1, %2, %0"
7700   [(set_attr "type" "fp")])
7701
7702 (define_expand "multf3"
7703   [(set (match_operand:TF 0 "nonimmediate_operand" "")
7704         (mult:TF (match_operand:TF 1 "general_operand" "")
7705                  (match_operand:TF 2 "general_operand" "")))]
7706   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7707   "
7708 {
7709   if (! TARGET_HARD_QUAD)
7710     {
7711       rtx slot0, slot1, slot2;
7712
7713       if (GET_CODE (operands[0]) != MEM)
7714         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7715       else
7716         slot0 = operands[0];
7717       if (GET_CODE (operands[1]) != MEM)
7718         {
7719           slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7720           emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7721         }
7722       else
7723         slot1 = operands[1];
7724       if (GET_CODE (operands[2]) != MEM)
7725         {
7726           slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7727           emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7728         }
7729       else
7730         slot2 = operands[2];
7731
7732       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7733                          VOIDmode, 3,
7734                          XEXP (slot0, 0), Pmode,
7735                          XEXP (slot1, 0), Pmode,
7736                          XEXP (slot2, 0), Pmode);
7737
7738       if (GET_CODE (operands[0]) != MEM)
7739         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7740       DONE;
7741     }
7742 }")
7743
7744 (define_insn "*multf3_hq"
7745   [(set (match_operand:TF 0 "register_operand" "=e")
7746         (mult:TF (match_operand:TF 1 "register_operand" "e")
7747                  (match_operand:TF 2 "register_operand" "e")))]
7748   "TARGET_FPU && TARGET_HARD_QUAD"
7749   "fmulq\\t%1, %2, %0"
7750   [(set_attr "type" "fpmul")])
7751
7752 (define_insn "muldf3"
7753   [(set (match_operand:DF 0 "register_operand" "=e")
7754         (mult:DF (match_operand:DF 1 "register_operand" "e")
7755                  (match_operand:DF 2 "register_operand" "e")))]
7756   "TARGET_FPU"
7757   "fmuld\\t%1, %2, %0"
7758   [(set_attr "type" "fpmul")
7759    (set_attr "fptype" "double")])
7760
7761 (define_insn "mulsf3"
7762   [(set (match_operand:SF 0 "register_operand" "=f")
7763         (mult:SF (match_operand:SF 1 "register_operand" "f")
7764                  (match_operand:SF 2 "register_operand" "f")))]
7765   "TARGET_FPU"
7766   "fmuls\\t%1, %2, %0"
7767   [(set_attr "type" "fpmul")])
7768
7769 (define_insn "*muldf3_extend"
7770   [(set (match_operand:DF 0 "register_operand" "=e")
7771         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7772                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7773   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7774   "fsmuld\\t%1, %2, %0"
7775   [(set_attr "type" "fpmul")
7776    (set_attr "fptype" "double")])
7777
7778 (define_insn "*multf3_extend"
7779   [(set (match_operand:TF 0 "register_operand" "=e")
7780         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7781                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7782   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7783   "fdmulq\\t%1, %2, %0"
7784   [(set_attr "type" "fpmul")])
7785
7786 (define_expand "divtf3"
7787   [(set (match_operand:TF 0 "nonimmediate_operand" "")
7788         (div:TF (match_operand:TF 1 "general_operand" "")
7789                 (match_operand:TF 2 "general_operand" "")))]
7790   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7791   "
7792 {
7793   if (! TARGET_HARD_QUAD)
7794     {
7795       rtx slot0, slot1, slot2;
7796
7797       if (GET_CODE (operands[0]) != MEM)
7798         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7799       else
7800         slot0 = operands[0];
7801       if (GET_CODE (operands[1]) != MEM)
7802         {
7803           slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7804           emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7805         }
7806       else
7807         slot1 = operands[1];
7808       if (GET_CODE (operands[2]) != MEM)
7809         {
7810           slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7811           emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7812         }
7813       else
7814         slot2 = operands[2];
7815
7816       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7817                          VOIDmode, 3,
7818                          XEXP (slot0, 0), Pmode,
7819                          XEXP (slot1, 0), Pmode,
7820                          XEXP (slot2, 0), Pmode);
7821
7822       if (GET_CODE (operands[0]) != MEM)
7823         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7824       DONE;
7825     }
7826 }")
7827
7828 ;; don't have timing for quad-prec. divide.
7829 (define_insn "*divtf3_hq"
7830   [(set (match_operand:TF 0 "register_operand" "=e")
7831         (div:TF (match_operand:TF 1 "register_operand" "e")
7832                 (match_operand:TF 2 "register_operand" "e")))]
7833   "TARGET_FPU && TARGET_HARD_QUAD"
7834   "fdivq\\t%1, %2, %0"
7835   [(set_attr "type" "fpdivd")])
7836
7837 (define_insn "divdf3"
7838   [(set (match_operand:DF 0 "register_operand" "=e")
7839         (div:DF (match_operand:DF 1 "register_operand" "e")
7840                 (match_operand:DF 2 "register_operand" "e")))]
7841   "TARGET_FPU"
7842   "fdivd\\t%1, %2, %0"
7843   [(set_attr "type" "fpdivd")
7844    (set_attr "fptype" "double")])
7845
7846 (define_insn "divsf3"
7847   [(set (match_operand:SF 0 "register_operand" "=f")
7848         (div:SF (match_operand:SF 1 "register_operand" "f")
7849                 (match_operand:SF 2 "register_operand" "f")))]
7850   "TARGET_FPU"
7851   "fdivs\\t%1, %2, %0"
7852   [(set_attr "type" "fpdivs")])
7853
7854 (define_expand "negtf2"
7855   [(set (match_operand:TF 0 "register_operand" "=e,e")
7856         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7857   "TARGET_FPU"
7858   "")
7859
7860 (define_insn "*negtf2_notv9"
7861   [(set (match_operand:TF 0 "register_operand" "=e,e")
7862         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7863   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7864   "TARGET_FPU
7865    && ! TARGET_V9"
7866   "@
7867   fnegs\\t%0, %0
7868   #"
7869   [(set_attr "type" "fpmove,*")
7870    (set_attr "length" "*,2")])
7871
7872 (define_split
7873   [(set (match_operand:TF 0 "register_operand" "")
7874         (neg:TF (match_operand:TF 1 "register_operand" "")))]
7875   "TARGET_FPU
7876    && ! TARGET_V9
7877    && reload_completed
7878    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7879   [(set (match_dup 2) (neg:SF (match_dup 3)))
7880    (set (match_dup 4) (match_dup 5))
7881    (set (match_dup 6) (match_dup 7))]
7882   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7883    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7884    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7885    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7886    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7887    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7888
7889 (define_insn "*negtf2_v9"
7890   [(set (match_operand:TF 0 "register_operand" "=e,e")
7891         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7892   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7893   "TARGET_FPU && TARGET_V9"
7894   "@
7895   fnegd\\t%0, %0
7896   #"
7897   [(set_attr "type" "fpmove,*")
7898    (set_attr "length" "*,2")
7899    (set_attr "fptype" "double")])
7900
7901 (define_split
7902   [(set (match_operand:TF 0 "register_operand" "")
7903         (neg:TF (match_operand:TF 1 "register_operand" "")))]
7904   "TARGET_FPU
7905    && TARGET_V9
7906    && reload_completed
7907    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7908   [(set (match_dup 2) (neg:DF (match_dup 3)))
7909    (set (match_dup 4) (match_dup 5))]
7910   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7911    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7912    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7913    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7914
7915 (define_expand "negdf2"
7916   [(set (match_operand:DF 0 "register_operand" "")
7917         (neg:DF (match_operand:DF 1 "register_operand" "")))]
7918   "TARGET_FPU"
7919   "")
7920
7921 (define_insn "*negdf2_notv9"
7922   [(set (match_operand:DF 0 "register_operand" "=e,e")
7923         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7924   "TARGET_FPU && ! TARGET_V9"
7925   "@
7926   fnegs\\t%0, %0
7927   #"
7928   [(set_attr "type" "fpmove,*")
7929    (set_attr "length" "*,2")])
7930
7931 (define_split
7932   [(set (match_operand:DF 0 "register_operand" "")
7933         (neg:DF (match_operand:DF 1 "register_operand" "")))]
7934   "TARGET_FPU
7935    && ! TARGET_V9
7936    && reload_completed
7937    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7938   [(set (match_dup 2) (neg:SF (match_dup 3)))
7939    (set (match_dup 4) (match_dup 5))]
7940   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7941    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7942    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7943    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7944
7945 (define_insn "*negdf2_v9"
7946   [(set (match_operand:DF 0 "register_operand" "=e")
7947         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7948   "TARGET_FPU && TARGET_V9"
7949   "fnegd\\t%1, %0"
7950   [(set_attr "type" "fpmove")
7951    (set_attr "fptype" "double")])
7952
7953 (define_insn "negsf2"
7954   [(set (match_operand:SF 0 "register_operand" "=f")
7955         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7956   "TARGET_FPU"
7957   "fnegs\\t%1, %0"
7958   [(set_attr "type" "fpmove")])
7959
7960 (define_expand "abstf2"
7961   [(set (match_operand:TF 0 "register_operand" "")
7962         (abs:TF (match_operand:TF 1 "register_operand" "")))]
7963   "TARGET_FPU"
7964   "")
7965
7966 (define_insn "*abstf2_notv9"
7967   [(set (match_operand:TF 0 "register_operand" "=e,e")
7968         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7969   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7970   "TARGET_FPU && ! TARGET_V9"
7971   "@
7972   fabss\\t%0, %0
7973   #"
7974   [(set_attr "type" "fpmove,*")
7975    (set_attr "length" "*,2")])
7976
7977 (define_split
7978   [(set (match_operand:TF 0 "register_operand" "")
7979         (abs:TF (match_operand:TF 1 "register_operand" "")))]
7980   "TARGET_FPU
7981    && ! TARGET_V9
7982    && reload_completed
7983    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7984   [(set (match_dup 2) (abs:SF (match_dup 3)))
7985    (set (match_dup 4) (match_dup 5))
7986    (set (match_dup 6) (match_dup 7))]
7987   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7988    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7989    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7990    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7991    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7992    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7993
7994 (define_insn "*abstf2_hq_v9"
7995   [(set (match_operand:TF 0 "register_operand" "=e,e")
7996         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7997   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7998   "@
7999   fabsd\\t%0, %0
8000   fabsq\\t%1, %0"
8001   [(set_attr "type" "fpmove")
8002    (set_attr "fptype" "double,*")])
8003
8004 (define_insn "*abstf2_v9"
8005   [(set (match_operand:TF 0 "register_operand" "=e,e")
8006         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
8007   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
8008   "@
8009   fabsd\\t%0, %0
8010   #"
8011   [(set_attr "type" "fpmove,*")
8012    (set_attr "length" "*,2")
8013    (set_attr "fptype" "double,*")])
8014
8015 (define_split
8016   [(set (match_operand:TF 0 "register_operand" "")
8017         (abs:TF (match_operand:TF 1 "register_operand" "")))]
8018   "TARGET_FPU
8019    && TARGET_V9
8020    && reload_completed
8021    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
8022   [(set (match_dup 2) (abs:DF (match_dup 3)))
8023    (set (match_dup 4) (match_dup 5))]
8024   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
8025    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
8026    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
8027    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
8028
8029 (define_expand "absdf2"
8030   [(set (match_operand:DF 0 "register_operand" "")
8031         (abs:DF (match_operand:DF 1 "register_operand" "")))]
8032   "TARGET_FPU"
8033   "")
8034
8035 (define_insn "*absdf2_notv9"
8036   [(set (match_operand:DF 0 "register_operand" "=e,e")
8037         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
8038   "TARGET_FPU && ! TARGET_V9"
8039   "@
8040   fabss\\t%0, %0
8041   #"
8042   [(set_attr "type" "fpmove,*")
8043    (set_attr "length" "*,2")])
8044
8045 (define_split
8046   [(set (match_operand:DF 0 "register_operand" "")
8047         (abs:DF (match_operand:DF 1 "register_operand" "")))]
8048   "TARGET_FPU
8049    && ! TARGET_V9
8050    && reload_completed
8051    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
8052   [(set (match_dup 2) (abs:SF (match_dup 3)))
8053    (set (match_dup 4) (match_dup 5))]
8054   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
8055    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
8056    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
8057    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
8058
8059 (define_insn "*absdf2_v9"
8060   [(set (match_operand:DF 0 "register_operand" "=e")
8061         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
8062   "TARGET_FPU && TARGET_V9"
8063   "fabsd\\t%1, %0"
8064   [(set_attr "type" "fpmove")
8065    (set_attr "fptype" "double")])
8066
8067 (define_insn "abssf2"
8068   [(set (match_operand:SF 0 "register_operand" "=f")
8069         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
8070   "TARGET_FPU"
8071   "fabss\\t%1, %0"
8072   [(set_attr "type" "fpmove")])
8073
8074 (define_expand "sqrttf2"
8075   [(set (match_operand:TF 0 "register_operand" "=e")
8076         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8077   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
8078   "
8079 {
8080   if (! TARGET_HARD_QUAD)
8081     {
8082       rtx slot0, slot1;
8083
8084       if (GET_CODE (operands[0]) != MEM)
8085         slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8086       else
8087         slot0 = operands[0];
8088       if (GET_CODE (operands[1]) != MEM)
8089         {
8090           slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
8091           emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
8092         }
8093       else
8094         slot1 = operands[1];
8095
8096       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
8097                          VOIDmode, 2,
8098                          XEXP (slot0, 0), Pmode,
8099                          XEXP (slot1, 0), Pmode);
8100
8101       if (GET_CODE (operands[0]) != MEM)
8102         emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
8103       DONE;
8104     }
8105 }")
8106
8107 (define_insn "*sqrttf2_hq"
8108   [(set (match_operand:TF 0 "register_operand" "=e")
8109         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
8110   "TARGET_FPU && TARGET_HARD_QUAD"
8111   "fsqrtq\\t%1, %0"
8112   [(set_attr "type" "fpsqrtd")])
8113
8114 (define_insn "sqrtdf2"
8115   [(set (match_operand:DF 0 "register_operand" "=e")
8116         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
8117   "TARGET_FPU"
8118   "fsqrtd\\t%1, %0"
8119   [(set_attr "type" "fpsqrtd")
8120    (set_attr "fptype" "double")])
8121
8122 (define_insn "sqrtsf2"
8123   [(set (match_operand:SF 0 "register_operand" "=f")
8124         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
8125   "TARGET_FPU"
8126   "fsqrts\\t%1, %0"
8127   [(set_attr "type" "fpsqrts")])
8128 \f
8129 ;;- arithmetic shift instructions
8130
8131 (define_insn "ashlsi3"
8132   [(set (match_operand:SI 0 "register_operand" "=r")
8133         (ashift:SI (match_operand:SI 1 "register_operand" "r")
8134                    (match_operand:SI 2 "arith_operand" "rI")))]
8135   ""
8136   "*
8137 {
8138   if (GET_CODE (operands[2]) == CONST_INT
8139       && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8140     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8141
8142   return \"sll\\t%1, %2, %0\";
8143 }"
8144   [(set_attr "type" "shift")])
8145
8146 ;; We special case multiplication by two, as add can be done
8147 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8148 (define_insn "*ashlsi3_const1"
8149   [(set (match_operand:SI 0 "register_operand" "=r")
8150         (ashift:SI (match_operand:SI 1 "register_operand" "r")
8151                    (const_int 1)))]
8152   ""
8153   "add\\t%1, %1, %0")
8154
8155 (define_expand "ashldi3"
8156   [(set (match_operand:DI 0 "register_operand" "=r")
8157         (ashift:DI (match_operand:DI 1 "register_operand" "r")
8158                    (match_operand:SI 2 "arith_operand" "rI")))]
8159   "TARGET_ARCH64 || TARGET_V8PLUS"
8160   "
8161 {
8162   if (! TARGET_ARCH64)
8163     {
8164       if (GET_CODE (operands[2]) == CONST_INT)
8165         FAIL;
8166       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
8167       DONE;
8168     }
8169 }")
8170
8171 ;; We special case multiplication by two, as add can be done
8172 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8173 (define_insn "*ashldi3_const1"
8174   [(set (match_operand:DI 0 "register_operand" "=r")
8175         (ashift:DI (match_operand:DI 1 "register_operand" "r")
8176                    (const_int 1)))]
8177   "TARGET_ARCH64"
8178   "add\\t%1, %1, %0")
8179
8180 (define_insn "*ashldi3_sp64"
8181   [(set (match_operand:DI 0 "register_operand" "=r")
8182         (ashift:DI (match_operand:DI 1 "register_operand" "r")
8183                    (match_operand:SI 2 "arith_operand" "rI")))]
8184   "TARGET_ARCH64"
8185   "*
8186 {
8187   if (GET_CODE (operands[2]) == CONST_INT
8188       && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8189     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8190
8191   return \"sllx\\t%1, %2, %0\";
8192 }"
8193   [(set_attr "type" "shift")])
8194
8195 ;; XXX UGH!
8196 (define_insn "ashldi3_v8plus"
8197   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8198         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8199                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8200    (clobber (match_scratch:SI 3 "=X,X,&h"))]
8201   "TARGET_V8PLUS"
8202   "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8203   [(set_attr "type" "multi")
8204    (set_attr "length" "5,5,6")])
8205
8206 ;; Optimize (1LL<<x)-1
8207 ;; XXX this also needs to be fixed to handle equal subregs
8208 ;; XXX first before we could re-enable it.
8209 ;(define_insn ""
8210 ;  [(set (match_operand:DI 0 "register_operand" "=h")
8211 ;       (plus:DI (ashift:DI (const_int 1)
8212 ;                           (match_operand:SI 1 "arith_operand" "rI"))
8213 ;                (const_int -1)))]
8214 ;  "0 && TARGET_V8PLUS"
8215 ;  "*
8216 ;{
8217 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8218 ;    return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8219 ;  return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8220 ;}"
8221 ;  [(set_attr "type" "multi")
8222 ;   (set_attr "length" "4")])
8223
8224 (define_insn "*cmp_cc_ashift_1"
8225   [(set (reg:CC_NOOV 100)
8226         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8227                                     (const_int 1))
8228                          (const_int 0)))]
8229   ""
8230   "addcc\\t%0, %0, %%g0"
8231   [(set_attr "type" "compare")])
8232
8233 (define_insn "*cmp_cc_set_ashift_1"
8234   [(set (reg:CC_NOOV 100)
8235         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8236                                     (const_int 1))
8237                          (const_int 0)))
8238    (set (match_operand:SI 0 "register_operand" "=r")
8239         (ashift:SI (match_dup 1) (const_int 1)))]
8240   ""
8241   "addcc\\t%1, %1, %0"
8242   [(set_attr "type" "compare")])
8243
8244 (define_insn "ashrsi3"
8245   [(set (match_operand:SI 0 "register_operand" "=r")
8246         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8247                      (match_operand:SI 2 "arith_operand" "rI")))]
8248   ""
8249   "*
8250 {
8251   if (GET_CODE (operands[2]) == CONST_INT
8252       && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8253     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8254
8255   return \"sra\\t%1, %2, %0\";
8256 }"
8257   [(set_attr "type" "shift")])
8258
8259 (define_insn "*ashrsi3_extend"
8260   [(set (match_operand:DI 0 "register_operand" "=r")
8261         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8262                                      (match_operand:SI 2 "arith_operand" "r"))))]
8263   "TARGET_ARCH64"
8264   "sra\\t%1, %2, %0"
8265   [(set_attr "type" "shift")])
8266
8267 ;; This handles the case as above, but with constant shift instead of
8268 ;; register. Combiner "simplifies" it for us a little bit though.
8269 (define_insn "*ashrsi3_extend2"
8270   [(set (match_operand:DI 0 "register_operand" "=r")
8271         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8272                                 (const_int 32))
8273                      (match_operand:SI 2 "small_int_or_double" "n")))]
8274   "TARGET_ARCH64
8275    && ((GET_CODE (operands[2]) == CONST_INT
8276         && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8277        || (GET_CODE (operands[2]) == CONST_DOUBLE
8278            && !CONST_DOUBLE_HIGH (operands[2])
8279            && CONST_DOUBLE_LOW (operands[2]) >= 32
8280            && CONST_DOUBLE_LOW (operands[2]) < 64))"
8281   "*
8282 {
8283   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8284
8285   return \"sra\\t%1, %2, %0\";
8286 }"
8287   [(set_attr "type" "shift")])
8288
8289 (define_expand "ashrdi3"
8290   [(set (match_operand:DI 0 "register_operand" "=r")
8291         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8292                      (match_operand:SI 2 "arith_operand" "rI")))]
8293   "TARGET_ARCH64 || TARGET_V8PLUS"
8294   "
8295 {
8296   if (! TARGET_ARCH64)
8297     {
8298       if (GET_CODE (operands[2]) == CONST_INT)
8299         FAIL;   /* prefer generic code in this case */
8300       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8301       DONE;
8302     }
8303 }")
8304
8305 (define_insn ""
8306   [(set (match_operand:DI 0 "register_operand" "=r")
8307         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8308                      (match_operand:SI 2 "arith_operand" "rI")))]
8309   "TARGET_ARCH64"
8310   "*
8311 {
8312   if (GET_CODE (operands[2]) == CONST_INT
8313       && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8314     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8315
8316   return \"srax\\t%1, %2, %0\";
8317 }"
8318   [(set_attr "type" "shift")])
8319
8320 ;; XXX
8321 (define_insn "ashrdi3_v8plus"
8322   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8323         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8324                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8325    (clobber (match_scratch:SI 3 "=X,X,&h"))]
8326   "TARGET_V8PLUS"
8327   "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8328   [(set_attr "type" "multi")
8329    (set_attr "length" "5,5,6")])
8330
8331 (define_insn "lshrsi3"
8332   [(set (match_operand:SI 0 "register_operand" "=r")
8333         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8334                      (match_operand:SI 2 "arith_operand" "rI")))]
8335   ""
8336   "*
8337 {
8338   if (GET_CODE (operands[2]) == CONST_INT
8339       && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8340     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8341
8342   return \"srl\\t%1, %2, %0\";
8343 }"
8344   [(set_attr "type" "shift")])
8345
8346 ;; This handles the case where
8347 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8348 ;; but combiner "simplifies" it for us.
8349 (define_insn "*lshrsi3_extend"
8350   [(set (match_operand:DI 0 "register_operand" "=r")
8351         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8352                            (match_operand:SI 2 "arith_operand" "r")) 0)
8353                 (match_operand 3 "" "")))]
8354   "TARGET_ARCH64
8355    && ((GET_CODE (operands[3]) == CONST_DOUBLE
8356            && CONST_DOUBLE_HIGH (operands[3]) == 0
8357            && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8358        || (HOST_BITS_PER_WIDE_INT >= 64
8359            && GET_CODE (operands[3]) == CONST_INT
8360            && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8361   "srl\\t%1, %2, %0"
8362   [(set_attr "type" "shift")])
8363
8364 ;; This handles the case where
8365 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8366 ;; but combiner "simplifies" it for us.
8367 (define_insn "*lshrsi3_extend2"
8368   [(set (match_operand:DI 0 "register_operand" "=r")
8369         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8370                          (match_operand 2 "small_int_or_double" "n")
8371                          (const_int 32)))]
8372   "TARGET_ARCH64
8373    && ((GET_CODE (operands[2]) == CONST_INT
8374         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8375        || (GET_CODE (operands[2]) == CONST_DOUBLE
8376            && CONST_DOUBLE_HIGH (operands[2]) == 0
8377            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8378   "*
8379 {
8380   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8381
8382   return \"srl\\t%1, %2, %0\";
8383 }"
8384   [(set_attr "type" "shift")])
8385
8386 (define_expand "lshrdi3"
8387   [(set (match_operand:DI 0 "register_operand" "=r")
8388         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8389                      (match_operand:SI 2 "arith_operand" "rI")))]
8390   "TARGET_ARCH64 || TARGET_V8PLUS"
8391   "
8392 {
8393   if (! TARGET_ARCH64)
8394     {
8395       if (GET_CODE (operands[2]) == CONST_INT)
8396         FAIL;
8397       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8398       DONE;
8399     }
8400 }")
8401
8402 (define_insn ""
8403   [(set (match_operand:DI 0 "register_operand" "=r")
8404         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8405                      (match_operand:SI 2 "arith_operand" "rI")))]
8406   "TARGET_ARCH64"
8407   "*
8408 {
8409   if (GET_CODE (operands[2]) == CONST_INT
8410       && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8411     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8412
8413   return \"srlx\\t%1, %2, %0\";
8414 }"
8415   [(set_attr "type" "shift")])
8416
8417 ;; XXX
8418 (define_insn "lshrdi3_v8plus"
8419   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8420         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8421                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8422    (clobber (match_scratch:SI 3 "=X,X,&h"))]
8423   "TARGET_V8PLUS"
8424   "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8425   [(set_attr "type" "multi")
8426    (set_attr "length" "5,5,6")])
8427
8428 (define_insn ""
8429   [(set (match_operand:SI 0 "register_operand" "=r")
8430         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8431                                              (const_int 32)) 4)
8432                      (match_operand:SI 2 "small_int_or_double" "n")))]
8433   "TARGET_ARCH64
8434    && ((GET_CODE (operands[2]) == CONST_INT
8435         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8436        || (GET_CODE (operands[2]) == CONST_DOUBLE
8437            && !CONST_DOUBLE_HIGH (operands[2])
8438            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8439   "*
8440 {
8441   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8442
8443   return \"srax\\t%1, %2, %0\";
8444 }"
8445   [(set_attr "type" "shift")])
8446
8447 (define_insn ""
8448   [(set (match_operand:SI 0 "register_operand" "=r")
8449         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8450                                              (const_int 32)) 4)
8451                      (match_operand:SI 2 "small_int_or_double" "n")))]
8452   "TARGET_ARCH64
8453    && ((GET_CODE (operands[2]) == CONST_INT
8454         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8455        || (GET_CODE (operands[2]) == CONST_DOUBLE
8456            && !CONST_DOUBLE_HIGH (operands[2])
8457            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8458   "*
8459 {
8460   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8461
8462   return \"srlx\\t%1, %2, %0\";
8463 }"
8464   [(set_attr "type" "shift")])
8465
8466 (define_insn ""
8467   [(set (match_operand:SI 0 "register_operand" "=r")
8468         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8469                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
8470                      (match_operand:SI 3 "small_int_or_double" "n")))]
8471   "TARGET_ARCH64
8472    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8473    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8474    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8475    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8476   "*
8477 {
8478   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8479
8480   return \"srax\\t%1, %2, %0\";
8481 }"
8482   [(set_attr "type" "shift")])
8483
8484 (define_insn ""
8485   [(set (match_operand:SI 0 "register_operand" "=r")
8486         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8487                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
8488                      (match_operand:SI 3 "small_int_or_double" "n")))]
8489   "TARGET_ARCH64
8490    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8491    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8492    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8493    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8494   "*
8495 {
8496   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8497
8498   return \"srlx\\t%1, %2, %0\";
8499 }"
8500   [(set_attr "type" "shift")])
8501 \f
8502 ;; Unconditional and other jump instructions
8503 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8504 ;; following insn is never executed.  This saves us a nop.  Dbx does not
8505 ;; handle such branches though, so we only use them when optimizing.
8506 (define_insn "jump"
8507   [(set (pc) (label_ref (match_operand 0 "" "")))]
8508   ""
8509   "*
8510 {
8511   /* TurboSparc is reported to have problems with
8512      with
8513         foo: b,a foo
8514      i.e. an empty loop with the annul bit set.  The workaround is to use 
8515         foo: b foo; nop
8516      instead.  */
8517
8518   if (! TARGET_V9 && flag_delayed_branch
8519       && (INSN_ADDRESSES (INSN_UID (operands[0]))
8520           == INSN_ADDRESSES (INSN_UID (insn))))
8521     return \"b\\t%l0%#\";
8522   else
8523     return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8524 }"
8525   [(set_attr "type" "uncond_branch")])
8526
8527 (define_expand "tablejump"
8528   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8529               (use (label_ref (match_operand 1 "" "")))])]
8530   ""
8531   "
8532 {
8533   if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8534     abort ();
8535
8536   /* In pic mode, our address differences are against the base of the
8537      table.  Add that base value back in; CSE ought to be able to combine
8538      the two address loads.  */
8539   if (flag_pic)
8540     {
8541       rtx tmp, tmp2;
8542       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8543       tmp2 = operands[0];
8544       if (CASE_VECTOR_MODE != Pmode)
8545         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8546       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8547       operands[0] = memory_address (Pmode, tmp);
8548     }
8549 }")
8550
8551 (define_insn "*tablejump_sp32"
8552   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8553    (use (label_ref (match_operand 1 "" "")))]
8554   "! TARGET_ARCH64"
8555   "jmp\\t%a0%#"
8556   [(set_attr "type" "uncond_branch")])
8557
8558 (define_insn "*tablejump_sp64"
8559   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8560    (use (label_ref (match_operand 1 "" "")))]
8561   "TARGET_ARCH64"
8562   "jmp\\t%a0%#"
8563   [(set_attr "type" "uncond_branch")])
8564
8565 ;; This pattern recognizes the "instruction" that appears in 
8566 ;; a function call that wants a structure value, 
8567 ;; to inform the called function if compiled with Sun CC.
8568 ;(define_insn "*unimp_insn"
8569 ;  [(match_operand:SI 0 "immediate_operand" "")]
8570 ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8571 ;  "unimp\\t%0"
8572 ;  [(set_attr "type" "marker")])
8573
8574 ;;- jump to subroutine
8575 (define_expand "call"
8576   ;; Note that this expression is not used for generating RTL.
8577   ;; All the RTL is generated explicitly below.
8578   [(call (match_operand 0 "call_operand" "")
8579          (match_operand 3 "" "i"))]
8580   ;; operands[2] is next_arg_register
8581   ;; operands[3] is struct_value_size_rtx.
8582   ""
8583   "
8584 {
8585   rtx fn_rtx, nregs_rtx;
8586
8587    if (GET_MODE (operands[0]) != FUNCTION_MODE)
8588     abort ();
8589
8590   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8591     {
8592       /* This is really a PIC sequence.  We want to represent
8593          it as a funny jump so its delay slots can be filled. 
8594
8595          ??? But if this really *is* a CALL, will not it clobber the
8596          call-clobbered registers?  We lose this if it is a JUMP_INSN.
8597          Why cannot we have delay slots filled if it were a CALL?  */
8598
8599       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8600         emit_jump_insn
8601           (gen_rtx_PARALLEL
8602            (VOIDmode,
8603             gen_rtvec (3,
8604                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8605                        operands[3],
8606                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8607       else
8608         emit_jump_insn
8609           (gen_rtx_PARALLEL
8610            (VOIDmode,
8611             gen_rtvec (2,
8612                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8613                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8614       goto finish_call;
8615     }
8616
8617   fn_rtx = operands[0];
8618
8619   /* Count the number of parameter registers being used by this call.
8620      if that argument is NULL, it means we are using them all, which
8621      means 6 on the sparc.  */
8622 #if 0
8623   if (operands[2])
8624     nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8625   else
8626     nregs_rtx = GEN_INT (6);
8627 #else
8628   nregs_rtx = const0_rtx;
8629 #endif
8630
8631   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8632     emit_call_insn
8633       (gen_rtx_PARALLEL
8634        (VOIDmode,
8635         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8636                    operands[3],
8637                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8638   else
8639     emit_call_insn
8640       (gen_rtx_PARALLEL
8641        (VOIDmode,
8642         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8643                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8644
8645  finish_call:
8646 #if 0
8647   /* If this call wants a structure value,
8648      emit an unimp insn to let the called function know about this.  */
8649   if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8650     {
8651       rtx insn = emit_insn (operands[3]);
8652       SCHED_GROUP_P (insn) = 1;
8653     }
8654 #endif
8655
8656   DONE;
8657 }")
8658
8659 ;; We can't use the same pattern for these two insns, because then registers
8660 ;; in the address may not be properly reloaded.
8661
8662 (define_insn "*call_address_sp32"
8663   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8664          (match_operand 1 "" ""))
8665    (clobber (reg:SI 15))]
8666   ;;- Do not use operand 1 for most machines.
8667   "! TARGET_ARCH64"
8668   "call\\t%a0, %1%#"
8669   [(set_attr "type" "call")])
8670
8671 (define_insn "*call_symbolic_sp32"
8672   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8673          (match_operand 1 "" ""))
8674    (clobber (reg:SI 15))]
8675   ;;- Do not use operand 1 for most machines.
8676   "! TARGET_ARCH64"
8677   "call\\t%a0, %1%#"
8678   [(set_attr "type" "call")])
8679
8680 (define_insn "*call_address_sp64"
8681   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8682          (match_operand 1 "" ""))
8683    (clobber (reg:DI 15))]
8684   ;;- Do not use operand 1 for most machines.
8685   "TARGET_ARCH64"
8686   "call\\t%a0, %1%#"
8687   [(set_attr "type" "call")])
8688
8689 (define_insn "*call_symbolic_sp64"
8690   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8691          (match_operand 1 "" ""))
8692    (clobber (reg:DI 15))]
8693   ;;- Do not use operand 1 for most machines.
8694   "TARGET_ARCH64"
8695   "call\\t%a0, %1%#"
8696   [(set_attr "type" "call")])
8697
8698 ;; This is a call that wants a structure value.
8699 ;; There is no such critter for v9 (??? we may need one anyway).
8700 (define_insn "*call_address_struct_value_sp32"
8701   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8702          (match_operand 1 "" ""))
8703    (match_operand 2 "immediate_operand" "")
8704    (clobber (reg:SI 15))]
8705   ;;- Do not use operand 1 for most machines.
8706   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8707   "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8708   [(set_attr "type" "call_no_delay_slot")
8709    (set_attr "length" "3")])
8710
8711 ;; This is a call that wants a structure value.
8712 ;; There is no such critter for v9 (??? we may need one anyway).
8713 (define_insn "*call_symbolic_struct_value_sp32"
8714   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8715          (match_operand 1 "" ""))
8716    (match_operand 2 "immediate_operand" "")
8717    (clobber (reg:SI 15))]
8718   ;;- Do not use operand 1 for most machines.
8719   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8720   "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8721   [(set_attr "type" "call_no_delay_slot")
8722    (set_attr "length" "3")])
8723
8724 ;; This is a call that may want a structure value.  This is used for
8725 ;; untyped_calls.
8726 (define_insn "*call_address_untyped_struct_value_sp32"
8727   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8728          (match_operand 1 "" ""))
8729    (match_operand 2 "immediate_operand" "")
8730    (clobber (reg:SI 15))]
8731   ;;- Do not use operand 1 for most machines.
8732   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8733   "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8734   [(set_attr "type" "call_no_delay_slot")
8735    (set_attr "length" "3")])
8736
8737 ;; This is a call that wants a structure value.
8738 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8739   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8740          (match_operand 1 "" ""))
8741    (match_operand 2 "immediate_operand" "")
8742    (clobber (reg:SI 15))]
8743   ;;- Do not use operand 1 for most machines.
8744   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8745   "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8746   [(set_attr "type" "call_no_delay_slot")
8747    (set_attr "length" "3")])
8748
8749 (define_expand "call_value"
8750   ;; Note that this expression is not used for generating RTL.
8751   ;; All the RTL is generated explicitly below.
8752   [(set (match_operand 0 "register_operand" "=rf")
8753         (call (match_operand 1 "" "")
8754               (match_operand 4 "" "")))]
8755   ;; operand 2 is stack_size_rtx
8756   ;; operand 3 is next_arg_register
8757   ""
8758   "
8759 {
8760   rtx fn_rtx, nregs_rtx;
8761   rtvec vec;
8762
8763   if (GET_MODE (operands[1]) != FUNCTION_MODE)
8764     abort ();
8765
8766   fn_rtx = operands[1];
8767
8768 #if 0
8769   if (operands[3])
8770     nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8771   else
8772     nregs_rtx = GEN_INT (6);
8773 #else
8774   nregs_rtx = const0_rtx;
8775 #endif
8776
8777   vec = gen_rtvec (2,
8778                    gen_rtx_SET (VOIDmode, operands[0],
8779                                 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8780                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8781
8782   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8783
8784   DONE;
8785 }")
8786
8787 (define_insn "*call_value_address_sp32"
8788   [(set (match_operand 0 "" "=rf")
8789         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8790               (match_operand 2 "" "")))
8791    (clobber (reg:SI 15))]
8792   ;;- Do not use operand 2 for most machines.
8793   "! TARGET_ARCH64"
8794   "call\\t%a1, %2%#"
8795   [(set_attr "type" "call")])
8796
8797 (define_insn "*call_value_symbolic_sp32"
8798   [(set (match_operand 0 "" "=rf")
8799         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8800               (match_operand 2 "" "")))
8801    (clobber (reg:SI 15))]
8802   ;;- Do not use operand 2 for most machines.
8803   "! TARGET_ARCH64"
8804   "call\\t%a1, %2%#"
8805   [(set_attr "type" "call")])
8806
8807 (define_insn "*call_value_address_sp64"
8808   [(set (match_operand 0 "" "")
8809         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8810               (match_operand 2 "" "")))
8811    (clobber (reg:DI 15))]
8812   ;;- Do not use operand 2 for most machines.
8813   "TARGET_ARCH64"
8814   "call\\t%a1, %2%#"
8815   [(set_attr "type" "call")])
8816
8817 (define_insn "*call_value_symbolic_sp64"
8818   [(set (match_operand 0 "" "")
8819         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8820               (match_operand 2 "" "")))
8821    (clobber (reg:DI 15))]
8822   ;;- Do not use operand 2 for most machines.
8823   "TARGET_ARCH64"
8824   "call\\t%a1, %2%#"
8825   [(set_attr "type" "call")])
8826
8827 (define_expand "untyped_call"
8828   [(parallel [(call (match_operand 0 "" "")
8829                     (const_int 0))
8830               (match_operand 1 "" "")
8831               (match_operand 2 "" "")])]
8832   ""
8833   "
8834 {
8835   int i;
8836
8837   /* Pass constm1 to indicate that it may expect a structure value, but
8838      we don't know what size it is.  */
8839   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8840
8841   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8842     {
8843       rtx set = XVECEXP (operands[2], 0, i);
8844       emit_move_insn (SET_DEST (set), SET_SRC (set));
8845     }
8846
8847   /* The optimizer does not know that the call sets the function value
8848      registers we stored in the result block.  We avoid problems by
8849      claiming that all hard registers are used and clobbered at this
8850      point.  */
8851   emit_insn (gen_blockage ());
8852
8853   DONE;
8854 }")
8855
8856 ;;- tail calls
8857 (define_expand "sibcall"
8858   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8859               (return)])]
8860   ""
8861   "")
8862
8863 (define_insn "*sibcall_symbolic_sp32"
8864   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8865          (match_operand 1 "" ""))
8866    (return)]
8867   "! TARGET_ARCH64"
8868   "* return output_sibcall(insn, operands[0]);"
8869   [(set_attr "type" "sibcall")])
8870
8871 (define_insn "*sibcall_symbolic_sp64"
8872   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8873          (match_operand 1 "" ""))
8874    (return)]
8875   "TARGET_ARCH64"
8876   "* return output_sibcall(insn, operands[0]);"
8877   [(set_attr "type" "sibcall")])
8878
8879 (define_expand "sibcall_value"
8880   [(parallel [(set (match_operand 0 "register_operand" "=rf")
8881                 (call (match_operand 1 "" "") (const_int 0)))
8882               (return)])]
8883   ""
8884   "")
8885
8886 (define_insn "*sibcall_value_symbolic_sp32"
8887   [(set (match_operand 0 "" "=rf")
8888         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8889               (match_operand 2 "" "")))
8890    (return)]
8891   "! TARGET_ARCH64"
8892   "* return output_sibcall(insn, operands[1]);"
8893   [(set_attr "type" "sibcall")])
8894
8895 (define_insn "*sibcall_value_symbolic_sp64"
8896   [(set (match_operand 0 "" "")
8897         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8898               (match_operand 2 "" "")))
8899    (return)]
8900   "TARGET_ARCH64"
8901   "* return output_sibcall(insn, operands[1]);"
8902   [(set_attr "type" "sibcall")])
8903
8904 (define_expand "sibcall_epilogue"
8905   [(const_int 0)]
8906   ""
8907   "DONE;")
8908
8909 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8910 ;; all of memory.  This blocks insns from being moved across this point.
8911
8912 (define_insn "blockage"
8913   [(unspec_volatile [(const_int 0)] 0)]
8914   ""
8915   ""
8916   [(set_attr "length" "0")])
8917
8918 ;; Prepare to return any type including a structure value.
8919
8920 (define_expand "untyped_return"
8921   [(match_operand:BLK 0 "memory_operand" "")
8922    (match_operand 1 "" "")]
8923   ""
8924   "
8925 {
8926   rtx valreg1 = gen_rtx_REG (DImode, 24);
8927   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8928   rtx result = operands[0];
8929
8930   if (! TARGET_ARCH64)
8931     {
8932       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8933                                          ? 15 : 31));
8934       rtx value = gen_reg_rtx (SImode);
8935
8936       /* Fetch the instruction where we will return to and see if it's an unimp
8937          instruction (the most significant 10 bits will be zero).  If so,
8938          update the return address to skip the unimp instruction.  */
8939       emit_move_insn (value,
8940                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8941       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8942       emit_insn (gen_update_return (rtnreg, value));
8943     }
8944
8945   /* Reload the function value registers.  */
8946   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8947   emit_move_insn (valreg2,
8948                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8949
8950   /* Put USE insns before the return.  */
8951   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8952   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8953
8954   /* Construct the return.  */
8955   expand_null_return ();
8956
8957   DONE;
8958 }")
8959
8960 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
8961 ;; and parts of the compiler don't want to believe that the add is needed.
8962
8963 (define_insn "update_return"
8964   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8965                (match_operand:SI 1 "register_operand" "r")] 1)]
8966   "! TARGET_ARCH64"
8967   "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8968   [(set_attr "type" "multi")
8969    (set_attr "length" "3")])
8970 \f
8971 (define_insn "nop"
8972   [(const_int 0)]
8973   ""
8974   "nop")
8975
8976 (define_expand "indirect_jump"
8977   [(set (pc) (match_operand 0 "address_operand" "p"))]
8978   ""
8979   "")
8980
8981 (define_insn "*branch_sp32"
8982   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8983   "! TARGET_ARCH64"
8984  "jmp\\t%a0%#"
8985  [(set_attr "type" "uncond_branch")])
8986  
8987 (define_insn "*branch_sp64"
8988   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8989   "TARGET_ARCH64"
8990   "jmp\\t%a0%#"
8991   [(set_attr "type" "uncond_branch")])
8992
8993 ;; ??? Doesn't work with -mflat.
8994 (define_expand "nonlocal_goto"
8995   [(match_operand:SI 0 "general_operand" "")
8996    (match_operand:SI 1 "general_operand" "")
8997    (match_operand:SI 2 "general_operand" "")
8998    (match_operand:SI 3 "" "")]
8999   ""
9000   "
9001 {
9002 #if 0
9003   rtx chain = operands[0];
9004 #endif
9005   rtx lab = operands[1];
9006   rtx stack = operands[2];
9007   rtx fp = operands[3];
9008   rtx labreg;
9009
9010   /* Trap instruction to flush all the register windows.  */
9011   emit_insn (gen_flush_register_windows ());
9012
9013   /* Load the fp value for the containing fn into %fp.  This is needed
9014      because STACK refers to %fp.  Note that virtual register instantiation
9015      fails if the virtual %fp isn't set from a register.  */
9016   if (GET_CODE (fp) != REG)
9017     fp = force_reg (Pmode, fp);
9018   emit_move_insn (virtual_stack_vars_rtx, fp);
9019
9020   /* Find the containing function's current nonlocal goto handler,
9021      which will do any cleanups and then jump to the label.  */
9022   labreg = gen_rtx_REG (Pmode, 8);
9023   emit_move_insn (labreg, lab);
9024
9025   /* Restore %fp from stack pointer value for containing function.
9026      The restore insn that follows will move this to %sp,
9027      and reload the appropriate value into %fp.  */
9028   emit_move_insn (hard_frame_pointer_rtx, stack);
9029
9030   /* USE of frame_pointer_rtx added for consistency; not clear if
9031      really needed.  */
9032   /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
9033   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
9034
9035 #if 0
9036   /* Return, restoring reg window and jumping to goto handler.  */
9037   if (TARGET_V9 && GET_CODE (chain) == CONST_INT
9038       && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
9039     {
9040       emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
9041                                                        static_chain_rtx,
9042                                                        chain));
9043       emit_barrier ();
9044       DONE;
9045     }
9046   /* Put in the static chain register the nonlocal label address.  */
9047   emit_move_insn (static_chain_rtx, chain);
9048 #endif
9049
9050   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
9051   emit_jump_insn (gen_goto_handler_and_restore (labreg));
9052   emit_barrier ();
9053   DONE;
9054 }")
9055
9056 ;; Special trap insn to flush register windows.
9057 (define_insn "flush_register_windows"
9058   [(unspec_volatile [(const_int 0)] 1)]
9059   ""
9060   "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
9061   [(set_attr "type" "misc")])
9062
9063 (define_insn "goto_handler_and_restore"
9064   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
9065   "GET_MODE (operands[0]) == Pmode"
9066   "jmp\\t%0+0\\n\\trestore"
9067   [(set_attr "type" "multi")
9068    (set_attr "length" "2")])
9069
9070 ;;(define_insn "goto_handler_and_restore_v9"
9071 ;;  [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
9072 ;;                   (match_operand:SI 1 "register_operand" "=r,r")
9073 ;;                   (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9074 ;;  "TARGET_V9 && ! TARGET_ARCH64"
9075 ;;  "@
9076 ;;   return\\t%0+0\\n\\tmov\\t%2, %Y1
9077 ;;   sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9078 ;;  [(set_attr "type" "multi")
9079 ;;   (set_attr "length" "2,3")])
9080 ;;
9081 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
9082 ;;  [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
9083 ;;                   (match_operand:DI 1 "register_operand" "=r,r")
9084 ;;                   (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
9085 ;;  "TARGET_V9 && TARGET_ARCH64"
9086 ;;  "@
9087 ;;   return\\t%0+0\\n\\tmov\\t%2, %Y1
9088 ;;   sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9089 ;;  [(set_attr "type" "multi")
9090 ;;   (set_attr "length" "2,3")])
9091
9092 ;; For __builtin_setjmp we need to flush register windows iff the function
9093 ;; calls alloca as well, because otherwise the register window might be
9094 ;; saved after %sp adjustement and thus setjmp would crash
9095 (define_expand "builtin_setjmp_setup"
9096   [(match_operand 0 "register_operand" "r")]
9097   ""
9098   "
9099 {
9100   emit_insn (gen_do_builtin_setjmp_setup ());
9101   DONE;
9102 }")
9103
9104 (define_insn "do_builtin_setjmp_setup"
9105   [(unspec_volatile [(const_int 0)] 5)]
9106   ""
9107   "*
9108 {
9109   if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
9110     return \"#\";
9111   fputs (\"\tflushw\n\", asm_out_file);
9112   if (flag_pic)
9113     fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
9114              TARGET_ARCH64 ? 'x' : 'w',
9115              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
9116   fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
9117            TARGET_ARCH64 ? 'x' : 'w',
9118            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
9119   fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
9120            TARGET_ARCH64 ? 'x' : 'w',
9121            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
9122   return \"\";
9123 }"
9124   [(set_attr "type" "misc")
9125    (set (attr "length") (if_then_else (eq_attr "pic" "true")
9126                                        (const_int 4)
9127                                        (const_int 3)))])
9128
9129 (define_split
9130   [(unspec_volatile [(const_int 0)] 5)]
9131   "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
9132   [(const_int 0)]
9133   "
9134 {
9135   if (current_function_calls_alloca)
9136     emit_insn (gen_flush_register_windows ());
9137   DONE;
9138 }")
9139
9140 ;; Pattern for use after a setjmp to store FP and the return register
9141 ;; into the stack area.
9142
9143 (define_expand "setjmp"
9144   [(const_int 0)]
9145   ""
9146   "
9147 {
9148   if (TARGET_ARCH64)
9149     emit_insn (gen_setjmp_64 ());
9150   else
9151     emit_insn (gen_setjmp_32 ());
9152   DONE;
9153 }")
9154
9155 (define_expand "setjmp_32"
9156   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
9157    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
9158   ""
9159   "
9160 { operands[0] = frame_pointer_rtx; }")
9161
9162 (define_expand "setjmp_64"
9163   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9164    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9165   ""
9166   "
9167 { operands[0] = frame_pointer_rtx; }")
9168
9169 ;; Special pattern for the FLUSH instruction.
9170
9171 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9172 ; of the define_insn otherwise missing a mode.  We make "flush", aka
9173 ; gen_flush, the default one since sparc_initialize_trampoline uses
9174 ; it on SImode mem values.
9175
9176 (define_insn "flush"
9177   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9178   ""
9179   "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9180   [(set_attr "type" "misc")])
9181
9182 (define_insn "flushdi"
9183   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9184   ""
9185   "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9186   [(set_attr "type" "misc")])
9187
9188 \f
9189 ;; find first set.
9190
9191 ;; The scan instruction searches from the most significant bit while ffs
9192 ;; searches from the least significant bit.  The bit index and treatment of
9193 ;; zero also differ.  It takes at least 7 instructions to get the proper
9194 ;; result.  Here is an obvious 8 instruction sequence.
9195
9196 ;; XXX
9197 (define_insn "ffssi2"
9198   [(set (match_operand:SI 0 "register_operand" "=&r")
9199         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9200    (clobber (match_scratch:SI 2 "=&r"))]
9201   "TARGET_SPARCLITE || TARGET_SPARCLET"
9202   "*
9203 {
9204   return \"sub\\t%%g0, %1, %0\;and\\t%0, %1, %0\;scan\\t%0, 0, %0\;mov\\t32, %2\;sub\\t%2, %0, %0\;sra\\t%0, 31, %2\;and\\t%2, 31, %2\;add\\t%2, %0, %0\";
9205 }"
9206   [(set_attr "type" "multi")
9207    (set_attr "length" "8")])
9208
9209 ;; ??? This should be a define expand, so that the extra instruction have
9210 ;; a chance of being optimized away.
9211
9212 ;; Disabled because none of the UltraSparcs implement popc.  The HAL R1
9213 ;; does, but no one uses that and we don't have a switch for it.
9214 ;
9215 ;(define_insn "ffsdi2"
9216 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
9217 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9218 ;   (clobber (match_scratch:DI 2 "=&r"))]
9219 ;  "TARGET_ARCH64"
9220 ;  "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9221 ;  [(set_attr "type" "multi")
9222 ;   (set_attr "length" "4")])
9223
9224
9225 \f
9226 ;; Peepholes go at the end.
9227
9228 ;; Optimize consecutive loads or stores into ldd and std when possible.
9229 ;; The conditions in which we do this are very restricted and are 
9230 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9231
9232 (define_peephole2
9233   [(set (match_operand:SI 0 "memory_operand" "")
9234       (const_int 0))
9235    (set (match_operand:SI 1 "memory_operand" "")
9236       (const_int 0))]
9237   "TARGET_V9
9238    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
9239   [(set (match_dup 0)
9240        (const_int 0))]
9241   "operands[0] = change_address (operands[0], DImode, NULL);")
9242
9243 (define_peephole2
9244   [(set (match_operand:SI 0 "memory_operand" "")
9245       (const_int 0))
9246    (set (match_operand:SI 1 "memory_operand" "")
9247       (const_int 0))]
9248   "TARGET_V9
9249    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9250   [(set (match_dup 1)
9251        (const_int 0))]
9252   "operands[1] = change_address (operands[1], DImode, NULL);")
9253
9254 (define_peephole2
9255   [(set (match_operand:SI 0 "register_operand" "")
9256         (match_operand:SI 1 "memory_operand" ""))
9257    (set (match_operand:SI 2 "register_operand" "")
9258         (match_operand:SI 3 "memory_operand" ""))]
9259   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
9260    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
9261   [(set (match_dup 0)
9262         (match_dup 1))]
9263   "operands[1] = change_address (operands[1], DImode, NULL);
9264    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9265
9266 (define_peephole2
9267   [(set (match_operand:SI 0 "memory_operand" "")
9268         (match_operand:SI 1 "register_operand" ""))
9269    (set (match_operand:SI 2 "memory_operand" "")
9270         (match_operand:SI 3 "register_operand" ""))]
9271   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
9272    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9273   [(set (match_dup 0)
9274         (match_dup 1))]
9275   "operands[0] = change_address (operands[0], DImode, NULL);
9276    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9277
9278 (define_peephole2
9279   [(set (match_operand:SF 0 "register_operand" "")
9280         (match_operand:SF 1 "memory_operand" ""))
9281    (set (match_operand:SF 2 "register_operand" "")
9282         (match_operand:SF 3 "memory_operand" ""))]
9283   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
9284    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9285   [(set (match_dup 0)
9286         (match_dup 1))]
9287   "operands[1] = change_address (operands[1], DFmode, NULL);
9288    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9289
9290 (define_peephole2
9291   [(set (match_operand:SF 0 "memory_operand" "")
9292         (match_operand:SF 1 "register_operand" ""))
9293    (set (match_operand:SF 2 "memory_operand" "")
9294         (match_operand:SF 3 "register_operand" ""))]
9295   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
9296   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9297   [(set (match_dup 0)
9298         (match_dup 1))]
9299   "operands[0] = change_address (operands[0], DFmode, NULL);
9300    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9301
9302 (define_peephole2
9303   [(set (match_operand:SI 0 "register_operand" "")
9304         (match_operand:SI 1 "memory_operand" ""))
9305    (set (match_operand:SI 2 "register_operand" "")
9306         (match_operand:SI 3 "memory_operand" ""))]
9307   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
9308   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9309   [(set (match_dup 2)
9310         (match_dup 3))]
9311    "operands[3] = change_address (operands[3], DImode, NULL);
9312     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9313
9314 (define_peephole2
9315   [(set (match_operand:SI 0 "memory_operand" "")
9316         (match_operand:SI 1 "register_operand" ""))
9317    (set (match_operand:SI 2 "memory_operand" "")
9318         (match_operand:SI 3 "register_operand" ""))]
9319   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
9320   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
9321   [(set (match_dup 2)
9322         (match_dup 3))]
9323   "operands[2] = change_address (operands[2], DImode, NULL);
9324    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9325    ")
9326  
9327 (define_peephole2
9328   [(set (match_operand:SF 0 "register_operand" "")
9329         (match_operand:SF 1 "memory_operand" ""))
9330    (set (match_operand:SF 2 "register_operand" "")
9331         (match_operand:SF 3 "memory_operand" ""))]
9332   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
9333   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9334   [(set (match_dup 2)
9335         (match_dup 3))]
9336   "operands[3] = change_address (operands[3], DFmode, NULL);
9337    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9338
9339 (define_peephole2
9340   [(set (match_operand:SF 0 "memory_operand" "")
9341         (match_operand:SF 1 "register_operand" ""))
9342    (set (match_operand:SF 2 "memory_operand" "")
9343         (match_operand:SF 3 "register_operand" ""))]
9344   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
9345   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9346   [(set (match_dup 2)
9347         (match_dup 3))]
9348   "operands[2] = change_address (operands[2], DFmode, NULL);
9349    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9350  
9351 ;; Optimize the case of following a reg-reg move with a test
9352 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
9353 ;; This can result from a float to fix conversion.
9354
9355 (define_peephole2
9356   [(set (match_operand:SI 0 "register_operand" "")
9357         (match_operand:SI 1 "register_operand" ""))
9358    (set (reg:CC 100)
9359         (compare:CC (match_operand:SI 2 "register_operand" "")
9360                     (const_int 0)))]
9361   "(rtx_equal_p (operands[2], operands[0])
9362     || rtx_equal_p (operands[2], operands[1]))
9363     && ! SPARC_FP_REG_P (REGNO (operands[0]))
9364     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9365   [(parallel [(set (match_dup 0) (match_dup 1))
9366               (set (reg:CC 100)
9367                    (compare:CC (match_dup 1) (const_int 0)))])]
9368   "")
9369
9370 (define_peephole2
9371   [(set (match_operand:DI 0 "register_operand" "")
9372         (match_operand:DI 1 "register_operand" ""))
9373    (set (reg:CCX 100)
9374         (compare:CCX (match_operand:DI 2 "register_operand" "")
9375                     (const_int 0)))]
9376   "TARGET_ARCH64
9377    && (rtx_equal_p (operands[2], operands[0])
9378        || rtx_equal_p (operands[2], operands[1]))
9379    && ! SPARC_FP_REG_P (REGNO (operands[0]))
9380    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9381   [(parallel [(set (match_dup 0) (match_dup 1))
9382               (set (reg:CCX 100)
9383                    (compare:CCX (match_dup 1) (const_int 0)))])]
9384   "")
9385
9386 ;; Return peepholes.  These are generated by sparc_nonflat_function_epilogue
9387 ;; who then immediately calls final_scan_insn.
9388
9389 (define_insn "*return_qi"
9390   [(set (match_operand:QI 0 "restore_operand" "")
9391         (match_operand:QI 1 "arith_operand" "rI"))
9392    (return)]
9393   "sparc_emitting_epilogue"
9394   "*
9395 {
9396   if (! TARGET_ARCH64 && current_function_returns_struct)
9397     return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9398   else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9399                          || IN_OR_GLOBAL_P (operands[1])))
9400     return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9401   else
9402     return \"ret\\n\\trestore %%g0, %1, %Y0\";
9403 }"
9404   [(set_attr "type" "multi")
9405    (set_attr "length" "2")])
9406
9407 (define_insn "*return_hi"
9408   [(set (match_operand:HI 0 "restore_operand" "")
9409         (match_operand:HI 1 "arith_operand" "rI"))
9410    (return)]
9411   "sparc_emitting_epilogue"
9412   "*
9413 {
9414   if (! TARGET_ARCH64 && current_function_returns_struct)
9415     return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9416   else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9417                          || IN_OR_GLOBAL_P (operands[1])))
9418     return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9419   else
9420     return \"ret\;restore %%g0, %1, %Y0\";
9421 }"
9422   [(set_attr "type" "multi")
9423    (set_attr "length" "2")])
9424
9425 (define_insn "*return_si"
9426   [(set (match_operand:SI 0 "restore_operand" "")
9427         (match_operand:SI 1 "arith_operand" "rI"))
9428    (return)]
9429   "sparc_emitting_epilogue"
9430   "*
9431 {
9432   if (! TARGET_ARCH64 && current_function_returns_struct)
9433     return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9434   else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9435                          || IN_OR_GLOBAL_P (operands[1])))
9436     return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9437   else
9438     return \"ret\;restore %%g0, %1, %Y0\";
9439 }"
9440   [(set_attr "type" "multi")
9441    (set_attr "length" "2")])
9442
9443 (define_insn "*return_sf_no_fpu"
9444   [(set (match_operand:SF 0 "restore_operand" "=r")
9445         (match_operand:SF 1 "register_operand" "r"))
9446    (return)]
9447   "sparc_emitting_epilogue"
9448   "*
9449 {
9450   if (! TARGET_ARCH64 && current_function_returns_struct)
9451     return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9452   else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9453     return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9454   else
9455     return \"ret\;restore %%g0, %1, %Y0\";
9456 }"
9457   [(set_attr "type" "multi")
9458    (set_attr "length" "2")])
9459
9460 (define_insn "*return_df_no_fpu"
9461   [(set (match_operand:DF 0 "restore_operand" "=r")
9462         (match_operand:DF 1 "register_operand" "r"))
9463    (return)]
9464   "sparc_emitting_epilogue && TARGET_ARCH64"
9465   "*
9466 {
9467   if (IN_OR_GLOBAL_P (operands[1]))
9468     return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9469   else
9470     return \"ret\;restore %%g0, %1, %Y0\";
9471 }"
9472   [(set_attr "type" "multi")
9473    (set_attr "length" "2")])
9474
9475 (define_insn "*return_addsi"
9476   [(set (match_operand:SI 0 "restore_operand" "")
9477         (plus:SI (match_operand:SI 1 "register_operand" "r")
9478                  (match_operand:SI 2 "arith_operand" "rI")))
9479    (return)]
9480   "sparc_emitting_epilogue"
9481   "*
9482 {
9483   if (! TARGET_ARCH64 && current_function_returns_struct)
9484     return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9485   /* If operands are global or in registers, can use return */
9486   else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9487            && (GET_CODE (operands[2]) == CONST_INT
9488                || IN_OR_GLOBAL_P (operands[2])))
9489     return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9490   else
9491     return \"ret\;restore %r1, %2, %Y0\";
9492 }"
9493   [(set_attr "type" "multi")
9494    (set_attr "length" "2")])
9495
9496 (define_insn "*return_losum_si"
9497   [(set (match_operand:SI 0 "restore_operand" "")
9498         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9499                    (match_operand:SI 2 "immediate_operand" "in")))
9500    (return)]
9501   "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
9502   "*
9503 {
9504   if (! TARGET_ARCH64 && current_function_returns_struct)
9505     return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9506   /* If operands are global or in registers, can use return */
9507   else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9508     return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9509   else
9510     return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9511 }"
9512   [(set_attr "type" "multi")
9513    (set_attr "length" "2")])
9514
9515 (define_insn "*return_di"
9516   [(set (match_operand:DI 0 "restore_operand" "")
9517         (match_operand:DI 1 "arith_double_operand" "rHI"))
9518    (return)]
9519   "sparc_emitting_epilogue && TARGET_ARCH64"
9520   "ret\;restore %%g0, %1, %Y0"
9521   [(set_attr "type" "multi")
9522    (set_attr "length" "2")])
9523
9524 (define_insn "*return_adddi"
9525   [(set (match_operand:DI 0 "restore_operand" "")
9526         (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9527                  (match_operand:DI 2 "arith_double_operand" "rHI")))
9528    (return)]
9529   "sparc_emitting_epilogue && TARGET_ARCH64"
9530   "ret\;restore %r1, %2, %Y0"
9531   [(set_attr "type" "multi")
9532    (set_attr "length" "2")])
9533
9534 (define_insn "*return_losum_di"
9535   [(set (match_operand:DI 0 "restore_operand" "")
9536         (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9537                    (match_operand:DI 2 "immediate_operand" "in")))
9538    (return)]
9539   "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
9540   "ret\;restore %r1, %%lo(%a2), %Y0"
9541   [(set_attr "type" "multi")
9542    (set_attr "length" "2")])
9543
9544 (define_insn "*return_sf"
9545   [(set (reg:SF 32)
9546         (match_operand:SF 0 "register_operand" "f"))
9547    (return)]
9548   "sparc_emitting_epilogue"
9549   "ret\;fmovs\\t%0, %%f0"
9550   [(set_attr "type" "multi")
9551    (set_attr "length" "2")])
9552
9553 ;; Now peepholes to do a call followed by a jump.
9554
9555 (define_peephole
9556   [(parallel [(set (match_operand 0 "" "")
9557                    (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9558                          (match_operand 2 "" "")))
9559               (clobber (reg:SI 15))])
9560    (set (pc) (label_ref (match_operand 3 "" "")))]
9561   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9562    && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
9563    && sparc_cpu != PROCESSOR_ULTRASPARC"
9564   "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9565
9566 (define_peephole
9567   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9568                     (match_operand 1 "" ""))
9569               (clobber (reg:SI 15))])
9570    (set (pc) (label_ref (match_operand 2 "" "")))]
9571   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9572    && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
9573    && sparc_cpu != PROCESSOR_ULTRASPARC"
9574   "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9575
9576 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
9577 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
9578 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
9579 ;; ??? state.
9580 (define_expand "prefetch"
9581   [(match_operand 0 "address_operand" "")
9582    (match_operand 1 "const_int_operand" "")
9583    (match_operand 2 "const_int_operand" "")]
9584   "TARGET_V9"
9585   "
9586 {
9587   if (TARGET_ARCH64)
9588     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
9589   else
9590     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
9591   DONE;
9592 }")
9593
9594 (define_insn "prefetch_64"
9595   [(prefetch (match_operand:DI 0 "address_operand" "p")
9596              (match_operand:DI 1 "const_int_operand" "n")
9597              (match_operand:DI 2 "const_int_operand" "n"))]
9598   ""
9599 {
9600   static const char * const prefetch_instr[2][2] = {
9601     {
9602       "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9603       "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
9604     },
9605     {
9606       "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9607       "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
9608     }
9609   };
9610   int read_or_write = INTVAL (operands[1]);
9611   int locality = INTVAL (operands[2]);
9612
9613   if (read_or_write != 0 && read_or_write != 1)
9614     abort ();
9615   if (locality < 0 || locality > 3)
9616     abort ();
9617   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
9618 }
9619   [(set_attr "type" "load")])
9620
9621 (define_insn "prefetch_32"
9622   [(prefetch (match_operand:SI 0 "address_operand" "p")
9623              (match_operand:SI 1 "const_int_operand" "n")
9624              (match_operand:SI 2 "const_int_operand" "n"))]
9625   ""
9626 {
9627   static const char * const prefetch_instr[2][2] = {
9628     {
9629       "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9630       "prefetch\\t[%a0], 0", /* medium to high locality: prefetch for several reads */
9631     },
9632     {
9633       "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9634       "prefetch\\t[%a0], 2", /* medium to high locality: prefetch for several writes */
9635     }
9636   };
9637   int read_or_write = INTVAL (operands[1]);
9638   int locality = INTVAL (operands[2]);
9639
9640   if (read_or_write != 0 && read_or_write != 1)
9641     abort ();
9642   if (locality < 0 || locality > 3)
9643     abort ();
9644   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
9645 }
9646   [(set_attr "type" "load")])
9647 \f
9648 (define_expand "prologue"
9649   [(const_int 1)]
9650   "flag_pic && current_function_uses_pic_offset_table"
9651   "
9652 {
9653   load_pic_register ();
9654   DONE;
9655 }")
9656
9657 ;; We need to reload %l7 for -mflat -fpic,
9658 ;; otherwise %l7 should be preserved simply
9659 ;; by loading the function's register window
9660 (define_expand "exception_receiver"
9661   [(const_int 0)]
9662   "TARGET_FLAT && flag_pic"
9663   "
9664 {
9665   load_pic_register ();
9666   DONE;
9667 }")
9668
9669 ;; Likewise
9670 (define_expand "builtin_setjmp_receiver"
9671   [(label_ref (match_operand 0 "" ""))]
9672   "TARGET_FLAT && flag_pic"
9673   "
9674 {
9675   load_pic_register ();
9676   DONE;
9677 }")
9678 \f
9679 (define_insn "trap"
9680   [(trap_if (const_int 1) (const_int 5))]
9681   ""
9682   "ta\\t5"
9683   [(set_attr "type" "misc")])
9684
9685 (define_expand "conditional_trap"
9686   [(trap_if (match_operator 0 "noov_compare_op"
9687                             [(match_dup 2) (match_dup 3)])
9688             (match_operand:SI 1 "arith_operand" ""))]
9689   ""
9690   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9691                                   sparc_compare_op0, sparc_compare_op1);
9692    operands[3] = const0_rtx;")
9693
9694 (define_insn ""
9695   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9696             (match_operand:SI 1 "arith_operand" "rM"))]
9697   ""
9698   "t%C0\\t%1"
9699   [(set_attr "type" "misc")])
9700
9701 (define_insn ""
9702   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9703             (match_operand:SI 1 "arith_operand" "rM"))]
9704   "TARGET_V9"
9705   "t%C0\\t%%xcc, %1"
9706   [(set_attr "type" "misc")])
9707
9708 (define_insn "cycle_display"
9709   [(unspec [(match_operand 0 "const_int_operand" "")] 20)]
9710   ""
9711   "! cycle %0"
9712   [(set_attr "length" "0")])