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