OSDN Git Service

Cosmetic changes only. Just reordered code a little.
[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 "movqi"
776   [(set (match_operand:QI 0 "general_operand" "")
777         (match_operand:QI 1 "general_operand" ""))]
778   ""
779   "
780 {
781   if (emit_move_sequence (operands, QImode))
782     DONE;
783 }")
784
785 (define_insn ""
786   [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
787         (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
788   "register_operand (operands[0], QImode)
789    || register_operand (operands[1], QImode)
790    || operands[1] == const0_rtx"
791   "@
792    mov %1,%0
793    sethi %%hi(%a1),%0
794    ldub %1,%0
795    stb %r1,%0"
796   [(set_attr "type" "move,move,load,store")
797    (set_attr "length" "*,1,*,1")])
798
799 (define_insn ""
800   [(set (match_operand:QI 0 "register_operand" "=r")
801         (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
802                               (match_operand 2 "immediate_operand" "in")) 0))]
803   ""
804   "or %1,%%lo(%a2),%0"
805   [(set_attr "length" "1")])
806
807 (define_insn ""
808   [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
809         (match_operand:QI 1 "reg_or_0_operand" "rJ"))
810    (clobber (match_scratch:SI 2 "=&r"))]
811   ""
812   "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
813   [(set_attr "type" "store")
814    (set_attr "length" "2")])
815
816 (define_expand "movhi"
817   [(set (match_operand:HI 0 "general_operand" "")
818         (match_operand:HI 1 "general_operand" ""))]
819   ""
820   "
821 {
822   if (emit_move_sequence (operands, HImode))
823     DONE;
824 }")
825
826 (define_insn ""
827   [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
828         (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
829   "register_operand (operands[0], HImode)
830    || register_operand (operands[1], HImode)
831    || operands[1] == const0_rtx"
832   "@
833    mov %1,%0
834    sethi %%hi(%a1),%0
835    lduh %1,%0
836    sth %r1,%0"
837   [(set_attr "type" "move,move,load,store")
838    (set_attr "length" "*,1,*,1")])
839
840 (define_insn ""
841   [(set (match_operand:HI 0 "register_operand" "=r")
842         (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
843                    (match_operand 2 "immediate_operand" "in")))]
844   ""
845   "or %1,%%lo(%a2),%0"
846   [(set_attr "length" "1")])
847
848 (define_insn ""
849   [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
850         (match_operand:HI 1 "reg_or_0_operand" "rJ"))
851    (clobber (match_scratch:SI 2 "=&r"))]
852   ""
853   "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
854   [(set_attr "type" "store")
855    (set_attr "length" "2")])
856
857 (define_expand "movsi"
858   [(set (match_operand:SI 0 "general_operand" "")
859         (match_operand:SI 1 "general_operand" ""))]
860   ""
861   "
862 {
863   if (emit_move_sequence (operands, SImode))
864     DONE;
865 }")
866
867 ;; We must support both 'r' and 'f' registers here, because combine may
868 ;; convert SFmode hard registers to SImode hard registers when simplifying
869 ;; subreg sets.
870
871 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
872 ;; problems with register allocation.  Reload might try to put an integer
873 ;; in an fp register, or an fp number is an integer register.
874
875 (define_insn ""
876   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q")
877         (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))]
878   "register_operand (operands[0], SImode)
879    || register_operand (operands[1], SImode)
880    || operands[1] == const0_rtx"
881   "@
882    mov %1,%0
883    fmovs %1,%0
884    sethi %%hi(%a1),%0
885    ld %1,%0
886    ld %1,%0
887    st %r1,%0
888    st %r1,%0"
889   [(set_attr "type" "move,fp,move,load,load,store,store")
890    (set_attr "length" "*,*,1,*,*,*,*")])
891
892 ;; Special pic pattern, for loading the address of a label into a register.
893 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
894 ;; there.
895
896 (define_insn ""
897   [(set (match_operand:SI 0 "register_operand" "=r")
898         (match_operand:SI 1 "move_pic_label" "i"))
899    (set (reg:SI 15) (pc))]
900   ""
901   "\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0"
902   [(set_attr "type" "multi")
903    (set_attr "length" "4")])
904
905 (define_insn ""
906   [(set (match_operand:DI 0 "register_operand" "=r")
907         (high:DI (match_operand 1 "" "")))]
908   "check_pic (1)"
909   "*
910 {
911   rtx op0 = operands[0];
912   rtx op1 = operands[1];
913
914   if (GET_CODE (op1) == CONST_INT)
915     {
916       operands[0] = operand_subword (op0, 1, 0, DImode);
917       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
918
919       operands[0] = operand_subword (op0, 0, 0, DImode);
920       if (INTVAL (op1) < 0)
921         return \"mov -1,%0\";
922       else
923         return \"mov 0,%0\";
924     }
925   else if (GET_CODE (op1) == CONST_DOUBLE)
926     {
927       operands[0] = operand_subword (op0, 1, 0, DImode);
928       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1));
929       output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
930
931       operands[0] = operand_subword (op0, 0, 0, DImode);
932       operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1));
933       return singlemove_string (operands);
934     }
935   else
936     abort ();
937   return \"\";
938 }"
939   [(set_attr "type" "move")
940    (set_attr "length" "2")])
941
942 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
943 ;; confuse them with real addresses.
944 (define_insn ""
945   [(set (match_operand:SI 0 "register_operand" "=r")
946         (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
947   "check_pic (1)"
948   "sethi %%hi(%a1),%0"
949   [(set_attr "type" "move")
950    (set_attr "length" "1")])
951
952 (define_insn ""
953   [(set (match_operand:SI 0 "register_operand" "=r")
954         (high:SI (match_operand 1 "" "")))]
955   "check_pic (1)"
956   "sethi %%hi(%a1),%0"
957   [(set_attr "type" "move")
958    (set_attr "length" "1")])
959
960 (define_insn ""
961   [(set (match_operand:HI 0 "register_operand" "=r")
962         (high:HI (match_operand 1 "" "")))]
963   "check_pic (1)"
964   "sethi %%hi(%a1),%0"
965   [(set_attr "type" "move")
966    (set_attr "length" "1")])
967
968 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
969 ;; confuse them with real addresses.
970 (define_insn ""
971   [(set (match_operand:SI 0 "register_operand" "=r")
972         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
973                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
974   ""
975   "or %1,%%lo(%a2),%0"
976   ;; Need to set length for this arith insn because operand2
977   ;; is not an "arith_operand".
978   [(set_attr "length" "1")])
979
980 ;; ??? Can the next two be moved above the PIC stuff?
981
982 (define_insn ""
983   [(set (match_operand:SI 0 "register_operand" "=r")
984         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
985                    (match_operand:SI 2 "immediate_operand" "in")))]
986   ""
987   "or %1,%%lo(%a2),%0"
988   ;; Need to set length for this arith insn because operand2
989   ;; is not an "arith_operand".
990   [(set_attr "length" "1")])
991
992 (define_insn ""
993   [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
994         (match_operand:SI 1 "reg_or_0_operand" "rJ"))
995    (clobber (match_scratch:SI 2 "=&r"))]
996   ""
997   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
998   [(set_attr "type" "store")
999    (set_attr "length" "2")])
1000
1001 (define_expand "movdi"
1002   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
1003         (match_operand:DI 1 "general_operand" ""))]
1004   ""
1005   "
1006 {
1007   if (emit_move_sequence (operands, DImode))
1008     DONE;
1009 }")
1010
1011 (define_insn ""
1012   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,r,r,?f,?f,?Q")
1013         (match_operand:DI 1 "general_operand" "r,r,Q,i,f,Q,f"))]
1014   "register_operand (operands[0], DImode)
1015    || register_operand (operands[1], DImode)
1016    || operands[1] == const0_rtx"
1017   "*
1018 {
1019   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1020     return output_fp_move_double (operands);
1021   return output_move_double (operands);
1022 }"
1023   [(set_attr "type" "move,store,load,multi,fp,fpload,fpstore")
1024    (set_attr "length" "2,3,3,3,2,3,3")])
1025
1026 (define_insn ""
1027   [(set (match_operand:DI 0 "register_operand" "=r")
1028         (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1029                    (match_operand:DI 2 "immediate_operand" "in")))]
1030   ""
1031   "*
1032 {
1033   /* Don't output a 64 bit constant, since we can't trust the assembler to
1034      handle it correctly.  */
1035   if (GET_CODE (operands[2]) == CONST_DOUBLE)
1036     operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2]));
1037   return \"or %R1,%%lo(%a2),%R0\";
1038 }"
1039   ;; Need to set length for this arith insn because operand2
1040   ;; is not an "arith_operand".
1041   [(set_attr "length" "1")])
1042
1043 ;; ??? There's no symbolic (set (mem:DI ...) ...).
1044 \f
1045 ;; Block move insns.
1046
1047 ;; ??? We get better code without it.  See output_block_move in sparc.c.
1048
1049 ;; The definition of this insn does not really explain what it does,
1050 ;; but it should suffice
1051 ;; that anything generated as this insn will be recognized as one
1052 ;; and that it will not successfully combine with anything.
1053 ;(define_expand "movstrsi"
1054 ;  [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
1055 ;                  (mem:BLK (match_operand:BLK 1 "general_operand" "")))
1056 ;             (use (match_operand:SI 2 "nonmemory_operand" ""))
1057 ;             (use (match_operand:SI 3 "immediate_operand" ""))
1058 ;             (clobber (match_dup 0))
1059 ;             (clobber (match_dup 1))
1060 ;             (clobber (match_scratch:SI 4 ""))
1061 ;             (clobber (reg:SI 0))
1062 ;             (clobber (reg:SI 1))])]
1063 ;  ""
1064 ;  "
1065 ;{
1066 ;  /* If the size isn't known, don't emit inline code.  output_block_move
1067 ;     would output code that's much slower than the library function.
1068 ;     Also don't output code for large blocks.  */
1069 ;  if (GET_CODE (operands[2]) != CONST_INT
1070 ;      || GET_CODE (operands[3]) != CONST_INT
1071 ;      || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
1072 ;    FAIL;
1073 ;
1074 ;  operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1075 ;  operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1076 ;  operands[2] = force_not_mem (operands[2]);
1077 ;}")
1078
1079 ;(define_insn ""
1080 ;  [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
1081 ;       (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
1082 ;   (use (match_operand:SI 2 "nonmemory_operand" "rn"))
1083 ;   (use (match_operand:SI 3 "immediate_operand" "i"))
1084 ;   (clobber (match_dup 0))
1085 ;   (clobber (match_dup 1))
1086 ;   (clobber (match_scratch:SI 4 "=&r"))
1087 ;   (clobber (reg:SI 0))
1088 ;   (clobber (reg:SI 1))]
1089 ;  ""
1090 ;  "* return output_block_move (operands);"
1091 ;  [(set_attr "type" "multi")
1092 ;   (set_attr "length" "6")])
1093 \f
1094 ;; Floating point move insns
1095
1096 ;; This pattern forces (set (reg:SF ...) (const_double ...))
1097 ;; to be reloaded by putting the constant into memory.
1098 ;; It must come before the more general movsf pattern.
1099 (define_insn ""
1100   [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
1101         (match_operand:SF 1 "" "?E,m,G"))]
1102   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1103   "*
1104 {
1105   switch (which_alternative)
1106     {
1107     case 0:
1108       return singlemove_string (operands);
1109     case 1:
1110       return \"ld %1,%0\";
1111     case 2:
1112       return \"st %%g0,%0\";
1113     }
1114 }"
1115   [(set_attr "type" "load,fpload,store")
1116    (set_attr "length" "2,1,1")])
1117
1118 (define_expand "movsf"
1119   [(set (match_operand:SF 0 "general_operand" "")
1120         (match_operand:SF 1 "general_operand" ""))]
1121   ""
1122   "
1123 {
1124   if (emit_move_sequence (operands, SFmode))
1125     DONE;
1126 }")
1127
1128 (define_insn ""
1129   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
1130         (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
1131   "TARGET_FPU
1132    && (register_operand (operands[0], SFmode)
1133        || register_operand (operands[1], SFmode))"
1134   "@
1135    fmovs %1,%0
1136    mov %1,%0
1137    ld %1,%0
1138    ld %1,%0
1139    st %r1,%0
1140    st %r1,%0"
1141   [(set_attr "type" "fp,move,fpload,load,fpstore,store")])
1142
1143 ;; Exactly the same as above, except that all `f' cases are deleted.
1144 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1145 ;; when -mno-fpu.
1146
1147 (define_insn ""
1148   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
1149         (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
1150   "! TARGET_FPU
1151    && (register_operand (operands[0], SFmode)
1152        || register_operand (operands[1], SFmode))"
1153   "@
1154    mov %1,%0
1155    ld %1,%0
1156    st %r1,%0"
1157   [(set_attr "type" "move,load,store")])
1158
1159 (define_insn ""
1160   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
1161         (match_operand:SF 1 "reg_or_0_operand" "rfG"))
1162    (clobber (match_scratch:SI 2 "=&r"))]
1163   ""
1164   "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
1165   [(set_attr "type" "store")
1166    (set_attr "length" "2")])
1167
1168 ;; This pattern forces (set (reg:DF ...) (const_double ...))
1169 ;; to be reloaded by putting the constant into memory.
1170 ;; It must come before the more general movdf pattern.
1171
1172 (define_insn ""
1173   [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
1174         (match_operand:DF 1 "" "?E,m,G"))]
1175   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1176   "*
1177 {
1178   switch (which_alternative)
1179     {
1180     case 0:
1181       return output_move_double (operands);
1182     case 1:
1183       return output_fp_move_double (operands);
1184     case 2:
1185       operands[1] = adj_offsettable_operand (operands[0], 4);
1186       return \"st %%g0,%0\;st %%g0,%1\";
1187     }
1188 }"
1189   [(set_attr "type" "load,fpload,store")
1190    (set_attr "length" "3,3,3")])
1191
1192 (define_expand "movdf"
1193   [(set (match_operand:DF 0 "general_operand" "")
1194         (match_operand:DF 1 "general_operand" ""))]
1195   ""
1196   "
1197 {
1198   if (emit_move_sequence (operands, DFmode))
1199     DONE;
1200 }")
1201
1202 (define_insn ""
1203   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,r")
1204         (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q"))]
1205   "TARGET_FPU
1206    && (register_operand (operands[0], DFmode)
1207        || register_operand (operands[1], DFmode))"
1208   "*
1209 {
1210   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1211     return output_fp_move_double (operands);
1212   return output_move_double (operands);
1213 }"
1214   [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
1215    (set_attr "length" "1,1,2,2,3,3,3,3")])
1216
1217 ;; Exactly the same as above, except that all `f' cases are deleted.
1218 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1219 ;; when -mno-fpu.
1220
1221 (define_insn ""
1222   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
1223         (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
1224   "! TARGET_FPU
1225    && (register_operand (operands[0], DFmode)
1226        || register_operand (operands[1], DFmode))"
1227   "* return output_move_double (operands);"
1228   [(set_attr "type" "store,load,move,store,load")
1229    (set_attr "length" "1,1,2,3,3")])
1230
1231 (define_split
1232   [(set (match_operand:DF 0 "register_operand" "")
1233         (match_operand:DF 1 "register_operand" ""))]
1234   "reload_completed"
1235   [(set (match_dup 2) (match_dup 3))
1236    (set (match_dup 4) (match_dup 5))]
1237   "
1238 { operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1239   operands[3] = operand_subword (operands[1], 0, 0, DFmode);
1240   operands[4] = operand_subword (operands[0], 1, 0, DFmode);
1241   operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
1242
1243 (define_insn ""
1244   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
1245         (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
1246    (clobber (match_scratch:SI 2 "=&r,&r"))]
1247   ""
1248   "*
1249 {
1250   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1251   if (which_alternative == 0)
1252     return \"std %1,[%2+%%lo(%a0)]\";
1253   else
1254     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
1255 }"
1256   [(set_attr "type" "store")
1257    (set_attr "length" "3")])
1258
1259 ;; This pattern forces (set (reg:TF ...) (const_double ...))
1260 ;; to be reloaded by putting the constant into memory.
1261 ;; It must come before the more general movtf pattern.
1262 (define_insn ""
1263   [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
1264         (match_operand:TF 1 "" "?E,m,G"))]
1265   "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
1266   "*
1267 {
1268   switch (which_alternative)
1269     {
1270     case 0:
1271       return output_move_quad (operands);
1272     case 1:
1273       return output_fp_move_quad (operands);
1274     case 2:
1275       operands[1] = adj_offsettable_operand (operands[0], 4);
1276       operands[2] = adj_offsettable_operand (operands[0], 8);
1277       operands[3] = adj_offsettable_operand (operands[0], 12);
1278       return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
1279     }
1280 }"
1281   [(set_attr "type" "load,fpload,store")
1282    (set_attr "length" "5,5,5")])
1283
1284 (define_expand "movtf"
1285   [(set (match_operand:TF 0 "general_operand" "")
1286         (match_operand:TF 1 "general_operand" ""))]
1287   ""
1288   "
1289 {
1290   if (emit_move_sequence (operands, TFmode))
1291     DONE;
1292 }")
1293
1294 (define_insn ""
1295   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r")
1296         (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q"))]
1297   "TARGET_FPU
1298    && (register_operand (operands[0], TFmode)
1299        || register_operand (operands[1], TFmode))"
1300   "*
1301 {
1302   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1303     return output_fp_move_quad (operands);
1304   return output_move_quad (operands);
1305 }"
1306   [(set_attr "type" "fp,move,fpstore,store,fpload,load")
1307    (set_attr "length" "4,4,5,5,5,5")])
1308
1309 ;; Exactly the same as above, except that all `f' cases are deleted.
1310 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1311 ;; when -mno-fpu.
1312
1313 (define_insn ""
1314   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
1315         (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
1316   "! TARGET_FPU
1317    && (register_operand (operands[0], TFmode)
1318        || register_operand (operands[1], TFmode))"
1319   "*
1320 {
1321   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
1322     return output_fp_move_quad (operands);
1323   return output_move_quad (operands);
1324 }"
1325   [(set_attr "type" "move,store,load")
1326    (set_attr "length" "4,5,5")])
1327
1328 (define_insn ""
1329   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
1330         (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
1331    (clobber (match_scratch:SI 2 "=&r,&r"))]
1332   ""
1333   "*
1334 {
1335   output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
1336   if (which_alternative == 0)
1337     return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
1338   else
1339     return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
1340 }"
1341   [(set_attr "type" "store")
1342    (set_attr "length" "5")])
1343 \f
1344 ;;- zero extension instructions
1345
1346 ;; These patterns originally accepted general_operands, however, slightly
1347 ;; better code is generated by only accepting register_operands, and then
1348 ;; letting combine generate the ldu[hb] insns.
1349
1350 (define_expand "zero_extendhisi2"
1351   [(set (match_operand:SI 0 "register_operand" "")
1352         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1353   ""
1354   "
1355 {
1356   rtx temp = gen_reg_rtx (SImode);
1357   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1358   int op1_subword = 0;
1359
1360   if (GET_CODE (operand1) == SUBREG)
1361     {
1362       op1_subword = SUBREG_WORD (operand1);
1363       operand1 = XEXP (operand1, 0);
1364     }
1365
1366   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1367                                          op1_subword),
1368                           shift_16));
1369   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1370   DONE;
1371 }")
1372
1373 (define_insn ""
1374   [(set (match_operand:SI 0 "register_operand" "=r")
1375         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1376   ""
1377   "lduh %1,%0"
1378   [(set_attr "type" "load")])
1379
1380 (define_expand "zero_extendqihi2"
1381   [(set (match_operand:HI 0 "register_operand" "")
1382         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
1383   ""
1384   "")
1385
1386 (define_insn ""
1387   [(set (match_operand:HI 0 "register_operand" "=r,r")
1388         (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1389   "GET_CODE (operands[1]) != CONST_INT"
1390   "@
1391    and %1,0xff,%0
1392    ldub %1,%0"
1393   [(set_attr "type" "unary,load")
1394    (set_attr "length" "1")])
1395
1396 (define_expand "zero_extendqisi2"
1397   [(set (match_operand:SI 0 "register_operand" "")
1398         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1399   ""
1400   "")
1401
1402 (define_insn ""
1403   [(set (match_operand:SI 0 "register_operand" "=r,r")
1404         (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
1405   "GET_CODE (operands[1]) != CONST_INT"
1406   "@
1407    and %1,0xff,%0
1408    ldub %1,%0"
1409   [(set_attr "type" "unary,load")
1410    (set_attr "length" "1")])
1411
1412 (define_insn ""
1413   [(set (reg:CC 0)
1414         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1415                     (const_int 0)))]
1416   ""
1417   "andcc %0,0xff,%%g0"
1418   [(set_attr "type" "compare")])
1419
1420 (define_insn ""
1421   [(set (reg:CC 0)
1422         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1423                     (const_int 0)))
1424    (set (match_operand:SI 0 "register_operand" "=r")
1425         (zero_extend:SI (match_dup 1)))]
1426   ""
1427   "andcc %1,0xff,%0"
1428   [(set_attr "type" "unary")])
1429
1430 ;; Similarly, handle SI->QI mode truncation followed by a compare.
1431
1432 (define_insn ""
1433   [(set (reg:CC 0)
1434         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
1435                     (const_int 0)))]
1436   ""
1437   "andcc %0,0xff,%%g0"
1438   [(set_attr "type" "compare")])
1439
1440 (define_insn ""
1441   [(set (reg:CC 0)
1442         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
1443                     (const_int 0)))
1444    (set (match_operand:QI 0 "register_operand" "=r")
1445         (match_dup 1))]
1446   ""
1447   "andcc %1,0xff,%0"
1448   [(set_attr "type" "unary")])
1449 \f
1450 ;;- sign extension instructions
1451
1452 ;; These patterns originally accepted general_operands, however, slightly
1453 ;; better code is generated by only accepting register_operands, and then
1454 ;; letting combine generate the lds[hb] insns.
1455
1456 (define_expand "extendhisi2"
1457   [(set (match_operand:SI 0 "register_operand" "")
1458         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1459   ""
1460   "
1461 {
1462   rtx temp = gen_reg_rtx (SImode);
1463   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1464   int op1_subword = 0;
1465
1466   if (GET_CODE (operand1) == SUBREG)
1467     {
1468       op1_subword = SUBREG_WORD (operand1);
1469       operand1 = XEXP (operand1, 0);
1470     }
1471
1472   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1473                                          op1_subword),
1474                           shift_16));
1475   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1476   DONE;
1477 }")
1478
1479 (define_insn ""
1480   [(set (match_operand:SI 0 "register_operand" "=r")
1481         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1482   ""
1483   "ldsh %1,%0"
1484   [(set_attr "type" "load")])
1485
1486 (define_expand "extendqihi2"
1487   [(set (match_operand:HI 0 "register_operand" "")
1488         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1489   ""
1490   "
1491 {
1492   rtx temp = gen_reg_rtx (SImode);
1493   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1494   int op1_subword = 0;
1495   int op0_subword = 0;
1496
1497   if (GET_CODE (operand1) == SUBREG)
1498     {
1499       op1_subword = SUBREG_WORD (operand1);
1500       operand1 = XEXP (operand1, 0);
1501     }
1502   if (GET_CODE (operand0) == SUBREG)
1503     {
1504       op0_subword = SUBREG_WORD (operand0);
1505       operand0 = XEXP (operand0, 0);
1506     }
1507   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1508                                          op1_subword),
1509                           shift_24));
1510   if (GET_MODE (operand0) != SImode)
1511     operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
1512   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1513   DONE;
1514 }")
1515
1516 (define_insn ""
1517   [(set (match_operand:HI 0 "register_operand" "=r")
1518         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1519   ""
1520   "ldsb %1,%0"
1521   [(set_attr "type" "load")])
1522
1523 (define_expand "extendqisi2"
1524   [(set (match_operand:SI 0 "register_operand" "")
1525         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1526   ""
1527   "
1528 {
1529   rtx temp = gen_reg_rtx (SImode);
1530   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1531   int op1_subword = 0;
1532
1533   if (GET_CODE (operand1) == SUBREG)
1534     {
1535       op1_subword = SUBREG_WORD (operand1);
1536       operand1 = XEXP (operand1, 0);
1537     }
1538
1539   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
1540                                          op1_subword),
1541                           shift_24));
1542   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1543   DONE;
1544 }")
1545
1546 (define_insn ""
1547   [(set (match_operand:SI 0 "register_operand" "=r")
1548         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1549   ""
1550   "ldsb %1,%0"
1551   [(set_attr "type" "load")])
1552 \f
1553 ;; Special pattern for optimizing bit-field compares.  This is needed
1554 ;; because combine uses this as a canonical form.
1555
1556 (define_insn ""
1557   [(set (reg:CC 0)
1558         (compare:CC
1559          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1560                           (match_operand:SI 1 "small_int" "n")
1561                           (match_operand:SI 2 "small_int" "n"))
1562          (const_int 0)))]
1563   "INTVAL (operands[2]) > 19"
1564   "*
1565 {
1566   int len = INTVAL (operands[1]);
1567   int pos = 32 - INTVAL (operands[2]) - len;
1568   unsigned mask = ((1 << len) - 1) << pos;
1569
1570   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1571   return \"andcc %0,%1,%%g0\";
1572 }")
1573 \f
1574 ;; Conversions between float, double and long double.
1575
1576 (define_insn "extendsfdf2"
1577   [(set (match_operand:DF 0 "register_operand" "=f")
1578         (float_extend:DF
1579          (match_operand:SF 1 "register_operand" "f")))]
1580   "TARGET_FPU"
1581   "fstod %1,%0"
1582   [(set_attr "type" "fp")])
1583
1584 (define_insn "extendsftf2"
1585   [(set (match_operand:TF 0 "register_operand" "=f")
1586         (float_extend:TF
1587          (match_operand:SF 1 "register_operand" "f")))]
1588   "TARGET_FPU"
1589   "fstoq %1,%0"
1590   [(set_attr "type" "fp")])
1591
1592 (define_insn "extenddftf2"
1593   [(set (match_operand:TF 0 "register_operand" "=f")
1594         (float_extend:TF
1595          (match_operand:DF 1 "register_operand" "f")))]
1596   "TARGET_FPU"
1597   "fdtoq %1,%0"
1598   [(set_attr "type" "fp")])
1599
1600 (define_insn "truncdfsf2"
1601   [(set (match_operand:SF 0 "register_operand" "=f")
1602         (float_truncate:SF
1603          (match_operand:DF 1 "register_operand" "f")))]
1604   "TARGET_FPU"
1605   "fdtos %1,%0"
1606   [(set_attr "type" "fp")])
1607
1608 (define_insn "trunctfsf2"
1609   [(set (match_operand:SF 0 "register_operand" "=f")
1610         (float_truncate:SF
1611          (match_operand:TF 1 "register_operand" "f")))]
1612   "TARGET_FPU"
1613   "fqtos %1,%0"
1614   [(set_attr "type" "fp")])
1615
1616 (define_insn "trunctfdf2"
1617   [(set (match_operand:DF 0 "register_operand" "=f")
1618         (float_truncate:DF
1619          (match_operand:TF 1 "register_operand" "f")))]
1620   "TARGET_FPU"
1621   "fqtod %1,%0"
1622   [(set_attr "type" "fp")])
1623 \f
1624 ;; Conversion between fixed point and floating point.
1625
1626 (define_insn "floatsisf2"
1627   [(set (match_operand:SF 0 "register_operand" "=f")
1628         (float:SF (match_operand:SI 1 "register_operand" "f")))]
1629   "TARGET_FPU"
1630   "fitos %1,%0"
1631   [(set_attr "type" "fp")])
1632
1633 (define_insn "floatsidf2"
1634   [(set (match_operand:DF 0 "register_operand" "=f")
1635         (float:DF (match_operand:SI 1 "register_operand" "f")))]
1636   "TARGET_FPU"
1637   "fitod %1,%0"
1638   [(set_attr "type" "fp")])
1639
1640 (define_insn "floatsitf2"
1641   [(set (match_operand:TF 0 "register_operand" "=f")
1642         (float:TF (match_operand:SI 1 "register_operand" "f")))]
1643   "TARGET_FPU"
1644   "fitoq %1,%0"
1645   [(set_attr "type" "fp")])
1646
1647 ;; Convert a float to an actual integer.
1648 ;; Truncation is performed as part of the conversion.
1649
1650 (define_insn "fix_truncsfsi2"
1651   [(set (match_operand:SI 0 "register_operand" "=f")
1652         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1653   "TARGET_FPU"
1654   "fstoi %1,%0"
1655   [(set_attr "type" "fp")])
1656
1657 (define_insn "fix_truncdfsi2"
1658   [(set (match_operand:SI 0 "register_operand" "=f")
1659         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1660   "TARGET_FPU"
1661   "fdtoi %1,%0"
1662   [(set_attr "type" "fp")])
1663
1664 (define_insn "fix_trunctfsi2"
1665   [(set (match_operand:SI 0 "register_operand" "=f")
1666         (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1667   "TARGET_FPU"
1668   "fqtoi %1,%0"
1669   [(set_attr "type" "fp")])
1670 \f
1671 ;;- arithmetic instructions
1672
1673 (define_insn "adddi3"
1674   [(set (match_operand:DI 0 "register_operand" "=r")
1675         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1676                  (match_operand:DI 2 "arith_double_operand" "rHI")))
1677    (clobber (reg:SI 0))]
1678   ""
1679   "*
1680 {
1681   rtx op2 = operands[2];
1682
1683   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1684      Give the assembler a chance to pick the move instruction. */
1685   if (GET_CODE (op2) == CONST_INT)
1686     {
1687       int sign = INTVAL (op2);
1688       if (sign < 0)
1689         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1690       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1691     }
1692   else if (GET_CODE (op2) == CONST_DOUBLE)
1693     {
1694       int sign = CONST_DOUBLE_HIGH (op2);
1695       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1696                              CONST_DOUBLE_LOW (operands[1]));
1697       if (sign < 0)
1698         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1699       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1700     }
1701   return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1702 }"
1703   [(set_attr "length" "2")])
1704
1705 (define_insn "addsi3"
1706   [(set (match_operand:SI 0 "register_operand" "=r")
1707         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1708                  (match_operand:SI 2 "arith_operand" "rI")))]
1709   ""
1710   "add %1,%2,%0")
1711
1712 (define_insn ""
1713   [(set (reg:CC_NOOV 0)
1714         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1715                                   (match_operand:SI 1 "arith_operand" "rI"))
1716                          (const_int 0)))]
1717   ""
1718   "addcc %0,%1,%%g0"
1719   [(set_attr "type" "compare")])
1720
1721 (define_insn ""
1722   [(set (reg:CC_NOOV 0)
1723         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1724                                   (match_operand:SI 2 "arith_operand" "rI"))
1725                          (const_int 0)))
1726    (set (match_operand:SI 0 "register_operand" "=r")
1727         (plus:SI (match_dup 1) (match_dup 2)))]
1728   ""
1729   "addcc %1,%2,%0")
1730
1731 (define_insn "subdi3"
1732   [(set (match_operand:DI 0 "register_operand" "=r")
1733         (minus:DI (match_operand:DI 1 "register_operand" "r")
1734                   (match_operand:DI 2 "arith_double_operand" "rHI")))
1735    (clobber (reg:SI 0))]
1736   ""
1737   "*
1738 {
1739   rtx op2 = operands[2];
1740
1741   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1742      Give the assembler a chance to pick the move instruction. */
1743   if (GET_CODE (op2) == CONST_INT)
1744     {
1745       int sign = INTVAL (op2);
1746       if (sign < 0)
1747         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1748       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1749     }
1750   else if (GET_CODE (op2) == CONST_DOUBLE)
1751     {
1752       int sign = CONST_DOUBLE_HIGH (op2);
1753       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1754                              CONST_DOUBLE_LOW (operands[1]));
1755       if (sign < 0)
1756         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1757       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1758     }
1759   return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1760 }"
1761   [(set_attr "length" "2")])
1762
1763 (define_insn "subsi3"
1764   [(set (match_operand:SI 0 "register_operand" "=r")
1765         (minus:SI (match_operand:SI 1 "register_operand" "r")
1766                   (match_operand:SI 2 "arith_operand" "rI")))]
1767   ""
1768   "sub %1,%2,%0")
1769
1770 (define_insn ""
1771   [(set (reg:CC_NOOV 0)
1772         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1773                                    (match_operand:SI 1 "arith_operand" "rI"))
1774                          (const_int 0)))]
1775   ""
1776   "subcc %0,%1,%%g0"
1777   [(set_attr "type" "compare")])
1778
1779 (define_insn ""
1780   [(set (reg:CC_NOOV 0)
1781         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1782                                    (match_operand:SI 2 "arith_operand" "rI"))
1783                          (const_int 0)))
1784    (set (match_operand:SI 0 "register_operand" "=r")
1785         (minus:SI (match_dup 1) (match_dup 2)))]
1786   ""
1787   "subcc %1,%2,%0")
1788
1789 (define_insn "mulsi3"
1790   [(set (match_operand:SI 0 "register_operand" "=r")
1791         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1792                  (match_operand:SI 2 "arith_operand" "rI")))]
1793   "TARGET_V8 || TARGET_SPARCLITE"
1794   "smul %1,%2,%0")
1795
1796 ;; It is not known whether this will match.
1797
1798 (define_insn ""
1799   [(set (match_operand:SI 0 "register_operand" "=r")
1800         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1801                  (match_operand:SI 2 "arith_operand" "rI")))
1802    (set (reg:CC_NOOV 0)
1803         (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1804                          (const_int 0)))]
1805   "TARGET_V8 || TARGET_SPARCLITE"
1806   "smulcc %1,%2,%0")
1807
1808 (define_expand "mulsidi3"
1809   [(set (match_operand:DI 0 "register_operand" "")
1810         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1811                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1812   "TARGET_V8 || TARGET_SPARCLITE"
1813   "
1814 {
1815   if (CONSTANT_P (operands[2]))
1816     {
1817       emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1818       DONE;
1819     }
1820 }")
1821
1822 (define_insn ""
1823   [(set (match_operand:DI 0 "register_operand" "=r")
1824         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1825                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1826   "TARGET_V8 || TARGET_SPARCLITE"
1827   "smul %1,%2,%R0\;rd %%y,%0"
1828   [(set_attr "length" "2")])
1829
1830 ;; Extra pattern, because sign_extend of a constant isn't legal.
1831
1832 (define_insn "const_mulsidi3"
1833   [(set (match_operand:DI 0 "register_operand" "=r")
1834         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1835                  (match_operand:SI 2 "small_int" "I")))]
1836   "TARGET_V8 || TARGET_SPARCLITE"
1837   "smul %1,%2,%R0\;rd %%y,%0"
1838   [(set_attr "length" "2")])
1839
1840 (define_expand "umulsidi3"
1841   [(set (match_operand:DI 0 "register_operand" "")
1842         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1843                  (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1844   "TARGET_V8 || TARGET_SPARCLITE"
1845   "
1846 {
1847   if (CONSTANT_P (operands[2]))
1848     {
1849       emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1850       DONE;
1851     }
1852 }")
1853
1854 (define_insn ""
1855   [(set (match_operand:DI 0 "register_operand" "=r")
1856         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1857                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1858   "TARGET_V8 || TARGET_SPARCLITE"
1859   "umul %1,%2,%R0\;rd %%y,%0"
1860   [(set_attr "length" "2")])
1861
1862 ;; Extra pattern, because sign_extend of a constant isn't legal.
1863
1864 (define_insn "const_umulsidi3"
1865   [(set (match_operand:DI 0 "register_operand" "=r")
1866         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1867                  (match_operand:SI 2 "small_int" "I")))]
1868   "TARGET_V8 || TARGET_SPARCLITE"
1869   "umul %1,%2,%R0\;rd %%y,%0"
1870   [(set_attr "length" "2")])
1871
1872 ;; The architecture specifies that there must be 3 instructions between
1873 ;; a y register write and a use of it for correct results.
1874
1875 (define_insn "divsi3"
1876   [(set (match_operand:SI 0 "register_operand" "=r")
1877         (div:SI (match_operand:SI 1 "register_operand" "r")
1878                 (match_operand:SI 2 "arith_operand" "rI")))
1879    (clobber (match_scratch:SI 3 "=&r"))]
1880   "TARGET_V8"
1881   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1882   [(set_attr "length" "6")])
1883
1884 ;; It is not known whether this will match.
1885
1886 (define_insn ""
1887   [(set (match_operand:SI 0 "register_operand" "=r")
1888         (div:SI (match_operand:SI 1 "register_operand" "r")
1889                 (match_operand:SI 2 "arith_operand" "rI")))
1890    (set (reg:CC 0)
1891         (compare:CC (div:SI (match_dup 1) (match_dup 2))
1892                     (const_int 0)))
1893    (clobber (match_scratch:SI 3 "=&r"))]
1894   "TARGET_V8"
1895   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1896   [(set_attr "length" "6")])
1897
1898 (define_insn "udivsi3"
1899   [(set (match_operand:SI 0 "register_operand" "=r")
1900         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1901                 (match_operand:SI 2 "arith_operand" "rI")))]
1902   "TARGET_V8"
1903   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1904   [(set_attr "length" "5")])
1905
1906 ;; It is not known whether this will match.
1907
1908 (define_insn ""
1909   [(set (match_operand:SI 0 "register_operand" "=r")
1910         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1911                 (match_operand:SI 2 "arith_operand" "rI")))
1912    (set (reg:CC 0)
1913         (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1914                     (const_int 0)))]
1915   "TARGET_V8"
1916   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1917   [(set_attr "length" "5")])
1918 \f
1919 ;;- Boolean instructions
1920 ;; We define DImode `and` so with DImode `not` we can get
1921 ;; DImode `andn`.  Other combinations are possible.
1922
1923 (define_expand "anddi3"
1924   [(set (match_operand:DI 0 "register_operand" "")
1925         (and:DI (match_operand:DI 1 "arith_double_operand" "")
1926                 (match_operand:DI 2 "arith_double_operand" "")))]
1927   ""
1928   "")
1929
1930 (define_insn ""
1931   [(set (match_operand:DI 0 "register_operand" "=r")
1932         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1933                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1934   ""
1935   "*
1936 {
1937   rtx op2 = operands[2];
1938
1939   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1940      Give the assembler a chance to pick the move instruction. */
1941   if (GET_CODE (op2) == CONST_INT)
1942     {
1943       int sign = INTVAL (op2);
1944       if (sign < 0)
1945         return \"mov %1,%0\;and %R1,%2,%R0\";
1946       return \"mov 0,%0\;and %R1,%2,%R0\";
1947     }
1948   else if (GET_CODE (op2) == CONST_DOUBLE)
1949     {
1950       int sign = CONST_DOUBLE_HIGH (op2);
1951       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1952                              CONST_DOUBLE_LOW (operands[1]));
1953       if (sign < 0)
1954         return \"mov %1,%0\;and %R1,%2,%R0\";
1955       return \"mov 0,%0\;and %R1,%2,%R0\";
1956     }
1957   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1958 }"
1959   [(set_attr "length" "2")])
1960
1961 (define_insn "andsi3"
1962   [(set (match_operand:SI 0 "register_operand" "=r")
1963         (and:SI (match_operand:SI 1 "arith_operand" "%r")
1964                 (match_operand:SI 2 "arith_operand" "rI")))]
1965   ""
1966   "and %1,%2,%0")
1967
1968 (define_split
1969   [(set (match_operand:SI 0 "register_operand" "")
1970         (and:SI (match_operand:SI 1 "register_operand" "")
1971                 (match_operand:SI 2 "" "")))
1972    (clobber (match_operand:SI 3 "register_operand" ""))]
1973   "GET_CODE (operands[2]) == CONST_INT
1974    && !SMALL_INT (operands[2])
1975    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1976   [(set (match_dup 3) (match_dup 4))
1977    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1978   "
1979 {
1980   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1981 }")
1982
1983 (define_insn ""
1984   [(set (match_operand:DI 0 "register_operand" "=r")
1985         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1986                 (match_operand:DI 2 "register_operand" "r")))]
1987   ""
1988   "andn %2,%1,%0\;andn %R2,%R1,%R0"
1989   [(set_attr "length" "2")])
1990
1991 (define_insn ""
1992   [(set (match_operand:SI 0 "register_operand" "=r")
1993         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1994                 (match_operand:SI 2 "register_operand" "r")))]
1995   ""
1996   "andn %2,%1,%0")
1997
1998 (define_expand "iordi3"
1999   [(set (match_operand:DI 0 "register_operand" "")
2000         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
2001                 (match_operand:DI 2 "arith_double_operand" "")))]
2002   ""
2003   "")
2004
2005 (define_insn ""
2006   [(set (match_operand:DI 0 "register_operand" "=r")
2007         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
2008                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2009   ""
2010   "*
2011 {
2012   rtx op2 = operands[2];
2013
2014   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2015      Give the assembler a chance to pick the move instruction. */
2016   if (GET_CODE (op2) == CONST_INT)
2017     {
2018       int sign = INTVAL (op2);
2019       if (sign < 0)
2020         return \"mov -1,%0\;or %R1,%2,%R0\";
2021       return \"mov %1,%0\;or %R1,%2,%R0\";
2022     }
2023   else if (GET_CODE (op2) == CONST_DOUBLE)
2024     {
2025       int sign = CONST_DOUBLE_HIGH (op2);
2026       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2027                              CONST_DOUBLE_LOW (operands[1]));
2028       if (sign < 0)
2029         return \"mov -1,%0\;or %R1,%2,%R0\";
2030       return \"mov %1,%0\;or %R1,%2,%R0\";
2031     }
2032   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
2033 }"
2034   [(set_attr "length" "2")])
2035
2036 (define_insn "iorsi3"
2037   [(set (match_operand:SI 0 "register_operand" "=r")
2038         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
2039                 (match_operand:SI 2 "arith_operand" "rI")))]
2040   ""
2041   "or %1,%2,%0")
2042
2043 (define_split
2044   [(set (match_operand:SI 0 "register_operand" "")
2045         (ior:SI (match_operand:SI 1 "register_operand" "")
2046                 (match_operand:SI 2 "" "")))
2047    (clobber (match_operand:SI 3 "register_operand" ""))]
2048   "GET_CODE (operands[2]) == CONST_INT
2049    && !SMALL_INT (operands[2])
2050    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2051   [(set (match_dup 3) (match_dup 4))
2052    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2053   "
2054 {
2055   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2056 }")
2057
2058 (define_insn ""
2059   [(set (match_operand:DI 0 "register_operand" "=r")
2060         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2061                 (match_operand:DI 2 "register_operand" "r")))]
2062   ""
2063   "orn %2,%1,%0\;orn %R2,%R1,%R0"
2064   [(set_attr "length" "2")])
2065
2066 (define_insn ""
2067   [(set (match_operand:SI 0 "register_operand" "=r")
2068         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2069                 (match_operand:SI 2 "register_operand" "r")))]
2070   ""
2071   "orn %2,%1,%0")
2072
2073 (define_expand "xordi3"
2074   [(set (match_operand:DI 0 "register_operand" "")
2075         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2076                 (match_operand:DI 2 "arith_double_operand" "")))]
2077   ""
2078   "")
2079
2080 (define_insn ""
2081   [(set (match_operand:DI 0 "register_operand" "=r")
2082         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2083                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2084   ""
2085   "*
2086 {
2087   rtx op2 = operands[2];
2088
2089   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2090      Give the assembler a chance to pick the move instruction. */
2091   if (GET_CODE (op2) == CONST_INT)
2092     {
2093       int sign = INTVAL (op2);
2094       if (sign < 0)
2095         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2096       return \"mov %1,%0\;xor %R1,%2,%R0\";
2097     }
2098   else if (GET_CODE (op2) == CONST_DOUBLE)
2099     {
2100       int sign = CONST_DOUBLE_HIGH (op2);
2101       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2102                              CONST_DOUBLE_LOW (operands[1]));
2103       if (sign < 0)
2104         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2105       return \"mov %1,%0\;xor %R1,%2,%R0\";
2106     }
2107   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2108 }"
2109   [(set_attr "length" "2")])
2110
2111 (define_insn "xorsi3"
2112   [(set (match_operand:SI 0 "register_operand" "=r")
2113         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2114                 (match_operand:SI 2 "arith_operand" "rI")))]
2115   ""
2116   "xor %r1,%2,%0")
2117
2118 (define_split
2119   [(set (match_operand:SI 0 "register_operand" "")
2120         (xor:SI (match_operand:SI 1 "register_operand" "")
2121                 (match_operand:SI 2 "" "")))
2122    (clobber (match_operand:SI 3 "register_operand" ""))]
2123   "GET_CODE (operands[2]) == CONST_INT
2124    && !SMALL_INT (operands[2])
2125    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2126   [(set (match_dup 3) (match_dup 4))
2127    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2128   "
2129 {
2130   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2131 }")
2132
2133 (define_split
2134   [(set (match_operand:SI 0 "register_operand" "")
2135         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2136                         (match_operand:SI 2 "" ""))))
2137    (clobber (match_operand:SI 3 "register_operand" ""))]
2138   "GET_CODE (operands[2]) == CONST_INT
2139    && !SMALL_INT (operands[2])
2140    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2141   [(set (match_dup 3) (match_dup 4))
2142    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2143   "
2144 {
2145   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2146 }")
2147
2148 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2149 ;; Combine now canonicalizes to the rightmost expression.
2150 (define_insn ""
2151   [(set (match_operand:DI 0 "register_operand" "=r")
2152         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2153                         (match_operand:DI 2 "register_operand" "r"))))]
2154   ""
2155   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2156   [(set_attr "length" "2")])
2157
2158 (define_insn ""
2159   [(set (match_operand:SI 0 "register_operand" "=r")
2160         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2161                         (match_operand:SI 2 "arith_operand" "rI"))))]
2162   ""
2163   "xnor %r1,%2,%0")
2164
2165 ;; These correspond to the above in the case where we also (or only)
2166 ;; want to set the condition code.  
2167
2168 (define_insn ""
2169   [(set (reg:CC 0)
2170         (compare:CC
2171          (match_operator:SI 2 "cc_arithop"
2172                             [(match_operand:SI 0 "arith_operand" "%r")
2173                              (match_operand:SI 1 "arith_operand" "rI")])
2174          (const_int 0)))]
2175   ""
2176   "%A2cc %0,%1,%%g0"
2177   [(set_attr "type" "compare")])
2178
2179 (define_insn ""
2180   [(set (reg:CC 0)
2181         (compare:CC
2182          (match_operator:SI 3 "cc_arithop"
2183                             [(match_operand:SI 1 "arith_operand" "%r")
2184                              (match_operand:SI 2 "arith_operand" "rI")])
2185          (const_int 0)))
2186    (set (match_operand:SI 0 "register_operand" "=r")
2187         (match_dup 3))]
2188   ""
2189   "%A3cc %1,%2,%0")
2190
2191 (define_insn ""
2192   [(set (reg:CC 0)
2193         (compare:CC
2194          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2195                          (match_operand:SI 1 "arith_operand" "rI")))
2196          (const_int 0)))]
2197   ""
2198   "xnorcc %r0,%1,%%g0"
2199   [(set_attr "type" "compare")])
2200
2201 (define_insn ""
2202   [(set (reg:CC 0)
2203         (compare:CC
2204          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2205                          (match_operand:SI 2 "arith_operand" "rI")))
2206          (const_int 0)))
2207    (set (match_operand:SI 0 "register_operand" "=r")
2208         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2209   ""
2210   "xnorcc %r1,%2,%0")
2211
2212 (define_insn ""
2213   [(set (reg:CC 0)
2214         (compare:CC
2215          (match_operator:SI 2 "cc_arithopn"
2216                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2217                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2218          (const_int 0)))]
2219   ""
2220   "%B2cc %r1,%0,%%g0"
2221   [(set_attr "type" "compare")])
2222
2223 (define_insn ""
2224   [(set (reg:CC 0)
2225         (compare:CC
2226          (match_operator:SI 3 "cc_arithopn"
2227                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2228                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2229          (const_int 0)))
2230    (set (match_operand:SI 0 "register_operand" "=r")
2231         (match_dup 3))]
2232   ""
2233   "%B3cc %r2,%1,%0")
2234
2235 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2236 ;; does not know how to make it work for constants.
2237
2238 (define_insn "negdi2"
2239   [(set (match_operand:DI 0 "register_operand" "=r")
2240         (neg:DI (match_operand:DI 1 "register_operand" "r")))
2241    (clobber (reg:SI 0))]
2242   ""
2243   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2244   [(set_attr "type" "unary")
2245    (set_attr "length" "2")])
2246
2247 (define_insn "negsi2"
2248   [(set (match_operand:SI 0 "general_operand" "=r")
2249         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2250   ""
2251   "sub %%g0,%1,%0"
2252   [(set_attr "type" "unary")])
2253
2254 (define_insn ""
2255   [(set (reg:CC_NOOV 0)
2256         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2257                          (const_int 0)))]
2258   ""
2259   "subcc %%g0,%0,%%g0"
2260   [(set_attr "type" "compare")])
2261
2262 (define_insn ""
2263   [(set (reg:CC_NOOV 0)
2264         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2265                          (const_int 0)))
2266    (set (match_operand:SI 0 "register_operand" "=r")
2267         (neg:SI (match_dup 1)))]
2268   ""
2269   "subcc %%g0,%1,%0"
2270   [(set_attr "type" "unary")])
2271
2272 ;; We cannot use the "not" pseudo insn because the Sun assembler
2273 ;; does not know how to make it work for constants.
2274 (define_expand "one_cmpldi2"
2275   [(set (match_operand:DI 0 "register_operand" "=r")
2276         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2277   ""
2278   "")
2279
2280 (define_insn ""
2281   [(set (match_operand:DI 0 "register_operand" "=r")
2282         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2283   ""
2284   "*
2285 {
2286   rtx op1 = operands[1];
2287
2288   if (GET_CODE (op1) == CONST_INT)
2289     {
2290       int sign = INTVAL (op1);
2291       if (sign < 0)
2292         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2293       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2294     }
2295   else if (GET_CODE (op1) == CONST_DOUBLE)
2296     {
2297       int sign = CONST_DOUBLE_HIGH (op1);
2298       operands[1] = gen_rtx (CONST_INT, VOIDmode,
2299                              CONST_DOUBLE_LOW (operands[1]));
2300       if (sign < 0)
2301         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2302       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2303     }
2304   return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2305 }"
2306   [(set_attr "type" "unary")
2307    (set_attr "length" "2")])
2308
2309 (define_insn "one_cmplsi2"
2310   [(set (match_operand:SI 0 "register_operand" "=r")
2311         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2312   ""
2313   "xnor %%g0,%1,%0"
2314   [(set_attr "type" "unary")])
2315
2316 (define_insn ""
2317   [(set (reg:CC 0)
2318         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2319                     (const_int 0)))]
2320   ""
2321   "xnorcc %%g0,%0,%%g0"
2322   [(set_attr "type" "compare")])
2323
2324 (define_insn ""
2325   [(set (reg:CC 0)
2326         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2327                     (const_int 0)))
2328    (set (match_operand:SI 0 "register_operand" "=r")
2329         (not:SI (match_dup 1)))]
2330   ""
2331   "xnorcc %%g0,%1,%0"
2332   [(set_attr "type" "unary")])
2333 \f
2334 ;; Floating point arithmetic instructions.
2335
2336 (define_insn "addtf3"
2337   [(set (match_operand:TF 0 "register_operand" "=f")
2338         (plus:TF (match_operand:TF 1 "register_operand" "f")
2339                  (match_operand:TF 2 "register_operand" "f")))]
2340   "TARGET_FPU"
2341   "faddq %1,%2,%0"
2342   [(set_attr "type" "fp")])
2343
2344 (define_insn "adddf3"
2345   [(set (match_operand:DF 0 "register_operand" "=f")
2346         (plus:DF (match_operand:DF 1 "register_operand" "f")
2347                  (match_operand:DF 2 "register_operand" "f")))]
2348   "TARGET_FPU"
2349   "faddd %1,%2,%0"
2350   [(set_attr "type" "fp")])
2351
2352 (define_insn "addsf3"
2353   [(set (match_operand:SF 0 "register_operand" "=f")
2354         (plus:SF (match_operand:SF 1 "register_operand" "f")
2355                  (match_operand:SF 2 "register_operand" "f")))]
2356   "TARGET_FPU"
2357   "fadds %1,%2,%0"
2358   [(set_attr "type" "fp")])
2359
2360 (define_insn "subtf3"
2361   [(set (match_operand:TF 0 "register_operand" "=f")
2362         (minus:TF (match_operand:TF 1 "register_operand" "f")
2363                   (match_operand:TF 2 "register_operand" "f")))]
2364   "TARGET_FPU"
2365   "fsubq %1,%2,%0"
2366   [(set_attr "type" "fp")])
2367
2368 (define_insn "subdf3"
2369   [(set (match_operand:DF 0 "register_operand" "=f")
2370         (minus:DF (match_operand:DF 1 "register_operand" "f")
2371                   (match_operand:DF 2 "register_operand" "f")))]
2372   "TARGET_FPU"
2373   "fsubd %1,%2,%0"
2374   [(set_attr "type" "fp")])
2375
2376 (define_insn "subsf3"
2377   [(set (match_operand:SF 0 "register_operand" "=f")
2378         (minus:SF (match_operand:SF 1 "register_operand" "f")
2379                   (match_operand:SF 2 "register_operand" "f")))]
2380   "TARGET_FPU"
2381   "fsubs %1,%2,%0"
2382   [(set_attr "type" "fp")])
2383
2384 (define_insn "multf3"
2385   [(set (match_operand:TF 0 "register_operand" "=f")
2386         (mult:TF (match_operand:TF 1 "register_operand" "f")
2387                  (match_operand:TF 2 "register_operand" "f")))]
2388   "TARGET_FPU"
2389   "fmulq %1,%2,%0"
2390   [(set_attr "type" "fpmul")])
2391
2392 (define_insn "muldf3"
2393   [(set (match_operand:DF 0 "register_operand" "=f")
2394         (mult:DF (match_operand:DF 1 "register_operand" "f")
2395                  (match_operand:DF 2 "register_operand" "f")))]
2396   "TARGET_FPU"
2397   "fmuld %1,%2,%0"
2398   [(set_attr "type" "fpmul")])
2399
2400 (define_insn "mulsf3"
2401   [(set (match_operand:SF 0 "register_operand" "=f")
2402         (mult:SF (match_operand:SF 1 "register_operand" "f")
2403                  (match_operand:SF 2 "register_operand" "f")))]
2404   "TARGET_FPU"
2405   "fmuls %1,%2,%0"
2406   [(set_attr "type" "fpmul")])
2407
2408 (define_insn ""
2409   [(set (match_operand:DF 0 "register_operand" "=f")
2410         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2411                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2412   "TARGET_V8 && TARGET_FPU"
2413   "fsmuld %1,%2,%0"
2414   [(set_attr "type" "fpmul")])
2415
2416 (define_insn ""
2417   [(set (match_operand:TF 0 "register_operand" "=f")
2418         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2419                  (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2420   "TARGET_V8 && TARGET_FPU"
2421   "fdmulq %1,%2,%0"
2422   [(set_attr "type" "fpmul")])
2423
2424 (define_insn "divtf3"
2425   [(set (match_operand:TF 0 "register_operand" "=f")
2426         (div:TF (match_operand:TF 1 "register_operand" "f")
2427                 (match_operand:TF 2 "register_operand" "f")))]
2428   "TARGET_FPU"
2429   "fdivq %1,%2,%0"
2430   [(set_attr "type" "fpdiv")])
2431
2432 (define_insn "divdf3"
2433   [(set (match_operand:DF 0 "register_operand" "=f")
2434         (div:DF (match_operand:DF 1 "register_operand" "f")
2435                 (match_operand:DF 2 "register_operand" "f")))]
2436   "TARGET_FPU"
2437   "fdivd %1,%2,%0"
2438   [(set_attr "type" "fpdiv")])
2439
2440 (define_insn "divsf3"
2441   [(set (match_operand:SF 0 "register_operand" "=f")
2442         (div:SF (match_operand:SF 1 "register_operand" "f")
2443                 (match_operand:SF 2 "register_operand" "f")))]
2444   "TARGET_FPU"
2445   "fdivs %1,%2,%0"
2446   [(set_attr "type" "fpdiv")])
2447
2448 (define_insn "negtf2"
2449   [(set (match_operand:TF 0 "register_operand" "=f,f")
2450         (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2451   "TARGET_FPU"
2452   "@
2453    fnegs %0,%0
2454    fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2455   [(set_attr "type" "fp")
2456    (set_attr "length" "1,4")])
2457
2458 (define_insn "negdf2"
2459   [(set (match_operand:DF 0 "register_operand" "=f,f")
2460         (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2461   "TARGET_FPU"
2462   "@
2463    fnegs %0,%0
2464    fnegs %1,%0\;fmovs %R1,%R0"
2465   [(set_attr "type" "fp")
2466    (set_attr "length" "1,2")])
2467
2468 (define_insn "negsf2"
2469   [(set (match_operand:SF 0 "register_operand" "=f")
2470         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2471   "TARGET_FPU"
2472   "fnegs %1,%0"
2473   [(set_attr "type" "fp")])
2474
2475 (define_insn "abstf2"
2476   [(set (match_operand:TF 0 "register_operand" "=f,f")
2477         (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2478   "TARGET_FPU"
2479   "@
2480    fabss %0,%0
2481    fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2482   [(set_attr "type" "fp")
2483    (set_attr "length" "1,4")])
2484
2485 (define_insn "absdf2"
2486   [(set (match_operand:DF 0 "register_operand" "=f,f")
2487         (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2488   "TARGET_FPU"
2489   "@
2490    fabss %0,%0
2491    fabss %1,%0\;fmovs %R1,%R0"
2492   [(set_attr "type" "fp")
2493    (set_attr "length" "1,2")])
2494
2495 (define_insn "abssf2"
2496   [(set (match_operand:SF 0 "register_operand" "=f")
2497         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2498   "TARGET_FPU"
2499   "fabss %1,%0"
2500   [(set_attr "type" "fp")])
2501
2502 (define_insn "sqrttf2"
2503   [(set (match_operand:TF 0 "register_operand" "=f")
2504         (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2505   "TARGET_FPU"
2506   "fsqrtq %1,%0"
2507   [(set_attr "type" "fpsqrt")])
2508
2509 (define_insn "sqrtdf2"
2510   [(set (match_operand:DF 0 "register_operand" "=f")
2511         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2512   "TARGET_FPU"
2513   "fsqrtd %1,%0"
2514   [(set_attr "type" "fpsqrt")])
2515
2516 (define_insn "sqrtsf2"
2517   [(set (match_operand:SF 0 "register_operand" "=f")
2518         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2519   "TARGET_FPU"
2520   "fsqrts %1,%0"
2521   [(set_attr "type" "fpsqrt")])
2522 \f
2523 ;;- arithmetic shift instructions
2524
2525 (define_insn "ashlsi3"
2526   [(set (match_operand:SI 0 "register_operand" "=r")
2527         (ashift:SI (match_operand:SI 1 "register_operand" "r")
2528                    (match_operand:SI 2 "shift_operand" "rI")))]
2529   ""
2530   "sll %1,%2,%0")
2531
2532 (define_insn "ashrsi3"
2533   [(set (match_operand:SI 0 "register_operand" "=r")
2534         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2535                      (match_operand:SI 2 "shift_operand" "rI")))]
2536   ""
2537   "sra %1,%2,%0")
2538
2539 (define_insn "lshrsi3"
2540   [(set (match_operand:SI 0 "register_operand" "=r")
2541         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2542                      (match_operand:SI 2 "shift_operand" "rI")))]
2543   ""
2544   "srl %1,%2,%0")
2545 \f
2546 ;; Unconditional and other jump instructions
2547 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2548 ;; following insn is never executed.  This saves us a nop.  Dbx does not
2549 ;; handle such branches though, so we only use them when optimizing.
2550 (define_insn "jump"
2551   [(set (pc) (label_ref (match_operand 0 "" "")))]
2552   ""
2553   "b%* %l0%("
2554   [(set_attr "type" "uncond_branch")])
2555
2556 (define_expand "tablejump"
2557   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2558               (use (label_ref (match_operand 1 "" "")))])]
2559   ""
2560   "
2561 {
2562   /* We need to use the PC value in %o7 that was set up when the address
2563      of the label was loaded into a register, so we need different RTL.  */
2564   if (flag_pic)
2565     {
2566       emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2567       DONE;
2568     }
2569 }")
2570
2571 (define_insn "pic_tablejump"
2572   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2573    (use (label_ref (match_operand 1 "" "")))
2574    (use (reg:SI 15))]
2575   ""
2576   "jmp %%o7+%0%#"
2577   [(set_attr "type" "uncond_branch")])
2578
2579 (define_insn ""
2580   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2581    (use (label_ref (match_operand 1 "" "")))]
2582   ""
2583   "jmp %a0%#"
2584   [(set_attr "type" "uncond_branch")])
2585
2586 (define_insn ""
2587   [(set (pc) (label_ref (match_operand 0 "" "")))
2588    (set (reg:SI 15) (label_ref (match_dup 0)))]
2589   ""
2590   "call %l0%#"
2591   [(set_attr "type" "uncond_branch")])
2592
2593 ;; This pattern recognizes the "instruction" that appears in 
2594 ;; a function call that wants a structure value, 
2595 ;; to inform the called function if compiled with Sun CC.
2596 ;(define_insn ""
2597 ;  [(match_operand:SI 0 "immediate_operand" "")]
2598 ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2599 ;  "unimp %0"
2600 ;  [(set_attr "type" "marker")])
2601
2602 ;;- jump to subroutine
2603 (define_expand "call"
2604   ;; Note that this expression is not used for generating RTL.
2605   ;; All the RTL is generated explicitly below.
2606   [(call (match_operand:SI 0 "call_operand" "")
2607          (match_operand 3 "" "i"))]
2608   ;; operands[2] is next_arg_register
2609   ;; operands[3] is struct_value_size_rtx.
2610   ""
2611   "
2612 {
2613   rtx fn_rtx, nregs_rtx;
2614
2615   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2616     {
2617       /* This is really a PIC sequence.  We want to represent
2618          it as a funny jump so it's delay slots can be filled. 
2619
2620          ??? But if this really *is* a CALL, will not it clobber the
2621          call-clobbered registers?  We lose this if it is a JUMP_INSN.
2622          Why cannot we have delay slots filled if it were a CALL?  */
2623
2624       if (INTVAL (operands[3]) > 0)
2625         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2626                                  gen_rtx (SET, VOIDmode, pc_rtx,
2627                                           XEXP (operands[0], 0)),
2628                                  operands[3],
2629                                  gen_rtx (CLOBBER, VOIDmode,
2630                                           gen_rtx (REG, SImode, 15)))));
2631       else
2632         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2633                                  gen_rtx (SET, VOIDmode, pc_rtx,
2634                                           XEXP (operands[0], 0)),
2635                                  gen_rtx (CLOBBER, VOIDmode,
2636                                           gen_rtx (REG, SImode, 15)))));
2637       goto finish_call;
2638     }
2639
2640   fn_rtx = operands[0];
2641
2642   /* Count the number of parameter registers being used by this call.
2643      if that argument is NULL, it means we are using them all, which
2644      means 6 on the sparc.  */
2645 #if 0
2646   if (operands[2])
2647     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2648   else
2649     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2650 #else
2651   nregs_rtx = const0_rtx;
2652 #endif
2653
2654   if (INTVAL (operands[3]) > 0)
2655     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2656                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2657                              operands[3],
2658                              gen_rtx (CLOBBER, VOIDmode,
2659                                                gen_rtx (REG, SImode, 15)))));
2660   else
2661     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2662                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2663                              gen_rtx (CLOBBER, VOIDmode,
2664                                                gen_rtx (REG, SImode, 15)))));
2665
2666  finish_call:
2667 #if 0
2668   /* If this call wants a structure value,
2669      emit an unimp insn to let the called function know about this.  */
2670   if (INTVAL (operands[3]) > 0)
2671     {
2672       rtx insn = emit_insn (operands[3]);
2673       SCHED_GROUP_P (insn) = 1;
2674     }
2675 #endif
2676
2677   DONE;
2678 }")
2679
2680 ;; We can't use the same pattern for these two insns, because then registers
2681 ;; in the address may not be properly reloaded.
2682
2683 (define_insn ""
2684   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2685          (match_operand 1 "" ""))
2686    (clobber (reg:SI 15))]
2687   ;;- Do not use operand 1 for most machines.
2688   ""
2689   "*
2690 {
2691   return \"call %a0,%1%#\";
2692 }"
2693   [(set_attr "type" "call")])
2694
2695 (define_insn ""
2696   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2697          (match_operand 1 "" ""))
2698    (clobber (reg:SI 15))]
2699   ;;- Do not use operand 1 for most machines.
2700   ""
2701   "*
2702 {
2703   return \"call %a0,%1%#\";
2704 }"
2705   [(set_attr "type" "call")])
2706
2707 ;; This is a call that wants a structure value.
2708 (define_insn ""
2709   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2710          (match_operand 1 "" ""))
2711    (match_operand 2 "immediate_operand" "")
2712    (clobber (reg:SI 15))]
2713   ;;- Do not use operand 1 for most machines.
2714   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2715   "*
2716 {
2717   return \"call %a0,%1\;nop\;unimp %2\";
2718 }"
2719   [(set_attr "type" "call_no_delay_slot")])
2720
2721 ;; This is a call that wants a structure value.
2722 (define_insn ""
2723   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2724          (match_operand 1 "" ""))
2725    (match_operand 2 "immediate_operand" "")
2726    (clobber (reg:SI 15))]
2727   ;;- Do not use operand 1 for most machines.
2728   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2729   "*
2730 {
2731   return \"call %a0,%1\;nop\;unimp %2\";
2732 }"
2733   [(set_attr "type" "call_no_delay_slot")])
2734
2735 (define_expand "call_value"
2736   [(set (match_operand 0 "register_operand" "=rf")
2737         (call (match_operand:SI 1 "" "")
2738               (match_operand 4 "" "")))]
2739   ;; operand 3 is next_arg_register
2740   ""
2741   "
2742 {
2743   rtx fn_rtx, nregs_rtx;
2744   rtvec vec;
2745
2746   fn_rtx = operands[1];
2747
2748 #if 0
2749   if (operands[3])
2750     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2751   else
2752     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2753 #else
2754   nregs_rtx = const0_rtx;
2755 #endif
2756
2757   vec = gen_rtvec (2,
2758                    gen_rtx (SET, VOIDmode, operands[0],
2759                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2760                    gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2761
2762   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2763
2764   DONE;
2765 }")
2766
2767 (define_insn ""
2768   [(set (match_operand 0 "" "=rf")
2769         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
2770               (match_operand 2 "" "")))
2771    (clobber (reg:SI 15))]
2772   ;;- Do not use operand 2 for most machines.
2773   ""
2774   "*
2775 {
2776   return \"call %a1,%2%#\";
2777 }"
2778   [(set_attr "type" "call")])
2779
2780 (define_insn ""
2781   [(set (match_operand 0 "" "=rf")
2782         (call (mem:SI (match_operand:SI 1 "immediate_operand" "i"))
2783               (match_operand 2 "" "")))
2784    (clobber (reg:SI 15))]
2785   ;;- Do not use operand 2 for most machines.
2786   ""
2787   "*
2788 {
2789   return \"call %a1,%2%#\";
2790 }"
2791   [(set_attr "type" "call")])
2792
2793 (define_expand "untyped_call"
2794   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2795                     (const_int 0))
2796               (match_operand:BLK 1 "memory_operand" "")
2797               (match_operand 2 "" "")
2798               (clobber (reg:SI 15))])]
2799   ""
2800   "
2801 {
2802   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
2803 }")
2804
2805 ;; Make a call followed by two nops in case the function being called
2806 ;; returns a structure value and expects to skip an unimp instruction.
2807
2808 (define_insn ""
2809   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2810          (const_int 0))
2811    (match_operand:DI 1 "memory_operand" "o")
2812    (match_operand 2 "" "")
2813    (clobber (reg:SI 15))]
2814   ""
2815   "*
2816 {
2817   operands[2] = adj_offsettable_operand (operands[1], 8);
2818   return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\";
2819 }"
2820   [(set_attr "type" "multi")])
2821
2822 ;; Make a call followed by two nops in case the function being called
2823 ;; returns a structure value and expects to skip an unimp instruction.
2824
2825 (define_insn ""
2826   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2827          (const_int 0))
2828    (match_operand:DI 1 "memory_operand" "o")
2829    (match_operand 2 "" "")
2830    (clobber (reg:SI 15))]
2831   ""
2832   "*
2833 {
2834   operands[2] = adj_offsettable_operand (operands[1], 8);
2835   return \"call %a0,0\;nop\;nop\;std %%o0,%1\;st %%f0,%2\";
2836 }"
2837   [(set_attr "type" "multi")])
2838
2839 ;; Prepare to return any type including a structure value.
2840
2841 (define_expand "untyped_return"
2842   [(match_operand:BLK 0 "memory_operand" "")
2843    (match_operand 1 "" "")]
2844   ""
2845   "
2846 {
2847   rtx valreg1 = gen_rtx (REG, DImode, 24);
2848   rtx valreg2 = gen_rtx (REG, DFmode, 32);
2849   rtx result = operands[0];
2850   rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
2851   rtx value = gen_reg_rtx (SImode);
2852
2853   /* Fetch the instruction where we will return to and see if it's an unimp
2854      instruction (the most significant 10 bits will be zero).  If so,
2855      update the return address to skip the unimp instruction.  */
2856   emit_move_insn (value,
2857                   gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
2858   emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
2859   emit_insn (gen_update_return (rtnreg, value));
2860
2861   /* Reload the function value registers.  */
2862   emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
2863   emit_move_insn (valreg2,
2864                   change_address (result, DFmode,
2865                                   plus_constant (XEXP (result, 0), 8)));
2866
2867   /* Put USE insns before the return.  */
2868   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
2869   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
2870
2871   /* Construct the return.  */
2872   expand_null_return ();
2873
2874   DONE;
2875 }")
2876
2877 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
2878 ;; and parts of the compiler don't want to believe that the add is needed.
2879
2880 (define_insn "update_return"
2881   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2882                (match_operand:SI 1 "register_operand" "r")] 0)]
2883   ""
2884   "cmp %1,0\;be,a .+8\;add %0,4,%0"
2885   [(set_attr "type" "multi")])
2886 \f
2887 (define_insn "return"
2888   [(return)]
2889   "! TARGET_EPILOGUE"
2890   "* return output_return (operands);"
2891   [(set_attr "type" "multi")])
2892
2893 (define_insn "nop"
2894   [(const_int 0)]
2895   ""
2896   "nop")
2897
2898 (define_insn "indirect_jump"
2899   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2900   ""
2901  "jmp %a0%#"
2902  [(set_attr "type" "uncond_branch")])
2903  
2904 (define_expand "nonlocal_goto"
2905   [(match_operand:SI 0 "general_operand" "")
2906    (match_operand:SI 1 "general_operand" "")
2907    (match_operand:SI 2 "general_operand" "")
2908    (match_operand:SI 3 "" "")]
2909   ""
2910   "
2911 {
2912   /* Trap instruction to flush all the registers window.  */
2913   emit_insn (gen_flush_register_windows ());
2914   /* Load the fp value for the containing fn into %fp.
2915      This is needed because operands[2] refers to %fp.
2916      Virtual register instantiation fails if the virtual %fp isn't set from a
2917      register.  Thus we must copy operands[0] into a register if it isn't
2918      already one.  */
2919   if (GET_CODE (operands[0]) != REG)
2920     operands[0] = force_reg (SImode, operands[0]);
2921   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2922   /* Find the containing function's current nonlocal goto handler,
2923      which will do any cleanups and then jump to the label.  */
2924   emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2925   /* Restore %fp from stack pointer value for containing function.
2926      The restore insn that follows will move this to %sp,
2927      and reload the appropriate value into %fp.  */
2928   emit_move_insn (frame_pointer_rtx, operands[2]);
2929   /* Put in the static chain register the nonlocal label address.  */
2930   emit_move_insn (static_chain_rtx, operands[3]);
2931   /* USE of frame_pointer_rtx added for consistency; not clear if
2932      really needed.  */
2933   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2934   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2935   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2936   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2937   /* Return, restoring reg window and jumping to goto handler.  */
2938   emit_insn (gen_goto_handler_and_restore ());
2939   DONE;
2940 }")
2941
2942 ;; Special trap insn to flush register windows.
2943 (define_insn "flush_register_windows"
2944   [(unspec_volatile [(const_int 0)] 0)]
2945   ""
2946   "ta 3"
2947   [(set_attr "type" "misc")])
2948
2949 (define_insn "goto_handler_and_restore"
2950   [(unspec_volatile [(const_int 0)] 1)]
2951   ""
2952   "jmp %%o0+0\;restore"
2953   [(set_attr "type" "misc")
2954    (set_attr "length" "2")])
2955 \f
2956 ;; find first set.
2957
2958 ;; The scan instruction searches from the most significant bit while ffs
2959 ;; searches from the least significant bit.  The bit index and treatment of
2960 ;; zero also differ.  It takes at least 7 instructions to get the proper
2961 ;; result.  Here is an obvious 8 instruction seequence.
2962
2963 (define_insn "ffssi2"
2964   [(set (match_operand:SI 0 "register_operand" "=&r")
2965         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2966    (clobber (match_scratch:SI 2 "=&r"))]
2967   "TARGET_SPARCLITE"
2968   "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"
2969   [(set_attr "type" "multi")
2970    (set_attr "length" "8")])
2971 \f
2972 ;; Split up troublesome insns for better scheduling.  */
2973
2974 ;; The following patterns are straightforward.  They can be applied
2975 ;; either before or after register allocation.
2976
2977 (define_split
2978   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2979         (match_operand 2 "reg_or_0_operand" ""))
2980    (clobber (match_operand:SI 3 "register_operand" ""))]
2981   "! flag_pic"
2982   [(set (match_dup 3) (high:SI (match_dup 1)))
2983    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2984         (match_dup 2))]
2985   "")
2986
2987 (define_split
2988   [(set (match_operator 0 "memop"
2989                         [(match_operand:SI 1 "immediate_operand" "")])
2990         (match_operand 2 "general_operand" ""))
2991    (clobber (match_operand:SI 3 "register_operand" ""))]
2992   "flag_pic"
2993   [(set (match_op_dup 0 [(match_dup 1)])
2994         (match_dup 2))]
2995   "
2996 {
2997   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
2998                                         operands[3]);
2999 }")
3000
3001 (define_split
3002   [(set (match_operand 0 "register_operand" "")
3003         (match_operator 1 "memop"
3004                         [(match_operand:SI 2 "immediate_operand" "")]))]
3005   "flag_pic"
3006   [(set (match_dup 0)
3007         (match_op_dup 1 [(match_dup 2)]))]
3008   "
3009 {
3010   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
3011                                         operands[0]);
3012 }")
3013
3014 ;; Sign- and Zero-extend operations can have symbolic memory operands.
3015
3016 (define_split
3017   [(set (match_operand 0 "register_operand" "")
3018         (match_operator 1 "extend_op"
3019                         [(match_operator 2 "memop"
3020                                          [(match_operand:SI 3 "immediate_operand" "")])]))]
3021   "flag_pic"
3022   [(set (match_dup 0)
3023         (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
3024   "
3025 {
3026   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
3027                                         operands[0]);
3028 }")
3029
3030 (define_split
3031   [(set (match_operand:SI 0 "register_operand" "")
3032         (match_operand:SI 1 "immediate_operand" ""))]
3033   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3034                   || GET_CODE (operands[1]) == CONST
3035                   || GET_CODE (operands[1]) == LABEL_REF)"
3036   [(set (match_dup 0) (high:SI (match_dup 1)))
3037    (set (match_dup 0)
3038         (lo_sum:SI (match_dup 0) (match_dup 1)))]
3039   "")
3040
3041 ;; LABEL_REFs are not modified by `legitimize_pic_address`
3042 ;; so do not recurse infinitely in the PIC case.
3043 (define_split
3044   [(set (match_operand:SI 0 "register_operand" "")
3045         (match_operand:SI 1 "immediate_operand" ""))]
3046   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3047                 || GET_CODE (operands[1]) == CONST)"
3048   [(set (match_dup 0) (match_dup 1))]
3049   "
3050 {
3051   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
3052 }")
3053 \f
3054 ;; These split sne/seq insns.  The forms of the resulting insns are 
3055 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
3056 ;; Nothing will look at these in detail after splitting has occurred.
3057
3058 (define_split
3059   [(set (match_operand:SI 0 "register_operand" "")
3060         (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3061    (clobber (reg:CC 0))]
3062   ""
3063   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3064                                          (const_int 0)))
3065    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
3066   "")
3067
3068 (define_split
3069   [(set (match_operand:SI 0 "register_operand" "")
3070         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3071                        (const_int 0))))
3072    (clobber (reg:CC 0))]
3073   ""
3074   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3075                                          (const_int 0)))
3076    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
3077   "")
3078
3079 (define_split
3080   [(set (match_operand:SI 0 "register_operand" "")
3081         (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3082    (clobber (reg:CC 0))]
3083   ""
3084   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3085                                          (const_int 0)))
3086    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
3087   "")
3088
3089 (define_split
3090   [(set (match_operand:SI 0 "register_operand" "")
3091         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3092                        (const_int 0))))
3093    (clobber (reg:CC 0))]
3094   ""
3095   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3096                                          (const_int 0)))
3097    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
3098   "")
3099
3100 (define_split
3101   [(set (match_operand:SI 0 "register_operand" "")
3102         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3103                         (const_int 0))
3104                  (match_operand:SI 2 "register_operand" "")))
3105    (clobber (reg:CC 0))]
3106   ""
3107   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3108                                          (const_int 0)))
3109    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
3110                                (match_dup 2)))]
3111   "")
3112
3113 (define_split
3114   [(set (match_operand:SI 0 "register_operand" "")
3115         (minus:SI (match_operand:SI 2 "register_operand" "")
3116                   (ne:SI (match_operand:SI 1 "register_operand" "")
3117                          (const_int 0))))
3118    (clobber (reg:CC 0))]
3119   ""
3120   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3121                                          (const_int 0)))
3122    (set (match_dup 0) (minus:SI (match_dup 2)
3123                                 (ltu:SI (reg:CC 0) (const_int 0))))]
3124   "")
3125
3126 (define_split
3127   [(set (match_operand:SI 0 "register_operand" "")
3128         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3129                         (const_int 0))
3130                  (match_operand:SI 2 "register_operand" "")))
3131    (clobber (reg:CC 0))]
3132   ""
3133   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3134                                          (const_int 0)))
3135    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
3136                                (match_dup 2)))]
3137   "")
3138
3139 (define_split
3140   [(set (match_operand:SI 0 "register_operand" "")
3141         (minus:SI (match_operand:SI 2 "register_operand" "")
3142                   (eq:SI (match_operand:SI 1 "register_operand" "")
3143                          (const_int 0))))
3144    (clobber (reg:CC 0))]
3145   ""
3146   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3147                                          (const_int 0)))
3148    (set (match_dup 0) (minus:SI (match_dup 2)
3149                                 (geu:SI (reg:CC 0) (const_int 0))))]
3150   "")
3151 \f
3152 ;; Peepholes go at the end.
3153
3154 ;; Optimize consecutive loads or stores into ldd and std when possible.
3155 ;; The conditions in which we do this are very restricted and are 
3156 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3157
3158 (define_peephole
3159   [(set (match_operand:SI 0 "register_operand" "=rf")
3160         (match_operand:SI 1 "memory_operand" ""))
3161    (set (match_operand:SI 2 "register_operand" "=rf")
3162         (match_operand:SI 3 "memory_operand" ""))]
3163   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3164    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3165    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
3166   "ldd %1,%0")
3167
3168 (define_peephole
3169   [(set (match_operand:SI 0 "memory_operand" "")
3170         (match_operand:SI 1 "register_operand" "rf"))
3171    (set (match_operand:SI 2 "memory_operand" "")
3172         (match_operand:SI 3 "register_operand" "rf"))]
3173   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3174    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3175    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3176   "std %1,%0")
3177  
3178 (define_peephole
3179   [(set (match_operand:SF 0 "register_operand" "=fr")
3180         (match_operand:SF 1 "memory_operand" ""))
3181    (set (match_operand:SF 2 "register_operand" "=fr")
3182         (match_operand:SF 3 "memory_operand" ""))]
3183   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3184    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3185    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3186   "ldd %1,%0")
3187
3188 (define_peephole
3189   [(set (match_operand:SF 0 "memory_operand" "")
3190         (match_operand:SF 1 "register_operand" "fr"))
3191    (set (match_operand:SF 2 "memory_operand" "")
3192         (match_operand:SF 3 "register_operand" "fr"))]
3193   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3194    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3195    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3196   "std %1,%0")
3197
3198 (define_peephole
3199   [(set (match_operand:SI 0 "register_operand" "=rf")
3200         (match_operand:SI 1 "memory_operand" ""))
3201    (set (match_operand:SI 2 "register_operand" "=rf")
3202         (match_operand:SI 3 "memory_operand" ""))]
3203   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3204    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3205    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3206   "ldd %3,%2")
3207
3208 (define_peephole
3209   [(set (match_operand:SI 0 "memory_operand" "")
3210         (match_operand:SI 1 "register_operand" "rf"))
3211    (set (match_operand:SI 2 "memory_operand" "")
3212         (match_operand:SI 3 "register_operand" "rf"))]
3213   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3214    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3215    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
3216   "std %3,%2")
3217  
3218 (define_peephole
3219   [(set (match_operand:SF 0 "register_operand" "=fr")
3220         (match_operand:SF 1 "memory_operand" ""))
3221    (set (match_operand:SF 2 "register_operand" "=fr")
3222         (match_operand:SF 3 "memory_operand" ""))]
3223   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3224    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3225    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3226   "ldd %3,%2")
3227
3228 (define_peephole
3229   [(set (match_operand:SF 0 "memory_operand" "")
3230         (match_operand:SF 1 "register_operand" "fr"))
3231    (set (match_operand:SF 2 "memory_operand" "")
3232         (match_operand:SF 3 "register_operand" "fr"))]
3233   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3234    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3235    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3236   "std %3,%2")
3237  
3238 ;; Optimize the case of following a reg-reg move with a test
3239 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
3240 ;; This can result from a float to fix conversion.
3241
3242 (define_peephole
3243   [(set (match_operand:SI 0 "register_operand" "=r")
3244         (match_operand:SI 1 "register_operand" "r"))
3245    (set (reg:CC 0)
3246         (compare:CC (match_operand:SI 2 "register_operand" "r")
3247                     (const_int 0)))]
3248   "(rtx_equal_p (operands[2], operands[0])
3249     || rtx_equal_p (operands[2], operands[1]))
3250    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3251   "orcc %1,%%g0,%0")
3252
3253 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3254 ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
3255 ;;     eventually have some impact here?
3256
3257 (define_peephole
3258   [(set (match_operand:HI 0 "register_operand" "")
3259         (match_operand:HI 1 "memory_operand" ""))
3260    (set (match_operand:SI 2 "register_operand" "")
3261         (sign_extend:SI (match_dup 0)))
3262    (set (reg:CC 0)
3263         (compare:CC (match_dup 2)
3264                     (const_int 0)))]
3265   ""
3266   "ldsh %1,%0\;orcc %0,%%g0,%2")
3267
3268 (define_peephole
3269   [(set (match_operand:QI 0 "register_operand" "")
3270         (match_operand:QI 1 "memory_operand" ""))
3271    (set (match_operand:SI 2 "register_operand" "")
3272         (sign_extend:SI (match_dup 0)))
3273    (set (reg:CC 0)
3274         (compare:CC (match_dup 2)
3275                     (const_int 0)))]
3276   ""
3277   "ldsb %1,%0\;orcc %0,%%g0,%2")
3278
3279 (define_peephole
3280   [(set (match_operand:HI 0 "register_operand" "")
3281         (match_operand:HI 1 "memory_operand" ""))
3282    (set (match_operand:SI 2 "register_operand" "")
3283         (sign_extend:SI (match_dup 0)))]
3284   "dead_or_set_p (insn, operands[0])"
3285   "*
3286 {
3287   warning (\"bad peephole\");
3288   if (! MEM_VOLATILE_P (operands[1]))
3289     abort ();
3290   return \"ldsh %1,%2\";
3291 }")
3292
3293 (define_peephole
3294   [(set (match_operand:QI 0 "register_operand" "")
3295         (match_operand:QI 1 "memory_operand" ""))
3296    (set (match_operand:SI 2 "register_operand" "")
3297         (sign_extend:SI (match_dup 0)))]
3298   "dead_or_set_p (insn, operands[0])"
3299   "*
3300 {
3301   warning (\"bad peephole\");
3302   if (! MEM_VOLATILE_P (operands[1]))
3303     abort ();
3304   return \"ldsb %1,%2\";
3305 }")
3306
3307 ;; Floating-point move peepholes
3308
3309 (define_peephole
3310   [(set (match_operand:SI 0 "register_operand" "=r")
3311         (lo_sum:SI (match_dup 0)
3312                    (match_operand:SI 1 "immediate_operand" "i")))
3313    (set (match_operand:DF 2 "register_operand" "=fr")
3314         (mem:DF (match_dup 0)))]
3315   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3316   "*
3317 {
3318   /* Go by way of output_move_double in case the register in operand 2
3319      is not properly aligned for ldd.  */
3320   operands[1] = gen_rtx (MEM, DFmode,
3321                          gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3322   operands[0] = operands[2];
3323   return output_move_double (operands);
3324 }")
3325
3326 (define_peephole
3327   [(set (match_operand:SI 0 "register_operand" "=r")
3328         (lo_sum:SI (match_dup 0)
3329                    (match_operand:SI 1 "immediate_operand" "i")))
3330    (set (match_operand:SF 2 "register_operand" "=fr")
3331         (mem:SF (match_dup 0)))]
3332   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3333   "ld [%0+%%lo(%a1)],%2")
3334
3335 ;; Return peepholes.  First the "normal" ones
3336
3337 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3338 ;; It might be possible to write one more general pattern instead of three.
3339
3340 (define_insn ""
3341   [(set (match_operand:QI 0 "restore_operand" "")
3342         (match_operand:QI 1 "arith_operand" "rI"))
3343    (return)]
3344   "! TARGET_EPILOGUE"
3345   "*
3346 {
3347   if (current_function_returns_struct)
3348     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3349   else
3350     return \"ret\;restore %%g0,%1,%Y0\";
3351 }"
3352   [(set_attr "type" "multi")])
3353
3354 (define_insn ""
3355   [(set (match_operand:HI 0 "restore_operand" "")
3356         (match_operand:HI 1 "arith_operand" "rI"))
3357    (return)]
3358   "! TARGET_EPILOGUE"
3359   "*
3360 {
3361   if (current_function_returns_struct)
3362     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3363   else
3364     return \"ret\;restore %%g0,%1,%Y0\";
3365 }"
3366   [(set_attr "type" "multi")])
3367
3368 (define_insn ""
3369   [(set (match_operand:SI 0 "restore_operand" "")
3370         (match_operand:SI 1 "arith_operand" "rI"))
3371    (return)]
3372   "! TARGET_EPILOGUE"
3373   "*
3374 {
3375   if (current_function_returns_struct)
3376     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3377   else
3378     return \"ret\;restore %%g0,%1,%Y0\";
3379 }"
3380   [(set_attr "type" "multi")])
3381
3382 ;; The following pattern is only generated by delayed-branch scheduling,
3383 ;; when the insn winds up in the epilogue.  This can only happen when
3384 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3385 (define_insn ""
3386   [(set (match_operand:SF 0 "restore_operand" "r")
3387         (match_operand:SF 1 "register_operand" "r"))
3388    (return)]
3389   "! TARGET_FPU && ! TARGET_EPILOGUE"
3390   "*
3391 {
3392   if (current_function_returns_struct)
3393     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3394   else
3395     return \"ret\;restore %%g0,%1,%Y0\";
3396 }"
3397   [(set_attr "type" "multi")])
3398
3399 (define_insn ""
3400   [(set (match_operand:SI 0 "restore_operand" "")
3401         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3402                  (match_operand:SI 2 "arith_operand" "rI")))
3403    (return)]
3404   "! TARGET_EPILOGUE"
3405   "*
3406 {
3407   if (current_function_returns_struct)
3408     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3409   else
3410     return \"ret\;restore %r1,%2,%Y0\";
3411 }"
3412   [(set_attr "type" "multi")])
3413
3414 ;; Turned off because it should never match (subtracting a constant
3415 ;; is turned into addition) and because it would do the wrong thing
3416 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3417 ;;(define_insn ""
3418 ;;  [(set (match_operand:SI 0 "restore_operand" "")
3419 ;;      (minus:SI (match_operand:SI 1 "register_operand" "r")
3420 ;;                (match_operand:SI 2 "small_int" "I")))
3421 ;;   (return)]
3422 ;;  "! TARGET_EPILOGUE"
3423 ;;  "ret\;restore %1,-(%2),%Y0"
3424 ;;  [(set_attr "type" "multi")])
3425
3426 ;; The following pattern is only generated by delayed-branch scheduling,
3427 ;; when the insn winds up in the epilogue.
3428 (define_insn ""
3429   [(set (reg:SF 32)
3430         (match_operand:SF 0 "register_operand" "f"))
3431    (return)]
3432   "! TARGET_EPILOGUE"
3433   "ret\;fmovs %0,%%f0"
3434   [(set_attr "type" "multi")])
3435
3436 ;; Now peepholes to go a call followed by a jump.
3437
3438 (define_peephole
3439   [(parallel [(set (match_operand 0 "" "")
3440                    (call (mem:SI (match_operand:SI 1 "call_operand_address" "pi"))
3441                          (match_operand 2 "" "")))
3442               (clobber (reg:SI 15))])
3443    (set (pc) (label_ref (match_operand 3 "" "")))]
3444   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3445   "*
3446 {
3447   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3448 }")
3449
3450 (define_peephole
3451   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "pi"))
3452                     (match_operand 1 "" ""))
3453               (clobber (reg:SI 15))])
3454    (set (pc) (label_ref (match_operand 2 "" "")))]
3455   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3456   "*
3457 {
3458   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3459 }")
3460
3461 (define_peephole
3462   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3463                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3464                              (reg:SI 0)))
3465               (clobber (reg:CC 0))])
3466    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3467   ""
3468   "subxcc %r1,0,%0")