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)
5 ;; This file is part of GNU CC.
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)
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.
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.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; Insn type. Used to default other attribute values.
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.
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"))
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" ""))
40 (const_string "false")))
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))
48 (eq_attr "type" "store,fpstore")
49 (if_then_else (match_operand
0 "symbolic_memory_operand" "")
50 (const_int
2) (const_int
1))
52 (eq_attr "type" "address") (const_int
2)
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))
59 (eq_attr "type" "multi") (const_int
2)
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))]
68 (define_asm_attributes
69 [(set_attr "length" "
1")
70 (set_attr "type" "multi")])
72 ;; Attributes for instruction and branch scheduling
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")
80 (const_string "false"))
81 (eq_attr "type" "address")
82 (if_then_else (eq_attr "use_clobbered" "false")
84 (const_string "false"))]
85 (if_then_else (eq_attr "length" "
1")
87 (const_string "false"))))
89 (define_delay (eq_attr "type" "call")
90 [(eq_attr "in_call_delay" "true") (nil) (nil)])
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.
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"))
100 (const_string "false")))
102 (define_delay (eq_attr "type" "branch")
103 [(eq_attr "in_branch_delay" "true")
104 (nil) (eq_attr "in_branch_delay" "true")])
106 ;; Function units of the SPARC
108 ;; (define_function_unit {name} {num-units} {n-users} {test}
109 ;; {ready-delay} {busy-delay} [{conflict-list}])
112 ;; (Noted only for documentation; units that take one cycle do not need to
115 ;; (define_function_unit "alu"
1 0
116 ;; (eq_attr "type" "unary,binary,move,address")
1 0)
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)
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
137 ;; The CY7C602 can only support
2 fp isnsn simultaneously.
138 ;; More insns cause the chip to stall.
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)
145 ;; Compare instructions.
146 ;; This controls RTL generation and register allocation.
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.
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
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.
161 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
163 (define_expand "cmpsi"
165 (compare:CC (match_operand:SI
0 "register_operand" "")
166 (match_operand:SI
1 "arith_operand" "")))]
170 sparc_compare_op0 = operands[
0];
171 sparc_compare_op1 = operands[
1];
175 (define_expand "cmpsf"
177 (compare:CCFP (match_operand:SF
0 "register_operand" "")
178 (match_operand:SF
1 "register_operand" "")))]
182 sparc_compare_op0 = operands[
0];
183 sparc_compare_op1 = operands[
1];
187 (define_expand "cmpdf"
189 (compare:CCFP (match_operand:DF
0 "register_operand" "")
190 (match_operand:DF
1 "register_operand" "")))]
194 sparc_compare_op0 = operands[
0];
195 sparc_compare_op1 = operands[
1];
199 (define_expand "cmptf"
201 (compare:CCFP (match_operand:TF
0 "register_operand" "")
202 (match_operand:TF
1 "register_operand" "")))]
206 sparc_compare_op0 = operands[
0];
207 sparc_compare_op1 = operands[
1];
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.
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))])]
224 "{ operands[
3] = gen_reg_rtx (SImode); }")
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))])]
233 "{ operands[
3] = gen_reg_rtx (SImode); }")
236 [(set (match_operand:SI
0 "register_operand" "")
237 (eq:SI (match_dup
1) (const_int
0)))]
240 { if (GET_MODE (sparc_compare_op0) == SImode)
242 emit_insn (gen_seq_special (operands[
0], sparc_compare_op0,
247 operands[
1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
251 [(set (match_operand:SI
0 "register_operand" "")
252 (ne:SI (match_dup
1) (const_int
0)))]
255 { if (GET_MODE (sparc_compare_op0) == SImode)
257 emit_insn (gen_sne_special (operands[
0], sparc_compare_op0,
262 operands[
1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
266 [(set (match_operand:SI
0 "register_operand" "")
267 (gt:SI (match_dup
1) (const_int
0)))]
270 { operands[
1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
273 [(set (match_operand:SI
0 "register_operand" "")
274 (lt:SI (match_dup
1) (const_int
0)))]
277 { operands[
1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
280 [(set (match_operand:SI
0 "register_operand" "")
281 (ge:SI (match_dup
1) (const_int
0)))]
284 { operands[
1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
287 [(set (match_operand:SI
0 "register_operand" "")
288 (le:SI (match_dup
1) (const_int
0)))]
291 { operands[
1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
293 (define_expand "sgtu"
294 [(set (match_operand:SI
0 "register_operand" "")
295 (gtu:SI (match_dup
1) (const_int
0)))]
301 /* We can do ltu easily, so if both operands are registers, swap them and
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))
308 tem = sparc_compare_op0;
309 sparc_compare_op0 = sparc_compare_op1;
310 sparc_compare_op1 = tem;
311 emit_insn (gen_sltu (operands[
0]));
315 operands[
1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
318 (define_expand "sltu"
319 [(set (match_operand:SI
0 "register_operand" "")
320 (ltu:SI (match_dup
1) (const_int
0)))]
323 { operands[
1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
326 (define_expand "sgeu"
327 [(set (match_operand:SI
0 "register_operand" "")
328 (geu:SI (match_dup
1) (const_int
0)))]
331 { operands[
1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
334 (define_expand "sleu"
335 [(set (match_operand:SI
0 "register_operand" "")
336 (leu:SI (match_dup
1) (const_int
0)))]
342 /* We can do geu easily, so if both operands are registers, swap them and
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))
349 tem = sparc_compare_op0;
350 sparc_compare_op0 = sparc_compare_op1;
351 sparc_compare_op1 = tem;
352 emit_insn (gen_sgeu (operands[
0]));
356 operands[
1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
359 ;; Now the DEFINE_INSNs for the compare and scc cases. First the compares.
363 (compare:CC (match_operand:SI
0 "register_operand" "rJ")
364 (match_operand:SI
1 "arith_operand" "rI")))]
367 [(set_attr "type" "compare")])
371 (compare:CCFPE (match_operand:DF
0 "register_operand" "f")
372 (match_operand:DF
1 "register_operand" "f")))]
375 [(set_attr "type" "fpcmp")])
379 (compare:CCFPE (match_operand:SF
0 "register_operand" "f")
380 (match_operand:SF
1 "register_operand" "f")))]
383 [(set_attr "type" "fpcmp")])
387 (compare:CCFPE (match_operand:TF
0 "register_operand" "f")
388 (match_operand:TF
1 "register_operand" "f")))]
391 [(set_attr "type" "fpcmp")])
395 (compare:CCFP (match_operand:DF
0 "register_operand" "f")
396 (match_operand:DF
1 "register_operand" "f")))]
399 [(set_attr "type" "fpcmp")])
403 (compare:CCFP (match_operand:SF
0 "register_operand" "f")
404 (match_operand:SF
1 "register_operand" "f")))]
407 [(set_attr "type" "fpcmp")])
411 (compare:CCFP (match_operand:TF
0 "register_operand" "f")
412 (match_operand:TF
1 "register_operand" "f")))]
415 [(set_attr "type" "fpcmp")])
417 ;; The SEQ and SNE patterns are special because they can be done
418 ;; without any branching and do not involve a COMPARE.
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))]
425 "subcc %%g0,%
1,%%g0\;addx %%g0,
0,%
0"
426 [(set_attr "type" "unary")
427 (set_attr "length" "
2")])
430 [(set (match_operand:SI
0 "register_operand" "=r")
431 (neg:SI (ne:SI (match_operand:SI
1 "register_operand" "r")
433 (clobber (reg:CC
0))]
435 "subcc %%g0,%
1,%%g0\;subx %%g0,
0,%
0"
436 [(set_attr "type" "unary")
437 (set_attr "length" "
2")])
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))]
444 "subcc %%g0,%
1,%%g0\;subx %%g0,-
1,%
0"
445 [(set_attr "type" "unary")
446 (set_attr "length" "
2")])
449 [(set (match_operand:SI
0 "register_operand" "=r")
450 (neg:SI (eq:SI (match_operand:SI
1 "register_operand" "r")
452 (clobber (reg:CC
0))]
454 "subcc %%g0,%
1,%%g0\;addx %%g0,-
1,%
0"
455 [(set_attr "type" "unary")
456 (set_attr "length" "
2")])
458 ;; We can also do (x + (i ==
0)) and related, so put them in.
461 [(set (match_operand:SI
0 "register_operand" "=r")
462 (plus:SI (ne:SI (match_operand:SI
1 "register_operand" "r")
464 (match_operand:SI
2 "register_operand" "r")))
465 (clobber (reg:CC
0))]
467 "subcc %%g0,%
1,%%g0\;addx %
2,
0,%
0"
468 [(set_attr "length" "
2")])
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")
475 (clobber (reg:CC
0))]
477 "subcc %%g0,%
1,%%g0\;subx %
2,
0,%
0"
478 [(set_attr "length" "
2")])
481 [(set (match_operand:SI
0 "register_operand" "=r")
482 (plus:SI (eq:SI (match_operand:SI
1 "register_operand" "r")
484 (match_operand:SI
2 "register_operand" "r")))
485 (clobber (reg:CC
0))]
487 "subcc %%g0,%
1,%%g0\;subx %
2,-
1,%
0"
488 [(set_attr "length" "
2")])
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")
495 (clobber (reg:CC
0))]
497 "subcc %%g0,%
1,%%g0\;addx %
2,-
1,%
0"
498 [(set_attr "length" "
2")])
500 ;; We can also do GEU and LTU directly, but these operate after a
504 [(set (match_operand:SI
0 "register_operand" "=r")
505 (ltu:SI (reg:CC
0) (const_int
0)))]
508 [(set_attr "type" "misc")])
511 [(set (match_operand:SI
0 "register_operand" "=r")
512 (neg:SI (ltu:SI (reg:CC
0) (const_int
0))))]
515 [(set_attr "type" "misc")])
517 ;; ??? Combine should canonicalize these next two to the same pattern.
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")))]
524 [(set_attr "type" "unary")])
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"))))]
532 [(set_attr "type" "unary")])
535 [(set (match_operand:SI
0 "register_operand" "=r")
536 (geu:SI (reg:CC
0) (const_int
0)))]
539 [(set_attr "type" "misc")])
542 [(set (match_operand:SI
0 "register_operand" "=r")
543 (neg:SI (geu:SI (reg:CC
0) (const_int
0))))]
546 [(set_attr "type" "misc")])
548 ;; We can also do (x + ((unsigned) i >=
0)) and related, so put them in.
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")))]
556 [(set_attr "type" "unary")])
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"))))]
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))))]
572 [(set_attr "type" "unary")])
574 ;; ??? Combine should canonicalize these next two to the same pattern.
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))))]
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"))))]
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")))]
597 [(set_attr "type" "unary")])
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))))]
605 [(set_attr "type" "unary")])
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.
611 [(set (match_operand:SI
0 "register_operand" "=r")
612 (match_operator:SI
1 "noov_compare_op" [(reg
0) (const_int
0)]))]
614 "* return output_scc_insn (operands, insn); "
615 [(set_attr "type" "multi")
616 (set_attr "length" "
3")])
618 ;; These control RTL generation for conditional jump insns
622 (if_then_else (eq (match_dup
1) (const_int
0))
623 (label_ref (match_operand
0 "" ""))
627 { operands[
1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); }")
631 (if_then_else (ne (match_dup
1) (const_int
0))
632 (label_ref (match_operand
0 "" ""))
636 { operands[
1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); }")
640 (if_then_else (gt (match_dup
1) (const_int
0))
641 (label_ref (match_operand
0 "" ""))
645 { operands[
1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); }")
647 (define_expand "bgtu"
649 (if_then_else (gtu (match_dup
1) (const_int
0))
650 (label_ref (match_operand
0 "" ""))
654 { operands[
1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
659 (if_then_else (lt (match_dup
1) (const_int
0))
660 (label_ref (match_operand
0 "" ""))
664 { operands[
1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); }")
666 (define_expand "bltu"
668 (if_then_else (ltu (match_dup
1) (const_int
0))
669 (label_ref (match_operand
0 "" ""))
673 { operands[
1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
678 (if_then_else (ge (match_dup
1) (const_int
0))
679 (label_ref (match_operand
0 "" ""))
683 { operands[
1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); }")
685 (define_expand "bgeu"
687 (if_then_else (geu (match_dup
1) (const_int
0))
688 (label_ref (match_operand
0 "" ""))
692 { operands[
1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
697 (if_then_else (le (match_dup
1) (const_int
0))
698 (label_ref (match_operand
0 "" ""))
702 { operands[
1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); }")
704 (define_expand "bleu"
706 (if_then_else (leu (match_dup
1) (const_int
0))
707 (label_ref (match_operand
0 "" ""))
711 { operands[
1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
714 ;; Now match both normal and inverted jump.
718 (if_then_else (match_operator
0 "noov_compare_op"
719 [(reg
0) (const_int
0)])
720 (label_ref (match_operand
1 "" ""))
725 return output_cbranch (operands[
0],
1,
0,
726 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
729 [(set_attr "type" "branch")])
733 (if_then_else (match_operator
0 "noov_compare_op"
734 [(reg
0) (const_int
0)])
736 (label_ref (match_operand
1 "" ""))))]
740 return output_cbranch (operands[
0],
1,
1,
741 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
744 [(set_attr "type" "branch")])
748 (define_expand "movsi"
749 [(set (match_operand:SI
0 "general_operand" "")
750 (match_operand:SI
1 "general_operand" ""))]
754 if (emit_move_sequence (operands, SImode,
0))
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"))]
765 if (emit_move_sequence (operands, SImode, operands[
2]))
768 /* We don't want the clobber emitted, so handle this ourselves. */
769 emit_insn (gen_rtx (SET, VOIDmode, operands[
0], operands[
1]));
773 ;; We must support both 'r' and 'f' registers here, because combine may
774 ;; convert SFmode hard registers to SImode hard registers when simplifying
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.
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"
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,*,*,*,*,*")])
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)
803 [(set (match_operand:SI
0 "register_operand" "=r")
804 (match_operand:SI
1 "move_pic_label" "i"))
805 (set (reg:SI
15) (pc))]
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")])
812 [(set (match_operand:DI
0 "register_operand" "=r")
813 (high:DI (match_operand
1 "" "")))]
817 rtx op0 = operands[
0];
818 rtx op1 = operands[
1];
820 if (GET_CODE (op1) == CONST_INT)
822 operands[
0] = operand_subword (op0,
1,
0, DImode);
823 output_asm_insn (
\"sethi %%hi(%a1),%
0\", operands);
825 operands[
0] = operand_subword (op0,
0,
0, DImode);
826 if (INTVAL (op1) <
0)
827 output_asm_insn (
\"mov -
1,%
0\", operands);
829 output_asm_insn (
\"mov
0,%
0\", operands);
831 else if (GET_CODE (op1) == CONST_DOUBLE)
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);
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);
844 [(set_attr "type" "move")
845 (set_attr "length" "
2")])
847 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
848 ;; confuse them with real addresses.
850 [(set (match_operand:SI
0 "register_operand" "=r")
851 (high:SI (unspec:SI [(match_operand
1 "" "")]
0)))]
854 [(set_attr "type" "move")
855 (set_attr "length" "
1")])
858 [(set (match_operand:SI
0 "register_operand" "=r")
859 (high:SI (match_operand
1 "" "")))]
862 [(set_attr "type" "move")
863 (set_attr "length" "
1")])
866 [(set (match_operand:HI
0 "register_operand" "=r")
867 (high:HI (match_operand
1 "" "")))]
870 [(set_attr "type" "move")
871 (set_attr "length" "
1")])
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")))]
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
\";
886 ;; Need to set length for this arith insn because operand2
887 ;; is not an "arith_operand".
888 [(set_attr "length" "
1")])
890 ;; For PIC, symbol_refs are put inside unspec so that the optimizer won't
891 ;; confuse them with real addresses.
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)))]
898 ;; Need to set length for this arith insn because operand2
899 ;; is not an "arith_operand".
900 [(set_attr "length" "
1")])
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")))]
908 ;; Need to set length for this arith insn because operand2
909 ;; is not an "arith_operand".
910 [(set_attr "length" "
1")])
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"))]
917 "sethi %%hi(%a0),%
2\;st %r1,[%
2+%%lo(%a0)]"
918 [(set_attr "type" "store")
919 (set_attr "length" "
2")])
921 (define_expand "movhi"
922 [(set (match_operand:HI
0 "general_operand" "")
923 (match_operand:HI
1 "general_operand" ""))]
927 if (emit_move_sequence (operands, HImode,
0))
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"
942 [(set_attr "type" "move,move,load,store")
943 (set_attr "length" "*,
1,*,
1")])
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")))]
951 [(set_attr "length" "
1")])
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"))]
958 "sethi %%hi(%a0),%
2\;sth %r1,[%
2+%%lo(%a0)]"
959 [(set_attr "type" "store")
960 (set_attr "length" "
2")])
962 (define_expand "movqi"
963 [(set (match_operand:QI
0 "general_operand" "")
964 (match_operand:QI
1 "general_operand" ""))]
968 if (emit_move_sequence (operands, QImode,
0))
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"
983 [(set_attr "type" "move,move,load,store")
984 (set_attr "length" "*,
1,*,
1")])
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))]
992 [(set_attr "length" "
1")])
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"))]
999 "sethi %%hi(%a0),%
2\;stb %r1,[%
2+%%lo(%a0)]"
1000 [(set_attr "type" "store")
1001 (set_attr "length" "
2")])
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))])]
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)
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]);
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))]
1044 "* return output_block_move (operands);"
1045 [(set_attr "type" "multi")
1046 (set_attr "length" "
6")])
1048 ;; Floating point move insns
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.
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"
1059 switch (which_alternative)
1062 return output_move_quad (operands);
1064 return output_fp_move_quad (operands);
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\";
1072 [(set_attr "type" "load,fpload,store")
1073 (set_attr "length" "
5,
5,
5")])
1075 (define_expand "movtf"
1076 [(set (match_operand:TF
0 "general_operand" "")
1077 (match_operand:TF
1 "general_operand" ""))]
1081 if (emit_move_sequence (operands, TFmode,
0))
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)"
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);
1096 [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
1097 (set_attr "length" "
4,
4,
5,
5,
5,
5,
5,
5")])
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"))]
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)]
\";
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)]
\";
1112 [(set_attr "type" "store")
1113 (set_attr "length" "
5")])
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.
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"
1124 switch (which_alternative)
1127 return output_move_double (operands);
1129 return output_fp_move_double (operands);
1131 operands[
1] = adj_offsettable_operand (operands[
0],
4);
1132 return
\"st %%g0,%
0\;st %%g0,%
1\";
1135 [(set_attr "type" "load,fpload,store")
1136 (set_attr "length" "
3,
3,
3")])
1138 (define_expand "movdf"
1139 [(set (match_operand:DF
0 "general_operand" "")
1140 (match_operand:DF
1 "general_operand" ""))]
1144 if (emit_move_sequence (operands, DFmode,
0))
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)"
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);
1159 [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
1160 (set_attr "length" "
2,
2,
3,
3,
3,
3,
3,
3")])
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"))]
1169 output_asm_insn (
\"sethi %%hi(%a0),%
2\", operands);
1170 if (which_alternative ==
0)
1171 return
\"std %
1,[%
2+%%lo(%a0)]
\";
1173 return
\"st %%g0,[%
2+%%lo(%a0)]\;st %%g0,[%
2+%%lo(%a0+
4)]
\";
1175 [(set_attr "type" "store")
1176 (set_attr "length" "
3")])
1178 ;; Double-word move insns.
1180 (define_expand "movdi"
1181 [(set (match_operand:DI
0 "reg_or_nonsymb_mem_operand" "")
1182 (match_operand:DI
1 "general_operand" ""))]
1186 if (emit_move_sequence (operands, DImode,
0))
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"
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);
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")])
1205 ;; Floating-point move insns.
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.
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"
1216 switch (which_alternative)
1219 return singlemove_string (operands);
1221 return
\"ld %
1,%
0\";
1223 return
\"st %%g0,%
0\";
1226 [(set_attr "type" "load,fpload,store")
1227 (set_attr "length" "
2,
1,
1")])
1229 (define_expand "movsf"
1230 [(set (match_operand:SF
0 "general_operand" "")
1231 (match_operand:SF
1 "general_operand" ""))]
1235 if (emit_move_sequence (operands, SFmode,
0))
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)"
1247 st %r1,[%%fp-
4]\;ld [%%fp-
4],%
0
1252 [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")])
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"))]
1259 "sethi %%hi(%a0),%
2\;st %r1,[%
2+%%lo(%a0)]"
1260 [(set_attr "type" "store")
1261 (set_attr "length" "
2")])
1263 ;;- zero extension instructions
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.
1269 (define_expand "zero_extendhisi2"
1270 [(set (match_operand:SI
0 "register_operand" "")
1271 (zero_extend:SI (match_operand:HI
1 "register_operand" "")))]
1275 rtx temp = gen_reg_rtx (SImode);
1276 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode,
16);
1278 if (GET_CODE (operand1) == SUBREG)
1279 operand1 = XEXP (operand1,
0);
1281 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
0),
1283 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
1288 [(set (match_operand:SI
0 "register_operand" "=r")
1289 (zero_extend:SI (match_operand:HI
1 "memory_operand" "m")))]
1292 [(set_attr "type" "load")])
1294 (define_expand "zero_extendqihi2"
1295 [(set (match_operand:HI
0 "register_operand" "")
1296 (zero_extend:HI (match_operand:QI
1 "register_operand" "")))]
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"
1308 [(set_attr "type" "unary,move,load")
1309 (set_attr "length" "
1")])
1311 (define_expand "zero_extendqisi2"
1312 [(set (match_operand:SI
0 "register_operand" "")
1313 (zero_extend:SI (match_operand:QI
1 "register_operand" "")))]
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"
1325 [(set_attr "type" "unary,move,load")
1326 (set_attr "length" "
1")])
1330 (compare:CC (zero_extend:SI (match_operand:QI
0 "register_operand" "r"))
1333 "andcc %
0,
0xff,%%g0"
1334 [(set_attr "type" "compare")])
1338 (compare:CC (zero_extend:SI (match_operand:QI
1 "register_operand" "r"))
1340 (set (match_operand:SI
0 "register_operand" "=r")
1341 (zero_extend:SI (match_dup
1)))]
1344 [(set_attr "type" "unary")])
1346 ;;- sign extension instructions
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.
1352 (define_expand "extendhisi2"
1353 [(set (match_operand:SI
0 "register_operand" "")
1354 (sign_extend:SI (match_operand:HI
1 "register_operand" "")))]
1358 rtx temp = gen_reg_rtx (SImode);
1359 rtx shift_16 = gen_rtx (CONST_INT, VOIDmode,
16);
1361 if (GET_CODE (operand1) == SUBREG)
1362 operand1 = XEXP (operand1,
0);
1364 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
0),
1366 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
1371 [(set (match_operand:SI
0 "register_operand" "=r")
1372 (sign_extend:SI (match_operand:HI
1 "memory_operand" "m")))]
1375 [(set_attr "type" "load")])
1377 (define_expand "extendqihi2"
1378 [(set (match_operand:HI
0 "register_operand" "")
1379 (sign_extend:HI (match_operand:QI
1 "register_operand" "")))]
1383 rtx temp = gen_reg_rtx (SImode);
1384 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode,
24);
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),
1392 if (GET_MODE (operand0) != SImode)
1393 operand0 = gen_rtx (SUBREG, SImode, operand0,
0);
1394 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1399 [(set (match_operand:HI
0 "register_operand" "=r")
1400 (sign_extend:HI (match_operand:QI
1 "memory_operand" "m")))]
1403 [(set_attr "type" "load")])
1405 (define_expand "extendqisi2"
1406 [(set (match_operand:SI
0 "register_operand" "")
1407 (sign_extend:SI (match_operand:QI
1 "register_operand" "")))]
1411 rtx temp = gen_reg_rtx (SImode);
1412 rtx shift_24 = gen_rtx (CONST_INT, VOIDmode,
24);
1414 if (GET_CODE (operand1) == SUBREG)
1415 operand1 = XEXP (operand1,
0);
1416 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
0),
1418 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
1423 [(set (match_operand:SI
0 "register_operand" "=r")
1424 (sign_extend:SI (match_operand:QI
1 "memory_operand" "m")))]
1427 [(set_attr "type" "load")])
1429 ;; Special pattern for optimizing bit-field compares. This is needed
1430 ;; because combine uses this as a canonical form.
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"))
1439 "INTVAL (operands[
2]) >
19"
1442 int len = INTVAL (operands[
1]);
1443 int pos =
32 - INTVAL (operands[
2]) - len;
1444 unsigned mask = ((
1 << len) -
1) << pos;
1446 operands[
1] = gen_rtx (CONST_INT, VOIDmode, mask);
1447 return
\"andcc %
0,%
1,%%g0
\";
1450 ;; Conversions between float, double and long double.
1452 (define_insn "extendsfdf2"
1453 [(set (match_operand:DF
0 "register_operand" "=f")
1455 (match_operand:SF
1 "register_operand" "f")))]
1458 [(set_attr "type" "fp")])
1460 (define_insn "extendsftf2"
1461 [(set (match_operand:TF
0 "register_operand" "=f")
1463 (match_operand:SF
1 "register_operand" "f")))]
1466 [(set_attr "type" "fp")])
1468 (define_insn "extenddftf2"
1469 [(set (match_operand:TF
0 "register_operand" "=f")
1471 (match_operand:DF
1 "register_operand" "f")))]
1474 [(set_attr "type" "fp")])
1476 (define_insn "truncdfsf2"
1477 [(set (match_operand:SF
0 "register_operand" "=f")
1479 (match_operand:DF
1 "register_operand" "f")))]
1482 [(set_attr "type" "fp")])
1484 (define_insn "trunctfsf2"
1485 [(set (match_operand:SF
0 "register_operand" "=f")
1487 (match_operand:TF
1 "register_operand" "f")))]
1490 [(set_attr "type" "fp")])
1492 (define_insn "trunctfdf2"
1493 [(set (match_operand:DF
0 "register_operand" "=f")
1495 (match_operand:TF
1 "register_operand" "f")))]
1498 [(set_attr "type" "fp")])
1500 ;; Conversion between fixed point and floating point.
1502 (define_insn "floatsisf2"
1503 [(set (match_operand:SF
0 "general_operand" "=f")
1504 (float:SF (match_operand:SI
1 "nonimmediate_operand" "rfm")))]
1506 "* return output_floatsisf2 (operands);"
1507 [(set_attr "type" "fp")
1508 (set_attr "length" "
3")])
1510 (define_insn "floatsidf2"
1511 [(set (match_operand:DF
0 "general_operand" "=f")
1512 (float:DF (match_operand:SI
1 "nonimmediate_operand" "rfm")))]
1514 "* return output_floatsidf2 (operands);"
1515 [(set_attr "type" "fp")
1516 (set_attr "length" "
3")])
1518 (define_insn "floatsitf2"
1519 [(set (match_operand:TF
0 "general_operand" "=f")
1520 (float:TF (match_operand:SI
1 "nonimmediate_operand" "rfm")))]
1522 "* return output_floatsitf2 (operands);"
1523 [(set_attr "type" "fp")
1524 (set_attr "length" "
3")])
1526 ;; Convert a float to an actual integer.
1527 ;; Truncation is performed as part of the conversion.
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"))]
1536 if (FP_REG_P (operands[
1]))
1537 output_asm_insn (
\"fstoi %
1,%
2\", operands);
1539 output_asm_insn (
\"ld %
1,%
2\;fstoi %
2,%
2\", operands);
1540 if (GET_CODE (operands[
0]) == MEM)
1541 return
\"st %
2,%
0\";
1543 return
\"st %
2,[%%fp-
4]\;ld [%%fp-
4],%
0\";
1545 [(set_attr "type" "fp")
1546 (set_attr "length" "
3")])
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"))]
1555 if (FP_REG_P (operands[
1]))
1556 output_asm_insn (
\"fdtoi %
1,%
2\", operands);
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);
1565 if (GET_CODE (operands[
0]) == MEM)
1566 return
\"st %
2,%
0\";
1568 return
\"st %
2,[%%fp-
4]\;ld [%%fp-
4],%
0\";
1570 [(set_attr "type" "fp")
1571 (set_attr "length" "
3")])
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"))]
1580 if (FP_REG_P (operands[
1]))
1581 output_asm_insn (
\"fqtoi %
1,%
2\", operands);
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);
1590 if (GET_CODE (operands[
0]) == MEM)
1591 return
\"st %
2,%
0\";
1593 return
\"st %
2,[%%fp-
4]\;ld [%%fp-
4],%
0\";
1595 [(set_attr "type" "fp")
1596 (set_attr "length" "
3")])
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.
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))))]
1611 if (FP_REG_P (operands[
1]))
1612 output_asm_insn (
\"fqtoi %
1,%
0\", operands);
1615 output_asm_insn (output_fp_move_quad (operands), operands);
1616 output_asm_insn (
\"fqtoi %
0,%
0\", operands);
1618 if (GET_CODE (operands[
2]) == MEM)
1619 return
\"st %
0,%
2\;fitoq %
0,%
0\";
1621 return
\"st %
0,[%%fp-
4]\;fitoq %
0,%
0\;ld [%%fp-
4],%
2\";
1623 [(set_attr "type" "fp")
1624 (set_attr "length" "
5")])
1627 [(set (match_operand:TF
0 "general_operand" "=f")
1628 (float:TF (fix:SI (fix:TF (match_operand:TF
1 "general_operand" "fm")))))]
1632 if (FP_REG_P (operands[
1]))
1633 output_asm_insn (
\"fqtoi %
1,%
0\", operands);
1636 output_asm_insn (output_fp_move_quad (operands), operands);
1637 output_asm_insn (
\"fqtoi %
0,%
0\", operands);
1639 return
\"fitoq %
0,%
0\";
1641 [(set_attr "type" "fp")
1642 (set_attr "length" "
3")])
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.
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))))]
1657 if (FP_REG_P (operands[
1]))
1658 output_asm_insn (
\"fdtoi %
1,%
0\", operands);
1661 output_asm_insn (output_fp_move_double (operands), operands);
1662 output_asm_insn (
\"fdtoi %
0,%
0\", operands);
1664 if (GET_CODE (operands[
2]) == MEM)
1665 return
\"st %
0,%
2\;fitod %
0,%
0\";
1667 return
\"st %
0,[%%fp-
4]\;fitod %
0,%
0\;ld [%%fp-
4],%
2\";
1669 [(set_attr "type" "fp")
1670 (set_attr "length" "
5")])
1673 [(set (match_operand:DF
0 "general_operand" "=f")
1674 (float:DF (fix:SI (fix:DF (match_operand:DF
1 "general_operand" "fm")))))]
1678 if (FP_REG_P (operands[
1]))
1679 output_asm_insn (
\"fdtoi %
1,%
0\", operands);
1682 output_asm_insn (output_fp_move_double (operands), operands);
1683 output_asm_insn (
\"fdtoi %
0,%
0\", operands);
1685 return
\"fitod %
0,%
0\";
1687 [(set_attr "type" "fp")
1688 (set_attr "length" "
3")])
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.
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))))]
1703 if (FP_REG_P (operands[
1]))
1704 output_asm_insn (
\"fstoi %
1,%
0\", operands);
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\";
1710 return
\"st %
0,[%%fp-
4]\;fitos %
0,%
0\;ld [%%fp-
4],%
2\";
1712 [(set_attr "type" "fp")
1713 (set_attr "length" "
5")])
1716 [(set (match_operand:SF
0 "general_operand" "=f")
1717 (float:SF (fix:SI (fix:SF (match_operand:SF
1 "general_operand" "fm")))))]
1721 if (FP_REG_P (operands[
1]))
1722 output_asm_insn (
\"fstoi %
1,%
0\", operands);
1724 output_asm_insn (
\"ld %
1,%
0\;fstoi %
0,%
0\", operands);
1725 return
\"fitos %
0,%
0\";
1727 [(set_attr "type" "fp")
1728 (set_attr "length" "
3")])
1730 ;;- arithmetic instructions
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))]
1740 rtx op2 = operands[
2];
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)
1746 int sign = INTVAL (op2);
1748 return
\"addcc %R1,%
2,%R0\;addx %
1,-
1,%
0\";
1749 return
\"addcc %R1,%
2,%R0\;addx %
1,
0,%
0\";
1751 else if (GET_CODE (op2) == CONST_DOUBLE)
1753 int sign = CONST_DOUBLE_HIGH (op2);
1754 operands[
2] = gen_rtx (CONST_INT, VOIDmode,
1755 CONST_DOUBLE_LOW (operands[
1]));
1757 return
\"addcc %R1,%
2,%R0\;addx %
1,-
1,%
0\";
1758 return
\"addcc %R1,%
2,%R0\;addx %
1,
0,%
0\";
1760 return
\"addcc %R1,%R2,%R0\;addx %
1,%
2,%
0\";
1762 [(set_attr "length" "
2")])
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")))]
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"))
1778 [(set_attr "type" "compare")])
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"))
1785 (set (match_operand:SI
0 "register_operand" "=r")
1786 (plus:SI (match_dup
1) (match_dup
2)))]
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))]
1798 rtx op2 = operands[
2];
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)
1804 int sign = INTVAL (op2);
1806 return
\"subcc %R1,%
2,%R0\;subx %
1,-
1,%
0\";
1807 return
\"subcc %R1,%
2,%R0\;subx %
1,
0,%
0\";
1809 else if (GET_CODE (op2) == CONST_DOUBLE)
1811 int sign = CONST_DOUBLE_HIGH (op2);
1812 operands[
2] = gen_rtx (CONST_INT, VOIDmode,
1813 CONST_DOUBLE_LOW (operands[
1]));
1815 return
\"subcc %R1,%
2,%R0\;subx %
1,-
1,%
0\";
1816 return
\"subcc %R1,%
2,%R0\;subx %
1,
0,%
0\";
1818 return
\"subcc %R1,%R2,%R0\;subx %
1,%
2,%
0\";
1820 [(set_attr "length" "
2")])
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")))]
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"))
1836 [(set_attr "type" "compare")])
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"))
1843 (set (match_operand:SI
0 "register_operand" "=r")
1844 (minus:SI (match_dup
1) (match_dup
2)))]
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"
1855 ;; It is not known whether this will match.
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))
1864 "TARGET_V8 || TARGET_SPARCLITE"
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")])
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")])
1883 ;; The architecture specifies that there must be
3 instructions between
1884 ;; a y register write and a use of it for correct results.
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"))]
1892 "sra %
1,
31,%
3\;wr %%g0,%
3,%%y\;nop\;nop\;nop\;sdiv %
1,%
2,%
0"
1893 [(set_attr "length" "
3")])
1895 ;; It is not known whether this will match.
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")))
1902 (compare:CC (div:SI (match_dup
1) (match_dup
2))
1904 (clobber (match_scratch:SI
3 "=&r"))]
1906 "sra %
1,
31,%
3\;wr %%g0,%
3,%%y\;nop\;nop\;nop\;sdivcc %
1,%
2,%
0"
1907 [(set_attr "length" "
3")])
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")))]
1914 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %
1,%
2,%
0"
1915 [(set_attr "length" "
2")])
1917 ;; It is not known whether this will match.
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")))
1924 (compare:CC (udiv:SI (match_dup
1) (match_dup
2))
1927 "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %
1,%
2,%
0"
1928 [(set_attr "length" "
2")])
1930 ;;- and instructions
1931 ;; We define DImode
`and` so with DImode
`not` we can get
1932 ;; DImode
`andn`. Other combinations are possible.
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" "")))]
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")))]
1948 rtx op2 = operands[
2];
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)
1954 int sign = INTVAL (op2);
1956 return
\"mov %
1,%
0\;and %R1,%
2,%R0
\";
1957 return
\"mov
0,%
0\;and %R1,%
2,%R0
\";
1959 else if (GET_CODE (op2) == CONST_DOUBLE)
1961 int sign = CONST_DOUBLE_HIGH (op2);
1962 operands[
2] = gen_rtx (CONST_INT, VOIDmode,
1963 CONST_DOUBLE_LOW (operands[
1]));
1965 return
\"mov %
1,%
0\;and %R1,%
2,%R0
\";
1966 return
\"mov
0,%
0\;and %R1,%
2,%R0
\";
1968 return
\"and %
1,%
2,%
0\;and %R1,%R2,%R0
\";
1970 [(set_attr "length" "
2")])
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")))]
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")))]
1984 "andn %
2,%
1,%
0\;andn %R2,%R1,%R0"
1985 [(set_attr "length" "
2")])
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")))]
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" "")))]
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")))]
2008 rtx op2 = operands[
2];
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)
2014 int sign = INTVAL (op2);
2016 return
\"mov -
1,%
0\;or %R1,%
2,%R0
\";
2017 return
\"mov %
1,%
0\;or %R1,%
2,%R0
\";
2019 else if (GET_CODE (op2) == CONST_DOUBLE)
2021 int sign = CONST_DOUBLE_HIGH (op2);
2022 operands[
2] = gen_rtx (CONST_INT, VOIDmode,
2023 CONST_DOUBLE_LOW (operands[
1]));
2025 return
\"mov -
1,%
0\;or %R1,%
2,%R0
\";
2026 return
\"mov %
1,%
0\;or %R1,%
2,%R0
\";
2028 return
\"or %
1,%
2,%
0\;or %R1,%R2,%R0
\";
2030 [(set_attr "length" "
2")])
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")))]
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")))]
2044 "orn %
2,%
1,%
0\;orn %R2,%R1,%R0"
2045 [(set_attr "length" "
2")])
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")))]
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" "")))]
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")))]
2068 rtx op2 = operands[
2];
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)
2074 int sign = INTVAL (op2);
2076 return
\"xor %
1,-
1,%
0\;xor %R1,%
2,%R0
\";
2077 return
\"mov %
1,%
0\;xor %R1,%
2,%R0
\";
2079 else if (GET_CODE (op2) == CONST_DOUBLE)
2081 int sign = CONST_DOUBLE_HIGH (op2);
2082 operands[
2] = gen_rtx (CONST_INT, VOIDmode,
2083 CONST_DOUBLE_LOW (operands[
1]));
2085 return
\"xor %
1,-
1,%
0\;xor %R1,%
2,%R0
\";
2086 return
\"mov %
1,%
0\;xor %R1,%
2,%R0
\";
2088 return
\"xor %
1,%
2,%
0\;xor %R1,%R2,%R0
\";
2090 [(set_attr "length" "
2")])
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")))]
2099 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
2100 ;; Combine now canonicalizes to the rightmost expression.
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"))))]
2106 "xnor %
1,%
2,%
0\;xnor %R1,%R2,%R0"
2107 [(set_attr "length" "
2")])
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"))))]
2116 ;; These correspond to the above in the case where we also (or only)
2117 ;; want to set the condition code.
2122 (match_operator:SI
2 "cc_arithop"
2123 [(match_operand:SI
0 "arith_operand" "%r")
2124 (match_operand:SI
1 "arith_operand" "rI")])
2128 [(set_attr "type" "compare")])
2133 (match_operator:SI
3 "cc_arithop"
2134 [(match_operand:SI
1 "arith_operand" "%r")
2135 (match_operand:SI
2 "arith_operand" "rI")])
2137 (set (match_operand:SI
0 "register_operand" "=r")
2145 (not:SI (xor:SI (match_operand:SI
0 "reg_or_0_operand" "%rJ")
2146 (match_operand:SI
1 "arith_operand" "rI")))
2149 "xnorcc %r0,%
1,%%g0"
2150 [(set_attr "type" "compare")])
2155 (not:SI (xor:SI (match_operand:SI
1 "reg_or_0_operand" "%rJ")
2156 (match_operand:SI
2 "arith_operand" "rI")))
2158 (set (match_operand:SI
0 "register_operand" "=r")
2159 (not:SI (xor:SI (match_dup
1) (match_dup
2))))]
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")])
2172 [(set_attr "type" "compare")])
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")])
2181 (set (match_operand:SI
0 "register_operand" "=r")
2186 ;; We cannot use the "neg" pseudo insn because the Sun assembler
2187 ;; does not know how to make it work for constants.
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))]
2194 "subcc %%g0,%R1,%R0\;subx %%g0,%
1,%
0"
2195 [(set_attr "type" "unary")
2196 (set_attr "length" "
2")])
2198 (define_insn "negsi2"
2199 [(set (match_operand:SI
0 "general_operand" "=r")
2200 (neg:SI (match_operand:SI
1 "arith_operand" "rI")))]
2203 [(set_attr "type" "unary")])
2206 [(set (reg:CC_NOOV
0)
2207 (compare:CC_NOOV (neg:SI (match_operand:SI
0 "arith_operand" "rI"))
2210 "subcc %%g0,%
0,%%g0"
2211 [(set_attr "type" "compare")])
2214 [(set (reg:CC_NOOV
0)
2215 (compare:CC_NOOV (neg:SI (match_operand:SI
1 "arith_operand" "rI"))
2217 (set (match_operand:SI
0 "register_operand" "=r")
2218 (neg:SI (match_dup
1)))]
2221 [(set_attr "type" "unary")])
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")))]
2232 [(set (match_operand:DI
0 "register_operand" "=r")
2233 (not:DI (match_operand:DI
1 "arith_double_operand" "rHI")))]
2237 rtx op1 = operands[
1];
2239 if (GET_CODE (op1) == CONST_INT)
2241 int sign = INTVAL (op1);
2243 return
\"xnor %%g0,%
1,%R0\;xnor %%g0,-
1,%
0\";
2244 return
\"xnor %%g0,%
1,%R0\;xnor %%g0,
0,%
0\";
2246 else if (GET_CODE (op1) == CONST_DOUBLE)
2248 int sign = CONST_DOUBLE_HIGH (op1);
2249 operands[
1] = gen_rtx (CONST_INT, VOIDmode,
2250 CONST_DOUBLE_LOW (operands[
1]));
2252 return
\"xnor %%g0,%
1,%R0\;xnor %%g0,-
1,%
0\";
2253 return
\"xnor %%g0,%
1,%R0\;xnor %%g0,
0,%
0\";
2255 return
\"xnor %%g0,%
1,%
0\;xnor %%g0,%R1,%R0
\";
2257 [(set_attr "type" "unary")
2258 (set_attr "length" "
2")])
2260 (define_insn "one_cmplsi2"
2261 [(set (match_operand:SI
0 "register_operand" "=r")
2262 (not:SI (match_operand:SI
1 "arith_operand" "rI")))]
2265 [(set_attr "type" "unary")])
2269 (compare:CC (not:SI (match_operand:SI
0 "arith_operand" "rI"))
2272 "xnorcc %%g0,%
0,%%g0"
2273 [(set_attr "type" "compare")])
2277 (compare:CC (not:SI (match_operand:SI
1 "arith_operand" "rI"))
2279 (set (match_operand:SI
0 "register_operand" "=r")
2280 (not:SI (match_dup
1)))]
2283 [(set_attr "type" "unary")])
2285 ;; Floating point arithmetic instructions.
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")))]
2293 [(set_attr "type" "fp")])
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")))]
2301 [(set_attr "type" "fp")])
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")))]
2309 [(set_attr "type" "fp")])
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")))]
2317 [(set_attr "type" "fp")])
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")))]
2325 [(set_attr "type" "fp")])
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")))]
2333 [(set_attr "type" "fp")])
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")))]
2341 [(set_attr "type" "fpmul")])
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")))]
2349 [(set_attr "type" "fpmul")])
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")))]
2357 [(set_attr "type" "fpmul")])
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")))]
2365 [(set_attr "type" "fpdiv")])
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")))]
2373 [(set_attr "type" "fpdiv")])
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")))]
2381 [(set_attr "type" "fpdiv")])
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")))]
2389 fnegs %
1,%
0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2390 [(set_attr "type" "fp")
2391 (set_attr "length" "
1,
4")])
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")))]
2399 fnegs %
1,%
0\;fmovs %R1,%R0"
2400 [(set_attr "type" "fp")
2401 (set_attr "length" "
1,
2")])
2403 (define_insn "negsf2"
2404 [(set (match_operand:SF
0 "register_operand" "=f")
2405 (neg:SF (match_operand:SF
1 "register_operand" "f")))]
2408 [(set_attr "type" "fp")])
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")))]
2416 fabss %
1,%
0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
2417 [(set_attr "type" "fp")
2418 (set_attr "length" "
1,
4")])
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")))]
2426 fabss %
1,%
0\;fmovs %R1,%R0"
2427 [(set_attr "type" "fp")
2428 (set_attr "length" "
1,
2")])
2430 (define_insn "abssf2"
2431 [(set (match_operand:SF
0 "register_operand" "=f")
2432 (abs:SF (match_operand:SF
1 "register_operand" "f")))]
2435 [(set_attr "type" "fp")])
2437 (define_insn "sqrttf2"
2438 [(set (match_operand:TF
0 "register_operand" "=f")
2439 (sqrt:TF (match_operand:TF
1 "register_operand" "f")))]
2442 [(set_attr "type" "fpsqrt")])
2444 (define_insn "sqrtdf2"
2445 [(set (match_operand:DF
0 "register_operand" "=f")
2446 (sqrt:DF (match_operand:DF
1 "register_operand" "f")))]
2449 [(set_attr "type" "fpsqrt")])
2451 (define_insn "sqrtsf2"
2452 [(set (match_operand:SF
0 "register_operand" "=f")
2453 (sqrt:SF (match_operand:SF
1 "register_operand" "f")))]
2456 [(set_attr "type" "fpsqrt")])
2458 ;;- arithmetic shift instructions
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))])]
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)
2479 ;; ??? Questionable, we can do better than this can't we?
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))]
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")])
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")))]
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")))]
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")))]
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.
2516 [(set (pc) (label_ref (match_operand
0 "" "")))]
2519 [(set_attr "type" "branch")])
2521 (define_expand "tablejump"
2522 [(parallel [(set (pc) (match_operand:SI
0 "register_operand" "r"))
2523 (use (label_ref (match_operand
1 "" "")))])]
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. */
2531 emit_insn (gen_pic_tablejump (operands[
0], operands[
1]));
2536 (define_insn "pic_tablejump"
2537 [(set (pc) (match_operand:SI
0 "register_operand" "r"))
2538 (use (label_ref (match_operand
1 "" "")))
2542 [(set_attr "type" "branch")])
2545 [(set (pc) (match_operand:SI
0 "address_operand" "p"))
2546 (use (label_ref (match_operand
1 "" "")))]
2549 [(set_attr "type" "branch")])
2552 [(set (pc) (label_ref (match_operand
0 "" "")))
2553 (set (reg:SI
15) (label_ref (match_dup
0)))]
2556 [(set_attr "type" "branch")])
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.
2562 ; [(match_operand:SI
0 "immediate_operand" "")]
2563 ; "GET_CODE (operands[
0]) == CONST_INT && INTVAL (operands[
0]) >
0"
2565 ; [(set_attr "type" "marker")])
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.
2578 rtx fn_rtx, nregs_rtx;
2580 if (GET_CODE (XEXP (operands[
0],
0)) == LABEL_REF)
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.
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? */
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)),
2594 gen_rtx (CLOBBER, VOIDmode,
2595 gen_rtx (REG, SImode,
15)))));
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)))));
2605 fn_rtx = operands[
0];
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. */
2612 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[
2]) -
8);
2614 nregs_rtx = gen_rtx (CONST_INT, VOIDmode,
6);
2616 nregs_rtx = const0_rtx;
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),
2623 gen_rtx (CLOBBER, VOIDmode,
2624 gen_rtx (REG, SImode,
15)))));
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)))));
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)
2637 rtx insn = emit_insn (operands[
3]);
2638 SCHED_GROUP_P (insn) =
1;
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.
2653 return
\"call %a0,%
1%#
\";
2655 [(set_attr "type" "call")])
2657 ;; This is a call that wants a structure value.
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"
2667 return
\"call %a0,%
1\;nop\;unimp %
2\";
2669 [(set_attr "type" "call_no_delay_slot")])
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
2679 rtx fn_rtx, nregs_rtx;
2682 fn_rtx = operands[
1];
2686 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[
3]) -
8);
2688 nregs_rtx = gen_rtx (CONST_INT, VOIDmode,
6);
2690 nregs_rtx = const0_rtx;
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)));
2698 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
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.
2712 return
\"call %a1,%
2%#
\";
2714 [(set_attr "type" "call")])
2716 (define_insn "return"
2719 "* return output_return (operands);"
2720 [(set_attr "type" "multi")])
2727 (define_insn "indirect_jump"
2728 [(set (pc) (match_operand:SI
0 "address_operand" "p"))]
2731 [(set_attr "type" "branch")])
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 "" "")]
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
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));
2769 ;; Special trap insn to flush register windows.
2771 [(unspec_volatile [(const_int
0)]
0)]
2774 [(set_attr "type" "misc")])
2777 [(unspec_volatile [(const_int
0)]
1)]
2779 "jmp %%o0+
0\;restore"
2780 [(set_attr "type" "misc")
2781 (set_attr "length" "
2")])
2783 ;; Split up troublesome insns for better scheduling. */
2785 ;; The following patterns are straightforward. They can be applied
2786 ;; either before or after register allocation.
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" ""))]
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))])
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" ""))]
2804 [(set (match_op_dup
0 [(match_dup
1)])
2808 operands[
1] = legitimize_pic_address (operands[
1], GET_MODE (operands[
0]),
2813 [(set (match_operand
0 "register_operand" "")
2814 (match_operator
1 "memop"
2815 [(match_operand:SI
2 "immediate_operand" "")]))]
2818 (match_op_dup
1 [(match_dup
2)]))]
2821 operands[
2] = legitimize_pic_address (operands[
2], GET_MODE (operands[
1]),
2825 ;; Sign- and Zero-extend operations can have symbolic memory operands.
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" "")])]))]
2834 (match_op_dup
1 [(match_op_dup
2 [(match_dup
3)])]))]
2837 operands[
3] = legitimize_pic_address (operands[
3], GET_MODE (operands[
2]),
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)))
2849 (lo_sum:SI (match_dup
0) (match_dup
1)))]
2852 ;; LABEL_REFs are not modified by
`legitimize_pic_address`
2853 ;; so do not recurse infinitely in the PIC case.
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))]
2862 operands[
1] = legitimize_pic_address (operands[
1], Pmode, operands[
0],
0);
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.
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))]
2874 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2876 (set (match_dup
0) (ltu:SI (reg:CC
0) (const_int
0)))]
2880 [(set (match_operand:SI
0 "register_operand" "")
2881 (neg:SI (ne:SI (match_operand:SI
1 "register_operand" "")
2883 (clobber (reg:CC
0))]
2885 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2887 (set (match_dup
0) (neg:SI (ltu:SI (reg:CC
0) (const_int
0))))]
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))]
2895 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2897 (set (match_dup
0) (geu:SI (reg:CC
0) (const_int
0)))]
2901 [(set (match_operand:SI
0 "register_operand" "")
2902 (neg:SI (eq:SI (match_operand:SI
1 "register_operand" "")
2904 (clobber (reg:CC
0))]
2906 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2908 (set (match_dup
0) (neg:SI (geu:SI (reg:CC
0) (const_int
0))))]
2912 [(set (match_operand:SI
0 "register_operand" "")
2913 (plus:SI (ne:SI (match_operand:SI
1 "register_operand" "")
2915 (match_operand:SI
2 "register_operand" "")))
2916 (clobber (reg:CC
0))]
2918 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2920 (set (match_dup
0) (plus:SI (ltu:SI (reg:CC
0) (const_int
0))
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" "")
2929 (clobber (reg:CC
0))]
2931 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2933 (set (match_dup
0) (minus:SI (match_dup
2)
2934 (ltu:SI (reg:CC
0) (const_int
0))))]
2938 [(set (match_operand:SI
0 "register_operand" "")
2939 (plus:SI (eq:SI (match_operand:SI
1 "register_operand" "")
2941 (match_operand:SI
2 "register_operand" "")))
2942 (clobber (reg:CC
0))]
2944 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2946 (set (match_dup
0) (plus:SI (geu:SI (reg:CC
0) (const_int
0))
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" "")
2955 (clobber (reg:CC
0))]
2957 [(set (reg:CC_NOOV
0) (compare:CC_NOOV (neg:SI (match_dup
1))
2959 (set (match_dup
0) (minus:SI (match_dup
2)
2960 (geu:SI (reg:CC
0) (const_int
0))))]
2963 ;; Peepholes go at the end.
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.
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))"
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))"
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))"
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))"
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))"
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))"
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))"
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))"
3049 ;; Optimize the case of following a reg-reg move with a test
3050 ;; of reg just moved.
3053 [(set (match_operand:SI
0 "register_operand" "=r")
3054 (match_operand:SI
1 "register_operand" "r"))
3056 (compare:CC (match_operand:SI
2 "register_operand" "r")
3058 "rtx_equal_p (operands[
2], operands[
0])
3059 || rtx_equal_p (operands[
2], operands[
1])"
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?
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)))
3072 (compare:CC (match_dup
2)
3075 "ldsh %
1,%
0\;orcc %
0,%%g0,%
2")
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)))
3083 (compare:CC (match_dup
2)
3086 "ldsb %
1,%
0\;orcc %
0,%%g0,%
2")
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])"
3096 warning (
\"bad peephole
\");
3097 if (! MEM_VOLATILE_P (operands[
1]))
3099 return
\"ldsh %
1,%
2\";
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])"
3110 warning (
\"bad peephole
\");
3111 if (! MEM_VOLATILE_P (operands[
1]))
3113 return
\"ldsb %
1,%
2\";
3116 ;; Floating-point move peepholes
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)"
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);
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")
3144 ;; Return peepholes. First the "normal" ones
3147 [(set (match_operand:SI
0 "restore_operand" "")
3148 (match_operand:SI
1 "arith_operand" "rI"))
3153 if (current_function_returns_struct)
3154 return
\"jmp %%i7+
12\;restore %%g0,%
1,%Y0
\";
3156 return
\"ret\;restore %%g0,%
1,%Y0
\";
3158 [(set_attr "type" "multi")])
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")))
3168 if (current_function_returns_struct)
3169 return
\"jmp %%i7+
12\;restore %r1,%
2,%Y0
\";
3171 return
\"ret\;restore %r1,%
2,%Y0
\";
3173 [(set_attr "type" "multi")])
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).
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")))
3183 ;; "! TARGET_EPILOGUE"
3184 ;; "ret\;restore %
1,-(%
2),%Y0"
3185 ;; [(set_attr "type" "multi")])
3187 ;; The following pattern is only generated by delayed-branch scheduling,
3188 ;; when the insn winds up in the epilogue.
3191 (match_operand:SF
0 "register_operand" "f"))
3194 "ret\;fmovs %
0,%%f0"
3195 [(set_attr "type" "multi")])
3197 ;; Now peepholes to go a call followed by a jump.
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]))"
3208 return
\"call %a1,%
2\;add %%o7,(%l3-.-
4),%%o7
\";
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]))"
3219 return
\"call %a0,%
1\;add %%o7,(%l2-.-
4),%%o7
\";
3223 [(parallel [(set (match_operand:SI
0 "register_operand" "=r")
3224 (minus:SI (match_operand:SI
1 "reg_or_0_operand" "rJ")
3226 (clobber (reg:CC
0))])
3227 (set (reg:CC
0) (compare (match_dup
0) (const_int
0)))]
3231 ;;- Local variables:
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 ?} "){")