OSDN Git Service

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