OSDN Git Service

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