OSDN Git Service

(movdi): Handle 'U' and 'T' constraints.
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;;   Copyright (C) 1987, 1988, 1989, 1992, 1993 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,T,U,Q,r,r,?f,?f,?Q")
1013         (match_operand:DI 1 "general_operand" "r,U,T,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,store,load,multi,fp,fpload,fpstore")
1024    (set_attr "length" "2,1,1,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 "smulsi3_highpart"
1841   [(set (match_operand:SI 0 "register_operand" "")
1842         (truncate:SI
1843          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1844                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
1845                       (const_int 32))))]
1846   "TARGET_V8 || TARGET_SPARCLITE"
1847   "
1848 {
1849   if (CONSTANT_P (operands[2]))
1850     {
1851       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
1852       DONE;
1853     }
1854 }")
1855
1856 (define_insn ""
1857   [(set (match_operand:SI 0 "register_operand" "=r")
1858         (truncate:SI
1859          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1860                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
1861                       (const_int 32))))]
1862   "TARGET_V8 || TARGET_SPARCLITE"
1863   "smul %1,%2,%%g0\;rd %%y,%0"
1864   [(set_attr "length" "2")])
1865
1866 (define_insn "const_smulsi3_highpart"
1867   [(set (match_operand:SI 0 "register_operand" "=r")
1868         (truncate:SI
1869          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1870                                (match_operand:SI 2 "register_operand" "r"))
1871                       (const_int 32))))]
1872   "TARGET_V8 || TARGET_SPARCLITE"
1873   "smul %1,%2,%%g0\;rd %%y,%0"
1874   [(set_attr "length" "2")])
1875
1876 (define_expand "umulsidi3"
1877   [(set (match_operand:DI 0 "register_operand" "")
1878         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1879                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
1880   "TARGET_V8 || TARGET_SPARCLITE"
1881   "
1882 {
1883   if (CONSTANT_P (operands[2]))
1884     {
1885       emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1886       DONE;
1887     }
1888 }")
1889
1890 (define_insn ""
1891   [(set (match_operand:DI 0 "register_operand" "=r")
1892         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1893                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1894   "TARGET_V8 || TARGET_SPARCLITE"
1895   "umul %1,%2,%R0\;rd %%y,%0"
1896   [(set_attr "length" "2")])
1897
1898 ;; Extra pattern, because sign_extend of a constant isn't legal.
1899
1900 (define_insn "const_umulsidi3"
1901   [(set (match_operand:DI 0 "register_operand" "=r")
1902         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1903                  (match_operand:SI 2 "uns_small_int" "")))]
1904   "TARGET_V8 || TARGET_SPARCLITE"
1905   "umul %1,%2,%R0\;rd %%y,%0"
1906   [(set_attr "length" "2")])
1907
1908 (define_expand "umulsi3_highpart"
1909   [(set (match_operand:SI 0 "register_operand" "")
1910         (truncate:SI
1911          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1912                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
1913                       (const_int 32))))]
1914   "TARGET_V8 || TARGET_SPARCLITE"
1915   "
1916 {
1917   if (CONSTANT_P (operands[2]))
1918     {
1919       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
1920       DONE;
1921     }
1922 }")
1923
1924 (define_insn ""
1925   [(set (match_operand:SI 0 "register_operand" "=r")
1926         (truncate:SI
1927          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1928                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
1929                       (const_int 32))))]
1930   "TARGET_V8 || TARGET_SPARCLITE"
1931   "umul %1,%2,%%g0\;rd %%y,%0"
1932   [(set_attr "length" "2")])
1933
1934 (define_insn "const_umulsi3_highpart"
1935   [(set (match_operand:SI 0 "register_operand" "=r")
1936         (truncate:SI
1937          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1938                                (match_operand:SI 2 "uns_small_int" ""))
1939                       (const_int 32))))]
1940   "TARGET_V8 || TARGET_SPARCLITE"
1941   "umul %1,%2,%%g0\;rd %%y,%0"
1942   [(set_attr "length" "2")])
1943
1944 ;; The architecture specifies that there must be 3 instructions between
1945 ;; a y register write and a use of it for correct results.
1946
1947 (define_insn "divsi3"
1948   [(set (match_operand:SI 0 "register_operand" "=r")
1949         (div:SI (match_operand:SI 1 "register_operand" "r")
1950                 (match_operand:SI 2 "arith_operand" "rI")))
1951    (clobber (match_scratch:SI 3 "=&r"))]
1952   "TARGET_V8"
1953   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1954   [(set_attr "length" "6")])
1955
1956 ;; It is not known whether this will match.
1957
1958 (define_insn ""
1959   [(set (match_operand:SI 0 "register_operand" "=r")
1960         (div:SI (match_operand:SI 1 "register_operand" "r")
1961                 (match_operand:SI 2 "arith_operand" "rI")))
1962    (set (reg:CC 0)
1963         (compare:CC (div:SI (match_dup 1) (match_dup 2))
1964                     (const_int 0)))
1965    (clobber (match_scratch:SI 3 "=&r"))]
1966   "TARGET_V8"
1967   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1968   [(set_attr "length" "6")])
1969
1970 (define_insn "udivsi3"
1971   [(set (match_operand:SI 0 "register_operand" "=r")
1972         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1973                 (match_operand:SI 2 "arith_operand" "rI")))]
1974   "TARGET_V8"
1975   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1976   [(set_attr "length" "5")])
1977
1978 ;; It is not known whether this will match.
1979
1980 (define_insn ""
1981   [(set (match_operand:SI 0 "register_operand" "=r")
1982         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1983                 (match_operand:SI 2 "arith_operand" "rI")))
1984    (set (reg:CC 0)
1985         (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1986                     (const_int 0)))]
1987   "TARGET_V8"
1988   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1989   [(set_attr "length" "5")])
1990 \f
1991 ;;- Boolean instructions
1992 ;; We define DImode `and` so with DImode `not` we can get
1993 ;; DImode `andn`.  Other combinations are possible.
1994
1995 (define_expand "anddi3"
1996   [(set (match_operand:DI 0 "register_operand" "")
1997         (and:DI (match_operand:DI 1 "arith_double_operand" "")
1998                 (match_operand:DI 2 "arith_double_operand" "")))]
1999   ""
2000   "")
2001
2002 (define_insn ""
2003   [(set (match_operand:DI 0 "register_operand" "=r")
2004         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
2005                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2006   ""
2007   "*
2008 {
2009   rtx op2 = operands[2];
2010
2011   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2012      Give the assembler a chance to pick the move instruction. */
2013   if (GET_CODE (op2) == CONST_INT)
2014     {
2015       int sign = INTVAL (op2);
2016       if (sign < 0)
2017         return \"mov %1,%0\;and %R1,%2,%R0\";
2018       return \"mov 0,%0\;and %R1,%2,%R0\";
2019     }
2020   else if (GET_CODE (op2) == CONST_DOUBLE)
2021     {
2022       int sign = CONST_DOUBLE_HIGH (op2);
2023       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2024                              CONST_DOUBLE_LOW (operands[1]));
2025       if (sign < 0)
2026         return \"mov %1,%0\;and %R1,%2,%R0\";
2027       return \"mov 0,%0\;and %R1,%2,%R0\";
2028     }
2029   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
2030 }"
2031   [(set_attr "length" "2")])
2032
2033 (define_insn "andsi3"
2034   [(set (match_operand:SI 0 "register_operand" "=r")
2035         (and:SI (match_operand:SI 1 "arith_operand" "%r")
2036                 (match_operand:SI 2 "arith_operand" "rI")))]
2037   ""
2038   "and %1,%2,%0")
2039
2040 (define_split
2041   [(set (match_operand:SI 0 "register_operand" "")
2042         (and:SI (match_operand:SI 1 "register_operand" "")
2043                 (match_operand:SI 2 "" "")))
2044    (clobber (match_operand:SI 3 "register_operand" ""))]
2045   "GET_CODE (operands[2]) == CONST_INT
2046    && !SMALL_INT (operands[2])
2047    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2048   [(set (match_dup 3) (match_dup 4))
2049    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
2050   "
2051 {
2052   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2053 }")
2054
2055 (define_insn ""
2056   [(set (match_operand:DI 0 "register_operand" "=r")
2057         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2058                 (match_operand:DI 2 "register_operand" "r")))]
2059   ""
2060   "andn %2,%1,%0\;andn %R2,%R1,%R0"
2061   [(set_attr "length" "2")])
2062
2063 (define_insn ""
2064   [(set (match_operand:SI 0 "register_operand" "=r")
2065         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2066                 (match_operand:SI 2 "register_operand" "r")))]
2067   ""
2068   "andn %2,%1,%0")
2069
2070 (define_expand "iordi3"
2071   [(set (match_operand:DI 0 "register_operand" "")
2072         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
2073                 (match_operand:DI 2 "arith_double_operand" "")))]
2074   ""
2075   "")
2076
2077 (define_insn ""
2078   [(set (match_operand:DI 0 "register_operand" "=r")
2079         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
2080                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2081   ""
2082   "*
2083 {
2084   rtx op2 = operands[2];
2085
2086   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2087      Give the assembler a chance to pick the move instruction. */
2088   if (GET_CODE (op2) == CONST_INT)
2089     {
2090       int sign = INTVAL (op2);
2091       if (sign < 0)
2092         return \"mov -1,%0\;or %R1,%2,%R0\";
2093       return \"mov %1,%0\;or %R1,%2,%R0\";
2094     }
2095   else if (GET_CODE (op2) == CONST_DOUBLE)
2096     {
2097       int sign = CONST_DOUBLE_HIGH (op2);
2098       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2099                              CONST_DOUBLE_LOW (operands[1]));
2100       if (sign < 0)
2101         return \"mov -1,%0\;or %R1,%2,%R0\";
2102       return \"mov %1,%0\;or %R1,%2,%R0\";
2103     }
2104   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
2105 }"
2106   [(set_attr "length" "2")])
2107
2108 (define_insn "iorsi3"
2109   [(set (match_operand:SI 0 "register_operand" "=r")
2110         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
2111                 (match_operand:SI 2 "arith_operand" "rI")))]
2112   ""
2113   "or %1,%2,%0")
2114
2115 (define_split
2116   [(set (match_operand:SI 0 "register_operand" "")
2117         (ior:SI (match_operand:SI 1 "register_operand" "")
2118                 (match_operand:SI 2 "" "")))
2119    (clobber (match_operand:SI 3 "register_operand" ""))]
2120   "GET_CODE (operands[2]) == CONST_INT
2121    && !SMALL_INT (operands[2])
2122    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2123   [(set (match_dup 3) (match_dup 4))
2124    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2125   "
2126 {
2127   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2128 }")
2129
2130 (define_insn ""
2131   [(set (match_operand:DI 0 "register_operand" "=r")
2132         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2133                 (match_operand:DI 2 "register_operand" "r")))]
2134   ""
2135   "orn %2,%1,%0\;orn %R2,%R1,%R0"
2136   [(set_attr "length" "2")])
2137
2138 (define_insn ""
2139   [(set (match_operand:SI 0 "register_operand" "=r")
2140         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2141                 (match_operand:SI 2 "register_operand" "r")))]
2142   ""
2143   "orn %2,%1,%0")
2144
2145 (define_expand "xordi3"
2146   [(set (match_operand:DI 0 "register_operand" "")
2147         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2148                 (match_operand:DI 2 "arith_double_operand" "")))]
2149   ""
2150   "")
2151
2152 (define_insn ""
2153   [(set (match_operand:DI 0 "register_operand" "=r")
2154         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2155                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2156   ""
2157   "*
2158 {
2159   rtx op2 = operands[2];
2160
2161   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2162      Give the assembler a chance to pick the move instruction. */
2163   if (GET_CODE (op2) == CONST_INT)
2164     {
2165       int sign = INTVAL (op2);
2166       if (sign < 0)
2167         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2168       return \"mov %1,%0\;xor %R1,%2,%R0\";
2169     }
2170   else if (GET_CODE (op2) == CONST_DOUBLE)
2171     {
2172       int sign = CONST_DOUBLE_HIGH (op2);
2173       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2174                              CONST_DOUBLE_LOW (operands[1]));
2175       if (sign < 0)
2176         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2177       return \"mov %1,%0\;xor %R1,%2,%R0\";
2178     }
2179   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2180 }"
2181   [(set_attr "length" "2")])
2182
2183 (define_insn "xorsi3"
2184   [(set (match_operand:SI 0 "register_operand" "=r")
2185         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2186                 (match_operand:SI 2 "arith_operand" "rI")))]
2187   ""
2188   "xor %r1,%2,%0")
2189
2190 (define_split
2191   [(set (match_operand:SI 0 "register_operand" "")
2192         (xor:SI (match_operand:SI 1 "register_operand" "")
2193                 (match_operand:SI 2 "" "")))
2194    (clobber (match_operand:SI 3 "register_operand" ""))]
2195   "GET_CODE (operands[2]) == CONST_INT
2196    && !SMALL_INT (operands[2])
2197    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2198   [(set (match_dup 3) (match_dup 4))
2199    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2200   "
2201 {
2202   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2203 }")
2204
2205 (define_split
2206   [(set (match_operand:SI 0 "register_operand" "")
2207         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2208                         (match_operand:SI 2 "" ""))))
2209    (clobber (match_operand:SI 3 "register_operand" ""))]
2210   "GET_CODE (operands[2]) == CONST_INT
2211    && !SMALL_INT (operands[2])
2212    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2213   [(set (match_dup 3) (match_dup 4))
2214    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2215   "
2216 {
2217   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2218 }")
2219
2220 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2221 ;; Combine now canonicalizes to the rightmost expression.
2222 (define_insn ""
2223   [(set (match_operand:DI 0 "register_operand" "=r")
2224         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2225                         (match_operand:DI 2 "register_operand" "r"))))]
2226   ""
2227   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2228   [(set_attr "length" "2")])
2229
2230 (define_insn ""
2231   [(set (match_operand:SI 0 "register_operand" "=r")
2232         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2233                         (match_operand:SI 2 "arith_operand" "rI"))))]
2234   ""
2235   "xnor %r1,%2,%0")
2236
2237 ;; These correspond to the above in the case where we also (or only)
2238 ;; want to set the condition code.  
2239
2240 (define_insn ""
2241   [(set (reg:CC 0)
2242         (compare:CC
2243          (match_operator:SI 2 "cc_arithop"
2244                             [(match_operand:SI 0 "arith_operand" "%r")
2245                              (match_operand:SI 1 "arith_operand" "rI")])
2246          (const_int 0)))]
2247   ""
2248   "%A2cc %0,%1,%%g0"
2249   [(set_attr "type" "compare")])
2250
2251 (define_insn ""
2252   [(set (reg:CC 0)
2253         (compare:CC
2254          (match_operator:SI 3 "cc_arithop"
2255                             [(match_operand:SI 1 "arith_operand" "%r")
2256                              (match_operand:SI 2 "arith_operand" "rI")])
2257          (const_int 0)))
2258    (set (match_operand:SI 0 "register_operand" "=r")
2259         (match_dup 3))]
2260   ""
2261   "%A3cc %1,%2,%0")
2262
2263 (define_insn ""
2264   [(set (reg:CC 0)
2265         (compare:CC
2266          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2267                          (match_operand:SI 1 "arith_operand" "rI")))
2268          (const_int 0)))]
2269   ""
2270   "xnorcc %r0,%1,%%g0"
2271   [(set_attr "type" "compare")])
2272
2273 (define_insn ""
2274   [(set (reg:CC 0)
2275         (compare:CC
2276          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2277                          (match_operand:SI 2 "arith_operand" "rI")))
2278          (const_int 0)))
2279    (set (match_operand:SI 0 "register_operand" "=r")
2280         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2281   ""
2282   "xnorcc %r1,%2,%0")
2283
2284 (define_insn ""
2285   [(set (reg:CC 0)
2286         (compare:CC
2287          (match_operator:SI 2 "cc_arithopn"
2288                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2289                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2290          (const_int 0)))]
2291   ""
2292   "%B2cc %r1,%0,%%g0"
2293   [(set_attr "type" "compare")])
2294
2295 (define_insn ""
2296   [(set (reg:CC 0)
2297         (compare:CC
2298          (match_operator:SI 3 "cc_arithopn"
2299                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2300                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2301          (const_int 0)))
2302    (set (match_operand:SI 0 "register_operand" "=r")
2303         (match_dup 3))]
2304   ""
2305   "%B3cc %r2,%1,%0")
2306
2307 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2308 ;; does not know how to make it work for constants.
2309
2310 (define_insn "negdi2"
2311   [(set (match_operand:DI 0 "register_operand" "=r")
2312         (neg:DI (match_operand:DI 1 "register_operand" "r")))
2313    (clobber (reg:SI 0))]
2314   ""
2315   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2316   [(set_attr "type" "unary")
2317    (set_attr "length" "2")])
2318
2319 (define_insn "negsi2"
2320   [(set (match_operand:SI 0 "general_operand" "=r")
2321         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2322   ""
2323   "sub %%g0,%1,%0"
2324   [(set_attr "type" "unary")])
2325
2326 (define_insn ""
2327   [(set (reg:CC_NOOV 0)
2328         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2329                          (const_int 0)))]
2330   ""
2331   "subcc %%g0,%0,%%g0"
2332   [(set_attr "type" "compare")])
2333
2334 (define_insn ""
2335   [(set (reg:CC_NOOV 0)
2336         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2337                          (const_int 0)))
2338    (set (match_operand:SI 0 "register_operand" "=r")
2339         (neg:SI (match_dup 1)))]
2340   ""
2341   "subcc %%g0,%1,%0"
2342   [(set_attr "type" "unary")])
2343
2344 ;; We cannot use the "not" pseudo insn because the Sun assembler
2345 ;; does not know how to make it work for constants.
2346 (define_expand "one_cmpldi2"
2347   [(set (match_operand:DI 0 "register_operand" "=r")
2348         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2349   ""
2350   "")
2351
2352 (define_insn ""
2353   [(set (match_operand:DI 0 "register_operand" "=r")
2354         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2355   ""
2356   "*
2357 {
2358   rtx op1 = operands[1];
2359
2360   if (GET_CODE (op1) == CONST_INT)
2361     {
2362       int sign = INTVAL (op1);
2363       if (sign < 0)
2364         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2365       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2366     }
2367   else if (GET_CODE (op1) == CONST_DOUBLE)
2368     {
2369       int sign = CONST_DOUBLE_HIGH (op1);
2370       operands[1] = gen_rtx (CONST_INT, VOIDmode,
2371                              CONST_DOUBLE_LOW (operands[1]));
2372       if (sign < 0)
2373         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2374       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2375     }
2376   return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2377 }"
2378   [(set_attr "type" "unary")
2379    (set_attr "length" "2")])
2380
2381 (define_insn "one_cmplsi2"
2382   [(set (match_operand:SI 0 "register_operand" "=r")
2383         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2384   ""
2385   "xnor %%g0,%1,%0"
2386   [(set_attr "type" "unary")])
2387
2388 (define_insn ""
2389   [(set (reg:CC 0)
2390         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2391                     (const_int 0)))]
2392   ""
2393   "xnorcc %%g0,%0,%%g0"
2394   [(set_attr "type" "compare")])
2395
2396 (define_insn ""
2397   [(set (reg:CC 0)
2398         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2399                     (const_int 0)))
2400    (set (match_operand:SI 0 "register_operand" "=r")
2401         (not:SI (match_dup 1)))]
2402   ""
2403   "xnorcc %%g0,%1,%0"
2404   [(set_attr "type" "unary")])
2405 \f
2406 ;; Floating point arithmetic instructions.
2407
2408 (define_insn "addtf3"
2409   [(set (match_operand:TF 0 "register_operand" "=f")
2410         (plus:TF (match_operand:TF 1 "register_operand" "f")
2411                  (match_operand:TF 2 "register_operand" "f")))]
2412   "TARGET_FPU"
2413   "faddq %1,%2,%0"
2414   [(set_attr "type" "fp")])
2415
2416 (define_insn "adddf3"
2417   [(set (match_operand:DF 0 "register_operand" "=f")
2418         (plus:DF (match_operand:DF 1 "register_operand" "f")
2419                  (match_operand:DF 2 "register_operand" "f")))]
2420   "TARGET_FPU"
2421   "faddd %1,%2,%0"
2422   [(set_attr "type" "fp")])
2423
2424 (define_insn "addsf3"
2425   [(set (match_operand:SF 0 "register_operand" "=f")
2426         (plus:SF (match_operand:SF 1 "register_operand" "f")
2427                  (match_operand:SF 2 "register_operand" "f")))]
2428   "TARGET_FPU"
2429   "fadds %1,%2,%0"
2430   [(set_attr "type" "fp")])
2431
2432 (define_insn "subtf3"
2433   [(set (match_operand:TF 0 "register_operand" "=f")
2434         (minus:TF (match_operand:TF 1 "register_operand" "f")
2435                   (match_operand:TF 2 "register_operand" "f")))]
2436   "TARGET_FPU"
2437   "fsubq %1,%2,%0"
2438   [(set_attr "type" "fp")])
2439
2440 (define_insn "subdf3"
2441   [(set (match_operand:DF 0 "register_operand" "=f")
2442         (minus:DF (match_operand:DF 1 "register_operand" "f")
2443                   (match_operand:DF 2 "register_operand" "f")))]
2444   "TARGET_FPU"
2445   "fsubd %1,%2,%0"
2446   [(set_attr "type" "fp")])
2447
2448 (define_insn "subsf3"
2449   [(set (match_operand:SF 0 "register_operand" "=f")
2450         (minus:SF (match_operand:SF 1 "register_operand" "f")
2451                   (match_operand:SF 2 "register_operand" "f")))]
2452   "TARGET_FPU"
2453   "fsubs %1,%2,%0"
2454   [(set_attr "type" "fp")])
2455
2456 (define_insn "multf3"
2457   [(set (match_operand:TF 0 "register_operand" "=f")
2458         (mult:TF (match_operand:TF 1 "register_operand" "f")
2459                  (match_operand:TF 2 "register_operand" "f")))]
2460   "TARGET_FPU"
2461   "fmulq %1,%2,%0"
2462   [(set_attr "type" "fpmul")])
2463
2464 (define_insn "muldf3"
2465   [(set (match_operand:DF 0 "register_operand" "=f")
2466         (mult:DF (match_operand:DF 1 "register_operand" "f")
2467                  (match_operand:DF 2 "register_operand" "f")))]
2468   "TARGET_FPU"
2469   "fmuld %1,%2,%0"
2470   [(set_attr "type" "fpmul")])
2471
2472 (define_insn "mulsf3"
2473   [(set (match_operand:SF 0 "register_operand" "=f")
2474         (mult:SF (match_operand:SF 1 "register_operand" "f")
2475                  (match_operand:SF 2 "register_operand" "f")))]
2476   "TARGET_FPU"
2477   "fmuls %1,%2,%0"
2478   [(set_attr "type" "fpmul")])
2479
2480 (define_insn ""
2481   [(set (match_operand:DF 0 "register_operand" "=f")
2482         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2483                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2484   "TARGET_V8 && TARGET_FPU"
2485   "fsmuld %1,%2,%0"
2486   [(set_attr "type" "fpmul")])
2487
2488 (define_insn ""
2489   [(set (match_operand:TF 0 "register_operand" "=f")
2490         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2491                  (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2492   "TARGET_V8 && TARGET_FPU"
2493   "fdmulq %1,%2,%0"
2494   [(set_attr "type" "fpmul")])
2495
2496 (define_insn "divtf3"
2497   [(set (match_operand:TF 0 "register_operand" "=f")
2498         (div:TF (match_operand:TF 1 "register_operand" "f")
2499                 (match_operand:TF 2 "register_operand" "f")))]
2500   "TARGET_FPU"
2501   "fdivq %1,%2,%0"
2502   [(set_attr "type" "fpdiv")])
2503
2504 (define_insn "divdf3"
2505   [(set (match_operand:DF 0 "register_operand" "=f")
2506         (div:DF (match_operand:DF 1 "register_operand" "f")
2507                 (match_operand:DF 2 "register_operand" "f")))]
2508   "TARGET_FPU"
2509   "fdivd %1,%2,%0"
2510   [(set_attr "type" "fpdiv")])
2511
2512 (define_insn "divsf3"
2513   [(set (match_operand:SF 0 "register_operand" "=f")
2514         (div:SF (match_operand:SF 1 "register_operand" "f")
2515                 (match_operand:SF 2 "register_operand" "f")))]
2516   "TARGET_FPU"
2517   "fdivs %1,%2,%0"
2518   [(set_attr "type" "fpdiv")])
2519
2520 (define_insn "negtf2"
2521   [(set (match_operand:TF 0 "register_operand" "=f,f")
2522         (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2523   "TARGET_FPU"
2524   "@
2525    fnegs %0,%0
2526    fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2527   [(set_attr "type" "fp")
2528    (set_attr "length" "1,4")])
2529
2530 (define_insn "negdf2"
2531   [(set (match_operand:DF 0 "register_operand" "=f,f")
2532         (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2533   "TARGET_FPU"
2534   "@
2535    fnegs %0,%0
2536    fnegs %1,%0\;fmovs %R1,%R0"
2537   [(set_attr "type" "fp")
2538    (set_attr "length" "1,2")])
2539
2540 (define_insn "negsf2"
2541   [(set (match_operand:SF 0 "register_operand" "=f")
2542         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2543   "TARGET_FPU"
2544   "fnegs %1,%0"
2545   [(set_attr "type" "fp")])
2546
2547 (define_insn "abstf2"
2548   [(set (match_operand:TF 0 "register_operand" "=f,f")
2549         (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2550   "TARGET_FPU"
2551   "@
2552    fabss %0,%0
2553    fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2554   [(set_attr "type" "fp")
2555    (set_attr "length" "1,4")])
2556
2557 (define_insn "absdf2"
2558   [(set (match_operand:DF 0 "register_operand" "=f,f")
2559         (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2560   "TARGET_FPU"
2561   "@
2562    fabss %0,%0
2563    fabss %1,%0\;fmovs %R1,%R0"
2564   [(set_attr "type" "fp")
2565    (set_attr "length" "1,2")])
2566
2567 (define_insn "abssf2"
2568   [(set (match_operand:SF 0 "register_operand" "=f")
2569         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2570   "TARGET_FPU"
2571   "fabss %1,%0"
2572   [(set_attr "type" "fp")])
2573
2574 (define_insn "sqrttf2"
2575   [(set (match_operand:TF 0 "register_operand" "=f")
2576         (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2577   "TARGET_FPU"
2578   "fsqrtq %1,%0"
2579   [(set_attr "type" "fpsqrt")])
2580
2581 (define_insn "sqrtdf2"
2582   [(set (match_operand:DF 0 "register_operand" "=f")
2583         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2584   "TARGET_FPU"
2585   "fsqrtd %1,%0"
2586   [(set_attr "type" "fpsqrt")])
2587
2588 (define_insn "sqrtsf2"
2589   [(set (match_operand:SF 0 "register_operand" "=f")
2590         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2591   "TARGET_FPU"
2592   "fsqrts %1,%0"
2593   [(set_attr "type" "fpsqrt")])
2594 \f
2595 ;;- arithmetic shift instructions
2596
2597 (define_insn "ashlsi3"
2598   [(set (match_operand:SI 0 "register_operand" "=r")
2599         (ashift:SI (match_operand:SI 1 "register_operand" "r")
2600                    (match_operand:SI 2 "arith_operand" "rI")))]
2601   ""
2602   "*
2603 {
2604   if (GET_CODE (operands[2]) == CONST_INT
2605       && (unsigned) INTVAL (operands[2]) > 31)
2606     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2607
2608   return \"sll %1,%2,%0\";
2609 }")
2610
2611 (define_insn ""
2612   [(set (reg:CC_NOOV 0)
2613         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
2614                                     (const_int 1))
2615                          (const_int 0)))]
2616   ""
2617   "addcc %0,%0,%%g0"
2618   [(set_attr "type" "compare")])
2619
2620 (define_insn ""
2621   [(set (reg:CC_NOOV 0)
2622         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
2623                                     (const_int 1))
2624                          (const_int 0)))
2625    (set (match_operand:SI 0 "register_operand" "=r")
2626         (ashift:SI (match_dup 1) (const_int 1)))]
2627   ""
2628   "addcc %1,%1,%0")
2629
2630 (define_insn "ashrsi3"
2631   [(set (match_operand:SI 0 "register_operand" "=r")
2632         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2633                      (match_operand:SI 2 "arith_operand" "rI")))]
2634   ""
2635   "*
2636 {
2637   if (GET_CODE (operands[2]) == CONST_INT
2638       && (unsigned) INTVAL (operands[2]) > 31)
2639     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2640
2641   return \"sra %1,%2,%0\";
2642 }")
2643
2644 (define_insn "lshrsi3"
2645   [(set (match_operand:SI 0 "register_operand" "=r")
2646         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2647                      (match_operand:SI 2 "arith_operand" "rI")))]
2648   ""
2649   "*
2650 {
2651   if (GET_CODE (operands[2]) == CONST_INT
2652       && (unsigned) INTVAL (operands[2]) > 31)
2653     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
2654
2655   return \"srl %1,%2,%0\";
2656 }")
2657 \f
2658 ;; Unconditional and other jump instructions
2659 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2660 ;; following insn is never executed.  This saves us a nop.  Dbx does not
2661 ;; handle such branches though, so we only use them when optimizing.
2662 (define_insn "jump"
2663   [(set (pc) (label_ref (match_operand 0 "" "")))]
2664   ""
2665   "b%* %l0%("
2666   [(set_attr "type" "uncond_branch")])
2667
2668 (define_expand "tablejump"
2669   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2670               (use (label_ref (match_operand 1 "" "")))])]
2671   ""
2672   "
2673 {
2674   /* We need to use the PC value in %o7 that was set up when the address
2675      of the label was loaded into a register, so we need different RTL.  */
2676   if (flag_pic)
2677     {
2678       emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2679       DONE;
2680     }
2681 }")
2682
2683 (define_insn "pic_tablejump"
2684   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2685    (use (label_ref (match_operand 1 "" "")))
2686    (use (reg:SI 15))]
2687   ""
2688   "jmp %%o7+%0%#"
2689   [(set_attr "type" "uncond_branch")])
2690
2691 (define_insn ""
2692   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2693    (use (label_ref (match_operand 1 "" "")))]
2694   ""
2695   "jmp %a0%#"
2696   [(set_attr "type" "uncond_branch")])
2697
2698 (define_insn ""
2699   [(set (pc) (label_ref (match_operand 0 "" "")))
2700    (set (reg:SI 15) (label_ref (match_dup 0)))]
2701   ""
2702   "call %l0%#"
2703   [(set_attr "type" "uncond_branch")])
2704
2705 ;; This pattern recognizes the "instruction" that appears in 
2706 ;; a function call that wants a structure value, 
2707 ;; to inform the called function if compiled with Sun CC.
2708 ;(define_insn ""
2709 ;  [(match_operand:SI 0 "immediate_operand" "")]
2710 ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2711 ;  "unimp %0"
2712 ;  [(set_attr "type" "marker")])
2713
2714 ;;- jump to subroutine
2715 (define_expand "call"
2716   ;; Note that this expression is not used for generating RTL.
2717   ;; All the RTL is generated explicitly below.
2718   [(call (match_operand:SI 0 "call_operand" "")
2719          (match_operand 3 "" "i"))]
2720   ;; operands[2] is next_arg_register
2721   ;; operands[3] is struct_value_size_rtx.
2722   ""
2723   "
2724 {
2725   rtx fn_rtx, nregs_rtx;
2726
2727   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2728     {
2729       /* This is really a PIC sequence.  We want to represent
2730          it as a funny jump so it's delay slots can be filled. 
2731
2732          ??? But if this really *is* a CALL, will not it clobber the
2733          call-clobbered registers?  We lose this if it is a JUMP_INSN.
2734          Why cannot we have delay slots filled if it were a CALL?  */
2735
2736       if (INTVAL (operands[3]) > 0)
2737         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2738                                  gen_rtx (SET, VOIDmode, pc_rtx,
2739                                           XEXP (operands[0], 0)),
2740                                  operands[3],
2741                                  gen_rtx (CLOBBER, VOIDmode,
2742                                           gen_rtx (REG, SImode, 15)))));
2743       else
2744         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2745                                  gen_rtx (SET, VOIDmode, pc_rtx,
2746                                           XEXP (operands[0], 0)),
2747                                  gen_rtx (CLOBBER, VOIDmode,
2748                                           gen_rtx (REG, SImode, 15)))));
2749       goto finish_call;
2750     }
2751
2752   fn_rtx = operands[0];
2753
2754   /* Count the number of parameter registers being used by this call.
2755      if that argument is NULL, it means we are using them all, which
2756      means 6 on the sparc.  */
2757 #if 0
2758   if (operands[2])
2759     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2760   else
2761     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2762 #else
2763   nregs_rtx = const0_rtx;
2764 #endif
2765
2766   if (INTVAL (operands[3]) > 0)
2767     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2768                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2769                              operands[3],
2770                              gen_rtx (CLOBBER, VOIDmode,
2771                                                gen_rtx (REG, SImode, 15)))));
2772   else
2773     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2774                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2775                              gen_rtx (CLOBBER, VOIDmode,
2776                                                gen_rtx (REG, SImode, 15)))));
2777
2778  finish_call:
2779 #if 0
2780   /* If this call wants a structure value,
2781      emit an unimp insn to let the called function know about this.  */
2782   if (INTVAL (operands[3]) > 0)
2783     {
2784       rtx insn = emit_insn (operands[3]);
2785       SCHED_GROUP_P (insn) = 1;
2786     }
2787 #endif
2788
2789   DONE;
2790 }")
2791
2792 ;; We can't use the same pattern for these two insns, because then registers
2793 ;; in the address may not be properly reloaded.
2794
2795 (define_insn ""
2796   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2797          (match_operand 1 "" ""))
2798    (clobber (reg:SI 15))]
2799   ;;- Do not use operand 1 for most machines.
2800   ""
2801   "*
2802 {
2803   return \"call %a0,%1%#\";
2804 }"
2805   [(set_attr "type" "call")])
2806
2807 (define_insn ""
2808   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2809          (match_operand 1 "" ""))
2810    (clobber (reg:SI 15))]
2811   ;;- Do not use operand 1 for most machines.
2812   ""
2813   "*
2814 {
2815   return \"call %a0,%1%#\";
2816 }"
2817   [(set_attr "type" "call")])
2818
2819 ;; This is a call that wants a structure value.
2820 (define_insn ""
2821   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2822          (match_operand 1 "" ""))
2823    (match_operand 2 "immediate_operand" "")
2824    (clobber (reg:SI 15))]
2825   ;;- Do not use operand 1 for most machines.
2826   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2827   "*
2828 {
2829   return \"call %a0,%1\;nop\;unimp %2\";
2830 }"
2831   [(set_attr "type" "call_no_delay_slot")])
2832
2833 ;; This is a call that wants a structure value.
2834 (define_insn ""
2835   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2836          (match_operand 1 "" ""))
2837    (match_operand 2 "immediate_operand" "")
2838    (clobber (reg:SI 15))]
2839   ;;- Do not use operand 1 for most machines.
2840   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2841   "*
2842 {
2843   return \"call %a0,%1\;nop\;unimp %2\";
2844 }"
2845   [(set_attr "type" "call_no_delay_slot")])
2846
2847 (define_expand "call_value"
2848   [(set (match_operand 0 "register_operand" "=rf")
2849         (call (match_operand:SI 1 "" "")
2850               (match_operand 4 "" "")))]
2851   ;; operand 3 is next_arg_register
2852   ""
2853   "
2854 {
2855   rtx fn_rtx, nregs_rtx;
2856   rtvec vec;
2857
2858   fn_rtx = operands[1];
2859
2860 #if 0
2861   if (operands[3])
2862     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2863   else
2864     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2865 #else
2866   nregs_rtx = const0_rtx;
2867 #endif
2868
2869   vec = gen_rtvec (2,
2870                    gen_rtx (SET, VOIDmode, operands[0],
2871                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2872                    gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2873
2874   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2875
2876   DONE;
2877 }")
2878
2879 (define_insn ""
2880   [(set (match_operand 0 "" "=rf")
2881         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
2882               (match_operand 2 "" "")))
2883    (clobber (reg:SI 15))]
2884   ;;- Do not use operand 2 for most machines.
2885   ""
2886   "*
2887 {
2888   return \"call %a1,%2%#\";
2889 }"
2890   [(set_attr "type" "call")])
2891
2892 (define_insn ""
2893   [(set (match_operand 0 "" "=rf")
2894         (call (mem:SI (match_operand:SI 1 "immediate_operand" "i"))
2895               (match_operand 2 "" "")))
2896    (clobber (reg:SI 15))]
2897   ;;- Do not use operand 2 for most machines.
2898   ""
2899   "*
2900 {
2901   return \"call %a1,%2%#\";
2902 }"
2903   [(set_attr "type" "call")])
2904
2905 (define_expand "untyped_call"
2906   [(parallel [(call (match_operand:SI 0 "call_operand" "")
2907                     (const_int 0))
2908               (match_operand:BLK 1 "memory_operand" "")
2909               (match_operand 2 "" "")
2910               (clobber (reg:SI 15))])]
2911   ""
2912   "
2913 {
2914   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
2915 }")
2916
2917 ;; Make a call followed by two nops in case the function being called
2918 ;; returns a structure value and expects to skip an unimp instruction.
2919
2920 (define_insn ""
2921   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
2922          (const_int 0))
2923    (match_operand:DI 1 "memory_operand" "o")
2924    (match_operand 2 "" "")
2925    (clobber (reg:SI 15))]
2926   ""
2927   "*
2928 {
2929   operands[2] = adj_offsettable_operand (operands[1], 8);
2930   return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
2931 }"
2932   [(set_attr "type" "multi")])
2933
2934 ;; Make a call followed by two nops in case the function being called
2935 ;; returns a structure value and expects to skip an unimp instruction.
2936
2937 (define_insn ""
2938   [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i"))
2939          (const_int 0))
2940    (match_operand:DI 1 "memory_operand" "o")
2941    (match_operand 2 "" "")
2942    (clobber (reg:SI 15))]
2943   ""
2944   "*
2945 {
2946   operands[2] = adj_offsettable_operand (operands[1], 8);
2947   return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
2948 }"
2949   [(set_attr "type" "multi")])
2950
2951 ;; Prepare to return any type including a structure value.
2952
2953 (define_expand "untyped_return"
2954   [(match_operand:BLK 0 "memory_operand" "")
2955    (match_operand 1 "" "")]
2956   ""
2957   "
2958 {
2959   rtx valreg1 = gen_rtx (REG, DImode, 24);
2960   rtx valreg2 = gen_rtx (REG, DFmode, 32);
2961   rtx result = operands[0];
2962   rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
2963   rtx value = gen_reg_rtx (SImode);
2964
2965   /* Fetch the instruction where we will return to and see if it's an unimp
2966      instruction (the most significant 10 bits will be zero).  If so,
2967      update the return address to skip the unimp instruction.  */
2968   emit_move_insn (value,
2969                   gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
2970   emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
2971   emit_insn (gen_update_return (rtnreg, value));
2972
2973   /* Reload the function value registers.  */
2974   emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
2975   emit_move_insn (valreg2,
2976                   change_address (result, DFmode,
2977                                   plus_constant (XEXP (result, 0), 8)));
2978
2979   /* Put USE insns before the return.  */
2980   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
2981   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
2982
2983   /* Construct the return.  */
2984   expand_null_return ();
2985
2986   DONE;
2987 }")
2988
2989 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
2990 ;; and parts of the compiler don't want to believe that the add is needed.
2991
2992 (define_insn "update_return"
2993   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
2994                (match_operand:SI 1 "register_operand" "r")] 0)]
2995   ""
2996   "cmp %1,0\;be,a .+8\;add %0,4,%0"
2997   [(set_attr "type" "multi")])
2998 \f
2999 (define_insn "return"
3000   [(return)]
3001   "! TARGET_EPILOGUE"
3002   "* return output_return (operands);"
3003   [(set_attr "type" "multi")])
3004
3005 (define_insn "nop"
3006   [(const_int 0)]
3007   ""
3008   "nop")
3009
3010 (define_insn "indirect_jump"
3011   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
3012   ""
3013  "jmp %a0%#"
3014  [(set_attr "type" "uncond_branch")])
3015  
3016 (define_expand "nonlocal_goto"
3017   [(match_operand:SI 0 "general_operand" "")
3018    (match_operand:SI 1 "general_operand" "")
3019    (match_operand:SI 2 "general_operand" "")
3020    (match_operand:SI 3 "" "")]
3021   ""
3022   "
3023 {
3024   /* Trap instruction to flush all the registers window.  */
3025   emit_insn (gen_flush_register_windows ());
3026   /* Load the fp value for the containing fn into %fp.
3027      This is needed because operands[2] refers to %fp.
3028      Virtual register instantiation fails if the virtual %fp isn't set from a
3029      register.  Thus we must copy operands[0] into a register if it isn't
3030      already one.  */
3031   if (GET_CODE (operands[0]) != REG)
3032     operands[0] = force_reg (SImode, operands[0]);
3033   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
3034   /* Find the containing function's current nonlocal goto handler,
3035      which will do any cleanups and then jump to the label.  */
3036   emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
3037   /* Restore %fp from stack pointer value for containing function.
3038      The restore insn that follows will move this to %sp,
3039      and reload the appropriate value into %fp.  */
3040   emit_move_insn (frame_pointer_rtx, operands[2]);
3041   /* Put in the static chain register the nonlocal label address.  */
3042   emit_move_insn (static_chain_rtx, operands[3]);
3043   /* USE of frame_pointer_rtx added for consistency; not clear if
3044      really needed.  */
3045   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
3046   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
3047   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
3048   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
3049   /* Return, restoring reg window and jumping to goto handler.  */
3050   emit_insn (gen_goto_handler_and_restore ());
3051   DONE;
3052 }")
3053
3054 ;; Special trap insn to flush register windows.
3055 (define_insn "flush_register_windows"
3056   [(unspec_volatile [(const_int 0)] 0)]
3057   ""
3058   "ta 3"
3059   [(set_attr "type" "misc")])
3060
3061 (define_insn "goto_handler_and_restore"
3062   [(unspec_volatile [(const_int 0)] 1)]
3063   ""
3064   "jmp %%o0+0\;restore"
3065   [(set_attr "type" "misc")
3066    (set_attr "length" "2")])
3067
3068 ;; Special pattern for the FLUSH instruction.
3069
3070 (define_insn "flush"
3071   [(unspec_volatile [(match_operand 0 "" "")] 2)]
3072   ""
3073   "iflush %a0"
3074   [(set_attr "type" "misc")])
3075 \f
3076 ;; find first set.
3077
3078 ;; The scan instruction searches from the most significant bit while ffs
3079 ;; searches from the least significant bit.  The bit index and treatment of
3080 ;; zero also differ.  It takes at least 7 instructions to get the proper
3081 ;; result.  Here is an obvious 8 instruction seequence.
3082
3083 (define_insn "ffssi2"
3084   [(set (match_operand:SI 0 "register_operand" "=&r")
3085         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
3086    (clobber (match_scratch:SI 2 "=&r"))]
3087   "TARGET_SPARCLITE"
3088   "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"
3089   [(set_attr "type" "multi")
3090    (set_attr "length" "8")])
3091 \f
3092 ;; Split up troublesome insns for better scheduling.  */
3093
3094 ;; The following patterns are straightforward.  They can be applied
3095 ;; either before or after register allocation.
3096
3097 (define_split
3098   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
3099         (match_operand 2 "reg_or_0_operand" ""))
3100    (clobber (match_operand:SI 3 "register_operand" ""))]
3101   "! flag_pic"
3102   [(set (match_dup 3) (high:SI (match_dup 1)))
3103    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
3104         (match_dup 2))]
3105   "")
3106
3107 (define_split
3108   [(set (match_operator 0 "memop"
3109                         [(match_operand:SI 1 "immediate_operand" "")])
3110         (match_operand 2 "general_operand" ""))
3111    (clobber (match_operand:SI 3 "register_operand" ""))]
3112   "flag_pic"
3113   [(set (match_op_dup 0 [(match_dup 1)])
3114         (match_dup 2))]
3115   "
3116 {
3117   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
3118                                         operands[3]);
3119 }")
3120
3121 (define_split
3122   [(set (match_operand 0 "register_operand" "")
3123         (match_operator 1 "memop"
3124                         [(match_operand:SI 2 "immediate_operand" "")]))]
3125   "flag_pic"
3126   [(set (match_dup 0)
3127         (match_op_dup 1 [(match_dup 2)]))]
3128   "
3129 {
3130   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
3131                                         operands[0]);
3132 }")
3133
3134 ;; Sign- and Zero-extend operations can have symbolic memory operands.
3135
3136 (define_split
3137   [(set (match_operand 0 "register_operand" "")
3138         (match_operator 1 "extend_op"
3139                         [(match_operator 2 "memop"
3140                                          [(match_operand:SI 3 "immediate_operand" "")])]))]
3141   "flag_pic"
3142   [(set (match_dup 0)
3143         (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
3144   "
3145 {
3146   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
3147                                         operands[0]);
3148 }")
3149
3150 (define_split
3151   [(set (match_operand:SI 0 "register_operand" "")
3152         (match_operand:SI 1 "immediate_operand" ""))]
3153   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3154                   || GET_CODE (operands[1]) == CONST
3155                   || GET_CODE (operands[1]) == LABEL_REF)"
3156   [(set (match_dup 0) (high:SI (match_dup 1)))
3157    (set (match_dup 0)
3158         (lo_sum:SI (match_dup 0) (match_dup 1)))]
3159   "")
3160
3161 ;; LABEL_REFs are not modified by `legitimize_pic_address`
3162 ;; so do not recurse infinitely in the PIC case.
3163 (define_split
3164   [(set (match_operand:SI 0 "register_operand" "")
3165         (match_operand:SI 1 "immediate_operand" ""))]
3166   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
3167                 || GET_CODE (operands[1]) == CONST)"
3168   [(set (match_dup 0) (match_dup 1))]
3169   "
3170 {
3171   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
3172 }")
3173 \f
3174 ;; These split sne/seq insns.  The forms of the resulting insns are 
3175 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
3176 ;; Nothing will look at these in detail after splitting has occurred.
3177
3178 (define_split
3179   [(set (match_operand:SI 0 "register_operand" "")
3180         (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3181    (clobber (reg:CC 0))]
3182   ""
3183   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3184                                          (const_int 0)))
3185    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
3186   "")
3187
3188 (define_split
3189   [(set (match_operand:SI 0 "register_operand" "")
3190         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3191                        (const_int 0))))
3192    (clobber (reg:CC 0))]
3193   ""
3194   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3195                                          (const_int 0)))
3196    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
3197   "")
3198
3199 (define_split
3200   [(set (match_operand:SI 0 "register_operand" "")
3201         (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
3202    (clobber (reg:CC 0))]
3203   ""
3204   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3205                                          (const_int 0)))
3206    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
3207   "")
3208
3209 (define_split
3210   [(set (match_operand:SI 0 "register_operand" "")
3211         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3212                        (const_int 0))))
3213    (clobber (reg:CC 0))]
3214   ""
3215   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3216                                          (const_int 0)))
3217    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
3218   "")
3219
3220 (define_split
3221   [(set (match_operand:SI 0 "register_operand" "")
3222         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
3223                         (const_int 0))
3224                  (match_operand:SI 2 "register_operand" "")))
3225    (clobber (reg:CC 0))]
3226   ""
3227   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3228                                          (const_int 0)))
3229    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
3230                                (match_dup 2)))]
3231   "")
3232
3233 (define_split
3234   [(set (match_operand:SI 0 "register_operand" "")
3235         (minus:SI (match_operand:SI 2 "register_operand" "")
3236                   (ne:SI (match_operand:SI 1 "register_operand" "")
3237                          (const_int 0))))
3238    (clobber (reg:CC 0))]
3239   ""
3240   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3241                                          (const_int 0)))
3242    (set (match_dup 0) (minus:SI (match_dup 2)
3243                                 (ltu:SI (reg:CC 0) (const_int 0))))]
3244   "")
3245
3246 (define_split
3247   [(set (match_operand:SI 0 "register_operand" "")
3248         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
3249                         (const_int 0))
3250                  (match_operand:SI 2 "register_operand" "")))
3251    (clobber (reg:CC 0))]
3252   ""
3253   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3254                                          (const_int 0)))
3255    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
3256                                (match_dup 2)))]
3257   "")
3258
3259 (define_split
3260   [(set (match_operand:SI 0 "register_operand" "")
3261         (minus:SI (match_operand:SI 2 "register_operand" "")
3262                   (eq:SI (match_operand:SI 1 "register_operand" "")
3263                          (const_int 0))))
3264    (clobber (reg:CC 0))]
3265   ""
3266   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
3267                                          (const_int 0)))
3268    (set (match_dup 0) (minus:SI (match_dup 2)
3269                                 (geu:SI (reg:CC 0) (const_int 0))))]
3270   "")
3271 \f
3272 ;; Peepholes go at the end.
3273
3274 ;; Optimize consecutive loads or stores into ldd and std when possible.
3275 ;; The conditions in which we do this are very restricted and are 
3276 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3277
3278 (define_peephole
3279   [(set (match_operand:SI 0 "register_operand" "=rf")
3280         (match_operand:SI 1 "memory_operand" ""))
3281    (set (match_operand:SI 2 "register_operand" "=rf")
3282         (match_operand:SI 3 "memory_operand" ""))]
3283   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3284    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3285    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
3286   "ldd %1,%0")
3287
3288 (define_peephole
3289   [(set (match_operand:SI 0 "memory_operand" "")
3290         (match_operand:SI 1 "register_operand" "rf"))
3291    (set (match_operand:SI 2 "memory_operand" "")
3292         (match_operand:SI 3 "register_operand" "rf"))]
3293   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3294    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3295    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3296   "std %1,%0")
3297  
3298 (define_peephole
3299   [(set (match_operand:SF 0 "register_operand" "=fr")
3300         (match_operand:SF 1 "memory_operand" ""))
3301    (set (match_operand:SF 2 "register_operand" "=fr")
3302         (match_operand:SF 3 "memory_operand" ""))]
3303   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3304    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3305    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3306   "ldd %1,%0")
3307
3308 (define_peephole
3309   [(set (match_operand:SF 0 "memory_operand" "")
3310         (match_operand:SF 1 "register_operand" "fr"))
3311    (set (match_operand:SF 2 "memory_operand" "")
3312         (match_operand:SF 3 "register_operand" "fr"))]
3313   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3314    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3315    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3316   "std %1,%0")
3317
3318 (define_peephole
3319   [(set (match_operand:SI 0 "register_operand" "=rf")
3320         (match_operand:SI 1 "memory_operand" ""))
3321    (set (match_operand:SI 2 "register_operand" "=rf")
3322         (match_operand:SI 3 "memory_operand" ""))]
3323   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3324    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3325    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3326   "ldd %3,%2")
3327
3328 (define_peephole
3329   [(set (match_operand:SI 0 "memory_operand" "")
3330         (match_operand:SI 1 "register_operand" "rf"))
3331    (set (match_operand:SI 2 "memory_operand" "")
3332         (match_operand:SI 3 "register_operand" "rf"))]
3333   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3334    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3335    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
3336   "std %3,%2")
3337  
3338 (define_peephole
3339   [(set (match_operand:SF 0 "register_operand" "=fr")
3340         (match_operand:SF 1 "memory_operand" ""))
3341    (set (match_operand:SF 2 "register_operand" "=fr")
3342         (match_operand:SF 3 "memory_operand" ""))]
3343   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3344    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3345    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3346   "ldd %3,%2")
3347
3348 (define_peephole
3349   [(set (match_operand:SF 0 "memory_operand" "")
3350         (match_operand:SF 1 "register_operand" "fr"))
3351    (set (match_operand:SF 2 "memory_operand" "")
3352         (match_operand:SF 3 "register_operand" "fr"))]
3353   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3354    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3355    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3356   "std %3,%2")
3357  
3358 ;; Optimize the case of following a reg-reg move with a test
3359 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
3360 ;; This can result from a float to fix conversion.
3361
3362 (define_peephole
3363   [(set (match_operand:SI 0 "register_operand" "=r")
3364         (match_operand:SI 1 "register_operand" "r"))
3365    (set (reg:CC 0)
3366         (compare:CC (match_operand:SI 2 "register_operand" "r")
3367                     (const_int 0)))]
3368   "(rtx_equal_p (operands[2], operands[0])
3369     || rtx_equal_p (operands[2], operands[1]))
3370    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3371   "orcc %1,%%g0,%0")
3372
3373 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3374 ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
3375 ;;     eventually have some impact here?
3376
3377 (define_peephole
3378   [(set (match_operand:HI 0 "register_operand" "")
3379         (match_operand:HI 1 "memory_operand" ""))
3380    (set (match_operand:SI 2 "register_operand" "")
3381         (sign_extend:SI (match_dup 0)))
3382    (set (reg:CC 0)
3383         (compare:CC (match_dup 2)
3384                     (const_int 0)))]
3385   ""
3386   "ldsh %1,%0\;orcc %0,%%g0,%2")
3387
3388 (define_peephole
3389   [(set (match_operand:QI 0 "register_operand" "")
3390         (match_operand:QI 1 "memory_operand" ""))
3391    (set (match_operand:SI 2 "register_operand" "")
3392         (sign_extend:SI (match_dup 0)))
3393    (set (reg:CC 0)
3394         (compare:CC (match_dup 2)
3395                     (const_int 0)))]
3396   ""
3397   "ldsb %1,%0\;orcc %0,%%g0,%2")
3398
3399 (define_peephole
3400   [(set (match_operand:HI 0 "register_operand" "")
3401         (match_operand:HI 1 "memory_operand" ""))
3402    (set (match_operand:SI 2 "register_operand" "")
3403         (sign_extend:SI (match_dup 0)))]
3404   "dead_or_set_p (insn, operands[0])"
3405   "*
3406 {
3407   warning (\"bad peephole\");
3408   if (! MEM_VOLATILE_P (operands[1]))
3409     abort ();
3410   return \"ldsh %1,%2\";
3411 }")
3412
3413 (define_peephole
3414   [(set (match_operand:QI 0 "register_operand" "")
3415         (match_operand:QI 1 "memory_operand" ""))
3416    (set (match_operand:SI 2 "register_operand" "")
3417         (sign_extend:SI (match_dup 0)))]
3418   "dead_or_set_p (insn, operands[0])"
3419   "*
3420 {
3421   warning (\"bad peephole\");
3422   if (! MEM_VOLATILE_P (operands[1]))
3423     abort ();
3424   return \"ldsb %1,%2\";
3425 }")
3426
3427 ;; Floating-point move peepholes
3428
3429 (define_peephole
3430   [(set (match_operand:SI 0 "register_operand" "=r")
3431         (lo_sum:SI (match_dup 0)
3432                    (match_operand:SI 1 "immediate_operand" "i")))
3433    (set (match_operand:DF 2 "register_operand" "=fr")
3434         (mem:DF (match_dup 0)))]
3435   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3436   "*
3437 {
3438   /* Go by way of output_move_double in case the register in operand 2
3439      is not properly aligned for ldd.  */
3440   operands[1] = gen_rtx (MEM, DFmode,
3441                          gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3442   operands[0] = operands[2];
3443   return output_move_double (operands);
3444 }")
3445
3446 (define_peephole
3447   [(set (match_operand:SI 0 "register_operand" "=r")
3448         (lo_sum:SI (match_dup 0)
3449                    (match_operand:SI 1 "immediate_operand" "i")))
3450    (set (match_operand:SF 2 "register_operand" "=fr")
3451         (mem:SF (match_dup 0)))]
3452   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3453   "ld [%0+%%lo(%a1)],%2")
3454
3455 ;; Return peepholes.  First the "normal" ones
3456
3457 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3458 ;; It might be possible to write one more general pattern instead of three.
3459
3460 (define_insn ""
3461   [(set (match_operand:QI 0 "restore_operand" "")
3462         (match_operand:QI 1 "arith_operand" "rI"))
3463    (return)]
3464   "! TARGET_EPILOGUE"
3465   "*
3466 {
3467   if (current_function_returns_struct)
3468     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3469   else
3470     return \"ret\;restore %%g0,%1,%Y0\";
3471 }"
3472   [(set_attr "type" "multi")])
3473
3474 (define_insn ""
3475   [(set (match_operand:HI 0 "restore_operand" "")
3476         (match_operand:HI 1 "arith_operand" "rI"))
3477    (return)]
3478   "! TARGET_EPILOGUE"
3479   "*
3480 {
3481   if (current_function_returns_struct)
3482     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3483   else
3484     return \"ret\;restore %%g0,%1,%Y0\";
3485 }"
3486   [(set_attr "type" "multi")])
3487
3488 (define_insn ""
3489   [(set (match_operand:SI 0 "restore_operand" "")
3490         (match_operand:SI 1 "arith_operand" "rI"))
3491    (return)]
3492   "! TARGET_EPILOGUE"
3493   "*
3494 {
3495   if (current_function_returns_struct)
3496     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3497   else
3498     return \"ret\;restore %%g0,%1,%Y0\";
3499 }"
3500   [(set_attr "type" "multi")])
3501
3502 ;; The following pattern is only generated by delayed-branch scheduling,
3503 ;; when the insn winds up in the epilogue.  This can only happen when
3504 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3505 (define_insn ""
3506   [(set (match_operand:SF 0 "restore_operand" "r")
3507         (match_operand:SF 1 "register_operand" "r"))
3508    (return)]
3509   "! TARGET_FPU && ! TARGET_EPILOGUE"
3510   "*
3511 {
3512   if (current_function_returns_struct)
3513     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3514   else
3515     return \"ret\;restore %%g0,%1,%Y0\";
3516 }"
3517   [(set_attr "type" "multi")])
3518
3519 (define_insn ""
3520   [(set (match_operand:SI 0 "restore_operand" "")
3521         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3522                  (match_operand:SI 2 "arith_operand" "rI")))
3523    (return)]
3524   "! TARGET_EPILOGUE"
3525   "*
3526 {
3527   if (current_function_returns_struct)
3528     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3529   else
3530     return \"ret\;restore %r1,%2,%Y0\";
3531 }"
3532   [(set_attr "type" "multi")])
3533
3534 ;; Turned off because it should never match (subtracting a constant
3535 ;; is turned into addition) and because it would do the wrong thing
3536 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3537 ;;(define_insn ""
3538 ;;  [(set (match_operand:SI 0 "restore_operand" "")
3539 ;;      (minus:SI (match_operand:SI 1 "register_operand" "r")
3540 ;;                (match_operand:SI 2 "small_int" "I")))
3541 ;;   (return)]
3542 ;;  "! TARGET_EPILOGUE"
3543 ;;  "ret\;restore %1,-(%2),%Y0"
3544 ;;  [(set_attr "type" "multi")])
3545
3546 ;; The following pattern is only generated by delayed-branch scheduling,
3547 ;; when the insn winds up in the epilogue.
3548 (define_insn ""
3549   [(set (reg:SF 32)
3550         (match_operand:SF 0 "register_operand" "f"))
3551    (return)]
3552   "! TARGET_EPILOGUE"
3553   "ret\;fmovs %0,%%f0"
3554   [(set_attr "type" "multi")])
3555
3556 ;; Now peepholes to go a call followed by a jump.
3557
3558 (define_peephole
3559   [(parallel [(set (match_operand 0 "" "")
3560                    (call (mem:SI (match_operand:SI 1 "call_operand_address" "pi"))
3561                          (match_operand 2 "" "")))
3562               (clobber (reg:SI 15))])
3563    (set (pc) (label_ref (match_operand 3 "" "")))]
3564   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3565   "*
3566 {
3567   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3568 }")
3569
3570 (define_peephole
3571   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "pi"))
3572                     (match_operand 1 "" ""))
3573               (clobber (reg:SI 15))])
3574    (set (pc) (label_ref (match_operand 2 "" "")))]
3575   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3576   "*
3577 {
3578   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3579 }")
3580
3581 (define_peephole
3582   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3583                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3584                              (reg:SI 0)))
3585               (clobber (reg:CC 0))])
3586    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3587   ""
3588   "subxcc %r1,0,%0")