OSDN Git Service

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