OSDN Git Service

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