OSDN Git Service

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