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