OSDN Git Service

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