OSDN Git Service

bcb2e96335224fffcccf82606609bfd0d8f46edf
[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,r")
1380         (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1381   "GET_CODE (operands[1]) != CONST_INT"
1382   "@
1383    and %1,0xff,%0;
1384    mov (%1 & 0xff),%0
1385    ldub %1,%0"
1386   [(set_attr "type" "unary,move,load")
1387    (set_attr "length" "1")])
1388
1389 (define_expand "zero_extendqisi2"
1390   [(set (match_operand:SI 0 "register_operand" "")
1391         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1392   ""
1393   "")
1394
1395 (define_insn ""
1396   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1397         (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,I,Q")))]
1398   "GET_CODE (operands[1]) != CONST_INT"
1399   "@
1400    and %1,0xff,%0
1401    mov (%1 & 0xff),%0
1402    ldub %1,%0"
1403   [(set_attr "type" "unary,move,load")
1404    (set_attr "length" "1")])
1405
1406 (define_insn ""
1407   [(set (reg:CC 0)
1408         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
1409                     (const_int 0)))]
1410   ""
1411   "andcc %0,0xff,%%g0"
1412   [(set_attr "type" "compare")])
1413
1414 (define_insn ""
1415   [(set (reg:CC 0)
1416         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1417                     (const_int 0)))
1418    (set (match_operand:SI 0 "register_operand" "=r")
1419         (zero_extend:SI (match_dup 1)))]
1420   ""
1421   "andcc %1,0xff,%0"
1422   [(set_attr "type" "unary")])
1423 \f
1424 ;;- sign extension instructions
1425
1426 ;; These patterns originally accepted general_operands, however, slightly
1427 ;; better code is generated by only accepting register_operands, and then
1428 ;; letting combine generate the lds[hb] insns.
1429
1430 (define_expand "extendhisi2"
1431   [(set (match_operand:SI 0 "register_operand" "")
1432         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
1433   ""
1434   "
1435 {
1436   rtx temp = gen_reg_rtx (SImode);
1437   rtx shift_16 = gen_rtx (CONST_INT, VOIDmode, 16);
1438
1439   if (GET_CODE (operand1) == SUBREG)
1440     operand1 = XEXP (operand1, 0);
1441
1442   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1443                           shift_16));
1444   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1445   DONE;
1446 }")
1447
1448 (define_insn ""
1449   [(set (match_operand:SI 0 "register_operand" "=r")
1450         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
1451   ""
1452   "ldsh %1,%0"
1453   [(set_attr "type" "load")])
1454
1455 (define_expand "extendqihi2"
1456   [(set (match_operand:HI 0 "register_operand" "")
1457         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
1458   ""
1459   "
1460 {
1461   rtx temp = gen_reg_rtx (SImode);
1462   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1463
1464   if (GET_CODE (operand1) == SUBREG)
1465     operand1 = XEXP (operand1, 0);
1466   if (GET_CODE (operand0) == SUBREG)
1467     operand0 = XEXP (operand0, 0);
1468   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1469                           shift_24));
1470   if (GET_MODE (operand0) != SImode)
1471     operand0 = gen_rtx (SUBREG, SImode, operand0, 0);
1472   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1473   DONE;
1474 }")
1475
1476 (define_insn ""
1477   [(set (match_operand:HI 0 "register_operand" "=r")
1478         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
1479   ""
1480   "ldsb %1,%0"
1481   [(set_attr "type" "load")])
1482
1483 (define_expand "extendqisi2"
1484   [(set (match_operand:SI 0 "register_operand" "")
1485         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
1486   ""
1487   "
1488 {
1489   rtx temp = gen_reg_rtx (SImode);
1490   rtx shift_24 = gen_rtx (CONST_INT, VOIDmode, 24);
1491
1492   if (GET_CODE (operand1) == SUBREG)
1493     operand1 = XEXP (operand1, 0);
1494   emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1, 0),
1495                           shift_24));
1496   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1497   DONE;
1498 }")
1499
1500 (define_insn ""
1501   [(set (match_operand:SI 0 "register_operand" "=r")
1502         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
1503   ""
1504   "ldsb %1,%0"
1505   [(set_attr "type" "load")])
1506 \f
1507 ;; Special pattern for optimizing bit-field compares.  This is needed
1508 ;; because combine uses this as a canonical form.
1509
1510 (define_insn ""
1511   [(set (reg:CC 0)
1512         (compare:CC
1513          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
1514                           (match_operand:SI 1 "small_int" "n")
1515                           (match_operand:SI 2 "small_int" "n"))
1516          (const_int 0)))]
1517   "INTVAL (operands[2]) > 19"
1518   "*
1519 {
1520   int len = INTVAL (operands[1]);
1521   int pos = 32 - INTVAL (operands[2]) - len;
1522   unsigned mask = ((1 << len) - 1) << pos;
1523
1524   operands[1] = gen_rtx (CONST_INT, VOIDmode, mask);
1525   return \"andcc %0,%1,%%g0\";
1526 }")
1527 \f
1528 ;; Conversions between float, double and long double.
1529
1530 (define_insn "extendsfdf2"
1531   [(set (match_operand:DF 0 "register_operand" "=f")
1532         (float_extend:DF
1533          (match_operand:SF 1 "register_operand" "f")))]
1534   "TARGET_FPU"
1535   "fstod %1,%0"
1536   [(set_attr "type" "fp")])
1537
1538 (define_insn "extendsftf2"
1539   [(set (match_operand:TF 0 "register_operand" "=f")
1540         (float_extend:TF
1541          (match_operand:SF 1 "register_operand" "f")))]
1542   "TARGET_FPU"
1543   "fstoq %1,%0"
1544   [(set_attr "type" "fp")])
1545
1546 (define_insn "extenddftf2"
1547   [(set (match_operand:TF 0 "register_operand" "=f")
1548         (float_extend:TF
1549          (match_operand:DF 1 "register_operand" "f")))]
1550   "TARGET_FPU"
1551   "fdtoq %1,%0"
1552   [(set_attr "type" "fp")])
1553
1554 (define_insn "truncdfsf2"
1555   [(set (match_operand:SF 0 "register_operand" "=f")
1556         (float_truncate:SF
1557          (match_operand:DF 1 "register_operand" "f")))]
1558   "TARGET_FPU"
1559   "fdtos %1,%0"
1560   [(set_attr "type" "fp")])
1561
1562 (define_insn "trunctfsf2"
1563   [(set (match_operand:SF 0 "register_operand" "=f")
1564         (float_truncate:SF
1565          (match_operand:TF 1 "register_operand" "f")))]
1566   "TARGET_FPU"
1567   "fqtos %1,%0"
1568   [(set_attr "type" "fp")])
1569
1570 (define_insn "trunctfdf2"
1571   [(set (match_operand:DF 0 "register_operand" "=f")
1572         (float_truncate:DF
1573          (match_operand:TF 1 "register_operand" "f")))]
1574   "TARGET_FPU"
1575   "fqtod %1,%0"
1576   [(set_attr "type" "fp")])
1577 \f
1578 ;; Conversion between fixed point and floating point.
1579
1580 (define_insn "floatsisf2"
1581   [(set (match_operand:SF 0 "register_operand" "=f")
1582         (float:SF (match_operand:SI 1 "register_operand" "f")))]
1583   "TARGET_FPU"
1584   "fitos %1,%0"
1585   [(set_attr "type" "fp")])
1586
1587 (define_insn "floatsidf2"
1588   [(set (match_operand:DF 0 "register_operand" "=f")
1589         (float:DF (match_operand:SI 1 "register_operand" "f")))]
1590   "TARGET_FPU"
1591   "fitod %1,%0"
1592   [(set_attr "type" "fp")])
1593
1594 (define_insn "floatsitf2"
1595   [(set (match_operand:TF 0 "register_operand" "=f")
1596         (float:TF (match_operand:SI 1 "register_operand" "f")))]
1597   "TARGET_FPU"
1598   "fitox %1,%0"
1599   [(set_attr "type" "fp")])
1600
1601 ;; Convert a float to an actual integer.
1602 ;; Truncation is performed as part of the conversion.
1603
1604 (define_insn "fix_truncsfsi2"
1605   [(set (match_operand:SI 0 "register_operand" "=f")
1606         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
1607   "TARGET_FPU"
1608   "fstoi %1,%0"
1609   [(set_attr "type" "fp")])
1610
1611 (define_insn "fix_truncdfsi2"
1612   [(set (match_operand:SI 0 "register_operand" "=f")
1613         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
1614   "TARGET_FPU"
1615   "fdtoi %1,%0"
1616   [(set_attr "type" "fp")])
1617
1618 (define_insn "fix_trunctfsi2"
1619   [(set (match_operand:SI 0 "register_operand" "=f")
1620         (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
1621   "TARGET_FPU"
1622   "fqtoi %1,%0"
1623   [(set_attr "type" "fp")])
1624 \f
1625 ;;- arithmetic instructions
1626
1627 (define_insn "adddi3"
1628   [(set (match_operand:DI 0 "register_operand" "=r")
1629         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
1630                  (match_operand:DI 2 "arith_double_operand" "rHI")))
1631    (clobber (reg:SI 0))]
1632   ""
1633   "*
1634 {
1635   rtx op2 = operands[2];
1636
1637   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1638      Give the assembler a chance to pick the move instruction. */
1639   if (GET_CODE (op2) == CONST_INT)
1640     {
1641       int sign = INTVAL (op2);
1642       if (sign < 0)
1643         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1644       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1645     }
1646   else if (GET_CODE (op2) == CONST_DOUBLE)
1647     {
1648       int sign = CONST_DOUBLE_HIGH (op2);
1649       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1650                              CONST_DOUBLE_LOW (operands[1]));
1651       if (sign < 0)
1652         return \"addcc %R1,%2,%R0\;addx %1,-1,%0\";
1653       return \"addcc %R1,%2,%R0\;addx %1,0,%0\";
1654     }
1655   return \"addcc %R1,%R2,%R0\;addx %1,%2,%0\";
1656 }"
1657   [(set_attr "length" "2")])
1658
1659 (define_insn "addsi3"
1660   [(set (match_operand:SI 0 "register_operand" "=r")
1661         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1662                  (match_operand:SI 2 "arith_operand" "rI")))]
1663   ""
1664   "add %1,%2,%0")
1665
1666 (define_insn ""
1667   [(set (reg:CC_NOOV 0)
1668         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
1669                                   (match_operand:SI 1 "arith_operand" "rI"))
1670                          (const_int 0)))]
1671   ""
1672   "addcc %0,%1,%%g0"
1673   [(set_attr "type" "compare")])
1674
1675 (define_insn ""
1676   [(set (reg:CC_NOOV 0)
1677         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1678                                   (match_operand:SI 2 "arith_operand" "rI"))
1679                          (const_int 0)))
1680    (set (match_operand:SI 0 "register_operand" "=r")
1681         (plus:SI (match_dup 1) (match_dup 2)))]
1682   ""
1683   "addcc %1,%2,%0")
1684
1685 (define_insn "subdi3"
1686   [(set (match_operand:DI 0 "register_operand" "=r")
1687         (minus:DI (match_operand:DI 1 "register_operand" "r")
1688                   (match_operand:DI 2 "arith_double_operand" "rHI")))
1689    (clobber (reg:SI 0))]
1690   ""
1691   "*
1692 {
1693   rtx op2 = operands[2];
1694
1695   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1696      Give the assembler a chance to pick the move instruction. */
1697   if (GET_CODE (op2) == CONST_INT)
1698     {
1699       int sign = INTVAL (op2);
1700       if (sign < 0)
1701         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1702       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1703     }
1704   else if (GET_CODE (op2) == CONST_DOUBLE)
1705     {
1706       int sign = CONST_DOUBLE_HIGH (op2);
1707       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1708                              CONST_DOUBLE_LOW (operands[1]));
1709       if (sign < 0)
1710         return \"subcc %R1,%2,%R0\;subx %1,-1,%0\";
1711       return \"subcc %R1,%2,%R0\;subx %1,0,%0\";
1712     }
1713   return \"subcc %R1,%R2,%R0\;subx %1,%2,%0\";
1714 }"
1715   [(set_attr "length" "2")])
1716
1717 (define_insn "subsi3"
1718   [(set (match_operand:SI 0 "register_operand" "=r")
1719         (minus:SI (match_operand:SI 1 "register_operand" "r")
1720                   (match_operand:SI 2 "arith_operand" "rI")))]
1721   ""
1722   "sub %1,%2,%0")
1723
1724 (define_insn ""
1725   [(set (reg:CC_NOOV 0)
1726         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
1727                                    (match_operand:SI 1 "arith_operand" "rI"))
1728                          (const_int 0)))]
1729   ""
1730   "subcc %0,%1,%%g0"
1731   [(set_attr "type" "compare")])
1732
1733 (define_insn ""
1734   [(set (reg:CC_NOOV 0)
1735         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
1736                                    (match_operand:SI 2 "arith_operand" "rI"))
1737                          (const_int 0)))
1738    (set (match_operand:SI 0 "register_operand" "=r")
1739         (minus:SI (match_dup 1) (match_dup 2)))]
1740   ""
1741   "subcc %1,%2,%0")
1742
1743 (define_insn "mulsi3"
1744   [(set (match_operand:SI 0 "register_operand" "=r")
1745         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1746                  (match_operand:SI 2 "arith_operand" "rI")))]
1747   "TARGET_V8 || TARGET_SPARCLITE"
1748   "smul %1,%2,%0")
1749
1750 ;; It is not known whether this will match.
1751
1752 (define_insn ""
1753   [(set (match_operand:SI 0 "register_operand" "=r")
1754         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
1755                  (match_operand:SI 2 "arith_operand" "rI")))
1756    (set (reg:CC_NOOV 0)
1757         (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
1758                          (const_int 0)))]
1759   "TARGET_V8 || TARGET_SPARCLITE"
1760   "smulcc %1,%2,%0")
1761
1762 (define_expand "mulsidi3"
1763   [(set (match_operand:DI 0 "register_operand" "")
1764         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1765                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1766   "TARGET_V8 || TARGET_SPARCLITE"
1767   "
1768 {
1769   if (CONSTANT_P (operands[2]))
1770     {
1771       emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
1772       DONE;
1773     }
1774 }")
1775
1776 (define_insn ""
1777   [(set (match_operand:DI 0 "register_operand" "=r")
1778         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1779                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1780   "TARGET_V8 || TARGET_SPARCLITE"
1781   "smul %1,%2,%R0\;rd %%y,%0"
1782   [(set_attr "length" "2")])
1783
1784 ;; Extra pattern, because sign_extend of a constant isn't legal.
1785
1786 (define_insn "const_mulsidi3"
1787   [(set (match_operand:DI 0 "register_operand" "=r")
1788         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
1789                  (match_operand:SI 2 "small_int" "I")))]
1790   "TARGET_V8 || TARGET_SPARCLITE"
1791   "smul %1,%2,%R0\;rd %%y,%0"
1792   [(set_attr "length" "2")])
1793
1794 (define_expand "umulsidi3"
1795   [(set (match_operand:DI 0 "register_operand" "")
1796         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1797                  (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
1798   "TARGET_V8 || TARGET_SPARCLITE"
1799   "
1800 {
1801   if (CONSTANT_P (operands[2]))
1802     {
1803       emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
1804       DONE;
1805     }
1806 }")
1807
1808 (define_insn ""
1809   [(set (match_operand:DI 0 "register_operand" "=r")
1810         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1811                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
1812   "TARGET_V8 || TARGET_SPARCLITE"
1813   "umul %1,%2,%R0\;rd %%y,%0"
1814   [(set_attr "length" "2")])
1815
1816 ;; Extra pattern, because sign_extend of a constant isn't legal.
1817
1818 (define_insn "const_umulsidi3"
1819   [(set (match_operand:DI 0 "register_operand" "=r")
1820         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1821                  (match_operand:SI 2 "small_int" "I")))]
1822   "TARGET_V8 || TARGET_SPARCLITE"
1823   "umul %1,%2,%R0\;rd %%y,%0"
1824   [(set_attr "length" "2")])
1825
1826 ;; The architecture specifies that there must be 3 instructions between
1827 ;; a y register write and a use of it for correct results.
1828
1829 (define_insn "divsi3"
1830   [(set (match_operand:SI 0 "register_operand" "=r")
1831         (div:SI (match_operand:SI 1 "register_operand" "r")
1832                 (match_operand:SI 2 "arith_operand" "rI")))
1833    (clobber (match_scratch:SI 3 "=&r"))]
1834   "TARGET_V8"
1835   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0"
1836   [(set_attr "length" "6")])
1837
1838 ;; It is not known whether this will match.
1839
1840 (define_insn ""
1841   [(set (match_operand:SI 0 "register_operand" "=r")
1842         (div:SI (match_operand:SI 1 "register_operand" "r")
1843                 (match_operand:SI 2 "arith_operand" "rI")))
1844    (set (reg:CC 0)
1845         (compare:CC (div:SI (match_dup 1) (match_dup 2))
1846                     (const_int 0)))
1847    (clobber (match_scratch:SI 3 "=&r"))]
1848   "TARGET_V8"
1849   "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0"
1850   [(set_attr "length" "6")])
1851
1852 (define_insn "udivsi3"
1853   [(set (match_operand:SI 0 "register_operand" "=r")
1854         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1855                 (match_operand:SI 2 "arith_operand" "rI")))]
1856   "TARGET_V8"
1857   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0"
1858   [(set_attr "length" "5")])
1859
1860 ;; It is not known whether this will match.
1861
1862 (define_insn ""
1863   [(set (match_operand:SI 0 "register_operand" "=r")
1864         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1865                 (match_operand:SI 2 "arith_operand" "rI")))
1866    (set (reg:CC 0)
1867         (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
1868                     (const_int 0)))]
1869   "TARGET_V8"
1870   "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0"
1871   [(set_attr "length" "5")])
1872
1873 ;;- and instructions
1874 ;; We define DImode `and` so with DImode `not` we can get
1875 ;; DImode `andn`.  Other combinations are possible.
1876
1877 (define_expand "anddi3"
1878   [(set (match_operand:DI 0 "register_operand" "")
1879         (and:DI (match_operand:DI 1 "arith_double_operand" "")
1880                 (match_operand:DI 2 "arith_double_operand" "")))]
1881   ""
1882   "")
1883
1884 (define_insn ""
1885   [(set (match_operand:DI 0 "register_operand" "=r")
1886         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
1887                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1888   ""
1889   "*
1890 {
1891   rtx op2 = operands[2];
1892
1893   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1894      Give the assembler a chance to pick the move instruction. */
1895   if (GET_CODE (op2) == CONST_INT)
1896     {
1897       int sign = INTVAL (op2);
1898       if (sign < 0)
1899         return \"mov %1,%0\;and %R1,%2,%R0\";
1900       return \"mov 0,%0\;and %R1,%2,%R0\";
1901     }
1902   else if (GET_CODE (op2) == CONST_DOUBLE)
1903     {
1904       int sign = CONST_DOUBLE_HIGH (op2);
1905       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1906                              CONST_DOUBLE_LOW (operands[1]));
1907       if (sign < 0)
1908         return \"mov %1,%0\;and %R1,%2,%R0\";
1909       return \"mov 0,%0\;and %R1,%2,%R0\";
1910     }
1911   return \"and %1,%2,%0\;and %R1,%R2,%R0\";
1912 }"
1913   [(set_attr "length" "2")])
1914
1915 (define_insn "andsi3"
1916   [(set (match_operand:SI 0 "register_operand" "=r")
1917         (and:SI (match_operand:SI 1 "arith_operand" "%r")
1918                 (match_operand:SI 2 "arith_operand" "rI")))]
1919   ""
1920   "and %1,%2,%0")
1921
1922 (define_split
1923   [(set (match_operand:SI 0 "register_operand" "")
1924         (and:SI (match_operand:SI 1 "register_operand" "")
1925                 (match_operand:SI 2 "" "")))
1926    (clobber (match_operand:SI 3 "register_operand" ""))]
1927   "GET_CODE (operands[2]) == CONST_INT
1928    && !SMALL_INT (operands[2])
1929    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
1930   [(set (match_dup 3) (match_dup 4))
1931    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
1932   "
1933 {
1934   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
1935 }")
1936
1937 (define_insn ""
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
1940                 (match_operand:DI 2 "register_operand" "r")))]
1941   ""
1942   "andn %2,%1,%0\;andn %R2,%R1,%R0"
1943   [(set_attr "length" "2")])
1944
1945 (define_insn ""
1946   [(set (match_operand:SI 0 "register_operand" "=r")
1947         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1948                 (match_operand:SI 2 "register_operand" "r")))]
1949   ""
1950   "andn %2,%1,%0")
1951
1952 (define_expand "iordi3"
1953   [(set (match_operand:DI 0 "register_operand" "")
1954         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
1955                 (match_operand:DI 2 "arith_double_operand" "")))]
1956   ""
1957   "")
1958
1959 (define_insn ""
1960   [(set (match_operand:DI 0 "register_operand" "=r")
1961         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
1962                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
1963   ""
1964   "*
1965 {
1966   rtx op2 = operands[2];
1967
1968   /* If constant is positive, upper bits zeroed, otherwise unchanged.
1969      Give the assembler a chance to pick the move instruction. */
1970   if (GET_CODE (op2) == CONST_INT)
1971     {
1972       int sign = INTVAL (op2);
1973       if (sign < 0)
1974         return \"mov -1,%0\;or %R1,%2,%R0\";
1975       return \"mov %1,%0\;or %R1,%2,%R0\";
1976     }
1977   else if (GET_CODE (op2) == CONST_DOUBLE)
1978     {
1979       int sign = CONST_DOUBLE_HIGH (op2);
1980       operands[2] = gen_rtx (CONST_INT, VOIDmode,
1981                              CONST_DOUBLE_LOW (operands[1]));
1982       if (sign < 0)
1983         return \"mov -1,%0\;or %R1,%2,%R0\";
1984       return \"mov %1,%0\;or %R1,%2,%R0\";
1985     }
1986   return \"or %1,%2,%0\;or %R1,%R2,%R0\";
1987 }"
1988   [(set_attr "length" "2")])
1989
1990 (define_insn "iorsi3"
1991   [(set (match_operand:SI 0 "register_operand" "=r")
1992         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
1993                 (match_operand:SI 2 "arith_operand" "rI")))]
1994   ""
1995   "or %1,%2,%0")
1996
1997 (define_split
1998   [(set (match_operand:SI 0 "register_operand" "")
1999         (ior:SI (match_operand:SI 1 "register_operand" "")
2000                 (match_operand:SI 2 "" "")))
2001    (clobber (match_operand:SI 3 "register_operand" ""))]
2002   "GET_CODE (operands[2]) == CONST_INT
2003    && !SMALL_INT (operands[2])
2004    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2005   [(set (match_dup 3) (match_dup 4))
2006    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
2007   "
2008 {
2009   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2010 }")
2011
2012 (define_insn ""
2013   [(set (match_operand:DI 0 "register_operand" "=r")
2014         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
2015                 (match_operand:DI 2 "register_operand" "r")))]
2016   ""
2017   "orn %2,%1,%0\;orn %R2,%R1,%R0"
2018   [(set_attr "length" "2")])
2019
2020 (define_insn ""
2021   [(set (match_operand:SI 0 "register_operand" "=r")
2022         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
2023                 (match_operand:SI 2 "register_operand" "r")))]
2024   ""
2025   "orn %2,%1,%0")
2026
2027 (define_expand "xordi3"
2028   [(set (match_operand:DI 0 "register_operand" "")
2029         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
2030                 (match_operand:DI 2 "arith_double_operand" "")))]
2031   ""
2032   "")
2033
2034 (define_insn ""
2035   [(set (match_operand:DI 0 "register_operand" "=r")
2036         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
2037                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
2038   ""
2039   "*
2040 {
2041   rtx op2 = operands[2];
2042
2043   /* If constant is positive, upper bits zeroed, otherwise unchanged.
2044      Give the assembler a chance to pick the move instruction. */
2045   if (GET_CODE (op2) == CONST_INT)
2046     {
2047       int sign = INTVAL (op2);
2048       if (sign < 0)
2049         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2050       return \"mov %1,%0\;xor %R1,%2,%R0\";
2051     }
2052   else if (GET_CODE (op2) == CONST_DOUBLE)
2053     {
2054       int sign = CONST_DOUBLE_HIGH (op2);
2055       operands[2] = gen_rtx (CONST_INT, VOIDmode,
2056                              CONST_DOUBLE_LOW (operands[1]));
2057       if (sign < 0)
2058         return \"xor %1,-1,%0\;xor %R1,%2,%R0\";
2059       return \"mov %1,%0\;xor %R1,%2,%R0\";
2060     }
2061   return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
2062 }"
2063   [(set_attr "length" "2")])
2064
2065 (define_insn "xorsi3"
2066   [(set (match_operand:SI 0 "register_operand" "=r")
2067         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
2068                 (match_operand:SI 2 "arith_operand" "rI")))]
2069   ""
2070   "xor %r1,%2,%0")
2071
2072 (define_split
2073   [(set (match_operand:SI 0 "register_operand" "")
2074         (xor:SI (match_operand:SI 1 "register_operand" "")
2075                 (match_operand:SI 2 "" "")))
2076    (clobber (match_operand:SI 3 "register_operand" ""))]
2077   "GET_CODE (operands[2]) == CONST_INT
2078    && !SMALL_INT (operands[2])
2079    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2080   [(set (match_dup 3) (match_dup 4))
2081    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
2082   "
2083 {
2084   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2085 }")
2086
2087 (define_split
2088   [(set (match_operand:SI 0 "register_operand" "")
2089         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
2090                         (match_operand:SI 2 "" ""))))
2091    (clobber (match_operand:SI 3 "register_operand" ""))]
2092   "GET_CODE (operands[2]) == CONST_INT
2093    && !SMALL_INT (operands[2])
2094    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
2095   [(set (match_dup 3) (match_dup 4))
2096    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
2097   "
2098 {
2099   operands[4] = gen_rtx (CONST_INT, VOIDmode, ~INTVAL (operands[2]));
2100 }")
2101
2102 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2103 ;; Combine now canonicalizes to the rightmost expression.
2104 (define_insn ""
2105   [(set (match_operand:DI 0 "register_operand" "=r")
2106         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
2107                         (match_operand:DI 2 "register_operand" "r"))))]
2108   ""
2109   "xnor %1,%2,%0\;xnor %R1,%R2,%R0"
2110   [(set_attr "length" "2")])
2111
2112 (define_insn ""
2113   [(set (match_operand:SI 0 "register_operand" "=r")
2114         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
2115                         (match_operand:SI 2 "arith_operand" "rI"))))]
2116   ""
2117   "xnor %r1,%2,%0")
2118
2119 ;; These correspond to the above in the case where we also (or only)
2120 ;; want to set the condition code.  
2121
2122 (define_insn ""
2123   [(set (reg:CC 0)
2124         (compare:CC
2125          (match_operator:SI 2 "cc_arithop"
2126                             [(match_operand:SI 0 "arith_operand" "%r")
2127                              (match_operand:SI 1 "arith_operand" "rI")])
2128          (const_int 0)))]
2129   ""
2130   "%A2cc %0,%1,%%g0"
2131   [(set_attr "type" "compare")])
2132
2133 (define_insn ""
2134   [(set (reg:CC 0)
2135         (compare:CC
2136          (match_operator:SI 3 "cc_arithop"
2137                             [(match_operand:SI 1 "arith_operand" "%r")
2138                              (match_operand:SI 2 "arith_operand" "rI")])
2139          (const_int 0)))
2140    (set (match_operand:SI 0 "register_operand" "=r")
2141         (match_dup 3))]
2142   ""
2143   "%A3cc %1,%2,%0")
2144
2145 (define_insn ""
2146   [(set (reg:CC 0)
2147         (compare:CC
2148          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
2149                          (match_operand:SI 1 "arith_operand" "rI")))
2150          (const_int 0)))]
2151   ""
2152   "xnorcc %r0,%1,%%g0"
2153   [(set_attr "type" "compare")])
2154
2155 (define_insn ""
2156   [(set (reg:CC 0)
2157         (compare:CC
2158          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
2159                          (match_operand:SI 2 "arith_operand" "rI")))
2160          (const_int 0)))
2161    (set (match_operand:SI 0 "register_operand" "=r")
2162         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
2163   ""
2164   "xnorcc %r1,%2,%0")
2165
2166 (define_insn ""
2167   [(set (reg:CC 0)
2168         (compare:CC
2169          (match_operator:SI 2 "cc_arithopn"
2170                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
2171                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
2172          (const_int 0)))]
2173   ""
2174   "%B2cc %r1,%0,%%g0"
2175   [(set_attr "type" "compare")])
2176
2177 (define_insn ""
2178   [(set (reg:CC 0)
2179         (compare:CC
2180          (match_operator:SI 3 "cc_arithopn"
2181                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
2182                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
2183          (const_int 0)))
2184    (set (match_operand:SI 0 "register_operand" "=r")
2185         (match_dup 3))]
2186   ""
2187   "%B3cc %r2,%1,%0")
2188
2189 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2190 ;; does not know how to make it work for constants.
2191
2192 (define_insn "negdi2"
2193   [(set (match_operand:DI 0 "register_operand" "=r")
2194         (neg:DI (match_operand:DI 1 "register_operand" "r")))
2195    (clobber (reg:SI 0))]
2196   ""
2197   "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0"
2198   [(set_attr "type" "unary")
2199    (set_attr "length" "2")])
2200
2201 (define_insn "negsi2"
2202   [(set (match_operand:SI 0 "general_operand" "=r")
2203         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
2204   ""
2205   "sub %%g0,%1,%0"
2206   [(set_attr "type" "unary")])
2207
2208 (define_insn ""
2209   [(set (reg:CC_NOOV 0)
2210         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
2211                          (const_int 0)))]
2212   ""
2213   "subcc %%g0,%0,%%g0"
2214   [(set_attr "type" "compare")])
2215
2216 (define_insn ""
2217   [(set (reg:CC_NOOV 0)
2218         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
2219                          (const_int 0)))
2220    (set (match_operand:SI 0 "register_operand" "=r")
2221         (neg:SI (match_dup 1)))]
2222   ""
2223   "subcc %%g0,%1,%0"
2224   [(set_attr "type" "unary")])
2225
2226 ;; We cannot use the "not" pseudo insn because the Sun assembler
2227 ;; does not know how to make it work for constants.
2228 (define_expand "one_cmpldi2"
2229   [(set (match_operand:DI 0 "register_operand" "=r")
2230         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2231   ""
2232   "")
2233
2234 (define_insn ""
2235   [(set (match_operand:DI 0 "register_operand" "=r")
2236         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
2237   ""
2238   "*
2239 {
2240   rtx op1 = operands[1];
2241
2242   if (GET_CODE (op1) == CONST_INT)
2243     {
2244       int sign = INTVAL (op1);
2245       if (sign < 0)
2246         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2247       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2248     }
2249   else if (GET_CODE (op1) == CONST_DOUBLE)
2250     {
2251       int sign = CONST_DOUBLE_HIGH (op1);
2252       operands[1] = gen_rtx (CONST_INT, VOIDmode,
2253                              CONST_DOUBLE_LOW (operands[1]));
2254       if (sign < 0)
2255         return \"xnor %%g0,%1,%R0\;xnor %%g0,-1,%0\";
2256       return \"xnor %%g0,%1,%R0\;xnor %%g0,0,%0\";
2257     }
2258   return \"xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0\";
2259 }"
2260   [(set_attr "type" "unary")
2261    (set_attr "length" "2")])
2262
2263 (define_insn "one_cmplsi2"
2264   [(set (match_operand:SI 0 "register_operand" "=r")
2265         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
2266   ""
2267   "xnor %%g0,%1,%0"
2268   [(set_attr "type" "unary")])
2269
2270 (define_insn ""
2271   [(set (reg:CC 0)
2272         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
2273                     (const_int 0)))]
2274   ""
2275   "xnorcc %%g0,%0,%%g0"
2276   [(set_attr "type" "compare")])
2277
2278 (define_insn ""
2279   [(set (reg:CC 0)
2280         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
2281                     (const_int 0)))
2282    (set (match_operand:SI 0 "register_operand" "=r")
2283         (not:SI (match_dup 1)))]
2284   ""
2285   "xnorcc %%g0,%1,%0"
2286   [(set_attr "type" "unary")])
2287 \f
2288 ;; Floating point arithmetic instructions.
2289
2290 (define_insn "addtf3"
2291   [(set (match_operand:TF 0 "register_operand" "=f")
2292         (plus:TF (match_operand:TF 1 "register_operand" "f")
2293                  (match_operand:TF 2 "register_operand" "f")))]
2294   "TARGET_FPU"
2295   "faddq %1,%2,%0"
2296   [(set_attr "type" "fp")])
2297
2298 (define_insn "adddf3"
2299   [(set (match_operand:DF 0 "register_operand" "=f")
2300         (plus:DF (match_operand:DF 1 "register_operand" "f")
2301                  (match_operand:DF 2 "register_operand" "f")))]
2302   "TARGET_FPU"
2303   "faddd %1,%2,%0"
2304   [(set_attr "type" "fp")])
2305
2306 (define_insn "addsf3"
2307   [(set (match_operand:SF 0 "register_operand" "=f")
2308         (plus:SF (match_operand:SF 1 "register_operand" "f")
2309                  (match_operand:SF 2 "register_operand" "f")))]
2310   "TARGET_FPU"
2311   "fadds %1,%2,%0"
2312   [(set_attr "type" "fp")])
2313
2314 (define_insn "subtf3"
2315   [(set (match_operand:TF 0 "register_operand" "=f")
2316         (minus:TF (match_operand:TF 1 "register_operand" "f")
2317                   (match_operand:TF 2 "register_operand" "f")))]
2318   "TARGET_FPU"
2319   "fsubq %1,%2,%0"
2320   [(set_attr "type" "fp")])
2321
2322 (define_insn "subdf3"
2323   [(set (match_operand:DF 0 "register_operand" "=f")
2324         (minus:DF (match_operand:DF 1 "register_operand" "f")
2325                   (match_operand:DF 2 "register_operand" "f")))]
2326   "TARGET_FPU"
2327   "fsubd %1,%2,%0"
2328   [(set_attr "type" "fp")])
2329
2330 (define_insn "subsf3"
2331   [(set (match_operand:SF 0 "register_operand" "=f")
2332         (minus:SF (match_operand:SF 1 "register_operand" "f")
2333                   (match_operand:SF 2 "register_operand" "f")))]
2334   "TARGET_FPU"
2335   "fsubs %1,%2,%0"
2336   [(set_attr "type" "fp")])
2337
2338 (define_insn "multf3"
2339   [(set (match_operand:TF 0 "register_operand" "=f")
2340         (mult:TF (match_operand:TF 1 "register_operand" "f")
2341                  (match_operand:TF 2 "register_operand" "f")))]
2342   "TARGET_FPU"
2343   "fmulq %1,%2,%0"
2344   [(set_attr "type" "fpmul")])
2345
2346 (define_insn "muldf3"
2347   [(set (match_operand:DF 0 "register_operand" "=f")
2348         (mult:DF (match_operand:DF 1 "register_operand" "f")
2349                  (match_operand:DF 2 "register_operand" "f")))]
2350   "TARGET_FPU"
2351   "fmuld %1,%2,%0"
2352   [(set_attr "type" "fpmul")])
2353
2354 (define_insn "mulsf3"
2355   [(set (match_operand:SF 0 "register_operand" "=f")
2356         (mult:SF (match_operand:SF 1 "register_operand" "f")
2357                  (match_operand:SF 2 "register_operand" "f")))]
2358   "TARGET_FPU"
2359   "fmuls %1,%2,%0"
2360   [(set_attr "type" "fpmul")])
2361
2362 (define_insn ""
2363   [(set (match_operand:DF 0 "register_operand" "=f")
2364         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
2365                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
2366   "TARGET_V8 && TARGET_FPU"
2367   "fsmuld %1,%2,%0"
2368   [(set_attr "type" "fpmul")])
2369
2370 (define_insn ""
2371   [(set (match_operand:TF 0 "register_operand" "=f")
2372         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "f"))
2373                  (float_extend:TF (match_operand:DF 2 "register_operand" "f"))))]
2374   "TARGET_V8 && TARGET_FPU"
2375   "fdmulq %1,%2,%0"
2376   [(set_attr "type" "fpmul")])
2377
2378 (define_insn "divtf3"
2379   [(set (match_operand:TF 0 "register_operand" "=f")
2380         (div:TF (match_operand:TF 1 "register_operand" "f")
2381                 (match_operand:TF 2 "register_operand" "f")))]
2382   "TARGET_FPU"
2383   "fdivq %1,%2,%0"
2384   [(set_attr "type" "fpdiv")])
2385
2386 (define_insn "divdf3"
2387   [(set (match_operand:DF 0 "register_operand" "=f")
2388         (div:DF (match_operand:DF 1 "register_operand" "f")
2389                 (match_operand:DF 2 "register_operand" "f")))]
2390   "TARGET_FPU"
2391   "fdivd %1,%2,%0"
2392   [(set_attr "type" "fpdiv")])
2393
2394 (define_insn "divsf3"
2395   [(set (match_operand:SF 0 "register_operand" "=f")
2396         (div:SF (match_operand:SF 1 "register_operand" "f")
2397                 (match_operand:SF 2 "register_operand" "f")))]
2398   "TARGET_FPU"
2399   "fdivs %1,%2,%0"
2400   [(set_attr "type" "fpdiv")])
2401
2402 (define_insn "negtf2"
2403   [(set (match_operand:TF 0 "register_operand" "=f,f")
2404         (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
2405   "TARGET_FPU"
2406   "@
2407    fnegs %0,%0
2408    fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2409   [(set_attr "type" "fp")
2410    (set_attr "length" "1,4")])
2411
2412 (define_insn "negdf2"
2413   [(set (match_operand:DF 0 "register_operand" "=f,f")
2414         (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
2415   "TARGET_FPU"
2416   "@
2417    fnegs %0,%0
2418    fnegs %1,%0\;fmovs %R1,%R0"
2419   [(set_attr "type" "fp")
2420    (set_attr "length" "1,2")])
2421
2422 (define_insn "negsf2"
2423   [(set (match_operand:SF 0 "register_operand" "=f")
2424         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
2425   "TARGET_FPU"
2426   "fnegs %1,%0"
2427   [(set_attr "type" "fp")])
2428
2429 (define_insn "abstf2"
2430   [(set (match_operand:TF 0 "register_operand" "=f,f")
2431         (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
2432   "TARGET_FPU"
2433   "@
2434    fabss %0,%0
2435    fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2436   [(set_attr "type" "fp")
2437    (set_attr "length" "1,4")])
2438
2439 (define_insn "absdf2"
2440   [(set (match_operand:DF 0 "register_operand" "=f,f")
2441         (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
2442   "TARGET_FPU"
2443   "@
2444    fabss %0,%0
2445    fabss %1,%0\;fmovs %R1,%R0"
2446   [(set_attr "type" "fp")
2447    (set_attr "length" "1,2")])
2448
2449 (define_insn "abssf2"
2450   [(set (match_operand:SF 0 "register_operand" "=f")
2451         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
2452   "TARGET_FPU"
2453   "fabss %1,%0"
2454   [(set_attr "type" "fp")])
2455
2456 (define_insn "sqrttf2"
2457   [(set (match_operand:TF 0 "register_operand" "=f")
2458         (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
2459   "TARGET_FPU"
2460   "fsqrtq %1,%0"
2461   [(set_attr "type" "fpsqrt")])
2462
2463 (define_insn "sqrtdf2"
2464   [(set (match_operand:DF 0 "register_operand" "=f")
2465         (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
2466   "TARGET_FPU"
2467   "fsqrtd %1,%0"
2468   [(set_attr "type" "fpsqrt")])
2469
2470 (define_insn "sqrtsf2"
2471   [(set (match_operand:SF 0 "register_operand" "=f")
2472         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
2473   "TARGET_FPU"
2474   "fsqrts %1,%0"
2475   [(set_attr "type" "fpsqrt")])
2476 \f
2477 ;;- arithmetic shift instructions
2478
2479 ;; We can trivially handle shifting the constant 1 by 64 bits.
2480 ;; For other shifts we use the library routine.
2481 ;; ??? Questionable, we can do better than this can't we?
2482 (define_expand "ashldi3"
2483   [(parallel [(set (match_operand:DI 0 "register_operand" "")
2484                    (ashift:DI (match_operand:DI 1 "const_double_operand" "")
2485                               (match_operand:SI 2 "register_operand" "")))
2486               (clobber (reg:SI 0))])]
2487   ""
2488   "
2489 {
2490   if (GET_CODE (operands[1]) == CONST_DOUBLE
2491       && CONST_DOUBLE_HIGH (operands[1]) == 0
2492       && CONST_DOUBLE_LOW (operands[1]) == 1)
2493     operands[1] = const1_rtx;
2494   else if (operands[1] != const1_rtx)
2495     FAIL;
2496 }")
2497
2498 ;; ??? Questionable, we can do better than this can't we?
2499 (define_insn ""
2500   [(set (match_operand:DI 0 "register_operand" "=&r")
2501         (ashift:DI (const_int 1)
2502                    (match_operand:SI 1 "register_operand" "r")))
2503    (clobber (reg:SI 0))]
2504   ""
2505   "subcc %1,32,%%g0\;addx %%g0,0,%R0\;xor %R0,1,%0\;sll %R0,%1,%R0\;sll %0,%1,%0"
2506   [(set_attr "type" "multi")
2507    (set_attr "length" "5")])
2508
2509 (define_insn "ashlsi3"
2510   [(set (match_operand:SI 0 "register_operand" "=r")
2511         (ashift:SI (match_operand:SI 1 "register_operand" "r")
2512                    (match_operand:SI 2 "arith_operand" "rI")))]
2513   ""
2514   "sll %1,%2,%0")
2515
2516 (define_insn "ashrsi3"
2517   [(set (match_operand:SI 0 "register_operand" "=r")
2518         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
2519                      (match_operand:SI 2 "arith_operand" "rI")))]
2520   ""
2521   "sra %1,%2,%0")
2522
2523 (define_insn "lshrsi3"
2524   [(set (match_operand:SI 0 "register_operand" "=r")
2525         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2526                      (match_operand:SI 2 "arith_operand" "rI")))]
2527   ""
2528   "srl %1,%2,%0")
2529 \f
2530 ;; Unconditional and other jump instructions
2531 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
2532 ;; following insn is never executed.  This saves us a nop.  Dbx does not
2533 ;; handle such branches though, so we only use them when optimizing.
2534 (define_insn "jump"
2535   [(set (pc) (label_ref (match_operand 0 "" "")))]
2536   ""
2537   "b%* %l0%("
2538   [(set_attr "type" "uncond_branch")])
2539
2540 (define_expand "tablejump"
2541   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2542               (use (label_ref (match_operand 1 "" "")))])]
2543   ""
2544   "
2545 {
2546   /* We need to use the PC value in %o7 that was set up when the address
2547      of the label was loaded into a register, so we need different RTL.  */
2548   if (flag_pic)
2549     {
2550       emit_insn (gen_pic_tablejump (operands[0], operands[1]));
2551       DONE;
2552     }
2553 }")
2554
2555 (define_insn "pic_tablejump"
2556   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2557    (use (label_ref (match_operand 1 "" "")))
2558    (use (reg:SI 15))]
2559   ""
2560   "jmp %%o7+%0%#"
2561   [(set_attr "type" "uncond_branch")])
2562
2563 (define_insn ""
2564   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
2565    (use (label_ref (match_operand 1 "" "")))]
2566   ""
2567   "jmp %a0%#"
2568   [(set_attr "type" "uncond_branch")])
2569
2570 (define_insn ""
2571   [(set (pc) (label_ref (match_operand 0 "" "")))
2572    (set (reg:SI 15) (label_ref (match_dup 0)))]
2573   ""
2574   "call %l0%#"
2575   [(set_attr "type" "uncond_branch")])
2576
2577 ;; This pattern recognizes the "instruction" that appears in 
2578 ;; a function call that wants a structure value, 
2579 ;; to inform the called function if compiled with Sun CC.
2580 ;(define_insn ""
2581 ;  [(match_operand:SI 0 "immediate_operand" "")]
2582 ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
2583 ;  "unimp %0"
2584 ;  [(set_attr "type" "marker")])
2585
2586 ;;- jump to subroutine
2587 (define_expand "call"
2588   ;; Note that this expression is not used for generating RTL.
2589   ;; All the RTL is generated explicitly below.
2590   [(call (match_operand:SI 0 "call_operand" "")
2591          (match_operand 3 "" "i"))]
2592   ;; operands[2] is next_arg_register
2593   ;; operands[3] is struct_value_size_rtx.
2594   ""
2595   "
2596 {
2597   rtx fn_rtx, nregs_rtx;
2598
2599   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
2600     {
2601       /* This is really a PIC sequence.  We want to represent
2602          it as a funny jump so it's delay slots can be filled. 
2603
2604          ??? But if this really *is* a CALL, will not it clobber the
2605          call-clobbered registers?  We lose this if it is a JUMP_INSN.
2606          Why cannot we have delay slots filled if it were a CALL?  */
2607
2608       if (INTVAL (operands[3]) > 0)
2609         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2610                                  gen_rtx (SET, VOIDmode, pc_rtx,
2611                                           XEXP (operands[0], 0)),
2612                                  operands[3],
2613                                  gen_rtx (CLOBBER, VOIDmode,
2614                                           gen_rtx (REG, SImode, 15)))));
2615       else
2616         emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2617                                  gen_rtx (SET, VOIDmode, pc_rtx,
2618                                           XEXP (operands[0], 0)),
2619                                  gen_rtx (CLOBBER, VOIDmode,
2620                                           gen_rtx (REG, SImode, 15)))));
2621       goto finish_call;
2622     }
2623
2624   fn_rtx = operands[0];
2625
2626   /* Count the number of parameter registers being used by this call.
2627      if that argument is NULL, it means we are using them all, which
2628      means 6 on the sparc.  */
2629 #if 0
2630   if (operands[2])
2631     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[2]) - 8);
2632   else
2633     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2634 #else
2635   nregs_rtx = const0_rtx;
2636 #endif
2637
2638   if (INTVAL (operands[3]) > 0)
2639     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
2640                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2641                              operands[3],
2642                              gen_rtx (CLOBBER, VOIDmode,
2643                                                gen_rtx (REG, SImode, 15)))));
2644   else
2645     emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
2646                              gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
2647                              gen_rtx (CLOBBER, VOIDmode,
2648                                                gen_rtx (REG, SImode, 15)))));
2649
2650  finish_call:
2651 #if 0
2652   /* If this call wants a structure value,
2653      emit an unimp insn to let the called function know about this.  */
2654   if (INTVAL (operands[3]) > 0)
2655     {
2656       rtx insn = emit_insn (operands[3]);
2657       SCHED_GROUP_P (insn) = 1;
2658     }
2659 #endif
2660
2661   DONE;
2662 }")
2663
2664 (define_insn ""
2665   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2666          (match_operand 1 "" ""))
2667    (clobber (reg:SI 15))]
2668   ;;- Do not use operand 1 for most machines.
2669   ""
2670   "*
2671 {
2672   return \"call %a0,%1%#\";
2673 }"
2674   [(set_attr "type" "call")])
2675
2676 ;; This is a call that wants a structure value.
2677 (define_insn ""
2678   [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
2679          (match_operand 1 "" ""))
2680    (match_operand 2 "immediate_operand" "")
2681    (clobber (reg:SI 15))]
2682   ;;- Do not use operand 1 for most machines.
2683   "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
2684   "*
2685 {
2686   return \"call %a0,%1\;nop\;unimp %2\";
2687 }"
2688   [(set_attr "type" "call_no_delay_slot")])
2689
2690 (define_expand "call_value"
2691   [(set (match_operand 0 "register_operand" "=rf")
2692         (call (match_operand:SI 1 "" "")
2693               (match_operand 4 "" "")))]
2694   ;; operand 3 is next_arg_register
2695   ""
2696   "
2697 {
2698   rtx fn_rtx, nregs_rtx;
2699   rtvec vec;
2700
2701   fn_rtx = operands[1];
2702
2703 #if 0
2704   if (operands[3])
2705     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
2706   else
2707     nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
2708 #else
2709   nregs_rtx = const0_rtx;
2710 #endif
2711
2712   vec = gen_rtvec (2,
2713                    gen_rtx (SET, VOIDmode, operands[0],
2714                             gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
2715                    gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 15)));
2716
2717   emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
2718
2719   DONE;
2720 }")
2721
2722 (define_insn ""
2723   [(set (match_operand 0 "" "=rf")
2724         (call (mem:SI (match_operand:SI 1 "call_operand_address" "rS"))
2725               (match_operand 2 "" "")))
2726    (clobber (reg:SI 15))]
2727   ;;- Do not use operand 2 for most machines.
2728   ""
2729   "*
2730 {
2731   return \"call %a1,%2%#\";
2732 }"
2733   [(set_attr "type" "call")])
2734 \f
2735 (define_insn "return"
2736   [(return)]
2737   "! TARGET_EPILOGUE"
2738   "* return output_return (operands);"
2739   [(set_attr "type" "multi")])
2740
2741 (define_insn "nop"
2742   [(const_int 0)]
2743   ""
2744   "nop")
2745
2746 (define_insn "indirect_jump"
2747   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
2748   ""
2749  "jmp %a0%#"
2750  [(set_attr "type" "uncond_branch")])
2751  
2752 (define_expand "nonlocal_goto"
2753   [(match_operand:SI 0 "general_operand" "")
2754    (match_operand:SI 1 "general_operand" "")
2755    (match_operand:SI 2 "general_operand" "")
2756    (match_operand:SI 3 "" "")]
2757   ""
2758   "
2759 {
2760   /* Trap instruction to flush all the registers window.  */
2761   emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2762                       gen_rtvec (1, const0_rtx), 0));
2763   /* Load the fp value for the containing fn into %fp.
2764      This is needed because operands[2] refers to %fp.
2765      Virtual register instantiation fails if the virtual %fp isn't set from a
2766      register.  Thus we must copy operands[0] into a register if it isn't
2767      already one.  */
2768   if (GET_CODE (operands[0]) != REG)
2769     operands[0] = force_reg (SImode, operands[0]);
2770   emit_move_insn (virtual_stack_vars_rtx, operands[0]);
2771   /* Find the containing function's current nonlocal goto handler,
2772      which will do any cleanups and then jump to the label.  */
2773   emit_move_insn (gen_rtx (REG, SImode, 8), operands[1]);
2774   /* Restore %fp from stack pointer value for containing function.
2775      The restore insn that follows will move this to %sp,
2776      and reload the appropriate value into %fp.  */
2777   emit_move_insn (frame_pointer_rtx, operands[2]);
2778   /* Put in the static chain register the nonlocal label address.  */
2779   emit_move_insn (static_chain_rtx, operands[3]);
2780   /* USE of frame_pointer_rtx added for consistency; not clear if
2781      really needed.  */
2782   emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
2783   emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
2784   emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
2785   emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 8)));
2786   /* Return, restoring reg window and jumping to goto handler.  */
2787   emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode,
2788                       gen_rtvec (1, const0_rtx), 1));
2789   DONE;
2790 }")
2791
2792 ;; Special trap insn to flush register windows.
2793 (define_insn ""
2794   [(unspec_volatile [(const_int 0)] 0)]
2795   ""
2796   "ta 3"
2797   [(set_attr "type" "misc")])
2798
2799 (define_insn ""
2800   [(unspec_volatile [(const_int 0)] 1)]
2801   ""
2802   "jmp %%o0+0\;restore"
2803   [(set_attr "type" "misc")
2804    (set_attr "length" "2")])
2805 \f
2806 ;; find first set.
2807
2808 ;; The scan instruction searches from the most significant bit while ffs
2809 ;; searches from the least significant bit.  The bit index and treatment of
2810 ;; zero also differ.  It takes at least 7 instructions to get the proper
2811 ;; result.  Here is an obvious 8 instruction seequence.
2812
2813 (define_insn "ffssi2"
2814   [(set (match_operand:SI 0 "register_operand" "=&r")
2815         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
2816    (clobber (match_scratch:SI 2 "=&r"))]
2817   "TARGET_SPARCLITE"
2818   "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"
2819   [(set_attr "type" "multi")
2820    (set_attr "length" "8")])
2821 \f
2822 ;; Split up troublesome insns for better scheduling.  */
2823
2824 ;; The following patterns are straightforward.  They can be applied
2825 ;; either before or after register allocation.
2826
2827 (define_split
2828   [(set (match_operator 0 "memop" [(match_operand:SI 1 "symbolic_operand" "")])
2829         (match_operand 2 "reg_or_0_operand" ""))
2830    (clobber (match_operand:SI 3 "register_operand" ""))]
2831   "! flag_pic"
2832   [(set (match_dup 3) (high:SI (match_dup 1)))
2833    (set (match_op_dup 0 [(lo_sum:SI (match_dup 3) (match_dup 1))])
2834         (match_dup 2))]
2835   "")
2836
2837 (define_split
2838   [(set (match_operator 0 "memop"
2839                         [(match_operand:SI 1 "immediate_operand" "")])
2840         (match_operand 2 "general_operand" ""))
2841    (clobber (match_operand:SI 3 "register_operand" ""))]
2842   "flag_pic"
2843   [(set (match_op_dup 0 [(match_dup 1)])
2844         (match_dup 2))]
2845   "
2846 {
2847   operands[1] = legitimize_pic_address (operands[1], GET_MODE (operands[0]),
2848                                         operands[3], 0);
2849 }")
2850
2851 (define_split
2852   [(set (match_operand 0 "register_operand" "")
2853         (match_operator 1 "memop"
2854                         [(match_operand:SI 2 "immediate_operand" "")]))]
2855   "flag_pic"
2856   [(set (match_dup 0)
2857         (match_op_dup 1 [(match_dup 2)]))]
2858   "
2859 {
2860   operands[2] = legitimize_pic_address (operands[2], GET_MODE (operands[1]),
2861                                         operands[0], 0);
2862 }")
2863
2864 ;; Sign- and Zero-extend operations can have symbolic memory operands.
2865
2866 (define_split
2867   [(set (match_operand 0 "register_operand" "")
2868         (match_operator 1 "extend_op"
2869                         [(match_operator 2 "memop"
2870                                          [(match_operand:SI 3 "immediate_operand" "")])]))]
2871   "flag_pic"
2872   [(set (match_dup 0)
2873         (match_op_dup 1 [(match_op_dup 2 [(match_dup 3)])]))]
2874   "
2875 {
2876   operands[3] = legitimize_pic_address (operands[3], GET_MODE (operands[2]),
2877                                         operands[0], 0);
2878 }")
2879
2880 (define_split
2881   [(set (match_operand:SI 0 "register_operand" "")
2882         (match_operand:SI 1 "immediate_operand" ""))]
2883   "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2884                   || GET_CODE (operands[1]) == CONST
2885                   || GET_CODE (operands[1]) == LABEL_REF)"
2886   [(set (match_dup 0) (high:SI (match_dup 1)))
2887    (set (match_dup 0)
2888         (lo_sum:SI (match_dup 0) (match_dup 1)))]
2889   "")
2890
2891 ;; LABEL_REFs are not modified by `legitimize_pic_address`
2892 ;; so do not recurse infinitely in the PIC case.
2893 (define_split
2894   [(set (match_operand:SI 0 "register_operand" "")
2895         (match_operand:SI 1 "immediate_operand" ""))]
2896   "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
2897                 || GET_CODE (operands[1]) == CONST)"
2898   [(set (match_dup 0) (match_dup 1))]
2899   "
2900 {
2901   operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0], 0);
2902 }")
2903 \f
2904 ;; These split sne/seq insns.  The forms of the resulting insns are 
2905 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
2906 ;; Nothing will look at these in detail after splitting has occurred.
2907
2908 (define_split
2909   [(set (match_operand:SI 0 "register_operand" "")
2910         (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2911    (clobber (reg:CC 0))]
2912   ""
2913   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2914                                          (const_int 0)))
2915    (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))]
2916   "")
2917
2918 (define_split
2919   [(set (match_operand:SI 0 "register_operand" "")
2920         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2921                        (const_int 0))))
2922    (clobber (reg:CC 0))]
2923   ""
2924   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2925                                          (const_int 0)))
2926    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))]
2927   "")
2928
2929 (define_split
2930   [(set (match_operand:SI 0 "register_operand" "")
2931         (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))
2932    (clobber (reg:CC 0))]
2933   ""
2934   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2935                                          (const_int 0)))
2936    (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))]
2937   "")
2938
2939 (define_split
2940   [(set (match_operand:SI 0 "register_operand" "")
2941         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2942                        (const_int 0))))
2943    (clobber (reg:CC 0))]
2944   ""
2945   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2946                                          (const_int 0)))
2947    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))]
2948   "")
2949
2950 (define_split
2951   [(set (match_operand:SI 0 "register_operand" "")
2952         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
2953                         (const_int 0))
2954                  (match_operand:SI 2 "register_operand" "")))
2955    (clobber (reg:CC 0))]
2956   ""
2957   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2958                                          (const_int 0)))
2959    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0))
2960                                (match_dup 2)))]
2961   "")
2962
2963 (define_split
2964   [(set (match_operand:SI 0 "register_operand" "")
2965         (minus:SI (match_operand:SI 2 "register_operand" "")
2966                   (ne:SI (match_operand:SI 1 "register_operand" "")
2967                          (const_int 0))))
2968    (clobber (reg:CC 0))]
2969   ""
2970   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2971                                          (const_int 0)))
2972    (set (match_dup 0) (minus:SI (match_dup 2)
2973                                 (ltu:SI (reg:CC 0) (const_int 0))))]
2974   "")
2975
2976 (define_split
2977   [(set (match_operand:SI 0 "register_operand" "")
2978         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
2979                         (const_int 0))
2980                  (match_operand:SI 2 "register_operand" "")))
2981    (clobber (reg:CC 0))]
2982   ""
2983   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2984                                          (const_int 0)))
2985    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0))
2986                                (match_dup 2)))]
2987   "")
2988
2989 (define_split
2990   [(set (match_operand:SI 0 "register_operand" "")
2991         (minus:SI (match_operand:SI 2 "register_operand" "")
2992                   (eq:SI (match_operand:SI 1 "register_operand" "")
2993                          (const_int 0))))
2994    (clobber (reg:CC 0))]
2995   ""
2996   [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1))
2997                                          (const_int 0)))
2998    (set (match_dup 0) (minus:SI (match_dup 2)
2999                                 (geu:SI (reg:CC 0) (const_int 0))))]
3000   "")
3001 \f
3002 ;; Peepholes go at the end.
3003
3004 ;; Optimize consecutive loads or stores into ldd and std when possible.
3005 ;; The conditions in which we do this are very restricted and are 
3006 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
3007
3008 (define_peephole
3009   [(set (match_operand:SI 0 "register_operand" "=rf")
3010         (match_operand:SI 1 "memory_operand" ""))
3011    (set (match_operand:SI 2 "register_operand" "=rf")
3012         (match_operand:SI 3 "memory_operand" ""))]
3013   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3014    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3015    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
3016   "ldd %1,%0")
3017
3018 (define_peephole
3019   [(set (match_operand:SI 0 "memory_operand" "")
3020         (match_operand:SI 1 "register_operand" "rf"))
3021    (set (match_operand:SI 2 "memory_operand" "")
3022         (match_operand:SI 3 "register_operand" "rf"))]
3023   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3024    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3025    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3026   "std %1,%0")
3027  
3028 (define_peephole
3029   [(set (match_operand:SF 0 "register_operand" "=fr")
3030         (match_operand:SF 1 "memory_operand" ""))
3031    (set (match_operand:SF 2 "register_operand" "=fr")
3032         (match_operand:SF 3 "memory_operand" ""))]
3033   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
3034    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
3035    && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
3036   "ldd %1,%0")
3037
3038 (define_peephole
3039   [(set (match_operand:SF 0 "memory_operand" "")
3040         (match_operand:SF 1 "register_operand" "fr"))
3041    (set (match_operand:SF 2 "memory_operand" "")
3042         (match_operand:SF 3 "register_operand" "fr"))]
3043   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
3044    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
3045    && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
3046   "std %1,%0")
3047
3048 (define_peephole
3049   [(set (match_operand:SI 0 "register_operand" "=rf")
3050         (match_operand:SI 1 "memory_operand" ""))
3051    (set (match_operand:SI 2 "register_operand" "=rf")
3052         (match_operand:SI 3 "memory_operand" ""))]
3053   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3054    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3055    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3056   "ldd %3,%2")
3057
3058 (define_peephole
3059   [(set (match_operand:SI 0 "memory_operand" "")
3060         (match_operand:SI 1 "register_operand" "rf"))
3061    (set (match_operand:SI 2 "memory_operand" "")
3062         (match_operand:SI 3 "register_operand" "rf"))]
3063   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3064    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3065    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
3066   "std %3,%2")
3067  
3068 (define_peephole
3069   [(set (match_operand:SF 0 "register_operand" "=fr")
3070         (match_operand:SF 1 "memory_operand" ""))
3071    (set (match_operand:SF 2 "register_operand" "=fr")
3072         (match_operand:SF 3 "memory_operand" ""))]
3073   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
3074    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
3075    && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
3076   "ldd %3,%2")
3077
3078 (define_peephole
3079   [(set (match_operand:SF 0 "memory_operand" "")
3080         (match_operand:SF 1 "register_operand" "fr"))
3081    (set (match_operand:SF 2 "memory_operand" "")
3082         (match_operand:SF 3 "register_operand" "fr"))]
3083   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
3084    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
3085    && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
3086   "std %3,%2")
3087  
3088 ;; Optimize the case of following a reg-reg move with a test
3089 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
3090 ;; This can result from a float to fix conversion.
3091
3092 (define_peephole
3093   [(set (match_operand:SI 0 "register_operand" "=r")
3094         (match_operand:SI 1 "register_operand" "r"))
3095    (set (reg:CC 0)
3096         (compare:CC (match_operand:SI 2 "register_operand" "r")
3097                     (const_int 0)))]
3098   "(rtx_equal_p (operands[2], operands[0])
3099     || rtx_equal_p (operands[2], operands[1]))
3100    && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
3101   "orcc %1,%%g0,%0")
3102
3103 ;; Do {sign,zero}-extended compares somewhat more efficiently.
3104 ;; ??? Is this now the Right Way to do this?  Or will SCRATCH
3105 ;;     eventually have some impact here?
3106
3107 (define_peephole
3108   [(set (match_operand:HI 0 "register_operand" "")
3109         (match_operand:HI 1 "memory_operand" ""))
3110    (set (match_operand:SI 2 "register_operand" "")
3111         (sign_extend:SI (match_dup 0)))
3112    (set (reg:CC 0)
3113         (compare:CC (match_dup 2)
3114                     (const_int 0)))]
3115   ""
3116   "ldsh %1,%0\;orcc %0,%%g0,%2")
3117
3118 (define_peephole
3119   [(set (match_operand:QI 0 "register_operand" "")
3120         (match_operand:QI 1 "memory_operand" ""))
3121    (set (match_operand:SI 2 "register_operand" "")
3122         (sign_extend:SI (match_dup 0)))
3123    (set (reg:CC 0)
3124         (compare:CC (match_dup 2)
3125                     (const_int 0)))]
3126   ""
3127   "ldsb %1,%0\;orcc %0,%%g0,%2")
3128
3129 (define_peephole
3130   [(set (match_operand:HI 0 "register_operand" "")
3131         (match_operand:HI 1 "memory_operand" ""))
3132    (set (match_operand:SI 2 "register_operand" "")
3133         (sign_extend:SI (match_dup 0)))]
3134   "dead_or_set_p (insn, operands[0])"
3135   "*
3136 {
3137   warning (\"bad peephole\");
3138   if (! MEM_VOLATILE_P (operands[1]))
3139     abort ();
3140   return \"ldsh %1,%2\";
3141 }")
3142
3143 (define_peephole
3144   [(set (match_operand:QI 0 "register_operand" "")
3145         (match_operand:QI 1 "memory_operand" ""))
3146    (set (match_operand:SI 2 "register_operand" "")
3147         (sign_extend:SI (match_dup 0)))]
3148   "dead_or_set_p (insn, operands[0])"
3149   "*
3150 {
3151   warning (\"bad peephole\");
3152   if (! MEM_VOLATILE_P (operands[1]))
3153     abort ();
3154   return \"ldsb %1,%2\";
3155 }")
3156
3157 ;; Floating-point move peepholes
3158
3159 (define_peephole
3160   [(set (match_operand:SI 0 "register_operand" "=r")
3161         (lo_sum:SI (match_dup 0)
3162                    (match_operand:SI 1 "immediate_operand" "i")))
3163    (set (match_operand:DF 2 "register_operand" "=fr")
3164         (mem:DF (match_dup 0)))]
3165   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3166   "*
3167 {
3168   /* Go by way of output_move_double in case the register in operand 2
3169      is not properly aligned for ldd.  */
3170   operands[1] = gen_rtx (MEM, DFmode,
3171                          gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
3172   operands[0] = operands[2];
3173   return output_move_double (operands);
3174 }")
3175
3176 (define_peephole
3177   [(set (match_operand:SI 0 "register_operand" "=r")
3178         (lo_sum:SI (match_dup 0)
3179                    (match_operand:SI 1 "immediate_operand" "i")))
3180    (set (match_operand:SF 2 "register_operand" "=fr")
3181         (mem:SF (match_dup 0)))]
3182   "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
3183   "ld [%0+%%lo(%a1)],%2")
3184
3185 ;; Return peepholes.  First the "normal" ones
3186
3187 ;; ??? There are QImode, HImode, and SImode versions of this pattern.
3188 ;; It might be possible to write one more general pattern instead of three.
3189
3190 (define_insn ""
3191   [(set (match_operand:QI 0 "restore_operand" "")
3192         (match_operand:QI 1 "arith_operand" "rI"))
3193    (return)]
3194   "! TARGET_EPILOGUE"
3195   "*
3196 {
3197   if (current_function_returns_struct)
3198     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3199   else
3200     return \"ret\;restore %%g0,%1,%Y0\";
3201 }"
3202   [(set_attr "type" "multi")])
3203
3204 (define_insn ""
3205   [(set (match_operand:HI 0 "restore_operand" "")
3206         (match_operand:HI 1 "arith_operand" "rI"))
3207    (return)]
3208   "! TARGET_EPILOGUE"
3209   "*
3210 {
3211   if (current_function_returns_struct)
3212     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3213   else
3214     return \"ret\;restore %%g0,%1,%Y0\";
3215 }"
3216   [(set_attr "type" "multi")])
3217
3218 (define_insn ""
3219   [(set (match_operand:SI 0 "restore_operand" "")
3220         (match_operand:SI 1 "arith_operand" "rI"))
3221    (return)]
3222   "! TARGET_EPILOGUE"
3223   "*
3224 {
3225   if (current_function_returns_struct)
3226     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3227   else
3228     return \"ret\;restore %%g0,%1,%Y0\";
3229 }"
3230   [(set_attr "type" "multi")])
3231
3232 ;; The following pattern is only generated by delayed-branch scheduling,
3233 ;; when the insn winds up in the epilogue.  This can only happen when
3234 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
3235 (define_insn ""
3236   [(set (match_operand:SF 0 "restore_operand" "r")
3237         (match_operand:SF 1 "register_operand" "r"))
3238    (return)]
3239   "! TARGET_FPU && ! TARGET_EPILOGUE"
3240   "*
3241 {
3242   if (current_function_returns_struct)
3243     return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
3244   else
3245     return \"ret\;restore %%g0,%1,%Y0\";
3246 }"
3247   [(set_attr "type" "multi")])
3248
3249 (define_insn ""
3250   [(set (match_operand:SI 0 "restore_operand" "")
3251         (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3252                  (match_operand:SI 2 "arith_operand" "rI")))
3253    (return)]
3254   "! TARGET_EPILOGUE"
3255   "*
3256 {
3257   if (current_function_returns_struct)
3258     return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
3259   else
3260     return \"ret\;restore %r1,%2,%Y0\";
3261 }"
3262   [(set_attr "type" "multi")])
3263
3264 ;; Turned off because it should never match (subtracting a constant
3265 ;; is turned into addition) and because it would do the wrong thing
3266 ;; when operand 2 is -4096 (--4096 == 4096 is not a valid immediate).
3267 ;;(define_insn ""
3268 ;;  [(set (match_operand:SI 0 "restore_operand" "")
3269 ;;      (minus:SI (match_operand:SI 1 "register_operand" "r")
3270 ;;                (match_operand:SI 2 "small_int" "I")))
3271 ;;   (return)]
3272 ;;  "! TARGET_EPILOGUE"
3273 ;;  "ret\;restore %1,-(%2),%Y0"
3274 ;;  [(set_attr "type" "multi")])
3275
3276 ;; The following pattern is only generated by delayed-branch scheduling,
3277 ;; when the insn winds up in the epilogue.
3278 (define_insn ""
3279   [(set (reg:SF 32)
3280         (match_operand:SF 0 "register_operand" "f"))
3281    (return)]
3282   "! TARGET_EPILOGUE"
3283   "ret\;fmovs %0,%%f0"
3284   [(set_attr "type" "multi")])
3285
3286 ;; Now peepholes to go a call followed by a jump.
3287
3288 (define_peephole
3289   [(parallel [(set (match_operand 0 "" "")
3290                    (call (mem:SI (match_operand:SI 1 "call_operand_address" "S,r"))
3291                          (match_operand 2 "" "")))
3292               (clobber (reg:SI 15))])
3293    (set (pc) (label_ref (match_operand 3 "" "")))]
3294   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))"
3295   "*
3296 {
3297   return \"call %a1,%2\;add %%o7,(%l3-.-4),%%o7\";
3298 }")
3299
3300 (define_peephole
3301   [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "S,r"))
3302                     (match_operand 1 "" ""))
3303               (clobber (reg:SI 15))])
3304    (set (pc) (label_ref (match_operand 2 "" "")))]
3305   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))"
3306   "*
3307 {
3308   return \"call %a0,%1\;add %%o7,(%l2-.-4),%%o7\";
3309 }")
3310
3311 (define_peephole
3312   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
3313                    (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
3314                              (reg:SI 0)))
3315               (clobber (reg:CC 0))])
3316    (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))]
3317   ""
3318   "subxcc %r1,0,%0")
3319
3320 ;;- Local variables:
3321 ;;- mode:emacs-lisp
3322 ;;- comment-start: ";;- "
3323 ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
3324 ;;- eval: (modify-syntax-entry ?[ "(]")
3325 ;;- eval: (modify-syntax-entry ?] ")[")
3326 ;;- eval: (modify-syntax-entry ?{ "(}")
3327 ;;- eval: (modify-syntax-entry ?} "){")
3328 ;;- End: