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