OSDN Git Service

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