OSDN Git Service

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