OSDN Git Service

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