OSDN Git Service

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