OSDN Git Service

(zero_extendhisi2, extendhisi2, extendqihi2,
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;;   Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3 ;;   Contributed by Michael Tiemann (tiemann@cygnus.com)
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
24 ;; Insn type.  Used to default other attribute values.
25
26 ;; type "unary" insns have one input operand (1) and one output operand (0)
27 ;; type "binary" insns have two input operands (1,2) and one output (0)
28 ;; type "compare" insns have one or two input operands (0,1) and no output
29 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
30
31 (define_attr "type"
32   "move,unary,binary,compare,load,store,uncond_branch,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc"
33   (const_string "binary"))
34
35 ;; Set true if insn uses call-clobbered intermediate register.
36 (define_attr "use_clobbered" "false,true"
37   (if_then_else (and (eq_attr "type" "address")
38                      (match_operand 0 "clobbered_register" ""))
39                 (const_string "true")
40                 (const_string "false")))
41
42 ;; Length (in # of insns).
43 (define_attr "length" ""
44   (cond [(eq_attr "type" "load,fpload")
45          (if_then_else (match_operand 1 "symbolic_memory_operand" "")
46                        (const_int 2) (const_int 1))
47
48          (eq_attr "type" "store,fpstore")
49          (if_then_else (match_operand 0 "symbolic_memory_operand" "")
50                        (const_int 2) (const_int 1))
51
52          (eq_attr "type" "address") (const_int 2)
53
54          (eq_attr "type" "binary")
55          (if_then_else (ior (match_operand 2 "arith_operand" "")
56                             (match_operand 2 "arith_double_operand" ""))
57                        (const_int 1) (const_int 3))
58
59          (eq_attr "type" "multi") (const_int 2)
60
61          (eq_attr "type" "move,unary")
62          (if_then_else (ior (match_operand 1 "arith_operand" "")
63                             (match_operand 1 "arith_double_operand" ""))
64                        (const_int 1) (const_int 2))]
65
66         (const_int 1)))
67
68 (define_asm_attributes
69   [(set_attr "length" "1")
70    (set_attr "type" "multi")])
71
72 ;; Attributes for instruction and branch scheduling
73
74 (define_attr "in_call_delay" "false,true"
75   (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
76                 (const_string "false")
77          (eq_attr "type" "load,fpload,store,fpstore")
78                 (if_then_else (eq_attr "length" "1")
79                               (const_string "true")
80                               (const_string "false"))
81          (eq_attr "type" "address")
82                 (if_then_else (eq_attr "use_clobbered" "false")
83                               (const_string "true")
84                               (const_string "false"))]
85         (if_then_else (eq_attr "length" "1")
86                       (const_string "true")
87                       (const_string "false"))))
88
89 (define_delay (eq_attr "type" "call")
90   [(eq_attr "in_call_delay" "true") (nil) (nil)])
91
92 ;; ??? Should implement the notion of predelay slots for floating point
93 ;; branches.  This would allow us to remove the nop always inserted before
94 ;; a floating point branch.
95
96 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
97 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
98 ;; This is because doing so will add several pipeline stalls to the path
99 ;; that the load/store did not come from.  Unfortunately, there is no way
100 ;; to prevent fill_eager_delay_slots from using load/store without completely
101 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
102 ;; because it prevents us from moving back the final store of inner loops.
103
104 (define_attr "in_branch_delay" "false,true"
105   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
106                      (eq_attr "length" "1"))
107                 (const_string "true")
108                 (const_string "false")))
109
110 (define_attr "in_uncond_branch_delay" "false,true"
111   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
112                      (eq_attr "length" "1"))
113                 (const_string "true")
114                 (const_string "false")))
115
116 (define_attr "in_annul_branch_delay" "false,true"
117   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
118                      (eq_attr "length" "1"))
119                 (const_string "true")
120                 (const_string "false")))
121
122 (define_delay (eq_attr "type" "branch")
123   [(eq_attr "in_branch_delay" "true")
124    (nil) (eq_attr "in_annul_branch_delay" "true")])
125
126 (define_delay (eq_attr "type" "uncond_branch")
127   [(eq_attr "in_uncond_branch_delay" "true")
128    (nil) (nil)])
129    
130 ;; Function units of the SPARC
131
132 ;; (define_function_unit {name} {num-units} {n-users} {test}
133 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
134
135 ;; The integer ALU.
136 ;; (Noted only for documentation; units that take one cycle do not need to
137 ;; be specified.)
138
139 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
140 ;; the inputs.
141
142 ;; (define_function_unit "alu" 1 0
143 ;;  (eq_attr "type" "unary,binary,move,address") 1 0)
144
145 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
146 (define_function_unit "memory" 1 1 (eq_attr "type" "load,fpload") 2 0)
147
148 ;; SPARC has two floating-point units: the FP ALU,
149 ;; and the FP MUL/DIV/SQRT unit.
150 ;; Instruction timings on the CY7C602 are as follows
151 ;; FABSs        4
152 ;; FADDs/d      5/5
153 ;; FCMPs/d      4/4
154 ;; FDIVs/d      23/37
155 ;; FMOVs        4
156 ;; FMULs/d      5/7
157 ;; FNEGs        4
158 ;; FSQRTs/d     34/63
159 ;; FSUBs/d      5/5
160 ;; FdTOi/s      5/5
161 ;; FsTOi/d      5/5
162 ;; FiTOs/d      9/5
163
164 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
165 ;; More insns cause the chip to stall.
166
167 (define_function_unit "fp_alu" 1 1 (eq_attr "type" "fp") 5 0)
168 (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpmul") 7 0)
169 (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpdiv") 37 0)
170 (define_function_unit "fp_mds" 1 1 (eq_attr "type" "fpsqrt") 63 0)
171 \f
172 ;; Compare instructions.
173 ;; This controls RTL generation and register allocation.
174
175 ;; We generate RTL for comparisons and branches by having the cmpxx 
176 ;; patterns store away the operands.  Then, the scc and bcc patterns
177 ;; emit RTL for both the compare and the branch.
178 ;;
179 ;; We do this because we want to generate different code for an sne and
180 ;; seq insn.  In those cases, if the second operand of the compare is not
181 ;; const0_rtx, we want to compute the xor of the two operands and test
182 ;; it against zero.
183 ;;
184 ;; We start with the DEFINE_EXPANDs, then then DEFINE_INSNs to match
185 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
186 ;; insns that actually require more than one machine instruction.
187
188 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
189
190 (define_expand "cmpsi"
191   [(set (reg:CC 0)
192         (compare:CC (match_operand:SI 0 "register_operand" "")
193                     (match_operand:SI 1 "arith_operand" "")))]
194   ""
195   "
196 {
197   sparc_compare_op0 = operands[0];
198   sparc_compare_op1 = operands[1];
199   DONE;
200 }")
201
202 (define_expand "cmpsf"
203   [(set (reg:CCFP 0)
204         (compare:CCFP (match_operand:SF 0 "register_operand" "")
205                       (match_operand:SF 1 "register_operand" "")))]
206   "TARGET_FPU"
207   "
208 {
209   sparc_compare_op0 = operands[0];
210   sparc_compare_op1 = operands[1];
211   DONE;
212 }")
213
214 (define_expand "cmpdf"
215   [(set (reg:CCFP 0)
216         (compare:CCFP (match_operand:DF 0 "register_operand" "")
217                       (match_operand:DF 1 "register_operand" "")))]
218   "TARGET_FPU"
219   "
220 {
221   sparc_compare_op0 = operands[0];
222   sparc_compare_op1 = operands[1];
223   DONE;
224 }")
225
226 (define_expand "cmptf"
227   [(set (reg:CCFP 0)
228         (compare:CCFP (match_operand:TF 0 "register_operand" "")
229                       (match_operand:TF 1 "register_operand" "")))]
230   "TARGET_FPU"
231   "
232 {
233   sparc_compare_op0 = operands[0];
234   sparc_compare_op1 = operands[1];
235   DONE;
236 }")
237
238 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
239 ;; without jumps using the addx/subx instructions.  For the rest, we do
240 ;; branches.  Seq_special and sne_special clobber the CC reg, because they
241 ;; generate addcc/subcc instructions.
242
243 (define_expand "seq_special"
244   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
245                               (match_operand:SI 2 "register_operand" "")))
246    (parallel [(set (match_operand:SI 0 "register_operand" "")
247                    (eq:SI (match_dup 3) (const_int 0)))
248               (clobber (reg:CC 0))])]
249              
250   ""
251   "{ operands[3] = gen_reg_rtx (SImode); }")
252
253 (define_expand "sne_special"
254   [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "")
255                               (match_operand:SI 2 "register_operand" "")))
256    (parallel [(set (match_operand:SI 0 "register_operand" "")
257                    (ne:SI (match_dup 3) (const_int 0)))
258               (clobber (reg:CC 0))])]
259   ""
260   "{ operands[3] = gen_reg_rtx (SImode); }")
261
262 (define_expand "seq"
263   [(set (match_operand:SI 0 "register_operand" "")
264         (eq:SI (match_dup 1) (const_int 0)))]
265   ""
266   "
267 { if (GET_MODE (sparc_compare_op0) == SImode)
268     {
269       emit_insn (gen_seq_special (operands[0], sparc_compare_op0,
270                                   sparc_compare_op1));
271       DONE;
272     }
273   else
274     operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
275 }")
276
277 (define_expand "sne"
278   [(set (match_operand:SI 0 "register_operand" "")
279         (ne:SI (match_dup 1) (const_int 0)))]
280   ""
281   "
282 { if (GET_MODE (sparc_compare_op0) == SImode)
283     {
284       emit_insn (gen_sne_special (operands[0], sparc_compare_op0,
285                                   sparc_compare_op1));
286       DONE;
287     }
288   else
289     operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
290 }")
291
292 (define_expand "sgt"
293   [(set (match_operand:SI 0 "register_operand" "")
294         (gt:SI (match_dup 1) (const_int 0)))]
295   ""
296   "
297 { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
298
299 (define_expand "slt"
300   [(set (match_operand:SI 0 "register_operand" "")
301         (lt:SI (match_dup 1) (const_int 0)))]
302   ""
303   "
304 { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
305
306 (define_expand "sge"
307   [(set (match_operand:SI 0 "register_operand" "")
308         (ge:SI (match_dup 1) (const_int 0)))]
309   ""
310   "
311 { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
312
313 (define_expand "sle"
314   [(set (match_operand:SI 0 "register_operand" "")
315         (le:SI (match_dup 1) (const_int 0)))]
316   ""
317   "
318 { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
319
320 (define_expand "sgtu"
321   [(set (match_operand:SI 0 "register_operand" "")
322         (gtu:SI (match_dup 1) (const_int 0)))]
323   ""
324   "
325 {
326   rtx tem;
327
328   /* We can do ltu easily, so if both operands are registers, swap them and
329      do a LTU.  */
330   if ((GET_CODE (sparc_compare_op0) == REG
331        || GET_CODE (sparc_compare_op0) == SUBREG)
332       && (GET_CODE (sparc_compare_op1) == REG
333           || GET_CODE (sparc_compare_op1) == SUBREG))
334     {
335       tem = sparc_compare_op0;
336       sparc_compare_op0 = sparc_compare_op1;
337       sparc_compare_op1 = tem;
338       emit_insn (gen_sltu (operands[0]));
339       DONE;
340     }
341
342   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
343 }")
344
345 (define_expand "sltu"
346   [(set (match_operand:SI 0 "register_operand" "")
347         (ltu:SI (match_dup 1) (const_int 0)))]
348   ""
349   "
350 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
351 }")
352
353 (define_expand "sgeu"
354   [(set (match_operand:SI 0 "register_operand" "")
355         (geu:SI (match_dup 1) (const_int 0)))]
356   ""
357   "
358 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
359 }")
360
361 (define_expand "sleu"
362   [(set (match_operand:SI 0 "register_operand" "")
363         (leu:SI (match_dup 1) (const_int 0)))]
364   ""
365   "
366 {
367   rtx tem;
368
369   /* We can do geu easily, so if both operands are registers, swap them and
370      do a GEU.  */
371   if ((GET_CODE (sparc_compare_op0) == REG
372        || GET_CODE (sparc_compare_op0) == SUBREG)
373       && (GET_CODE (sparc_compare_op1) == REG
374           || GET_CODE (sparc_compare_op1) == SUBREG))
375     {
376       tem = sparc_compare_op0;
377       sparc_compare_op0 = sparc_compare_op1;
378       sparc_compare_op1 = tem;
379       emit_insn (gen_sgeu (operands[0]));
380       DONE;
381     }
382
383   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
384 }")
385
386 ;; Now the DEFINE_INSNs for the compare and scc cases.  First the compares.
387
388 (define_insn ""
389   [(set (reg:CC 0)
390         (compare:CC (match_operand:SI 0 "register_operand" "r")
391                     (match_operand:SI 1 "arith_operand" "rI")))]
392   ""
393   "cmp %r0,%1"
394   [(set_attr "type" "compare")])
395
396 (define_insn ""
397   [(set (reg:CCFPE 0)
398         (compare:CCFPE (match_operand:DF 0 "register_operand" "f")
399                        (match_operand:DF 1 "register_operand" "f")))]
400   "TARGET_FPU"
401   "fcmped %0,%1"
402   [(set_attr "type" "fpcmp")])
403
404 (define_insn ""
405   [(set (reg:CCFPE 0)
406         (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
407                        (match_operand:SF 1 "register_operand" "f")))]
408   "TARGET_FPU"
409   "fcmpes %0,%1"
410   [(set_attr "type" "fpcmp")])
411
412 (define_insn ""
413   [(set (reg:CCFPE 0)
414         (compare:CCFPE (match_operand:TF 0 "register_operand" "f")
415                        (match_operand:TF 1 "register_operand" "f")))]
416   "TARGET_FPU"
417   "fcmpeq %0,%1"
418   [(set_attr "type" "fpcmp")])
419
420 (define_insn ""
421   [(set (reg:CCFP 0)
422         (compare:CCFP (match_operand:DF 0 "register_operand" "f")
423                       (match_operand:DF 1 "register_operand" "f")))]
424   "TARGET_FPU"
425   "fcmpd %0,%1"
426   [(set_attr "type" "fpcmp")])
427
428 (define_insn ""
429   [(set (reg:CCFP 0)
430         (compare:CCFP (match_operand:SF 0 "register_operand" "f")
431                       (match_operand:SF 1 "register_operand" "f")))]
432   "TARGET_FPU"
433   "fcmps %0,%1"
434   [(set_attr "type" "fpcmp")])
435
436 (define_insn ""
437   [(set (reg:CCFP 0)
438         (compare:CCFP (match_operand:TF 0 "register_operand" "f")
439                       (match_operand:TF 1 "register_operand" "f")))]
440   "TARGET_FPU"
441   "fcmpq %0,%1"
442   [(set_attr "type" "fpcmp")])
443
444 ;; The SEQ and SNE patterns are special because they can be done
445 ;; without any branching and do not involve a COMPARE.
446
447 (define_insn ""
448   [(set (match_operand:SI 0 "register_operand" "=r")
449         (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
450    (clobber (reg:CC 0))]
451   ""
452   "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
453   [(set_attr "type" "unary")
454    (set_attr "length" "2")])
455
456 (define_insn ""
457   [(set (match_operand:SI 0 "register_operand" "=r")
458         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
459                        (const_int 0))))
460    (clobber (reg:CC 0))]
461   ""
462   "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
463   [(set_attr "type" "unary")
464    (set_attr "length" "2")])
465
466 (define_insn ""
467   [(set (match_operand:SI 0 "register_operand" "=r")
468         (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))
469    (clobber (reg:CC 0))]
470   ""
471   "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
472   [(set_attr "type" "unary")
473    (set_attr "length" "2")])
474
475 (define_insn ""
476   [(set (match_operand:SI 0 "register_operand" "=r")
477         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
478                        (const_int 0))))
479    (clobber (reg:CC 0))]
480   ""
481   "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
482   [(set_attr "type" "unary")
483    (set_attr "length" "2")])
484
485 ;; We can also do (x + (i == 0)) and related, so put them in.
486
487 (define_insn ""
488   [(set (match_operand:SI 0 "register_operand" "=r")
489         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
490                         (const_int 0))
491                  (match_operand:SI 2 "register_operand" "r")))
492    (clobber (reg:CC 0))]
493   ""
494   "subcc %%g0,%1,%%g0\;addx %2,0,%0"
495   [(set_attr "length" "2")])
496
497 (define_insn ""
498   [(set (match_operand:SI 0 "register_operand" "=r")
499         (minus:SI (match_operand:SI 2 "register_operand" "r")
500                   (ne:SI (match_operand:SI 1 "register_operand" "r")
501                          (const_int 0))))
502    (clobber (reg:CC 0))]
503   ""
504   "subcc %%g0,%1,%%g0\;subx %2,0,%0"
505   [(set_attr "length" "2")])
506
507 (define_insn ""
508   [(set (match_operand:SI 0 "register_operand" "=r")
509         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
510                         (const_int 0))
511                  (match_operand:SI 2 "register_operand" "r")))
512    (clobber (reg:CC 0))]
513   ""
514   "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
515   [(set_attr "length" "2")])
516
517 (define_insn ""
518   [(set (match_operand:SI 0 "register_operand" "=r")
519         (minus:SI (match_operand:SI 2 "register_operand" "r")
520                   (eq:SI (match_operand:SI 1 "register_operand" "r")
521                          (const_int 0))))
522    (clobber (reg:CC 0))]
523   ""
524   "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
525   [(set_attr "length" "2")])
526
527 ;; We can also do GEU and LTU directly, but these operate after a
528 ;; compare.
529
530 (define_insn ""
531   [(set (match_operand:SI 0 "register_operand" "=r")
532         (ltu:SI (reg:CC 0) (const_int 0)))]
533   ""
534   "addx %%g0,0,%0"
535   [(set_attr "type" "misc")])
536
537 (define_insn ""
538   [(set (match_operand:SI 0 "register_operand" "=r")
539         (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
540   ""
541   "subx %%g0,0,%0"
542   [(set_attr "type" "misc")])
543
544 ;; ??? Combine should canonicalize these next two to the same pattern.
545 (define_insn ""
546   [(set (match_operand:SI 0 "register_operand" "=r")
547         (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0)))
548                   (match_operand:SI 1 "arith_operand" "rI")))]
549   ""
550   "subx %%g0,%1,%0"
551   [(set_attr "type" "unary")])
552
553 (define_insn ""
554   [(set (match_operand:SI 0 "register_operand" "=r")
555         (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
556                          (match_operand:SI 1 "arith_operand" "rI"))))]
557   ""
558   "subx %%g0,%1,%0"
559   [(set_attr "type" "unary")])
560
561 (define_insn ""
562   [(set (match_operand:SI 0 "register_operand" "=r")
563         (geu:SI (reg:CC 0) (const_int 0)))]
564   ""
565   "subx %%g0,-1,%0"
566   [(set_attr "type" "misc")])
567
568 (define_insn ""
569   [(set (match_operand:SI 0 "register_operand" "=r")
570         (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
571   ""
572   "addx %%g0,-1,%0"
573   [(set_attr "type" "misc")])
574
575 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
576
577 (define_insn ""
578   [(set (match_operand:SI 0 "register_operand" "=r")
579         (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
580                  (match_operand:SI 1 "arith_operand" "rI")))]
581   ""
582   "addx %%g0,%1,%0"
583   [(set_attr "type" "unary")])
584
585 (define_insn ""
586   [(set (match_operand:SI 0 "register_operand" "=r")
587         (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
588                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
589                           (match_operand:SI 2 "arith_operand" "rI"))))]
590   ""
591   "addx %1,%2,%0")
592
593 (define_insn ""
594   [(set (match_operand:SI 0 "register_operand" "=r")
595         (minus:SI (match_operand:SI 1 "register_operand" "r")
596                   (ltu:SI (reg:CC 0) (const_int 0))))]
597   ""
598   "subx %1,0,%0"
599   [(set_attr "type" "unary")])
600
601 ;; ??? Combine should canonicalize these next two to the same pattern.
602 (define_insn ""
603   [(set (match_operand:SI 0 "register_operand" "=r")
604         (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
605                             (match_operand:SI 2 "arith_operand" "rI"))
606                   (ltu:SI (reg:CC 0) (const_int 0))))]
607   ""
608   "subx %1,%2,%0")
609
610 (define_insn ""
611   [(set (match_operand:SI 0 "register_operand" "=r")
612         (minus:SI (match_operand:SI 1 "register_operand" "r")
613                   (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
614                            (match_operand:SI 2 "arith_operand" "rI"))))]
615   ""
616   "subx %1,%2,%0")
617
618 (define_insn ""
619   [(set (match_operand:SI 0 "register_operand" "=r")
620         (plus:SI (geu:SI (reg:CC 0) (const_int 0))
621                  (match_operand:SI 1 "register_operand" "r")))]
622   ""
623   "subx %1,-1,%0"
624   [(set_attr "type" "unary")])
625
626 (define_insn ""
627   [(set (match_operand:SI 0 "register_operand" "=r")
628         (minus:SI (match_operand:SI 1 "register_operand" "r")
629                   (geu:SI (reg:CC 0) (const_int 0))))]
630   ""
631   "addx %1,-1,%0"
632   [(set_attr "type" "unary")])
633
634 ;; Now we have the generic scc insns.  These will be done using a jump.
635 ;; We have to exclude the cases above, since we will not want combine to
636 ;; turn something that does not require a jump into something that does.
637 (define_insn ""
638   [(set (match_operand:SI 0 "register_operand" "=r")
639         (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))]
640   ""
641   "* return output_scc_insn (operands, insn); "
642   [(set_attr "type" "multi")
643    (set_attr "length" "3")])
644 \f
645 ;; These control RTL generation for conditional jump insns
646
647 (define_expand "beq"
648   [(set (pc)
649         (if_then_else (eq (match_dup 1) (const_int 0))
650                       (label_ref (match_operand 0 "" ""))
651                       (pc)))]
652   ""
653   "
654 { operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
655
656 (define_expand "bne"
657   [(set (pc)
658         (if_then_else (ne (match_dup 1) (const_int 0))
659                       (label_ref (match_operand 0 "" ""))
660                       (pc)))]
661   ""
662   "
663 { operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
664
665 (define_expand "bgt"
666   [(set (pc)
667         (if_then_else (gt (match_dup 1) (const_int 0))
668                       (label_ref (match_operand 0 "" ""))
669                       (pc)))]
670   ""
671   "
672 { operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
673
674 (define_expand "bgtu"
675   [(set (pc)
676         (if_then_else (gtu (match_dup 1) (const_int 0))
677                       (label_ref (match_operand 0 "" ""))
678                       (pc)))]
679   ""
680   "
681 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
682 }")
683
684 (define_expand "blt"
685   [(set (pc)
686         (if_then_else (lt (match_dup 1) (const_int 0))
687                       (label_ref (match_operand 0 "" ""))
688                       (pc)))]
689   ""
690   "
691 { operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
692
693 (define_expand "bltu"
694   [(set (pc)
695         (if_then_else (ltu (match_dup 1) (const_int 0))
696                       (label_ref (match_operand 0 "" ""))
697                       (pc)))]
698   ""
699   "
700 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
701 }")
702
703 (define_expand "bge"
704   [(set (pc)
705         (if_then_else (ge (match_dup 1) (const_int 0))
706                       (label_ref (match_operand 0 "" ""))
707                       (pc)))]
708   ""
709   "
710 { operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
711
712 (define_expand "bgeu"
713   [(set (pc)
714         (if_then_else (geu (match_dup 1) (const_int 0))
715                       (label_ref (match_operand 0 "" ""))
716                       (pc)))]
717   ""
718   "
719 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
720 }")
721
722 (define_expand "ble"
723   [(set (pc)
724         (if_then_else (le (match_dup 1) (const_int 0))
725                       (label_ref (match_operand 0 "" ""))
726                       (pc)))]
727   ""
728   "
729 { operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
730
731 (define_expand "bleu"
732   [(set (pc)
733         (if_then_else (leu (match_dup 1) (const_int 0))
734                       (label_ref (match_operand 0 "" ""))
735                       (pc)))]
736   ""
737   "
738 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
739 }")
740 \f
741 ;; Now match both normal and inverted jump.
742
743 (define_insn ""
744   [(set (pc)
745         (if_then_else (match_operator 0 "noov_compare_op"
746                                       [(reg 0) (const_int 0)])
747                       (label_ref (match_operand 1 "" ""))
748                       (pc)))]
749   ""
750   "*
751 {
752   return output_cbranch (operands[0], 1, 0,
753                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
754                          ! final_sequence);
755 }"
756   [(set_attr "type" "branch")])
757
758 (define_insn ""
759   [(set (pc)
760         (if_then_else (match_operator 0 "noov_compare_op"
761                                       [(reg 0) (const_int 0)])
762                       (pc)
763                       (label_ref (match_operand 1 "" ""))))]
764   ""
765   "*
766 {
767   return output_cbranch (operands[0], 1, 1,
768                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
769                          ! final_sequence);
770 }"
771   [(set_attr "type" "branch")])
772 \f
773 ;; Move instructions
774
775 (define_expand "movsi"
776   [(set (match_operand:SI 0 "general_operand" "")
777         (match_operand:SI 1 "general_operand" ""))]
778   ""
779   "
780 {
781   if (emit_move_sequence (operands, SImode, NULL_RTX))
782     DONE;
783 }")
784
785 (define_expand "reload_insi"
786   [(set (match_operand:SI 0 "register_operand" "=r")
787         (match_operand:SI 1 "general_operand" ""))
788    (clobber (match_operand:SI 2 "register_operand" "=&r"))]
789   ""
790   "
791 {
792   if (emit_move_sequence (operands, SImode, operands[2]))
793     DONE;
794
795   /* We don't want the clobber emitted, so handle this ourselves.  */
796   emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
797   DONE;
798 }")
799
800 ;; We must support both 'r' and 'f' registers here, because combine may
801 ;; convert SFmode hard registers to SImode hard registers when simplifying
802 ;; subreg sets.
803
804 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
805 ;; problems with register allocation.  Reload might try to put an integer
806 ;; in an fp register, or an fp number is an integer register.
807
808 (define_insn ""
809   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
810         (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
811   "register_operand (operands[0], SImode)
812    || register_operand (operands[1], SImode)
813    || operands[1] == const0_rtx"
814   "@
815    mov %1,%0
816    fmovs %1,%0
817    sethi %%hi(%a1),%0
818    ld %1,%0
819    ld %1,%0
820    st %r1,%0
821    st %r1,%0"
822   [(set_attr "type" "move,fp,move,load,load,store,store")
823    (set_attr "length" "*,*,1,*,*,*,*")])
824
825 ;; Special pic pattern, for loading the address of a label into a register.
826 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
827 ;; there.
828
829 (define_insn ""
830   [(set (match_operand:SI 0 "register_operand" "=r")
831         (match_operand:SI 1 "move_pic_label" "i"))
832    (set (reg:SI 15) (pc))]
833   ""
834   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
835   [(set_attr "type" "multi")
836    (set_attr "length" "4")])
837
838 (define_insn ""
839   [(set (match_operand:DI 0 "register_operand" "=r")
840         (high:DI (match_operand 1 "" "")))]
841   "check_pic (1)"
842   "*
843 {
844   rtx op0 = operands[0];
845   rtx op1 = operands[1];
846
847   if (GET_CODE (op1) == CONST_INT)
848     {
849       operands[0] = operand_subword (op0, 1, 0, DImode);
850       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
851
852       operands[0] = operand_subword (op0, 0, 0, DImode);
853       if (INTVAL (op1) < 0)
854         return \"mov -1,%0\";
855       else
856         return \"mov 0,%0\";
857     }
858   else if (GET_CODE (op1) == CONST_DOUBLE)
859     {
860       operands[0] = operand_subword (op0, 1, 0, DImode);
861       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
862       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
863
864       operands[0] = operand_subword (op0, 0, 0, DImode);
865       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
866       return singlemove_string (operands);
867     }
868   else
869     abort ();
870   return \"\";
871 }"
872   [(set_attr "type" "move")
873    (set_attr "length" "2")])
874
875 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
876 ;; confuse them with real addresses.
877 (define_insn ""
878   [(set (match_operand:SI 0 "register_operand" "=r")
879         (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
880   "check_pic (1)"
881   "sethi %%hi(%a1),%0"
882   [(set_attr "type" "move")
883    (set_attr "length" "1")])
884
885 (define_insn ""
886   [(set (match_operand:SI 0 "register_operand" "=r")
887         (high:SI (match_operand 1 "" "")))]
888   "check_pic (1)"
889   "sethi %%hi(%a1),%0"
890   [(set_attr "type" "move")
891    (set_attr "length" "1")])
892
893 (define_insn ""
894   [(set (match_operand:HI 0 "register_operand" "=r")
895         (high:HI (match_operand 1 "" "")))]
896   "check_pic (1)"
897   "sethi %%hi(%a1),%0"
898   [(set_attr "type" "move")
899    (set_attr "length" "1")])
900
901 (define_insn ""
902   [(set (match_operand:DI 0 "register_operand" "=r")
903         (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
904                    (match_operand:DI 2 "immediate_operand" "in")))]
905   ""
906   "*
907 {
908   /* Don't output a 64 bit constant, since we can't trust the assembler to
909      handle it correctly.  */
910   if (GET_CODE (operands[2]) == CONST_DOUBLE)
911     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
912   return \"or %R1,%%lo(%a2),%R0\";
913 }"
914   ;; Need to set length for this arith insn because operand2
915   ;; is not an "arith_operand".
916   [(set_attr "length" "1")])
917
918 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
919 ;; confuse them with real addresses.
920 (define_insn ""
921   [(set (match_operand:SI 0 "register_operand" "=r")
922         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
923                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
924   ""
925   "or %1,%%lo(%a2),%0"
926   ;; Need to set length for this arith insn because operand2
927   ;; is not an "arith_operand".
928   [(set_attr "length" "1")])
929
930 (define_insn ""
931   [(set (match_operand:SI 0 "register_operand" "=r")
932         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
933                    (match_operand:SI 2 "immediate_operand" "in")))]
934   ""
935   "or %1,%%lo(%a2),%0"
936   ;; Need to set length for this arith insn because operand2
937   ;; is not an "arith_operand".
938   [(set_attr "length" "1")])
939
940 (define_insn ""
941   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
942         (match_operand:SI 1 "reg_or_0_operand" "rJ"))
943    (clobber (match_scratch:SI 2 "=&r"))]
944   ""
945   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
946   [(set_attr "type" "store")
947    (set_attr "length" "2")])
948
949 (define_expand "movhi"
950   [(set (match_operand:HI 0 "general_operand" "")
951         (match_operand:HI 1 "general_operand" ""))]
952   ""
953   "
954 {
955   if (emit_move_sequence (operands, HImode, NULL_RTX))
956     DONE;
957 }")
958
959 (define_insn ""
960   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
961         (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
962   "register_operand (operands[0], HImode)
963    || register_operand (operands[1], HImode)
964    || operands[1] == const0_rtx"
965   "@
966    mov %1,%0
967    sethi %%hi(%a1),%0
968    lduh %1,%0
969    sth %r1,%0"
970   [(set_attr "type" "move,move,load,store")
971    (set_attr "length" "*,1,*,1")])
972
973 (define_insn ""
974   [(set (match_operand:HI 0 "register_operand" "=r")
975         (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
976                    (match_operand 2 "immediate_operand" "in")))]
977   ""
978   "or %1,%%lo(%a2),%0"
979   [(set_attr "length" "1")])
980
981 (define_insn ""
982   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
983         (match_operand:HI 1 "reg_or_0_operand" "rJ"))
984    (clobber (match_scratch:SI 2 "=&r"))]
985   ""
986   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
987   [(set_attr "type" "store")
988    (set_attr "length" "2")])
989
990 (define_expand "movqi"
991   [(set (match_operand:QI 0 "general_operand" "")
992         (match_operand:QI 1 "general_operand" ""))]
993   ""
994   "
995 {
996   if (emit_move_sequence (operands, QImode, NULL_RTX))
997     DONE;
998 }")
999
1000 (define_insn ""
1001   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1002         (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1003   "register_operand (operands[0], QImode)
1004    || register_operand (operands[1], QImode)
1005    || operands[1] == const0_rtx"
1006   "@
1007    mov %1,%0
1008    sethi %%hi(%a1),%0
1009    ldub %1,%0
1010    stb %r1,%0"
1011   [(set_attr "type" "move,move,load,store")
1012    (set_attr "length" "*,1,*,1")])
1013
1014 (define_insn ""
1015   [(set (match_operand:QI 0 "register_operand" "=r")
1016         (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1017                               (match_operand 2 "immediate_operand" "in")) 0))]
1018   ""
1019   "or %1,%%lo(%a2),%0"
1020   [(set_attr "length" "1")])
1021
1022 (define_insn ""
1023   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
1024         (match_operand:QI 1 "reg_or_0_operand" "rJ"))
1025    (clobber (match_scratch:SI 2 "=&r"))]
1026   ""
1027   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
1028   [(set_attr "type" "store")
1029    (set_attr "length" "2")])
1030
1031 ;; ??? We get better code without it.  See output_block_move in sparc.c.
1032
1033 ;; The definition of this insn does not really explain what it does,
1034 ;; but it should suffice
1035 ;; that anything generated as this insn will be recognized as one
1036 ;; and that it will not successfully combine with anything.
1037 ;(define_expand "movstrsi"
1038 ;  [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1039 ;                  (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1040 ;             (use (match_operand:SI 2 "nonmemory_operand" ""))
1041 ;             (use (match_operand:SI 3 "immediate_operand" ""))
1042 ;             (clobber (match_dup 0))
1043 ;             (clobber (match_dup 1))
1044 ;             (clobber (match_scratch:SI 4 ""))
1045 ;             (clobber (reg:SI 0))
1046 ;             (clobber (reg:SI 1))])]
1047 ;  ""
1048 ;  "
1049 ;{
1050 ;  /* If the size isn't known, don't emit inline code.  output_block_move
1051 ;     would output code that's much slower than the library function.
1052 ;     Also don't output code for large blocks.  */
1053 ;  if (GET_CODE (operands[2]) != CONST_INT
1054 ;      || GET_CODE (operands[3]) != CONST_INT
1055 ;      || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1056 ;    FAIL;
1057 ;
1058 ;  operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1059 ;  operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1060 ;  operands[2] = force_not_mem (operands[2]);
1061 ;}")
1062
1063 ;(define_insn ""
1064 ;  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1065 ;       (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1066 ;   (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1067 ;   (use (match_operand:SI 3 "immediate_operand" "i"))
1068 ;   (clobber (match_dup 0))
1069 ;   (clobber (match_dup 1))
1070 ;   (clobber (match_scratch:SI 4 "=&r"))
1071 ;   (clobber (reg:SI 0))
1072 ;   (clobber (reg:SI 1))]
1073 ;  ""
1074 ;  "* return output_block_move (operands);"
1075 ;  [(set_attr "type" "multi")
1076 ;   (set_attr "length" "6")])
1077 \f
1078 ;; Floating point move insns
1079
1080 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1081 ;; to be reloaded by putting the constant into memory.
1082 ;; It must come before the more general movtf pattern.
1083 (define_insn ""
1084   [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1085         (match_operand:TF 1 "" "?E,m,G"))]
1086   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1087   "*
1088 {
1089   switch (which_alternative)
1090     {
1091     case 0:
1092       return output_move_quad (operands);
1093     case 1:
1094       return output_fp_move_quad (operands);
1095     case 2:
1096       operands[1] = adj_offsettable_operand (operands[0], 4);
1097       operands[2] = adj_offsettable_operand (operands[0], 8);
1098       operands[3] = adj_offsettable_operand (operands[0], 12);
1099       return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1100     }
1101 }"
1102   [(set_attr "type" "load,fpload,store")
1103    (set_attr "length" "5,5,5")])
1104
1105 (define_expand "movtf"
1106   [(set (match_operand:TF 0 "general_operand" "")
1107         (match_operand:TF 1 "general_operand" ""))]
1108   ""
1109   "
1110 {
1111   if (emit_move_sequence (operands, TFmode, NULL_RTX))
1112     DONE;
1113 }")
1114
1115 (define_insn ""
1116   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r")
1117         (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))]
1118   "TARGET_FPU
1119    && (register_operand (operands[0], TFmode)
1120        || register_operand (operands[1], TFmode))"
1121   "*
1122 {
1123   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1124     return output_fp_move_quad (operands);
1125   return output_move_quad (operands);
1126 }"
1127   [(set_attr "type" "fp,move,fpstore,store,fpload,load")
1128    (set_attr "length" "4,4,5,5,5,5")])
1129
1130 ;; Exactly the same as above, except that all `f' cases are deleted.
1131 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1132 ;; when -mno-fpu.
1133
1134 (define_insn ""
1135   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
1136         (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
1137   "! TARGET_FPU
1138    && (register_operand (operands[0], TFmode)
1139        || register_operand (operands[1], TFmode))"
1140   "*
1141 {
1142   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1143     return output_fp_move_quad (operands);
1144   return output_move_quad (operands);
1145 }"
1146   [(set_attr "type" "move,store,load")
1147    (set_attr "length" "4,5,5")])
1148
1149 (define_insn ""
1150   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1151         (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1152    (clobber (match_scratch:SI 2 "=&r,&r"))]
1153   ""
1154   "*
1155 {
1156   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1157   if (which_alternative == 0)
1158     return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1159   else
1160     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1161 }"
1162   [(set_attr "type" "store")
1163    (set_attr "length" "5")])
1164 \f
1165 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1166 ;; to be reloaded by putting the constant into memory.
1167 ;; It must come before the more general movdf pattern.
1168
1169 (define_insn ""
1170   [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1171         (match_operand:DF 1 "" "?E,m,G"))]
1172   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1173   "*
1174 {
1175   switch (which_alternative)
1176     {
1177     case 0:
1178       return output_move_double (operands);
1179     case 1:
1180       return output_fp_move_double (operands);
1181     case 2:
1182       operands[1] = adj_offsettable_operand (operands[0], 4);
1183       return \"st %%g0,%0\;st %%g0,%1\";
1184     }
1185 }"
1186   [(set_attr "type" "load,fpload,store")
1187    (set_attr "length" "3,3,3")])
1188
1189 (define_expand "movdf"
1190   [(set (match_operand:DF 0 "general_operand" "")
1191         (match_operand:DF 1 "general_operand" ""))]
1192   ""
1193   "
1194 {
1195   if (emit_move_sequence (operands, DFmode, NULL_RTX))
1196     DONE;
1197 }")
1198
1199 (define_insn ""
1200   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,r")
1201         (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))]
1202   "TARGET_FPU
1203    && (register_operand (operands[0], DFmode)
1204        || register_operand (operands[1], DFmode))"
1205   "*
1206 {
1207   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1208     return output_fp_move_double (operands);
1209   return output_move_double (operands);
1210 }"
1211   [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
1212    (set_attr "length" "1,1,2,2,3,3,3,3")])
1213
1214 ;; Exactly the same as above, except that all `f' cases are deleted.
1215 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1216 ;; when -mno-fpu.
1217
1218 (define_insn ""
1219   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
1220         (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
1221   "! TARGET_FPU
1222    && (register_operand (operands[0], DFmode)
1223        || register_operand (operands[1], DFmode))"
1224   "* return output_move_double (operands);"
1225   [(set_attr "type" "store,load,move,store,load")
1226    (set_attr "length" "1,1,2,3,3")])
1227
1228 (define_split
1229   [(set (match_operand:DF 0 "register_operand" "")
1230         (match_operand:DF 1 "register_operand" ""))]
1231   "reload_completed"
1232   [(set (match_dup 2) (match_dup 3))
1233    (set (match_dup 4) (match_dup 5))]
1234   "
1235 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1236   operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1237   operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1238   operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
1239
1240 (define_insn ""
1241   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1242         (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1243    (clobber (match_scratch:SI 2 "=&r,&r"))]
1244   ""
1245   "*
1246 {
1247   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1248   if (which_alternative == 0)
1249     return \"std %1,[%2+%%lo(%a0)]\";
1250   else
1251     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1252 }"
1253   [(set_attr "type" "store")
1254    (set_attr "length" "3")])
1255 \f
1256 ;; Double-word move insns.
1257
1258 (define_expand "movdi"
1259   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1260         (match_operand:DI 1 "general_operand" ""))]
1261   ""
1262   "
1263 {
1264   if (emit_move_sequence (operands, DImode, NULL_RTX))
1265     DONE;
1266 }")
1267
1268 (define_insn ""
1269   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,r,&r,?f,?f,?Q")
1270         (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))]
1271   "register_operand (operands[0], DImode)
1272    || register_operand (operands[1], DImode)
1273    || operands[1] == const0_rtx"
1274   "*
1275 {
1276   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1277     return output_fp_move_double (operands);
1278   return output_move_double (operands);
1279 }"
1280   [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore")
1281    (set_attr "length" "2,3,3,3,2,3,3")])
1282
1283 ;; Floating-point move insns.
1284
1285 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1286 ;; to be reloaded by putting the constant into memory.
1287 ;; It must come before the more general movsf pattern.
1288 (define_insn ""
1289   [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1290         (match_operand:SF 1 "" "?E,m,G"))]
1291   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1292   "*
1293 {
1294   switch (which_alternative)
1295     {
1296     case 0:
1297       return singlemove_string (operands);
1298     case 1:
1299       return \"ld %1,%0\";
1300     case 2:
1301       return \"st %%g0,%0\";
1302     }
1303 }"
1304   [(set_attr "type" "load,fpload,store")
1305    (set_attr "length" "2,1,1")])
1306
1307 (define_expand "movsf"
1308   [(set (match_operand:SF 0 "general_operand" "")
1309         (match_operand:SF 1 "general_operand" ""))]
1310   ""
1311   "
1312 {
1313   if (emit_move_sequence (operands, SFmode, NULL_RTX))
1314     DONE;
1315 }")
1316
1317 (define_insn ""
1318   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1319         (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1320   "TARGET_FPU
1321    && (register_operand (operands[0], SFmode)
1322        || register_operand (operands[1], SFmode))"
1323   "@
1324    fmovs %1,%0
1325    mov %1,%0
1326    ld %1,%0
1327    ld %1,%0
1328    st %r1,%0
1329    st %r1,%0"
1330   [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1331
1332 ;; Exactly the same as above, except that all `f' cases are deleted.
1333 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1334 ;; when -mno-fpu.
1335
1336 (define_insn ""
1337   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1338         (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1339   "! TARGET_FPU
1340    && (register_operand (operands[0], SFmode)
1341        || register_operand (operands[1], SFmode))"
1342   "@
1343    mov %1,%0
1344    ld %1,%0
1345    st %r1,%0"
1346   [(set_attr "type" "move,load,store")])
1347
1348 (define_insn ""
1349   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1350         (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1351    (clobber (match_scratch:SI 2 "=&r"))]
1352   ""
1353   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1354   [(set_attr "type" "store")
1355    (set_attr "length" "2")])
1356 \f
1357 ;;- zero extension instructions
1358
1359 ;; These patterns originally accepted general_operands, however, slightly
1360 ;; better code is generated by only accepting register_operands, and then
1361 ;; letting combine generate the ldu[hb] insns.
1362
1363 (define_expand "zero_extendhisi2"
1364   [(set (match_operand:SI 0 "register_operand" "")
1365         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1366   ""
1367   "
1368 {
1369   rtx temp = gen_reg_rtx (SImode);
1370   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1371   int op1_subword = 0;
1372
1373   if (GET_CODE (operand1) == SUBREG)
1374     {
1375       op1_subword = SUBREG_WORD (operand1);
1376       operand1 = XEXP (operand1, 0);
1377     }
1378
1379   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1380                                          op1_subword),
1381                           shift_16));
1382   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1383   DONE;
1384 }")
1385
1386 (define_insn ""
1387   [(set (match_operand:SI 0 "register_operand" "=r")
1388         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1389   ""
1390   "lduh %1,%0"
1391   [(set_attr "type" "load")])
1392
1393 (define_expand "zero_extendqihi2"
1394   [(set (match_operand:HI 0 "register_operand" "")
1395         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1396   ""
1397   "")
1398
1399 (define_insn ""
1400   [(set (match_operand:HI 0 "register_operand" "=r,r")
1401         (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1402   "GET_CODE (operands[1]) != CONST_INT"
1403   "@
1404    and %1,0xff,%0
1405    ldub %1,%0"
1406   [(set_attr "type" "unary,load")
1407    (set_attr "length" "1")])
1408
1409 (define_expand "zero_extendqisi2"
1410   [(set (match_operand:SI 0 "register_operand" "")
1411         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1412   ""
1413   "")
1414
1415 (define_insn ""
1416   [(set (match_operand:SI 0 "register_operand" "=r,r")
1417         (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1418   "GET_CODE (operands[1]) != CONST_INT"
1419   "@
1420    and %1,0xff,%0
1421    ldub %1,%0"
1422   [(set_attr "type" "unary,load")
1423    (set_attr "length" "1")])
1424
1425 (define_insn ""
1426   [(set (reg:CC 0)
1427         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1428                     (const_int 0)))]
1429   ""
1430   "andcc %0,0xff,%%g0"
1431   [(set_attr "type" "compare")])
1432
1433 (define_insn ""
1434   [(set (reg:CC 0)
1435         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1436                     (const_int 0)))
1437    (set (match_operand:SI 0 "register_operand" "=r")
1438         (zero_extend:SI (match_dup 1)))]
1439   ""
1440   "andcc %1,0xff,%0"
1441   [(set_attr "type" "unary")])
1442
1443 ;; Similarly, handle SI->QI mode truncation followed by a compare.
1444
1445 (define_insn ""
1446   [(set (reg:CC 0)
1447         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
1448                     (const_int 0)))]
1449   ""
1450   "andcc %0,0xff,%%g0"
1451   [(set_attr "type" "compare")])
1452
1453 (define_insn ""
1454   [(set (reg:CC 0)
1455         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
1456                     (const_int 0)))
1457    (set (match_operand:QI 0 "register_operand" "=r")
1458         (match_dup 1))]
1459   ""
1460   "andcc %1,0xff,%0"
1461   [(set_attr "type" "unary")])
1462 \f
1463 ;;- sign extension instructions
1464
1465 ;; These patterns originally accepted general_operands, however, slightly
1466 ;; better code is generated by only accepting register_operands, and then
1467 ;; letting combine generate the lds[hb] insns.
1468
1469 (define_expand "extendhisi2"
1470   [(set (match_operand:SI 0 "register_operand" "")
1471         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1472   ""
1473   "
1474 {
1475   rtx temp = gen_reg_rtx (SImode);
1476   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1477   int op1_subword = 0;
1478
1479   if (GET_CODE (operand1) == SUBREG)
1480     {
1481       op1_subword = SUBREG_WORD (operand1);
1482       operand1 = XEXP (operand1, 0);
1483     }
1484
1485   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1486                                          op1_subword),
1487                           shift_16));
1488   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1489   DONE;
1490 }")
1491
1492 (define_insn ""
1493   [(set (match_operand:SI 0 "register_operand" "=r")
1494         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1495   ""
1496   "ldsh %1,%0"
1497   [(set_attr "type" "load")])
1498
1499 (define_expand "extendqihi2"
1500   [(set (match_operand:HI 0 "register_operand" "")
1501         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1502   ""
1503   "
1504 {
1505   rtx temp = gen_reg_rtx (SImode);
1506   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1507   int op1_subword = 0;
1508   int op0_subword = 0;
1509
1510   if (GET_CODE (operand1) == SUBREG)
1511     {
1512       op1_subword = SUBREG_WORD (operand1);
1513       operand1 = XEXP (operand1, 0);
1514     }
1515   if (GET_CODE (operand0) == SUBREG)
1516     {
1517       op0_subword = SUBREG_WORD (operand0);
1518       operand0 = XEXP (operand0, 0);
1519     }
1520   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1521                                          op1_subword),
1522                           shift_24));
1523   if (GET_MODE (operand0) != SImode)
1524     operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
1525   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1526   DONE;
1527 }")
1528
1529 (define_insn ""
1530   [(set (match_operand:HI 0 "register_operand" "=r")
1531         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1532   ""
1533   "ldsb %1,%0"
1534   [(set_attr "type" "load")])
1535
1536 (define_expand "extendqisi2"
1537   [(set (match_operand:SI 0 "register_operand" "")
1538         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1539   ""
1540   "
1541 {
1542   rtx temp = gen_reg_rtx (SImode);
1543   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1544   int op1_subword = 0;
1545
1546   if (GET_CODE (operand1) == SUBREG)
1547     {
1548       op1_subword = SUBREG_WORD (operand1);
1549       operand1 = XEXP (operand1, 0);
1550     }
1551
1552   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1553                                          op1_subword),
1554                           shift_24));
1555   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1556   DONE;
1557 }")
1558
1559 (define_insn ""
1560   [(set (match_operand:SI 0 "register_operand" "=r")
1561         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1562   ""
1563   "ldsb %1,%0"
1564   [(set_attr "type" "load")])
1565 \f
1566 ;; Special pattern for optimizing bit-field compares.  This is needed
1567 ;; because combine uses this as a canonical form.
1568
1569 (define_insn ""
1570   [(set (reg:CC 0)
1571         (compare:CC
1572          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1573                           (match_operand:SI 1 "small_int" "n")
1574                           (match_operand:SI 2 "small_int" "n"))
1575          (const_int 0)))]
1576   "INTVAL (operands[2]) > 19"
1577   "*
1578 {
1579   int len = INTVAL (operands[1]);
1580   int pos = 32 - INTVAL (operands[2]) - len;
1581   unsigned mask = ((1 << len) - 1) << pos;
1582
1583   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1584   return \"andcc %0,%1,%%g0\";
1585 }")
1586 \f
1587 ;; Conversions between float, double and long double.
1588
1589 (define_insn "extendsfdf2"
1590   [(set (match_operand:DF 0 "register_operand" "=f")
1591         (float_extend:DF
1592          (match_operand:SF 1 "register_operand" "f")))]
1593   "TARGET_FPU"
1594   "fstod %1,%0"
1595   [(set_attr "type" "fp")])
1596
1597 (define_insn "extendsftf2"
1598   [(set (match_operand:TF 0 "register_operand" "=f")
1599         (float_extend:TF
1600          (match_operand:SF 1 "register_operand" "f")))]
1601   "TARGET_FPU"
1602   "fstoq %1,%0"
1603   [(set_attr "type" "fp")])
1604
1605 (define_insn "extenddftf2"
1606   [(set (match_operand:TF 0 "register_operand" "=f")
1607         (float_extend:TF
1608          (match_operand:DF 1 "register_operand" "f")))]
1609   "TARGET_FPU"
1610   "fdtoq %1,%0"
1611   [(set_attr "type" "fp")])
1612
1613 (define_insn "truncdfsf2"
1614   [(set (match_operand:SF 0 "register_operand" "=f")
1615         (float_truncate:SF
1616          (match_operand:DF 1 "register_operand" "f")))]
1617   "TARGET_FPU"
1618   "fdtos %1,%0"
1619   [(set_attr "type" "fp")])
1620
1621 (define_insn "trunctfsf2"
1622   [(set (match_operand:SF 0 "register_operand" "=f")
1623         (float_truncate:SF
1624          (match_operand:TF 1 "register_operand" "f")))]
1625   "TARGET_FPU"
1626   "fqtos %1,%0"
1627   [(set_attr "type" "fp")])
1628
1629 (define_insn "trunctfdf2"
1630   [(set (match_operand:DF 0 "register_operand" "=f")
1631         (float_truncate:DF
1632          (match_operand:TF 1 "register_operand" "f")))]
1633   "TARGET_FPU"
1634   "fqtod %1,%0"
1635   [(set_attr "type" "fp")])
1636 \f
1637 ;; Conversion between fixed point and floating point.
1638
1639 (define_insn "floatsisf2"
1640   [(set (match_operand:SF 0 "register_operand" "=f")
1641         (float:SF (match_operand:SI 1 "register_operand" "f")))]
1642   "TARGET_FPU"
1643   "fitos %1,%0"
1644   [(set_attr "type" "fp")])
1645
1646 (define_insn "floatsidf2"
1647   [(set (match_operand:DF 0 "register_operand" "=f")
1648         (float:DF (match_operand:SI 1 "register_operand" "f")))]
1649   "TARGET_FPU"
1650   "fitod %1,%0"
1651   [(set_attr "type" "fp")])
1652
1653 (define_insn "floatsitf2"
1654   [(set (match_operand:TF 0 "register_operand" "=f")
1655         (float:TF (match_operand:SI 1 "register_operand" "f")))]
1656   "TARGET_FPU"
1657   "fitoq %1,%0"
1658   [(set_attr "type" "fp")])
1659
1660 ;; Convert a float to an actual integer.
1661 ;; Truncation is performed as part of the conversion.
1662
1663 (define_insn "fix_truncsfsi2"
1664   [(set (match_operand:SI 0 "register_operand" "=f")
1665         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1666   "TARGET_FPU"
1667   "fstoi %1,%0"
1668   [(set_attr "type" "fp")])
1669
1670 (define_insn "fix_truncdfsi2"
1671   [(set (match_operand:SI 0 "register_operand" "=f")
1672         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1673   "TARGET_FPU"
1674   "fdtoi %1,%0"
1675   [(set_attr "type" "fp")])
1676
1677 (define_insn "fix_trunctfsi2"
1678   [(set (match_operand:SI 0 "register_operand" "=f")
1679         (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1680   "TARGET_FPU"
1681   "fqtoi %1,%0"
1682   [(set_attr "type" "fp")])
1683 \f
1684 ;;- arithmetic instructions
1685
1686 (define_insn "adddi3"
1687   [(set (match_operand:DI 0 "register_operand" "=r")
1688         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1689                  (match_operand:DI 2 "arith_double_operand" "rHI")))
1690    (clobber (reg:SI 0))]
1691   ""
1692   "*
1693 {
1694   rtx op2 = operands[2];
1695
1696   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1697      Give the assembler a chance to pick the move instruction. */
1698   if (GET_CODE (op2) == CONST_INT)
1699     {
1700       int sign = INTVAL (op2);
1701       if (sign < 0)
1702         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1703       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1704     }
1705   else if (GET_CODE (op2) == CONST_DOUBLE)
1706     {
1707       int sign = CONST_DOUBLE_HIGH (op2);
1708       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1709                              CONST_DOUBLE_LOW (operands[1]));
1710       if (sign < 0)
1711         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1712       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1713     }
1714   return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1715 }"
1716   [(set_attr "length" "2")])
1717
1718 (define_insn "addsi3"
1719   [(set (match_operand:SI 0 "register_operand" "=r")
1720         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1721                  (match_operand:SI 2 "arith_operand" "rI")))]
1722   ""
1723   "add %1,%2,%0")
1724
1725 (define_insn ""
1726   [(set (reg:CC_NOOV 0)
1727         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1728                                   (match_operand:SI 1 "arith_operand" "rI"))
1729                          (const_int 0)))]
1730   ""
1731   "addcc %0,%1,%%g0"
1732   [(set_attr "type" "compare")])
1733
1734 (define_insn ""
1735   [(set (reg:CC_NOOV 0)
1736         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1737                                   (match_operand:SI 2 "arith_operand" "rI"))
1738                          (const_int 0)))
1739    (set (match_operand:SI 0 "register_operand" "=r")
1740         (plus:SI (match_dup 1) (match_dup 2)))]
1741   ""
1742   "addcc %1,%2,%0")
1743
1744 (define_insn "subdi3"
1745   [(set (match_operand:DI 0 "register_operand" "=r")
1746         (minus:DI (match_operand:DI 1 "register_operand" "r")
1747                   (match_operand:DI 2 "arith_double_operand" "rHI")))
1748    (clobber (reg:SI 0))]
1749   ""
1750   "*
1751 {
1752   rtx op2 = operands[2];
1753
1754   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1755      Give the assembler a chance to pick the move instruction. */
1756   if (GET_CODE (op2) == CONST_INT)
1757     {
1758       int sign = INTVAL (op2);
1759       if (sign < 0)
1760         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1761       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1762     }
1763   else if (GET_CODE (op2) == CONST_DOUBLE)
1764     {
1765       int sign = CONST_DOUBLE_HIGH (op2);
1766       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1767                              CONST_DOUBLE_LOW (operands[1]));
1768       if (sign < 0)
1769         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1770       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1771     }
1772   return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1773 }"
1774   [(set_attr "length" "2")])
1775
1776 (define_insn "subsi3"
1777   [(set (match_operand:SI 0 "register_operand" "=r")
1778         (minus:SI (match_operand:SI 1 "register_operand" "r")
1779                   (match_operand:SI 2 "arith_operand" "rI")))]
1780   ""
1781   "sub %1,%2,%0")
1782
1783 (define_insn ""
1784   [(set (reg:CC_NOOV 0)
1785         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1786                                    (match_operand:SI 1 "arith_operand" "rI"))
1787                          (const_int 0)))]
1788   ""
1789   "subcc %0,%1,%%g0"
1790   [(set_attr "type" "compare")])
1791
1792 (define_insn ""
1793   [(set (reg:CC_NOOV 0)
1794         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1795                                    (match_operand:SI 2 "arith_operand" "rI"))
1796                          (const_int 0)))
1797    (set (match_operand:SI 0 "register_operand" "=r")
1798         (minus:SI (match_dup 1) (match_dup 2)))]
1799   ""
1800   "subcc %1,%2,%0")
1801
1802 (define_insn "mulsi3"
1803   [(set (match_operand:SI 0 "register_operand" "=r")
1804         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1805                  (match_operand:SI 2 "arith_operand" "rI")))]
1806   "TARGET_V8 || TARGET_SPARCLITE"
1807   "smul %1,%2,%0")
1808
1809 ;; It is not known whether this will match.
1810
1811 (define_insn ""
1812   [(set (match_operand:SI 0 "register_operand" "=r")
1813         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1814                  (match_operand:SI 2 "arith_operand" "rI")))
1815    (set (reg:CC_NOOV 0)
1816         (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1817                          (const_int 0)))]
1818   "TARGET_V8 || TARGET_SPARCLITE"
1819   "smulcc %1,%2,%0")
1820
1821 (define_expand "mulsidi3"
1822   [(set (match_operand:DI 0 "register_operand" "")
1823         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1824                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1825   "TARGET_V8 || TARGET_SPARCLITE"
1826   "
1827 {
1828   if (CONSTANT_P (operands[2]))
1829     {
1830       emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1831       DONE;
1832     }
1833 }")
1834
1835 (define_insn ""
1836   [(set (match_operand:DI 0 "register_operand" "=r")
1837         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1838                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1839   "TARGET_V8 || TARGET_SPARCLITE"
1840   "smul %1,%2,%R0\;rd %%y,%0"
1841   [(set_attr "length" "2")])
1842
1843 ;; Extra pattern, because sign_extend of a constant isn't legal.
1844
1845 (define_insn "const_mulsidi3"
1846   [(set (match_operand:DI 0 "register_operand" "=r")
1847         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1848                  (match_operand:SI 2 "small_int" "I")))]
1849   "TARGET_V8 || TARGET_SPARCLITE"
1850   "smul %1,%2,%R0\;rd %%y,%0"
1851   [(set_attr "length" "2")])
1852
1853 (define_expand "umulsidi3"
1854   [(set (match_operand:DI 0 "register_operand" "")
1855         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1856                  (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1857   "TARGET_V8 || TARGET_SPARCLITE"
1858   "
1859 {
1860   if (CONSTANT_P (operands[2]))
1861     {
1862       emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1863       DONE;
1864     }
1865 }")
1866
1867 (define_insn ""
1868   [(set (match_operand:DI 0 "register_operand" "=r")
1869         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1870                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1871   "TARGET_V8 || TARGET_SPARCLITE"
1872   "umul %1,%2,%R0\;rd %%y,%0"
1873   [(set_attr "length" "2")])
1874
1875 ;; Extra pattern, because sign_extend of a constant isn't legal.
1876
1877 (define_insn "const_umulsidi3"
1878   [(set (match_operand:DI 0 "register_operand" "=r")
1879         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1880                  (match_operand:SI 2 "small_int" "I")))]
1881   "TARGET_V8 || TARGET_SPARCLITE"
1882   "umul %1,%2,%R0\;rd %%y,%0"
1883   [(set_attr "length" "2")])
1884
1885 ;; The architecture specifies that there must be 3 instructions between
1886 ;; a y register write and a use of it for correct results.
1887
1888 (define_insn "divsi3"
1889   [(set (match_operand:SI 0 "register_operand" "=r")
1890         (div:SI (match_operand:SI 1 "register_operand" "r")
1891                 (match_operand:SI 2 "arith_operand" "rI")))
1892    (clobber (match_scratch:SI 3 "=&r"))]
1893   "TARGET_V8"
1894   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1895   [(set_attr "length" "6")])
1896
1897 ;; It is not known whether this will match.
1898
1899 (define_insn ""
1900   [(set (match_operand:SI 0 "register_operand" "=r")
1901         (div:SI (match_operand:SI 1 "register_operand" "r")
1902                 (match_operand:SI 2 "arith_operand" "rI")))
1903    (set (reg:CC 0)
1904         (compare:CC (div:SI (match_dup 1) (match_dup 2))
1905                     (const_int 0)))
1906    (clobber (match_scratch:SI 3 "=&r"))]
1907   "TARGET_V8"
1908   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1909   [(set_attr "length" "6")])
1910
1911 (define_insn "udivsi3"
1912   [(set (match_operand:SI 0 "register_operand" "=r")
1913         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1914                 (match_operand:SI 2 "arith_operand" "rI")))]
1915   "TARGET_V8"
1916   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1917   [(set_attr "length" "5")])
1918
1919 ;; It is not known whether this will match.
1920
1921 (define_insn ""
1922   [(set (match_operand:SI 0 "register_operand" "=r")
1923         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1924                 (match_operand:SI 2 "arith_operand" "rI")))
1925    (set (reg:CC 0)
1926         (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1927                     (const_int 0)))]
1928   "TARGET_V8"
1929   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1930   [(set_attr "length" "5")])
1931
1932 ;;- and instructions
1933 ;; We define DImode `and` so with DImode `not` we can get
1934 ;; DImode `andn`.  Other combinations are possible.
1935
1936 (define_expand "anddi3"
1937   [(set (match_operand:DI 0 "register_operand" "")
1938         (and:DI (match_operand:DI 1 "arith_double_operand" "")
1939                 (match_operand:DI 2 "arith_double_operand" "")))]
1940   ""
1941   "")
1942
1943 (define_insn ""
1944   [(set (match_operand:DI 0 "register_operand" "=r")
1945         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1946                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1947   ""
1948   "*
1949 {
1950   rtx op2 = operands[2];
1951
1952   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1953      Give the assembler a chance to pick the move instruction. */
1954   if (GET_CODE (op2) == CONST_INT)
1955     {
1956       int sign = INTVAL (op2);
1957       if (sign < 0)
1958         return \"mov %1,%0\;and %R1,%2,%R0\";
1959       return \"mov 0,%0\;and %R1,%2,%R0\";
1960     }
1961   else if (GET_CODE (op2) == CONST_DOUBLE)
1962     {
1963       int sign = CONST_DOUBLE_HIGH (op2);
1964       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1965                              CONST_DOUBLE_LOW (operands[1]));
1966       if (sign < 0)
1967         return \"mov %1,%0\;and %R1,%2,%R0\";
1968       return \"mov 0,%0\;and %R1,%2,%R0\";
1969     }
1970   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1971 }"
1972   [(set_attr "length" "2")])
1973
1974 (define_insn "andsi3"
1975   [(set (match_operand:SI 0 "register_operand" "=r")
1976         (and:SI (match_operand:SI 1 "arith_operand" "%r")
1977                 (match_operand:SI 2 "arith_operand" "rI")))]
1978   ""
1979   "and %1,%2,%0")
1980
1981 (define_split
1982   [(set (match_operand:SI 0 "register_operand" "")
1983         (and:SI (match_operand:SI 1 "register_operand" "")
1984                 (match_operand:SI 2 "" "")))
1985    (clobber (match_operand:SI 3 "register_operand" ""))]
1986   "GET_CODE (operands[2]) == CONST_INT
1987    && !SMALL_INT (operands[2])
1988    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1989   [(set (match_dup 3) (match_dup 4))
1990    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1991   "
1992 {
1993   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1994 }")
1995
1996 (define_insn ""
1997   [(set (match_operand:DI 0 "register_operand" "=r")
1998         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1999                 (match_operand:DI 2 "register_operand" "r")))]
2000   ""
2001   "andn %2,%1,%0\;andn %R2,%R1,%R0"
2002   [(set_attr "length" "2")])
2003
2004 (define_insn ""
2005   [(set (match_operand:SI 0 "register_operand" "=r")
2006         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2007                 (match_operand:SI 2 "register_operand" "r")))]
2008   ""
2009   "andn %2,%1,%0")
2010
2011 (define_expand "iordi3"
2012   [(set (match_operand:DI 0 "register_operand" "")
2013         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
2014                 (match_operand:DI 2 "arith_double_operand" "")))]
2015   ""
2016   "")
2017
2018 (define_insn ""
2019   [(set (match_operand:DI 0 "register_operand" "=r")
2020         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
2021                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2022   ""
2023   "*
2024 {
2025   rtx op2 = operands[2];
2026
2027   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2028      Give the assembler a chance to pick the move instruction. */
2029   if (GET_CODE (op2) == CONST_INT)
2030     {
2031       int sign = INTVAL (op2);
2032       if (sign < 0)
2033         return \"mov -1,%0\;or %R1,%2,%R0\";
2034       return \"mov %1,%0\;or %R1,%2,%R0\";
2035     }
2036   else if (GET_CODE (op2) == CONST_DOUBLE)
2037     {
2038       int sign = CONST_DOUBLE_HIGH (op2);
2039       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2040                              CONST_DOUBLE_LOW (operands[1]));
2041       if (sign < 0)
2042         return \"mov -1,%0\;or %R1,%2,%R0\";
2043       return \"mov %1,%0\;or %R1,%2,%R0\";
2044     }
2045   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
2046 }"
2047   [(set_attr "length" "2")])
2048
2049 (define_insn "iorsi3"
2050   [(set (match_operand:SI 0 "register_operand" "=r")
2051         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
2052                 (match_operand:SI 2 "arith_operand" "rI")))]
2053   ""
2054   "or %1,%2,%0")
2055
2056 (define_split
2057   [(set (match_operand:SI 0 "register_operand" "")
2058         (ior:SI (match_operand:SI 1 "register_operand" "")
2059                 (match_operand:SI 2 "" "")))
2060    (clobber (match_operand:SI 3 "register_operand" ""))]
2061   "GET_CODE (operands[2]) == CONST_INT
2062    && !SMALL_INT (operands[2])
2063    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2064   [(set (match_dup 3) (match_dup 4))
2065    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2066   "
2067 {
2068   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2069 }")
2070
2071 (define_insn ""
2072   [(set (match_operand:DI 0 "register_operand" "=r")
2073         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2074                 (match_operand:DI 2 "register_operand" "r")))]
2075   ""
2076   "orn %2,%1,%0\;orn %R2,%R1,%R0"
2077   [(set_attr "length" "2")])
2078
2079 (define_insn ""
2080   [(set (match_operand:SI 0 "register_operand" "=r")
2081         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2082                 (match_operand:SI 2 "register_operand" "r")))]
2083   ""
2084   "orn %2,%1,%0")
2085
2086 (define_expand "xordi3"
2087   [(set (match_operand:DI 0 "register_operand" "")
2088         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2089                 (match_operand:DI 2 "arith_double_operand" "")))]
2090   ""
2091   "")
2092
2093 (define_insn ""
2094   [(set (match_operand:DI 0 "register_operand" "=r")
2095         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2096                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2097   ""
2098   "*
2099 {
2100   rtx op2 = operands[2];
2101
2102   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2103      Give the assembler a chance to pick the move instruction. */
2104   if (GET_CODE (op2) == CONST_INT)
2105     {
2106       int sign = INTVAL (op2);
2107       if (sign < 0)
2108         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2109       return \"mov %1,%0\;xor %R1,%2,%R0\";
2110     }
2111   else if (GET_CODE (op2) == CONST_DOUBLE)
2112     {
2113       int sign = CONST_DOUBLE_HIGH (op2);
2114       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2115                              CONST_DOUBLE_LOW (operands[1]));
2116       if (sign < 0)
2117         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2118       return \"mov %1,%0\;xor %R1,%2,%R0\";
2119     }
2120   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2121 }"
2122   [(set_attr "length" "2")])
2123
2124 (define_insn "xorsi3"
2125   [(set (match_operand:SI 0 "register_operand" "=r")
2126         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2127                 (match_operand:SI 2 "arith_operand" "rI")))]
2128   ""
2129   "xor %r1,%2,%0")
2130
2131 (define_split
2132   [(set (match_operand:SI 0 "register_operand" "")
2133         (xor:SI (match_operand:SI 1 "register_operand" "")
2134                 (match_operand:SI 2 "" "")))
2135    (clobber (match_operand:SI 3 "register_operand" ""))]
2136   "GET_CODE (operands[2]) == CONST_INT
2137    && !SMALL_INT (operands[2])
2138    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2139   [(set (match_dup 3) (match_dup 4))
2140    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2141   "
2142 {
2143   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2144 }")
2145
2146 (define_split
2147   [(set (match_operand:SI 0 "register_operand" "")
2148         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2149                         (match_operand:SI 2 "" ""))))
2150    (clobber (match_operand:SI 3 "register_operand" ""))]
2151   "GET_CODE (operands[2]) == CONST_INT
2152    && !SMALL_INT (operands[2])
2153    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2154   [(set (match_dup 3) (match_dup 4))
2155    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2156   "
2157 {
2158   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2159 }")
2160
2161 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2162 ;; Combine now canonicalizes to the rightmost expression.
2163 (define_insn ""
2164   [(set (match_operand:DI 0 "register_operand" "=r")
2165         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2166                         (match_operand:DI 2 "register_operand" "r"))))]
2167   ""
2168   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2169   [(set_attr "length" "2")])
2170
2171 (define_insn ""
2172   [(set (match_operand:SI 0 "register_operand" "=r")
2173         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2174                         (match_operand:SI 2 "arith_operand" "rI"))))]
2175   ""
2176   "xnor %r1,%2,%0")
2177
2178 ;; These correspond to the above in the case where we also (or only)
2179 ;; want to set the condition code.  
2180
2181 (define_insn ""
2182   [(set (reg:CC 0)
2183         (compare:CC
2184          (match_operator:SI 2 "cc_arithop"
2185                             [(match_operand:SI 0 "arith_operand" "%r")
2186                              (match_operand:SI 1 "arith_operand" "rI")])
2187          (const_int 0)))]
2188   ""
2189   "%A2cc %0,%1,%%g0"
2190   [(set_attr "type" "compare")])
2191
2192 (define_insn ""
2193   [(set (reg:CC 0)
2194         (compare:CC
2195          (match_operator:SI 3 "cc_arithop"
2196                             [(match_operand:SI 1 "arith_operand" "%r")
2197                              (match_operand:SI 2 "arith_operand" "rI")])
2198          (const_int 0)))
2199    (set (match_operand:SI 0 "register_operand" "=r")
2200         (match_dup 3))]
2201   ""
2202   "%A3cc %1,%2,%0")
2203
2204 (define_insn ""
2205   [(set (reg:CC 0)
2206         (compare:CC
2207          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2208                          (match_operand:SI 1 "arith_operand" "rI")))
2209          (const_int 0)))]
2210   ""
2211   "xnorcc %r0,%1,%%g0"
2212   [(set_attr "type" "compare")])
2213
2214 (define_insn ""
2215   [(set (reg:CC 0)
2216         (compare:CC
2217          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2218                          (match_operand:SI 2 "arith_operand" "rI")))
2219          (const_int 0)))
2220    (set (match_operand:SI 0 "register_operand" "=r")
2221         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2222   ""
2223   "xnorcc %r1,%2,%0")
2224
2225 (define_insn ""
2226   [(set (reg:CC 0)
2227         (compare:CC
2228          (match_operator:SI 2 "cc_arithopn"
2229                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2230                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2231          (const_int 0)))]
2232   ""
2233   "%B2cc %r1,%0,%%g0"
2234   [(set_attr "type" "compare")])
2235
2236 (define_insn ""
2237   [(set (reg:CC 0)
2238         (compare:CC
2239          (match_operator:SI 3 "cc_arithopn"
2240                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2241                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2242          (const_int 0)))
2243    (set (match_operand:SI 0 "register_operand" "=r")
2244         (match_dup 3))]
2245   ""
2246   "%B3cc %r2,%1,%0")
2247
2248 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2249 ;; does not know how to make it work for constants.
2250
2251 (define_insn "negdi2"
2252   [(set (match_operand:DI 0 "register_operand" "=r")
2253         (neg:DI (match_operand:DI 1 "register_operand" "r")))
2254    (clobber (reg:SI 0))]
2255   ""
2256   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2257   [(set_attr "type" "unary")
2258    (set_attr "length" "2")])
2259
2260 (define_insn "negsi2"
2261   [(set (match_operand:SI 0 "general_operand" "=r")
2262         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2263   ""
2264   "sub %%g0,%1,%0"
2265   [(set_attr "type" "unary")])
2266
2267 (define_insn ""
2268   [(set (reg:CC_NOOV 0)
2269         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2270                          (const_int 0)))]
2271   ""
2272   "subcc %%g0,%0,%%g0"
2273   [(set_attr "type" "compare")])
2274
2275 (define_insn ""
2276   [(set (reg:CC_NOOV 0)
2277         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2278                          (const_int 0)))
2279    (set (match_operand:SI 0 "register_operand" "=r")
2280         (neg:SI (match_dup 1)))]
2281   ""
2282   "subcc %%g0,%1,%0"
2283   [(set_attr "type" "unary")])
2284
2285 ;; We cannot use the "not" pseudo insn because the Sun assembler
2286 ;; does not know how to make it work for constants.
2287 (define_expand "one_cmpldi2"
2288   [(set (match_operand:DI 0 "register_operand" "=r")
2289         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2290   ""
2291   "")
2292
2293 (define_insn ""
2294   [(set (match_operand:DI 0 "register_operand" "=r")
2295         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2296   ""
2297   "*
2298 {
2299   rtx op1 = operands[1];
2300
2301   if (GET_CODE (op1) == CONST_INT)
2302     {
2303       int sign = INTVAL (op1);
2304       if (sign < 0)
2305         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2306       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2307     }
2308   else if (GET_CODE (op1) == CONST_DOUBLE)
2309     {
2310       int sign = CONST_DOUBLE_HIGH (op1);
2311       operands[1] = gen_rtx (CONST_INT, VOIDmode,
2312                              CONST_DOUBLE_LOW (operands[1]));
2313       if (sign < 0)
2314         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2315       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2316     }
2317   return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2318 }"
2319   [(set_attr "type" "unary")
2320    (set_attr "length" "2")])
2321
2322 (define_insn "one_cmplsi2"
2323   [(set (match_operand:SI 0 "register_operand" "=r")
2324         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2325   ""
2326   "xnor %%g0,%1,%0"
2327   [(set_attr "type" "unary")])
2328
2329 (define_insn ""
2330   [(set (reg:CC 0)
2331         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2332                     (const_int 0)))]
2333   ""
2334   "xnorcc %%g0,%0,%%g0"
2335   [(set_attr "type" "compare")])
2336
2337 (define_insn ""
2338   [(set (reg:CC 0)
2339         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2340                     (const_int 0)))
2341    (set (match_operand:SI 0 "register_operand" "=r")
2342         (not:SI (match_dup 1)))]
2343   ""
2344   "xnorcc %%g0,%1,%0"
2345   [(set_attr "type" "unary")])
2346 \f
2347 ;; Floating point arithmetic instructions.
2348
2349 (define_insn "addtf3"
2350   [(set (match_operand:TF 0 "register_operand" "=f")
2351         (plus:TF (match_operand:TF 1 "register_operand" "f")
2352                  (match_operand:TF 2 "register_operand" "f")))]
2353   "TARGET_FPU"
2354   "faddq %1,%2,%0"
2355   [(set_attr "type" "fp")])
2356
2357 (define_insn "adddf3"
2358   [(set (match_operand:DF 0 "register_operand" "=f")
2359         (plus:DF (match_operand:DF 1 "register_operand" "f")
2360                  (match_operand:DF 2 "register_operand" "f")))]
2361   "TARGET_FPU"
2362   "faddd %1,%2,%0"
2363   [(set_attr "type" "fp")])
2364
2365 (define_insn "addsf3"
2366   [(set (match_operand:SF 0 "register_operand" "=f")
2367         (plus:SF (match_operand:SF 1 "register_operand" "f")
2368                  (match_operand:SF 2 "register_operand" "f")))]
2369   "TARGET_FPU"
2370   "fadds %1,%2,%0"
2371   [(set_attr "type" "fp")])
2372
2373 (define_insn "subtf3"
2374   [(set (match_operand:TF 0 "register_operand" "=f")
2375         (minus:TF (match_operand:TF 1 "register_operand" "f")
2376                   (match_operand:TF 2 "register_operand" "f")))]
2377   "TARGET_FPU"
2378   "fsubq %1,%2,%0"
2379   [(set_attr "type" "fp")])
2380
2381 (define_insn "subdf3"
2382   [(set (match_operand:DF 0 "register_operand" "=f")
2383         (minus:DF (match_operand:DF 1 "register_operand" "f")
2384                   (match_operand:DF 2 "register_operand" "f")))]
2385   "TARGET_FPU"
2386   "fsubd %1,%2,%0"
2387   [(set_attr "type" "fp")])
2388
2389 (define_insn "subsf3"
2390   [(set (match_operand:SF 0 "register_operand" "=f")
2391         (minus:SF (match_operand:SF 1 "register_operand" "f")
2392                   (match_operand:SF 2 "register_operand" "f")))]
2393   "TARGET_FPU"
2394   "fsubs %1,%2,%0"
2395   [(set_attr "type" "fp")])
2396
2397 (define_insn "multf3"
2398   [(set (match_operand:TF 0 "register_operand" "=f")
2399         (mult:TF (match_operand:TF 1 "register_operand" "f")
2400                  (match_operand:TF 2 "register_operand" "f")))]
2401   "TARGET_FPU"
2402   "fmulq %1,%2,%0"
2403   [(set_attr "type" "fpmul")])
2404
2405 (define_insn "muldf3"
2406   [(set (match_operand:DF 0 "register_operand" "=f")
2407         (mult:DF (match_operand:DF 1 "register_operand" "f")
2408                  (match_operand:DF 2 "register_operand" "f")))]
2409   "TARGET_FPU"
2410   "fmuld %1,%2,%0"
2411   [(set_attr "type" "fpmul")])
2412
2413 (define_insn "mulsf3"
2414   [(set (match_operand:SF 0 "register_operand" "=f")
2415         (mult:SF (match_operand:SF 1 "register_operand" "f")
2416                  (match_operand:SF 2 "register_operand" "f")))]
2417   "TARGET_FPU"
2418   "fmuls %1,%2,%0"
2419   [(set_attr "type" "fpmul")])
2420
2421 (define_insn ""
2422   [(set (match_operand:DF 0 "register_operand" "=f")
2423         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2424                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2425   "TARGET_V8 && TARGET_FPU"
2426   "fsmuld %1,%2,%0"
2427   [(set_attr "type" "fpmul")])
2428
2429 (define_insn ""
2430   [(set (match_operand:TF 0 "register_operand" "=f")
2431         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2432                  (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2433   "TARGET_V8 && TARGET_FPU"
2434   "fdmulq %1,%2,%0"
2435   [(set_attr "type" "fpmul")])
2436
2437 (define_insn "divtf3"
2438   [(set (match_operand:TF 0 "register_operand" "=f")
2439         (div:TF (match_operand:TF 1 "register_operand" "f")
2440                 (match_operand:TF 2 "register_operand" "f")))]
2441   "TARGET_FPU"
2442   "fdivq %1,%2,%0"
2443   [(set_attr "type" "fpdiv")])
2444
2445 (define_insn "divdf3"
2446   [(set (match_operand:DF 0 "register_operand" "=f")
2447         (div:DF (match_operand:DF 1 "register_operand" "f")
2448                 (match_operand:DF 2 "register_operand" "f")))]
2449   "TARGET_FPU"
2450   "fdivd %1,%2,%0"
2451   [(set_attr "type" "fpdiv")])
2452
2453 (define_insn "divsf3"
2454   [(set (match_operand:SF 0 "register_operand" "=f")
2455         (div:SF (match_operand:SF 1 "register_operand" "f")
2456                 (match_operand:SF 2 "register_operand" "f")))]
2457   "TARGET_FPU"
2458   "fdivs %1,%2,%0"
2459   [(set_attr "type" "fpdiv")])
2460
2461 (define_insn "negtf2"
2462   [(set (match_operand:TF 0 "register_operand" "=f,f")
2463         (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2464   "TARGET_FPU"
2465   "@
2466    fnegs %0,%0
2467    fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2468   [(set_attr "type" "fp")
2469    (set_attr "length" "1,4")])
2470
2471 (define_insn "negdf2"
2472   [(set (match_operand:DF 0 "register_operand" "=f,f")
2473         (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2474   "TARGET_FPU"
2475   "@
2476    fnegs %0,%0
2477    fnegs %1,%0\;fmovs %R1,%R0"
2478   [(set_attr "type" "fp")
2479    (set_attr "length" "1,2")])
2480
2481 (define_insn "negsf2"
2482   [(set (match_operand:SF 0 "register_operand" "=f")
2483         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2484   "TARGET_FPU"
2485   "fnegs %1,%0"
2486   [(set_attr "type" "fp")])
2487
2488 (define_insn "abstf2"
2489   [(set (match_operand:TF 0 "register_operand" "=f,f")
2490         (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2491   "TARGET_FPU"
2492   "@
2493    fabss %0,%0
2494    fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2495   [(set_attr "type" "fp")
2496    (set_attr "length" "1,4")])
2497
2498 (define_insn "absdf2"
2499   [(set (match_operand:DF 0 "register_operand" "=f,f")
2500         (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2501   "TARGET_FPU"
2502   "@
2503    fabss %0,%0
2504    fabss %1,%0\;fmovs %R1,%R0"
2505   [(set_attr "type" "fp")
2506    (set_attr "length" "1,2")])
2507
2508 (define_insn "abssf2"
2509   [(set (match_operand:SF 0 "register_operand" "=f")
2510         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2511   "TARGET_FPU"
2512   "fabss %1,%0"
2513   [(set_attr "type" "fp")])
2514
2515 (define_insn "sqrttf2"
2516   [(set (match_operand:TF 0 "register_operand" "=f")
2517         (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2518   "TARGET_FPU"
2519   "fsqrtq %1,%0"
2520   [(set_attr "type" "fpsqrt")])
2521
2522 (define_insn "sqrtdf2"
2523   [(set (match_operand:DF 0 "register_operand" "=f")
2524         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2525   "TARGET_FPU"
2526   "fsqrtd %1,%0"
2527   [(set_attr "type" "fpsqrt")])
2528
2529 (define_insn "sqrtsf2"
2530   [(set (match_operand:SF 0 "register_operand" "=f")
2531         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2532   "TARGET_FPU"
2533   "fsqrts %1,%0"
2534   [(set_attr "type" "fpsqrt")])
2535 \f
2536 ;;- arithmetic shift instructions
2537
2538 (define_insn "ashlsi3"
2539   [(set (match_operand:SI 0 "register_operand" "=r")
2540         (ashift:SI (match_operand:SI 1 "register_operand" "r")
2541                    (match_operand:SI 2 "arith_operand" "rI")))]
2542   ""
2543   "sll %1,%2,%0")
2544
2545 (define_expand "ashldi3"
2546   [(parallel [(set (match_operand:DI 0 "register_operand" "")
2547                    (ashift:DI (match_operand:DI 1 "register_operand" "")
2548                               (match_operand:DI 2 "const_int_operand" "")))
2549               (clobber (match_scratch:SI 3 ""))])]
2550   ""
2551   "
2552 {
2553   if (GET_CODE (operands[2]) != CONST_INT)
2554     FAIL;
2555 }")
2556
2557 (define_insn ""
2558   [(set (match_operand:DI 0 "register_operand" "=r")
2559         (ashift:DI (match_operand:DI 1 "register_operand" "r")
2560                      (match_operand:DI 2 "const_int_operand" "I")))
2561    (clobber (match_scratch:SI 3 "=r"))]
2562   "INTVAL (operands[2]) < 32"
2563   "*
2564 {
2565   operands[4] = GEN_INT (32 - INTVAL (operands[2]));
2566   return \"srl %R1,%4,%3\;sll %R1,%2,%R0\;sll %1,%2,%0\;or %3,%0,%0\";
2567 }"
2568  [(set_attr "type" "multi")
2569   (set_attr "length" "4")])
2570
2571 (define_insn ""
2572   [(set (match_operand:DI 0 "register_operand" "=r")
2573         (lshift:DI (match_operand:DI 1 "register_operand" "r")
2574                      (match_operand:DI 2 "const_int_operand" "I")))
2575    (clobber (match_scratch:SI 3 "=X"))]
2576   "INTVAL (operands[2]) >= 32"
2577   "*
2578 {
2579   operands[4] = GEN_INT (INTVAL (operands[2]) - 32);
2580   return \"sll %R1,%4,%0\;mov %%g0,%R0\";
2581 }"
2582  [(set_attr "type" "multi")
2583   (set_attr "length" "2")])
2584
2585 (define_insn "ashrsi3"
2586   [(set (match_operand:SI 0 "register_operand" "=r")
2587         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2588                      (match_operand:SI 2 "arith_operand" "rI")))]
2589   ""
2590   "sra %1,%2,%0")
2591
2592 (define_insn "lshrsi3"
2593   [(set (match_operand:SI 0 "register_operand" "=r")
2594         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2595                      (match_operand:SI 2 "arith_operand" "rI")))]
2596   ""
2597   "srl %1,%2,%0")
2598
2599 (define_expand "lshrdi3"
2600   [(parallel [(set (match_operand:DI 0 "register_operand" "")
2601                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
2602                                 (match_operand:DI 2 "const_int_operand" "")))
2603               (clobber (match_scratch:SI 3 ""))])]
2604   ""
2605   "
2606 {
2607   if (GET_CODE (operands[2]) != CONST_INT)
2608     FAIL;
2609 }")
2610
2611 (define_insn ""
2612   [(set (match_operand:DI 0 "register_operand" "=r")
2613         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
2614                      (match_operand:DI 2 "const_int_operand" "I")))
2615    (clobber (match_scratch:SI 3 "=r"))]
2616   "INTVAL (operands[2]) < 32"
2617   "*
2618 {
2619   operands[4] = GEN_INT (32 - INTVAL (operands[2]));
2620   return \"sll %1,%4,%3\;srl %1,%2,%0\;srl %R1,%2,%R0\;or %3,%R0,%R0\";
2621 }"
2622  [(set_attr "type" "multi")
2623   (set_attr "length" "4")])
2624
2625 (define_insn ""
2626   [(set (match_operand:DI 0 "register_operand" "=r")
2627         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
2628                      (match_operand:DI 2 "const_int_operand" "I")))
2629    (clobber (match_scratch:SI 3 "=X"))]
2630   "INTVAL (operands[2]) >= 32"
2631   "*
2632 {
2633   operands[4] = GEN_INT (INTVAL (operands[2]) - 32);
2634   return \"srl %1,%4,%R0\;mov %%g0,%0\";
2635 }"
2636  [(set_attr "type" "multi")
2637   (set_attr "length" "2")])
2638 \f
2639 ;; Unconditional and other jump instructions
2640 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2641 ;; following insn is never executed.  This saves us a nop.  Dbx does not
2642 ;; handle such branches though, so we only use them when optimizing.
2643 (define_insn "jump"
2644   [(set (pc) (label_ref (match_operand 0 "" "")))]
2645   ""
2646   "b%* %l0%("
2647   [(set_attr "type" "uncond_branch")])
2648
2649 (define_expand "tablejump"
2650   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2651               (use (label_ref (match_operand 1 "" "")))])]
2652   ""
2653   "
2654 {
2655   /* We need to use the PC value in %o7 that was set up when the address
2656      of the label was loaded into a register, so we need different RTL.  */
2657   if (flag_pic)
2658     {
2659       emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2660       DONE;
2661     }
2662 }")
2663
2664 (define_insn "pic_tablejump"
2665   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2666    (use (label_ref (match_operand 1 "" "")))
2667    (use (reg:SI 15))]
2668   ""
2669   "jmp %%o7+%0%#"
2670   [(set_attr "type" "uncond_branch")])
2671
2672 (define_insn ""
2673   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2674    (use (label_ref (match_operand 1 "" "")))]
2675   ""
2676   "jmp %a0%#"
2677   [(set_attr "type" "uncond_branch")])
2678
2679 (define_insn ""
2680   [(set (pc) (label_ref (match_operand 0 "" "")))
2681    (set (reg:SI 15) (label_ref (match_dup 0)))]
2682   ""
2683   "call %l0%#"
2684   [(set_attr "type" "uncond_branch")])
2685
2686 ;; This pattern recognizes the "instruction" that appears in 
2687 ;; a function call that wants a structure value, 
2688 ;; to inform the called function if compiled with Sun CC.
2689 ;(define_insn ""
2690 ;  [(match_operand:SI 0 "immediate_operand" "")]
2691 ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2692 ;  "unimp %0"
2693 ;  [(set_attr "type" "marker")])
2694
2695 ;;- jump to subroutine
2696 (define_expand "call"
2697   ;; Note that this expression is not used for generating RTL.
2698   ;; All the RTL is generated explicitly below.
2699   [(call (match_operand:SI 0 "call_operand" "")
2700          (match_operand 3 "" "i"))]
2701   ;; operands[2] is next_arg_register
2702   ;; operands[3] is struct_value_size_rtx.
2703   ""
2704   "
2705 {
2706   rtx fn_rtx, nregs_rtx;
2707
2708   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2709     {
2710       /* This is really a PIC sequence.  We want to represent
2711          it as a funny jump so it's delay slots can be filled. 
2712
2713          ??? But if this really *is* a CALL, will not it clobber the
2714          call-clobbered registers?  We lose this if it is a JUMP_INSN.
2715          Why cannot we have delay slots filled if it were a CALL?  */
2716
2717       if (INTVAL (operands[3]) > 0)
2718         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2719                                  gen_rtx (SET, VOIDmode, pc_rtx,
2720                                           XEXP (operands[0], 0)),
2721                                  operands[3],
2722                                  gen_rtx (CLOBBER, VOIDmode,
2723                                           gen_rtx (REG, SImode, 15)))));
2724       else
2725         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2726                                  gen_rtx (SET, VOIDmode, pc_rtx,
2727                                           XEXP (operands[0], 0)),
2728                                  gen_rtx (CLOBBER, VOIDmode,
2729                                           gen_rtx (REG, SImode, 15)))));
2730       goto finish_call;
2731     }
2732
2733   fn_rtx = operands[0];
2734
2735   /* Count the number of parameter registers being used by this call.
2736      if that argument is NULL, it means we are using them all, which
2737      means 6 on the sparc.  */
2738 #if 0
2739   if (operands[2])
2740     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2741   else
2742     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2743 #else
2744   nregs_rtx = const0_rtx;
2745 #endif
2746
2747   if (INTVAL (operands[3]) > 0)
2748     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2749                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2750                              operands[3],
2751                              gen_rtx (CLOBBER, VOIDmode,
2752                                                gen_rtx (REG, SImode, 15)))));
2753   else
2754     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2755                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2756                              gen_rtx (CLOBBER, VOIDmode,
2757                                                gen_rtx (REG, SImode, 15)))));
2758
2759  finish_call:
2760 #if 0
2761   /* If this call wants a structure value,
2762      emit an unimp insn to let the called function know about this.  */
2763   if (INTVAL (operands[3]) > 0)
2764     {
2765       rtx insn = emit_insn (operands[3]);
2766       SCHED_GROUP_P (insn) = 1;
2767     }
2768 #endif
2769
2770   DONE;
2771 }")
2772
2773 (define_insn ""
2774   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2775          (match_operand 1 "" ""))
2776    (clobber (reg:SI 15))]
2777   ;;- Do not use operand 1 for most machines.
2778   ""
2779   "*
2780 {
2781   return \"call %a0,%1%#\";
2782 }"
2783   [(set_attr "type" "call")])
2784
2785 ;; This is a call that wants a structure value.
2786 (define_insn ""
2787   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2788          (match_operand 1 "" ""))
2789    (match_operand 2 "immediate_operand" "")
2790    (clobber (reg:SI 15))]
2791   ;;- Do not use operand 1 for most machines.
2792   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2793   "*
2794 {
2795   return \"call %a0,%1\;nop\;unimp %2\";
2796 }"
2797   [(set_attr "type" "call_no_delay_slot")])
2798
2799 (define_expand "call_value"
2800   [(set (match_operand 0 "register_operand" "=rf")
2801         (call (match_operand:SI 1 "" "")
2802               (match_operand 4 "" "")))]
2803   ;; operand 3 is next_arg_register
2804   ""
2805   "
2806 {
2807   rtx fn_rtx, nregs_rtx;
2808   rtvec vec;
2809
2810   fn_rtx = operands[1];
2811
2812 #if 0
2813   if (operands[3])
2814     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2815   else
2816     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2817 #else
2818   nregs_rtx = const0_rtx;
2819 #endif
2820
2821   vec = gen_rtvec (2,
2822                    gen_rtx (SET, VOIDmode, operands[0],
2823                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2824                    gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2825
2826   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2827
2828   DONE;
2829 }")
2830
2831 (define_insn ""
2832   [(set (match_operand 0 "" "=rf")
2833         (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2834               (match_operand 2 "" "")))
2835    (clobber (reg:SI 15))]
2836   ;;- Do not use operand 2 for most machines.
2837   ""
2838   "*
2839 {
2840   return \"call %a1,%2%#\";
2841 }"
2842   [(set_attr "type" "call")])
2843
2844 (define_expand "untyped_call"
2845   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2846                     (const_int 0))
2847               (match_operand:BLK 1 "memory_operand" "")
2848               (match_operand 2 "" "")
2849               (clobber (reg:SI 15))])]
2850   ""
2851   "
2852 {
2853   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
2854 }")
2855
2856 ;; Make a call followed by two nops in case the function being called
2857 ;; returns a structure value and expects to skip an unimp instruction.
2858
2859 (define_insn ""
2860   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "rS"))
2861          (const_int 0))
2862    (match_operand:DI 1 "memory_operand" "o")
2863    (match_operand 2 "" "")
2864    (clobber (reg:SI 15))]
2865   ""
2866   "*
2867 {
2868   operands[2] = adj_offsettable_operand (operands[1], 8);
2869   return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\";
2870 }"
2871   [(set_attr "type" "multi")])
2872
2873 ;; Prepare to return any type including a structure value.
2874
2875 (define_expand "untyped_return"
2876   [(match_operand:BLK 0 "memory_operand" "")
2877    (match_operand 1 "" "")]
2878   ""
2879   "
2880 {
2881   rtx valreg1 = gen_rtx (REG, DImode, 24);
2882   rtx valreg2 = gen_rtx (REG, DFmode, 32);
2883   rtx result = operands[0];
2884   rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
2885   rtx value = gen_reg_rtx (SImode);
2886
2887   /* Fetch the instruction where we will return to and see if it's an unimp
2888      instruction (the most significant 10 bits will be zero).  If so,
2889      update the return address to skip the unimp instruction.  */
2890   emit_move_insn (value,
2891                   gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
2892   emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
2893   emit_insn (gen_update_return (rtnreg, value));
2894
2895   /* Reload the function value registers.  */
2896   emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
2897   emit_move_insn (valreg2,
2898                   change_address (result, DFmode,
2899                                   plus_constant (XEXP (result, 0), 8)));
2900
2901   /* Put USE insns before the return.  */
2902   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
2903   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
2904
2905   /* Construct the return.  */
2906   expand_null_return ();
2907
2908   DONE;
2909 }")
2910
2911 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
2912 ;; and parts of the compiler don't want to believe that the add is needed.
2913
2914 (define_insn "update_return"
2915   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2916                (match_operand:SI 1 "register_operand" "r")] 0)]
2917   ""
2918   "cmp %1,0\;be,a .+8\;add %0,4,%0"
2919   [(set_attr "type" "multi")])
2920 \f
2921 (define_insn "return"
2922   [(return)]
2923   "! TARGET_EPILOGUE"
2924   "* return output_return (operands);"
2925   [(set_attr "type" "multi")])
2926
2927 (define_insn "nop"
2928   [(const_int 0)]
2929   ""
2930   "nop")
2931
2932 (define_insn "indirect_jump"
2933   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2934   ""
2935  "jmp %a0%#"
2936  [(set_attr "type" "uncond_branch")])
2937  
2938 (define_expand "nonlocal_goto"
2939   [(match_operand:SI 0 "general_operand" "")
2940    (match_operand:SI 1 "general_operand" "")
2941    (match_operand:SI 2 "general_operand" "")
2942    (match_operand:SI 3 "" "")]
2943   ""
2944   "
2945 {
2946   /* Trap instruction to flush all the registers window.  */
2947   emit_insn (gen_flush_register_windows ());
2948   /* Load the fp value for the containing fn into %fp.
2949      This is needed because operands[2] refers to %fp.
2950      Virtual register instantiation fails if the virtual %fp isn't set from a
2951      register.  Thus we must copy operands[0] into a register if it isn't
2952      already one.  */
2953   if (GET_CODE (operands[0]) != REG)
2954     operands[0] = force_reg (SImode, operands[0]);
2955   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2956   /* Find the containing function's current nonlocal goto handler,
2957      which will do any cleanups and then jump to the label.  */
2958   emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2959   /* Restore %fp from stack pointer value for containing function.
2960      The restore insn that follows will move this to %sp,
2961      and reload the appropriate value into %fp.  */
2962   emit_move_insn (frame_pointer_rtx, operands[2]);
2963   /* Put in the static chain register the nonlocal label address.  */
2964   emit_move_insn (static_chain_rtx, operands[3]);
2965   /* USE of frame_pointer_rtx added for consistency; not clear if
2966      really needed.  */
2967   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2968   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2969   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2970   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2971   /* Return, restoring reg window and jumping to goto handler.  */
2972   emit_insn (gen_goto_handler_and_restore ());
2973   DONE;
2974 }")
2975
2976 ;; Special trap insn to flush register windows.
2977 (define_insn "flush_register_windows"
2978   [(unspec_volatile [(const_int 0)] 0)]
2979   ""
2980   "ta 3"
2981   [(set_attr "type" "misc")])
2982
2983 (define_insn "goto_handler_and_restore"
2984   [(unspec_volatile [(const_int 0)] 1)]
2985   ""
2986   "jmp %%o0+0\;restore"
2987   [(set_attr "type" "misc")
2988    (set_attr "length" "2")])
2989 \f
2990 ;; find first set.
2991
2992 ;; The scan instruction searches from the most significant bit while ffs
2993 ;; searches from the least significant bit.  The bit index and treatment of
2994 ;; zero also differ.  It takes at least 7 instructions to get the proper
2995 ;; result.  Here is an obvious 8 instruction seequence.
2996
2997 (define_insn "ffssi2"
2998   [(set (match_operand:SI 0 "register_operand" "=&r")
2999         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
3000    (clobber (match_scratch:SI 2 "=&r"))]
3001   "TARGET_SPARCLITE"
3002   "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"
3003   [(set_attr "type" "multi")
3004    (set_attr "length" "8")])
3005 \f
3006 ;; Split up troublesome insns for better scheduling.  */
3007
3008 ;; The following patterns are straightforward.  They can be applied
3009 ;; either before or after register allocation.
3010
3011 (define_split
3012   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
3013         (match_operand 2 "reg_or_0_operand" ""))
3014    (clobber (match_operand:SI 3 "register_operand" ""))]
3015   "! flag_pic"
3016   [(set (match_dup 3) (high:SI (match_dup 1)))
3017    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
3018         (match_dup 2))]
3019   "")
3020
3021 (define_split
3022   [(set (match_operator 0 "memop"
3023                         [(match_operand:SI 1 "immediate_operand" "")])
3024         (match_operand 2 "general_operand" ""))
3025    (clobber (match_operand:SI 3 "register_operand" ""))]
3026   "flag_pic"
3027   [(set (match_op_dup 0 [(match_dup 1)])
3028         (match_dup 2))]
3029   "
3030 {
3031   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
3032                                         operands[3], 0);
3033 }")
3034
3035 (define_split
3036   [(set (match_operand 0 "register_operand" "")
3037         (match_operator 1 "memop"
3038                         [(match_operand:SI 2 "immediate_operand" "")]))]
3039   "flag_pic"
3040   [(set (match_dup 0)
3041         (match_op_dup 1 [(match_dup 2)]))]
3042   "
3043 {
3044   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
3045                                         operands[0], 0);
3046 }")
3047
3048 ;; Sign- and Zero-extend operations can have symbolic memory operands.
3049
3050 (define_split
3051   [(set (match_operand 0 "register_operand" "")
3052         (match_operator 1 "extend_op"
3053                         [(match_operator 2 "memop"
3054                                          [(match_operand:SI 3 "immediate_operand" "")])]))]
3055   "flag_pic"
3056   [(set (match_dup 0)
3057         (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
3058   "
3059 {
3060   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
3061                                         operands[0], 0);
3062 }")
3063
3064 (define_split
3065   [(set (match_operand:SI 0 "register_operand" "")
3066         (match_operand:SI 1 "immediate_operand" ""))]
3067   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3068                   || GET_CODE (operands[1]) == CONST
3069                   || GET_CODE (operands[1]) == LABEL_REF)"
3070   [(set (match_dup 0) (high:SI (match_dup 1)))
3071    (set (match_dup 0)
3072         (lo_sum:SI (match_dup 0) (match_dup 1)))]
3073   "")
3074
3075 ;; LABEL_REFs are not modified by `legitimize_pic_address`
3076 ;; so do not recurse infinitely in the PIC case.
3077 (define_split
3078   [(set (match_operand:SI 0 "register_operand" "")
3079         (match_operand:SI 1 "immediate_operand" ""))]
3080   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3081                 || GET_CODE (operands[1]) == CONST)"
3082   [(set (match_dup 0) (match_dup 1))]
3083   "
3084 {
3085   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
3086 }")
3087 \f
3088 ;; These split sne/seq insns.  The forms of the resulting insns are 
3089 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
3090 ;; Nothing will look at these in detail after splitting has occurred.
3091
3092 (define_split
3093   [(set (match_operand:SI 0 "register_operand" "")
3094         (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3095    (clobber (reg:CC 0))]
3096   ""
3097   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3098                                          (const_int 0)))
3099    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
3100   "")
3101
3102 (define_split
3103   [(set (match_operand:SI 0 "register_operand" "")
3104         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3105                        (const_int 0))))
3106    (clobber (reg:CC 0))]
3107   ""
3108   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3109                                          (const_int 0)))
3110    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
3111   "")
3112
3113 (define_split
3114   [(set (match_operand:SI 0 "register_operand" "")
3115         (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3116    (clobber (reg:CC 0))]
3117   ""
3118   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3119                                          (const_int 0)))
3120    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
3121   "")
3122
3123 (define_split
3124   [(set (match_operand:SI 0 "register_operand" "")
3125         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3126                        (const_int 0))))
3127    (clobber (reg:CC 0))]
3128   ""
3129   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3130                                          (const_int 0)))
3131    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
3132   "")
3133
3134 (define_split
3135   [(set (match_operand:SI 0 "register_operand" "")
3136         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3137                         (const_int 0))
3138                  (match_operand:SI 2 "register_operand" "")))
3139    (clobber (reg:CC 0))]
3140   ""
3141   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3142                                          (const_int 0)))
3143    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
3144                                (match_dup 2)))]
3145   "")
3146
3147 (define_split
3148   [(set (match_operand:SI 0 "register_operand" "")
3149         (minus:SI (match_operand:SI 2 "register_operand" "")
3150                   (ne:SI (match_operand:SI 1 "register_operand" "")
3151                          (const_int 0))))
3152    (clobber (reg:CC 0))]
3153   ""
3154   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3155                                          (const_int 0)))
3156    (set (match_dup 0) (minus:SI (match_dup 2)
3157                                 (ltu:SI (reg:CC 0) (const_int 0))))]
3158   "")
3159
3160 (define_split
3161   [(set (match_operand:SI 0 "register_operand" "")
3162         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3163                         (const_int 0))
3164                  (match_operand:SI 2 "register_operand" "")))
3165    (clobber (reg:CC 0))]
3166   ""
3167   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3168                                          (const_int 0)))
3169    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
3170                                (match_dup 2)))]
3171   "")
3172
3173 (define_split
3174   [(set (match_operand:SI 0 "register_operand" "")
3175         (minus:SI (match_operand:SI 2 "register_operand" "")
3176                   (eq:SI (match_operand:SI 1 "register_operand" "")
3177                          (const_int 0))))
3178    (clobber (reg:CC 0))]
3179   ""
3180   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3181                                          (const_int 0)))
3182    (set (match_dup 0) (minus:SI (match_dup 2)
3183                                 (geu:SI (reg:CC 0) (const_int 0))))]
3184   "")
3185 \f
3186 ;; Peepholes go at the end.
3187
3188 ;; Optimize consecutive loads or stores into ldd and std when possible.
3189 ;; The conditions in which we do this are very restricted and are 
3190 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3191
3192 (define_peephole
3193   [(set (match_operand:SI 0 "register_operand" "=rf")
3194         (match_operand:SI 1 "memory_operand" ""))
3195    (set (match_operand:SI 2 "register_operand" "=rf")
3196         (match_operand:SI 3 "memory_operand" ""))]
3197   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3198    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3199    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
3200   "ldd %1,%0")
3201
3202 (define_peephole
3203   [(set (match_operand:SI 0 "memory_operand" "")
3204         (match_operand:SI 1 "register_operand" "rf"))
3205    (set (match_operand:SI 2 "memory_operand" "")
3206         (match_operand:SI 3 "register_operand" "rf"))]
3207   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3208    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3209    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3210   "std %1,%0")
3211  
3212 (define_peephole
3213   [(set (match_operand:SF 0 "register_operand" "=fr")
3214         (match_operand:SF 1 "memory_operand" ""))
3215    (set (match_operand:SF 2 "register_operand" "=fr")
3216         (match_operand:SF 3 "memory_operand" ""))]
3217   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3218    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3219    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3220   "ldd %1,%0")
3221
3222 (define_peephole
3223   [(set (match_operand:SF 0 "memory_operand" "")
3224         (match_operand:SF 1 "register_operand" "fr"))
3225    (set (match_operand:SF 2 "memory_operand" "")
3226         (match_operand:SF 3 "register_operand" "fr"))]
3227   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3228    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3229    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3230   "std %1,%0")
3231
3232 (define_peephole
3233   [(set (match_operand:SI 0 "register_operand" "=rf")
3234         (match_operand:SI 1 "memory_operand" ""))
3235    (set (match_operand:SI 2 "register_operand" "=rf")
3236         (match_operand:SI 3 "memory_operand" ""))]
3237   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3238    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3239    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3240   "ldd %3,%2")
3241
3242 (define_peephole
3243   [(set (match_operand:SI 0 "memory_operand" "")
3244         (match_operand:SI 1 "register_operand" "rf"))
3245    (set (match_operand:SI 2 "memory_operand" "")
3246         (match_operand:SI 3 "register_operand" "rf"))]
3247   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3248    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3249    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
3250   "std %3,%2")
3251  
3252 (define_peephole
3253   [(set (match_operand:SF 0 "register_operand" "=fr")
3254         (match_operand:SF 1 "memory_operand" ""))
3255    (set (match_operand:SF 2 "register_operand" "=fr")
3256         (match_operand:SF 3 "memory_operand" ""))]
3257   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3258    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3259    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3260   "ldd %3,%2")
3261
3262 (define_peephole
3263   [(set (match_operand:SF 0 "memory_operand" "")
3264         (match_operand:SF 1 "register_operand" "fr"))
3265    (set (match_operand:SF 2 "memory_operand" "")
3266         (match_operand:SF 3 "register_operand" "fr"))]
3267   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3268    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3269    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3270   "std %3,%2")
3271  
3272 ;; Optimize the case of following a reg-reg move with a test
3273 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
3274 ;; This can result from a float to fix conversion.
3275
3276 (define_peephole
3277   [(set (match_operand:SI 0 "register_operand" "=r")
3278         (match_operand:SI 1 "register_operand" "r"))
3279    (set (reg:CC 0)
3280         (compare:CC (match_operand:SI 2 "register_operand" "r")
3281                     (const_int 0)))]
3282   "(rtx_equal_p (operands[2], operands[0])
3283     || rtx_equal_p (operands[2], operands[1]))
3284    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3285   "orcc %1,%%g0,%0")
3286
3287 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3288 ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
3289 ;;     eventually have some impact here?
3290
3291 (define_peephole
3292   [(set (match_operand:HI 0 "register_operand" "")
3293         (match_operand:HI 1 "memory_operand" ""))
3294    (set (match_operand:SI 2 "register_operand" "")
3295         (sign_extend:SI (match_dup 0)))
3296    (set (reg:CC 0)
3297         (compare:CC (match_dup 2)
3298                     (const_int 0)))]
3299   ""
3300   "ldsh %1,%0\;orcc %0,%%g0,%2")
3301
3302 (define_peephole
3303   [(set (match_operand:QI 0 "register_operand" "")
3304         (match_operand:QI 1 "memory_operand" ""))
3305    (set (match_operand:SI 2 "register_operand" "")
3306         (sign_extend:SI (match_dup 0)))
3307    (set (reg:CC 0)
3308         (compare:CC (match_dup 2)
3309                     (const_int 0)))]
3310   ""
3311   "ldsb %1,%0\;orcc %0,%%g0,%2")
3312
3313 (define_peephole
3314   [(set (match_operand:HI 0 "register_operand" "")
3315         (match_operand:HI 1 "memory_operand" ""))
3316    (set (match_operand:SI 2 "register_operand" "")
3317         (sign_extend:SI (match_dup 0)))]
3318   "dead_or_set_p (insn, operands[0])"
3319   "*
3320 {
3321   warning (\"bad peephole\");
3322   if (! MEM_VOLATILE_P (operands[1]))
3323     abort ();
3324   return \"ldsh %1,%2\";
3325 }")
3326
3327 (define_peephole
3328   [(set (match_operand:QI 0 "register_operand" "")
3329         (match_operand:QI 1 "memory_operand" ""))
3330    (set (match_operand:SI 2 "register_operand" "")
3331         (sign_extend:SI (match_dup 0)))]
3332   "dead_or_set_p (insn, operands[0])"
3333   "*
3334 {
3335   warning (\"bad peephole\");
3336   if (! MEM_VOLATILE_P (operands[1]))
3337     abort ();
3338   return \"ldsb %1,%2\";
3339 }")
3340
3341 ;; Floating-point move peepholes
3342
3343 (define_peephole
3344   [(set (match_operand:SI 0 "register_operand" "=r")
3345         (lo_sum:SI (match_dup 0)
3346                    (match_operand:SI 1 "immediate_operand" "i")))
3347    (set (match_operand:DF 2 "register_operand" "=fr")
3348         (mem:DF (match_dup 0)))]
3349   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3350   "*
3351 {
3352   /* Go by way of output_move_double in case the register in operand 2
3353      is not properly aligned for ldd.  */
3354   operands[1] = gen_rtx (MEM, DFmode,
3355                          gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3356   operands[0] = operands[2];
3357   return output_move_double (operands);
3358 }")
3359
3360 (define_peephole
3361   [(set (match_operand:SI 0 "register_operand" "=r")
3362         (lo_sum:SI (match_dup 0)
3363                    (match_operand:SI 1 "immediate_operand" "i")))
3364    (set (match_operand:SF 2 "register_operand" "=fr")
3365         (mem:SF (match_dup 0)))]
3366   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3367   "ld [%0+%%lo(%a1)],%2")
3368
3369 ;; Return peepholes.  First the "normal" ones
3370
3371 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3372 ;; It might be possible to write one more general pattern instead of three.
3373
3374 (define_insn ""
3375   [(set (match_operand:QI 0 "restore_operand" "")
3376         (match_operand:QI 1 "arith_operand" "rI"))
3377    (return)]
3378   "! TARGET_EPILOGUE"
3379   "*
3380 {
3381   if (current_function_returns_struct)
3382     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3383   else
3384     return \"ret\;restore %%g0,%1,%Y0\";
3385 }"
3386   [(set_attr "type" "multi")])
3387
3388 (define_insn ""
3389   [(set (match_operand:HI 0 "restore_operand" "")
3390         (match_operand:HI 1 "arith_operand" "rI"))
3391    (return)]
3392   "! TARGET_EPILOGUE"
3393   "*
3394 {
3395   if (current_function_returns_struct)
3396     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3397   else
3398     return \"ret\;restore %%g0,%1,%Y0\";
3399 }"
3400   [(set_attr "type" "multi")])
3401
3402 (define_insn ""
3403   [(set (match_operand:SI 0 "restore_operand" "")
3404         (match_operand:SI 1 "arith_operand" "rI"))
3405    (return)]
3406   "! TARGET_EPILOGUE"
3407   "*
3408 {
3409   if (current_function_returns_struct)
3410     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3411   else
3412     return \"ret\;restore %%g0,%1,%Y0\";
3413 }"
3414   [(set_attr "type" "multi")])
3415
3416 ;; The following pattern is only generated by delayed-branch scheduling,
3417 ;; when the insn winds up in the epilogue.  This can only happen when
3418 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3419 (define_insn ""
3420   [(set (match_operand:SF 0 "restore_operand" "r")
3421         (match_operand:SF 1 "register_operand" "r"))
3422    (return)]
3423   "! TARGET_FPU && ! TARGET_EPILOGUE"
3424   "*
3425 {
3426   if (current_function_returns_struct)
3427     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3428   else
3429     return \"ret\;restore %%g0,%1,%Y0\";
3430 }"
3431   [(set_attr "type" "multi")])
3432
3433 (define_insn ""
3434   [(set (match_operand:SI 0 "restore_operand" "")
3435         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3436                  (match_operand:SI 2 "arith_operand" "rI")))
3437    (return)]
3438   "! TARGET_EPILOGUE"
3439   "*
3440 {
3441   if (current_function_returns_struct)
3442     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3443   else
3444     return \"ret\;restore %r1,%2,%Y0\";
3445 }"
3446   [(set_attr "type" "multi")])
3447
3448 ;; Turned off because it should never match (subtracting a constant
3449 ;; is turned into addition) and because it would do the wrong thing
3450 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3451 ;;(define_insn ""
3452 ;;  [(set (match_operand:SI 0 "restore_operand" "")
3453 ;;      (minus:SI (match_operand:SI 1 "register_operand" "r")
3454 ;;                (match_operand:SI 2 "small_int" "I")))
3455 ;;   (return)]
3456 ;;  "! TARGET_EPILOGUE"
3457 ;;  "ret\;restore %1,-(%2),%Y0"
3458 ;;  [(set_attr "type" "multi")])
3459
3460 ;; The following pattern is only generated by delayed-branch scheduling,
3461 ;; when the insn winds up in the epilogue.
3462 (define_insn ""
3463   [(set (reg:SF 32)
3464         (match_operand:SF 0 "register_operand" "f"))
3465    (return)]
3466   "! TARGET_EPILOGUE"
3467   "ret\;fmovs %0,%%f0"
3468   [(set_attr "type" "multi")])
3469
3470 ;; Now peepholes to go a call followed by a jump.
3471
3472 (define_peephole
3473   [(parallel [(set (match_operand 0 "" "")
3474                    (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3475                          (match_operand 2 "" "")))
3476               (clobber (reg:SI 15))])
3477    (set (pc) (label_ref (match_operand 3 "" "")))]
3478   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3479   "*
3480 {
3481   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3482 }")
3483
3484 (define_peephole
3485   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3486                     (match_operand 1 "" ""))
3487               (clobber (reg:SI 15))])
3488    (set (pc) (label_ref (match_operand 2 "" "")))]
3489   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3490   "*
3491 {
3492   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3493 }")
3494
3495 (define_peephole
3496   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3497                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3498                              (reg:SI 0)))
3499               (clobber (reg:CC 0))])
3500    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3501   ""
3502   "subxcc %r1,0,%0")