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