OSDN Git Service

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