OSDN Git Service

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