OSDN Git Service

(movsf-1, movdf-1, movtf-1): Use 'F' not 'E'.
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;;  Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
3 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;;  64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
5 ;;  at Cygnus Support.
6
7 ;; This file is part of GNU CC.
8
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
26 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
27 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
28 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
29 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
30
31 ;; Architecture type.  Arch32bit includes v7, sparclite, v8.
32
33 (define_attr "arch" "arch32bit,arch64bit"
34   (const (symbol_ref "sparc_arch_type")))
35
36 ;; CPU type. This is only used for instruction scheduling
37 (define_attr "cpu" "cypress,supersparc"
38  (const
39   (cond [(symbol_ref "TARGET_SUPERSPARC") (const_string "supersparc")]
40         (const_string "cypress"))))
41
42 ;; Insn type.  Used to default other attribute values.
43
44 ;; type "unary" insns have one input operand (1) and one output operand (0)
45 ;; type "binary" insns have two input operands (1,2) and one output (0)
46 ;; type "compare" insns have one or two input operands (0,1) and no output
47 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
48
49 (define_attr "type"
50   "move,unary,binary,compare,load,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"
51   (const_string "binary"))
52
53 ;; Set true if insn uses call-clobbered intermediate register.
54 (define_attr "use_clobbered" "false,true"
55   (if_then_else (and (eq_attr "type" "address")
56                      (match_operand 0 "clobbered_register" ""))
57                 (const_string "true")
58                 (const_string "false")))
59
60 ;; Length (in # of insns).
61 (define_attr "length" ""
62   (cond [(eq_attr "type" "load,fpload")
63          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
64                        (const_int 2) (const_int 1))
65
66          (eq_attr "type" "store,fpstore")
67          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
68                        (const_int 2) (const_int 1))
69
70          (eq_attr "type" "address") (const_int 2)
71
72          (eq_attr "type" "binary")
73          (if_then_else (ior (match_operand 2 "arith_operand" "")
74                             (match_operand 2 "arith_double_operand" ""))
75                        (const_int 1) (const_int 3))
76
77          (eq_attr "type" "multi") (const_int 2)
78
79          (eq_attr "type" "move,unary")
80          (if_then_else (ior (match_operand 1 "arith_operand" "")
81                             (match_operand 1 "arith_double_operand" ""))
82                        (const_int 1) (const_int 2))]
83
84         (const_int 1)))
85
86 (define_asm_attributes
87   [(set_attr "length" "1")
88    (set_attr "type" "multi")])
89
90 ;; Attributes for instruction and branch scheduling
91
92 (define_attr "in_call_delay" "false,true"
93   (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
94                 (const_string "false")
95          (eq_attr "type" "load,fpload,store,fpstore")
96                 (if_then_else (eq_attr "length" "1")
97                               (const_string "true")
98                               (const_string "false"))
99          (eq_attr "type" "address")
100                 (if_then_else (eq_attr "use_clobbered" "false")
101                               (const_string "true")
102                               (const_string "false"))]
103         (if_then_else (eq_attr "length" "1")
104                       (const_string "true")
105                       (const_string "false"))))
106
107 (define_delay (eq_attr "type" "call")
108   [(eq_attr "in_call_delay" "true") (nil) (nil)])
109
110 ;; ??? Should implement the notion of predelay slots for floating point
111 ;; branches.  This would allow us to remove the nop always inserted before
112 ;; a floating point branch.
113
114 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
115 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
116 ;; This is because doing so will add several pipeline stalls to the path
117 ;; that the load/store did not come from.  Unfortunately, there is no way
118 ;; to prevent fill_eager_delay_slots from using load/store without completely
119 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
120 ;; because it prevents us from moving back the final store of inner loops.
121
122 (define_attr "in_branch_delay" "false,true"
123   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
124                      (eq_attr "length" "1"))
125                 (const_string "true")
126                 (const_string "false")))
127
128 (define_attr "in_uncond_branch_delay" "false,true"
129   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
130                      (eq_attr "length" "1"))
131                 (const_string "true")
132                 (const_string "false")))
133
134 (define_attr "in_annul_branch_delay" "false,true"
135   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
136                      (eq_attr "length" "1"))
137                 (const_string "true")
138                 (const_string "false")))
139
140 (define_delay (eq_attr "type" "branch")
141   [(eq_attr "in_branch_delay" "true")
142    (nil) (eq_attr "in_annul_branch_delay" "true")])
143
144 (define_delay (eq_attr "type" "uncond_branch")
145   [(eq_attr "in_uncond_branch_delay" "true")
146    (nil) (nil)])
147    
148 ;; Function units of the SPARC
149
150 ;; (define_function_unit {name} {num-units} {n-users} {test}
151 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
152
153 ;; The integer ALU.
154 ;; (Noted only for documentation; units that take one cycle do not need to
155 ;; be specified.)
156
157 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
158 ;; the inputs.
159
160 ;; (define_function_unit "alu" 1 0
161 ;;  (eq_attr "type" "unary,binary,move,address") 1 0)
162
163 ;; ---- cypress CY7C602 scheduling:
164 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
165 (define_function_unit "memory" 1 0 
166   (and (eq_attr "type" "load,fpload") (eq_attr "cpu" "cypress")) 2 2)
167
168 ;; SPARC has two floating-point units: the FP ALU,
169 ;; and the FP MUL/DIV/SQRT unit.
170 ;; Instruction timings on the CY7C602 are as follows
171 ;; FABSs        4
172 ;; FADDs/d      5/5
173 ;; FCMPs/d      4/4
174 ;; FDIVs/d      23/37
175 ;; FMOVs        4
176 ;; FMULs/d      5/7
177 ;; FNEGs        4
178 ;; FSQRTs/d     34/63
179 ;; FSUBs/d      5/5
180 ;; FdTOi/s      5/5
181 ;; FsTOi/d      5/5
182 ;; FiTOs/d      9/5
183
184 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
185 ;; More insns cause the chip to stall.
186
187 (define_function_unit "fp_alu" 1 0
188   (and (eq_attr "type" "fp")            (eq_attr "cpu" "cypress")) 5 5)
189 (define_function_unit "fp_mds" 1 0
190   (and (eq_attr "type" "fpmul")         (eq_attr "cpu" "cypress")) 7 7)
191 (define_function_unit "fp_mds" 1 0
192   (and (eq_attr "type" "fpdivs,fpdivd") (eq_attr "cpu" "cypress")) 37 37)
193 (define_function_unit "fp_mds" 1 0
194   (and (eq_attr "type" "fpsqrt")        (eq_attr "cpu" "cypress")) 63 63)
195
196 ;; ----- The TMS390Z55 scheduling
197 ;; The Supersparc can issue 1 - 3 insns per cycle; here we assume
198 ;; three insns/cycle, and hence multiply all costs by three.
199 ;; Combinations up to two integer, one ld/st, one fp.
200 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
201 (define_function_unit "memory" 1 0
202   (and (eq_attr "type" "load")          (eq_attr "cpu" "supersparc")) 3 3)
203 (define_function_unit "memory" 1 0
204   (and (eq_attr "type" "fpload")        (eq_attr "cpu" "supersparc")) 1 3)
205 ;; at least one in three instructions can be a mem opt.
206 (define_function_unit "memory" 1 0
207   (and (eq_attr "type" "store,fpstore") (eq_attr "cpu" "supersparc")) 1 3)
208 ;; at least one in three instructions can be a shift op.
209 (define_function_unit "shift" 1 0
210   (and (eq_attr "type" "shift")         (eq_attr "cpu" "supersparc")) 1 3)
211
212 ;; There are only two write ports to the integer register file
213 ;; A store also uses a write port
214 (define_function_unit "iwport" 2 0
215   (and (eq_attr "type" "load,store,shift,ialu") (eq_attr "cpu" "supersparc")) 1 3)
216
217 ;; Timings; throughput/latency
218 ;; FADD     1/3    add/sub, format conv, compar, abs, neg
219 ;; FMUL     1/3
220 ;; FDIVs    4/6
221 ;; FDIVd    7/9
222 ;; FSQRTs   6/8
223 ;; FSQRTd  10/12
224 ;; IMUL     4/4
225
226 (define_function_unit "fp_alu" 1 0
227   (and (eq_attr "type" "fp,fpcmp") (eq_attr "cpu" "supersparc")) 9 3)
228 (define_function_unit "fp_mds" 1 0
229   (and (eq_attr "type" "fpmul")    (eq_attr "cpu" "supersparc")) 9 3)
230 (define_function_unit "fp_mds" 1 0
231   (and (eq_attr "type" "fpdivs")   (eq_attr "cpu" "supersparc")) 18 12)
232 (define_function_unit "fp_mds" 1 0
233   (and (eq_attr "type" "fpdivd")   (eq_attr "cpu" "supersparc")) 27 21)
234 (define_function_unit "fp_mds" 1 0
235   (and (eq_attr "type" "fpsqrt")   (eq_attr "cpu" "supersparc")) 36 30)
236 (define_function_unit "fp_mds" 1 0
237   (and (eq_attr "type" "imul")     (eq_attr "cpu" "supersparc")) 12 12)
238 \f
239 ;; Compare instructions.
240 ;; This controls RTL generation and register allocation.
241
242 ;; We generate RTL for comparisons and branches by having the cmpxx 
243 ;; patterns store away the operands.  Then, the scc and bcc patterns
244 ;; emit RTL for both the compare and the branch.
245 ;;
246 ;; We do this because we want to generate different code for an sne and
247 ;; seq insn.  In those cases, if the second operand of the compare is not
248 ;; const0_rtx, we want to compute the xor of the two operands and test
249 ;; it against zero.
250 ;;
251 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
252 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
253 ;; insns that actually require more than one machine instruction.
254
255 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
256
257 (define_expand "cmpsi"
258   [(set (reg:CC 0)
259         (compare:CC (match_operand:SI 0 "register_operand" "")
260                     (match_operand:SI 1 "arith_operand" "")))]
261   ""
262   "
263 {
264   sparc_compare_op0 = operands[0];
265   sparc_compare_op1 = operands[1];
266   DONE;
267 }")
268
269 (define_expand "cmpdi"
270   [(set (reg:CCX 0)
271         (compare:CCX (match_operand:DI 0 "register_operand" "")
272                      (match_operand:DI 1 "arith_double_operand" "")))]
273   "TARGET_V9"
274   "
275 {
276   sparc_compare_op0 = operands[0];
277   sparc_compare_op1 = operands[1];
278   DONE;
279 }")
280
281 (define_expand "cmpsf"
282   [(set (reg:CCFP 0)
283         (compare:CCFP (match_operand:SF 0 "register_operand" "")
284                       (match_operand:SF 1 "register_operand" "")))]
285   "TARGET_FPU"
286   "
287 {
288   sparc_compare_op0 = operands[0];
289   sparc_compare_op1 = operands[1];
290   DONE;
291 }")
292
293 (define_expand "cmpdf"
294   [(set (reg:CCFP 0)
295         (compare:CCFP (match_operand:DF 0 "register_operand" "")
296                       (match_operand:DF 1 "register_operand" "")))]
297   "TARGET_FPU"
298   "
299 {
300   sparc_compare_op0 = operands[0];
301   sparc_compare_op1 = operands[1];
302   DONE;
303 }")
304
305 (define_expand "cmptf"
306   [(set (reg:CCFP 0)
307         (compare:CCFP (match_operand:TF 0 "register_operand" "")
308                       (match_operand:TF 1 "register_operand" "")))]
309   "TARGET_FPU"
310   "
311 {
312   sparc_compare_op0 = operands[0];
313   sparc_compare_op1 = operands[1];
314   DONE;
315 }")
316
317 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
318 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
319 ;; the same code as v8 (the addx/subx method has more applications).  The
320 ;; exception to this is "reg != 0" which can be done in one instruction on v9
321 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
322 ;; branches.
323
324 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
325 ;; generate addcc/subcc instructions.
326
327 (define_expand "seqsi_special"
328   [(set (match_dup 3)
329         (xor:SI (match_operand:SI 1 "register_operand" "")
330                 (match_operand:SI 2 "register_operand" "")))
331    (parallel [(set (match_operand:SI 0 "register_operand" "")
332                    (eq:SI (match_dup 3) (const_int 0)))
333               (clobber (reg:CC 0))])]
334   ""
335   "{ operands[3] = gen_reg_rtx (SImode); }")
336
337 (define_expand "seqdi_special"
338   [(set (match_dup 3)
339         (xor:DI (match_operand:DI 1 "register_operand" "")
340                 (match_operand:DI 2 "register_operand" "")))
341    (parallel [(set (match_operand:DI 0 "register_operand" "")
342                    (eq:DI (match_dup 3) (const_int 0)))
343               (clobber (reg:CCX 0))])]
344   ""
345   "{ operands[3] = gen_reg_rtx (DImode); }")
346
347 (define_expand "snesi_special"
348   [(set (match_dup 3)
349         (xor:SI (match_operand:SI 1 "register_operand" "")
350                 (match_operand:SI 2 "register_operand" "")))
351    (parallel [(set (match_operand:SI 0 "register_operand" "")
352                    (ne:SI (match_dup 3) (const_int 0)))
353               (clobber (reg:CC 0))])]
354   ""
355   "{ operands[3] = gen_reg_rtx (SImode); }")
356
357 (define_expand "snedi_special"
358   [(set (match_dup 3)
359         (xor:DI (match_operand:DI 1 "register_operand" "")
360                 (match_operand:DI 2 "register_operand" "")))
361    (parallel [(set (match_operand:DI 0 "register_operand" "")
362                    (ne:DI (match_dup 3) (const_int 0)))
363               (clobber (reg:CCX 0))])]
364   ""
365   "{ operands[3] = gen_reg_rtx (DImode); }")
366
367 (define_expand "seqdi_special_trunc"
368   [(set (match_dup 3)
369         (xor:DI (match_operand:DI 1 "register_operand" "")
370                 (match_operand:DI 2 "register_operand" "")))
371    (parallel [(set (match_operand:SI 0 "register_operand" "")
372                    (eq:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
373               (clobber (reg:CC 0))])]
374   ""
375   "{ operands[3] = gen_reg_rtx (DImode); }")
376
377 (define_expand "snedi_special_trunc"
378   [(set (match_dup 3)
379         (xor:DI (match_operand:DI 1 "register_operand" "")
380                 (match_operand:DI 2 "register_operand" "")))
381    (parallel [(set (match_operand:SI 0 "register_operand" "")
382                    (ne:SI (subreg:SI (match_dup 3) 0) (const_int 0)))
383               (clobber (reg:CC 0))])]
384   ""
385   "{ operands[3] = gen_reg_rtx (DImode); }")
386
387 (define_expand "seqsi_special_extend"
388   [(set (subreg:SI (match_dup 3) 0)
389         (xor:SI (match_operand:SI 1 "register_operand" "")
390                 (match_operand:SI 2 "register_operand" "")))
391    (parallel [(set (match_operand:DI 0 "register_operand" "")
392                    (eq:DI (match_dup 3) (const_int 0)))
393               (clobber (reg:CCX 0))])]
394   ""
395   "{ operands[3] = gen_reg_rtx (DImode); }")
396
397 (define_expand "snesi_special_extend"
398   [(set (subreg:SI (match_dup 3) 0)
399         (xor:SI (match_operand:SI 1 "register_operand" "")
400                 (match_operand:SI 2 "register_operand" "")))
401    (parallel [(set (match_operand:DI 0 "register_operand" "")
402                    (ne:DI (match_dup 3) (const_int 0)))
403               (clobber (reg:CCX 0))])]
404   ""
405   "{ operands[3] = gen_reg_rtx (DImode); }")
406
407 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
408 ;; However, the code handles both SImode and DImode.
409 (define_expand "seq"
410   [(set (match_operand:SI 0 "intreg_operand" "")
411         (eq:SI (match_dup 1) (const_int 0)))]
412   ""
413   "
414 {
415   if (GET_MODE (sparc_compare_op0) == SImode)
416     {
417       rtx pat;
418
419       if (GET_MODE (operands[0]) == SImode)
420         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
421                                  sparc_compare_op1);
422       else if (! TARGET_V9)
423         FAIL;
424       else
425         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
426                                         sparc_compare_op1);
427       emit_insn (pat);
428       DONE;
429     }
430   else if (GET_MODE (sparc_compare_op0) == DImode)
431     {
432       rtx pat;
433
434       if (GET_MODE (operands[0]) == SImode)
435         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
436                                        sparc_compare_op1);
437       else if (! TARGET_V9)
438         FAIL;
439       else
440         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
441                                  sparc_compare_op1);
442       emit_insn (pat);
443       DONE;
444     }
445   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
446     {
447       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
448       emit_insn (gen_sne (operands[0]));
449       DONE;
450     }      
451   else if (TARGET_V9)
452     {
453       if (gen_v9_scc (EQ, operands))
454         DONE;
455       /* fall through */
456     }
457   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
458 }")
459
460 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
461 ;; However, the code handles both SImode and DImode.
462 (define_expand "sne"
463   [(set (match_operand:SI 0 "intreg_operand" "")
464         (ne:SI (match_dup 1) (const_int 0)))]
465   ""
466   "
467 {
468   if (GET_MODE (sparc_compare_op0) == SImode)
469     {
470       rtx pat;
471
472       if (GET_MODE (operands[0]) == SImode)
473         pat = gen_snesi_special (operands[0], sparc_compare_op0,
474                                  sparc_compare_op1);
475       else if (! TARGET_V9)
476         FAIL;
477       else
478         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
479                                         sparc_compare_op1);
480       emit_insn (pat);
481       DONE;
482     }
483   else if (GET_MODE (sparc_compare_op0) == DImode)
484     {
485       rtx pat;
486
487       if (GET_MODE (operands[0]) == SImode)
488         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
489                                        sparc_compare_op1);
490       else if (! TARGET_V9)
491         FAIL;
492       else
493         pat = gen_snedi_special (operands[0], sparc_compare_op0,
494                                  sparc_compare_op1);
495       emit_insn (pat);
496       DONE;
497     }
498   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
499     {
500       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
501       emit_insn (gen_sne (operands[0]));
502       DONE;
503     }      
504   else if (TARGET_V9)
505     {
506       if (gen_v9_scc (NE, operands))
507         DONE;
508       /* fall through */
509     }
510   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
511 }")
512
513 (define_expand "sgt"
514   [(set (match_operand:SI 0 "intreg_operand" "")
515         (gt:SI (match_dup 1) (const_int 0)))]
516   ""
517   "
518 {
519   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
520     {
521       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
522       emit_insn (gen_sne (operands[0]));
523       DONE;
524     }
525   else if (TARGET_V9)
526     {
527       if (gen_v9_scc (GT, operands))
528         DONE;
529       /* fall through */
530     }
531   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
532 }")
533
534 (define_expand "slt"
535   [(set (match_operand:SI 0 "intreg_operand" "")
536         (lt:SI (match_dup 1) (const_int 0)))]
537   ""
538   "
539 {
540   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
541     {
542       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
543       emit_insn (gen_sne (operands[0]));
544       DONE;
545     }
546   else if (TARGET_V9)
547     {
548       if (gen_v9_scc (LT, operands))
549         DONE;
550       /* fall through */
551     }
552   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
553 }")
554
555 (define_expand "sge"
556   [(set (match_operand:SI 0 "intreg_operand" "")
557         (ge:SI (match_dup 1) (const_int 0)))]
558   ""
559   "
560 {
561   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
562     {
563       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
564       emit_insn (gen_sne (operands[0]));
565       DONE;
566     }
567   else if (TARGET_V9)
568     {
569       if (gen_v9_scc (GE, operands))
570         DONE;
571       /* fall through */
572     }
573   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
574 }")
575
576 (define_expand "sle"
577   [(set (match_operand:SI 0 "intreg_operand" "")
578         (le:SI (match_dup 1) (const_int 0)))]
579   ""
580   "
581 {
582   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
583     {
584       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
585       emit_insn (gen_sne (operands[0]));
586       DONE;
587     }
588   else if (TARGET_V9)
589     {
590       if (gen_v9_scc (LE, operands))
591         DONE;
592       /* fall through */
593     }
594   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
595 }")
596
597 (define_expand "sgtu"
598   [(set (match_operand:SI 0 "intreg_operand" "")
599         (gtu:SI (match_dup 1) (const_int 0)))]
600   ""
601   "
602 {
603   if (! TARGET_V9)
604     {
605       rtx tem;
606
607       /* We can do ltu easily, so if both operands are registers, swap them and
608          do a LTU.  */
609       if ((GET_CODE (sparc_compare_op0) == REG
610            || GET_CODE (sparc_compare_op0) == SUBREG)
611           && (GET_CODE (sparc_compare_op1) == REG
612               || GET_CODE (sparc_compare_op1) == SUBREG))
613         {
614           tem = sparc_compare_op0;
615           sparc_compare_op0 = sparc_compare_op1;
616           sparc_compare_op1 = tem;
617           emit_insn (gen_sltu (operands[0]));
618           DONE;
619         }
620     }
621   else
622     {
623       if (gen_v9_scc (GTU, operands))
624         DONE;
625     }
626   operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
627 }")
628
629 (define_expand "sltu"
630   [(set (match_operand:SI 0 "intreg_operand" "")
631         (ltu:SI (match_dup 1) (const_int 0)))]
632   ""
633   "
634 {
635   if (TARGET_V9)
636     {
637       if (gen_v9_scc (LTU, operands))
638         DONE;
639     }
640   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
641 }")
642
643 (define_expand "sgeu"
644   [(set (match_operand:SI 0 "intreg_operand" "")
645         (geu:SI (match_dup 1) (const_int 0)))]
646   ""
647   "
648 {
649   if (TARGET_V9)
650     {
651       if (gen_v9_scc (GEU, operands))
652         DONE;
653     }
654   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
655 }")
656
657 (define_expand "sleu"
658   [(set (match_operand:SI 0 "intreg_operand" "")
659         (leu:SI (match_dup 1) (const_int 0)))]
660   ""
661   "
662 {
663   if (! TARGET_V9)
664     {
665       rtx tem;
666
667       /* We can do geu easily, so if both operands are registers, swap them and
668          do a GEU.  */
669       if ((GET_CODE (sparc_compare_op0) == REG
670            || GET_CODE (sparc_compare_op0) == SUBREG)
671           && (GET_CODE (sparc_compare_op1) == REG
672               || GET_CODE (sparc_compare_op1) == SUBREG))
673         {
674           tem = sparc_compare_op0;
675           sparc_compare_op0 = sparc_compare_op1;
676           sparc_compare_op1 = tem;
677           emit_insn (gen_sgeu (operands[0]));
678           DONE;
679         }
680     }
681   else
682     {
683       if (gen_v9_scc (LEU, operands))
684         DONE;
685     }
686   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
687 }")
688
689 ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
690
691 (define_insn ""
692   [(set (reg:CC 0)
693         (compare:CC (match_operand:SI 0 "register_operand" "r")
694                     (match_operand:SI 1 "arith_operand" "rI")))]
695   ""
696   "cmp %r0,%1"
697   [(set_attr "type" "compare")])
698
699 (define_insn ""
700   [(set (reg:CCFPE 0)
701         (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
702                        (match_operand:SF 1 "register_operand" "f")))]
703   "! TARGET_V9 && TARGET_FPU"
704   "fcmpes %0,%1"
705   [(set_attr "type" "fpcmp")])
706
707 (define_insn ""
708   [(set (reg:CCFPE 0)
709         (compare:CCFPE (match_operand:DF 0 "register_operand" "e")
710                        (match_operand:DF 1 "register_operand" "e")))]
711   "! TARGET_V9 && TARGET_FPU"
712   "fcmped %0,%1"
713   [(set_attr "type" "fpcmp")])
714
715 (define_insn ""
716   [(set (reg:CCFPE 0)
717         (compare:CCFPE (match_operand:TF 0 "register_operand" "e")
718                        (match_operand:TF 1 "register_operand" "e")))]
719   "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
720   "fcmpeq %0,%1"
721   [(set_attr "type" "fpcmp")])
722
723 (define_insn ""
724   [(set (reg:CCFP 0)
725         (compare:CCFP (match_operand:SF 0 "register_operand" "f")
726                       (match_operand:SF 1 "register_operand" "f")))]
727   "! TARGET_V9 && TARGET_FPU"
728   "fcmps %0,%1"
729   [(set_attr "type" "fpcmp")])
730
731 (define_insn ""
732   [(set (reg:CCFP 0)
733         (compare:CCFP (match_operand:DF 0 "register_operand" "e")
734                       (match_operand:DF 1 "register_operand" "e")))]
735   "! TARGET_V9 && TARGET_FPU"
736   "fcmpd %0,%1"
737   [(set_attr "type" "fpcmp")])
738
739 (define_insn ""
740   [(set (reg:CCFP 0)
741         (compare:CCFP (match_operand:TF 0 "register_operand" "e")
742                       (match_operand:TF 1 "register_operand" "e")))]
743   "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
744   "fcmpq %0,%1"
745   [(set_attr "type" "fpcmp")])
746
747 (define_insn ""
748   [(set (reg:CCX 0)
749         (compare:CCX (match_operand:DI 0 "register_operand" "r")
750                      (match_operand:DI 1 "arith_double_operand" "rHI")))]
751   "TARGET_V9"
752   "cmp %r0,%1"
753   [(set_attr "type" "compare")])
754
755 (define_insn ""
756   [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
757         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
758                        (match_operand:SF 2 "register_operand" "f")))]
759   "TARGET_V9 && TARGET_FPU"
760   "fcmpes %0,%1,%2"
761   [(set_attr "type" "fpcmp")])
762
763 (define_insn ""
764   [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
765         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
766                        (match_operand:DF 2 "register_operand" "e")))]
767   "TARGET_V9 && TARGET_FPU"
768   "fcmped %0,%1,%2"
769   [(set_attr "type" "fpcmp")])
770
771 (define_insn ""
772   [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c")
773         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
774                        (match_operand:TF 2 "register_operand" "e")))]
775   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
776   "fcmpeq %0,%1,%2"
777   [(set_attr "type" "fpcmp")])
778
779 (define_insn ""
780   [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
781         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
782                       (match_operand:SF 2 "register_operand" "f")))]
783   "TARGET_V9 && TARGET_FPU"
784   "fcmps %0,%1,%2"
785   [(set_attr "type" "fpcmp")])
786
787 (define_insn ""
788   [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
789         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
790                       (match_operand:DF 2 "register_operand" "e")))]
791   "TARGET_V9 && TARGET_FPU"
792   "fcmpd %0,%1,%2"
793   [(set_attr "type" "fpcmp")])
794
795 (define_insn ""
796   [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c")
797         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
798                       (match_operand:TF 2 "register_operand" "e")))]
799   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
800   "fcmpq %0,%1,%2"
801   [(set_attr "type" "fpcmp")])
802
803 ;; The SEQ and SNE patterns are special because they can be done
804 ;; without any branching and do not involve a COMPARE.
805
806 (define_insn ""
807   [(set (match_operand:SI 0 "register_operand" "=r")
808         (ne:SI (match_operand:SI 1 "register_operand" "r")
809                (const_int 0)))
810    (clobber (reg:CC 0))]
811   ""
812   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
813   [(set_attr "type" "unary")
814    (set_attr "length" "2")])
815
816 (define_insn ""
817   [(set (match_operand:SI 0 "register_operand" "=r")
818         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
819                        (const_int 0))))
820    (clobber (reg:CC 0))]
821   ""
822   "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
823   [(set_attr "type" "unary")
824    (set_attr "length" "2")])
825
826 (define_insn ""
827   [(set (match_operand:DI 0 "register_operand" "=r")
828         (ne:DI (match_operand:DI 1 "register_operand" "r")
829                (const_int 0)))
830    (clobber (reg:CCX 0))]
831   "TARGET_V9"
832   "mov 0,%0\;movrnz %1,1,%0"
833   [(set_attr "type" "unary")
834    (set_attr "length" "2")])
835
836 (define_insn ""
837   [(set (match_operand:DI 0 "register_operand" "=r")
838         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
839                        (const_int 0))))
840    (clobber (reg:CCX 0))]
841   "TARGET_V9"
842   "mov 0,%0\;movrnz %1,-1,%0"
843   [(set_attr "type" "unary")
844    (set_attr "length" "2")])
845
846 (define_insn ""
847   [(set (match_operand:SI 0 "register_operand" "=r")
848         (eq:SI (match_operand:SI 1 "register_operand" "r")
849                (const_int 0)))
850    (clobber (reg:CC 0))]
851   ""
852   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
853   [(set_attr "type" "unary")
854    (set_attr "length" "2")])
855
856 (define_insn ""
857   [(set (match_operand:SI 0 "register_operand" "=r")
858         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
859                        (const_int 0))))
860    (clobber (reg:CC 0))]
861   ""
862   "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
863   [(set_attr "type" "unary")
864    (set_attr "length" "2")])
865
866 (define_insn ""
867   [(set (match_operand:DI 0 "register_operand" "=r")
868         (eq:DI (match_operand:DI 1 "register_operand" "r")
869                (const_int 0)))
870    (clobber (reg:CCX 0))]
871   "TARGET_V9"
872   "mov 0,%0\;movrz %1,1,%0"
873   [(set_attr "type" "unary")
874    (set_attr "length" "2")])
875
876 (define_insn ""
877   [(set (match_operand:DI 0 "register_operand" "=r")
878         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
879                        (const_int 0))))
880    (clobber (reg:CCX 0))]
881   "TARGET_V9"
882   "mov 0,%0\;movrz %1,-1,%0"
883   [(set_attr "type" "unary")
884    (set_attr "length" "2")]) 
885
886 ;; We can also do (x + (i == 0)) and related, so put them in.
887 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
888 ;; versions for v9.
889
890 (define_insn ""
891   [(set (match_operand:SI 0 "register_operand" "=r")
892         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
893                         (const_int 0))
894                  (match_operand:SI 2 "register_operand" "r")))
895    (clobber (reg:CC 0))]
896   ""
897   "subcc %%g0,%1,%%g0\;addx %2,0,%0"
898   [(set_attr "length" "2")])
899
900 (define_insn ""
901   [(set (match_operand:SI 0 "register_operand" "=r")
902         (minus:SI (match_operand:SI 2 "register_operand" "r")
903                   (ne:SI (match_operand:SI 1 "register_operand" "r")
904                          (const_int 0))))
905    (clobber (reg:CC 0))]
906   ""
907   "subcc %%g0,%1,%%g0\;subx %2,0,%0"
908   [(set_attr "length" "2")])
909
910 (define_insn ""
911   [(set (match_operand:SI 0 "register_operand" "=r")
912         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
913                         (const_int 0))
914                  (match_operand:SI 2 "register_operand" "r")))
915    (clobber (reg:CC 0))]
916   ""
917   "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
918   [(set_attr "length" "2")])
919
920 (define_insn ""
921   [(set (match_operand:SI 0 "register_operand" "=r")
922         (minus:SI (match_operand:SI 2 "register_operand" "r")
923                   (eq:SI (match_operand:SI 1 "register_operand" "r")
924                          (const_int 0))))
925    (clobber (reg:CC 0))]
926   ""
927   "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
928   [(set_attr "length" "2")])
929
930 ;; We can also do GEU and LTU directly, but these operate after a compare.
931 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
932 ;; versions for v9.
933
934 (define_insn ""
935   [(set (match_operand:SI 0 "register_operand" "=r")
936         (ltu:SI (reg:CC 0) (const_int 0)))]
937   ""
938   "addx %%g0,0,%0"
939   [(set_attr "type" "misc")])
940
941 (define_insn ""
942   [(set (match_operand:SI 0 "register_operand" "=r")
943         (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
944   ""
945   "subx %%g0,0,%0"
946   [(set_attr "type" "misc")])
947
948 ;; ??? Combine should canonicalize these next two to the same pattern.
949 (define_insn ""
950   [(set (match_operand:SI 0 "register_operand" "=r")
951         (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
952                   (match_operand:SI 1 "arith_operand" "rI")))]
953   ""
954   "subx %%g0,%1,%0"
955   [(set_attr "type" "unary")])
956
957 (define_insn ""
958   [(set (match_operand:SI 0 "register_operand" "=r")
959         (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
960                          (match_operand:SI 1 "arith_operand" "rI"))))]
961   ""
962   "subx %%g0,%1,%0"
963   [(set_attr "type" "unary")])
964
965 (define_insn ""
966   [(set (match_operand:SI 0 "register_operand" "=r")
967         (geu:SI (reg:CC 0) (const_int 0)))]
968   ""
969   "subx %%g0,-1,%0"
970   [(set_attr "type" "misc")])
971
972 (define_insn ""
973   [(set (match_operand:SI 0 "register_operand" "=r")
974         (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
975   ""
976   "addx %%g0,-1,%0"
977   [(set_attr "type" "misc")])
978
979 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
980 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
981 ;; versions for v9.
982
983 (define_insn ""
984   [(set (match_operand:SI 0 "register_operand" "=r")
985         (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
986                  (match_operand:SI 1 "arith_operand" "rI")))]
987   ""
988   "addx %%g0,%1,%0"
989   [(set_attr "type" "unary")])
990
991 (define_insn ""
992   [(set (match_operand:SI 0 "register_operand" "=r")
993         (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
994                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
995                           (match_operand:SI 2 "arith_operand" "rI"))))]
996   ""
997   "addx %1,%2,%0")
998
999 (define_insn ""
1000   [(set (match_operand:SI 0 "register_operand" "=r")
1001         (minus:SI (match_operand:SI 1 "register_operand" "r")
1002                   (ltu:SI (reg:CC 0) (const_int 0))))]
1003   ""
1004   "subx %1,0,%0"
1005   [(set_attr "type" "unary")])
1006
1007 ;; ??? Combine should canonicalize these next two to the same pattern.
1008 (define_insn ""
1009   [(set (match_operand:SI 0 "register_operand" "=r")
1010         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1011                             (match_operand:SI 2 "arith_operand" "rI"))
1012                   (ltu:SI (reg:CC 0) (const_int 0))))]
1013   ""
1014   "subx %1,%2,%0")
1015
1016 (define_insn ""
1017   [(set (match_operand:SI 0 "register_operand" "=r")
1018         (minus:SI (match_operand:SI 1 "register_operand" "r")
1019                   (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
1020                            (match_operand:SI 2 "arith_operand" "rI"))))]
1021   ""
1022   "subx %1,%2,%0")
1023
1024 (define_insn ""
1025   [(set (match_operand:SI 0 "register_operand" "=r")
1026         (plus:SI (geu:SI (reg:CC 0) (const_int 0))
1027                  (match_operand:SI 1 "register_operand" "r")))]
1028   ""
1029   "subx %1,-1,%0"
1030   [(set_attr "type" "unary")])
1031
1032 (define_insn ""
1033   [(set (match_operand:SI 0 "register_operand" "=r")
1034         (minus:SI (match_operand:SI 1 "register_operand" "r")
1035                   (geu:SI (reg:CC 0) (const_int 0))))]
1036   ""
1037   "addx %1,-1,%0"
1038   [(set_attr "type" "unary")])
1039
1040 ;; Now we have the generic scc insns.
1041 ;; !v9: These will be done using a jump.
1042 ;; v9: Use conditional moves which are defined elsewhere.
1043 ;; We have to exclude the cases above, since we will not want combine to
1044 ;; turn something that does not require a jump into something that does.
1045
1046 (define_insn ""
1047   [(set (match_operand:SI 0 "register_operand" "=r")
1048         (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1049   ""
1050   "* return output_scc_insn (operands, insn); "
1051   [(set_attr "type" "multi")
1052    (set_attr "length" "3")])
1053
1054 (define_insn ""
1055   [(set (match_operand:DI 0 "register_operand" "=r")
1056         (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
1057   "TARGET_V9"
1058   "* return output_scc_insn (operands, insn); "
1059   [(set_attr "type" "multi")
1060    (set_attr "length" "3")])
1061 \f
1062 ;; These control RTL generation for conditional jump insns
1063
1064 ;; The quad-word fp compare library routines all return nonzero to indicate
1065 ;; true, which is different from the equivalent libgcc routines, so we must
1066 ;; handle them specially here.
1067
1068 (define_expand "beq"
1069   [(set (pc)
1070         (if_then_else (eq (match_dup 1) (const_int 0))
1071                       (label_ref (match_operand 0 "" ""))
1072                       (pc)))]
1073   ""
1074   "
1075 {
1076   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1077       && GET_CODE (sparc_compare_op0) == REG
1078       && GET_MODE (sparc_compare_op0) == DImode)
1079     {
1080       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1081       DONE;
1082     }
1083   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1084     {
1085       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1086       emit_jump_insn (gen_bne (operands[0]));
1087       DONE;
1088     }      
1089   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1090 }")
1091
1092 (define_expand "bne"
1093   [(set (pc)
1094         (if_then_else (ne (match_dup 1) (const_int 0))
1095                       (label_ref (match_operand 0 "" ""))
1096                       (pc)))]
1097   ""
1098   "
1099 {
1100   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1101       && GET_CODE (sparc_compare_op0) == REG
1102       && GET_MODE (sparc_compare_op0) == DImode)
1103     {
1104       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1105       DONE;
1106     }
1107   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1108     {
1109       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1110       emit_jump_insn (gen_bne (operands[0]));
1111       DONE;
1112     }      
1113   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1114 }")
1115
1116 (define_expand "bgt"
1117   [(set (pc)
1118         (if_then_else (gt (match_dup 1) (const_int 0))
1119                       (label_ref (match_operand 0 "" ""))
1120                       (pc)))]
1121   ""
1122   "
1123 {
1124   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1125       && GET_CODE (sparc_compare_op0) == REG
1126       && GET_MODE (sparc_compare_op0) == DImode)
1127     {
1128       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1129       DONE;
1130     }
1131   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1132     {
1133       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1134       emit_jump_insn (gen_bne (operands[0]));
1135       DONE;
1136     }      
1137   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1138 }")
1139
1140 (define_expand "bgtu"
1141   [(set (pc)
1142         (if_then_else (gtu (match_dup 1) (const_int 0))
1143                       (label_ref (match_operand 0 "" ""))
1144                       (pc)))]
1145   ""
1146   "
1147 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1148 }")
1149
1150 (define_expand "blt"
1151   [(set (pc)
1152         (if_then_else (lt (match_dup 1) (const_int 0))
1153                       (label_ref (match_operand 0 "" ""))
1154                       (pc)))]
1155   ""
1156   "
1157 {
1158   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1159       && GET_CODE (sparc_compare_op0) == REG
1160       && GET_MODE (sparc_compare_op0) == DImode)
1161     {
1162       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1163       DONE;
1164     }
1165   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1166     {
1167       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1168       emit_jump_insn (gen_bne (operands[0]));
1169       DONE;
1170     }      
1171   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1172 }")
1173
1174 (define_expand "bltu"
1175   [(set (pc)
1176         (if_then_else (ltu (match_dup 1) (const_int 0))
1177                       (label_ref (match_operand 0 "" ""))
1178                       (pc)))]
1179   ""
1180   "
1181 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1182 }")
1183
1184 (define_expand "bge"
1185   [(set (pc)
1186         (if_then_else (ge (match_dup 1) (const_int 0))
1187                       (label_ref (match_operand 0 "" ""))
1188                       (pc)))]
1189   ""
1190   "
1191 {
1192   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1193       && GET_CODE (sparc_compare_op0) == REG
1194       && GET_MODE (sparc_compare_op0) == DImode)
1195     {
1196       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1197       DONE;
1198     }
1199   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1200     {
1201       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1202       emit_jump_insn (gen_bne (operands[0]));
1203       DONE;
1204     }      
1205   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1206 }")
1207
1208 (define_expand "bgeu"
1209   [(set (pc)
1210         (if_then_else (geu (match_dup 1) (const_int 0))
1211                       (label_ref (match_operand 0 "" ""))
1212                       (pc)))]
1213   ""
1214   "
1215 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1216 }")
1217
1218 (define_expand "ble"
1219   [(set (pc)
1220         (if_then_else (le (match_dup 1) (const_int 0))
1221                       (label_ref (match_operand 0 "" ""))
1222                       (pc)))]
1223   ""
1224   "
1225 {
1226   if (TARGET_V9 && sparc_compare_op1 == const0_rtx
1227       && GET_CODE (sparc_compare_op0) == REG
1228       && GET_MODE (sparc_compare_op0) == DImode)
1229     {
1230       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1231       DONE;
1232     }
1233   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1234     {
1235       emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1236       emit_jump_insn (gen_bne (operands[0]));
1237       DONE;
1238     }      
1239   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1240 }")
1241
1242 (define_expand "bleu"
1243   [(set (pc)
1244         (if_then_else (leu (match_dup 1) (const_int 0))
1245                       (label_ref (match_operand 0 "" ""))
1246                       (pc)))]
1247   ""
1248   "
1249 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1250 }")
1251 \f
1252 ;; Now match both normal and inverted jump.
1253
1254 (define_insn ""
1255   [(set (pc)
1256         (if_then_else (match_operator 0 "noov_compare_op"
1257                                       [(reg 0) (const_int 0)])
1258                       (label_ref (match_operand 1 "" ""))
1259                       (pc)))]
1260   ""
1261   "*
1262 {
1263   return output_cbranch (operands[0], 0, 1, 0,
1264                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1265                          ! final_sequence);
1266 }"
1267   [(set_attr "type" "branch")])
1268
1269 (define_insn ""
1270   [(set (pc)
1271         (if_then_else (match_operator 0 "noov_compare_op"
1272                                       [(reg 0) (const_int 0)])
1273                       (pc)
1274                       (label_ref (match_operand 1 "" ""))))]
1275   ""
1276   "*
1277 {
1278   return output_cbranch (operands[0], 0, 1, 1,
1279                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1280                          ! final_sequence);
1281 }"
1282   [(set_attr "type" "branch")])
1283
1284 (define_insn ""
1285   [(set (pc)
1286         (if_then_else (match_operator 0 "comparison_operator"
1287                                       [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1288                                        (const_int 0)])
1289                       (label_ref (match_operand 2 "" ""))
1290                       (pc)))]
1291   "TARGET_V9"
1292   "*
1293 {
1294   return output_cbranch (operands[0], operands[1], 2, 0,
1295                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1296                          ! final_sequence);
1297 }"
1298   [(set_attr "type" "branch")])
1299
1300 (define_insn ""
1301   [(set (pc)
1302         (if_then_else (match_operator 0 "comparison_operator"
1303                                       [(match_operand:CCFP 1 "ccfp_reg_operand" "c")
1304                                        (const_int 0)])
1305                       (pc)
1306                       (label_ref (match_operand 2 "" ""))))]
1307   "TARGET_V9"
1308   "*
1309 {
1310   return output_cbranch (operands[0], operands[1], 2, 1,
1311                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1312                          ! final_sequence);
1313 }"
1314   [(set_attr "type" "branch")])
1315
1316 (define_insn ""
1317   [(set (pc)
1318         (if_then_else (match_operator 0 "comparison_operator"
1319                                       [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1320                                        (const_int 0)])
1321                       (label_ref (match_operand 2 "" ""))
1322                       (pc)))]
1323   "TARGET_V9"
1324   "*
1325 {
1326   return output_cbranch (operands[0], operands[1], 2, 0,
1327                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1328                          ! final_sequence);
1329 }"
1330   [(set_attr "type" "branch")])
1331
1332 (define_insn ""
1333   [(set (pc)
1334         (if_then_else (match_operator 0 "comparison_operator"
1335                                       [(match_operand:CCFPE 1 "ccfp_reg_operand" "c")
1336                                        (const_int 0)])
1337                       (pc)
1338                       (label_ref (match_operand 2 "" ""))))]
1339   "TARGET_V9"
1340   "*
1341 {
1342   return output_cbranch (operands[0], operands[1], 2, 1,
1343                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1344                          ! final_sequence);
1345 }"
1346   [(set_attr "type" "branch")])
1347
1348 ;; Sparc V9-specific jump insns.  None of these are guaranteed to be
1349 ;; in the architecture.
1350
1351 ;; There are no 32 bit brreg insns.
1352
1353 (define_insn ""
1354   [(set (pc)
1355         (if_then_else (match_operator 0 "v9_regcmp_op"
1356                                       [(match_operand:DI 1 "register_operand" "r")
1357                                        (const_int 0)])
1358                       (label_ref (match_operand 2 "" ""))
1359                       (pc)))]
1360   "TARGET_V9"
1361   "*
1362 {
1363   return output_v9branch (operands[0], 1, 2, 0,
1364                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1365                           ! final_sequence);
1366 }"
1367   [(set_attr "type" "branch")])
1368
1369 (define_insn ""
1370   [(set (pc)
1371         (if_then_else (match_operator 0 "v9_regcmp_op"
1372                                       [(match_operand:DI 1 "register_operand" "r")
1373                                        (const_int 0)])
1374                       (pc)
1375                       (label_ref (match_operand 2 "" ""))))]
1376   "TARGET_V9"
1377   "*
1378 {
1379   return output_v9branch (operands[0], 1, 2, 1,
1380                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1381                           ! final_sequence);
1382 }"
1383   [(set_attr "type" "branch")])
1384 \f
1385 ;; Esoteric move insns (lo_sum, high, pic).
1386
1387 (define_insn ""
1388   [(set (match_operand:SI 0 "register_operand" "=r")
1389         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1390                    (match_operand:SI 2 "immediate_operand" "in")))]
1391   ""
1392   ;; V9 needs "add" because of the code models.  We still use "or" for v8
1393   ;; so we can compare the old compiler with the new.
1394   "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1395   ;; Need to set length for this arith insn because operand2
1396   ;; is not an "arith_operand".
1397   [(set_attr "length" "1")])
1398
1399 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1400 ;; confuse them with real addresses.
1401 (define_insn ""
1402   [(set (match_operand:SI 0 "register_operand" "=r")
1403         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1404                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1405   ""
1406   ;; V9 needs "add" because of the code models.  We still use "or" for v8
1407   ;; so we can compare the old compiler with the new.
1408   "* return TARGET_V9 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1409   ;; Need to set length for this arith insn because operand2
1410   ;; is not an "arith_operand".
1411   [(set_attr "length" "1")])
1412
1413 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1414 ;; confuse them with real addresses.
1415 (define_insn ""
1416   [(set (match_operand:SI 0 "register_operand" "=r")
1417         (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1418   "check_pic (1)"
1419   "sethi %%hi(%a1),%0"
1420   [(set_attr "type" "move")
1421    (set_attr "length" "1")])
1422
1423 (define_insn ""
1424   [(set (match_operand:SI 0 "register_operand" "=r")
1425         (high:SI (match_operand 1 "" "")))]
1426   "check_pic (1)"
1427   "sethi %%hi(%a1),%0"
1428   [(set_attr "type" "move")
1429    (set_attr "length" "1")])
1430
1431 (define_insn ""
1432   [(set (match_operand:HI 0 "register_operand" "=r")
1433         (high:HI (match_operand 1 "" "")))]
1434   "check_pic (1)"
1435   "sethi %%hi(%a1),%0"
1436   [(set_attr "type" "move")
1437    (set_attr "length" "1")])
1438
1439 ;; Special pic pattern, for loading the address of a label into a register.
1440 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
1441 ;; there.
1442
1443 (define_insn ""
1444   [(set (match_operand:SI 0 "register_operand" "=r")
1445         (match_operand:SI 1 "move_pic_label" "i"))
1446    (set (reg:SI 15) (pc))]
1447   ""
1448   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
1449   [(set_attr "type" "multi")
1450    (set_attr "length" "4")])
1451
1452 ;; v9 special pic pattern, for loading the address of a label into a register.
1453
1454 (define_insn ""
1455   [(set (match_operand:DI 0 "register_operand" "=r")
1456         (match_operand:DI 1 "move_pic_label" "i"))
1457    (set (reg:DI 15) (pc))]
1458   "TARGET_V9"
1459   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
1460   [(set_attr "type" "multi")
1461    (set_attr "length" "4")])
1462
1463 (define_insn ""
1464   [(set (match_operand:DI 0 "register_operand" "=r")
1465         (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1466                    (match_operand:DI 2 "immediate_operand" "in")))]
1467   "! TARGET_V9"
1468   "*
1469 {
1470   /* Don't output a 64 bit constant, since we can't trust the assembler to
1471      handle it correctly.  */
1472   if (GET_CODE (operands[2]) == CONST_DOUBLE)
1473     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1474   return \"or %R1,%%lo(%a2),%R0\";
1475 }"
1476   ;; Need to set length for this arith insn because operand2
1477   ;; is not an "arith_operand".
1478   [(set_attr "length" "1")])
1479
1480 ;; ??? Gas does not handle %lo(DI), so we use the same code for ! TARGET_V9.
1481 ;; ??? The previous comment is obsolete.
1482 ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?
1483
1484 (define_insn ""
1485   [(set (match_operand:DI 0 "register_operand" "=r")
1486         (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1487                    (match_operand:DI 2 "immediate_operand" "in")))]
1488   "TARGET_V9"
1489   "*
1490 {
1491   /* Don't output a 64 bit constant, since we can't trust the assembler to
1492      handle it correctly.  */
1493   if (GET_CODE (operands[2]) == CONST_DOUBLE)
1494     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1495   /* Note that we use add here.  This is important because Medium/Anywhere
1496      code model support depends on it.  */
1497   return \"add %1,%%lo(%a2),%0\";
1498 }"
1499   ;; Need to set length for this arith insn because operand2
1500   ;; is not an "arith_operand".
1501   [(set_attr "length" "1")])
1502
1503 (define_insn ""
1504   [(set (match_operand:DI 0 "register_operand" "=r")
1505         (high:DI (match_operand 1 "" "")))]
1506   "! TARGET_V9 && check_pic (1)"
1507   "*
1508 {
1509   rtx op0 = operands[0];
1510   rtx op1 = operands[1];
1511
1512   if (GET_CODE (op1) == CONST_INT)
1513     {
1514       operands[0] = operand_subword (op0, 1, 0, DImode);
1515       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1516
1517       operands[0] = operand_subword (op0, 0, 0, DImode);
1518       if (INTVAL (op1) < 0)
1519         return \"mov -1,%0\";
1520       else
1521         return \"mov 0,%0\";
1522     }
1523   else if (GET_CODE (op1) == CONST_DOUBLE)
1524     {
1525       operands[0] = operand_subword (op0, 1, 0, DImode);
1526       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
1527       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1528
1529       operands[0] = operand_subword (op0, 0, 0, DImode);
1530       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
1531       return singlemove_string (operands);
1532     }
1533   else
1534     abort ();
1535   return \"\";
1536 }"
1537   [(set_attr "type" "move")
1538    (set_attr "length" "2")])
1539
1540 ;;; ??? This pattern originally clobbered a scratch register.  However, this
1541 ;;; is invalid, the movdi pattern may not use a temp register because it
1542 ;;; may be called from reload to reload a DImode value.  In that case, we
1543 ;;; end up with a scratch register that never gets allocated.  To avoid this,
1544 ;;; we use global register 1 which is never otherwise used by gcc as a temp.
1545 ;;; The correct solution here might be to force DImode constants to memory,
1546 ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg
1547 ;;; 1 will then no longer need to be considered a fixed reg.
1548
1549 ;;; Gas doesn't have any 64 bit constant support, so don't use %uhi and %ulo
1550 ;;; on constants.  Symbols have to be handled by the linker, so we must use
1551 ;;; %uhi and %ulo for them, but gas will handle these correctly.
1552 ;;; ??? This comment is obsolete, gas handles them now.
1553
1554 (define_insn ""
1555   [(set (match_operand:DI 0 "register_operand" "=r")
1556         (high:DI (match_operand 1 "const_double_operand" "")))
1557    (clobber (reg:DI 1))]
1558   "TARGET_V9 && check_pic (1)"
1559   "*
1560 {
1561   rtx high, low;
1562   
1563   split_double (operands[1], &high, &low);
1564
1565   if (high == const0_rtx)
1566     {
1567       operands[1] = low;
1568       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1569     }
1570   else
1571     {
1572       operands[1] = high;
1573       output_asm_insn (singlemove_string (operands), operands);
1574
1575       operands[1] = low;
1576       output_asm_insn (\"sllx %0,32,%0\", operands);
1577       if (low != const0_rtx)
1578         output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1579     }
1580 }"
1581   [(set_attr "type" "move")
1582    (set_attr "length" "5")])
1583
1584 ;; Most of the required support for the various code models is here.
1585 ;; We can do this because sparcs need the high insn to load the address.  We
1586 ;; just need to get high to do the right thing for each code model.  Then each
1587 ;; uses the same "%X+%lo(...)" in the load/store insn.
1588
1589 ;; When TARGET_MEDLOW, assume that the upper 32 bits of symbol addresses are
1590 ;; always 0.
1591 ;; When TARGET_MEDANY, the upper 32 bits of function addresses are 0.
1592 ;; The data segment has a maximum size of 32 bits, but may be located anywhere.
1593 ;; MEDANY_BASE_REG contains the start address, currently %g4.
1594 ;; When TARGET_FULLANY, symbolic addresses are 64 bits.
1595
1596 (define_insn ""
1597   [(set (match_operand:DI 0 "register_operand" "=r")
1598         (high:DI (match_operand 1 "" "")))
1599 ;; ??? Why the clobber?
1600    (clobber (reg:DI 1))]
1601   "TARGET_MEDLOW && check_pic (1)"
1602   "sethi %%hi(%a1),%0"
1603   [(set_attr "type" "move")
1604    (set_attr "length" "1")])
1605
1606 ;; WARNING: %0 gets %hi(%1)+%g4.
1607 ;;          You cannot OR in %lo(%1), it must be added in.
1608
1609 (define_insn ""
1610   [(set (match_operand:DI 0 "register_operand" "=r")
1611         (high:DI (match_operand 1 "data_segment_operand" "")))
1612 ;; ??? Why the clobber?
1613    (clobber (reg:DI 1))]
1614   "TARGET_MEDANY && check_pic (1)"
1615   "sethi %%hi(%a1),%0; add %0,%%g4,%0"
1616   [(set_attr "type" "move")
1617    (set_attr "length" "2")])
1618
1619 (define_insn ""
1620   [(set (match_operand:DI 0 "register_operand" "=r")
1621         (high:DI (match_operand 1 "text_segment_operand" "")))
1622 ;; ??? Why the clobber?
1623    (clobber (reg:DI 1))]
1624   "TARGET_MEDANY && check_pic (1)"
1625   "sethi %%hi(%a1),%0"
1626   [(set_attr "type" "move")
1627    (set_attr "length" "1")])
1628
1629 (define_insn ""
1630   [(set (match_operand:DI 0 "register_operand" "=r")
1631         (high:DI (match_operand 1 "" "")))
1632    (clobber (reg:DI 1))]
1633   "TARGET_FULLANY && check_pic (1)"
1634   "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1635   [(set_attr "type" "move")
1636    (set_attr "length" "5")])
1637 \f
1638 ;; Move instructions
1639
1640 (define_expand "movqi"
1641   [(set (match_operand:QI 0 "general_operand" "")
1642         (match_operand:QI 1 "general_operand" ""))]
1643   ""
1644   "
1645 {
1646   if (emit_move_sequence (operands, QImode))
1647     DONE;
1648 }")
1649
1650 (define_insn ""
1651   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1652         (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1653   "register_operand (operands[0], QImode)
1654    || register_operand (operands[1], QImode)
1655    || operands[1] == const0_rtx"
1656   "@
1657    mov %1,%0
1658    sethi %%hi(%a1),%0
1659    ldub %1,%0
1660    stb %r1,%0"
1661   [(set_attr "type" "move,move,load,store")
1662    (set_attr "length" "*,1,*,1")])
1663
1664 (define_insn ""
1665   [(set (match_operand:QI 0 "register_operand" "=r")
1666         (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1667                               (match_operand 2 "immediate_operand" "in")) 0))]
1668   ""
1669   "or %1,%%lo(%a2),%0"
1670   [(set_attr "length" "1")])
1671
1672 (define_insn ""
1673   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1674         (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1675    (clobber (match_scratch:SI 2 "=&r"))]
1676   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1677   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1678   [(set_attr "type" "store")
1679    (set_attr "length" "2")])
1680
1681 (define_expand "movhi"
1682   [(set (match_operand:HI 0 "general_operand" "")
1683         (match_operand:HI 1 "general_operand" ""))]
1684   ""
1685   "
1686 {
1687   if (emit_move_sequence (operands, HImode))
1688     DONE;
1689 }")
1690
1691 (define_insn ""
1692   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1693         (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
1694   "register_operand (operands[0], HImode)
1695    || register_operand (operands[1], HImode)
1696    || operands[1] == const0_rtx"
1697   "@
1698    mov %1,%0
1699    sethi %%hi(%a1),%0
1700    lduh %1,%0
1701    sth %r1,%0"
1702   [(set_attr "type" "move,move,load,store")
1703    (set_attr "length" "*,1,*,1")])
1704
1705 (define_insn ""
1706   [(set (match_operand:HI 0 "register_operand" "=r")
1707         (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
1708                    (match_operand 2 "immediate_operand" "in")))]
1709   ""
1710   "or %1,%%lo(%a2),%0"
1711   [(set_attr "length" "1")])
1712
1713 (define_insn ""
1714   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
1715         (match_operand:HI 1 "reg_or_0_operand" "rJ"))
1716    (clobber (match_scratch:SI 2 "=&r"))]
1717   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1718   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
1719   [(set_attr "type" "store")
1720    (set_attr "length" "2")])
1721
1722 (define_expand "movsi"
1723   [(set (match_operand:SI 0 "general_operand" "")
1724         (match_operand:SI 1 "general_operand" ""))]
1725   ""
1726   "
1727 {
1728   if (emit_move_sequence (operands, SImode))
1729     DONE;
1730 }")
1731
1732 ;; We must support both 'r' and 'f' registers here, because combine may
1733 ;; convert SFmode hard registers to SImode hard registers when simplifying
1734 ;; subreg sets.
1735
1736 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
1737 ;; problems with register allocation.  Reload might try to put an integer
1738 ;; in an fp register, or an fp number is an integer register.
1739
1740 (define_insn ""
1741   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
1742         (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
1743   "register_operand (operands[0], SImode)
1744    || register_operand (operands[1], SImode)
1745    || operands[1] == const0_rtx"
1746   "@
1747    mov %1,%0
1748    fmovs %1,%0
1749    sethi %%hi(%a1),%0
1750    ld %1,%0
1751    ld %1,%0
1752    st %r1,%0
1753    st %r1,%0"
1754   [(set_attr "type" "move,fp,move,load,load,store,store")
1755    (set_attr "length" "*,*,1,*,*,*,*")])
1756
1757 (define_insn ""
1758   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
1759         (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1760    (clobber (match_scratch:SI 2 "=&r"))]
1761   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1762   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1763   [(set_attr "type" "store")
1764    (set_attr "length" "2")])
1765
1766 (define_expand "movdi"
1767   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1768         (match_operand:DI 1 "general_operand" ""))]
1769   ""
1770   "
1771 {
1772   if (emit_move_sequence (operands, DImode))
1773     DONE;
1774 }")
1775
1776 (define_insn ""
1777   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
1778         (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
1779   "! TARGET_V9
1780    && (register_operand (operands[0], DImode)
1781        || register_operand (operands[1], DImode)
1782        || operands[1] == const0_rtx)"
1783   "*
1784 {
1785   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1786     return output_fp_move_double (operands);
1787   return output_move_double (operands);
1788 }"
1789   [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
1790    (set_attr "length" "2,1,1,3,3,3,2,3,3")])
1791
1792 ;;; ??? The trick used below can be extended to load any negative 32 bit
1793 ;;; constant in two instructions.  Currently the compiler will use HIGH/LO_SUM
1794 ;;; for anything not matching the HIK constraints, which results in 5
1795 ;;; instructions.  Positive 32 bit constants can be loaded in the obvious way
1796 ;;; with sethi/ori.  To extend the trick, in the xor instruction, use 
1797 ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0
1798 ;;; This needs the original value of operands[1], not the inverted value.
1799
1800 (define_insn ""
1801   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q")
1802         (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))]
1803   "TARGET_V9
1804    && (register_operand (operands[0], DImode)
1805        || register_operand (operands[1], DImode)
1806        || operands[1] == const0_rtx)"
1807   "*
1808 {
1809   switch (which_alternative)
1810     {
1811     case 0:
1812       return \"mov %1,%0\";
1813     case 1:
1814       /* Sethi does not sign extend, so we must use a little trickery
1815          to use it for negative numbers.  Invert the constant before
1816          loading it in, then use a xor immediate to invert the loaded bits
1817          (along with the upper 32 bits) to the desired constant.  This
1818          works because the sethi and immediate fields overlap.  */
1819
1820       if ((INTVAL (operands[1]) & 0x80000000) == 0)
1821         return \"sethi %%hi(%a1),%0\";
1822       else
1823         {
1824           operands[1] = gen_rtx (CONST_INT, VOIDmode,
1825                                  ~ INTVAL (operands[1]));
1826           output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1827           /* The low 10 bits are already zero, but invert the rest.
1828              Assemblers don't accept 0x1c00, so use -0x400 instead.  */
1829           return \"xor %0,-0x400,%0\";
1830         }
1831     case 2:
1832       return \"ldx %1,%0\";
1833     case 3:
1834       return \"stx %r1,%0\";
1835     case 4:
1836       return \"mov %1,%0\";
1837     case 5:
1838       return \"ldd %1,%0\";
1839     case 6:
1840       return \"std %1,%0\";
1841     }
1842 }"
1843   [(set_attr "type" "move,move,load,store,fp,fpload,fpstore")
1844    (set_attr "length" "1,2,1,1,1,1,1")])
1845
1846 ;; ??? There's no symbolic (set (mem:DI ...) ...).
1847 ;; Experimentation with v9 suggested one isn't needed.
1848 \f
1849 ;; Block move insns.
1850
1851 ;; ??? We get better code without it.  See output_block_move in sparc.c.
1852
1853 ;; The definition of this insn does not really explain what it does,
1854 ;; but it should suffice
1855 ;; that anything generated as this insn will be recognized as one
1856 ;; and that it will not successfully combine with anything.
1857 ;(define_expand "movstrsi"
1858 ;  [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1859 ;                  (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1860 ;             (use (match_operand:SI 2 "nonmemory_operand" ""))
1861 ;             (use (match_operand:SI 3 "immediate_operand" ""))
1862 ;             (clobber (match_dup 0))
1863 ;             (clobber (match_dup 1))
1864 ;             (clobber (match_scratch:SI 4 ""))
1865 ;             (clobber (reg:SI 0))
1866 ;             (clobber (reg:SI 1))])]
1867 ;  ""
1868 ;  "
1869 ;{
1870 ;  /* If the size isn't known, don't emit inline code.  output_block_move
1871 ;     would output code that's much slower than the library function.
1872 ;     Also don't output code for large blocks.  */
1873 ;  if (GET_CODE (operands[2]) != CONST_INT
1874 ;      || GET_CODE (operands[3]) != CONST_INT
1875 ;      || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1876 ;    FAIL;
1877 ;
1878 ;  operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1879 ;  operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1880 ;  operands[2] = force_not_mem (operands[2]);
1881 ;}")
1882
1883 ;(define_insn ""
1884 ;  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1885 ;       (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1886 ;   (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1887 ;   (use (match_operand:SI 3 "immediate_operand" "i"))
1888 ;   (clobber (match_dup 0))
1889 ;   (clobber (match_dup 1))
1890 ;   (clobber (match_scratch:SI 4 "=&r"))
1891 ;   (clobber (reg:SI 0))
1892 ;   (clobber (reg:SI 1))]
1893 ;  ""
1894 ;  "* return output_block_move (operands);"
1895 ;  [(set_attr "type" "multi")
1896 ;   (set_attr "length" "6")])
1897 \f
1898 ;; Floating point move insns
1899
1900 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1901 ;; to be reloaded by putting the constant into memory.
1902 ;; It must come before the more general movsf pattern.
1903 (define_insn ""
1904   [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1905         (match_operand:SF 1 "" "?F,m,G"))]
1906   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1907   "*
1908 {
1909   switch (which_alternative)
1910     {
1911     case 0:
1912       return singlemove_string (operands);
1913     case 1:
1914       return \"ld %1,%0\";
1915     case 2:
1916       return \"st %%g0,%0\";
1917     }
1918 }"
1919   [(set_attr "type" "load,fpload,store")
1920    (set_attr "length" "2,1,1")])
1921
1922 (define_expand "movsf"
1923   [(set (match_operand:SF 0 "general_operand" "")
1924         (match_operand:SF 1 "general_operand" ""))]
1925   ""
1926   "
1927 {
1928   if (emit_move_sequence (operands, SFmode))
1929     DONE;
1930 }")
1931
1932 (define_insn ""
1933   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1934         (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1935   "TARGET_FPU
1936    && (register_operand (operands[0], SFmode)
1937        || register_operand (operands[1], SFmode))"
1938   "@
1939    fmovs %1,%0
1940    mov %1,%0
1941    ld %1,%0
1942    ld %1,%0
1943    st %r1,%0
1944    st %r1,%0"
1945   [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1946
1947 ;; Exactly the same as above, except that all `f' cases are deleted.
1948 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1949 ;; when -mno-fpu.
1950
1951 (define_insn ""
1952   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1953         (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1954   "! TARGET_FPU
1955    && (register_operand (operands[0], SFmode)
1956        || register_operand (operands[1], SFmode))"
1957   "@
1958    mov %1,%0
1959    ld %1,%0
1960    st %r1,%0"
1961   [(set_attr "type" "move,load,store")])
1962
1963 (define_insn ""
1964   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1965         (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1966    (clobber (match_scratch:SI 2 "=&r"))]
1967   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
1968   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1969   [(set_attr "type" "store")
1970    (set_attr "length" "2")])
1971
1972 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1973 ;; to be reloaded by putting the constant into memory.
1974 ;; It must come before the more general movdf pattern.
1975
1976 (define_insn ""
1977   [(set (match_operand:DF 0 "general_operand" "=?r,e,o")
1978         (match_operand:DF 1 "" "?F,m,G"))]
1979   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1980   "*
1981 {
1982   switch (which_alternative)
1983     {
1984     case 0:
1985       return output_move_double (operands);
1986     case 1:
1987       return output_fp_move_double (operands);
1988     case 2:
1989       if (TARGET_V9)
1990         {
1991           return \"stx %%g0,%0\";
1992         }
1993       else
1994         {
1995           operands[1] = adj_offsettable_operand (operands[0], 4);
1996           return \"st %%g0,%0\;st %%g0,%1\";
1997         }
1998     }
1999 }"
2000   [(set_attr "type" "load,fpload,store")
2001    (set_attr "length" "3,3,3")])
2002
2003 (define_expand "movdf"
2004   [(set (match_operand:DF 0 "general_operand" "")
2005         (match_operand:DF 1 "general_operand" ""))]
2006   ""
2007   "
2008 {
2009   if (emit_move_sequence (operands, DFmode))
2010     DONE;
2011 }")
2012
2013 (define_insn ""
2014   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r")
2015         (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))]
2016   "TARGET_FPU
2017    && (register_operand (operands[0], DFmode)
2018        || register_operand (operands[1], DFmode))"
2019   "*
2020 {
2021   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2022     return output_fp_move_double (operands);
2023   return output_move_double (operands);
2024 }"
2025   [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
2026    (set_attr "length" "1,1,2,2,3,3,3,3")])
2027
2028 ;; Exactly the same as above, except that all `e' cases are deleted.
2029 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2030 ;; when -mno-fpu.
2031
2032 (define_insn ""
2033   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
2034         (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
2035   "! TARGET_FPU
2036    && (register_operand (operands[0], DFmode)
2037        || register_operand (operands[1], DFmode))"
2038   "* return output_move_double (operands);"
2039   [(set_attr "type" "store,load,move,store,load")
2040    (set_attr "length" "1,1,2,3,3")])
2041
2042 ;; Must handle overlapping registers here, since parameters can be unaligned
2043 ;; in registers.
2044 ;; ??? Do we need a v9 version of this?
2045 (define_split
2046   [(set (match_operand:DF 0 "register_operand" "")
2047         (match_operand:DF 1 "register_operand" ""))]
2048   "! TARGET_V9 && reload_completed"
2049   [(set (match_dup 2) (match_dup 3))
2050    (set (match_dup 4) (match_dup 5))]
2051   "
2052 {
2053   rtx first_set = operand_subword (operands[0], 0, 0, DFmode);
2054   rtx second_use = operand_subword (operands[1], 1, 0, DFmode);
2055
2056   if (REGNO (first_set) == REGNO (second_use))
2057     {
2058       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2059       operands[3] = second_use;
2060       operands[4] = first_set;
2061       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2062     }
2063   else
2064     {
2065       operands[2] = first_set;
2066       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2067       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2068       operands[5] = second_use;
2069     }
2070 }")
2071
2072 (define_insn ""
2073   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
2074         (match_operand:DF 1 "reg_or_0_operand" "re,G"))
2075    (clobber (match_scratch:SI 2 "=&r,&r"))]
2076   "(reload_completed || reload_in_progress) && ! TARGET_PTR64"
2077   "*
2078 {
2079   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2080   if (which_alternative == 0)
2081     return \"std %1,[%2+%%lo(%a0)]\";
2082   else
2083     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
2084 }"
2085   [(set_attr "type" "store")
2086    (set_attr "length" "3")])
2087
2088 ;; This pattern forces (set (reg:TF ...) (const_double ...))
2089 ;; to be reloaded by putting the constant into memory.
2090 ;; It must come before the more general movtf pattern.
2091 (define_insn ""
2092   [(set (match_operand:TF 0 "general_operand" "=?r,e,o")
2093         (match_operand:TF 1 "" "?F,m,G"))]
2094   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
2095   "*
2096 {
2097   switch (which_alternative)
2098     {
2099     case 0:
2100       return output_move_quad (operands);
2101     case 1:
2102       return output_fp_move_quad (operands);
2103     case 2:
2104       if (TARGET_V9)
2105         {
2106           operands[1] = adj_offsettable_operand (operands[0], 8);
2107           return \"stx %%g0,%0\;stx %%g0,%1\";
2108         }
2109       else
2110         {
2111           /* ??? Do we run off the end of the array here? */
2112           operands[1] = adj_offsettable_operand (operands[0], 4);
2113           operands[2] = adj_offsettable_operand (operands[0], 8);
2114           operands[3] = adj_offsettable_operand (operands[0], 12);
2115           return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
2116         }
2117     }
2118 }"
2119   [(set_attr "type" "load,fpload,store")
2120    (set_attr "length" "5,5,5")])
2121
2122 (define_expand "movtf"
2123   [(set (match_operand:TF 0 "general_operand" "")
2124         (match_operand:TF 1 "general_operand" ""))]
2125   ""
2126   "
2127 {
2128   if (emit_move_sequence (operands, TFmode))
2129     DONE;
2130 }")
2131
2132 (define_insn ""
2133   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r")
2134         (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))]
2135   "TARGET_FPU
2136    && (register_operand (operands[0], TFmode)
2137        || register_operand (operands[1], TFmode))"
2138   "*
2139 {
2140   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2141     return output_fp_move_quad (operands);
2142   return output_move_quad (operands);
2143 }"
2144   [(set_attr "type" "fp,move,fpstore,store,fpload,load")
2145    (set_attr "length" "4,4,5,5,5,5")])
2146
2147 ;; Exactly the same as above, except that all `e' cases are deleted.
2148 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2149 ;; when -mno-fpu.
2150
2151 (define_insn ""
2152   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
2153         (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
2154   "! TARGET_FPU
2155    && (register_operand (operands[0], TFmode)
2156        || register_operand (operands[1], TFmode))"
2157   "*
2158 {
2159   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2160     return output_fp_move_quad (operands);
2161   return output_move_quad (operands);
2162 }"
2163   [(set_attr "type" "move,store,load")
2164    (set_attr "length" "4,5,5")])
2165
2166 ;; This is disabled because it does not work.  Long doubles have only 8
2167 ;; byte alignment.  Adding an offset of 8 or 12 to an 8 byte aligned %lo may 
2168 ;; cause it to overflow.  See also GO_IF_LEGITIMATE_ADDRESS.
2169 (define_insn ""
2170   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
2171         (match_operand:TF 1 "reg_or_0_operand" "re,G"))
2172    (clobber (match_scratch:SI 2 "=&r,&r"))]
2173   "0 && (reload_completed || reload_in_progress) && ! TARGET_PTR64"
2174   "*
2175 {
2176   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2177   if (which_alternative == 0)
2178     return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
2179   else
2180     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
2181 }"
2182   [(set_attr "type" "store")
2183    (set_attr "length" "5")])
2184 \f
2185 ;; Sparc V9 conditional move instructions.
2186
2187 ; ??? There is not actually a 32 bit version of this instruction.
2188 (define_insn ""
2189   [(set (match_operand:SI 0 "register_operand" "=r")
2190         (if_then_else (match_operator 1 "comparison_operator"
2191                                       [(reg:CC 0) (const_int 0)])
2192                       (match_operand:SI 2 "arith11_operand" "ri")
2193                       (match_operand:SI 3 "register_operand" "0")))]
2194   "TARGET_V9"
2195   "mov%C1 %%icc,%2,%0"
2196   [(set_attr "type" "cmove")])
2197
2198 (define_insn ""
2199   [(set (match_operand:DI 0 "register_operand" "=r")
2200         (if_then_else (match_operator 1 "comparison_operator"
2201                                       [(reg:CC 0) (const_int 0)])
2202                       (match_operand:DI 2 "arith11_double_operand" "rHI")
2203                       (match_operand:DI 3 "register_operand" "0")))]
2204   "TARGET_V9"
2205   "mov%C1 %%icc,%2,%0"
2206   [(set_attr "type" "cmove")])
2207
2208 ;; ??? There is not actually a 32 bit version of this instruction.
2209 (define_insn ""
2210   [(set (match_operand:SI 0 "register_operand" "=r")
2211         (if_then_else (match_operator 1 "comparison_operator"
2212                                       [(reg:CCX 0) (const_int 0)])
2213                       (match_operand:SI 2 "arith11_operand" "ri")
2214                       (match_operand:SI 3 "register_operand" "0")))]
2215   "TARGET_V9"
2216   "mov%C1 %%xcc,%2,%0"
2217   [(set_attr "type" "cmove")])
2218
2219 (define_insn ""
2220   [(set (match_operand:DI 0 "register_operand" "=r")
2221         (if_then_else (match_operator 1 "comparison_operator"
2222                                       [(reg:CCX 0) (const_int 0)])
2223                       (match_operand:DI 2 "arith11_double_operand" "rHI")
2224                       (match_operand:DI 3 "register_operand" "0")))]
2225   "TARGET_V9"
2226   "mov%C1 %%xcc,%2,%0"
2227   [(set_attr "type" "cmove")])
2228
2229 ;; ??? There is not actually a 32 bit version of this instruction.
2230 (define_insn ""
2231   [(set (match_operand:SI 0 "register_operand" "=r")
2232         (if_then_else (match_operator 1 "comparison_operator"
2233                                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2234                                  (const_int 0)])
2235                       (match_operand:SI 3 "arith11_operand" "ri")
2236                       (match_operand:SI 4 "register_operand" "0")))]
2237   "TARGET_V9"
2238   "mov%C1 %2,%3,%0"
2239   [(set_attr "type" "cmove")])
2240
2241 ;; ??? There is not actually a 32 bit version of this instruction.
2242 (define_insn ""
2243   [(set (match_operand:SI 0 "register_operand" "=r")
2244         (if_then_else (match_operator 1 "comparison_operator"
2245                                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2246                                  (const_int 0)])
2247                       (match_operand:SI 3 "arith11_operand" "ri")
2248                       (match_operand:SI 4 "register_operand" "0")))]
2249   "TARGET_V9"
2250   "mov%C1 %2,%3,%0"
2251   [(set_attr "type" "cmove")])
2252
2253 (define_insn ""
2254   [(set (match_operand:DI 0 "register_operand" "=r")
2255         (if_then_else (match_operator 1 "comparison_operator"
2256                                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2257                                  (const_int 0)])
2258                       (match_operand:DI 3 "arith11_double_operand" "rHI")
2259                       (match_operand:DI 4 "register_operand" "0")))]
2260   "TARGET_V9"
2261   "mov%C1 %2,%3,%0"
2262   [(set_attr "type" "cmove")])
2263
2264 (define_insn ""
2265   [(set (match_operand:DI 0 "register_operand" "=r")
2266         (if_then_else (match_operator 1 "comparison_operator"
2267                                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2268                                  (const_int 0)])
2269                       (match_operand:DI 3 "arith11_double_operand" "rHI")
2270                       (match_operand:DI 4 "register_operand" "0")))]
2271   "TARGET_V9"
2272   "mov%C1 %2,%3,%0"
2273   [(set_attr "type" "cmove")])
2274
2275 ;; ??? There is not actually a 32 bit version of this instruction.
2276 (define_insn ""
2277   [(set (match_operand:SI 0 "register_operand" "=r")
2278         (if_then_else (match_operator 1 "v9_regcmp_op"
2279                                 [(match_operand:DI 2 "register_operand" "r")
2280                                  (const_int 0)])
2281                       (match_operand:SI 3 "arith10_operand" "ri")
2282                       (match_operand:SI 4 "register_operand" "0")))]
2283   "TARGET_V9"
2284   "movr%D1 %2,%r3,%0"
2285   [(set_attr "type" "cmove")])
2286
2287 (define_insn ""
2288   [(set (match_operand:DI 0 "register_operand" "=r")
2289         (if_then_else (match_operator 1 "v9_regcmp_op"
2290                                 [(match_operand:DI 2 "register_operand" "r")
2291                                  (const_int 0)])
2292                       (match_operand:DI 3 "arith10_double_operand" "ri")
2293                       (match_operand:DI 4 "register_operand" "0")))]
2294   "TARGET_V9"
2295   "movr%D1 %2,%r3,%0"
2296   [(set_attr "type" "cmove")])
2297
2298 (define_insn ""
2299   [(set (match_operand:SF 0 "register_operand" "=f")
2300         (if_then_else (match_operator 1 "v9_regcmp_op"
2301                                 [(match_operand:DI 2 "register_operand" "r")
2302                                  (const_int 0)])
2303                       (match_operand:SF 3 "register_operand" "f")
2304                       (match_operand:SF 4 "register_operand" "0")))]
2305   "TARGET_V9 && TARGET_FPU"
2306   "fmovrs%D1 %2,%r3,%0"
2307   [(set_attr "type" "cmove")])
2308
2309 (define_insn ""
2310   [(set (match_operand:DF 0 "register_operand" "=e")
2311         (if_then_else (match_operator 1 "v9_regcmp_op"
2312                                 [(match_operand:DI 2 "register_operand" "r")
2313                                  (const_int 0)])
2314                       (match_operand:DF 3 "register_operand" "e")
2315                       (match_operand:DF 4 "register_operand" "0")))]
2316   "TARGET_V9 && TARGET_FPU"
2317   "fmovrd%D1 %2,%r3,%0"
2318   [(set_attr "type" "cmove")])
2319
2320 (define_insn ""
2321   [(set (match_operand:TF 0 "register_operand" "=e")
2322         (if_then_else (match_operator 1 "v9_regcmp_op"
2323                                 [(match_operand:DI 2 "register_operand" "r")
2324                                  (const_int 0)])
2325                       (match_operand:TF 3 "register_operand" "e")
2326                       (match_operand:TF 4 "register_operand" "0")))]
2327   "TARGET_V9 && TARGET_FPU"
2328   "fmovrq%D1 %2,%r3,%0"
2329   [(set_attr "type" "cmove")])
2330
2331 (define_insn ""
2332   [(set (match_operand:SF 0 "register_operand" "=f")
2333         (if_then_else (match_operator 1 "comparison_operator"
2334                                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2335                                  (const_int 0)])
2336                       (match_operand:SF 3 "register_operand" "f")
2337                       (match_operand:SF 4 "register_operand" "0")))]
2338   "TARGET_V9 && TARGET_FPU"
2339   "fmovs%C1 %2,%3,%0"
2340   [(set_attr "type" "cmove")])
2341
2342 (define_insn ""
2343   [(set (match_operand:SF 0 "register_operand" "=f")
2344         (if_then_else (match_operator 1 "comparison_operator"
2345                                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2346                                  (const_int 0)])
2347                       (match_operand:SF 3 "register_operand" "f")
2348                       (match_operand:SF 4 "register_operand" "0")))]
2349   "TARGET_V9 && TARGET_FPU"
2350   "fmovs%C1 %2,%3,%0"
2351   [(set_attr "type" "cmove")])
2352
2353 (define_insn ""
2354   [(set (match_operand:DF 0 "register_operand" "=e")
2355         (if_then_else (match_operator 1 "comparison_operator"
2356                                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2357                                  (const_int 0)])
2358                       (match_operand:DF 3 "register_operand" "e")
2359                       (match_operand:DF 4 "register_operand" "0")))]
2360   "TARGET_V9 && TARGET_FPU"
2361   "fmovd%C1 %2,%3,%0"
2362   [(set_attr "type" "cmove")])
2363
2364 (define_insn ""
2365   [(set (match_operand:DF 0 "register_operand" "=e")
2366         (if_then_else (match_operator 1 "comparison_operator"
2367                                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2368                                  (const_int 0)])
2369                       (match_operand:DF 3 "register_operand" "e")
2370                       (match_operand:DF 4 "register_operand" "0")))]
2371   "TARGET_V9 && TARGET_FPU"
2372   "fmovd%C1 %2,%3,%0"
2373   [(set_attr "type" "cmove")])
2374
2375 (define_insn ""
2376   [(set (match_operand:TF 0 "register_operand" "=e")
2377         (if_then_else (match_operator 1 "comparison_operator"
2378                                 [(match_operand:CCFP 2 "ccfp_reg_operand" "c")
2379                                  (const_int 0)])
2380                       (match_operand:TF 3 "register_operand" "e")
2381                       (match_operand:TF 4 "register_operand" "0")))]
2382   "TARGET_V9 && TARGET_FPU"
2383   "fmovq%C1 %2,%3,%0"
2384   [(set_attr "type" "cmove")])
2385
2386 (define_insn ""
2387   [(set (match_operand:TF 0 "register_operand" "=e")
2388         (if_then_else (match_operator 1 "comparison_operator"
2389                                 [(match_operand:CCFPE 2 "ccfp_reg_operand" "c")
2390                                  (const_int 0)])
2391                       (match_operand:TF 3 "register_operand" "e")
2392                       (match_operand:TF 4 "register_operand" "0")))]
2393   "TARGET_V9 && TARGET_FPU"
2394   "fmovq%C1 %2,%3,%0"
2395   [(set_attr "type" "cmove")])
2396
2397 (define_insn ""
2398   [(set (match_operand:SF 0 "register_operand" "=f")
2399         (if_then_else (match_operator 1 "comparison_operator"
2400                                       [(reg:CC 0) (const_int 0)])
2401                       (match_operand:SF 2 "register_operand" "f")
2402                       (match_operand:SF 3 "register_operand" "0")))]
2403   "TARGET_V9 && TARGET_FPU"
2404   "fmovs%C1 %%icc,%2,%0"
2405   [(set_attr "type" "cmove")])
2406
2407 (define_insn ""
2408   [(set (match_operand:DF 0 "register_operand" "=e")
2409         (if_then_else (match_operator 1 "comparison_operator"
2410                                       [(reg:CC 0) (const_int 0)])
2411                       (match_operand:DF 2 "register_operand" "e")
2412                       (match_operand:DF 3 "register_operand" "0")))]
2413   "TARGET_V9 && TARGET_FPU"
2414   "fmovd%C1 %%icc,%2,%0"
2415   [(set_attr "type" "cmove")])
2416
2417 (define_insn ""
2418   [(set (match_operand:TF 0 "register_operand" "=e")
2419         (if_then_else (match_operator 1 "comparison_operator"
2420                                       [(reg:CC 0) (const_int 0)])
2421                       (match_operand:TF 2 "register_operand" "e")
2422                       (match_operand:TF 3 "register_operand" "0")))]
2423   "TARGET_V9 && TARGET_FPU"
2424   "fmovq%C1 %%icc,%2,%0"
2425   [(set_attr "type" "cmove")])
2426
2427 (define_insn ""
2428   [(set (match_operand:SF 0 "register_operand" "=f")
2429         (if_then_else (match_operator 1 "comparison_operator"
2430                                       [(reg:CCX 0) (const_int 0)])
2431                       (match_operand:SF 2 "register_operand" "f")
2432                       (match_operand:SF 3 "register_operand" "0")))]
2433   "TARGET_V9 && TARGET_FPU"
2434   "fmovs%C1 %%xcc,%2,%0"
2435   [(set_attr "type" "cmove")])
2436
2437 (define_insn ""
2438   [(set (match_operand:DF 0 "register_operand" "=e")
2439         (if_then_else (match_operator 1 "comparison_operator"
2440                                       [(reg:CCX 0) (const_int 0)])
2441                       (match_operand:DF 2 "register_operand" "e")
2442                       (match_operand:DF 3 "register_operand" "0")))]
2443   "TARGET_V9 && TARGET_FPU"
2444   "fmovd%C1 %%xcc,%2,%0"
2445   [(set_attr "type" "cmove")])
2446
2447 (define_insn ""
2448   [(set (match_operand:TF 0 "register_operand" "=e")
2449         (if_then_else (match_operator 1 "comparison_operator"
2450                                       [(reg:CCX 0) (const_int 0)])
2451                       (match_operand:TF 2 "register_operand" "e")
2452                       (match_operand:TF 3 "register_operand" "0")))]
2453   "TARGET_V9 && TARGET_FPU"
2454   "fmovq%C1 %%xcc,%2,%0"
2455   [(set_attr "type" "cmove")])
2456 \f
2457 ;;- zero extension instructions
2458
2459 ;; These patterns originally accepted general_operands, however, slightly
2460 ;; better code is generated by only accepting register_operands, and then
2461 ;; letting combine generate the ldu[hb] insns.
2462
2463 (define_expand "zero_extendhisi2"
2464   [(set (match_operand:SI 0 "register_operand" "")
2465         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2466   ""
2467   "
2468 {
2469   rtx temp = gen_reg_rtx (SImode);
2470   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2471   int op1_subword = 0;
2472
2473   if (GET_CODE (operand1) == SUBREG)
2474     {
2475       op1_subword = SUBREG_WORD (operand1);
2476       operand1 = XEXP (operand1, 0);
2477     }
2478
2479   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2480                                          op1_subword),
2481                           shift_16));
2482   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2483   DONE;
2484 }")
2485
2486 (define_insn ""
2487   [(set (match_operand:SI 0 "register_operand" "=r")
2488         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2489   ""
2490   "lduh %1,%0"
2491   [(set_attr "type" "load")])
2492
2493 (define_expand "zero_extendqihi2"
2494   [(set (match_operand:HI 0 "register_operand" "")
2495         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2496   ""
2497   "")
2498
2499 (define_insn ""
2500   [(set (match_operand:HI 0 "register_operand" "=r,r")
2501         (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2502   "GET_CODE (operands[1]) != CONST_INT"
2503   "@
2504    and %1,0xff,%0
2505    ldub %1,%0"
2506   [(set_attr "type" "unary,load")
2507    (set_attr "length" "1")])
2508
2509 (define_expand "zero_extendqisi2"
2510   [(set (match_operand:SI 0 "register_operand" "")
2511         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2512   ""
2513   "")
2514
2515 (define_insn ""
2516   [(set (match_operand:SI 0 "register_operand" "=r,r")
2517         (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2518   "GET_CODE (operands[1]) != CONST_INT"
2519   "@
2520    and %1,0xff,%0
2521    ldub %1,%0"
2522   [(set_attr "type" "unary,load")
2523    (set_attr "length" "1")])
2524
2525 (define_expand "zero_extendqidi2"
2526   [(set (match_operand:DI 0 "register_operand" "")
2527         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2528   "TARGET_V9"
2529   "")
2530
2531 (define_insn ""
2532   [(set (match_operand:DI 0 "register_operand" "=r,r")
2533         (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))]
2534   "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
2535   "@
2536    and %1,0xff,%0
2537    ldub %1,%0"
2538   [(set_attr "type" "unary,load")
2539    (set_attr "length" "1")])
2540
2541 (define_expand "zero_extendhidi2"
2542   [(set (match_operand:DI 0 "register_operand" "")
2543         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2544   "TARGET_V9"
2545   "
2546 {
2547   rtx temp = gen_reg_rtx (DImode);
2548   rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
2549   int op1_subword = 0;
2550
2551   if (GET_CODE (operand1) == SUBREG)
2552     {
2553       op1_subword = SUBREG_WORD (operand1);
2554       operand1 = XEXP (operand1, 0);
2555     }
2556
2557   emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2558                                          op1_subword),
2559                           shift_48));
2560   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2561   DONE;
2562 }")
2563
2564 (define_insn ""
2565   [(set (match_operand:DI 0 "register_operand" "=r")
2566         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2567   "TARGET_V9"
2568   "lduh %1,%0"
2569   [(set_attr "type" "load")])
2570
2571 ;; ??? Write truncdisi pattern using sra?
2572
2573 (define_expand "zero_extendsidi2"
2574   [(set (match_operand:DI 0 "register_operand" "")
2575         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2576   "TARGET_V9"
2577   "")
2578
2579 (define_insn ""
2580   [(set (match_operand:DI 0 "register_operand" "=r,r")
2581         (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2582   "TARGET_V9 && GET_CODE (operands[1]) != CONST_INT"
2583   "@
2584    srl %1,0,%0
2585    lduw %1,%0"
2586   [(set_attr "type" "unary,load")
2587    (set_attr "length" "1")])
2588
2589 ;; Simplify comparisons of extended values.
2590
2591 (define_insn ""
2592   [(set (reg:CC 0)
2593         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2594                     (const_int 0)))]
2595   ""
2596   "andcc %0,0xff,%%g0"
2597   [(set_attr "type" "compare")])
2598
2599 (define_insn ""
2600   [(set (reg:CC 0)
2601         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2602                     (const_int 0)))
2603    (set (match_operand:SI 0 "register_operand" "=r")
2604         (zero_extend:SI (match_dup 1)))]
2605   ""
2606   "andcc %1,0xff,%0"
2607   [(set_attr "type" "unary")])
2608
2609 ;; Similarly, handle SI->QI mode truncation followed by a compare.
2610
2611 (define_insn ""
2612   [(set (reg:CC 0)
2613         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
2614                     (const_int 0)))]
2615   ""
2616   "andcc %0,0xff,%%g0"
2617   [(set_attr "type" "compare")])
2618
2619 (define_insn ""
2620   [(set (reg:CC 0)
2621         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
2622                     (const_int 0)))
2623    (set (match_operand:QI 0 "register_operand" "=r")
2624         (match_dup 1))]
2625   ""
2626   "andcc %1,0xff,%0"
2627   [(set_attr "type" "unary")])
2628 \f
2629 ;;- sign extension instructions
2630
2631 ;; These patterns originally accepted general_operands, however, slightly
2632 ;; better code is generated by only accepting register_operands, and then
2633 ;; letting combine generate the lds[hb] insns.
2634
2635 (define_expand "extendhisi2"
2636   [(set (match_operand:SI 0 "register_operand" "")
2637         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2638   ""
2639   "
2640 {
2641   rtx temp = gen_reg_rtx (SImode);
2642   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
2643   int op1_subword = 0;
2644
2645   if (GET_CODE (operand1) == SUBREG)
2646     {
2647       op1_subword = SUBREG_WORD (operand1);
2648       operand1 = XEXP (operand1, 0);
2649     }
2650
2651   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2652                                          op1_subword),
2653                           shift_16));
2654   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
2655   DONE;
2656 }")
2657
2658 (define_insn ""
2659   [(set (match_operand:SI 0 "register_operand" "=r")
2660         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2661   ""
2662   "ldsh %1,%0"
2663   [(set_attr "type" "load")])
2664
2665 (define_expand "extendqihi2"
2666   [(set (match_operand:HI 0 "register_operand" "")
2667         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
2668   ""
2669   "
2670 {
2671   rtx temp = gen_reg_rtx (SImode);
2672   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2673   int op1_subword = 0;
2674   int op0_subword = 0;
2675
2676   if (GET_CODE (operand1) == SUBREG)
2677     {
2678       op1_subword = SUBREG_WORD (operand1);
2679       operand1 = XEXP (operand1, 0);
2680     }
2681   if (GET_CODE (operand0) == SUBREG)
2682     {
2683       op0_subword = SUBREG_WORD (operand0);
2684       operand0 = XEXP (operand0, 0);
2685     }
2686   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2687                                          op1_subword),
2688                           shift_24));
2689   if (GET_MODE (operand0) != SImode)
2690     operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
2691   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2692   DONE;
2693 }")
2694
2695 (define_insn ""
2696   [(set (match_operand:HI 0 "register_operand" "=r")
2697         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
2698   ""
2699   "ldsb %1,%0"
2700   [(set_attr "type" "load")])
2701
2702 (define_expand "extendqisi2"
2703   [(set (match_operand:SI 0 "register_operand" "")
2704         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2705   ""
2706   "
2707 {
2708   rtx temp = gen_reg_rtx (SImode);
2709   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
2710   int op1_subword = 0;
2711
2712   if (GET_CODE (operand1) == SUBREG)
2713     {
2714       op1_subword = SUBREG_WORD (operand1);
2715       operand1 = XEXP (operand1, 0);
2716     }
2717
2718   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
2719                                          op1_subword),
2720                           shift_24));
2721   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
2722   DONE;
2723 }")
2724
2725 (define_insn ""
2726   [(set (match_operand:SI 0 "register_operand" "=r")
2727         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2728   ""
2729   "ldsb %1,%0"
2730   [(set_attr "type" "load")])
2731
2732 (define_expand "extendqidi2"
2733   [(set (match_operand:DI 0 "register_operand" "")
2734         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
2735   "TARGET_V9"
2736   "
2737 {
2738   rtx temp = gen_reg_rtx (DImode);
2739   rtx shift_56 = gen_rtx (CONST_INT, VOIDmode, 56);
2740   int op1_subword = 0;
2741
2742   if (GET_CODE (operand1) == SUBREG)
2743     {
2744       op1_subword = SUBREG_WORD (operand1);
2745       operand1 = XEXP (operand1, 0);
2746     }
2747
2748   emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2749                                          op1_subword),
2750                           shift_56));
2751   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
2752   DONE;
2753 }")
2754
2755 (define_insn ""
2756   [(set (match_operand:DI 0 "register_operand" "=r")
2757         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2758   "TARGET_V9"
2759   "ldsb %1,%0"
2760   [(set_attr "type" "load")])
2761
2762 (define_expand "extendhidi2"
2763   [(set (match_operand:DI 0 "register_operand" "")
2764         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
2765   "TARGET_V9"
2766   "
2767 {
2768   rtx temp = gen_reg_rtx (DImode);
2769   rtx shift_48 = gen_rtx (CONST_INT, VOIDmode, 48);
2770   int op1_subword = 0;
2771
2772   if (GET_CODE (operand1) == SUBREG)
2773     {
2774       op1_subword = SUBREG_WORD (operand1);
2775       operand1 = XEXP (operand1, 0);
2776     }
2777
2778   emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
2779                                          op1_subword),
2780                           shift_48));
2781   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
2782   DONE;
2783 }")
2784
2785 (define_insn ""
2786   [(set (match_operand:DI 0 "register_operand" "=r")
2787         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2788   "TARGET_V9"
2789   "ldsh %1,%0"
2790   [(set_attr "type" "load")])
2791
2792 (define_expand "extendsidi2"
2793   [(set (match_operand:DI 0 "register_operand" "")
2794         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
2795   "TARGET_V9"
2796   "")
2797
2798 (define_insn ""
2799   [(set (match_operand:DI 0 "register_operand" "=r,r")
2800         (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
2801   "TARGET_V9"
2802   "@
2803   sra %1,0,%0
2804   ldsw %1,%0"
2805   [(set_attr "type" "unary,load")
2806    (set_attr "length" "1")])
2807 \f
2808 ;; Special pattern for optimizing bit-field compares.  This is needed
2809 ;; because combine uses this as a canonical form.
2810
2811 (define_insn ""
2812   [(set (reg:CC 0)
2813         (compare:CC
2814          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
2815                           (match_operand:SI 1 "small_int" "n")
2816                           (match_operand:SI 2 "small_int" "n"))
2817          (const_int 0)))]
2818   "INTVAL (operands[2]) > 19"
2819   "*
2820 {
2821   int len = INTVAL (operands[1]);
2822   int pos = 32 - INTVAL (operands[2]) - len;
2823   unsigned mask = ((1 << len) - 1) << pos;
2824
2825   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
2826   return \"andcc %0,%1,%%g0\";
2827 }")
2828
2829 (define_insn ""
2830   [(set (reg:CCX 0)
2831         (compare:CCX
2832          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
2833                           (match_operand:SI 1 "small_int" "n")
2834                           (match_operand:SI 2 "small_int" "n"))
2835          (const_int 0)))]
2836   "TARGET_V9 && INTVAL (operands[2]) > 51"
2837   "*
2838 {
2839   int len = INTVAL (operands[1]);
2840   int pos = 64 - INTVAL (operands[2]) - len;
2841   unsigned mask = ((1 << len) - 1) << pos;
2842
2843   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
2844   return \"andcc %0,%1,%%g0\";
2845 }")
2846 \f
2847 ;; Conversions between float, double and long double.
2848
2849 (define_insn "extendsfdf2"
2850   [(set (match_operand:DF 0 "register_operand" "=e")
2851         (float_extend:DF
2852          (match_operand:SF 1 "register_operand" "f")))]
2853   "TARGET_FPU"
2854   "fstod %1,%0"
2855   [(set_attr "type" "fp")])
2856
2857 (define_insn "extendsftf2"
2858   [(set (match_operand:TF 0 "register_operand" "=e")
2859         (float_extend:TF
2860          (match_operand:SF 1 "register_operand" "f")))]
2861   "TARGET_FPU && TARGET_HARD_QUAD"
2862   "fstoq %1,%0"
2863   [(set_attr "type" "fp")])
2864
2865 (define_insn "extenddftf2"
2866   [(set (match_operand:TF 0 "register_operand" "=e")
2867         (float_extend:TF
2868          (match_operand:DF 1 "register_operand" "e")))]
2869   "TARGET_FPU && TARGET_HARD_QUAD"
2870   "fdtoq %1,%0"
2871   [(set_attr "type" "fp")])
2872
2873 (define_insn "truncdfsf2"
2874   [(set (match_operand:SF 0 "register_operand" "=f")
2875         (float_truncate:SF
2876          (match_operand:DF 1 "register_operand" "e")))]
2877   "TARGET_FPU"
2878   "fdtos %1,%0"
2879   [(set_attr "type" "fp")])
2880
2881 (define_insn "trunctfsf2"
2882   [(set (match_operand:SF 0 "register_operand" "=f")
2883         (float_truncate:SF
2884          (match_operand:TF 1 "register_operand" "e")))]
2885   "TARGET_FPU && TARGET_HARD_QUAD"
2886   "fqtos %1,%0"
2887   [(set_attr "type" "fp")])
2888
2889 (define_insn "trunctfdf2"
2890   [(set (match_operand:DF 0 "register_operand" "=e")
2891         (float_truncate:DF
2892          (match_operand:TF 1 "register_operand" "e")))]
2893   "TARGET_FPU && TARGET_HARD_QUAD"
2894   "fqtod %1,%0"
2895   [(set_attr "type" "fp")])
2896 \f
2897 ;; Conversion between fixed point and floating point.
2898
2899 (define_insn "floatsisf2"
2900   [(set (match_operand:SF 0 "register_operand" "=f")
2901         (float:SF (match_operand:SI 1 "register_operand" "f")))]
2902   "TARGET_FPU"
2903   "fitos %1,%0"
2904   [(set_attr "type" "fp")])
2905
2906 (define_insn "floatsidf2"
2907   [(set (match_operand:DF 0 "register_operand" "=e")
2908         (float:DF (match_operand:SI 1 "register_operand" "f")))]
2909   "TARGET_FPU"
2910   "fitod %1,%0"
2911   [(set_attr "type" "fp")])
2912
2913 (define_insn "floatsitf2"
2914   [(set (match_operand:TF 0 "register_operand" "=e")
2915         (float:TF (match_operand:SI 1 "register_operand" "f")))]
2916   "TARGET_FPU && TARGET_HARD_QUAD"
2917   "fitoq %1,%0"
2918   [(set_attr "type" "fp")])
2919
2920 ;; Now the same for 64 bit sources.
2921 ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2).
2922
2923 (define_expand "floatdisf2"
2924   [(parallel [(set (match_operand:SF 0 "register_operand" "")
2925                    (float:SF (match_operand:DI 1 "general_operand" "")))
2926               (clobber (match_dup 2))
2927               (clobber (match_dup 3))])]
2928   "TARGET_V9 && TARGET_FPU"
2929   "
2930 {
2931   operands[2] = gen_reg_rtx (DFmode);
2932   operands[3] = sparc64_fpconv_stack_temp ();
2933 }")
2934
2935 (define_expand "floatdidf2"
2936   [(parallel [(set (match_operand:DF 0 "register_operand" "")
2937                    (float:DF (match_operand:DI 1 "general_operand" "")))
2938               (clobber (match_dup 2))
2939               (clobber (match_dup 3))])]
2940   "TARGET_V9 && TARGET_FPU"
2941   "
2942 {
2943   operands[2] = gen_reg_rtx (DFmode);
2944   operands[3] = sparc64_fpconv_stack_temp ();
2945 }")
2946
2947 (define_expand "floatditf2"
2948   [(parallel [(set (match_operand:TF 0 "register_operand" "")
2949                    (float:TF (match_operand:DI 1 "general_operand" "")))
2950               (clobber (match_dup 2))
2951               (clobber (match_dup 3))])]
2952   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2953   "
2954 {
2955   operands[2] = gen_reg_rtx (DFmode);
2956   operands[3] = sparc64_fpconv_stack_temp ();
2957 }")
2958
2959 (define_insn ""
2960   [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
2961                    (float:SF (match_operand:DI 1 "general_operand" "rm")))
2962               (clobber (match_operand:DF 2 "register_operand" "=&e"))
2963               (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2964   "TARGET_V9 && TARGET_FPU"
2965   "*
2966 {
2967   if (GET_CODE (operands[1]) == MEM)
2968     output_asm_insn (\"ldd %1,%2\", operands);
2969   else
2970     output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
2971   return \"fxtos %2,%0\";
2972 }"
2973   [(set_attr "type" "fp")
2974    (set_attr "length" "3")])
2975
2976 (define_insn ""
2977   [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
2978                    (float:DF (match_operand:DI 1 "general_operand" "rm")))
2979               (clobber (match_operand:DF 2 "register_operand" "=&e"))
2980               (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2981   "TARGET_V9 && TARGET_FPU"
2982   "*
2983 {
2984   if (GET_CODE (operands[1]) == MEM)
2985     output_asm_insn (\"ldd %1,%2\", operands);
2986   else
2987     output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
2988   return \"fxtod %2,%0\";
2989 }"
2990   [(set_attr "type" "fp")
2991    (set_attr "length" "3")])
2992
2993 (define_insn ""
2994   [(parallel [(set (match_operand:TF 0 "register_operand" "=e")
2995                    (float:TF (match_operand:DI 1 "general_operand" "rm")))
2996               (clobber (match_operand:DF 2 "register_operand" "=&e"))
2997               (clobber (match_operand:DI 3 "memory_operand" "m"))])]
2998   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2999   "*
3000 {
3001   if (GET_CODE (operands[1]) == MEM)
3002     output_asm_insn (\"ldd %1,%2\", operands);
3003   else
3004     output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3005   return \"fxtoq %2,%0\";
3006 }"
3007   [(set_attr "type" "fp")
3008    (set_attr "length" "3")])
3009
3010 ;; ??? Ideally, these are what we would like to use.
3011
3012 (define_insn "floatdisf2_v9"
3013   [(set (match_operand:SF 0 "register_operand" "=f")
3014         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3015   "0 && TARGET_V9 && TARGET_FPU"
3016   "fxtos %1,%0"
3017   [(set_attr "type" "fp")])
3018
3019 (define_insn "floatdidf2_v9"
3020   [(set (match_operand:DF 0 "register_operand" "=e")
3021         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3022   "0 && TARGET_V9 && TARGET_FPU"
3023   "fxtod %1,%0"
3024   [(set_attr "type" "fp")])
3025
3026 (define_insn "floatditf2_v9"
3027   [(set (match_operand:TF 0 "register_operand" "=e")
3028         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3029   "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3030   "fxtoq %1,%0"
3031   [(set_attr "type" "fp")])
3032
3033 ;; Convert a float to an actual integer.
3034 ;; Truncation is performed as part of the conversion.
3035
3036 (define_insn "fix_truncsfsi2"
3037   [(set (match_operand:SI 0 "register_operand" "=f")
3038         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3039   "TARGET_FPU"
3040   "fstoi %1,%0"
3041   [(set_attr "type" "fp")])
3042
3043 (define_insn "fix_truncdfsi2"
3044   [(set (match_operand:SI 0 "register_operand" "=f")
3045         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3046   "TARGET_FPU"
3047   "fdtoi %1,%0"
3048   [(set_attr "type" "fp")])
3049
3050 (define_insn "fix_trunctfsi2"
3051   [(set (match_operand:SI 0 "register_operand" "=f")
3052         (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3053   "TARGET_FPU && TARGET_HARD_QUAD"
3054   "fqtoi %1,%0"
3055   [(set_attr "type" "fp")])
3056
3057 ;; Now the same, for 64-bit targets
3058 ;; ??? We try to work around an interesting problem.
3059 ;; If gcc tries to do a subreg on the result it will get the wrong answer:
3060 ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as
3061 ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change
3062 ;; the "0" to a "1".  One could enhance alter_subreg but it is not clear how to
3063 ;; do this cleanly.
3064
3065 (define_expand "fix_truncsfdi2"
3066   [(parallel [(set (match_operand:DI 0 "general_operand" "")
3067                    (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
3068               (clobber (match_dup 2))
3069               (clobber (match_dup 3))])]
3070   "TARGET_V9 && TARGET_FPU"
3071   "
3072 {
3073   operands[2] = gen_reg_rtx (DFmode);
3074   operands[3] = sparc64_fpconv_stack_temp ();
3075 }")
3076
3077 (define_expand "fix_truncdfdi2"
3078   [(parallel [(set (match_operand:DI 0 "general_operand" "")
3079                    (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
3080               (clobber (match_dup 2))
3081               (clobber (match_dup 3))])]
3082   "TARGET_V9 && TARGET_FPU"
3083   "
3084 {
3085   operands[2] = gen_reg_rtx (DFmode);
3086   operands[3] = sparc64_fpconv_stack_temp ();
3087 }")
3088
3089 (define_expand "fix_trunctfdi2"
3090   [(parallel [(set (match_operand:DI 0 "general_operand" "")
3091                    (fix:DI (fix:TF (match_operand:TF 1 "register_operand" ""))))
3092               (clobber (match_dup 2))
3093               (clobber (match_dup 3))])]
3094   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3095   "
3096 {
3097   operands[2] = gen_reg_rtx (DFmode);
3098   operands[3] = sparc64_fpconv_stack_temp ();
3099 }")
3100
3101 (define_insn ""
3102   [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3103                    (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
3104               (clobber (match_operand:DF 2 "register_operand" "=&e"))
3105               (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3106   "TARGET_V9 && TARGET_FPU"
3107   "*
3108 {
3109   output_asm_insn (\"fstox %1,%2\", operands);
3110   if (GET_CODE (operands[0]) == MEM)
3111     return \"std %2,%0\";
3112   else
3113     return \"std %2,%3\;ldx %3,%0\";
3114 }"
3115   [(set_attr "type" "fp")
3116    (set_attr "length" "3")])
3117
3118 (define_insn ""
3119   [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3120                    (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))
3121               (clobber (match_operand:DF 2 "register_operand" "=&e"))
3122               (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3123   "TARGET_V9 && TARGET_FPU"
3124   "*
3125 {
3126   output_asm_insn (\"fdtox %1,%2\", operands);
3127   if (GET_CODE (operands[0]) == MEM)
3128     return \"std %2,%0\";
3129   else
3130     return \"std %2,%3\;ldx %3,%0\";
3131 }"
3132   [(set_attr "type" "fp")
3133    (set_attr "length" "3")])
3134
3135 (define_insn ""
3136   [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3137                    (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))
3138               (clobber (match_operand:DF 2 "register_operand" "=&e"))
3139               (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3140   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3141   "*
3142 {
3143   output_asm_insn (\"fqtox %1,%2\", operands);
3144   if (GET_CODE (operands[0]) == MEM)
3145     return \"std %2,%0\";
3146   else
3147     return \"std %2,%3\;ldx %3,%0\";
3148 }"
3149   [(set_attr "type" "fp")
3150    (set_attr "length" "3")])
3151
3152 ;; ??? Ideally, these are what we would like to use.
3153
3154 (define_insn "fix_truncsfdi2_v9"
3155   [(set (match_operand:DI 0 "register_operand" "=e")
3156         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3157   "0 && TARGET_V9 && TARGET_FPU"
3158   "fstox %1,%0"
3159   [(set_attr "type" "fp")])
3160
3161 (define_insn "fix_truncdfdi2_v9"
3162   [(set (match_operand:DI 0 "register_operand" "=e")
3163         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3164   "0 && TARGET_V9 && TARGET_FPU"
3165   "fdtox %1,%0"
3166   [(set_attr "type" "fp")])
3167
3168 (define_insn "fix_trunctfdi2_v9"
3169   [(set (match_operand:DI 0 "register_operand" "=e")
3170         (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3171   "0 && TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3172   "fqtox %1,%0"
3173   [(set_attr "type" "fp")])
3174 \f
3175 ;;- arithmetic instructions
3176
3177 (define_expand "adddi3"
3178   [(set (match_operand:DI 0 "register_operand" "=r")
3179         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3180                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
3181   ""
3182   "
3183 {
3184   if (! TARGET_V9)
3185     {
3186       emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3187                           gen_rtx (SET, VOIDmode, operands[0],
3188                                    gen_rtx (PLUS, DImode, operands[1],
3189                                                   operands[2])),
3190                           gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3191       DONE;
3192     }
3193 }")
3194
3195 (define_insn ""
3196   [(set (match_operand:DI 0 "register_operand" "=r")
3197         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3198                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3199    (clobber (reg:SI 0))]
3200   "! TARGET_V9"
3201   "*
3202 {
3203   rtx op2 = operands[2];
3204
3205   /* If constant is positive, upper bits zeroed, otherwise unchanged.
3206      Give the assembler a chance to pick the move instruction. */
3207   if (GET_CODE (op2) == CONST_INT)
3208     {
3209       int sign = INTVAL (op2);
3210       if (sign < 0)
3211         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
3212       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
3213     }
3214   else if (GET_CODE (op2) == CONST_DOUBLE)
3215     {
3216       rtx xoperands[4];
3217       xoperands[0] = operands[0];
3218       xoperands[1] = operands[1];
3219       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3220       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3221       if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3222         output_asm_insn (\"add %1,%3,%0\", xoperands);
3223       else
3224         output_asm_insn (\"addcc %R1,%2,%R0\;addx %1,%3,%0\", xoperands);
3225       return \"\";
3226     }
3227   return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
3228 }"
3229   [(set_attr "length" "2")])
3230
3231 (define_insn ""
3232   [(set (match_operand:DI 0 "register_operand" "=r")
3233         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3234                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
3235   "TARGET_V9"
3236   "add %1,%2,%0")
3237
3238 (define_insn "addsi3"
3239   [(set (match_operand:SI 0 "register_operand" "=r")
3240         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3241                  (match_operand:SI 2 "arith_operand" "rI")))]
3242   ""
3243   "add %1,%2,%0"
3244   [(set_attr "type" "ialu")])
3245
3246 (define_insn ""
3247   [(set (reg:CC_NOOV 0)
3248         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3249                                   (match_operand:SI 1 "arith_operand" "rI"))
3250                          (const_int 0)))]
3251   ""
3252   "addcc %0,%1,%%g0"
3253   [(set_attr "type" "compare")])
3254
3255 (define_insn ""
3256   [(set (reg:CCX_NOOV 0)
3257         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
3258                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
3259                           (const_int 0)))]
3260   "TARGET_V9"
3261   "addcc %0,%1,%%g0"
3262   [(set_attr "type" "compare")])
3263
3264 (define_insn ""
3265   [(set (reg:CC_NOOV 0)
3266         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3267                                   (match_operand:SI 2 "arith_operand" "rI"))
3268                          (const_int 0)))
3269    (set (match_operand:SI 0 "register_operand" "=r")
3270         (plus:SI (match_dup 1) (match_dup 2)))]
3271   ""
3272   "addcc %1,%2,%0")
3273
3274 (define_insn ""
3275   [(set (reg:CCX_NOOV 0)
3276         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3277                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
3278                           (const_int 0)))
3279    (set (match_operand:DI 0 "register_operand" "=r")
3280         (plus:DI (match_dup 1) (match_dup 2)))]
3281   "TARGET_V9"
3282   "addcc %1,%2,%0")
3283
3284 (define_expand "subdi3"
3285   [(set (match_operand:DI 0 "register_operand" "=r")
3286         (minus:DI (match_operand:DI 1 "register_operand" "r")
3287                   (match_operand:DI 2 "arith_double_operand" "rHI")))]
3288   ""
3289   "
3290 {
3291   if (! TARGET_V9)
3292     {
3293       emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3294                           gen_rtx (SET, VOIDmode, operands[0],
3295                                    gen_rtx (MINUS, DImode, operands[1],
3296                                                    operands[2])),
3297                           gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
3298       DONE;
3299     }
3300 }")
3301
3302 (define_insn ""
3303   [(set (match_operand:DI 0 "register_operand" "=r")
3304         (minus:DI (match_operand:DI 1 "register_operand" "r")
3305                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3306    (clobber (reg:SI 0))]
3307   "! TARGET_V9"
3308   "*
3309 {
3310   rtx op2 = operands[2];
3311
3312   /* If constant is positive, upper bits zeroed, otherwise unchanged.
3313      Give the assembler a chance to pick the move instruction. */
3314   if (GET_CODE (op2) == CONST_INT)
3315     {
3316       int sign = INTVAL (op2);
3317       if (sign < 0)
3318         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
3319       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
3320     }
3321   else if (GET_CODE (op2) == CONST_DOUBLE)
3322     {
3323       rtx xoperands[4];
3324       xoperands[0] = operands[0];
3325       xoperands[1] = operands[1];
3326       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3327       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3328       if (xoperands[2] == const0_rtx && xoperands[0] == xoperands[1])
3329         output_asm_insn (\"sub %1,%3,%0\", xoperands);
3330       else
3331         output_asm_insn (\"subcc %R1,%2,%R0\;subx %1,%3,%0\", xoperands);
3332       return \"\";
3333     }
3334   return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
3335 }"
3336   [(set_attr "length" "2")])
3337
3338 (define_insn ""
3339   [(set (match_operand:DI 0 "register_operand" "=r")
3340         (minus:DI (match_operand:DI 1 "register_operand" "r")
3341                   (match_operand:DI 2 "arith_double_operand" "rHI")))]
3342   "TARGET_V9"
3343   "sub %1,%2,%0")
3344
3345 (define_insn "subsi3"
3346   [(set (match_operand:SI 0 "register_operand" "=r")
3347         (minus:SI (match_operand:SI 1 "register_operand" "r")
3348                   (match_operand:SI 2 "arith_operand" "rI")))]
3349   ""
3350   "sub %1,%2,%0"
3351   [(set_attr "type" "ialu")])
3352
3353 (define_insn ""
3354   [(set (reg:CC_NOOV 0)
3355         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
3356                                    (match_operand:SI 1 "arith_operand" "rI"))
3357                          (const_int 0)))]
3358   ""
3359   "subcc %0,%1,%%g0"
3360   [(set_attr "type" "compare")])
3361
3362 (define_insn ""
3363   [(set (reg:CCX_NOOV 0)
3364         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3365                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
3366                           (const_int 0)))]
3367   "TARGET_V9"
3368   "subcc %0,%1,%%g0"
3369   [(set_attr "type" "compare")])
3370
3371 (define_insn ""
3372   [(set (reg:CC_NOOV 0)
3373         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
3374                                    (match_operand:SI 2 "arith_operand" "rI"))
3375                          (const_int 0)))
3376    (set (match_operand:SI 0 "register_operand" "=r")
3377         (minus:SI (match_dup 1) (match_dup 2)))]
3378   ""
3379   "subcc %1,%2,%0")
3380
3381 (define_insn ""
3382   [(set (reg:CCX_NOOV 0)
3383         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3384                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
3385                           (const_int 0)))
3386    (set (match_operand:DI 0 "register_operand" "=r")
3387         (minus:DI (match_dup 1) (match_dup 2)))]
3388   "TARGET_V9"
3389   "subcc %1,%2,%0")
3390
3391 ;; This is anachronistic, and should not be used in v9 software.
3392 ;; The v9 compiler will widen the args and use muldi3.
3393
3394 (define_insn "mulsi3"
3395   [(set (match_operand:SI 0 "register_operand" "=r")
3396         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3397                  (match_operand:SI 2 "arith_operand" "rI")))]
3398   "TARGET_V8 || TARGET_SPARCLITE"
3399   "smul %1,%2,%0"
3400   [(set_attr "type" "imul")])
3401
3402 (define_insn "muldi3"
3403   [(set (match_operand:DI 0 "register_operand" "=r")
3404         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
3405                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
3406   "TARGET_V9"
3407   "mulx %1,%2,%0")
3408
3409 ;; It is not known whether this will match.
3410
3411 (define_insn ""
3412   [(set (match_operand:SI 0 "register_operand" "=r")
3413         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3414                  (match_operand:SI 2 "arith_operand" "rI")))
3415    (set (reg:CC_NOOV 0)
3416         (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
3417                          (const_int 0)))]
3418   "TARGET_V8 || TARGET_SPARCLITE"
3419   "smulcc %1,%2,%0"
3420   [(set_attr "type" "imul")])
3421
3422 (define_expand "mulsidi3"
3423   [(set (match_operand:DI 0 "register_operand" "")
3424         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3425                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3426   "TARGET_V8 || TARGET_SPARCLITE"
3427   "
3428 {
3429   if (CONSTANT_P (operands[2]))
3430     {
3431       emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
3432       DONE;
3433     }
3434 }")
3435
3436 (define_insn ""
3437   [(set (match_operand:DI 0 "register_operand" "=r")
3438         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3439                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3440   "TARGET_V8 || TARGET_SPARCLITE"
3441   "smul %1,%2,%R0\;rd %%y,%0"
3442   [(set_attr "length" "2")])
3443
3444 ;; Extra pattern, because sign_extend of a constant isn't valid.
3445
3446 (define_insn "const_mulsidi3"
3447   [(set (match_operand:DI 0 "register_operand" "=r")
3448         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3449                  (match_operand:SI 2 "small_int" "I")))]
3450   "TARGET_V8 || TARGET_SPARCLITE"
3451   "smul %1,%2,%R0\;rd %%y,%0"
3452   [(set_attr "length" "2")])
3453
3454 (define_expand "smulsi3_highpart"
3455   [(set (match_operand:SI 0 "register_operand" "")
3456         (truncate:SI
3457          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3458                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
3459                       (const_int 32))))]
3460   "TARGET_V8 || TARGET_SPARCLITE"
3461   "
3462 {
3463   if (CONSTANT_P (operands[2]))
3464     {
3465       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
3466       DONE;
3467     }
3468 }")
3469
3470 (define_insn ""
3471   [(set (match_operand:SI 0 "register_operand" "=r")
3472         (truncate:SI
3473          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3474                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
3475                       (const_int 32))))]
3476   "TARGET_V8 || TARGET_SPARCLITE"
3477   "smul %1,%2,%%g0\;rd %%y,%0"
3478   [(set_attr "length" "2")])
3479
3480 (define_insn "const_smulsi3_highpart"
3481   [(set (match_operand:SI 0 "register_operand" "=r")
3482         (truncate:SI
3483          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3484                                (match_operand:SI 2 "register_operand" "r"))
3485                       (const_int 32))))]
3486   "TARGET_V8 || TARGET_SPARCLITE"
3487   "smul %1,%2,%%g0\;rd %%y,%0"
3488   [(set_attr "length" "2")])
3489
3490 (define_expand "umulsidi3"
3491   [(set (match_operand:DI 0 "register_operand" "")
3492         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3493                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
3494   "TARGET_V8 || TARGET_SPARCLITE"
3495   "
3496 {
3497   if (CONSTANT_P (operands[2]))
3498     {
3499       emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
3500       DONE;
3501     }
3502 }")
3503
3504 (define_insn ""
3505   [(set (match_operand:DI 0 "register_operand" "=r")
3506         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3507                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3508   "TARGET_V8 || TARGET_SPARCLITE"
3509   "umul %1,%2,%R0\;rd %%y,%0"
3510   [(set_attr "length" "2")])
3511
3512 ;; Extra pattern, because sign_extend of a constant isn't valid.
3513
3514 (define_insn "const_umulsidi3"
3515   [(set (match_operand:DI 0 "register_operand" "=r")
3516         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3517                  (match_operand:SI 2 "uns_small_int" "")))]
3518   "TARGET_V8 || TARGET_SPARCLITE"
3519   "umul %1,%2,%R0\;rd %%y,%0"
3520   [(set_attr "length" "2")])
3521
3522 (define_expand "umulsi3_highpart"
3523   [(set (match_operand:SI 0 "register_operand" "")
3524         (truncate:SI
3525          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
3526                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
3527                       (const_int 32))))]
3528   "TARGET_V8 || TARGET_SPARCLITE"
3529   "
3530 {
3531   if (CONSTANT_P (operands[2]))
3532     {
3533       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
3534       DONE;
3535     }
3536 }")
3537
3538 (define_insn ""
3539   [(set (match_operand:SI 0 "register_operand" "=r")
3540         (truncate:SI
3541          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3542                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
3543                       (const_int 32))))]
3544   "TARGET_V8 || TARGET_SPARCLITE"
3545   "umul %1,%2,%%g0\;rd %%y,%0"
3546   [(set_attr "length" "2")])
3547
3548 (define_insn "const_umulsi3_highpart"
3549   [(set (match_operand:SI 0 "register_operand" "=r")
3550         (truncate:SI
3551          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3552                                (match_operand:SI 2 "uns_small_int" ""))
3553                       (const_int 32))))]
3554   "TARGET_V8 || TARGET_SPARCLITE"
3555   "umul %1,%2,%%g0\;rd %%y,%0"
3556   [(set_attr "length" "2")])
3557
3558 ;; The architecture specifies that there must be 3 instructions between
3559 ;; a y register write and a use of it for correct results.
3560
3561 (define_insn "divsi3"
3562   [(set (match_operand:SI 0 "register_operand" "=r")
3563         (div:SI (match_operand:SI 1 "register_operand" "r")
3564                 (match_operand:SI 2 "arith_operand" "rI")))
3565    (clobber (match_scratch:SI 3 "=&r"))]
3566   "TARGET_V8"
3567   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
3568   [(set_attr "length" "6")])
3569
3570 (define_insn "divdi3"
3571   [(set (match_operand:DI 0 "register_operand" "=r")
3572         (div:DI (match_operand:DI 1 "register_operand" "r")
3573                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3574   "TARGET_V9"
3575   "sdivx %1,%2,%0")
3576
3577 ;; It is not known whether this will match.
3578
3579 (define_insn ""
3580   [(set (match_operand:SI 0 "register_operand" "=r")
3581         (div:SI (match_operand:SI 1 "register_operand" "r")
3582                 (match_operand:SI 2 "arith_operand" "rI")))
3583    (set (reg:CC 0)
3584         (compare:CC (div:SI (match_dup 1) (match_dup 2))
3585                     (const_int 0)))
3586    (clobber (match_scratch:SI 3 "=&r"))]
3587   "TARGET_V8"
3588   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
3589   [(set_attr "length" "6")])
3590
3591 (define_insn "udivsi3"
3592   [(set (match_operand:SI 0 "register_operand" "=r")
3593         (udiv:SI (match_operand:SI 1 "register_operand" "r")
3594                 (match_operand:SI 2 "arith_operand" "rI")))]
3595   "TARGET_V8"
3596   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
3597   [(set_attr "length" "5")])
3598
3599 (define_insn "udivdi3"
3600   [(set (match_operand:DI 0 "register_operand" "=r")
3601         (udiv:DI (match_operand:DI 1 "register_operand" "r")
3602                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
3603   "TARGET_V9"
3604   "udivx %1,%2,%0")
3605
3606 ;; It is not known whether this will match.
3607
3608 (define_insn ""
3609   [(set (match_operand:SI 0 "register_operand" "=r")
3610         (udiv:SI (match_operand:SI 1 "register_operand" "r")
3611                 (match_operand:SI 2 "arith_operand" "rI")))
3612    (set (reg:CC 0)
3613         (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
3614                     (const_int 0)))]
3615   "TARGET_V8"
3616   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
3617   [(set_attr "length" "5")])
3618 \f
3619 ;;- Boolean instructions
3620 ;; We define DImode `and` so with DImode `not` we can get
3621 ;; DImode `andn`.  Other combinations are possible.
3622
3623 (define_expand "anddi3"
3624   [(set (match_operand:DI 0 "register_operand" "")
3625         (and:DI (match_operand:DI 1 "arith_double_operand" "")
3626                 (match_operand:DI 2 "arith_double_operand" "")))]
3627   ""
3628   "")
3629
3630 (define_insn ""
3631   [(set (match_operand:DI 0 "register_operand" "=r")
3632         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3633                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3634   "! TARGET_V9"
3635   "*
3636 {
3637   rtx op2 = operands[2];
3638
3639   /* If constant is positive, upper bits zeroed, otherwise unchanged.
3640      Give the assembler a chance to pick the move instruction. */
3641   if (GET_CODE (op2) == CONST_INT)
3642     {
3643       int sign = INTVAL (op2);
3644       if (sign < 0)
3645         return \"mov %1,%0\;and %R1,%2,%R0\";
3646       return \"mov 0,%0\;and %R1,%2,%R0\";
3647     }
3648   else if (GET_CODE (op2) == CONST_DOUBLE)
3649     {
3650       rtx xoperands[4];
3651       xoperands[0] = operands[0];
3652       xoperands[1] = operands[1];
3653       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3654       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3655       /* We could optimize then operands[1] == operands[0]
3656          and either half of the constant is -1.  */
3657       output_asm_insn (\"and %R1,%2,%R0\;and %1,%3,%0\", xoperands);
3658       return \"\";
3659     }
3660   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
3661 }"
3662   [(set_attr "length" "2")])
3663
3664 (define_insn ""
3665   [(set (match_operand:DI 0 "register_operand" "=r")
3666         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
3667                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3668   "TARGET_V9"
3669   "and %1,%2,%0")
3670
3671 (define_insn "andsi3"
3672   [(set (match_operand:SI 0 "register_operand" "=r")
3673         (and:SI (match_operand:SI 1 "arith_operand" "%r")
3674                 (match_operand:SI 2 "arith_operand" "rI")))]
3675   ""
3676   "and %1,%2,%0"
3677   [(set_attr "type" "ialu")])
3678
3679 (define_split
3680   [(set (match_operand:SI 0 "register_operand" "")
3681         (and:SI (match_operand:SI 1 "register_operand" "")
3682                 (match_operand:SI 2 "" "")))
3683    (clobber (match_operand:SI 3 "register_operand" ""))]
3684   "GET_CODE (operands[2]) == CONST_INT
3685    && !SMALL_INT (operands[2])
3686    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3687   [(set (match_dup 3) (match_dup 4))
3688    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
3689   "
3690 {
3691   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3692 }")
3693
3694 (define_insn ""
3695   [(set (match_operand:DI 0 "register_operand" "=r")
3696         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3697                 (match_operand:DI 2 "register_operand" "r")))]
3698   "! TARGET_V9"
3699   "andn %2,%1,%0\;andn %R2,%R1,%R0"
3700   [(set_attr "length" "2")])
3701
3702 (define_insn ""
3703   [(set (match_operand:DI 0 "register_operand" "=r")
3704         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3705                 (match_operand:DI 2 "register_operand" "r")))]
3706   "TARGET_V9"
3707   "andn %2,%1,%0")
3708
3709 (define_insn ""
3710   [(set (match_operand:SI 0 "register_operand" "=r")
3711         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3712                 (match_operand:SI 2 "register_operand" "r")))]
3713   ""
3714   "andn %2,%1,%0"
3715   [(set_attr "type" "ialu")])
3716
3717 (define_expand "iordi3"
3718   [(set (match_operand:DI 0 "register_operand" "")
3719         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
3720                 (match_operand:DI 2 "arith_double_operand" "")))]
3721   ""
3722   "")
3723
3724 (define_insn ""
3725   [(set (match_operand:DI 0 "register_operand" "=r")
3726         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
3727                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3728   "! TARGET_V9"
3729   "*
3730 {
3731   rtx op2 = operands[2];
3732
3733   /* If constant is positive, upper bits zeroed, otherwise unchanged.
3734      Give the assembler a chance to pick the move instruction. */
3735   if (GET_CODE (op2) == CONST_INT)
3736     {
3737       int sign = INTVAL (op2);
3738       if (sign < 0)
3739         return \"mov -1,%0\;or %R1,%2,%R0\";
3740       return \"mov %1,%0\;or %R1,%2,%R0\";
3741     }
3742   else if (GET_CODE (op2) == CONST_DOUBLE)
3743     {
3744       rtx xoperands[4];
3745       xoperands[0] = operands[0];
3746       xoperands[1] = operands[1];
3747       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3748       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3749       /* We could optimize then operands[1] == operands[0]
3750          and either half of the constant is 0.  */
3751       output_asm_insn (\"or %R1,%2,%R0\;or %1,%3,%0\", xoperands);
3752       return \"\";
3753     }
3754   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
3755 }"
3756   [(set_attr "length" "2")])
3757
3758 (define_insn ""
3759   [(set (match_operand:DI 0 "register_operand" "=r")
3760         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
3761                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3762   "TARGET_V9"
3763   "or %1,%2,%0")
3764
3765 (define_insn "iorsi3"
3766   [(set (match_operand:SI 0 "register_operand" "=r")
3767         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
3768                 (match_operand:SI 2 "arith_operand" "rI")))]
3769   ""
3770   "or %1,%2,%0"
3771   [(set_attr "type" "ialu")])
3772
3773 (define_split
3774   [(set (match_operand:SI 0 "register_operand" "")
3775         (ior:SI (match_operand:SI 1 "register_operand" "")
3776                 (match_operand:SI 2 "" "")))
3777    (clobber (match_operand:SI 3 "register_operand" ""))]
3778   "GET_CODE (operands[2]) == CONST_INT
3779    && !SMALL_INT (operands[2])
3780    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3781   [(set (match_dup 3) (match_dup 4))
3782    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
3783   "
3784 {
3785   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3786 }")
3787
3788 (define_insn ""
3789   [(set (match_operand:DI 0 "register_operand" "=r")
3790         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3791                 (match_operand:DI 2 "register_operand" "r")))]
3792   "! TARGET_V9"
3793   "orn %2,%1,%0\;orn %R2,%R1,%R0"
3794   [(set_attr "length" "2")])
3795
3796 (define_insn ""
3797   [(set (match_operand:DI 0 "register_operand" "=r")
3798         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
3799                 (match_operand:DI 2 "register_operand" "r")))]
3800   "TARGET_V9"
3801   "orn %2,%1,%0")
3802
3803 (define_insn ""
3804   [(set (match_operand:SI 0 "register_operand" "=r")
3805         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3806                 (match_operand:SI 2 "register_operand" "r")))]
3807   ""
3808   "orn %2,%1,%0"
3809   [(set_attr "type" "ialu")])
3810
3811 (define_expand "xordi3"
3812   [(set (match_operand:DI 0 "register_operand" "")
3813         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
3814                 (match_operand:DI 2 "arith_double_operand" "")))]
3815   ""
3816   "")
3817
3818 (define_insn ""
3819   [(set (match_operand:DI 0 "register_operand" "=r")
3820         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
3821                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3822   "! TARGET_V9"
3823   "*
3824 {
3825   rtx op2 = operands[2];
3826
3827   /* If constant is positive, upper bits zeroed, otherwise unchanged.
3828      Give the assembler a chance to pick the move instruction. */
3829   if (GET_CODE (op2) == CONST_INT)
3830     {
3831       int sign = INTVAL (op2);
3832       if (sign < 0)
3833         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
3834       return \"mov %1,%0\;xor %R1,%2,%R0\";
3835     }
3836   else if (GET_CODE (op2) == CONST_DOUBLE)
3837     {
3838       rtx xoperands[4];
3839       xoperands[0] = operands[0];
3840       xoperands[1] = operands[1];
3841       xoperands[2] = GEN_INT (CONST_DOUBLE_LOW (op2));
3842       xoperands[3] = GEN_INT (CONST_DOUBLE_HIGH (op2));
3843       /* We could optimize then operands[1] == operands[0]
3844          and either half of the constant is 0.  */
3845       output_asm_insn (\"xor %R1,%2,%R0\;xor %1,%3,%0\", xoperands);
3846       return \"\";
3847     }
3848   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
3849 }"
3850   [(set_attr "length" "2")])
3851
3852 (define_insn ""
3853   [(set (match_operand:DI 0 "register_operand" "=r")
3854         (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ")
3855                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3856   "TARGET_V9"
3857   "xor %r1,%2,%0")
3858
3859 (define_insn "xorsi3"
3860   [(set (match_operand:SI 0 "register_operand" "=r")
3861         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
3862                 (match_operand:SI 2 "arith_operand" "rI")))]
3863   ""
3864   "xor %r1,%2,%0"
3865   [(set_attr "type" "ialu")])
3866
3867 (define_split
3868   [(set (match_operand:SI 0 "register_operand" "")
3869         (xor:SI (match_operand:SI 1 "register_operand" "")
3870                 (match_operand:SI 2 "" "")))
3871    (clobber (match_operand:SI 3 "register_operand" ""))]
3872   "GET_CODE (operands[2]) == CONST_INT
3873    && !SMALL_INT (operands[2])
3874    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3875   [(set (match_dup 3) (match_dup 4))
3876    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
3877   "
3878 {
3879   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3880 }")
3881
3882 (define_split
3883   [(set (match_operand:SI 0 "register_operand" "")
3884         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
3885                         (match_operand:SI 2 "" ""))))
3886    (clobber (match_operand:SI 3 "register_operand" ""))]
3887   "GET_CODE (operands[2]) == CONST_INT
3888    && !SMALL_INT (operands[2])
3889    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
3890   [(set (match_dup 3) (match_dup 4))
3891    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
3892   "
3893 {
3894   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
3895 }")
3896
3897 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
3898 ;; Combine now canonicalizes to the rightmost expression.
3899 (define_insn ""
3900   [(set (match_operand:DI 0 "register_operand" "=r")
3901         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
3902                         (match_operand:DI 2 "register_operand" "r"))))]
3903   "! TARGET_V9"
3904   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
3905   [(set_attr "length" "2")])
3906
3907 (define_insn ""
3908   [(set (match_operand:DI 0 "register_operand" "=r")
3909         (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3910                         (match_operand:DI 2 "arith_double_operand" "rHI"))))]
3911   "TARGET_V9"
3912   "xnor %r1,%2,%0")
3913
3914 (define_insn ""
3915   [(set (match_operand:SI 0 "register_operand" "=r")
3916         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3917                         (match_operand:SI 2 "arith_operand" "rI"))))]
3918   ""
3919   "xnor %r1,%2,%0"
3920   [(set_attr "type" "ialu")])
3921
3922 ;; These correspond to the above in the case where we also (or only)
3923 ;; want to set the condition code.  
3924
3925 (define_insn ""
3926   [(set (reg:CC 0)
3927         (compare:CC
3928          (match_operator:SI 2 "cc_arithop"
3929                             [(match_operand:SI 0 "arith_operand" "%r")
3930                              (match_operand:SI 1 "arith_operand" "rI")])
3931          (const_int 0)))]
3932   ""
3933   "%A2cc %0,%1,%%g0"
3934   [(set_attr "type" "compare")])
3935
3936 (define_insn ""
3937   [(set (reg:CCX 0)
3938         (compare:CCX
3939          (match_operator:DI 2 "cc_arithop"
3940                             [(match_operand:DI 0 "arith_double_operand" "%r")
3941                              (match_operand:DI 1 "arith_double_operand" "rHI")])
3942          (const_int 0)))]
3943   "TARGET_V9"
3944   "%A2cc %0,%1,%%g0"
3945   [(set_attr "type" "compare")])
3946
3947 (define_insn ""
3948   [(set (reg:CC 0)
3949         (compare:CC
3950          (match_operator:SI 3 "cc_arithop"
3951                             [(match_operand:SI 1 "arith_operand" "%r")
3952                              (match_operand:SI 2 "arith_operand" "rI")])
3953          (const_int 0)))
3954    (set (match_operand:SI 0 "register_operand" "=r")
3955         (match_dup 3))]
3956   ""
3957   "%A3cc %1,%2,%0")
3958
3959 (define_insn ""
3960   [(set (reg:CCX 0)
3961         (compare:CCX
3962          (match_operator:DI 3 "cc_arithop"
3963                             [(match_operand:DI 1 "arith_double_operand" "%r")
3964                              (match_operand:DI 2 "arith_double_operand" "rHI")])
3965          (const_int 0)))
3966    (set (match_operand:DI 0 "register_operand" "=r")
3967         (match_dup 3))]
3968   "TARGET_V9"
3969   "%A3cc %1,%2,%0")
3970
3971 (define_insn ""
3972   [(set (reg:CC 0)
3973         (compare:CC
3974          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
3975                          (match_operand:SI 1 "arith_operand" "rI")))
3976          (const_int 0)))]
3977   ""
3978   "xnorcc %r0,%1,%%g0"
3979   [(set_attr "type" "compare")])
3980
3981 (define_insn ""
3982   [(set (reg:CCX 0)
3983         (compare:CCX
3984          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
3985                          (match_operand:DI 1 "arith_double_operand" "rHI")))
3986          (const_int 0)))]
3987   "TARGET_V9"
3988   "xnorcc %r0,%1,%%g0"
3989   [(set_attr "type" "compare")])
3990
3991 (define_insn ""
3992   [(set (reg:CC 0)
3993         (compare:CC
3994          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
3995                          (match_operand:SI 2 "arith_operand" "rI")))
3996          (const_int 0)))
3997    (set (match_operand:SI 0 "register_operand" "=r")
3998         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
3999   ""
4000   "xnorcc %r1,%2,%0")
4001
4002 (define_insn ""
4003   [(set (reg:CCX 0)
4004         (compare:CCX
4005          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
4006                          (match_operand:DI 2 "arith_double_operand" "rHI")))
4007          (const_int 0)))
4008    (set (match_operand:DI 0 "register_operand" "=r")
4009         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4010   "TARGET_V9"
4011   "xnorcc %r1,%2,%0")
4012
4013 (define_insn ""
4014   [(set (reg:CC 0)
4015         (compare:CC
4016          (match_operator:SI 2 "cc_arithopn"
4017                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4018                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
4019          (const_int 0)))]
4020   ""
4021   "%B2cc %r1,%0,%%g0"
4022   [(set_attr "type" "compare")])
4023
4024 (define_insn ""
4025   [(set (reg:CCX 0)
4026         (compare:CCX
4027          (match_operator:DI 2 "cc_arithopn"
4028                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4029                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
4030          (const_int 0)))]
4031   "TARGET_V9"
4032   "%B2cc %r1,%0,%%g0"
4033   [(set_attr "type" "compare")])
4034
4035 (define_insn ""
4036   [(set (reg:CC 0)
4037         (compare:CC
4038          (match_operator:SI 3 "cc_arithopn"
4039                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4040                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
4041          (const_int 0)))
4042    (set (match_operand:SI 0 "register_operand" "=r")
4043         (match_dup 3))]
4044   ""
4045   "%B3cc %r2,%1,%0")
4046
4047 (define_insn ""
4048   [(set (reg:CCX 0)
4049         (compare:CCX
4050          (match_operator:DI 3 "cc_arithopn"
4051                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4052                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
4053          (const_int 0)))
4054    (set (match_operand:DI 0 "register_operand" "=r")
4055         (match_dup 3))]
4056   "TARGET_V9"
4057   "%B3cc %r2,%1,%0")
4058
4059 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4060 ;; does not know how to make it work for constants.
4061
4062 (define_expand "negdi2"
4063   [(set (match_operand:DI 0 "register_operand" "=r")
4064         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4065   ""
4066   "
4067 {
4068   if (! TARGET_V9)
4069     {
4070       emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4071                           gen_rtx (SET, VOIDmode, operand0,
4072                                    gen_rtx (NEG, DImode, operand1)),
4073                           gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0)))));
4074       DONE;
4075     }
4076 }")
4077
4078 (define_insn ""
4079   [(set (match_operand:DI 0 "register_operand" "=r")
4080         (neg:DI (match_operand:DI 1 "register_operand" "r")))
4081    (clobber (reg:SI 0))]
4082   "! TARGET_V9"
4083   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
4084   [(set_attr "type" "unary")
4085    (set_attr "length" "2")])
4086
4087 (define_insn ""
4088   [(set (match_operand:DI 0 "register_operand" "=r")
4089         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4090   "TARGET_V9"
4091   "sub %%g0,%1,%0"
4092   [(set_attr "type" "unary")
4093    (set_attr "length" "1")])
4094
4095 (define_insn "negsi2"
4096   [(set (match_operand:SI 0 "register_operand" "=r")
4097         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
4098   ""
4099   "sub %%g0,%1,%0"
4100   [(set_attr "type" "unary")])
4101
4102 (define_insn ""
4103   [(set (reg:CC_NOOV 0)
4104         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
4105                          (const_int 0)))]
4106   ""
4107   "subcc %%g0,%0,%%g0"
4108   [(set_attr "type" "compare")])
4109
4110 (define_insn ""
4111   [(set (reg:CCX_NOOV 0)
4112         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4113                           (const_int 0)))]
4114   "TARGET_V9"
4115   "subcc %%g0,%0,%%g0"
4116   [(set_attr "type" "compare")])
4117
4118 (define_insn ""
4119   [(set (reg:CC_NOOV 0)
4120         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
4121                          (const_int 0)))
4122    (set (match_operand:SI 0 "register_operand" "=r")
4123         (neg:SI (match_dup 1)))]
4124   ""
4125   "subcc %%g0,%1,%0"
4126   [(set_attr "type" "unary")])
4127
4128 (define_insn ""
4129   [(set (reg:CCX_NOOV 0)
4130         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4131                           (const_int 0)))
4132    (set (match_operand:DI 0 "register_operand" "=r")
4133         (neg:DI (match_dup 1)))]
4134   "TARGET_V9"
4135   "subcc %%g0,%1,%0"
4136   [(set_attr "type" "unary")])
4137
4138 ;; We cannot use the "not" pseudo insn because the Sun assembler
4139 ;; does not know how to make it work for constants.
4140 (define_expand "one_cmpldi2"
4141   [(set (match_operand:DI 0 "register_operand" "")
4142         (not:DI (match_operand:DI 1 "register_operand" "")))]
4143   ""
4144   "")
4145
4146 (define_insn ""
4147   [(set (match_operand:DI 0 "register_operand" "=r")
4148         (not:DI (match_operand:DI 1 "register_operand" "r")))]
4149   "! TARGET_V9"
4150   "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0"
4151   [(set_attr "type" "unary")
4152    (set_attr "length" "2")])
4153
4154 (define_insn ""
4155   [(set (match_operand:DI 0 "register_operand" "=r")
4156         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
4157   "TARGET_V9"
4158   "xnor %%g0,%1,%0"
4159   [(set_attr "type" "unary")])
4160
4161 (define_insn "one_cmplsi2"
4162   [(set (match_operand:SI 0 "register_operand" "=r")
4163         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
4164   ""
4165   "xnor %%g0,%1,%0"
4166   [(set_attr "type" "unary")])
4167
4168 (define_insn ""
4169   [(set (reg:CC 0)
4170         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
4171                     (const_int 0)))]
4172   ""
4173   "xnorcc %%g0,%0,%%g0"
4174   [(set_attr "type" "compare")])
4175
4176 (define_insn ""
4177   [(set (reg:CCX 0)
4178         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4179                      (const_int 0)))]
4180   "TARGET_V9"
4181   "xnorcc %%g0,%0,%%g0"
4182   [(set_attr "type" "compare")])
4183
4184 (define_insn ""
4185   [(set (reg:CC 0)
4186         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
4187                     (const_int 0)))
4188    (set (match_operand:SI 0 "register_operand" "=r")
4189         (not:SI (match_dup 1)))]
4190   ""
4191   "xnorcc %%g0,%1,%0"
4192   [(set_attr "type" "unary")])
4193
4194 (define_insn ""
4195   [(set (reg:CCX 0)
4196         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4197                     (const_int 0)))
4198    (set (match_operand:DI 0 "register_operand" "=r")
4199         (not:DI (match_dup 1)))]
4200   "TARGET_V9"
4201   "xnorcc %%g0,%1,%0"
4202   [(set_attr "type" "unary")])
4203 \f
4204 ;; Floating point arithmetic instructions.
4205
4206 (define_insn "addtf3"
4207   [(set (match_operand:TF 0 "register_operand" "=e")
4208         (plus:TF (match_operand:TF 1 "register_operand" "e")
4209                  (match_operand:TF 2 "register_operand" "e")))]
4210   "TARGET_FPU && TARGET_HARD_QUAD"
4211   "faddq %1,%2,%0"
4212   [(set_attr "type" "fp")])
4213
4214 (define_insn "adddf3"
4215   [(set (match_operand:DF 0 "register_operand" "=e")
4216         (plus:DF (match_operand:DF 1 "register_operand" "e")
4217                  (match_operand:DF 2 "register_operand" "e")))]
4218   "TARGET_FPU"
4219   "faddd %1,%2,%0"
4220   [(set_attr "type" "fp")])
4221
4222 (define_insn "addsf3"
4223   [(set (match_operand:SF 0 "register_operand" "=f")
4224         (plus:SF (match_operand:SF 1 "register_operand" "f")
4225                  (match_operand:SF 2 "register_operand" "f")))]
4226   "TARGET_FPU"
4227   "fadds %1,%2,%0"
4228   [(set_attr "type" "fp")])
4229
4230 (define_insn "subtf3"
4231   [(set (match_operand:TF 0 "register_operand" "=e")
4232         (minus:TF (match_operand:TF 1 "register_operand" "e")
4233                   (match_operand:TF 2 "register_operand" "e")))]
4234   "TARGET_FPU && TARGET_HARD_QUAD"
4235   "fsubq %1,%2,%0"
4236   [(set_attr "type" "fp")])
4237
4238 (define_insn "subdf3"
4239   [(set (match_operand:DF 0 "register_operand" "=e")
4240         (minus:DF (match_operand:DF 1 "register_operand" "e")
4241                   (match_operand:DF 2 "register_operand" "e")))]
4242   "TARGET_FPU"
4243   "fsubd %1,%2,%0"
4244   [(set_attr "type" "fp")])
4245
4246 (define_insn "subsf3"
4247   [(set (match_operand:SF 0 "register_operand" "=f")
4248         (minus:SF (match_operand:SF 1 "register_operand" "f")
4249                   (match_operand:SF 2 "register_operand" "f")))]
4250   "TARGET_FPU"
4251   "fsubs %1,%2,%0"
4252   [(set_attr "type" "fp")])
4253
4254 (define_insn "multf3"
4255   [(set (match_operand:TF 0 "register_operand" "=e")
4256         (mult:TF (match_operand:TF 1 "register_operand" "e")
4257                  (match_operand:TF 2 "register_operand" "e")))]
4258   "TARGET_FPU && TARGET_HARD_QUAD"
4259   "fmulq %1,%2,%0"
4260   [(set_attr "type" "fpmul")])
4261
4262 (define_insn "muldf3"
4263   [(set (match_operand:DF 0 "register_operand" "=e")
4264         (mult:DF (match_operand:DF 1 "register_operand" "e")
4265                  (match_operand:DF 2 "register_operand" "e")))]
4266   "TARGET_FPU"
4267   "fmuld %1,%2,%0"
4268   [(set_attr "type" "fpmul")])
4269
4270 (define_insn "mulsf3"
4271   [(set (match_operand:SF 0 "register_operand" "=f")
4272         (mult:SF (match_operand:SF 1 "register_operand" "f")
4273                  (match_operand:SF 2 "register_operand" "f")))]
4274   "TARGET_FPU"
4275   "fmuls %1,%2,%0"
4276   [(set_attr "type" "fpmul")])
4277
4278 (define_insn ""
4279   [(set (match_operand:DF 0 "register_operand" "=e")
4280         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
4281                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
4282   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4283   "fsmuld %1,%2,%0"
4284   [(set_attr "type" "fpmul")])
4285
4286 (define_insn ""
4287   [(set (match_operand:TF 0 "register_operand" "=e")
4288         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
4289                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
4290   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4291   "fdmulq %1,%2,%0"
4292   [(set_attr "type" "fpmul")])
4293
4294 ;; don't have timing for quad-prec. divide.
4295 (define_insn "divtf3"
4296   [(set (match_operand:TF 0 "register_operand" "=e")
4297         (div:TF (match_operand:TF 1 "register_operand" "e")
4298                 (match_operand:TF 2 "register_operand" "e")))]
4299   "TARGET_FPU && TARGET_HARD_QUAD"
4300   "fdivq %1,%2,%0"
4301   [(set_attr "type" "fpdivd")])
4302
4303 (define_insn "divdf3"
4304   [(set (match_operand:DF 0 "register_operand" "=e")
4305         (div:DF (match_operand:DF 1 "register_operand" "e")
4306                 (match_operand:DF 2 "register_operand" "e")))]
4307   "TARGET_FPU"
4308   "fdivd %1,%2,%0"
4309   [(set_attr "type" "fpdivd")])
4310
4311 (define_insn "divsf3"
4312   [(set (match_operand:SF 0 "register_operand" "=f")
4313         (div:SF (match_operand:SF 1 "register_operand" "f")
4314                 (match_operand:SF 2 "register_operand" "f")))]
4315   "TARGET_FPU"
4316   "fdivs %1,%2,%0"
4317   [(set_attr "type" "fpdivs")])
4318
4319 (define_insn "negtf2"
4320   [(set (match_operand:TF 0 "register_operand" "=e,e")
4321         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
4322   "TARGET_FPU"
4323   "*
4324 {
4325   if (TARGET_V9)
4326     return \"fnegd %1,%0\"; /* Can't use fnegs, won't work with upper regs.  */
4327   else if (which_alternative == 0)
4328    return \"fnegs %0,%0\";
4329   else
4330    return \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4331 }"
4332   [(set_attr "type" "fp")
4333    (set_attr_alternative "length"
4334      [(const_int 1)
4335       (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
4336
4337 (define_insn "negdf2"
4338   [(set (match_operand:DF 0 "register_operand" "=e,e")
4339         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
4340   "TARGET_FPU"
4341   "*
4342 {
4343   if (TARGET_V9)
4344     return \"fnegd %1,%0\";
4345   else if (which_alternative == 0)
4346    return \"fnegs %0,%0\";
4347   else
4348    return \"fnegs %1,%0\;fmovs %R1,%R0\";
4349 }"
4350   [(set_attr "type" "fp")
4351    (set_attr_alternative "length"
4352      [(const_int 1)
4353       (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
4354
4355 (define_insn "negsf2"
4356   [(set (match_operand:SF 0 "register_operand" "=f")
4357         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
4358   "TARGET_FPU"
4359   "fnegs %1,%0"
4360   [(set_attr "type" "fp")])
4361
4362 (define_insn "abstf2"
4363   [(set (match_operand:TF 0 "register_operand" "=e,e")
4364         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
4365   "TARGET_FPU"
4366   "*
4367 {
4368   if (TARGET_V9)
4369     return \"fabsd %1,%0\"; /* Can't use fabss, won't work with upper regs.  */
4370   else if (which_alternative == 0)
4371     return \"fabss %0,%0\";
4372   else
4373     return \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
4374 }"
4375   [(set_attr "type" "fp")
4376    (set_attr_alternative "length"
4377      [(const_int 1)
4378       (if_then_else (eq_attr "arch" "arch32bit") (const_int 4) (const_int 1))])])
4379
4380 (define_insn "absdf2"
4381   [(set (match_operand:DF 0 "register_operand" "=e,e")
4382         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
4383   "TARGET_FPU"
4384   "*
4385 {
4386   if (TARGET_V9)
4387     return \"fabsd %1,%0\";
4388   else if (which_alternative == 0)
4389     return \"fabss %0,%0\";
4390   else
4391     return \"fabss %1,%0\;fmovs %R1,%R0\";
4392 }"
4393   [(set_attr "type" "fp")
4394    (set_attr_alternative "length"
4395      [(const_int 1)
4396       (if_then_else (eq_attr "arch" "arch32bit") (const_int 2) (const_int 1))])])
4397
4398 (define_insn "abssf2"
4399   [(set (match_operand:SF 0 "register_operand" "=f")
4400         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
4401   "TARGET_FPU"
4402   "fabss %1,%0"
4403   [(set_attr "type" "fp")])
4404
4405 (define_insn "sqrttf2"
4406   [(set (match_operand:TF 0 "register_operand" "=e")
4407         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
4408   "TARGET_FPU && TARGET_HARD_QUAD"
4409   "fsqrtq %1,%0"
4410   [(set_attr "type" "fpsqrt")])
4411
4412 (define_insn "sqrtdf2"
4413   [(set (match_operand:DF 0 "register_operand" "=e")
4414         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
4415   "TARGET_FPU"
4416   "fsqrtd %1,%0"
4417   [(set_attr "type" "fpsqrt")])
4418
4419 (define_insn "sqrtsf2"
4420   [(set (match_operand:SF 0 "register_operand" "=f")
4421         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
4422   "TARGET_FPU"
4423   "fsqrts %1,%0"
4424   [(set_attr "type" "fpsqrt")])
4425 \f
4426 ;;- arithmetic shift instructions
4427
4428 (define_insn "ashlsi3"
4429   [(set (match_operand:SI 0 "register_operand" "=r")
4430         (ashift:SI (match_operand:SI 1 "register_operand" "r")
4431                    (match_operand:SI 2 "arith_operand" "rI")))]
4432   ""
4433   "*
4434 {
4435   if (GET_CODE (operands[2]) == CONST_INT
4436       && (unsigned) INTVAL (operands[2]) > 31)
4437     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4438
4439   return \"sll %1,%2,%0\";
4440 }"
4441   [(set_attr "type" "shift")])
4442
4443 (define_insn "ashldi3"
4444   [(set (match_operand:DI 0 "register_operand" "=r")
4445         (ashift:DI (match_operand:DI 1 "register_operand" "r")
4446                    (match_operand:SI 2 "arith_operand" "rI")))]
4447   "TARGET_V9"
4448   "*
4449 {
4450   if (GET_CODE (operands[2]) == CONST_INT
4451       && (unsigned) INTVAL (operands[2]) > 63)
4452     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4453
4454   return \"sllx %1,%2,%0\";
4455 }")
4456
4457 (define_insn ""
4458   [(set (reg:CC_NOOV 0)
4459         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
4460                                     (const_int 1))
4461                          (const_int 0)))]
4462   ""
4463   "addcc %0,%0,%%g0"
4464   [(set_attr "type" "compare")])
4465
4466 (define_insn ""
4467   [(set (reg:CC_NOOV 0)
4468         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
4469                                     (const_int 1))
4470                          (const_int 0)))
4471    (set (match_operand:SI 0 "register_operand" "=r")
4472         (ashift:SI (match_dup 1) (const_int 1)))]
4473   ""
4474   "addcc %1,%1,%0")
4475
4476 (define_insn "ashrsi3"
4477   [(set (match_operand:SI 0 "register_operand" "=r")
4478         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
4479                      (match_operand:SI 2 "arith_operand" "rI")))]
4480   ""
4481   "*
4482 {
4483   if (GET_CODE (operands[2]) == CONST_INT
4484       && (unsigned) INTVAL (operands[2]) > 31)
4485     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4486
4487   return \"sra %1,%2,%0\";
4488 }"
4489   [(set_attr "type" "shift")])
4490
4491 (define_insn "ashrdi3"
4492   [(set (match_operand:DI 0 "register_operand" "=r")
4493         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
4494                      (match_operand:SI 2 "arith_operand" "rI")))]
4495   "TARGET_V9"
4496   "*
4497 {
4498   if (GET_CODE (operands[2]) == CONST_INT
4499       && (unsigned) INTVAL (operands[2]) > 63)
4500     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4501
4502   return \"srax %1,%2,%0\";
4503 }")
4504
4505 (define_insn "lshrsi3"
4506   [(set (match_operand:SI 0 "register_operand" "=r")
4507         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
4508                      (match_operand:SI 2 "arith_operand" "rI")))]
4509   ""
4510   "*
4511 {
4512   if (GET_CODE (operands[2]) == CONST_INT
4513       && (unsigned) INTVAL (operands[2]) > 31)
4514     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
4515
4516   return \"srl %1,%2,%0\";
4517 }"
4518   [(set_attr "type" "shift")])
4519
4520 (define_insn "lshrdi3"
4521   [(set (match_operand:DI 0 "register_operand" "=r")
4522         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
4523                      (match_operand:SI 2 "arith_operand" "rI")))]
4524   "TARGET_V9"
4525   "*
4526 {
4527   if (GET_CODE (operands[2]) == CONST_INT
4528       && (unsigned) INTVAL (operands[2]) > 63)
4529     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
4530
4531   return \"srlx %1,%2,%0\";
4532 }")
4533 \f
4534 ;; Unconditional and other jump instructions
4535 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
4536 ;; following insn is never executed.  This saves us a nop.  Dbx does not
4537 ;; handle such branches though, so we only use them when optimizing.
4538 (define_insn "jump"
4539   [(set (pc) (label_ref (match_operand 0 "" "")))]
4540   ""
4541   "b%* %l0%("
4542   [(set_attr "type" "uncond_branch")])
4543
4544 (define_expand "tablejump"
4545   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
4546               (use (label_ref (match_operand 1 "" "")))])]
4547   ""
4548   "
4549 {
4550   if (GET_MODE (operands[0]) != Pmode)
4551     abort ();
4552
4553   /* We need to use the PC value in %o7 that was set up when the address
4554      of the label was loaded into a register, so we need different RTL.  */
4555   if (flag_pic)
4556     {
4557       if (!TARGET_PTR64)
4558         emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1]));
4559       else
4560         emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1]));
4561       DONE;
4562     }
4563 }")
4564
4565 (define_insn "pic_tablejump_32"
4566   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
4567    (use (label_ref (match_operand 1 "" "")))
4568    (use (reg:SI 15))]
4569   "! TARGET_PTR64"
4570   "jmp %%o7+%0%#"
4571   [(set_attr "type" "uncond_branch")])
4572
4573 (define_insn "pic_tablejump_64"
4574   [(set (pc) (match_operand:DI 0 "register_operand" "r"))
4575    (use (label_ref (match_operand 1 "" "")))
4576    (use (reg:DI 15))]
4577   "TARGET_PTR64"
4578   "jmp %%o7+%0%#"
4579   [(set_attr "type" "uncond_branch")])
4580
4581 (define_insn ""
4582   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
4583    (use (label_ref (match_operand 1 "" "")))]
4584   "! TARGET_PTR64"
4585   "jmp %a0%#"
4586   [(set_attr "type" "uncond_branch")])
4587
4588 (define_insn ""
4589   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
4590    (use (label_ref (match_operand 1 "" "")))]
4591   "TARGET_PTR64"
4592   "jmp %a0%#"
4593   [(set_attr "type" "uncond_branch")])
4594
4595 (define_insn ""
4596   [(set (pc) (label_ref (match_operand 0 "" "")))
4597    (set (reg:SI 15) (label_ref (match_dup 0)))]
4598   "! TARGET_PTR64"
4599   "call %l0%#"
4600   [(set_attr "type" "uncond_branch")])
4601
4602 (define_insn ""
4603   [(set (pc) (label_ref (match_operand 0 "" "")))
4604    (set (reg:DI 15) (label_ref (match_dup 0)))]
4605   "TARGET_PTR64"
4606   "call %l0%#"
4607   [(set_attr "type" "uncond_branch")])
4608
4609 ;; This pattern recognizes the "instruction" that appears in 
4610 ;; a function call that wants a structure value, 
4611 ;; to inform the called function if compiled with Sun CC.
4612 ;(define_insn ""
4613 ;  [(match_operand:SI 0 "immediate_operand" "")]
4614 ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
4615 ;  "unimp %0"
4616 ;  [(set_attr "type" "marker")])
4617
4618 ;;- jump to subroutine
4619 (define_expand "call"
4620   ;; Note that this expression is not used for generating RTL.
4621   ;; All the RTL is generated explicitly below.
4622   [(call (match_operand 0 "call_operand" "")
4623          (match_operand 3 "" "i"))]
4624   ;; operands[2] is next_arg_register
4625   ;; operands[3] is struct_value_size_rtx.
4626   ""
4627   "
4628 {
4629   rtx fn_rtx, nregs_rtx;
4630
4631    if (GET_MODE (operands[0]) != FUNCTION_MODE)
4632     abort ();
4633
4634  if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
4635     {
4636       /* This is really a PIC sequence.  We want to represent
4637          it as a funny jump so it's delay slots can be filled. 
4638
4639          ??? But if this really *is* a CALL, will not it clobber the
4640          call-clobbered registers?  We lose this if it is a JUMP_INSN.
4641          Why cannot we have delay slots filled if it were a CALL?  */
4642
4643       if (! TARGET_V9 && INTVAL (operands[3]) != 0)
4644         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4645                                  gen_rtx (SET, VOIDmode, pc_rtx,
4646                                           XEXP (operands[0], 0)),
4647                                  operands[3],
4648                                  gen_rtx (CLOBBER, VOIDmode,
4649                                           gen_rtx (REG, Pmode, 15)))));
4650       else
4651         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4652                                  gen_rtx (SET, VOIDmode, pc_rtx,
4653                                           XEXP (operands[0], 0)),
4654                                  gen_rtx (CLOBBER, VOIDmode,
4655                                           gen_rtx (REG, Pmode, 15)))));
4656       goto finish_call;
4657     }
4658
4659   fn_rtx = operands[0];
4660
4661   /* Count the number of parameter registers being used by this call.
4662      if that argument is NULL, it means we are using them all, which
4663      means 6 on the sparc.  */
4664 #if 0
4665   if (operands[2])
4666     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
4667   else
4668     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
4669 #else
4670   nregs_rtx = const0_rtx;
4671 #endif
4672
4673   if (! TARGET_V9 && INTVAL (operands[3]) != 0)
4674     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
4675                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4676                              operands[3],
4677                              gen_rtx (CLOBBER, VOIDmode,
4678                                                gen_rtx (REG, Pmode, 15)))));
4679   else
4680     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4681                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
4682                              gen_rtx (CLOBBER, VOIDmode,
4683                                                gen_rtx (REG, Pmode, 15)))));
4684
4685  finish_call:
4686 #if 0
4687   /* If this call wants a structure value,
4688      emit an unimp insn to let the called function know about this.  */
4689   if (! TARGET_V9 && INTVAL (operands[3]) > 0)
4690     {
4691       rtx insn = emit_insn (operands[3]);
4692       SCHED_GROUP_P (insn) = 1;
4693     }
4694 #endif
4695
4696   DONE;
4697 }")
4698
4699 ;; We can't use the same pattern for these two insns, because then registers
4700 ;; in the address may not be properly reloaded.
4701
4702 (define_insn ""
4703   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4704          (match_operand 1 "" ""))
4705    (clobber (reg:SI 15))]
4706   ;;- Do not use operand 1 for most machines.
4707   "! TARGET_PTR64"
4708   "*
4709 {
4710   return \"call %a0,%1%#\";
4711 }"
4712   [(set_attr "type" "call")])
4713
4714 (define_insn ""
4715   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4716          (match_operand 1 "" ""))
4717    (clobber (reg:SI 15))]
4718   ;;- Do not use operand 1 for most machines.
4719   "! TARGET_PTR64"
4720   "*
4721 {
4722   return \"call %a0,%1%#\";
4723 }"
4724   [(set_attr "type" "call")])
4725
4726 (define_insn ""
4727   [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
4728          (match_operand 1 "" ""))
4729    (clobber (reg:DI 15))]
4730   ;;- Do not use operand 1 for most machines.
4731   "TARGET_PTR64"
4732   "*
4733 {
4734   return \"call %a0,%1%#\";
4735 }"
4736   [(set_attr "type" "call")])
4737
4738 (define_insn ""
4739   [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
4740          (match_operand 1 "" ""))
4741    (clobber (reg:DI 15))]
4742   ;;- Do not use operand 1 for most machines.
4743   "TARGET_PTR64"
4744   "*
4745 {
4746   return \"call %a0,%1%#\";
4747 }"
4748   [(set_attr "type" "call")])
4749
4750 ;; This is a call that wants a structure value.
4751 ;; There is no such critter for v9 (??? we may need one anyway).
4752 (define_insn ""
4753   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4754          (match_operand 1 "" ""))
4755    (match_operand 2 "immediate_operand" "")
4756    (clobber (reg:SI 15))]
4757   ;;- Do not use operand 1 for most machines.
4758   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
4759   "*
4760 {
4761   return \"call %a0,%1\;nop\;unimp %2\";
4762 }"
4763   [(set_attr "type" "call_no_delay_slot")])
4764
4765 ;; This is a call that wants a structure value.
4766 ;; There is no such critter for v9 (??? we may need one anyway).
4767 (define_insn ""
4768   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4769          (match_operand 1 "" ""))
4770    (match_operand 2 "immediate_operand" "")
4771    (clobber (reg:SI 15))]
4772   ;;- Do not use operand 1 for most machines.
4773   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
4774   "*
4775 {
4776   return \"call %a0,%1\;nop\;unimp %2\";
4777 }"
4778   [(set_attr "type" "call_no_delay_slot")])
4779
4780 ;; This is a call that may want a structure value.  This is used for
4781 ;; untyped_calls.
4782 (define_insn ""
4783   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
4784          (match_operand 1 "" ""))
4785    (match_operand 2 "immediate_operand" "")
4786    (clobber (reg:SI 15))]
4787   ;;- Do not use operand 1 for most machines.
4788   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
4789   "*
4790 {
4791   return \"call %a0,%1\;nop\;nop\";
4792 }"
4793   [(set_attr "type" "call_no_delay_slot")])
4794
4795 ;; This is a call that wants a structure value.
4796 (define_insn ""
4797   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
4798          (match_operand 1 "" ""))
4799    (match_operand 2 "immediate_operand" "")
4800    (clobber (reg:SI 15))]
4801   ;;- Do not use operand 1 for most machines.
4802   "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
4803   "*
4804 {
4805   return \"call %a0,%1\;nop\;nop\";
4806 }"
4807   [(set_attr "type" "call_no_delay_slot")])
4808
4809 (define_expand "call_value"
4810   ;; Note that this expression is not used for generating RTL.
4811   ;; All the RTL is generated explicitly below.
4812   [(set (match_operand 0 "register_operand" "=rf")
4813         (call (match_operand:SI 1 "" "")
4814               (match_operand 4 "" "")))]
4815   ;; operand 2 is stack_size_rtx
4816   ;; operand 3 is next_arg_register
4817   ""
4818   "
4819 {
4820   rtx fn_rtx, nregs_rtx;
4821   rtvec vec;
4822
4823   if (GET_MODE (operands[1]) != FUNCTION_MODE)
4824     abort ();
4825
4826   fn_rtx = operands[1];
4827
4828 #if 0
4829   if (operands[3])
4830     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
4831   else
4832     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
4833 #else
4834   nregs_rtx = const0_rtx;
4835 #endif
4836
4837   vec = gen_rtvec (2,
4838                    gen_rtx (SET, VOIDmode, operands[0],
4839                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
4840                    gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15)));
4841
4842   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
4843
4844   DONE;
4845 }")
4846
4847 (define_insn ""
4848   [(set (match_operand 0 "" "=rf")
4849         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
4850               (match_operand 2 "" "")))
4851    (clobber (reg:SI 15))]
4852   ;;- Do not use operand 2 for most machines.
4853   "! TARGET_PTR64"
4854   "*
4855 {
4856   return \"call %a1,%2%#\";
4857 }"
4858   [(set_attr "type" "call")])
4859
4860 (define_insn ""
4861   [(set (match_operand 0 "" "=rf")
4862         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
4863               (match_operand 2 "" "")))
4864    (clobber (reg:SI 15))]
4865   ;;- Do not use operand 2 for most machines.
4866   "! TARGET_PTR64"
4867   "*
4868 {
4869   return \"call %a1,%2%#\";
4870 }"
4871   [(set_attr "type" "call")])
4872
4873 (define_insn ""
4874   [(set (match_operand 0 "" "=rf")
4875         (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
4876               (match_operand 2 "" "")))
4877    (clobber (reg:DI 15))]
4878   ;;- Do not use operand 2 for most machines.
4879   "TARGET_PTR64"
4880   "*
4881 {
4882   return \"call %a1,%2%#\";
4883 }"
4884   [(set_attr "type" "call")])
4885
4886 (define_insn ""
4887   [(set (match_operand 0 "" "=rf")
4888         (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
4889               (match_operand 2 "" "")))
4890    (clobber (reg:DI 15))]
4891   ;;- Do not use operand 2 for most machines.
4892   "TARGET_PTR64"
4893   "*
4894 {
4895   return \"call %a1,%2%#\";
4896 }"
4897   [(set_attr "type" "call")])
4898
4899 (define_expand "untyped_call"
4900   [(parallel [(call (match_operand 0 "" "")
4901                     (const_int 0))
4902               (match_operand 1 "" "")
4903               (match_operand 2 "" "")])]
4904   ""
4905   "
4906 {
4907   int i;
4908
4909   /* Pass constm1 to indicate that it may expect a structure value, but
4910      we don't know what size it is.  */
4911   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
4912
4913   for (i = 0; i < XVECLEN (operands[2], 0); i++)
4914     {
4915       rtx set = XVECEXP (operands[2], 0, i);
4916       emit_move_insn (SET_DEST (set), SET_SRC (set));
4917     }
4918
4919   /* The optimizer does not know that the call sets the function value
4920      registers we stored in the result block.  We avoid problems by
4921      claiming that all hard registers are used and clobbered at this
4922      point.  */
4923   emit_insn (gen_blockage ());
4924
4925   DONE;
4926 }")
4927
4928 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4929 ;; all of memory.  This blocks insns from being moved across this point.
4930
4931 (define_insn "blockage"
4932   [(unspec_volatile [(const_int 0)] 0)]
4933   ""
4934   "")
4935
4936 ;; Prepare to return any type including a structure value.
4937
4938 (define_expand "untyped_return"
4939   [(match_operand:BLK 0 "memory_operand" "")
4940    (match_operand 1 "" "")]
4941   ""
4942   "
4943 {
4944   rtx valreg1 = gen_rtx (REG, DImode, 24);
4945   rtx valreg2 = gen_rtx (REG, TARGET_V9 ? TFmode : DFmode, 32);
4946   rtx result = operands[0];
4947
4948   if (! TARGET_V9)
4949     {
4950       rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
4951       rtx value = gen_reg_rtx (SImode);
4952
4953       /* Fetch the instruction where we will return to and see if it's an unimp
4954          instruction (the most significant 10 bits will be zero).  If so,
4955          update the return address to skip the unimp instruction.  */
4956       emit_move_insn (value,
4957                       gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
4958       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
4959       emit_insn (gen_update_return (rtnreg, value));
4960     }
4961
4962   /* Reload the function value registers.  */
4963   emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
4964   emit_move_insn (valreg2,
4965                   change_address (result, TARGET_V9 ? TFmode : DFmode,
4966                                   plus_constant (XEXP (result, 0), 8)));
4967
4968   /* Put USE insns before the return.  */
4969   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
4970   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
4971
4972   /* Construct the return.  */
4973   expand_null_return ();
4974
4975   DONE;
4976 }")
4977
4978 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
4979 ;; and parts of the compiler don't want to believe that the add is needed.
4980
4981 (define_insn "update_return"
4982   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
4983                (match_operand:SI 1 "register_operand" "r")] 0)]
4984   "! TARGET_V9"
4985   "cmp %1,0\;be,a .+8\;add %0,4,%0"
4986   [(set_attr "type" "multi")])
4987 \f
4988 (define_insn "return"
4989   [(return)]
4990   "! TARGET_EPILOGUE"
4991   "* return output_return (operands);"
4992   [(set_attr "type" "multi")])
4993
4994 (define_insn "nop"
4995   [(const_int 0)]
4996   ""
4997   "nop")
4998
4999 (define_expand "indirect_jump"
5000   [(set (pc) (match_operand 0 "address_operand" "p"))]
5001   ""
5002   "")
5003
5004 (define_insn ""
5005   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
5006   "! TARGET_PTR64"
5007  "jmp %a0%#"
5008  [(set_attr "type" "uncond_branch")])
5009  
5010 (define_insn ""
5011   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
5012   "TARGET_PTR64"
5013   "jmp %a0%#"
5014   [(set_attr "type" "uncond_branch")])
5015
5016 ;; ??? This doesn't handle v9 yet.  It also doesn't work with -mflat.
5017 (define_expand "nonlocal_goto"
5018   [(match_operand:SI 0 "general_operand" "")
5019    (match_operand:SI 1 "general_operand" "")
5020    (match_operand:SI 2 "general_operand" "")
5021    (match_operand:SI 3 "" "")]
5022   ""
5023   "
5024 {
5025   /* Trap instruction to flush all the register windows.  */
5026   emit_insn (gen_flush_register_windows ());
5027   /* Load the fp value for the containing fn into %fp.
5028      This is needed because operands[2] refers to %fp.
5029      Virtual register instantiation fails if the virtual %fp isn't set from a
5030      register.  Thus we must copy operands[0] into a register if it isn't
5031      already one.  */
5032   if (GET_CODE (operands[0]) != REG)
5033     operands[0] = force_reg (SImode, operands[0]);
5034   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
5035   /* Find the containing function's current nonlocal goto handler,
5036      which will do any cleanups and then jump to the label.  */
5037   emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
5038   /* Restore %fp from stack pointer value for containing function.
5039      The restore insn that follows will move this to %sp,
5040      and reload the appropriate value into %fp.  */
5041   emit_move_insn (frame_pointer_rtx, operands[2]);
5042   /* Put in the static chain register the nonlocal label address.  */
5043   emit_move_insn (static_chain_rtx, operands[3]);
5044   /* USE of frame_pointer_rtx added for consistency; not clear if
5045      really needed.  */
5046   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
5047   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
5048   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
5049   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
5050   /* Return, restoring reg window and jumping to goto handler.  */
5051   emit_insn (gen_goto_handler_and_restore ());
5052   DONE;
5053 }")
5054
5055 ;; Special trap insn to flush register windows.
5056 (define_insn "flush_register_windows"
5057   [(unspec_volatile [(const_int 0)] 1)]
5058   ""
5059   "* return TARGET_V9 ? \"flushw\" : \"ta 3\";"
5060   [(set_attr "type" "misc")])
5061
5062 (define_insn "goto_handler_and_restore"
5063   [(unspec_volatile [(const_int 0)] 2)]
5064   ""
5065   "jmp %%o0+0\;restore"
5066   [(set_attr "type" "misc")
5067    (set_attr "length" "2")])
5068
5069 ;; Special pattern for the FLUSH instruction.
5070
5071 (define_insn "flush"
5072   [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)]
5073   ""
5074   "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
5075   [(set_attr "type" "misc")])
5076 \f
5077 ;; find first set.
5078
5079 ;; The scan instruction searches from the most significant bit while ffs
5080 ;; searches from the least significant bit.  The bit index and treatment of
5081 ;; zero also differ.  It takes at least 7 instructions to get the proper
5082 ;; result.  Here is an obvious 8 instruction seequence.
5083
5084 (define_insn "ffssi2"
5085   [(set (match_operand:SI 0 "register_operand" "=&r")
5086         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
5087    (clobber (match_scratch:SI 2 "=&r"))]
5088   "TARGET_SPARCLITE"
5089   "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0"
5090   [(set_attr "type" "multi")
5091    (set_attr "length" "8")])
5092
5093 ;; ??? This should be a define expand, so that the extra instruction have
5094 ;; a chance of being optimized away.
5095
5096 (define_insn "ffsdi2"
5097   [(set (match_operand:DI 0 "register_operand" "=&r")
5098         (ffs:DI (match_operand:DI 1 "register_operand" "r")))
5099    (clobber (match_scratch:DI 2 "=&r"))]
5100   "TARGET_V9"
5101   "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0"
5102   [(set_attr "type" "multi")
5103    (set_attr "length" "5")])
5104 \f
5105 ;; Split up troublesome insns for better scheduling.  */
5106
5107 ;; The following patterns are straightforward.  They can be applied
5108 ;; either before or after register allocation.
5109
5110 (define_split
5111   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
5112         (match_operand 2 "reg_or_0_operand" ""))
5113    (clobber (match_operand:SI 3 "register_operand" ""))]
5114   "! flag_pic"
5115   [(set (match_dup 3) (high:SI (match_dup 1)))
5116    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
5117         (match_dup 2))]
5118   "")
5119
5120 (define_split
5121   [(set (match_operator 0 "memop"
5122                         [(match_operand:SI 1 "immediate_operand" "")])
5123         (match_operand 2 "general_operand" ""))
5124    (clobber (match_operand:SI 3 "register_operand" ""))]
5125   "flag_pic"
5126   [(set (match_op_dup 0 [(match_dup 1)])
5127         (match_dup 2))]
5128   "
5129 {
5130   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
5131                                         operands[3]);
5132 }")
5133
5134 (define_split
5135   [(set (match_operand 0 "register_operand" "")
5136         (match_operator 1 "memop"
5137                         [(match_operand:SI 2 "immediate_operand" "")]))]
5138   "flag_pic"
5139   [(set (match_dup 0)
5140         (match_op_dup 1 [(match_dup 2)]))]
5141   "
5142 {
5143   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
5144                                         operands[0]);
5145 }")
5146
5147 ;; Sign- and Zero-extend operations can have symbolic memory operands.
5148
5149 (define_split
5150   [(set (match_operand 0 "register_operand" "")
5151         (match_operator 1 "extend_op"
5152                         [(match_operator 2 "memop"
5153                                          [(match_operand:SI 3 "immediate_operand" "")])]))]
5154   "flag_pic"
5155   [(set (match_dup 0)
5156         (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
5157   "
5158 {
5159   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
5160                                         operands[0]);
5161 }")
5162
5163 (define_split
5164   [(set (match_operand:SI 0 "register_operand" "")
5165         (match_operand:SI 1 "immediate_operand" ""))]
5166   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5167                   || GET_CODE (operands[1]) == CONST
5168                   || GET_CODE (operands[1]) == LABEL_REF)"
5169   [(set (match_dup 0) (high:SI (match_dup 1)))
5170    (set (match_dup 0)
5171         (lo_sum:SI (match_dup 0) (match_dup 1)))]
5172   "")
5173
5174 ;; LABEL_REFs are not modified by `legitimize_pic_address`
5175 ;; so do not recurse infinitely in the PIC case.
5176 (define_split
5177   [(set (match_operand:SI 0 "register_operand" "")
5178         (match_operand:SI 1 "immediate_operand" ""))]
5179   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5180                 || GET_CODE (operands[1]) == CONST)"
5181   [(set (match_dup 0) (match_dup 1))]
5182   "
5183 {
5184   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
5185 }")
5186 \f
5187 ;; These split sne/seq insns.  The forms of the resulting insns are 
5188 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
5189 ;; Nothing will look at these in detail after splitting has occurred.
5190
5191 ;; ??? v9 DImode versions are missing because addc and subc use %icc.
5192
5193 (define_split
5194   [(set (match_operand:SI 0 "register_operand" "")
5195         (ne:SI (match_operand:SI 1 "register_operand" "")
5196                (const_int 0)))
5197    (clobber (reg:CC 0))]
5198   ""
5199   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5200                                          (const_int 0)))
5201    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
5202   "")
5203
5204 (define_split
5205   [(set (match_operand:SI 0 "register_operand" "")
5206         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5207                        (const_int 0))))
5208    (clobber (reg:CC 0))]
5209   ""
5210   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5211                                          (const_int 0)))
5212    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
5213   "")
5214
5215 (define_split
5216   [(set (match_operand:SI 0 "register_operand" "")
5217         (eq:SI (match_operand:SI 1 "register_operand" "")
5218                (const_int 0)))
5219    (clobber (reg:CC 0))]
5220   ""
5221   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5222                                          (const_int 0)))
5223    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
5224   "")
5225
5226 (define_split
5227   [(set (match_operand:SI 0 "register_operand" "")
5228         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5229                        (const_int 0))))
5230    (clobber (reg:CC 0))]
5231   ""
5232   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5233                                          (const_int 0)))
5234    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
5235   "")
5236
5237 (define_split
5238   [(set (match_operand:SI 0 "register_operand" "")
5239         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5240                         (const_int 0))
5241                  (match_operand:SI 2 "register_operand" "")))
5242    (clobber (reg:CC 0))]
5243   ""
5244   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5245                                          (const_int 0)))
5246    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
5247                                (match_dup 2)))]
5248   "")
5249
5250 (define_split
5251   [(set (match_operand:SI 0 "register_operand" "")
5252         (minus:SI (match_operand:SI 2 "register_operand" "")
5253                   (ne:SI (match_operand:SI 1 "register_operand" "")
5254                          (const_int 0))))
5255    (clobber (reg:CC 0))]
5256   ""
5257   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5258                                          (const_int 0)))
5259    (set (match_dup 0) (minus:SI (match_dup 2)
5260                                 (ltu:SI (reg:CC 0) (const_int 0))))]
5261   "")
5262
5263 (define_split
5264   [(set (match_operand:SI 0 "register_operand" "")
5265         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5266                         (const_int 0))
5267                  (match_operand:SI 2 "register_operand" "")))
5268    (clobber (reg:CC 0))]
5269   ""
5270   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5271                                          (const_int 0)))
5272    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
5273                                (match_dup 2)))]
5274   "")
5275
5276 (define_split
5277   [(set (match_operand:SI 0 "register_operand" "")
5278         (minus:SI (match_operand:SI 2 "register_operand" "")
5279                   (eq:SI (match_operand:SI 1 "register_operand" "")
5280                          (const_int 0))))
5281    (clobber (reg:CC 0))]
5282   ""
5283   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
5284                                          (const_int 0)))
5285    (set (match_dup 0) (minus:SI (match_dup 2)
5286                                 (geu:SI (reg:CC 0) (const_int 0))))]
5287   "")
5288 \f
5289 ;; Peepholes go at the end.
5290
5291 ;; Optimize consecutive loads or stores into ldd and std when possible.
5292 ;; The conditions in which we do this are very restricted and are 
5293 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
5294
5295 (define_peephole
5296   [(set (match_operand:SI 0 "register_operand" "=rf")
5297         (match_operand:SI 1 "memory_operand" ""))
5298    (set (match_operand:SI 2 "register_operand" "=rf")
5299         (match_operand:SI 3 "memory_operand" ""))]
5300   "! TARGET_V9
5301    && registers_ok_for_ldd_peep (operands[0], operands[2]) 
5302    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5303    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
5304   "ldd %1,%0")
5305
5306 (define_peephole
5307   [(set (match_operand:SI 0 "memory_operand" "")
5308         (match_operand:SI 1 "register_operand" "rf"))
5309    (set (match_operand:SI 2 "memory_operand" "")
5310         (match_operand:SI 3 "register_operand" "rf"))]
5311   "! TARGET_V9
5312    && registers_ok_for_ldd_peep (operands[1], operands[3]) 
5313    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5314    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5315   "std %1,%0")
5316  
5317 (define_peephole
5318   [(set (match_operand:SF 0 "register_operand" "=fr")
5319         (match_operand:SF 1 "memory_operand" ""))
5320    (set (match_operand:SF 2 "register_operand" "=fr")
5321         (match_operand:SF 3 "memory_operand" ""))]
5322   "! TARGET_V9
5323    && registers_ok_for_ldd_peep (operands[0], operands[2]) 
5324    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
5325    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
5326   "ldd %1,%0")
5327
5328 (define_peephole
5329   [(set (match_operand:SF 0 "memory_operand" "")
5330         (match_operand:SF 1 "register_operand" "fr"))
5331    (set (match_operand:SF 2 "memory_operand" "")
5332         (match_operand:SF 3 "register_operand" "fr"))]
5333   "! TARGET_V9
5334    && registers_ok_for_ldd_peep (operands[1], operands[3]) 
5335    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
5336    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
5337   "std %1,%0")
5338
5339 (define_peephole
5340   [(set (match_operand:SI 0 "register_operand" "=rf")
5341         (match_operand:SI 1 "memory_operand" ""))
5342    (set (match_operand:SI 2 "register_operand" "=rf")
5343         (match_operand:SI 3 "memory_operand" ""))]
5344   "! TARGET_V9
5345    && registers_ok_for_ldd_peep (operands[2], operands[0]) 
5346    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5347    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5348   "ldd %3,%2")
5349
5350 (define_peephole
5351   [(set (match_operand:SI 0 "memory_operand" "")
5352         (match_operand:SI 1 "register_operand" "rf"))
5353    (set (match_operand:SI 2 "memory_operand" "")
5354         (match_operand:SI 3 "register_operand" "rf"))]
5355   "! TARGET_V9
5356    && registers_ok_for_ldd_peep (operands[3], operands[1]) 
5357    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5358    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
5359   "std %3,%2")
5360  
5361 (define_peephole
5362   [(set (match_operand:SF 0 "register_operand" "=fr")
5363         (match_operand:SF 1 "memory_operand" ""))
5364    (set (match_operand:SF 2 "register_operand" "=fr")
5365         (match_operand:SF 3 "memory_operand" ""))]
5366   "! TARGET_V9
5367    && registers_ok_for_ldd_peep (operands[2], operands[0]) 
5368    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
5369    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
5370   "ldd %3,%2")
5371
5372 (define_peephole
5373   [(set (match_operand:SF 0 "memory_operand" "")
5374         (match_operand:SF 1 "register_operand" "fr"))
5375    (set (match_operand:SF 2 "memory_operand" "")
5376         (match_operand:SF 3 "register_operand" "fr"))]
5377   "! TARGET_V9
5378    && registers_ok_for_ldd_peep (operands[3], operands[1]) 
5379    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
5380    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
5381   "std %3,%2")
5382  
5383 ;; Optimize the case of following a reg-reg move with a test
5384 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
5385 ;; This can result from a float to fix conversion.
5386
5387 (define_peephole
5388   [(set (match_operand:SI 0 "register_operand" "=r")
5389         (match_operand:SI 1 "register_operand" "r"))
5390    (set (reg:CC 0)
5391         (compare:CC (match_operand:SI 2 "register_operand" "r")
5392                     (const_int 0)))]
5393   "(rtx_equal_p (operands[2], operands[0])
5394     || rtx_equal_p (operands[2], operands[1]))
5395    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5396   "orcc %1,%%g0,%0")
5397
5398 (define_peephole
5399   [(set (match_operand:DI 0 "register_operand" "=r")
5400         (match_operand:DI 1 "register_operand" "r"))
5401    (set (reg:CCX 0)
5402         (compare:CCX (match_operand:DI 2 "register_operand" "r")
5403                     (const_int 0)))]
5404   "TARGET_V9
5405    && (rtx_equal_p (operands[2], operands[0])
5406        || rtx_equal_p (operands[2], operands[1]))
5407    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
5408   "orcc %1,%%g0,%0")
5409
5410 ;; Do {sign,zero}-extended compares somewhat more efficiently.
5411 ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
5412 ;;     eventually have some impact here?
5413
5414 (define_peephole
5415   [(set (match_operand:HI 0 "register_operand" "")
5416         (match_operand:HI 1 "memory_operand" ""))
5417    (set (match_operand:SI 2 "register_operand" "")
5418         (sign_extend:SI (match_dup 0)))
5419    (set (reg:CC 0)
5420         (compare:CC (match_dup 2)
5421                     (const_int 0)))]
5422   ""
5423   "ldsh %1,%0\;orcc %0,%%g0,%2")
5424
5425 (define_peephole
5426   [(set (match_operand:HI 0 "register_operand" "")
5427         (match_operand:HI 1 "memory_operand" ""))
5428    (set (match_operand:DI 2 "register_operand" "")
5429         (sign_extend:DI (match_dup 0)))
5430    (set (reg:CCX 0)
5431         (compare:CCX (match_dup 2)
5432                      (const_int 0)))]
5433   "TARGET_V9"
5434   "ldsh %1,%0\;orcc %0,%%g0,%2")
5435
5436 (define_peephole
5437   [(set (match_operand:QI 0 "register_operand" "")
5438         (match_operand:QI 1 "memory_operand" ""))
5439    (set (match_operand:SI 2 "register_operand" "")
5440         (sign_extend:SI (match_dup 0)))
5441    (set (reg:CC 0)
5442         (compare:CC (match_dup 2)
5443                     (const_int 0)))]
5444   ""
5445   "ldsb %1,%0\;orcc %0,%%g0,%2")
5446
5447 (define_peephole
5448   [(set (match_operand:QI 0 "register_operand" "")
5449         (match_operand:QI 1 "memory_operand" ""))
5450    (set (match_operand:DI 2 "register_operand" "")
5451         (sign_extend:DI (match_dup 0)))
5452    (set (reg:CCX 0)
5453         (compare:CCX (match_dup 2)
5454                      (const_int 0)))]
5455   "TARGET_V9"
5456   "ldsb %1,%0\;orcc %0,%%g0,%2")
5457
5458 (define_peephole
5459   [(set (match_operand:HI 0 "register_operand" "")
5460         (match_operand:HI 1 "memory_operand" ""))
5461    (set (match_operand:SI 2 "register_operand" "")
5462         (sign_extend:SI (match_dup 0)))]
5463   "dead_or_set_p (insn, operands[0])"
5464   "*
5465 {
5466   warning (\"bad peephole\");
5467   if (! MEM_VOLATILE_P (operands[1]))
5468     abort ();
5469   return \"ldsh %1,%2\";
5470 }")
5471
5472 (define_peephole
5473   [(set (match_operand:QI 0 "register_operand" "")
5474         (match_operand:QI 1 "memory_operand" ""))
5475    (set (match_operand:SI 2 "register_operand" "")
5476         (sign_extend:SI (match_dup 0)))]
5477   "dead_or_set_p (insn, operands[0])"
5478   "*
5479 {
5480   warning (\"bad peephole\");
5481   if (! MEM_VOLATILE_P (operands[1]))
5482     abort ();
5483   return \"ldsb %1,%2\";
5484 }")
5485
5486 ;; Floating-point move peepholes
5487 ;; ??? v9: Do we want similar ones?
5488
5489 (define_peephole
5490   [(set (match_operand:SI 0 "register_operand" "=r")
5491         (lo_sum:SI (match_dup 0)
5492                    (match_operand:SI 1 "immediate_operand" "i")))
5493    (set (match_operand:DF 2 "register_operand" "=er")
5494         (mem:DF (match_dup 0)))]
5495   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5496   "*
5497 {
5498   /* Go by way of output_move_double in case the register in operand 2
5499      is not properly aligned for ldd.  */
5500   operands[1] = gen_rtx (MEM, DFmode,
5501                          gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
5502   operands[0] = operands[2];
5503   return output_move_double (operands);
5504 }")
5505
5506 (define_peephole
5507   [(set (match_operand:SI 0 "register_operand" "=r")
5508         (lo_sum:SI (match_dup 0)
5509                    (match_operand:SI 1 "immediate_operand" "i")))
5510    (set (match_operand:SF 2 "register_operand" "=fr")
5511         (mem:SF (match_dup 0)))]
5512   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
5513   "ld [%0+%%lo(%a1)],%2")
5514
5515 ;; Return peepholes.  First the "normal" ones
5516
5517 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
5518 ;; It might be possible to write one more general pattern instead of three.
5519
5520 (define_insn ""
5521   [(set (match_operand:QI 0 "restore_operand" "")
5522         (match_operand:QI 1 "arith_operand" "rI"))
5523    (return)]
5524   "! TARGET_EPILOGUE"
5525   "*
5526 {
5527   if (! TARGET_V9 && current_function_returns_struct)
5528     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5529   else
5530     return \"ret\;restore %%g0,%1,%Y0\";
5531 }"
5532   [(set_attr "type" "multi")])
5533
5534 (define_insn ""
5535   [(set (match_operand:HI 0 "restore_operand" "")
5536         (match_operand:HI 1 "arith_operand" "rI"))
5537    (return)]
5538   "! TARGET_EPILOGUE"
5539   "*
5540 {
5541   if (! TARGET_V9 && current_function_returns_struct)
5542     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5543   else
5544     return \"ret\;restore %%g0,%1,%Y0\";
5545 }"
5546   [(set_attr "type" "multi")])
5547
5548 (define_insn ""
5549   [(set (match_operand:SI 0 "restore_operand" "")
5550         (match_operand:SI 1 "arith_operand" "rI"))
5551    (return)]
5552   "! TARGET_EPILOGUE"
5553   "*
5554 {
5555   if (! TARGET_V9 && current_function_returns_struct)
5556     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5557   else
5558     return \"ret\;restore %%g0,%1,%Y0\";
5559 }"
5560   [(set_attr "type" "multi")])
5561
5562 ;; The following pattern is only generated by delayed-branch scheduling,
5563 ;; when the insn winds up in the epilogue.  This can only happen when
5564 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
5565 (define_insn ""
5566   [(set (match_operand:SF 0 "restore_operand" "r")
5567         (match_operand:SF 1 "register_operand" "r"))
5568    (return)]
5569   "! TARGET_FPU && ! TARGET_EPILOGUE"
5570   "*
5571 {
5572   if (! TARGET_V9 && current_function_returns_struct)
5573     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
5574   else
5575     return \"ret\;restore %%g0,%1,%Y0\";
5576 }"
5577   [(set_attr "type" "multi")])
5578
5579 (define_insn ""
5580   [(set (match_operand:SI 0 "restore_operand" "")
5581         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5582                  (match_operand:SI 2 "arith_operand" "rI")))
5583    (return)]
5584   "! TARGET_EPILOGUE"
5585   "*
5586 {
5587   if (! TARGET_V9 && current_function_returns_struct)
5588     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
5589   else
5590     return \"ret\;restore %r1,%2,%Y0\";
5591 }"
5592   [(set_attr "type" "multi")])
5593
5594 (define_insn ""
5595   [(set (match_operand:DI 0 "restore_operand" "")
5596         (match_operand:DI 1 "arith_double_operand" "rHI"))
5597    (return)]
5598   "TARGET_V9 && ! TARGET_EPILOGUE"
5599   "ret\;restore %%g0,%1,%Y0"
5600   [(set_attr "type" "multi")])
5601
5602 (define_insn ""
5603   [(set (match_operand:DI 0 "restore_operand" "")
5604         (plus:DI (match_operand:DI 1 "arith_operand" "%r")
5605                  (match_operand:DI 2 "arith_double_operand" "rHI")))
5606    (return)]
5607   "TARGET_V9 && ! TARGET_EPILOGUE"
5608   "ret\;restore %r1,%2,%Y0"
5609   [(set_attr "type" "multi")])
5610
5611 ;; Turned off because it should never match (subtracting a constant
5612 ;; is turned into addition) and because it would do the wrong thing
5613 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
5614 ;;(define_insn ""
5615 ;;  [(set (match_operand:SI 0 "restore_operand" "")
5616 ;;      (minus:SI (match_operand:SI 1 "register_operand" "r")
5617 ;;                (match_operand:SI 2 "small_int" "I")))
5618 ;;   (return)]
5619 ;;  "! TARGET_EPILOGUE"
5620 ;;  "ret\;restore %1,-(%2),%Y0"
5621 ;;  [(set_attr "type" "multi")])
5622
5623 ;; The following pattern is only generated by delayed-branch scheduling,
5624 ;; when the insn winds up in the epilogue.
5625 (define_insn ""
5626   [(set (reg:SF 32)
5627         (match_operand:SF 0 "register_operand" "f"))
5628    (return)]
5629   "! TARGET_EPILOGUE"
5630   "ret\;fmovs %0,%%f0"
5631   [(set_attr "type" "multi")])
5632
5633 ;; Now peepholes to do a call followed by a jump.
5634
5635 (define_peephole
5636   [(parallel [(set (match_operand 0 "" "")
5637                    (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
5638                          (match_operand 2 "" "")))
5639               (clobber (reg:SI 15))])
5640    (set (pc) (label_ref (match_operand 3 "" "")))]
5641   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5642   "*
5643 {
5644   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
5645 }")
5646
5647 (define_peephole
5648   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
5649                     (match_operand 1 "" ""))
5650               (clobber (reg:SI 15))])
5651    (set (pc) (label_ref (match_operand 2 "" "")))]
5652   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5653   "*
5654 {
5655   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
5656 }")
5657
5658 (define_peephole
5659   [(parallel [(set (match_operand 0 "" "")
5660                    (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
5661                          (match_operand 2 "" "")))
5662               (clobber (reg:DI 15))])
5663    (set (pc) (label_ref (match_operand 3 "" "")))]
5664   "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
5665   "*
5666 {
5667   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
5668 }")
5669
5670 (define_peephole
5671   [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
5672                     (match_operand 1 "" ""))
5673               (clobber (reg:DI 15))])
5674    (set (pc) (label_ref (match_operand 2 "" "")))]
5675   "TARGET_V9 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
5676   "*
5677 {
5678   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
5679 }")
5680
5681 ;; Other miscellaneous peepholes.
5682
5683 (define_peephole
5684   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
5685                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5686                              (reg:SI 0)))
5687               (clobber (reg:CC 0))])
5688    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
5689   ""
5690   "subxcc %r1,0,%0")