1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92-96, 1997 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
27 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
28 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
29 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
30 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
32 ;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to
33 ;; test TARGET_LIVE_G0 if we have TARGET_ARCH64.
35 ;; Attribute for cpu type.
36 ;; These must match the values for enum processor_type in sparc.h.
37 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v8plus,v9,ultrasparc"
38 (const (symbol_ref "sparc_cpu_attr")))
40 ;; Attribute for the instruction set.
41 ;; At present we only need to distinguish v9/!v9, but for clarity we
42 ;; test TARGET_V8 too.
43 (define_attr "isa" "v6,v8,v9,sparclet"
45 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
46 (symbol_ref "TARGET_V8") (const_string "v8")
47 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
48 (const_string "v6"))))
51 (define_attr "arch" "arch32bit,arch64bit"
53 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
54 (const_string "arch32bit"))))
56 ;; Whether -mlive-g0 is in effect.
57 (define_attr "live_g0" "no,yes"
59 (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")]
60 (const_string "no"))))
62 ;; Insn type. Used to default other attribute values.
64 ;; type "unary" insns have one input operand (1) and one output operand (0)
65 ;; type "binary" insns have two input operands (1,2) and one output (0)
66 ;; type "compare" insns have one or two input operands (0,1) and no output
67 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
70 "move,unary,binary,compare,load,sload,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,address,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"
71 (const_string "binary"))
73 ;; Set true if insn uses call-clobbered intermediate register.
74 (define_attr "use_clobbered" "false,true"
75 (if_then_else (and (eq_attr "type" "address")
76 (match_operand 0 "clobbered_register" ""))
78 (const_string "false")))
80 ;; Length (in # of insns).
81 (define_attr "length" ""
82 (cond [(eq_attr "type" "load,sload,fpload")
83 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
84 (const_int 2) (const_int 1))
86 (eq_attr "type" "store,fpstore")
87 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
88 (const_int 2) (const_int 1))
90 (eq_attr "type" "address") (const_int 2)
92 (eq_attr "type" "binary")
93 (if_then_else (ior (match_operand 2 "arith_operand" "")
94 (match_operand 2 "arith_double_operand" ""))
95 (const_int 1) (const_int 3))
97 (eq_attr "type" "multi") (const_int 2)
99 (eq_attr "type" "move,unary")
100 (if_then_else (ior (match_operand 1 "arith_operand" "")
101 (match_operand 1 "arith_double_operand" ""))
102 (const_int 1) (const_int 2))]
106 (define_asm_attributes
107 [(set_attr "length" "1")
108 (set_attr "type" "multi")])
110 ;; Attributes for instruction and branch scheduling
112 (define_attr "in_call_delay" "false,true"
113 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
114 (const_string "false")
115 (eq_attr "type" "load,fpload,store,fpstore")
116 (if_then_else (eq_attr "length" "1")
117 (const_string "true")
118 (const_string "false"))
119 (eq_attr "type" "address")
120 (if_then_else (eq_attr "use_clobbered" "false")
121 (const_string "true")
122 (const_string "false"))]
123 (if_then_else (eq_attr "length" "1")
124 (const_string "true")
125 (const_string "false"))))
127 (define_delay (eq_attr "type" "call")
128 [(eq_attr "in_call_delay" "true") (nil) (nil)])
130 ;; ??? Should implement the notion of predelay slots for floating point
131 ;; branches. This would allow us to remove the nop always inserted before
132 ;; a floating point branch.
134 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
135 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
136 ;; This is because doing so will add several pipeline stalls to the path
137 ;; that the load/store did not come from. Unfortunately, there is no way
138 ;; to prevent fill_eager_delay_slots from using load/store without completely
139 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
140 ;; because it prevents us from moving back the final store of inner loops.
142 (define_attr "in_branch_delay" "false,true"
143 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
144 (eq_attr "length" "1"))
145 (const_string "true")
146 (const_string "false")))
148 (define_attr "in_uncond_branch_delay" "false,true"
149 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
150 (eq_attr "length" "1"))
151 (const_string "true")
152 (const_string "false")))
154 (define_attr "in_annul_branch_delay" "false,true"
155 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
156 (eq_attr "length" "1"))
157 (const_string "true")
158 (const_string "false")))
160 (define_delay (eq_attr "type" "branch")
161 [(eq_attr "in_branch_delay" "true")
162 (nil) (eq_attr "in_annul_branch_delay" "true")])
164 (define_delay (eq_attr "type" "uncond_branch")
165 [(eq_attr "in_uncond_branch_delay" "true")
168 ;; Function units of the SPARC
170 ;; (define_function_unit {name} {num-units} {n-users} {test}
171 ;; {ready-delay} {issue-delay} [{conflict-list}])
174 ;; (Noted only for documentation; units that take one cycle do not need to
177 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
180 ;; (define_function_unit "alu" 1 0
181 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
183 ;; ---- cypress CY7C602 scheduling:
184 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
186 (define_function_unit "memory" 1 0
187 (and (eq_attr "cpu" "cypress")
188 (eq_attr "type" "load,sload,fpload"))
191 ;; SPARC has two floating-point units: the FP ALU,
192 ;; and the FP MUL/DIV/SQRT unit.
193 ;; Instruction timings on the CY7C602 are as follows
207 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
208 ;; More insns cause the chip to stall.
210 (define_function_unit "fp_alu" 1 0
211 (and (eq_attr "cpu" "cypress")
212 (eq_attr "type" "fp,fpmove"))
215 (define_function_unit "fp_mds" 1 0
216 (and (eq_attr "cpu" "cypress")
217 (eq_attr "type" "fpmul"))
220 (define_function_unit "fp_mds" 1 0
221 (and (eq_attr "cpu" "cypress")
222 (eq_attr "type" "fpdivs,fpdivd"))
225 (define_function_unit "fp_mds" 1 0
226 (and (eq_attr "cpu" "cypress")
227 (eq_attr "type" "fpsqrt"))
230 ;; ----- The TMS390Z55 scheduling
231 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
232 ;; one ld/st, one fp.
233 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
235 (define_function_unit "memory" 1 0
236 (and (eq_attr "cpu" "supersparc")
237 (eq_attr "type" "load,sload"))
240 (define_function_unit "memory" 1 0
241 (and (eq_attr "cpu" "supersparc")
242 (eq_attr "type" "fpload"))
245 (define_function_unit "memory" 1 0
246 (and (eq_attr "cpu" "supersparc")
247 (eq_attr "type" "store,fpstore"))
250 (define_function_unit "shift" 1 0
251 (and (eq_attr "cpu" "supersparc")
252 (eq_attr "type" "shift"))
255 ;; There are only two write ports to the integer register file
256 ;; A store also uses a write port
258 (define_function_unit "iwport" 2 0
259 (and (eq_attr "cpu" "supersparc")
260 (eq_attr "type" "load,sload,store,shift,ialu"))
263 ;; Timings; throughput/latency
264 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
272 (define_function_unit "fp_alu" 1 0
273 (and (eq_attr "cpu" "supersparc")
274 (eq_attr "type" "fp,fpmove,fpcmp"))
277 (define_function_unit "fp_mds" 1 0
278 (and (eq_attr "cpu" "supersparc")
279 (eq_attr "type" "fpmul"))
282 (define_function_unit "fp_mds" 1 0
283 (and (eq_attr "cpu" "supersparc")
284 (eq_attr "type" "fpdivs"))
287 (define_function_unit "fp_mds" 1 0
288 (and (eq_attr "cpu" "supersparc")
289 (eq_attr "type" "fpdivd"))
292 (define_function_unit "fp_mds" 1 0
293 (and (eq_attr "cpu" "supersparc")
294 (eq_attr "type" "fpsqrt"))
297 (define_function_unit "fp_mds" 1 0
298 (and (eq_attr "cpu" "supersparc")
299 (eq_attr "type" "imul"))
302 ;; ----- sparclet tsc701 scheduling
303 ;; The tsc701 issues 1 insn per cycle.
304 ;; Results may be written back out of order.
306 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
308 (define_function_unit "tsc701_load" 4 1
309 (and (eq_attr "cpu" "tsc701")
310 (eq_attr "type" "load,sload"))
313 ;; Stores take 2(?) extra cycles to complete.
314 ;; It is desirable to not have any memory operation in the following 2 cycles.
315 ;; (??? or 2 memory ops in the case of std).
317 (define_function_unit "tsc701_store" 1 0
318 (and (eq_attr "cpu" "tsc701")
319 (eq_attr "type" "store"))
321 [(eq_attr "type" "load,sload,store")])
323 ;; The multiply unit has a latency of 5.
324 (define_function_unit "tsc701_mul" 1 0
325 (and (eq_attr "cpu" "tsc701")
326 (eq_attr "type" "imul"))
329 ;; ----- The UltraSPARC-1 scheduling
330 ;; UltraSPARC has two integer units. Shift instructions can only execute
331 ;; on IE0. Condition code setting instructions, call, and jmpl (including
332 ;; the ret and retl pseudo-instructions) can only execute on IE1.
333 ;; Branch on register uses IE1, but branch on condition code does not.
334 ;; Conditional moves take 2 cycles. No other instruction can issue in the
335 ;; same cycle as a conditional move.
336 ;; Multiply and divide take many cycles during which no other instructions
338 ;; Memory delivers its result in two cycles (except for signed loads,
339 ;; which take one cycle more). One memory instruction can be issued per
342 (define_function_unit "memory" 1 0
343 (and (eq_attr "cpu" "ultrasparc")
344 (eq_attr "type" "load,fpload"))
347 (define_function_unit "memory" 1 0
348 (and (eq_attr "cpu" "ultrasparc")
349 (eq_attr "type" "sload"))
352 (define_function_unit "memory" 1 0
353 (and (eq_attr "cpu" "ultrasparc")
354 (eq_attr "type" "store,fpstore"))
357 (define_function_unit "ieu" 1 0
358 (and (eq_attr "cpu" "ultrasparc")
359 (eq_attr "type" "ialu,shift,compare,cmove,call"))
362 (define_function_unit "ieu_shift" 1 0
363 (and (eq_attr "cpu" "ultrasparc")
364 (eq_attr "type" "shift"))
367 (define_function_unit "ieu_shift" 1 0
368 (and (eq_attr "cpu" "ultrasparc")
369 (eq_attr "type" "cmove"))
372 ;; Timings; throughput/latency
373 ;; ?? FADD 1/3 add/sub, format conv, compar, abs, neg
380 (define_function_unit "fadd" 1 0
381 (and (eq_attr "cpu" "ultrasparc")
382 (eq_attr "type" "fpmove"))
385 (define_function_unit "fadd" 1 0
386 (and (eq_attr "cpu" "ultrasparc")
387 (eq_attr "type" "fpcmove"))
390 (define_function_unit "fadd" 1 0
391 (and (eq_attr "cpu" "ultrasparc")
392 (eq_attr "type" "fp"))
395 (define_function_unit "fadd" 1 0
396 (and (eq_attr "cpu" "ultrasparc")
397 (eq_attr "type" "fpcmp"))
400 (define_function_unit "fmul" 1 0
401 (and (eq_attr "cpu" "ultrasparc")
402 (eq_attr "type" "fpmul"))
405 (define_function_unit "fadd" 1 0
406 (and (eq_attr "cpu" "ultrasparc")
407 (eq_attr "type" "fpcmove"))
410 (define_function_unit "fadd" 1 0
411 (and (eq_attr "cpu" "ultrasparc")
412 (eq_attr "type" "fpdivs"))
415 (define_function_unit "fadd" 1 0
416 (and (eq_attr "cpu" "ultrasparc")
417 (eq_attr "type" "fpdivd"))
420 (define_function_unit "fadd" 1 0
421 (and (eq_attr "cpu" "ultrasparc")
422 (eq_attr "type" "fpsqrt"))
425 ;; Compare instructions.
426 ;; This controls RTL generation and register allocation.
428 ;; We generate RTL for comparisons and branches by having the cmpxx
429 ;; patterns store away the operands. Then, the scc and bcc patterns
430 ;; emit RTL for both the compare and the branch.
432 ;; We do this because we want to generate different code for an sne and
433 ;; seq insn. In those cases, if the second operand of the compare is not
434 ;; const0_rtx, we want to compute the xor of the two operands and test
437 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
438 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
439 ;; insns that actually require more than one machine instruction.
441 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
443 (define_expand "cmpsi"
445 (compare:CC (match_operand:SI 0 "register_operand" "")
446 (match_operand:SI 1 "arith_operand" "")))]
450 sparc_compare_op0 = operands[0];
451 sparc_compare_op1 = operands[1];
455 (define_expand "cmpdi"
457 (compare:CCX (match_operand:DI 0 "register_operand" "")
458 (match_operand:DI 1 "arith_double_operand" "")))]
462 sparc_compare_op0 = operands[0];
463 sparc_compare_op1 = operands[1];
467 (define_expand "cmpsf"
468 ;; The 96 here isn't ever used by anyone.
470 (compare:CCFP (match_operand:SF 0 "register_operand" "")
471 (match_operand:SF 1 "register_operand" "")))]
475 sparc_compare_op0 = operands[0];
476 sparc_compare_op1 = operands[1];
480 (define_expand "cmpdf"
481 ;; The 96 here isn't ever used by anyone.
483 (compare:CCFP (match_operand:DF 0 "register_operand" "")
484 (match_operand:DF 1 "register_operand" "")))]
488 sparc_compare_op0 = operands[0];
489 sparc_compare_op1 = operands[1];
493 (define_expand "cmptf"
494 ;; The 96 here isn't ever used by anyone.
496 (compare:CCFP (match_operand:TF 0 "register_operand" "")
497 (match_operand:TF 1 "register_operand" "")))]
501 sparc_compare_op0 = operands[0];
502 sparc_compare_op1 = operands[1];
506 ;; Now the compare DEFINE_INSNs.
508 (define_insn "*cmpsi_insn"
510 (compare:CC (match_operand:SI 0 "register_operand" "r")
511 (match_operand:SI 1 "arith_operand" "rI")))]
514 [(set_attr "type" "compare")])
516 (define_insn "*cmpdi_sp64"
518 (compare:CCX (match_operand:DI 0 "register_operand" "r")
519 (match_operand:DI 1 "arith_double_operand" "rHI")))]
522 [(set_attr "type" "compare")])
524 (define_insn "*cmpsf_fpe"
525 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
526 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
527 (match_operand:SF 2 "register_operand" "f")))]
532 return \"fcmpes %0,%1,%2\";
533 return \"fcmpes %1,%2\";
535 [(set_attr "type" "fpcmp")])
537 (define_insn "*cmpdf_fpe"
538 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
539 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
540 (match_operand:DF 2 "register_operand" "e")))]
545 return \"fcmped %0,%1,%2\";
546 return \"fcmped %1,%2\";
548 [(set_attr "type" "fpcmp")])
550 (define_insn "*cmptf_fpe"
551 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
552 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
553 (match_operand:TF 2 "register_operand" "e")))]
554 "TARGET_FPU && TARGET_HARD_QUAD"
558 return \"fcmpeq %0,%1,%2\";
559 return \"fcmpeq %1,%2\";
561 [(set_attr "type" "fpcmp")])
563 (define_insn "*cmpsf_fp"
564 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
565 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
566 (match_operand:SF 2 "register_operand" "f")))]
571 return \"fcmps %0,%1,%2\";
572 return \"fcmps %1,%2\";
574 [(set_attr "type" "fpcmp")])
576 (define_insn "*cmpdf_fp"
577 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
578 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
579 (match_operand:DF 2 "register_operand" "e")))]
584 return \"fcmpd %0,%1,%2\";
585 return \"fcmpd %1,%2\";
587 [(set_attr "type" "fpcmp")])
589 (define_insn "*cmptf_fp"
590 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
591 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
592 (match_operand:TF 2 "register_operand" "e")))]
593 "TARGET_FPU && TARGET_HARD_QUAD"
597 return \"fcmpq %0,%1,%2\";
598 return \"fcmpq %1,%2\";
600 [(set_attr "type" "fpcmp")])
602 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
603 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
604 ;; the same code as v8 (the addx/subx method has more applications). The
605 ;; exception to this is "reg != 0" which can be done in one instruction on v9
606 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
609 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
610 ;; generate addcc/subcc instructions.
612 (define_expand "seqsi_special"
614 (xor:SI (match_operand:SI 1 "register_operand" "")
615 (match_operand:SI 2 "register_operand" "")))
616 (parallel [(set (match_operand:SI 0 "register_operand" "")
617 (eq:SI (match_dup 3) (const_int 0)))
618 (clobber (reg:CC 100))])]
620 "{ operands[3] = gen_reg_rtx (SImode); }")
622 (define_expand "seqdi_special"
624 (xor:DI (match_operand:DI 1 "register_operand" "")
625 (match_operand:DI 2 "register_operand" "")))
626 (set (match_operand:DI 0 "register_operand" "")
627 (eq:DI (match_dup 3) (const_int 0)))]
629 "{ operands[3] = gen_reg_rtx (DImode); }")
631 (define_expand "snesi_special"
633 (xor:SI (match_operand:SI 1 "register_operand" "")
634 (match_operand:SI 2 "register_operand" "")))
635 (parallel [(set (match_operand:SI 0 "register_operand" "")
636 (ne:SI (match_dup 3) (const_int 0)))
637 (clobber (reg:CC 100))])]
639 "{ operands[3] = gen_reg_rtx (SImode); }")
641 (define_expand "snedi_special"
643 (xor:DI (match_operand:DI 1 "register_operand" "")
644 (match_operand:DI 2 "register_operand" "")))
645 (set (match_operand:DI 0 "register_operand" "")
646 (ne:DI (match_dup 3) (const_int 0)))]
648 "{ operands[3] = gen_reg_rtx (DImode); }")
650 (define_expand "seqdi_special_trunc"
652 (xor:DI (match_operand:DI 1 "register_operand" "")
653 (match_operand:DI 2 "register_operand" "")))
654 (set (match_operand:SI 0 "register_operand" "")
655 (eq:DI (match_dup 3) (const_int 0)))]
657 "{ operands[3] = gen_reg_rtx (DImode); }")
659 (define_expand "snedi_special_trunc"
661 (xor:DI (match_operand:DI 1 "register_operand" "")
662 (match_operand:DI 2 "register_operand" "")))
663 (set (match_operand:SI 0 "register_operand" "")
664 (ne:DI (match_dup 3) (const_int 0)))]
666 "{ operands[3] = gen_reg_rtx (DImode); }")
668 (define_expand "seqsi_special_extend"
670 (xor:SI (match_operand:SI 1 "register_operand" "")
671 (match_operand:SI 2 "register_operand" "")))
672 (parallel [(set (match_operand:DI 0 "register_operand" "")
673 (eq:SI (match_dup 3) (const_int 0)))
674 (clobber (reg:CC 100))])]
676 "{ operands[3] = gen_reg_rtx (SImode); }")
678 (define_expand "snesi_special_extend"
680 (xor:SI (match_operand:SI 1 "register_operand" "")
681 (match_operand:SI 2 "register_operand" "")))
682 (parallel [(set (match_operand:DI 0 "register_operand" "")
683 (ne:SI (match_dup 3) (const_int 0)))
684 (clobber (reg:CC 100))])]
686 "{ operands[3] = gen_reg_rtx (SImode); }")
688 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
689 ;; However, the code handles both SImode and DImode.
691 [(set (match_operand:SI 0 "intreg_operand" "")
692 (eq:SI (match_dup 1) (const_int 0)))]
696 if (GET_MODE (sparc_compare_op0) == SImode)
700 if (GET_MODE (operands[0]) == SImode)
701 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
703 else if (! TARGET_ARCH64)
706 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
711 else if (GET_MODE (sparc_compare_op0) == DImode)
717 else if (GET_MODE (operands[0]) == SImode)
718 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
721 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
726 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
728 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
729 emit_insn (gen_sne (operands[0]));
734 if (gen_v9_scc (EQ, operands))
738 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
741 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
742 ;; However, the code handles both SImode and DImode.
744 [(set (match_operand:SI 0 "intreg_operand" "")
745 (ne:SI (match_dup 1) (const_int 0)))]
749 if (GET_MODE (sparc_compare_op0) == SImode)
753 if (GET_MODE (operands[0]) == SImode)
754 pat = gen_snesi_special (operands[0], sparc_compare_op0,
756 else if (! TARGET_ARCH64)
759 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
764 else if (GET_MODE (sparc_compare_op0) == DImode)
770 else if (GET_MODE (operands[0]) == SImode)
771 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
774 pat = gen_snedi_special (operands[0], sparc_compare_op0,
779 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
781 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
782 emit_insn (gen_sne (operands[0]));
787 if (gen_v9_scc (NE, operands))
791 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
795 [(set (match_operand:SI 0 "intreg_operand" "")
796 (gt:SI (match_dup 1) (const_int 0)))]
800 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
802 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
803 emit_insn (gen_sne (operands[0]));
808 if (gen_v9_scc (GT, operands))
812 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
816 [(set (match_operand:SI 0 "intreg_operand" "")
817 (lt:SI (match_dup 1) (const_int 0)))]
821 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
823 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
824 emit_insn (gen_sne (operands[0]));
829 if (gen_v9_scc (LT, operands))
833 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
837 [(set (match_operand:SI 0 "intreg_operand" "")
838 (ge:SI (match_dup 1) (const_int 0)))]
842 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
844 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
845 emit_insn (gen_sne (operands[0]));
850 if (gen_v9_scc (GE, operands))
854 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
858 [(set (match_operand:SI 0 "intreg_operand" "")
859 (le:SI (match_dup 1) (const_int 0)))]
863 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
865 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
866 emit_insn (gen_sne (operands[0]));
871 if (gen_v9_scc (LE, operands))
875 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
878 (define_expand "sgtu"
879 [(set (match_operand:SI 0 "intreg_operand" "")
880 (gtu:SI (match_dup 1) (const_int 0)))]
888 /* We can do ltu easily, so if both operands are registers, swap them and
890 if ((GET_CODE (sparc_compare_op0) == REG
891 || GET_CODE (sparc_compare_op0) == SUBREG)
892 && (GET_CODE (sparc_compare_op1) == REG
893 || GET_CODE (sparc_compare_op1) == SUBREG))
895 tem = sparc_compare_op0;
896 sparc_compare_op0 = sparc_compare_op1;
897 sparc_compare_op1 = tem;
898 emit_insn (gen_sltu (operands[0]));
904 if (gen_v9_scc (GTU, operands))
907 operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
910 (define_expand "sltu"
911 [(set (match_operand:SI 0 "intreg_operand" "")
912 (ltu:SI (match_dup 1) (const_int 0)))]
918 if (gen_v9_scc (LTU, operands))
921 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
924 (define_expand "sgeu"
925 [(set (match_operand:SI 0 "intreg_operand" "")
926 (geu:SI (match_dup 1) (const_int 0)))]
932 if (gen_v9_scc (GEU, operands))
935 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
938 (define_expand "sleu"
939 [(set (match_operand:SI 0 "intreg_operand" "")
940 (leu:SI (match_dup 1) (const_int 0)))]
948 /* We can do geu easily, so if both operands are registers, swap them and
950 if ((GET_CODE (sparc_compare_op0) == REG
951 || GET_CODE (sparc_compare_op0) == SUBREG)
952 && (GET_CODE (sparc_compare_op1) == REG
953 || GET_CODE (sparc_compare_op1) == SUBREG))
955 tem = sparc_compare_op0;
956 sparc_compare_op0 = sparc_compare_op1;
957 sparc_compare_op1 = tem;
958 emit_insn (gen_sgeu (operands[0]));
964 if (gen_v9_scc (LEU, operands))
967 operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
970 ;; Now the DEFINE_INSNs for the scc cases.
972 ;; The SEQ and SNE patterns are special because they can be done
973 ;; without any branching and do not involve a COMPARE.
975 (define_insn "*snesi_zero"
976 [(set (match_operand:SI 0 "register_operand" "=r")
977 (ne:SI (match_operand:SI 1 "register_operand" "r")
979 (clobber (reg:CC 100))]
981 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
982 [(set_attr "type" "unary")
983 (set_attr "length" "2")])
985 (define_insn "*neg_snesi_zero"
986 [(set (match_operand:SI 0 "register_operand" "=r")
987 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
989 (clobber (reg:CC 100))]
991 "subcc %%g0,%1,%%g0\;subx %%g0,0,%0"
992 [(set_attr "type" "unary")
993 (set_attr "length" "2")])
995 (define_insn "*snesi_zero_extend"
996 [(set (match_operand:DI 0 "register_operand" "=r")
997 (ne:SI (match_operand:SI 1 "register_operand" "r")
999 (clobber (reg:CC 100))]
1001 "subcc %%g0,%1,%%g0\;addx %%g0,0,%0"
1002 [(set_attr "type" "unary")
1003 (set_attr "length" "2")])
1005 (define_insn "*snedi_zero"
1006 [(set (match_operand:DI 0 "register_operand" "=&r")
1007 (ne:DI (match_operand:DI 1 "register_operand" "r")
1010 "mov 0,%0\;movrnz %1,1,%0"
1011 [(set_attr "type" "unary")
1012 (set_attr "length" "2")])
1014 (define_insn "*neg_snedi_zero"
1015 [(set (match_operand:DI 0 "register_operand" "=&r")
1016 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1019 "mov 0,%0\;movrnz %1,-1,%0"
1020 [(set_attr "type" "unary")
1021 (set_attr "length" "2")])
1023 (define_insn "*snedi_zero_trunc"
1024 [(set (match_operand:SI 0 "register_operand" "=&r")
1025 (ne:DI (match_operand:DI 1 "register_operand" "r")
1028 "mov 0,%0\;movrnz %1,1,%0"
1029 [(set_attr "type" "unary")
1030 (set_attr "length" "2")])
1032 (define_insn "*seqsi_zero"
1033 [(set (match_operand:SI 0 "register_operand" "=r")
1034 (eq:SI (match_operand:SI 1 "register_operand" "r")
1036 (clobber (reg:CC 100))]
1038 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
1039 [(set_attr "type" "unary")
1040 (set_attr "length" "2")])
1042 (define_insn "*neg_seqsi_zero"
1043 [(set (match_operand:SI 0 "register_operand" "=r")
1044 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1046 (clobber (reg:CC 100))]
1048 "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0"
1049 [(set_attr "type" "unary")
1050 (set_attr "length" "2")])
1052 (define_insn "*seqsi_zero_extend"
1053 [(set (match_operand:DI 0 "register_operand" "=r")
1054 (eq:SI (match_operand:SI 1 "register_operand" "r")
1056 (clobber (reg:CC 100))]
1058 "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0"
1059 [(set_attr "type" "unary")
1060 (set_attr "length" "2")])
1062 (define_insn "*seqdi_zero"
1063 [(set (match_operand:DI 0 "register_operand" "=&r")
1064 (eq:DI (match_operand:DI 1 "register_operand" "r")
1067 "mov 0,%0\;movrz %1,1,%0"
1068 [(set_attr "type" "unary")
1069 (set_attr "length" "2")])
1071 (define_insn "*neg_seqdi_zero"
1072 [(set (match_operand:DI 0 "register_operand" "=&r")
1073 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1076 "mov 0,%0\;movrz %1,-1,%0"
1077 [(set_attr "type" "unary")
1078 (set_attr "length" "2")])
1080 (define_insn "*seqdi_zero_trunc"
1081 [(set (match_operand:SI 0 "register_operand" "=&r")
1082 (eq:DI (match_operand:DI 1 "register_operand" "r")
1085 "mov 0,%0\;movrz %1,1,%0"
1086 [(set_attr "type" "unary")
1087 (set_attr "length" "2")])
1089 ;; We can also do (x + (i == 0)) and related, so put them in.
1090 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1093 (define_insn "*x_plus_i_ne_0"
1094 [(set (match_operand:SI 0 "register_operand" "=r")
1095 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1097 (match_operand:SI 2 "register_operand" "r")))
1098 (clobber (reg:CC 100))]
1100 "subcc %%g0,%1,%%g0\;addx %2,0,%0"
1101 [(set_attr "length" "2")])
1103 (define_insn "*x_minus_i_ne_0"
1104 [(set (match_operand:SI 0 "register_operand" "=r")
1105 (minus:SI (match_operand:SI 2 "register_operand" "r")
1106 (ne:SI (match_operand:SI 1 "register_operand" "r")
1108 (clobber (reg:CC 100))]
1110 "subcc %%g0,%1,%%g0\;subx %2,0,%0"
1111 [(set_attr "length" "2")])
1113 (define_insn "*x_plus_i_eq_0"
1114 [(set (match_operand:SI 0 "register_operand" "=r")
1115 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1117 (match_operand:SI 2 "register_operand" "r")))
1118 (clobber (reg:CC 100))]
1120 "subcc %%g0,%1,%%g0\;subx %2,-1,%0"
1121 [(set_attr "length" "2")])
1123 (define_insn "*x_minus_i_eq_0"
1124 [(set (match_operand:SI 0 "register_operand" "=r")
1125 (minus:SI (match_operand:SI 2 "register_operand" "r")
1126 (eq:SI (match_operand:SI 1 "register_operand" "r")
1128 (clobber (reg:CC 100))]
1130 "subcc %%g0,%1,%%g0\;addx %2,-1,%0"
1131 [(set_attr "length" "2")])
1133 ;; We can also do GEU and LTU directly, but these operate after a compare.
1134 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1137 (define_insn "*sltu_insn"
1138 [(set (match_operand:SI 0 "register_operand" "=r")
1139 (ltu:SI (reg:CC 100) (const_int 0)))]
1142 [(set_attr "type" "misc")])
1144 (define_insn "*neg_sltu_insn"
1145 [(set (match_operand:SI 0 "register_operand" "=r")
1146 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1149 [(set_attr "type" "misc")])
1151 ;; ??? Combine should canonicalize these next two to the same pattern.
1152 (define_insn "*neg_sltu_minus_x"
1153 [(set (match_operand:SI 0 "register_operand" "=r")
1154 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1155 (match_operand:SI 1 "arith_operand" "rI")))]
1158 [(set_attr "type" "unary")])
1160 (define_insn "*neg_sltu_plus_x"
1161 [(set (match_operand:SI 0 "register_operand" "=r")
1162 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1163 (match_operand:SI 1 "arith_operand" "rI"))))]
1166 [(set_attr "type" "unary")])
1168 (define_insn "*sgeu_insn"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (geu:SI (reg:CC 100) (const_int 0)))]
1173 [(set_attr "type" "misc")])
1175 (define_insn "*neg_sgeu_insn"
1176 [(set (match_operand:SI 0 "register_operand" "=r")
1177 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1180 [(set_attr "type" "misc")])
1182 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1183 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1186 (define_insn "*sltu_plus_x"
1187 [(set (match_operand:SI 0 "register_operand" "=r")
1188 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1189 (match_operand:SI 1 "arith_operand" "rI")))]
1192 [(set_attr "type" "unary")])
1194 (define_insn "*sltu_plus_x_plus_y"
1195 [(set (match_operand:SI 0 "register_operand" "=r")
1196 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1197 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1198 (match_operand:SI 2 "arith_operand" "rI"))))]
1202 (define_insn "*x_minus_sltu"
1203 [(set (match_operand:SI 0 "register_operand" "=r")
1204 (minus:SI (match_operand:SI 1 "register_operand" "r")
1205 (ltu:SI (reg:CC 100) (const_int 0))))]
1208 [(set_attr "type" "unary")])
1210 ;; ??? Combine should canonicalize these next two to the same pattern.
1211 (define_insn "*x_minus_y_minus_sltu"
1212 [(set (match_operand:SI 0 "register_operand" "=r")
1213 (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
1214 (match_operand:SI 2 "arith_operand" "rI"))
1215 (ltu:SI (reg:CC 100) (const_int 0))))]
1219 (define_insn "*x_minus_sltu_plus_y"
1220 [(set (match_operand:SI 0 "register_operand" "=r")
1221 (minus:SI (match_operand:SI 1 "register_operand" "r")
1222 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1223 (match_operand:SI 2 "arith_operand" "rI"))))]
1227 (define_insn "*sgeu_plus_x"
1228 [(set (match_operand:SI 0 "register_operand" "=r")
1229 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1230 (match_operand:SI 1 "register_operand" "r")))]
1233 [(set_attr "type" "unary")])
1235 (define_insn "*x_minus_sgeu"
1236 [(set (match_operand:SI 0 "register_operand" "=r")
1237 (minus:SI (match_operand:SI 1 "register_operand" "r")
1238 (geu:SI (reg:CC 100) (const_int 0))))]
1241 [(set_attr "type" "unary")])
1243 ;; Now we have the generic scc insns.
1244 ;; !v9: These will be done using a jump.
1245 ;; v9: Use conditional moves which are defined elsewhere.
1246 ;; We have to exclude the cases above, since we will not want combine to
1247 ;; turn something that does not require a jump into something that does.
1249 (define_insn "*scc_si"
1250 [(set (match_operand:SI 0 "register_operand" "=r")
1251 (match_operator:SI 2 "noov_compare_op"
1252 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1255 "* return output_scc_insn (operands, insn); "
1256 [(set_attr "type" "multi")
1257 (set_attr "length" "3")])
1259 (define_insn "*scc_di"
1260 [(set (match_operand:DI 0 "register_operand" "=r")
1261 (match_operator:DI 2 "noov_compare_op"
1262 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1265 "* return output_scc_insn (operands, insn); "
1266 [(set_attr "type" "multi")
1267 (set_attr "length" "3")])
1269 ;; These control RTL generation for conditional jump insns
1271 ;; The quad-word fp compare library routines all return nonzero to indicate
1272 ;; true, which is different from the equivalent libgcc routines, so we must
1273 ;; handle them specially here.
1275 (define_expand "beq"
1277 (if_then_else (eq (match_dup 1) (const_int 0))
1278 (label_ref (match_operand 0 "" ""))
1283 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1284 && GET_CODE (sparc_compare_op0) == REG
1285 && GET_MODE (sparc_compare_op0) == DImode)
1287 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1290 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1292 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1293 emit_jump_insn (gen_bne (operands[0]));
1296 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1299 (define_expand "bne"
1301 (if_then_else (ne (match_dup 1) (const_int 0))
1302 (label_ref (match_operand 0 "" ""))
1307 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1308 && GET_CODE (sparc_compare_op0) == REG
1309 && GET_MODE (sparc_compare_op0) == DImode)
1311 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1314 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1316 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1317 emit_jump_insn (gen_bne (operands[0]));
1320 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1323 (define_expand "bgt"
1325 (if_then_else (gt (match_dup 1) (const_int 0))
1326 (label_ref (match_operand 0 "" ""))
1331 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1332 && GET_CODE (sparc_compare_op0) == REG
1333 && GET_MODE (sparc_compare_op0) == DImode)
1335 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1338 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1340 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1341 emit_jump_insn (gen_bne (operands[0]));
1344 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1347 (define_expand "bgtu"
1349 (if_then_else (gtu (match_dup 1) (const_int 0))
1350 (label_ref (match_operand 0 "" ""))
1354 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1357 (define_expand "blt"
1359 (if_then_else (lt (match_dup 1) (const_int 0))
1360 (label_ref (match_operand 0 "" ""))
1365 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1366 && GET_CODE (sparc_compare_op0) == REG
1367 && GET_MODE (sparc_compare_op0) == DImode)
1369 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1372 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1374 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1375 emit_jump_insn (gen_bne (operands[0]));
1378 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1381 (define_expand "bltu"
1383 (if_then_else (ltu (match_dup 1) (const_int 0))
1384 (label_ref (match_operand 0 "" ""))
1388 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1391 (define_expand "bge"
1393 (if_then_else (ge (match_dup 1) (const_int 0))
1394 (label_ref (match_operand 0 "" ""))
1399 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1400 && GET_CODE (sparc_compare_op0) == REG
1401 && GET_MODE (sparc_compare_op0) == DImode)
1403 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1406 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1408 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1409 emit_jump_insn (gen_bne (operands[0]));
1412 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1415 (define_expand "bgeu"
1417 (if_then_else (geu (match_dup 1) (const_int 0))
1418 (label_ref (match_operand 0 "" ""))
1422 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1425 (define_expand "ble"
1427 (if_then_else (le (match_dup 1) (const_int 0))
1428 (label_ref (match_operand 0 "" ""))
1433 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1434 && GET_CODE (sparc_compare_op0) == REG
1435 && GET_MODE (sparc_compare_op0) == DImode)
1437 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1440 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1442 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1443 emit_jump_insn (gen_bne (operands[0]));
1446 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1449 (define_expand "bleu"
1451 (if_then_else (leu (match_dup 1) (const_int 0))
1452 (label_ref (match_operand 0 "" ""))
1456 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1459 ;; Now match both normal and inverted jump.
1461 (define_insn "*normal_branch"
1463 (if_then_else (match_operator 0 "noov_compare_op"
1464 [(reg 100) (const_int 0)])
1465 (label_ref (match_operand 1 "" ""))
1470 return output_cbranch (operands[0], 1, 0,
1471 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1474 [(set_attr "type" "branch")])
1476 (define_insn "*inverted_branch"
1478 (if_then_else (match_operator 0 "noov_compare_op"
1479 [(reg 100) (const_int 0)])
1481 (label_ref (match_operand 1 "" ""))))]
1485 return output_cbranch (operands[0], 1, 1,
1486 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1489 [(set_attr "type" "branch")])
1491 (define_insn "*normal_fp_branch"
1493 (if_then_else (match_operator 1 "comparison_operator"
1494 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1496 (label_ref (match_operand 2 "" ""))
1501 return output_cbranch (operands[1], 2, 0,
1502 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1505 [(set_attr "type" "branch")])
1507 (define_insn "*inverted_fp_branch"
1509 (if_then_else (match_operator 1 "comparison_operator"
1510 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1513 (label_ref (match_operand 2 "" ""))))]
1517 return output_cbranch (operands[1], 2, 1,
1518 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1521 [(set_attr "type" "branch")])
1523 (define_insn "*normal_fpe_branch"
1525 (if_then_else (match_operator 1 "comparison_operator"
1526 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1528 (label_ref (match_operand 2 "" ""))
1533 return output_cbranch (operands[1], 2, 0,
1534 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1537 [(set_attr "type" "branch")])
1539 (define_insn "*inverted_fpe_branch"
1541 (if_then_else (match_operator 1 "comparison_operator"
1542 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1545 (label_ref (match_operand 2 "" ""))))]
1549 return output_cbranch (operands[1], 2, 1,
1550 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1553 [(set_attr "type" "branch")])
1555 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1556 ;; in the architecture.
1558 ;; There are no 32 bit brreg insns.
1560 (define_insn "*normal_int_branch_sp64"
1562 (if_then_else (match_operator 0 "v9_regcmp_op"
1563 [(match_operand:DI 1 "register_operand" "r")
1565 (label_ref (match_operand 2 "" ""))
1570 return output_v9branch (operands[0], 1, 2, 0,
1571 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1574 [(set_attr "type" "branch")])
1576 (define_insn "*inverted_int_branch_sp64"
1578 (if_then_else (match_operator 0 "v9_regcmp_op"
1579 [(match_operand:DI 1 "register_operand" "r")
1582 (label_ref (match_operand 2 "" ""))))]
1586 return output_v9branch (operands[0], 1, 2, 1,
1587 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1590 [(set_attr "type" "branch")])
1592 ;; Esoteric move insns (lo_sum, high, pic).
1594 (define_insn "*lo_sum_si"
1595 [(set (match_operand:SI 0 "register_operand" "=r")
1596 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1597 (match_operand:SI 2 "immediate_operand" "in")))]
1599 ;; V9 needs "add" because of the code models. We still use "or" for v8
1600 ;; so we can compare the old compiler with the new.
1601 "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1602 ;; Need to set length for this arith insn because operand2
1603 ;; is not an "arith_operand".
1604 [(set_attr "length" "1")])
1606 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1607 ;; confuse them with real addresses.
1608 (define_insn "pic_lo_sum_si"
1609 [(set (match_operand:SI 0 "register_operand" "=r")
1610 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1611 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
1613 ;; V9 needs "add" because of the code models. We still use "or" for v8
1614 ;; so we can compare the old compiler with the new.
1615 "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";"
1616 ;; Need to set length for this arith insn because operand2
1617 ;; is not an "arith_operand".
1618 [(set_attr "length" "1")])
1620 ;; The PIC version of sethi must appear before the non-pic case so that
1621 ;; the unspec will not be matched as part of the operand.
1622 ;; For PIC, symbol_refs are put inside unspec so that the optimizer will not
1623 ;; confuse them with real addresses.
1624 (define_insn "pic_sethi_si"
1625 [(set (match_operand:SI 0 "register_operand" "=r")
1626 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1627 "flag_pic && check_pic (1)"
1628 "sethi %%hi(%a1),%0"
1629 [(set_attr "type" "move")
1630 (set_attr "length" "1")])
1632 (define_insn "pic_lo_sum_di"
1633 [(set (match_operand:DI 0 "register_operand" "=r")
1634 (lo_sum:SI (match_operand:DI 1 "register_operand" "r")
1635 (unspec:SI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
1636 "TARGET_ARCH64 && flag_pic"
1637 "add %1,%%lo(%a2),%0"
1638 [(set_attr "length" "1")])
1640 (define_insn "pic_sethi_di"
1641 [(set (match_operand:DI 0 "register_operand" "=r")
1642 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
1643 "TARGET_ARCH64 && flag_pic && check_pic (1)"
1644 "sethi %%hi(%a1),%0"
1645 [(set_attr "type" "move")
1646 (set_attr "length" "1")])
1648 (define_insn "get_pc_via_call"
1649 [(set (pc) (label_ref (match_operand 0 "" "")))
1650 (set (reg:SI 15) (label_ref (match_operand 1 "" "")))]
1653 [(set_attr "type" "uncond_branch")])
1655 (define_insn "get_pc_via_rdpc"
1656 [(set (match_operand:DI 0 "register_operand" "=r") (pc))]
1659 [(set_attr "type" "move")])
1661 ;; Special pic pattern, for loading the address of a label into a register.
1662 ;; It clobbers o7 because the call puts the return address (i.e. pc value)
1663 ;; there. The pic tablejump pattern also uses this.
1665 (define_insn "move_pic_label_si"
1666 [(set (match_operand:SI 0 "register_operand" "=r")
1667 ; This was previously (label_ref:SI (match_operand 1 "" "")) but that
1668 ; loses the volatil and other flags of the original label_ref.
1669 (match_operand:SI 1 "label_ref_operand" ""))
1670 (set (reg:SI 15) (pc))]
1674 if (get_attr_length (insn) == 2)
1675 return \"\\n1:\;call 2f\;add %%o7,%%lo(%l1-1b),%0\\n2:\";
1677 return \"\\n1:\;call 2f\;sethi %%hi(%l1-1b),%0\\n2:\\tor %0,%%lo(%l1-1b),%0\;add %0,%%o7,%0\";
1679 [(set_attr "type" "multi")
1680 ; 960 = 4096 bytes / 4 bytes/insn - 64 (for not always perfect length calcs)
1681 (set (attr "length") (if_then_else (ltu (minus (match_dup 1) (pc))
1686 ;; Special sparc64 pattern for loading the address of a label into a register.
1687 ;; The pic and non-pic cases are the same since it's the most efficient way.
1689 ;; ??? The non-pic case doesn't need to use %o7, we could use a scratch
1690 ;; instead. But the pic case doesn't need to use %o7 either. We handle them
1691 ;; both here so that when this is fixed, they can both be fixed together.
1692 ;; Don't forget that the pic jump table stuff uses %o7 (that will need to be
1695 (define_insn "move_label_di"
1696 [(set (match_operand:DI 0 "register_operand" "=r")
1697 ; This was previously (label_ref:DI (match_operand 1 "" "")) but that
1698 ; loses the volatil and other flags of the original label_ref.
1699 (match_operand:DI 1 "label_ref_operand" ""))
1700 (set (reg:DI 15) (pc))]
1704 if (get_attr_length (insn) == 2)
1705 return \"\\n1:\;rd %%pc,%%o7\;add %%o7,%l1-1b,%0\";
1707 return \"\\n1:\;rd %%pc,%%o7\;sethi %%hi(%l1-1b),%0\;add %0,%%lo(%l1-1b),%0\;sra %0,0,%0\;add %0,%%o7,%0\";
1709 [(set_attr "type" "multi")
1710 ; 960 = 4096 bytes / 4 bytes/insn - 64 (for not always perfect length calcs)
1711 (set (attr "length") (if_then_else (ltu (minus (match_dup 1) (pc))
1716 (define_insn "*sethi_hi"
1717 [(set (match_operand:HI 0 "register_operand" "=r")
1718 (high:HI (match_operand 1 "" "")))]
1720 "sethi %%hi(%a1),%0"
1721 [(set_attr "type" "move")
1722 (set_attr "length" "1")])
1724 ;; This must appear after the PIC sethi so that the PIC unspec will not
1725 ;; be matched as part of the operand.
1726 (define_insn "*sethi_si"
1727 [(set (match_operand:SI 0 "register_operand" "=r")
1728 (high:SI (match_operand 1 "" "")))]
1730 "sethi %%hi(%a1),%0"
1731 [(set_attr "type" "move")
1732 (set_attr "length" "1")])
1734 (define_insn "*lo_sum_di_sp32"
1735 [(set (match_operand:DI 0 "register_operand" "=r")
1736 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1737 (match_operand:DI 2 "immediate_operand" "in")))]
1741 /* Don't output a 64 bit constant, since we can't trust the assembler to
1742 handle it correctly. */
1743 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1744 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
1745 else if (GET_CODE (operands[2]) == CONST_INT
1746 && HOST_BITS_PER_WIDE_INT > 32
1747 && INTVAL (operands[2]) > 0xffffffff)
1748 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
1750 return \"or %L1,%%lo(%a2),%L0\";
1752 ;; Need to set length for this arith insn because operand2
1753 ;; is not an "arith_operand".
1754 [(set_attr "length" "1")])
1756 ;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add?
1758 (define_insn "*lo_sum_di_sp64"
1759 [(set (match_operand:DI 0 "register_operand" "=r")
1760 (lo_sum:DI (match_operand:DI 1 "register_operand" "0")
1761 (match_operand:DI 2 "immediate_operand" "in")))]
1765 /* Don't output a 64 bit constant, since we can't trust the assembler to
1766 handle it correctly. */
1767 if (GET_CODE (operands[2]) == CONST_DOUBLE)
1768 operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
1769 else if (GET_CODE (operands[2]) == CONST_INT
1770 && HOST_BITS_PER_WIDE_INT > 32
1771 && INTVAL (operands[2]) > 0xffffffff)
1772 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff);
1774 /* Note that we use add here. This is important because Medium/Anywhere
1775 code model support depends on it. */
1776 return \"add %1,%%lo(%a2),%0\";
1778 ;; Need to set length for this arith insn because operand2
1779 ;; is not an "arith_operand".
1780 [(set_attr "length" "1")])
1782 (define_insn "*sethi_di_sp32"
1783 [(set (match_operand:DI 0 "register_operand" "=r")
1784 (high:DI (match_operand 1 "" "")))]
1785 "! TARGET_ARCH64 && check_pic (1)"
1788 rtx op0 = operands[0];
1789 rtx op1 = operands[1];
1791 if (GET_CODE (op1) == CONST_INT)
1793 operands[0] = operand_subword (op0, 1, 0, DImode);
1794 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1796 operands[0] = operand_subword (op0, 0, 0, DImode);
1797 if (INTVAL (op1) < 0)
1798 return \"mov -1,%0\";
1800 return \"mov 0,%0\";
1802 else if (GET_CODE (op1) == CONST_DOUBLE)
1804 operands[0] = operand_subword (op0, 1, 0, DImode);
1805 operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
1806 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1808 operands[0] = operand_subword (op0, 0, 0, DImode);
1809 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
1810 return singlemove_string (operands);
1816 [(set_attr "type" "move")
1817 (set_attr "length" "2")])
1819 ;;; ??? This pattern originally clobbered a scratch register. However, this
1820 ;;; is invalid, the movdi pattern may not use a temp register because it
1821 ;;; may be called from reload to reload a DImode value. In that case, we
1822 ;;; end up with a scratch register that never gets allocated. To avoid this,
1823 ;;; we use global register 1 which is never otherwise used by gcc as a temp.
1824 ;;; The correct solution here might be to force DImode constants to memory,
1825 ;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg
1826 ;;; 1 will then no longer need to be considered a fixed reg.
1828 (define_expand "sethi_di_sp64"
1830 [(set (match_operand:DI 0 "register_operand" "")
1831 (high:DI (match_operand 1 "general_operand" "")))
1832 (clobber (reg:DI 1))])]
1836 (define_insn "*sethi_di_sp64_const"
1837 [(set (match_operand:DI 0 "register_operand" "=r")
1838 (high:DI (match_operand 1 "const_double_operand" "")))
1839 (clobber (reg:DI 1))]
1840 "TARGET_ARCH64 && check_pic (1)"
1843 #if HOST_BITS_PER_WIDE_INT == 32
1846 split_double (operands[1], &high, &low);
1848 if (high == const0_rtx)
1851 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1856 output_asm_insn (singlemove_string (operands), operands);
1859 output_asm_insn (\"sllx %0,32,%0\", operands);
1860 if (low != const0_rtx)
1861 output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1864 rtx op = operands[1];
1866 if (! SPARC_SETHI_P (INTVAL(op)))
1868 operands[1] = GEN_INT (INTVAL (op) >> 32);
1869 output_asm_insn (singlemove_string (operands), operands);
1871 output_asm_insn (\"sllx %0,32,%0\", operands);
1872 if (INTVAL (op) & 0xffffffff)
1874 operands[1] = GEN_INT (INTVAL (op) & 0xffffffff);
1875 output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands);
1880 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
1886 [(set_attr "type" "move")
1887 (set_attr "length" "5")])
1889 ;; Most of the required support for the various code models is here.
1890 ;; We can do this because sparcs need the high insn to load the address. We
1891 ;; just need to get high to do the right thing for each code model. Then each
1892 ;; uses the same "%X+%lo(...)" in the load/store insn, though in the case of
1893 ;; the medium/middle code model "%lo" is written "%l44".
1895 ;; When TARGET_CM_MEDLOW, assume that the upper 32 bits of symbol addresses are
1897 ;; When TARGET_CM_MEDMID, the executable must be in the low 16 TB of memory.
1898 ;; This corresponds to the low 44 bits, and the %[hml]44 relocs are used.
1899 ;; ??? Not implemented yet.
1900 ;; When TARGET_CM_EMBMEDANY, the text and data segments have a maximum size of
1901 ;; 31 bits and may be located anywhere. EMBMEDANY_BASE_REG contains the start
1902 ;; address of the data segment, currently %g4.
1903 ;; When TARGET_CM_MEDANY, the text and data segments have a maximum size of 31
1904 ;; bits and may be located anywhere. The maximum offset from any instruction
1905 ;; to the label _GLOBAL_OFFSET_TABLE_ is 31 bits.
1907 (define_insn "*sethi_di_medlow"
1908 [(set (match_operand:DI 0 "register_operand" "=r")
1909 (high:DI (match_operand 1 "" "")))
1910 ;; The clobber is here because emit_move_sequence assumes the worst case.
1911 (clobber (reg:DI 1))]
1912 "TARGET_CM_MEDLOW && check_pic (1)"
1913 "sethi %%hi(%a1),%0"
1914 [(set_attr "type" "move")
1915 (set_attr "length" "1")])
1917 (define_insn "*sethi_di_medium_pic"
1918 [(set (match_operand:DI 0 "register_operand" "=r")
1919 (high:DI (match_operand 1 "sp64_medium_pic_operand" "")))]
1920 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1921 "sethi %%hi(%a1),%0"
1922 [(set_attr "type" "move")
1923 (set_attr "length" "1")])
1925 ;; WARNING: %0 gets %hi(%1)+%g4.
1926 ;; You cannot OR in %lo(%1), it must be added in.
1928 (define_insn "*sethi_di_embmedany_data"
1929 [(set (match_operand:DI 0 "register_operand" "=r")
1930 (high:DI (match_operand 1 "data_segment_operand" "")))
1931 ;; The clobber is here because emit_move_sequence assumes the worst case.
1932 (clobber (reg:DI 1))]
1933 "TARGET_CM_EMBMEDANY && check_pic (1)"
1934 "sethi %%hi(%a1),%0; add %0,%_,%0"
1935 [(set_attr "type" "move")
1936 (set_attr "length" "2")])
1938 (define_insn "*sethi_di_embmedany_text"
1939 [(set (match_operand:DI 0 "register_operand" "=r")
1940 (high:DI (match_operand 1 "text_segment_operand" "")))
1941 ;; The clobber is here because emit_move_sequence assumes the worst case.
1942 (clobber (reg:DI 1))]
1943 "TARGET_CM_EMBMEDANY && check_pic (1)"
1944 "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0"
1945 [(set_attr "type" "move")
1946 (set_attr "length" "5")])
1948 ;; Move instructions
1950 (define_expand "movqi"
1951 [(set (match_operand:QI 0 "general_operand" "")
1952 (match_operand:QI 1 "general_operand" ""))]
1956 if (emit_move_sequence (operands, QImode))
1960 (define_insn "*movqi_insn"
1961 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
1962 (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))]
1964 && (register_operand (operands[0], QImode)
1965 || register_operand (operands[1], QImode)
1966 || operands[1] == const0_rtx)"
1972 [(set_attr "type" "move,move,load,store")
1973 (set_attr "length" "1")])
1975 (define_insn "*movqi_insn_liveg0"
1976 [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q")
1977 (match_operand:QI 1 "move_operand" "r,J,I,K,Q,r"))]
1979 && (register_operand (operands[0], QImode)
1980 || register_operand (operands[1], QImode))"
1984 and %0,0,%0\;or %0,%1,%0
1988 [(set_attr "type" "move,move,move,move,load,store")
1989 (set_attr "length" "1,1,2,1,1,1")])
1991 (define_insn "*lo_sum_qi"
1992 [(set (match_operand:QI 0 "register_operand" "=r")
1993 (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r")
1994 (match_operand 2 "immediate_operand" "in")) 0))]
1996 "or %1,%%lo(%a2),%0"
1997 [(set_attr "length" "1")])
1999 (define_insn "*store_qi"
2000 [(set (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
2001 (match_operand:QI 1 "reg_or_0_operand" "rJ"))
2002 (clobber (match_scratch:SI 2 "=&r"))]
2003 "(reload_completed || reload_in_progress)
2005 "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]"
2006 [(set_attr "type" "store")
2007 (set_attr "length" "2")])
2009 (define_expand "movhi"
2010 [(set (match_operand:HI 0 "general_operand" "")
2011 (match_operand:HI 1 "general_operand" ""))]
2015 if (emit_move_sequence (operands, HImode))
2019 (define_insn "*movhi_insn"
2020 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q")
2021 (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))]
2023 && (register_operand (operands[0], HImode)
2024 || register_operand (operands[1], HImode)
2025 || operands[1] == const0_rtx)"
2031 [(set_attr "type" "move,move,load,store")
2032 (set_attr "length" "1")])
2034 (define_insn "*movhi_insn_liveg0"
2035 [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q")
2036 (match_operand:HI 1 "move_operand" "r,J,I,K,Q,r"))]
2038 && (register_operand (operands[0], HImode)
2039 || register_operand (operands[1], HImode))"
2043 and %0,0,%0\;or %0,%1,%0
2047 [(set_attr "type" "move,move,move,move,load,store")
2048 (set_attr "length" "1,1,2,1,1,1")])
2050 (define_insn "*lo_sum_hi"
2051 [(set (match_operand:HI 0 "register_operand" "=r")
2052 (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
2053 (match_operand 2 "immediate_operand" "in")))]
2055 "or %1,%%lo(%a2),%0"
2056 [(set_attr "length" "1")])
2058 (define_insn "*store_hi"
2059 [(set (mem:HI (match_operand:SI 0 "symbolic_operand" ""))
2060 (match_operand:HI 1 "reg_or_0_operand" "rJ"))
2061 (clobber (match_scratch:SI 2 "=&r"))]
2062 "(reload_completed || reload_in_progress)
2064 "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]"
2065 [(set_attr "type" "store")
2066 (set_attr "length" "2")])
2068 (define_expand "movsi"
2069 [(set (match_operand:SI 0 "general_operand" "")
2070 (match_operand:SI 1 "general_operand" ""))]
2074 if (emit_move_sequence (operands, SImode))
2078 ;; We must support both 'r' and 'f' registers here, because combine may
2079 ;; convert SFmode hard registers to SImode hard registers when simplifying
2082 ;; We cannot combine the similar 'r' and 'f' constraints, because it causes
2083 ;; problems with register allocation. Reload might try to put an integer
2084 ;; in an fp register, or an fp number is an integer register.
2086 (define_insn "*movsi_insn"
2087 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q,d")
2088 (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f,J"))]
2090 && (register_operand (operands[0], SImode)
2091 || register_operand (operands[1], SImode)
2092 || operands[1] == const0_rtx)"
2102 [(set_attr "type" "move,fp,move,load,fpload,store,fpstore,fpmove")
2103 (set_attr "length" "1")])
2105 (define_insn "*movsi_insn_liveg0"
2106 [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,r,r,f,Q,Q")
2107 (match_operand:SI 1 "move_operand" "r,J,I,!f,K,Q,!Q,r,!f"))]
2109 && (register_operand (operands[0], SImode)
2110 || register_operand (operands[1], SImode))"
2114 and %0,0,%0\;or %0,%1,%0
2121 [(set_attr "type" "move,move,move,fpmove,move,load,fpload,store,fpstore")
2122 (set_attr "length" "1,1,2,1,1,1,1,1,1")])
2124 (define_insn "*store_si"
2125 [(set (mem:SI (match_operand:SI 0 "symbolic_operand" ""))
2126 (match_operand:SI 1 "reg_or_0_operand" "rJ"))
2127 (clobber (match_scratch:SI 2 "=&r"))]
2128 "(reload_completed || reload_in_progress)
2130 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
2131 [(set_attr "type" "store")
2132 (set_attr "length" "2")])
2134 (define_expand "movdi"
2135 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2136 (match_operand:DI 1 "general_operand" ""))]
2140 if (emit_move_sequence (operands, DImode))
2144 ;; V8+ movdi is like regular 32 bit except that a 64 bit zero can be stored
2145 ;; to aligned memory with a single instruction and the ldd/std instructions
2147 (define_insn "*movdi_v8plus"
2148 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,Q,r,r,f,f,Q,b")
2149 (match_operand:DI 1 "general_operand" "r,J,r,Q,i,?f,?Q,?f,?J"))]
2151 && (register_operand (operands[0], DImode)
2152 || register_operand (operands[1], DImode)
2153 || operands[1] == const0_rtx)"
2156 if (which_alternative == 1)
2157 return \"stx %%g0,%0\";
2158 if (which_alternative == 8)
2159 return \"fzero %0\";
2160 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2161 return output_fp_move_double (operands);
2162 return output_move_double (operands);
2164 [(set_attr "type" "move,store,store,load,multi,fp,fpload,fpstore,fpmove")
2165 (set_attr "length" "2,1,3,3,3,2,3,3,1")])
2167 ;; ??? The Haifa scheduler does not split instructions after reload if
2168 ;; it also ran before reload.
2171 [(set (match_operand:DI 0 "memory_operand" "=m")
2172 (match_operand:DI 1 "register_operand" "r"))]
2173 "TARGET_V8PLUS && !TARGET_ARCH64 && reload_completed
2174 && REGNO (operands[1]) < 32 && ! MEM_VOLATILE_P (operands[0])
2175 && offsettable_memref_p (operands[0])"
2176 [(set (match_dup 2) (match_dup 3))
2177 (set (match_dup 4) (match_dup 5))]
2178 "operands[3] = gen_highpart (SImode, operands[1]);
2179 operands[5] = gen_lowpart (SImode, operands[1]);
2180 operands[4] = adj_offsettable_operand (operands[0], 4);
2181 PUT_MODE (operands[4], SImode);
2182 operands[2] = copy_rtx (operands[0]);
2183 PUT_MODE (operands[2], SImode);")
2185 (define_insn "*movdi_sp32_insn"
2186 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q")
2187 (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))]
2189 && (register_operand (operands[0], DImode)
2190 || register_operand (operands[1], DImode)
2191 || operands[1] == const0_rtx)"
2194 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2195 return output_fp_move_double (operands);
2196 return output_move_double (operands);
2198 [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore")
2199 (set_attr "length" "2,1,1,3,3,3,2,3,3")])
2201 ;;; ??? The trick used below can be extended to load any negative 32 bit
2202 ;;; constant in two instructions. Currently the compiler will use HIGH/LO_SUM
2203 ;;; for anything not matching the HIK constraints, which results in 5
2204 ;;; instructions. Positive 32 bit constants can be loaded in the obvious way
2205 ;;; with sethi/ori. To extend the trick, in the xor instruction, use
2206 ;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0
2207 ;;; This needs the original value of operands[1], not the inverted value.
2209 (define_insn "*movdi_sp64_insn"
2210 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?f,?f,?Q")
2211 (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,f,Q,f"))]
2213 && (register_operand (operands[0], DImode)
2214 || register_operand (operands[1], DImode)
2215 || operands[1] == const0_rtx)"
2218 switch (which_alternative)
2221 return \"mov %1,%0\";
2223 /* Sethi does not sign extend, so we must use a little trickery
2224 to use it for negative numbers. Invert the constant before
2225 loading it in, then use a xor immediate to invert the loaded bits
2226 (along with the upper 32 bits) to the desired constant. This
2227 works because the sethi and immediate fields overlap. */
2229 if ((INTVAL (operands[1]) & 0x80000000) == 0)
2230 return \"sethi %%hi(%a1),%0\";
2233 operands[1] = GEN_INT (~INTVAL (operands[1]));
2234 output_asm_insn (\"sethi %%hi(%a1),%0\", operands);
2235 /* The low 10 bits are already zero, but invert the rest.
2236 Assemblers don't accept 0x1c00, so use -0x400 instead. */
2237 return \"xor %0,-0x400,%0\";
2240 return \"ldx %1,%0\";
2242 return \"stx %r1,%0\";
2244 return \"mov %1,%0\";
2246 return \"ldd %1,%0\";
2248 return \"std %1,%0\";
2253 [(set_attr "type" "move,move,load,store,fp,fpload,fpstore")
2254 (set_attr "length" "1,2,1,1,1,1,1")])
2256 ;; ??? There's no symbolic (set (mem:DI ...) ...).
2257 ;; Experimentation with v9 suggested one isn't needed.
2259 ;; Block move insns.
2261 ;; ??? We get better code without it. See output_block_move in sparc.c.
2263 ;; The definition of this insn does not really explain what it does,
2264 ;; but it should suffice
2265 ;; that anything generated as this insn will be recognized as one
2266 ;; and that it will not successfully combine with anything.
2267 ;(define_expand "movstrsi"
2268 ; [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
2269 ; (mem:BLK (match_operand:BLK 1 "general_operand" "")))
2270 ; (use (match_operand:SI 2 "nonmemory_operand" ""))
2271 ; (use (match_operand:SI 3 "immediate_operand" ""))
2272 ; (clobber (match_dup 0))
2273 ; (clobber (match_dup 1))
2274 ; (clobber (match_scratch:SI 4 ""))
2275 ; (clobber (reg:SI 100))
2276 ; (clobber (reg:SI 1))])]
2280 ; /* If the size isn't known, don't emit inline code. output_block_move
2281 ; would output code that's much slower than the library function.
2282 ; Also don't output code for large blocks. */
2283 ; if (GET_CODE (operands[2]) != CONST_INT
2284 ; || GET_CODE (operands[3]) != CONST_INT
2285 ; || INTVAL (operands[2]) / INTVAL (operands[3]) > 16)
2288 ; operands[0] = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
2289 ; operands[1] = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
2290 ; operands[2] = force_not_mem (operands[2]);
2293 ;(define_insn "*block_move_insn"
2294 ; [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r"))
2295 ; (mem:BLK (match_operand:SI 1 "register_operand" "+r")))
2296 ; (use (match_operand:SI 2 "nonmemory_operand" "rn"))
2297 ; (use (match_operand:SI 3 "immediate_operand" "i"))
2298 ; (clobber (match_dup 0))
2299 ; (clobber (match_dup 1))
2300 ; (clobber (match_scratch:SI 4 "=&r"))
2301 ; (clobber (reg:SI 100))
2302 ; (clobber (reg:SI 1))]
2304 ; "* return output_block_move (operands);"
2305 ; [(set_attr "type" "multi")
2306 ; (set_attr "length" "6")])
2308 ;; Floating point move insns
2310 ;; This pattern forces (set (reg:SF ...) (const_double ...))
2311 ;; to be reloaded by putting the constant into memory.
2312 ;; It must come before the more general movsf pattern.
2313 (define_insn "*movsf_const_insn"
2314 [(set (match_operand:SF 0 "general_operand" "=?r,f,m,d")
2315 (match_operand:SF 1 "" "?F,m,G,G"))]
2317 && GET_CODE (operands[1]) == CONST_DOUBLE
2318 && (GET_CODE (operands[0]) == REG
2319 || fp_zero_operand (operands[1]))"
2322 switch (which_alternative)
2325 return singlemove_string (operands);
2327 return \"ld %1,%0\";
2329 return \"st %%g0,%0\";
2331 return \"fzeros %0\";
2336 [(set_attr "type" "load,fpload,store,fpmove")
2337 (set_attr "length" "2,1,1,1")])
2339 (define_expand "movsf"
2340 [(set (match_operand:SF 0 "general_operand" "")
2341 (match_operand:SF 1 "general_operand" ""))]
2345 if (emit_move_sequence (operands, SFmode))
2349 (define_insn "*movsf_insn"
2350 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,f,r,Q,Q")
2351 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,Q,Q,f,r"))]
2353 && (register_operand (operands[0], SFmode)
2354 || register_operand (operands[1], SFmode))"
2362 [(set_attr "type" "fpmove,move,fpload,load,fpstore,store")])
2364 ;; Exactly the same as above, except that all `f' cases are deleted.
2365 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2368 (define_insn "*movsf_no_f_insn"
2369 [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
2370 (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
2372 && (register_operand (operands[0], SFmode)
2373 || register_operand (operands[1], SFmode))"
2378 [(set_attr "type" "move,load,store")])
2380 (define_insn "*store_sf"
2381 [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
2382 (match_operand:SF 1 "reg_or_0_operand" "rfG"))
2383 (clobber (match_scratch:SI 2 "=&r"))]
2384 "(reload_completed || reload_in_progress)
2386 "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]"
2387 [(set_attr "type" "store")
2388 (set_attr "length" "2")])
2390 ;; This pattern forces (set (reg:DF ...) (const_double ...))
2391 ;; to be reloaded by putting the constant into memory.
2392 ;; It must come before the more general movdf pattern.
2394 (define_insn "*movdf_const_insn"
2395 [(set (match_operand:DF 0 "general_operand" "=?r,e,o,d")
2396 (match_operand:DF 1 "" "?F,m,G,G"))]
2398 && GET_CODE (operands[1]) == CONST_DOUBLE
2399 && (GET_CODE (operands[0]) == REG
2400 || fp_zero_operand (operands[1]))"
2403 switch (which_alternative)
2406 return output_move_double (operands);
2408 return output_fp_move_double (operands);
2410 if (TARGET_ARCH64 || (TARGET_V9 && mem_aligned_8 (operands[0])))
2412 return \"stx %%g0,%0\";
2416 operands[1] = adj_offsettable_operand (operands[0], 4);
2417 return \"st %%g0,%0\;st %%g0,%1\";
2420 return \"fzero %0\";
2425 [(set_attr "type" "load,fpload,store,fpmove")
2426 (set_attr "length" "3,3,3,1")])
2428 (define_expand "movdf"
2429 [(set (match_operand:DF 0 "general_operand" "")
2430 (match_operand:DF 1 "general_operand" ""))]
2434 if (emit_move_sequence (operands, DFmode))
2438 (define_insn "*movdf_insn"
2439 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,e,r,Q,Q,e,r")
2440 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,e,r,e,r,Q,Q"))]
2442 && (register_operand (operands[0], DFmode)
2443 || register_operand (operands[1], DFmode))"
2446 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2447 return output_fp_move_double (operands);
2448 return output_move_double (operands);
2450 [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load")
2451 (set_attr "length" "1,1,2,2,3,3,3,3")])
2453 ;; Exactly the same as above, except that all `e' cases are deleted.
2454 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2457 (define_insn "*movdf_no_e_insn"
2458 [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
2459 (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
2461 && (register_operand (operands[0], DFmode)
2462 || register_operand (operands[1], DFmode))"
2463 "* return output_move_double (operands);"
2464 [(set_attr "type" "store,load,move,store,load")
2465 (set_attr "length" "1,1,2,3,3")])
2467 ;; Must handle overlapping registers here, since parameters can be unaligned
2471 [(set (match_operand:DF 0 "register_operand" "")
2472 (match_operand:DF 1 "register_operand" ""))]
2473 "! TARGET_ARCH64 && reload_completed
2474 && REGNO (operands[0]) < SPARC_FIRST_V9_FP_REG
2475 && REGNO (operands[1]) < SPARC_FIRST_V9_FP_REG"
2476 [(set (match_dup 2) (match_dup 3))
2477 (set (match_dup 4) (match_dup 5))]
2480 rtx first_set = operand_subword (operands[0], 0, 0, DFmode);
2481 rtx second_use = operand_subword (operands[1], 1, 0, DFmode);
2483 if (REGNO (first_set) == REGNO (second_use))
2485 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2486 operands[3] = second_use;
2487 operands[4] = first_set;
2488 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2492 operands[2] = first_set;
2493 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2494 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2495 operands[5] = second_use;
2499 (define_insn "*store_df"
2500 [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
2501 (match_operand:DF 1 "reg_or_0_operand" "re,G"))
2502 (clobber (match_scratch:SI 2 "=&r,&r"))]
2503 "(reload_completed || reload_in_progress)
2507 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2508 if (which_alternative == 0)
2509 return \"std %1,[%2+%%lo(%a0)]\";
2511 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\";
2513 [(set_attr "type" "store")
2514 (set_attr "length" "3")])
2516 ;; This pattern forces (set (reg:TF ...) (const_double ...))
2517 ;; to be reloaded by putting the constant into memory.
2518 ;; It must come before the more general movtf pattern.
2519 (define_insn "*movtf_const_insn"
2520 [(set (match_operand:TF 0 "general_operand" "=?r,e,o")
2521 (match_operand:TF 1 "" "?F,m,G"))]
2523 && GET_CODE (operands[1]) == CONST_DOUBLE
2524 && (GET_CODE (operands[0]) == REG
2525 || fp_zero_operand (operands[1]))"
2528 switch (which_alternative)
2531 return output_move_quad (operands);
2533 return output_fp_move_quad (operands);
2535 if (TARGET_ARCH64 || (TARGET_V9 && mem_aligned_8 (operands[0])))
2537 operands[1] = adj_offsettable_operand (operands[0], 8);
2538 return \"stx %%g0,%0\;stx %%g0,%1\";
2542 /* ??? Do we run off the end of the array here? */
2543 operands[1] = adj_offsettable_operand (operands[0], 4);
2544 operands[2] = adj_offsettable_operand (operands[0], 8);
2545 operands[3] = adj_offsettable_operand (operands[0], 12);
2546 return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\";
2552 [(set_attr "type" "load,fpload,store")
2553 (set_attr "length" "5,5,5")])
2555 (define_expand "movtf"
2556 [(set (match_operand:TF 0 "general_operand" "")
2557 (match_operand:TF 1 "general_operand" ""))]
2561 if (emit_move_sequence (operands, TFmode))
2565 (define_insn "*movtf_insn"
2566 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,r,Q,Q,e,&r")
2567 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,r,e,r,Q,Q"))]
2569 && (register_operand (operands[0], TFmode)
2570 || register_operand (operands[1], TFmode))"
2573 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2574 return output_fp_move_quad (operands);
2575 return output_move_quad (operands);
2577 [(set_attr "type" "fp,move,fpstore,store,fpload,load")
2578 (set_attr "length" "4,4,5,5,5,5")])
2580 ;; Exactly the same as above, except that all `e' cases are deleted.
2581 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2584 (define_insn "*movtf_no_e_insn"
2585 [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
2586 (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
2588 && (register_operand (operands[0], TFmode)
2589 || register_operand (operands[1], TFmode))"
2592 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
2593 return output_fp_move_quad (operands);
2594 return output_move_quad (operands);
2596 [(set_attr "type" "move,store,load")
2597 (set_attr "length" "4,5,5")])
2599 ;; This is disabled because it does not work. Long doubles have only 8
2600 ;; byte alignment. Adding an offset of 8 or 12 to an 8 byte aligned %lo may
2601 ;; cause it to overflow. See also GO_IF_LEGITIMATE_ADDRESS.
2602 (define_insn "*store_tf"
2603 [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
2604 (match_operand:TF 1 "reg_or_0_operand" "re,G"))
2605 (clobber (match_scratch:SI 2 "=&r,&r"))]
2606 "0 && (reload_completed || reload_in_progress)
2610 output_asm_insn (\"sethi %%hi(%a0),%2\", operands);
2611 if (which_alternative == 0)
2612 return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\";
2614 return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\";
2616 [(set_attr "type" "store")
2617 (set_attr "length" "5")])
2619 ;; Sparc V9 conditional move instructions.
2621 ;; We can handle larger constants here for some flavors, but for now we keep
2622 ;; it simple and only allow those constants supported by all flavours.
2623 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2624 ;; 3 contains the constant if one is present, but we handle either for
2625 ;; generality (sparc.c puts a constant in operand 2).
2627 (define_expand "movqicc"
2628 [(set (match_operand:QI 0 "register_operand" "")
2629 (if_then_else:QI (match_operand 1 "comparison_operator" "")
2630 (match_operand:QI 2 "arith10_operand" "")
2631 (match_operand:QI 3 "arith10_operand" "")))]
2635 enum rtx_code code = GET_CODE (operands[1]);
2637 if (GET_MODE (sparc_compare_op0) == DImode
2641 if (sparc_compare_op1 == const0_rtx
2642 && GET_CODE (sparc_compare_op0) == REG
2643 && GET_MODE (sparc_compare_op0) == DImode
2644 && v9_regcmp_p (code))
2646 operands[1] = gen_rtx (code, DImode,
2647 sparc_compare_op0, sparc_compare_op1);
2651 rtx cc_reg = gen_compare_reg (code,
2652 sparc_compare_op0, sparc_compare_op1);
2653 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2657 (define_expand "movhicc"
2658 [(set (match_operand:HI 0 "register_operand" "")
2659 (if_then_else:HI (match_operand 1 "comparison_operator" "")
2660 (match_operand:HI 2 "arith10_operand" "")
2661 (match_operand:HI 3 "arith10_operand" "")))]
2665 enum rtx_code code = GET_CODE (operands[1]);
2667 if (GET_MODE (sparc_compare_op0) == DImode
2671 if (sparc_compare_op1 == const0_rtx
2672 && GET_CODE (sparc_compare_op0) == REG
2673 && GET_MODE (sparc_compare_op0) == DImode
2674 && v9_regcmp_p (code))
2676 operands[1] = gen_rtx (code, DImode,
2677 sparc_compare_op0, sparc_compare_op1);
2681 rtx cc_reg = gen_compare_reg (code,
2682 sparc_compare_op0, sparc_compare_op1);
2683 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2687 (define_expand "movsicc"
2688 [(set (match_operand:SI 0 "register_operand" "")
2689 (if_then_else:SI (match_operand 1 "comparison_operator" "")
2690 (match_operand:SI 2 "arith10_operand" "")
2691 (match_operand:SI 3 "arith10_operand" "")))]
2695 enum rtx_code code = GET_CODE (operands[1]);
2697 if (GET_MODE (sparc_compare_op0) == DImode
2701 if (sparc_compare_op1 == const0_rtx
2702 && GET_CODE (sparc_compare_op0) == REG
2703 && GET_MODE (sparc_compare_op0) == DImode
2704 && v9_regcmp_p (code))
2706 operands[1] = gen_rtx (code, DImode,
2707 sparc_compare_op0, sparc_compare_op1);
2711 rtx cc_reg = gen_compare_reg (code,
2712 sparc_compare_op0, sparc_compare_op1);
2713 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2717 (define_expand "movdicc"
2718 [(set (match_operand:DI 0 "register_operand" "")
2719 (if_then_else:DI (match_operand 1 "comparison_operator" "")
2720 (match_operand:DI 2 "arith10_double_operand" "")
2721 (match_operand:DI 3 "arith10_double_operand" "")))]
2725 enum rtx_code code = GET_CODE (operands[1]);
2727 if (sparc_compare_op1 == const0_rtx
2728 && GET_CODE (sparc_compare_op0) == REG
2729 && GET_MODE (sparc_compare_op0) == DImode
2730 && v9_regcmp_p (code))
2732 operands[1] = gen_rtx (code, DImode,
2733 sparc_compare_op0, sparc_compare_op1);
2737 rtx cc_reg = gen_compare_reg (code,
2738 sparc_compare_op0, sparc_compare_op1);
2739 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2743 (define_expand "movsfcc"
2744 [(set (match_operand:SF 0 "register_operand" "")
2745 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2746 (match_operand:SF 2 "register_operand" "")
2747 (match_operand:SF 3 "register_operand" "")))]
2748 "TARGET_V9 && TARGET_FPU"
2751 enum rtx_code code = GET_CODE (operands[1]);
2753 if (GET_MODE (sparc_compare_op0) == DImode
2757 if (sparc_compare_op1 == const0_rtx
2758 && GET_CODE (sparc_compare_op0) == REG
2759 && GET_MODE (sparc_compare_op0) == DImode
2760 && v9_regcmp_p (code))
2762 operands[1] = gen_rtx (code, DImode,
2763 sparc_compare_op0, sparc_compare_op1);
2767 rtx cc_reg = gen_compare_reg (code,
2768 sparc_compare_op0, sparc_compare_op1);
2769 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2773 (define_expand "movdfcc"
2774 [(set (match_operand:DF 0 "register_operand" "")
2775 (if_then_else:DF (match_operand 1 "comparison_operator" "")
2776 (match_operand:DF 2 "register_operand" "")
2777 (match_operand:DF 3 "register_operand" "")))]
2778 "TARGET_V9 && TARGET_FPU"
2781 enum rtx_code code = GET_CODE (operands[1]);
2783 if (GET_MODE (sparc_compare_op0) == DImode
2787 if (sparc_compare_op1 == const0_rtx
2788 && GET_CODE (sparc_compare_op0) == REG
2789 && GET_MODE (sparc_compare_op0) == DImode
2790 && v9_regcmp_p (code))
2792 operands[1] = gen_rtx (code, DImode,
2793 sparc_compare_op0, sparc_compare_op1);
2797 rtx cc_reg = gen_compare_reg (code,
2798 sparc_compare_op0, sparc_compare_op1);
2799 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2803 (define_expand "movtfcc"
2804 [(set (match_operand:TF 0 "register_operand" "")
2805 (if_then_else:TF (match_operand 1 "comparison_operator" "")
2806 (match_operand:TF 2 "register_operand" "")
2807 (match_operand:TF 3 "register_operand" "")))]
2808 "TARGET_V9 && TARGET_FPU"
2811 enum rtx_code code = GET_CODE (operands[1]);
2813 if (GET_MODE (sparc_compare_op0) == DImode
2817 if (sparc_compare_op1 == const0_rtx
2818 && GET_CODE (sparc_compare_op0) == REG
2819 && GET_MODE (sparc_compare_op0) == DImode
2820 && v9_regcmp_p (code))
2822 operands[1] = gen_rtx (code, DImode,
2823 sparc_compare_op0, sparc_compare_op1);
2827 rtx cc_reg = gen_compare_reg (code,
2828 sparc_compare_op0, sparc_compare_op1);
2829 operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2833 ;; Conditional move define_insns.
2835 (define_insn "*movqi_cc_sp64"
2836 [(set (match_operand:QI 0 "register_operand" "=r,r")
2837 (if_then_else:QI (match_operator 1 "comparison_operator"
2838 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2840 (match_operand:QI 3 "arith11_operand" "rL,0")
2841 (match_operand:QI 4 "arith11_operand" "0,rL")))]
2846 [(set_attr "type" "cmove")])
2848 (define_insn "*movhi_cc_sp64"
2849 [(set (match_operand:HI 0 "register_operand" "=r,r")
2850 (if_then_else:HI (match_operator 1 "comparison_operator"
2851 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2853 (match_operand:HI 3 "arith11_operand" "rL,0")
2854 (match_operand:HI 4 "arith11_operand" "0,rL")))]
2859 [(set_attr "type" "cmove")])
2861 (define_insn "*movsi_cc_sp64"
2862 [(set (match_operand:SI 0 "register_operand" "=r,r")
2863 (if_then_else:SI (match_operator 1 "comparison_operator"
2864 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2866 (match_operand:SI 3 "arith11_operand" "rL,0")
2867 (match_operand:SI 4 "arith11_operand" "0,rL")))]
2872 [(set_attr "type" "cmove")])
2874 ;; ??? The constraints of operands 3,4 need work.
2875 (define_insn "*movdi_cc_sp64"
2876 [(set (match_operand:DI 0 "register_operand" "=r,r")
2877 (if_then_else:DI (match_operator 1 "comparison_operator"
2878 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2880 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
2881 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
2886 [(set_attr "type" "cmove")])
2888 (define_insn "*movsf_cc_sp64"
2889 [(set (match_operand:SF 0 "register_operand" "=f,f")
2890 (if_then_else:SF (match_operator 1 "comparison_operator"
2891 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2893 (match_operand:SF 3 "register_operand" "f,0")
2894 (match_operand:SF 4 "register_operand" "0,f")))]
2895 "TARGET_V9 && TARGET_FPU"
2899 [(set_attr "type" "fpcmove")])
2901 (define_insn "*movdf_cc_sp64"
2902 [(set (match_operand:DF 0 "register_operand" "=e,e")
2903 (if_then_else:DF (match_operator 1 "comparison_operator"
2904 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2906 (match_operand:DF 3 "register_operand" "e,0")
2907 (match_operand:DF 4 "register_operand" "0,e")))]
2908 "TARGET_V9 && TARGET_FPU"
2912 [(set_attr "type" "fpcmove")])
2914 (define_insn "*movtf_cc_sp64"
2915 [(set (match_operand:TF 0 "register_operand" "=e,e")
2916 (if_then_else:TF (match_operator 1 "comparison_operator"
2917 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
2919 (match_operand:TF 3 "register_operand" "e,0")
2920 (match_operand:TF 4 "register_operand" "0,e")))]
2921 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2925 [(set_attr "type" "fpcmove")])
2927 (define_insn "*movqi_cc_reg_sp64"
2928 [(set (match_operand:QI 0 "register_operand" "=r,r")
2929 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
2930 [(match_operand:DI 2 "register_operand" "r,r")
2932 (match_operand:QI 3 "arith10_operand" "rM,0")
2933 (match_operand:QI 4 "arith10_operand" "0,rM")))]
2938 [(set_attr "type" "cmove")])
2940 (define_insn "*movhi_cc_reg_sp64"
2941 [(set (match_operand:HI 0 "register_operand" "=r,r")
2942 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
2943 [(match_operand:DI 2 "register_operand" "r,r")
2945 (match_operand:HI 3 "arith10_operand" "rM,0")
2946 (match_operand:HI 4 "arith10_operand" "0,rM")))]
2951 [(set_attr "type" "cmove")])
2953 (define_insn "*movsi_cc_reg_sp64"
2954 [(set (match_operand:SI 0 "register_operand" "=r,r")
2955 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
2956 [(match_operand:DI 2 "register_operand" "r,r")
2958 (match_operand:SI 3 "arith10_operand" "rM,0")
2959 (match_operand:SI 4 "arith10_operand" "0,rM")))]
2964 [(set_attr "type" "cmove")])
2966 ;; ??? The constraints of operands 3,4 need work.
2967 (define_insn "*movdi_cc_reg_sp64"
2968 [(set (match_operand:DI 0 "register_operand" "=r,r")
2969 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
2970 [(match_operand:DI 2 "register_operand" "r,r")
2972 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
2973 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
2978 [(set_attr "type" "cmove")])
2980 (define_insn "*movsf_cc_reg_sp64"
2981 [(set (match_operand:SF 0 "register_operand" "=f,f")
2982 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
2983 [(match_operand:DI 2 "register_operand" "r,r")
2985 (match_operand:SF 3 "register_operand" "f,0")
2986 (match_operand:SF 4 "register_operand" "0,f")))]
2987 "TARGET_ARCH64 && TARGET_FPU"
2991 [(set_attr "type" "fpcmove")])
2993 (define_insn "*movdf_cc_reg_sp64"
2994 [(set (match_operand:DF 0 "register_operand" "=e,e")
2995 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
2996 [(match_operand:DI 2 "register_operand" "r,r")
2998 (match_operand:DF 3 "register_operand" "e,0")
2999 (match_operand:DF 4 "register_operand" "0,e")))]
3000 "TARGET_ARCH64 && TARGET_FPU"
3004 [(set_attr "type" "fpcmove")])
3006 (define_insn "*movtf_cc_reg_sp64"
3007 [(set (match_operand:TF 0 "register_operand" "=e,e")
3008 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3009 [(match_operand:DI 2 "register_operand" "r,r")
3011 (match_operand:TF 3 "register_operand" "e,0")
3012 (match_operand:TF 4 "register_operand" "0,e")))]
3013 "TARGET_ARCH64 && TARGET_FPU"
3017 [(set_attr "type" "fpcmove")])
3019 ;;- zero extension instructions
3021 ;; These patterns originally accepted general_operands, however, slightly
3022 ;; better code is generated by only accepting register_operands, and then
3023 ;; letting combine generate the ldu[hb] insns.
3025 (define_expand "zero_extendhisi2"
3026 [(set (match_operand:SI 0 "register_operand" "")
3027 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3031 rtx temp = gen_reg_rtx (SImode);
3032 rtx shift_16 = GEN_INT (16);
3033 int op1_subword = 0;
3035 if (GET_CODE (operand1) == SUBREG)
3037 op1_subword = SUBREG_WORD (operand1);
3038 operand1 = XEXP (operand1, 0);
3041 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
3044 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3048 (define_insn "*zero_extendhisi2_insn"
3049 [(set (match_operand:SI 0 "register_operand" "=r")
3050 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3053 [(set_attr "type" "load")])
3055 (define_expand "zero_extendqihi2"
3056 [(set (match_operand:HI 0 "register_operand" "")
3057 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3061 (define_insn "*zero_extendqihi2_insn"
3062 [(set (match_operand:HI 0 "register_operand" "=r,r")
3063 (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))]
3064 "GET_CODE (operands[1]) != CONST_INT"
3068 [(set_attr "type" "unary,load")
3069 (set_attr "length" "1")])
3071 (define_expand "zero_extendqisi2"
3072 [(set (match_operand:SI 0 "register_operand" "")
3073 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3077 (define_insn "*zero_extendqisi2_insn"
3078 [(set (match_operand:SI 0 "register_operand" "=r,r")
3079 (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))]
3080 "GET_CODE (operands[1]) != CONST_INT"
3084 [(set_attr "type" "unary,load")
3085 (set_attr "length" "1")])
3087 (define_expand "zero_extendqidi2"
3088 [(set (match_operand:DI 0 "register_operand" "")
3089 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3093 (define_insn "*zero_extendqidi2_insn"
3094 [(set (match_operand:DI 0 "register_operand" "=r,r")
3095 (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))]
3096 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3100 [(set_attr "type" "unary,load")
3101 (set_attr "length" "1")])
3103 (define_expand "zero_extendhidi2"
3104 [(set (match_operand:DI 0 "register_operand" "")
3105 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3109 rtx temp = gen_reg_rtx (DImode);
3110 rtx shift_48 = GEN_INT (48);
3111 int op1_subword = 0;
3113 if (GET_CODE (operand1) == SUBREG)
3115 op1_subword = SUBREG_WORD (operand1);
3116 operand1 = XEXP (operand1, 0);
3119 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
3122 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3126 (define_insn "*zero_extendhidi2_insn"
3127 [(set (match_operand:DI 0 "register_operand" "=r")
3128 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3131 [(set_attr "type" "load")])
3133 ;; ??? Write truncdisi pattern using sra?
3135 (define_expand "zero_extendsidi2"
3136 [(set (match_operand:DI 0 "register_operand" "")
3137 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3141 (define_insn "*zero_extendsidi2_insn"
3142 [(set (match_operand:DI 0 "register_operand" "=r,r")
3143 (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
3144 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3148 [(set_attr "type" "unary,load")
3149 (set_attr "length" "1")])
3151 ;; Simplify comparisons of extended values.
3153 (define_insn "*cmp_zero_extendqisi2"
3155 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3158 "andcc %0,0xff,%%g0"
3159 [(set_attr "type" "compare")])
3161 (define_insn "*cmp_zero_extendqisi2_set"
3163 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3165 (set (match_operand:SI 0 "register_operand" "=r")
3166 (zero_extend:SI (match_dup 1)))]
3169 [(set_attr "type" "unary")])
3171 ;; Similarly, handle SI->QI mode truncation followed by a compare.
3173 (define_insn "*cmp_siqi_trunc"
3175 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
3178 "andcc %0,0xff,%%g0"
3179 [(set_attr "type" "compare")])
3181 (define_insn "*cmp_siqi_trunc_set"
3183 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
3185 (set (match_operand:QI 0 "register_operand" "=r")
3189 [(set_attr "type" "unary")])
3191 ;;- sign extension instructions
3193 ;; These patterns originally accepted general_operands, however, slightly
3194 ;; better code is generated by only accepting register_operands, and then
3195 ;; letting combine generate the lds[hb] insns.
3197 (define_expand "extendhisi2"
3198 [(set (match_operand:SI 0 "register_operand" "")
3199 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3203 rtx temp = gen_reg_rtx (SImode);
3204 rtx shift_16 = GEN_INT (16);
3205 int op1_subword = 0;
3207 if (GET_CODE (operand1) == SUBREG)
3209 op1_subword = SUBREG_WORD (operand1);
3210 operand1 = XEXP (operand1, 0);
3213 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
3216 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3220 (define_insn "*sign_extendhisi2_insn"
3221 [(set (match_operand:SI 0 "register_operand" "=r")
3222 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3225 [(set_attr "type" "sload")])
3227 (define_expand "extendqihi2"
3228 [(set (match_operand:HI 0 "register_operand" "")
3229 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3233 rtx temp = gen_reg_rtx (SImode);
3234 rtx shift_24 = GEN_INT (24);
3235 int op1_subword = 0;
3236 int op0_subword = 0;
3238 if (GET_CODE (operand1) == SUBREG)
3240 op1_subword = SUBREG_WORD (operand1);
3241 operand1 = XEXP (operand1, 0);
3243 if (GET_CODE (operand0) == SUBREG)
3245 op0_subword = SUBREG_WORD (operand0);
3246 operand0 = XEXP (operand0, 0);
3248 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
3251 if (GET_MODE (operand0) != SImode)
3252 operand0 = gen_rtx (SUBREG, SImode, operand0, op0_subword);
3253 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3257 (define_insn "*sign_extendqihi2_insn"
3258 [(set (match_operand:HI 0 "register_operand" "=r")
3259 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3262 [(set_attr "type" "sload")])
3264 (define_expand "extendqisi2"
3265 [(set (match_operand:SI 0 "register_operand" "")
3266 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3270 rtx temp = gen_reg_rtx (SImode);
3271 rtx shift_24 = GEN_INT (24);
3272 int op1_subword = 0;
3274 if (GET_CODE (operand1) == SUBREG)
3276 op1_subword = SUBREG_WORD (operand1);
3277 operand1 = XEXP (operand1, 0);
3280 emit_insn (gen_ashlsi3 (temp, gen_rtx (SUBREG, SImode, operand1,
3283 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3287 (define_insn "*sign_extendqisi2_insn"
3288 [(set (match_operand:SI 0 "register_operand" "=r")
3289 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3292 [(set_attr "type" "sload")])
3294 (define_expand "extendqidi2"
3295 [(set (match_operand:DI 0 "register_operand" "")
3296 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3300 rtx temp = gen_reg_rtx (DImode);
3301 rtx shift_56 = GEN_INT (56);
3302 int op1_subword = 0;
3304 if (GET_CODE (operand1) == SUBREG)
3306 op1_subword = SUBREG_WORD (operand1);
3307 operand1 = XEXP (operand1, 0);
3310 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
3313 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3317 (define_insn "*sign_extendqidi2_insn"
3318 [(set (match_operand:DI 0 "register_operand" "=r")
3319 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3322 [(set_attr "type" "sload")])
3324 (define_expand "extendhidi2"
3325 [(set (match_operand:DI 0 "register_operand" "")
3326 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3330 rtx temp = gen_reg_rtx (DImode);
3331 rtx shift_48 = GEN_INT (48);
3332 int op1_subword = 0;
3334 if (GET_CODE (operand1) == SUBREG)
3336 op1_subword = SUBREG_WORD (operand1);
3337 operand1 = XEXP (operand1, 0);
3340 emit_insn (gen_ashldi3 (temp, gen_rtx (SUBREG, DImode, operand1,
3343 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3347 (define_insn "*sign_extendhidi2_insn"
3348 [(set (match_operand:DI 0 "register_operand" "=r")
3349 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3352 [(set_attr "type" "load")])
3354 (define_expand "extendsidi2"
3355 [(set (match_operand:DI 0 "register_operand" "")
3356 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3360 (define_insn "*sign_extendsidi2_insn"
3361 [(set (match_operand:DI 0 "register_operand" "=r,r")
3362 (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))]
3367 [(set_attr "type" "unary,sload")
3368 (set_attr "length" "1")])
3370 ;; Special pattern for optimizing bit-field compares. This is needed
3371 ;; because combine uses this as a canonical form.
3373 (define_insn "*cmp_zero_extract"
3376 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3377 (match_operand:SI 1 "small_int" "n")
3378 (match_operand:SI 2 "small_int" "n"))
3380 "INTVAL (operands[2]) > 19"
3383 int len = INTVAL (operands[1]);
3384 int pos = 32 - INTVAL (operands[2]) - len;
3385 unsigned mask = ((1 << len) - 1) << pos;
3387 operands[1] = GEN_INT (mask);
3388 return \"andcc %0,%1,%%g0\";
3391 (define_insn "*cmp_zero_extract_sp64"
3394 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3395 (match_operand:SI 1 "small_int" "n")
3396 (match_operand:SI 2 "small_int" "n"))
3398 "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3401 int len = INTVAL (operands[1]);
3402 int pos = 64 - INTVAL (operands[2]) - len;
3403 unsigned HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3405 operands[1] = GEN_INT (mask);
3406 return \"andcc %0,%1,%%g0\";
3409 ;; Conversions between float, double and long double.
3411 (define_insn "extendsfdf2"
3412 [(set (match_operand:DF 0 "register_operand" "=e")
3414 (match_operand:SF 1 "register_operand" "f")))]
3417 [(set_attr "type" "fp")])
3419 (define_insn "extendsftf2"
3420 [(set (match_operand:TF 0 "register_operand" "=e")
3422 (match_operand:SF 1 "register_operand" "f")))]
3423 "TARGET_FPU && TARGET_HARD_QUAD"
3425 [(set_attr "type" "fp")])
3427 (define_insn "extenddftf2"
3428 [(set (match_operand:TF 0 "register_operand" "=e")
3430 (match_operand:DF 1 "register_operand" "e")))]
3431 "TARGET_FPU && TARGET_HARD_QUAD"
3433 [(set_attr "type" "fp")])
3435 (define_insn "truncdfsf2"
3436 [(set (match_operand:SF 0 "register_operand" "=f")
3438 (match_operand:DF 1 "register_operand" "e")))]
3441 [(set_attr "type" "fp")])
3443 (define_insn "trunctfsf2"
3444 [(set (match_operand:SF 0 "register_operand" "=f")
3446 (match_operand:TF 1 "register_operand" "e")))]
3447 "TARGET_FPU && TARGET_HARD_QUAD"
3449 [(set_attr "type" "fp")])
3451 (define_insn "trunctfdf2"
3452 [(set (match_operand:DF 0 "register_operand" "=e")
3454 (match_operand:TF 1 "register_operand" "e")))]
3455 "TARGET_FPU && TARGET_HARD_QUAD"
3457 [(set_attr "type" "fp")])
3459 ;; Conversion between fixed point and floating point.
3461 (define_insn "floatsisf2"
3462 [(set (match_operand:SF 0 "register_operand" "=f")
3463 (float:SF (match_operand:SI 1 "register_operand" "f")))]
3466 [(set_attr "type" "fp")])
3468 (define_insn "floatsidf2"
3469 [(set (match_operand:DF 0 "register_operand" "=e")
3470 (float:DF (match_operand:SI 1 "register_operand" "f")))]
3473 [(set_attr "type" "fp")])
3475 (define_insn "floatsitf2"
3476 [(set (match_operand:TF 0 "register_operand" "=e")
3477 (float:TF (match_operand:SI 1 "register_operand" "f")))]
3478 "TARGET_FPU && TARGET_HARD_QUAD"
3480 [(set_attr "type" "fp")])
3482 ;; Now the same for 64 bit sources.
3483 ;; ??? We cannot put DImode values in fp regs (see below near fix_truncdfsi2).
3485 (define_expand "floatdisf2"
3486 [(parallel [(set (match_operand:SF 0 "register_operand" "")
3487 (float:SF (match_operand:DI 1 "general_operand" "")))
3488 (clobber (match_dup 2))
3489 (clobber (match_dup 3))])]
3490 "TARGET_ARCH64 && TARGET_FPU"
3493 operands[2] = gen_reg_rtx (DFmode);
3494 operands[3] = sparc64_fpconv_stack_temp ();
3497 (define_expand "floatdidf2"
3498 [(parallel [(set (match_operand:DF 0 "register_operand" "")
3499 (float:DF (match_operand:DI 1 "general_operand" "")))
3500 (clobber (match_dup 2))
3501 (clobber (match_dup 3))])]
3502 "TARGET_ARCH64 && TARGET_FPU"
3505 operands[2] = gen_reg_rtx (DFmode);
3506 operands[3] = sparc64_fpconv_stack_temp ();
3509 (define_expand "floatditf2"
3510 [(parallel [(set (match_operand:TF 0 "register_operand" "")
3511 (float:TF (match_operand:DI 1 "general_operand" "")))
3512 (clobber (match_dup 2))
3513 (clobber (match_dup 3))])]
3514 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3517 operands[2] = gen_reg_rtx (DFmode);
3518 operands[3] = sparc64_fpconv_stack_temp ();
3521 (define_insn "*floatdisf2_insn"
3522 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
3523 (float:SF (match_operand:DI 1 "general_operand" "rm")))
3524 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3525 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3526 "TARGET_ARCH64 && TARGET_FPU"
3529 if (GET_CODE (operands[1]) == MEM)
3530 output_asm_insn (\"ldd %1,%2\", operands);
3532 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3533 return \"fxtos %2,%0\";
3535 [(set_attr "type" "fp")
3536 (set_attr "length" "3")])
3538 (define_insn "*floatdidf2_insn"
3539 [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
3540 (float:DF (match_operand:DI 1 "general_operand" "rm")))
3541 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3542 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3543 "TARGET_ARCH64 && TARGET_FPU"
3546 if (GET_CODE (operands[1]) == MEM)
3547 output_asm_insn (\"ldd %1,%2\", operands);
3549 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3550 return \"fxtod %2,%0\";
3552 [(set_attr "type" "fp")
3553 (set_attr "length" "3")])
3555 (define_insn "*floatditf2_insn"
3556 [(parallel [(set (match_operand:TF 0 "register_operand" "=e")
3557 (float:TF (match_operand:DI 1 "general_operand" "rm")))
3558 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3559 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3560 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3563 if (GET_CODE (operands[1]) == MEM)
3564 output_asm_insn (\"ldd %1,%2\", operands);
3566 output_asm_insn (\"stx %1,%3\;ldd %3,%2\", operands);
3567 return \"fxtoq %2,%0\";
3569 [(set_attr "type" "fp")
3570 (set_attr "length" "3")])
3572 ;; ??? Ideally, these are what we would like to use.
3574 (define_insn "floatdisf2_sp64"
3575 [(set (match_operand:SF 0 "register_operand" "=f")
3576 (float:SF (match_operand:DI 1 "register_operand" "e")))]
3577 "0 && TARGET_ARCH64 && TARGET_FPU"
3579 [(set_attr "type" "fp")])
3581 (define_insn "floatdidf2_sp64"
3582 [(set (match_operand:DF 0 "register_operand" "=e")
3583 (float:DF (match_operand:DI 1 "register_operand" "e")))]
3584 "0 && TARGET_ARCH64 && TARGET_FPU"
3586 [(set_attr "type" "fp")])
3588 (define_insn "floatditf2_sp64"
3589 [(set (match_operand:TF 0 "register_operand" "=e")
3590 (float:TF (match_operand:DI 1 "register_operand" "e")))]
3591 "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3593 [(set_attr "type" "fp")])
3595 ;; Convert a float to an actual integer.
3596 ;; Truncation is performed as part of the conversion.
3598 (define_insn "fix_truncsfsi2"
3599 [(set (match_operand:SI 0 "register_operand" "=f")
3600 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3603 [(set_attr "type" "fp")])
3605 (define_insn "fix_truncdfsi2"
3606 [(set (match_operand:SI 0 "register_operand" "=f")
3607 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3610 [(set_attr "type" "fp")])
3612 (define_insn "fix_trunctfsi2"
3613 [(set (match_operand:SI 0 "register_operand" "=f")
3614 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3615 "TARGET_FPU && TARGET_HARD_QUAD"
3617 [(set_attr "type" "fp")])
3619 ;; Now the same, for 64-bit targets
3620 ;; ??? We try to work around an interesting problem.
3621 ;; If gcc tries to do a subreg on the result it will get the wrong answer:
3622 ;; "(subreg:SI (reg:DI M int-reg) 0)" is the same as
3623 ;; "(subreg:SI (reg:DI N float-reg) 1)", but gcc does not know how to change
3624 ;; the "0" to a "1". One could enhance alter_subreg but it is not clear how to
3627 (define_expand "fix_truncsfdi2"
3628 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3629 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
3630 (clobber (match_dup 2))
3631 (clobber (match_dup 3))])]
3632 "TARGET_ARCH64 && TARGET_FPU"
3635 operands[2] = gen_reg_rtx (DFmode);
3636 operands[3] = sparc64_fpconv_stack_temp ();
3639 (define_expand "fix_truncdfdi2"
3640 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3641 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
3642 (clobber (match_dup 2))
3643 (clobber (match_dup 3))])]
3644 "TARGET_ARCH64 && TARGET_FPU"
3647 operands[2] = gen_reg_rtx (DFmode);
3648 operands[3] = sparc64_fpconv_stack_temp ();
3651 (define_expand "fix_trunctfdi2"
3652 [(parallel [(set (match_operand:DI 0 "general_operand" "")
3653 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" ""))))
3654 (clobber (match_dup 2))
3655 (clobber (match_dup 3))])]
3656 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3659 operands[2] = gen_reg_rtx (DFmode);
3660 operands[3] = sparc64_fpconv_stack_temp ();
3663 (define_insn "*fix_truncsfdi2_insn"
3664 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3665 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
3666 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3667 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3668 "TARGET_ARCH64 && TARGET_FPU"
3671 output_asm_insn (\"fstox %1,%2\", operands);
3672 if (GET_CODE (operands[0]) == MEM)
3673 return \"std %2,%0\";
3675 return \"std %2,%3\;ldx %3,%0\";
3677 [(set_attr "type" "fp")
3678 (set_attr "length" "3")])
3680 (define_insn "*fix_truncdfdi2_insn"
3681 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3682 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))
3683 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3684 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3685 "TARGET_ARCH64 && TARGET_FPU"
3688 output_asm_insn (\"fdtox %1,%2\", operands);
3689 if (GET_CODE (operands[0]) == MEM)
3690 return \"std %2,%0\";
3692 return \"std %2,%3\;ldx %3,%0\";
3694 [(set_attr "type" "fp")
3695 (set_attr "length" "3")])
3697 (define_insn "*fix_trunctfdi2_insn"
3698 [(parallel [(set (match_operand:DI 0 "general_operand" "=rm")
3699 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))
3700 (clobber (match_operand:DF 2 "register_operand" "=&e"))
3701 (clobber (match_operand:DI 3 "memory_operand" "m"))])]
3702 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3705 output_asm_insn (\"fqtox %1,%2\", operands);
3706 if (GET_CODE (operands[0]) == MEM)
3707 return \"std %2,%0\";
3709 return \"std %2,%3\;ldx %3,%0\";
3711 [(set_attr "type" "fp")
3712 (set_attr "length" "3")])
3714 ;; ??? Ideally, these are what we would like to use.
3716 (define_insn "fix_truncsfdi2_sp64"
3717 [(set (match_operand:DI 0 "register_operand" "=e")
3718 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3719 "0 && TARGET_ARCH64 && TARGET_FPU"
3721 [(set_attr "type" "fp")])
3723 (define_insn "fix_truncdfdi2_sp64"
3724 [(set (match_operand:DI 0 "register_operand" "=e")
3725 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3726 "0 && TARGET_ARCH64 && TARGET_FPU"
3728 [(set_attr "type" "fp")])
3730 (define_insn "fix_trunctfdi2_sp64"
3731 [(set (match_operand:DI 0 "register_operand" "=e")
3732 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
3733 "0 && TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3735 [(set_attr "type" "fp")])
3737 ;;- arithmetic instructions
3739 (define_expand "adddi3"
3740 [(set (match_operand:DI 0 "register_operand" "=r")
3741 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3742 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3746 if (! TARGET_ARCH64)
3748 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3749 gen_rtx (SET, VOIDmode, operands[0],
3750 gen_rtx (PLUS, DImode, operands[1],
3752 gen_rtx (CLOBBER, VOIDmode,
3753 gen_rtx (REG, SImode, SPARC_ICC_REG)))));
3758 (define_insn "*adddi3_sp32"
3759 [(set (match_operand:DI 0 "register_operand" "=r")
3760 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3761 (match_operand:DI 2 "arith_double_operand" "rHI")))
3762 (clobber (reg:SI 100))]
3766 rtx op2 = operands[2];
3768 if (GET_CODE (op2) == CONST_INT
3769 || GET_CODE (op2) == CONST_DOUBLE)
3772 xoperands[0] = operands[0];
3773 xoperands[1] = operands[1];
3774 if (WORDS_BIG_ENDIAN)
3775 split_double (op2, &xoperands[2], &xoperands[3]);
3777 split_double (op2, &xoperands[3], &xoperands[2]);
3778 if (xoperands[3] == const0_rtx && xoperands[0] == xoperands[1])
3779 output_asm_insn (\"add %H1,%2,%H0\", xoperands);
3781 output_asm_insn (\"addcc %L1,%3,%L0\;addx %H1,%2,%H0\", xoperands);
3784 return \"addcc %L1,%L2,%L0\;addx %H1,%H2,%H0\";
3786 [(set_attr "length" "2")])
3789 [(set (match_operand:DI 0 "register_operand" "=r")
3790 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3791 (match_operand:DI 2 "register_operand" "r")))
3792 (clobber (reg:SI 100))]
3794 "addcc %L2,%1,%L0\;addx %H2,0,%H0"
3795 [(set_attr "type" "multi")])
3797 (define_insn "*adddi3_sp64"
3798 [(set (match_operand:DI 0 "register_operand" "=r")
3799 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3800 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3804 (define_insn "addsi3"
3805 [(set (match_operand:SI 0 "register_operand" "=r,d")
3806 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
3807 (match_operand:SI 2 "arith_operand" "rI,d")))]
3812 [(set_attr "type" "ialu,fp")])
3814 (define_insn "*cmp_cc_plus"
3815 [(set (reg:CC_NOOV 100)
3816 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3817 (match_operand:SI 1 "arith_operand" "rI"))
3821 [(set_attr "type" "compare")])
3823 (define_insn "*cmp_ccx_plus"
3824 [(set (reg:CCX_NOOV 100)
3825 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
3826 (match_operand:DI 1 "arith_double_operand" "rHI"))
3830 [(set_attr "type" "compare")])
3832 (define_insn "*cmp_cc_plus_set"
3833 [(set (reg:CC_NOOV 100)
3834 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3835 (match_operand:SI 2 "arith_operand" "rI"))
3837 (set (match_operand:SI 0 "register_operand" "=r")
3838 (plus:SI (match_dup 1) (match_dup 2)))]
3842 (define_insn "*cmp_ccx_plus_set"
3843 [(set (reg:CCX_NOOV 100)
3844 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3845 (match_operand:DI 2 "arith_double_operand" "rHI"))
3847 (set (match_operand:DI 0 "register_operand" "=r")
3848 (plus:DI (match_dup 1) (match_dup 2)))]
3852 (define_expand "subdi3"
3853 [(set (match_operand:DI 0 "register_operand" "=r")
3854 (minus:DI (match_operand:DI 1 "register_operand" "r")
3855 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3859 if (! TARGET_ARCH64)
3861 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
3862 gen_rtx (SET, VOIDmode, operands[0],
3863 gen_rtx (MINUS, DImode, operands[1],
3865 gen_rtx (CLOBBER, VOIDmode,
3866 gen_rtx (REG, SImode, SPARC_ICC_REG)))));
3871 (define_insn "*subdi3_sp32"
3872 [(set (match_operand:DI 0 "register_operand" "=r")
3873 (minus:DI (match_operand:DI 1 "register_operand" "r")
3874 (match_operand:DI 2 "arith_double_operand" "rHI")))
3875 (clobber (reg:SI 100))]
3879 rtx op2 = operands[2];
3881 if (GET_CODE (op2) == CONST_INT
3882 || GET_CODE (op2) == CONST_DOUBLE)
3885 xoperands[0] = operands[0];
3886 xoperands[1] = operands[1];
3887 if (WORDS_BIG_ENDIAN)
3888 split_double (op2, &xoperands[2], &xoperands[3]);
3890 split_double (op2, &xoperands[3], &xoperands[2]);
3891 if (xoperands[3] == const0_rtx && xoperands[0] == xoperands[1])
3892 output_asm_insn (\"sub %H1,%2,%H0\", xoperands);
3894 output_asm_insn (\"subcc %L1,%3,%L0\;subx %H1,%2,%H0\", xoperands);
3897 return \"subcc %L1,%L2,%L0\;subx %H1,%H2,%H0\";
3899 [(set_attr "length" "2")])
3902 [(set (match_operand:DI 0 "register_operand" "=r")
3903 (minus:DI (match_operand:DI 1 "register_operand" "r")
3904 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3905 (clobber (reg:SI 100))]
3907 "subcc %L1,%2,%L0\;addx %H1,0,%H0"
3908 [(set_attr "type" "multi")])
3910 (define_insn "*subdi3_sp64"
3911 [(set (match_operand:DI 0 "register_operand" "=r")
3912 (minus:DI (match_operand:DI 1 "register_operand" "r")
3913 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3917 (define_insn "subsi3"
3918 [(set (match_operand:SI 0 "register_operand" "=r,d")
3919 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
3920 (match_operand:SI 2 "arith_operand" "rI,d")))]
3925 [(set_attr "type" "ialu,fp")])
3927 (define_insn "*cmp_minus_cc"
3928 [(set (reg:CC_NOOV 100)
3929 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r")
3930 (match_operand:SI 1 "arith_operand" "rI"))
3934 [(set_attr "type" "compare")])
3936 (define_insn "*cmp_minus_ccx"
3937 [(set (reg:CCX_NOOV 100)
3938 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3939 (match_operand:DI 1 "arith_double_operand" "rHI"))
3943 [(set_attr "type" "compare")])
3945 (define_insn "*cmp_minus_cc_set"
3946 [(set (reg:CC_NOOV 100)
3947 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r")
3948 (match_operand:SI 2 "arith_operand" "rI"))
3950 (set (match_operand:SI 0 "register_operand" "=r")
3951 (minus:SI (match_dup 1) (match_dup 2)))]
3955 (define_insn "*cmp_minus_ccx_set"
3956 [(set (reg:CCX_NOOV 100)
3957 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3958 (match_operand:DI 2 "arith_double_operand" "rHI"))
3960 (set (match_operand:DI 0 "register_operand" "=r")
3961 (minus:DI (match_dup 1) (match_dup 2)))]
3965 ;; Integer Multiply/Divide.
3967 ;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't
3968 ;; we used. We still use them in 32 bit v9 compilers.
3969 ;; The 64 bit v9 compiler will (/should) widen the args and use muldi3.
3971 (define_insn "mulsi3"
3972 [(set (match_operand:SI 0 "register_operand" "=r")
3973 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3974 (match_operand:SI 2 "arith_operand" "rI")))]
3977 [(set_attr "type" "imul")])
3979 (define_insn "muldi3"
3980 [(set (match_operand:DI 0 "register_operand" "=r")
3981 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
3982 (match_operand:DI 2 "arith_double_operand" "rHI")))]
3986 ;; It is not known whether this will match.
3988 (define_insn "*cmp_mul_set"
3989 [(set (match_operand:SI 0 "register_operand" "=r")
3990 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3991 (match_operand:SI 2 "arith_operand" "rI")))
3992 (set (reg:CC_NOOV 100)
3993 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
3995 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3997 [(set_attr "type" "imul")])
3999 (define_expand "mulsidi3"
4000 [(set (match_operand:DI 0 "register_operand" "")
4001 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4002 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4006 if (CONSTANT_P (operands[2]))
4008 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
4013 (define_insn "*mulsidi3_sp32"
4014 [(set (match_operand:DI 0 "register_operand" "=r")
4015 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4016 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4020 return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\";
4022 [(set (attr "length")
4023 (if_then_else (eq_attr "isa" "sparclet")
4024 (const_int 1) (const_int 2)))])
4026 ;; Extra pattern, because sign_extend of a constant isn't valid.
4028 (define_insn "const_mulsidi3"
4029 [(set (match_operand:DI 0 "register_operand" "=r")
4030 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4031 (match_operand:SI 2 "small_int" "I")))]
4035 return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\";
4037 [(set (attr "length")
4038 (if_then_else (eq_attr "isa" "sparclet")
4039 (const_int 1) (const_int 2)))])
4041 (define_expand "smulsi3_highpart"
4042 [(set (match_operand:SI 0 "register_operand" "")
4044 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4045 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4050 if (CONSTANT_P (operands[2]))
4052 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4057 (define_insn "*smulsidi3_highpart_sp32"
4058 [(set (match_operand:SI 0 "register_operand" "=r")
4060 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4061 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4064 "smul %1,%2,%%g0\;rd %%y,%0"
4065 [(set_attr "length" "2")])
4067 (define_insn "const_smulsi3_highpart"
4068 [(set (match_operand:SI 0 "register_operand" "=r")
4070 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4071 (match_operand:SI 2 "register_operand" "r"))
4073 "TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET || TARGET_DEPRECATED_V8_INSNS"
4074 "smul %1,%2,%%g0\;rd %%y,%0"
4075 [(set_attr "length" "2")])
4077 (define_expand "umulsidi3"
4078 [(set (match_operand:DI 0 "register_operand" "")
4079 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4080 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4084 if (CONSTANT_P (operands[2]))
4086 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
4091 (define_insn "*umulsidi3_sp32"
4092 [(set (match_operand:DI 0 "register_operand" "=r")
4093 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4094 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4098 return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\";
4100 [(set (attr "length")
4101 (if_then_else (eq_attr "isa" "sparclet")
4102 (const_int 1) (const_int 2)))])
4104 ;; Extra pattern, because sign_extend of a constant isn't valid.
4106 (define_insn "const_umulsidi3"
4107 [(set (match_operand:DI 0 "register_operand" "=r")
4108 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4109 (match_operand:SI 2 "uns_small_int" "")))]
4113 return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\";
4115 [(set (attr "length")
4116 (if_then_else (eq_attr "isa" "sparclet")
4117 (const_int 1) (const_int 2)))])
4119 (define_expand "umulsi3_highpart"
4120 [(set (match_operand:SI 0 "register_operand" "")
4122 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4123 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4128 if (CONSTANT_P (operands[2]))
4130 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4135 (define_insn "*umulsidi3_highpart_sp32"
4136 [(set (match_operand:SI 0 "register_operand" "=r")
4138 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4139 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4142 "umul %1,%2,%%g0\;rd %%y,%0"
4143 [(set_attr "length" "2")])
4145 (define_insn "const_umulsi3_highpart"
4146 [(set (match_operand:SI 0 "register_operand" "=r")
4148 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4149 (match_operand:SI 2 "uns_small_int" ""))
4152 "umul %1,%2,%%g0\;rd %%y,%0"
4153 [(set_attr "length" "2")])
4155 ;; The v8 architecture specifies that there must be 3 instructions between
4156 ;; a y register write and a use of it for correct results.
4158 (define_insn "divsi3"
4159 [(set (match_operand:SI 0 "register_operand" "=r")
4160 (div:SI (match_operand:SI 1 "register_operand" "r")
4161 (match_operand:SI 2 "arith_operand" "rI")))
4162 (clobber (match_scratch:SI 3 "=&r"))]
4163 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4167 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdiv %1,%2,%0\";
4169 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0\";
4171 [(set (attr "length")
4172 (if_then_else (eq_attr "isa" "v9")
4173 (const_int 3) (const_int 6)))])
4175 (define_insn "divdi3"
4176 [(set (match_operand:DI 0 "register_operand" "=r")
4177 (div:DI (match_operand:DI 1 "register_operand" "r")
4178 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4182 ;; It is not known whether this will match.
4184 (define_insn "*cmp_sdiv_cc_set"
4185 [(set (match_operand:SI 0 "register_operand" "=r")
4186 (div:SI (match_operand:SI 1 "register_operand" "r")
4187 (match_operand:SI 2 "arith_operand" "rI")))
4189 (compare:CC (div:SI (match_dup 1) (match_dup 2))
4191 (clobber (match_scratch:SI 3 "=&r"))]
4192 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4196 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdivcc %1,%2,%0\";
4198 return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0\";
4200 [(set (attr "length")
4201 (if_then_else (eq_attr "isa" "v9")
4202 (const_int 3) (const_int 6)))])
4204 (define_insn "udivsi3"
4205 [(set (match_operand:SI 0 "register_operand" "=r")
4206 (udiv:SI (match_operand:SI 1 "register_operand" "r")
4207 (match_operand:SI 2 "arith_operand" "rI")))]
4208 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4212 return \"wr %%g0,%%g0,%%y\;udiv %1,%2,%0\";
4214 return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0\";
4216 [(set (attr "length")
4217 (if_then_else (eq_attr "isa" "v9")
4218 (const_int 2) (const_int 5)))])
4220 (define_insn "udivdi3"
4221 [(set (match_operand:DI 0 "register_operand" "=r")
4222 (udiv:DI (match_operand:DI 1 "register_operand" "r")
4223 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4227 ;; It is not known whether this will match.
4229 (define_insn "*cmp_udiv_cc_set"
4230 [(set (match_operand:SI 0 "register_operand" "=r")
4231 (udiv:SI (match_operand:SI 1 "register_operand" "r")
4232 (match_operand:SI 2 "arith_operand" "rI")))
4234 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
4236 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4240 return \"wr %%g0,%%g0,%%y\;udivcc %1,%2,%0\";
4242 return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0\";
4244 [(set (attr "length")
4245 (if_then_else (eq_attr "isa" "v9")
4246 (const_int 2) (const_int 5)))])
4248 ; sparclet multiply/accumulate insns
4250 (define_insn "*smacsi"
4251 [(set (match_operand:SI 0 "register_operand" "=r")
4252 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4253 (match_operand:SI 2 "arith_operand" "rI"))
4254 (match_operand:SI 3 "register_operand" "0")))]
4257 [(set_attr "type" "imul")])
4259 (define_insn "*smacdi"
4260 [(set (match_operand:DI 0 "register_operand" "=r")
4261 (plus:DI (mult:DI (sign_extend:DI
4262 (match_operand:SI 1 "register_operand" "%r"))
4264 (match_operand:SI 2 "register_operand" "r")))
4265 (match_operand:DI 3 "register_operand" "0")))]
4268 [(set_attr "type" "imul")])
4270 (define_insn "*umacdi"
4271 [(set (match_operand:DI 0 "register_operand" "=r")
4272 (plus:DI (mult:DI (zero_extend:DI
4273 (match_operand:SI 1 "register_operand" "%r"))
4275 (match_operand:SI 2 "register_operand" "r")))
4276 (match_operand:DI 3 "register_operand" "0")))]
4279 [(set_attr "type" "imul")])
4281 ;;- Boolean instructions
4282 ;; We define DImode `and' so with DImode `not' we can get
4283 ;; DImode `andn'. Other combinations are possible.
4285 (define_expand "anddi3"
4286 [(set (match_operand:DI 0 "register_operand" "")
4287 (and:DI (match_operand:DI 1 "arith_double_operand" "")
4288 (match_operand:DI 2 "arith_double_operand" "")))]
4292 (define_insn "*anddi3_sp32"
4293 [(set (match_operand:DI 0 "register_operand" "=r,b")
4294 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
4295 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
4299 rtx op2 = operands[2];
4301 if (which_alternative == 1)
4302 return \"fand %1,%2,%0\";
4304 if (GET_CODE (op2) == CONST_INT
4305 || GET_CODE (op2) == CONST_DOUBLE)
4308 xoperands[0] = operands[0];
4309 xoperands[1] = operands[1];
4310 if (WORDS_BIG_ENDIAN)
4311 split_double (op2, &xoperands[2], &xoperands[3]);
4313 split_double (op2, &xoperands[3], &xoperands[2]);
4314 output_asm_insn (\"and %L1,%3,%L0\;and %H1,%2,%H0\", xoperands);
4317 return \"and %1,%2,%0\;and %R1,%R2,%R0\";
4319 [(set_attr "length" "2,1")])
4321 (define_insn "*anddi3_sp64"
4322 [(set (match_operand:DI 0 "register_operand" "=r")
4323 (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4324 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4328 (define_insn "andsi3"
4329 [(set (match_operand:SI 0 "register_operand" "=r,d")
4330 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
4331 (match_operand:SI 2 "arith_operand" "rI,d")))]
4336 [(set_attr "type" "ialu,fp")])
4339 [(set (match_operand:SI 0 "register_operand" "")
4340 (and:SI (match_operand:SI 1 "register_operand" "")
4341 (match_operand:SI 2 "" "")))
4342 (clobber (match_operand:SI 3 "register_operand" ""))]
4343 "GET_CODE (operands[2]) == CONST_INT
4344 && !SMALL_INT (operands[2])
4345 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4346 [(set (match_dup 3) (match_dup 4))
4347 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4350 operands[4] = GEN_INT (~INTVAL (operands[2]));
4353 (define_insn "*and_not_di_sp32"
4354 [(set (match_operand:DI 0 "register_operand" "=r,b")
4355 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
4356 (match_operand:DI 2 "register_operand" "r,b")))]
4359 andn %2,%1,%0\;andn %R2,%R1,%R0
4361 [(set_attr "length" "2,1")])
4363 (define_insn "*and_not_di_sp64"
4364 [(set (match_operand:DI 0 "register_operand" "=r")
4365 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4366 (match_operand:DI 2 "register_operand" "r")))]
4370 (define_insn "*and_not_si"
4371 [(set (match_operand:SI 0 "register_operand" "=r,d")
4372 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
4373 (match_operand:SI 2 "register_operand" "r,d")))]
4378 [(set_attr "type" "ialu,fp")])
4380 (define_expand "iordi3"
4381 [(set (match_operand:DI 0 "register_operand" "")
4382 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4383 (match_operand:DI 2 "arith_double_operand" "")))]
4387 (define_insn "*iordi3_sp32"
4388 [(set (match_operand:DI 0 "register_operand" "=r,b")
4389 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
4390 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
4394 rtx op2 = operands[2];
4396 if (which_alternative == 1)
4397 return \"for %1,%2,%0\";
4399 if (GET_CODE (op2) == CONST_INT
4400 || GET_CODE (op2) == CONST_DOUBLE)
4403 xoperands[0] = operands[0];
4404 xoperands[1] = operands[1];
4405 if (WORDS_BIG_ENDIAN)
4406 split_double (op2, &xoperands[2], &xoperands[3]);
4408 split_double (op2, &xoperands[3], &xoperands[2]);
4409 output_asm_insn (\"or %L1,%3,%L0\;or %H1,%2,%H0\", xoperands);
4412 return \"or %1,%2,%0\;or %R1,%R2,%R0\";
4414 [(set_attr "length" "2,1")])
4416 (define_insn "*iordi3_sp64"
4417 [(set (match_operand:DI 0 "register_operand" "=r")
4418 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4419 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4423 (define_insn "iorsi3"
4424 [(set (match_operand:SI 0 "register_operand" "=r,d")
4425 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
4426 (match_operand:SI 2 "arith_operand" "rI,d")))]
4431 [(set_attr "type" "ialu,fp")])
4434 [(set (match_operand:SI 0 "register_operand" "")
4435 (ior:SI (match_operand:SI 1 "register_operand" "")
4436 (match_operand:SI 2 "" "")))
4437 (clobber (match_operand:SI 3 "register_operand" ""))]
4438 "GET_CODE (operands[2]) == CONST_INT
4439 && !SMALL_INT (operands[2])
4440 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4441 [(set (match_dup 3) (match_dup 4))
4442 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4445 operands[4] = GEN_INT (~INTVAL (operands[2]));
4448 (define_insn "*or_not_di_sp32"
4449 [(set (match_operand:DI 0 "register_operand" "=r,b")
4450 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
4451 (match_operand:DI 2 "register_operand" "r,b")))]
4454 orn %2,%1,%0\;orn %R2,%R1,%R0
4456 [(set_attr "length" "2,1")])
4458 (define_insn "*or_not_di_sp64"
4459 [(set (match_operand:DI 0 "register_operand" "=r")
4460 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4461 (match_operand:DI 2 "register_operand" "r")))]
4465 (define_insn "*or_not_si"
4466 [(set (match_operand:SI 0 "register_operand" "=r,d")
4467 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
4468 (match_operand:SI 2 "register_operand" "r,d")))]
4473 [(set_attr "type" "ialu,fp")])
4475 (define_expand "xordi3"
4476 [(set (match_operand:DI 0 "register_operand" "")
4477 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4478 (match_operand:DI 2 "arith_double_operand" "")))]
4482 (define_insn "*xorsi3_sp32"
4483 [(set (match_operand:DI 0 "register_operand" "=r,b")
4484 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
4485 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
4489 rtx op2 = operands[2];
4491 if (which_alternative == 1)
4492 return \"fxor %1,%2,%0\";
4494 if (GET_CODE (op2) == CONST_INT
4495 || GET_CODE (op2) == CONST_DOUBLE)
4498 xoperands[0] = operands[0];
4499 xoperands[1] = operands[1];
4500 if (WORDS_BIG_ENDIAN)
4501 split_double (op2, &xoperands[2], &xoperands[3]);
4503 split_double (op2, &xoperands[3], &xoperands[2]);
4504 output_asm_insn (\"xor %L1,%3,%L0\;xor %H1,%2,%H0\", xoperands);
4507 return \"xor %1,%2,%0\;xor %R1,%R2,%R0\";
4509 [(set_attr "length" "2,1")])
4511 (define_insn "*xordi3_sp64"
4512 [(set (match_operand:DI 0 "register_operand" "=r")
4513 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ")
4514 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4518 (define_insn "xorsi3"
4519 [(set (match_operand:SI 0 "register_operand" "=r,d")
4520 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
4521 (match_operand:SI 2 "arith_operand" "rI,d")))]
4526 [(set_attr "type" "ialu,fp")])
4529 [(set (match_operand:SI 0 "register_operand" "")
4530 (xor:SI (match_operand:SI 1 "register_operand" "")
4531 (match_operand:SI 2 "" "")))
4532 (clobber (match_operand:SI 3 "register_operand" ""))]
4533 "GET_CODE (operands[2]) == CONST_INT
4534 && !SMALL_INT (operands[2])
4535 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4536 [(set (match_dup 3) (match_dup 4))
4537 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4540 operands[4] = GEN_INT (~INTVAL (operands[2]));
4544 [(set (match_operand:SI 0 "register_operand" "")
4545 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4546 (match_operand:SI 2 "" ""))))
4547 (clobber (match_operand:SI 3 "register_operand" ""))]
4548 "GET_CODE (operands[2]) == CONST_INT
4549 && !SMALL_INT (operands[2])
4550 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
4551 [(set (match_dup 3) (match_dup 4))
4552 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4555 operands[4] = GEN_INT (~INTVAL (operands[2]));
4558 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4559 ;; Combine now canonicalizes to the rightmost expression.
4560 (define_insn "*xor_not_di_sp32"
4561 [(set (match_operand:DI 0 "register_operand" "=r,b")
4562 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
4563 (match_operand:DI 2 "register_operand" "r,b"))))]
4566 xnor %1,%2,%0\;xnor %R1,%R2,%R0
4568 [(set_attr "length" "2,1")
4569 (set_attr "type" "ialu,fp")])
4571 (define_insn "*xor_not_di_sp64"
4572 [(set (match_operand:DI 0 "register_operand" "=r")
4573 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
4574 (match_operand:DI 2 "arith_double_operand" "rHI"))))]
4577 [(set_attr "type" "ialu")])
4579 (define_insn "*xor_not_si"
4580 [(set (match_operand:SI 0 "register_operand" "=r,d")
4581 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
4582 (match_operand:SI 2 "arith_operand" "rI,d"))))]
4587 [(set_attr "type" "ialu,fp")])
4589 ;; These correspond to the above in the case where we also (or only)
4590 ;; want to set the condition code.
4592 (define_insn "*cmp_cc_arith_op"
4595 (match_operator:SI 2 "cc_arithop"
4596 [(match_operand:SI 0 "arith_operand" "%r")
4597 (match_operand:SI 1 "arith_operand" "rI")])
4601 [(set_attr "type" "compare")])
4603 (define_insn "*cmp_ccx_arith_op"
4606 (match_operator:DI 2 "cc_arithop"
4607 [(match_operand:DI 0 "arith_double_operand" "%r")
4608 (match_operand:DI 1 "arith_double_operand" "rHI")])
4612 [(set_attr "type" "compare")])
4614 (define_insn "*cmp_cc_arith_op_set"
4617 (match_operator:SI 3 "cc_arithop"
4618 [(match_operand:SI 1 "arith_operand" "%r")
4619 (match_operand:SI 2 "arith_operand" "rI")])
4621 (set (match_operand:SI 0 "register_operand" "=r")
4626 (define_insn "*cmp_ccx_arith_op_set"
4629 (match_operator:DI 3 "cc_arithop"
4630 [(match_operand:DI 1 "arith_double_operand" "%r")
4631 (match_operand:DI 2 "arith_double_operand" "rHI")])
4633 (set (match_operand:DI 0 "register_operand" "=r")
4638 (define_insn "*cmp_cc_xor_not"
4641 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
4642 (match_operand:SI 1 "arith_operand" "rI")))
4645 "xnorcc %r0,%1,%%g0"
4646 [(set_attr "type" "compare")])
4648 (define_insn "*cmp_ccx_xor_not"
4651 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
4652 (match_operand:DI 1 "arith_double_operand" "rHI")))
4655 "xnorcc %r0,%1,%%g0"
4656 [(set_attr "type" "compare")])
4658 (define_insn "*cmp_cc_xor_not_set"
4661 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4662 (match_operand:SI 2 "arith_operand" "rI")))
4664 (set (match_operand:SI 0 "register_operand" "=r")
4665 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4669 (define_insn "*cmp_ccx_xor_not_set"
4672 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
4673 (match_operand:DI 2 "arith_double_operand" "rHI")))
4675 (set (match_operand:DI 0 "register_operand" "=r")
4676 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4680 (define_insn "*cmp_cc_arith_op_not"
4683 (match_operator:SI 2 "cc_arithopn"
4684 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4685 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
4689 [(set_attr "type" "compare")])
4691 (define_insn "*cmp_ccx_arith_op_not"
4694 (match_operator:DI 2 "cc_arithopn"
4695 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4696 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
4700 [(set_attr "type" "compare")])
4702 (define_insn "*cmp_cc_arith_op_not_set"
4705 (match_operator:SI 3 "cc_arithopn"
4706 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
4707 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
4709 (set (match_operand:SI 0 "register_operand" "=r")
4714 (define_insn "*cmp_ccx_arith_op_not_set"
4717 (match_operator:DI 3 "cc_arithopn"
4718 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4719 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
4721 (set (match_operand:DI 0 "register_operand" "=r")
4726 ;; We cannot use the "neg" pseudo insn because the Sun assembler
4727 ;; does not know how to make it work for constants.
4729 (define_expand "negdi2"
4730 [(set (match_operand:DI 0 "register_operand" "=r")
4731 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4735 if (! TARGET_ARCH64)
4737 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
4738 gen_rtx (SET, VOIDmode, operand0,
4739 gen_rtx (NEG, DImode, operand1)),
4740 gen_rtx (CLOBBER, VOIDmode,
4741 gen_rtx (REG, SImode, SPARC_ICC_REG)))));
4746 (define_insn "*negdi2_sp32"
4747 [(set (match_operand:DI 0 "register_operand" "=r")
4748 (neg:DI (match_operand:DI 1 "register_operand" "r")))
4749 (clobber (reg:SI 100))]
4754 output_asm_insn (\"and %%g0,0,%%g0\", operands);
4755 return \"subcc %%g0,%L1,%L0\;subx %%g0,%H1,%H0\";
4757 [(set_attr "type" "unary")
4758 ;; ??? This is wrong for TARGET_LIVE_G0 but it's not critical.
4759 (set_attr "length" "2")])
4761 (define_insn "*negdi2_sp64"
4762 [(set (match_operand:DI 0 "register_operand" "=r")
4763 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
4766 [(set_attr "type" "unary")
4767 (set_attr "length" "1")])
4769 (define_insn "negsi2"
4770 [(set (match_operand:SI 0 "register_operand" "=r")
4771 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
4776 return \"and %%g0,0,%%g0\;sub %%g0,%1,%0\";
4777 return \"sub %%g0,%1,%0\";
4779 [(set_attr "type" "unary")
4780 (set (attr "length")
4781 (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1)))])
4783 (define_insn "*cmp_cc_neg"
4784 [(set (reg:CC_NOOV 100)
4785 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
4788 "subcc %%g0,%0,%%g0"
4789 [(set_attr "type" "compare")])
4791 (define_insn "*cmp_ccx_neg"
4792 [(set (reg:CCX_NOOV 100)
4793 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4796 "subcc %%g0,%0,%%g0"
4797 [(set_attr "type" "compare")])
4799 (define_insn "*cmp_cc_set_neg"
4800 [(set (reg:CC_NOOV 100)
4801 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
4803 (set (match_operand:SI 0 "register_operand" "=r")
4804 (neg:SI (match_dup 1)))]
4807 [(set_attr "type" "unary")])
4809 (define_insn "*cmp_ccx_set_neg"
4810 [(set (reg:CCX_NOOV 100)
4811 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4813 (set (match_operand:DI 0 "register_operand" "=r")
4814 (neg:DI (match_dup 1)))]
4817 [(set_attr "type" "unary")])
4819 ;; We cannot use the "not" pseudo insn because the Sun assembler
4820 ;; does not know how to make it work for constants.
4821 (define_expand "one_cmpldi2"
4822 [(set (match_operand:DI 0 "register_operand" "")
4823 (not:DI (match_operand:DI 1 "register_operand" "")))]
4827 (define_insn "*one_cmpldi2_sp32"
4828 [(set (match_operand:DI 0 "register_operand" "=r,b")
4829 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
4832 xnor %1,0,%0\;xnor %R1,0,%R0
4834 [(set_attr "type" "unary,fp")
4835 (set_attr "length" "2,1")])
4837 (define_insn "*one_cmpldi2_sp64"
4838 [(set (match_operand:DI 0 "register_operand" "=r")
4839 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))]
4842 [(set_attr "type" "unary")])
4844 (define_insn "one_cmplsi2"
4845 [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4846 (not:SI (match_operand:SI 1 "arith_operand" "r,I,d")))]
4850 if (which_alternative == 0)
4851 return \"xnor %1,0,%0\";
4852 if (which_alternative == 1)
4853 return \"fnot1s %1,%0\";
4855 output_asm_insn (\"and %%g0,0,%%g0\", operands);
4856 return \"xnor %%g0,%1,%0\";
4858 [(set_attr "type" "unary,unary,fp")
4859 (set_attr_alternative "length"
4861 (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1))
4864 (define_insn "*cmp_cc_not"
4866 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
4869 "xnorcc %%g0,%0,%%g0"
4870 [(set_attr "type" "compare")])
4872 (define_insn "*cmp_ccx_not"
4874 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
4877 "xnorcc %%g0,%0,%%g0"
4878 [(set_attr "type" "compare")])
4880 (define_insn "*cmp_cc_set_not"
4882 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
4884 (set (match_operand:SI 0 "register_operand" "=r")
4885 (not:SI (match_dup 1)))]
4888 [(set_attr "type" "unary")])
4890 (define_insn "*cmp_ccx_set_not"
4892 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
4894 (set (match_operand:DI 0 "register_operand" "=r")
4895 (not:DI (match_dup 1)))]
4898 [(set_attr "type" "unary")])
4900 ;; Floating point arithmetic instructions.
4902 (define_insn "addtf3"
4903 [(set (match_operand:TF 0 "register_operand" "=e")
4904 (plus:TF (match_operand:TF 1 "register_operand" "e")
4905 (match_operand:TF 2 "register_operand" "e")))]
4906 "TARGET_FPU && TARGET_HARD_QUAD"
4908 [(set_attr "type" "fp")])
4910 (define_insn "adddf3"
4911 [(set (match_operand:DF 0 "register_operand" "=e")
4912 (plus:DF (match_operand:DF 1 "register_operand" "e")
4913 (match_operand:DF 2 "register_operand" "e")))]
4916 [(set_attr "type" "fp")])
4918 (define_insn "addsf3"
4919 [(set (match_operand:SF 0 "register_operand" "=f")
4920 (plus:SF (match_operand:SF 1 "register_operand" "f")
4921 (match_operand:SF 2 "register_operand" "f")))]
4924 [(set_attr "type" "fp")])
4926 (define_insn "subtf3"
4927 [(set (match_operand:TF 0 "register_operand" "=e")
4928 (minus:TF (match_operand:TF 1 "register_operand" "e")
4929 (match_operand:TF 2 "register_operand" "e")))]
4930 "TARGET_FPU && TARGET_HARD_QUAD"
4932 [(set_attr "type" "fp")])
4934 (define_insn "subdf3"
4935 [(set (match_operand:DF 0 "register_operand" "=e")
4936 (minus:DF (match_operand:DF 1 "register_operand" "e")
4937 (match_operand:DF 2 "register_operand" "e")))]
4940 [(set_attr "type" "fp")])
4942 (define_insn "subsf3"
4943 [(set (match_operand:SF 0 "register_operand" "=f")
4944 (minus:SF (match_operand:SF 1 "register_operand" "f")
4945 (match_operand:SF 2 "register_operand" "f")))]
4948 [(set_attr "type" "fp")])
4950 (define_insn "multf3"
4951 [(set (match_operand:TF 0 "register_operand" "=e")
4952 (mult:TF (match_operand:TF 1 "register_operand" "e")
4953 (match_operand:TF 2 "register_operand" "e")))]
4954 "TARGET_FPU && TARGET_HARD_QUAD"
4956 [(set_attr "type" "fpmul")])
4958 (define_insn "muldf3"
4959 [(set (match_operand:DF 0 "register_operand" "=e")
4960 (mult:DF (match_operand:DF 1 "register_operand" "e")
4961 (match_operand:DF 2 "register_operand" "e")))]
4964 [(set_attr "type" "fpmul")])
4966 (define_insn "mulsf3"
4967 [(set (match_operand:SF 0 "register_operand" "=f")
4968 (mult:SF (match_operand:SF 1 "register_operand" "f")
4969 (match_operand:SF 2 "register_operand" "f")))]
4972 [(set_attr "type" "fpmul")])
4974 (define_insn "*muldf3_extend"
4975 [(set (match_operand:DF 0 "register_operand" "=e")
4976 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
4977 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
4978 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
4980 [(set_attr "type" "fpmul")])
4982 (define_insn "*multf3_extend"
4983 [(set (match_operand:TF 0 "register_operand" "=e")
4984 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
4985 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
4986 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
4988 [(set_attr "type" "fpmul")])
4990 ;; don't have timing for quad-prec. divide.
4991 (define_insn "divtf3"
4992 [(set (match_operand:TF 0 "register_operand" "=e")
4993 (div:TF (match_operand:TF 1 "register_operand" "e")
4994 (match_operand:TF 2 "register_operand" "e")))]
4995 "TARGET_FPU && TARGET_HARD_QUAD"
4997 [(set_attr "type" "fpdivd")])
4999 (define_insn "divdf3"
5000 [(set (match_operand:DF 0 "register_operand" "=e")
5001 (div:DF (match_operand:DF 1 "register_operand" "e")
5002 (match_operand:DF 2 "register_operand" "e")))]
5005 [(set_attr "type" "fpdivd")])
5007 (define_insn "divsf3"
5008 [(set (match_operand:SF 0 "register_operand" "=f")
5009 (div:SF (match_operand:SF 1 "register_operand" "f")
5010 (match_operand:SF 2 "register_operand" "f")))]
5013 [(set_attr "type" "fpdivs")])
5015 (define_insn "negtf2"
5016 [(set (match_operand:TF 0 "register_operand" "=e,e")
5017 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5018 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5022 /* v9: can't use fnegs, won't work with upper regs. */
5023 if (which_alternative == 0)
5024 return TARGET_V9 ? \"fnegd %0,%0\" : \"fnegs %0,%0\";
5026 return TARGET_V9 ? \"fnegd %1,%0\;fmovd %S1,%S0\"
5027 : \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
5029 [(set_attr "type" "fpmove")
5030 (set_attr_alternative "length"
5032 (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])])
5034 (define_insn "negdf2"
5035 [(set (match_operand:DF 0 "register_operand" "=e,e")
5036 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5041 return \"fnegd %1,%0\";
5042 else if (which_alternative == 0)
5043 return \"fnegs %0,%0\";
5045 return \"fnegs %1,%0\;fmovs %R1,%R0\";
5047 [(set_attr "type" "fpmove")
5048 (set_attr_alternative "length"
5050 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])])
5052 (define_insn "negsf2"
5053 [(set (match_operand:SF 0 "register_operand" "=f")
5054 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5057 [(set_attr "type" "fpmove")])
5059 (define_insn "abstf2"
5060 [(set (match_operand:TF 0 "register_operand" "=e,e")
5061 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5062 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5066 /* v9: can't use fabss, won't work with upper regs. */
5067 if (which_alternative == 0)
5068 return TARGET_V9 ? \"fabsd %0,%0\" : \"fabss %0,%0\";
5070 return TARGET_V9 ? \"fabsd %1,%0\;fmovd %S1,%S0\"
5071 : \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\";
5073 [(set_attr "type" "fpmove")
5074 (set_attr_alternative "length"
5076 (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])])
5078 (define_insn "absdf2"
5079 [(set (match_operand:DF 0 "register_operand" "=e,e")
5080 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5085 return \"fabsd %1,%0\";
5086 else if (which_alternative == 0)
5087 return \"fabss %0,%0\";
5089 return \"fabss %1,%0\;fmovs %R1,%R0\";
5091 [(set_attr "type" "fpmove")
5092 (set_attr_alternative "length"
5094 (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])])
5096 (define_insn "abssf2"
5097 [(set (match_operand:SF 0 "register_operand" "=f")
5098 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5101 [(set_attr "type" "fpmove")])
5103 (define_insn "sqrttf2"
5104 [(set (match_operand:TF 0 "register_operand" "=e")
5105 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5106 "TARGET_FPU && TARGET_HARD_QUAD"
5108 [(set_attr "type" "fpsqrt")])
5110 (define_insn "sqrtdf2"
5111 [(set (match_operand:DF 0 "register_operand" "=e")
5112 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5115 [(set_attr "type" "fpsqrt")])
5117 (define_insn "sqrtsf2"
5118 [(set (match_operand:SF 0 "register_operand" "=f")
5119 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5122 [(set_attr "type" "fpsqrt")])
5124 ;;- arithmetic shift instructions
5126 (define_insn "ashlsi3"
5127 [(set (match_operand:SI 0 "register_operand" "=r")
5128 (ashift:SI (match_operand:SI 1 "register_operand" "r")
5129 (match_operand:SI 2 "arith_operand" "rI")))]
5133 if (GET_CODE (operands[2]) == CONST_INT
5134 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
5135 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5137 return \"sll %1,%2,%0\";
5139 [(set_attr "type" "shift")])
5141 (define_insn "ashldi3"
5142 [(set (match_operand:DI 0 "register_operand" "=r")
5143 (ashift:DI (match_operand:DI 1 "register_operand" "r")
5144 (match_operand:SI 2 "arith_operand" "rI")))]
5148 if (GET_CODE (operands[2]) == CONST_INT
5149 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
5150 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5152 return \"sllx %1,%2,%0\";
5155 (define_insn "*cmp_cc_ashift_1"
5156 [(set (reg:CC_NOOV 100)
5157 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5162 [(set_attr "type" "compare")])
5164 (define_insn "*cmp_cc_set_ashift_1"
5165 [(set (reg:CC_NOOV 100)
5166 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5169 (set (match_operand:SI 0 "register_operand" "=r")
5170 (ashift:SI (match_dup 1) (const_int 1)))]
5174 (define_insn "ashrsi3"
5175 [(set (match_operand:SI 0 "register_operand" "=r")
5176 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5177 (match_operand:SI 2 "arith_operand" "rI")))]
5181 if (GET_CODE (operands[2]) == CONST_INT
5182 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
5183 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5185 return \"sra %1,%2,%0\";
5187 [(set_attr "type" "shift")])
5189 (define_insn "ashrdi3"
5190 [(set (match_operand:DI 0 "register_operand" "=r")
5191 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5192 (match_operand:SI 2 "arith_operand" "rI")))]
5196 if (GET_CODE (operands[2]) == CONST_INT
5197 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
5198 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5200 return \"srax %1,%2,%0\";
5203 (define_insn "lshrsi3"
5204 [(set (match_operand:SI 0 "register_operand" "=r")
5205 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5206 (match_operand:SI 2 "arith_operand" "rI")))]
5210 if (GET_CODE (operands[2]) == CONST_INT
5211 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
5212 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5214 return \"srl %1,%2,%0\";
5216 [(set_attr "type" "shift")])
5218 (define_insn "lshrdi3"
5219 [(set (match_operand:DI 0 "register_operand" "=r")
5220 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5221 (match_operand:SI 2 "arith_operand" "rI")))]
5225 if (GET_CODE (operands[2]) == CONST_INT
5226 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
5227 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5229 return \"srlx %1,%2,%0\";
5232 ;; Unconditional and other jump instructions
5233 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
5234 ;; following insn is never executed. This saves us a nop. Dbx does not
5235 ;; handle such branches though, so we only use them when optimizing.
5237 [(set (pc) (label_ref (match_operand 0 "" "")))]
5241 /* Some implementations are reported to have problems with
5243 i.e. an empty loop with the annul bit set. The workaround is to use
5247 if (flag_delayed_branch
5248 && (insn_addresses[INSN_UID (operands[0])]
5249 == insn_addresses[INSN_UID (insn)]))
5252 return \"b%* %l0%(\";
5254 [(set_attr "type" "uncond_branch")])
5256 (define_expand "tablejump"
5257 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5258 (use (label_ref (match_operand 1 "" "")))])]
5262 if (GET_MODE (operands[0]) != Pmode)
5265 /* We need to use the PC value in %o7 that was set up when the address
5266 of the label was loaded into a register, so we need different RTL. */
5270 emit_jump_insn (gen_pic_tablejump_32 (operands[0], operands[1]));
5272 emit_jump_insn (gen_pic_tablejump_64 (operands[0], operands[1]));
5277 (define_insn "pic_tablejump_32"
5278 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
5279 (use (label_ref (match_operand 1 "" "")))
5283 [(set_attr "type" "uncond_branch")])
5285 (define_insn "pic_tablejump_64"
5286 [(set (pc) (match_operand:DI 0 "register_operand" "r"))
5287 (use (label_ref (match_operand 1 "" "")))
5291 [(set_attr "type" "uncond_branch")])
5293 (define_insn "*tablejump_sp32"
5294 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5295 (use (label_ref (match_operand 1 "" "")))]
5298 [(set_attr "type" "uncond_branch")])
5300 (define_insn "*tablejump_sp64"
5301 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5302 (use (label_ref (match_operand 1 "" "")))]
5305 [(set_attr "type" "uncond_branch")])
5307 ;; This pattern recognizes the "instruction" that appears in
5308 ;; a function call that wants a structure value,
5309 ;; to inform the called function if compiled with Sun CC.
5310 ;(define_insn "*unimp_insn"
5311 ; [(match_operand:SI 0 "immediate_operand" "")]
5312 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
5314 ; [(set_attr "type" "marker")])
5316 ;;- jump to subroutine
5317 (define_expand "call"
5318 ;; Note that this expression is not used for generating RTL.
5319 ;; All the RTL is generated explicitly below.
5320 [(call (match_operand 0 "call_operand" "")
5321 (match_operand 3 "" "i"))]
5322 ;; operands[2] is next_arg_register
5323 ;; operands[3] is struct_value_size_rtx.
5327 rtx fn_rtx, nregs_rtx;
5329 if (GET_MODE (operands[0]) != FUNCTION_MODE)
5332 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5334 /* This is really a PIC sequence. We want to represent
5335 it as a funny jump so it's delay slots can be filled.
5337 ??? But if this really *is* a CALL, will not it clobber the
5338 call-clobbered registers? We lose this if it is a JUMP_INSN.
5339 Why cannot we have delay slots filled if it were a CALL? */
5341 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5343 (gen_rtx (PARALLEL, VOIDmode,
5345 gen_rtx (SET, VOIDmode, pc_rtx,
5346 XEXP (operands[0], 0)),
5347 GEN_INT (INTVAL (operands[3]) & 0xfff),
5348 gen_rtx (CLOBBER, VOIDmode,
5349 gen_rtx (REG, Pmode, 15)))));
5352 (gen_rtx (PARALLEL, VOIDmode,
5354 gen_rtx (SET, VOIDmode, pc_rtx,
5355 XEXP (operands[0], 0)),
5356 gen_rtx (CLOBBER, VOIDmode,
5357 gen_rtx (REG, Pmode, 15)))));
5361 fn_rtx = operands[0];
5363 /* Count the number of parameter registers being used by this call.
5364 if that argument is NULL, it means we are using them all, which
5365 means 6 on the sparc. */
5368 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
5370 nregs_rtx = GEN_INT (6);
5372 nregs_rtx = const0_rtx;
5375 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5377 (gen_rtx (PARALLEL, VOIDmode,
5378 gen_rtvec (3, gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
5379 GEN_INT (INTVAL (operands[3]) & 0xfff),
5380 gen_rtx (CLOBBER, VOIDmode,
5381 gen_rtx (REG, Pmode, 15)))));
5384 (gen_rtx (PARALLEL, VOIDmode,
5385 gen_rtvec (2, gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
5386 gen_rtx (CLOBBER, VOIDmode,
5387 gen_rtx (REG, Pmode, 15)))));
5391 /* If this call wants a structure value,
5392 emit an unimp insn to let the called function know about this. */
5393 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
5395 rtx insn = emit_insn (operands[3]);
5396 SCHED_GROUP_P (insn) = 1;
5403 ;; We can't use the same pattern for these two insns, because then registers
5404 ;; in the address may not be properly reloaded.
5406 (define_insn "*call_address_sp32"
5407 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5408 (match_operand 1 "" ""))
5409 (clobber (reg:SI 15))]
5410 ;;- Do not use operand 1 for most machines.
5413 [(set_attr "type" "call")])
5415 (define_insn "*call_symbolic_sp32"
5416 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5417 (match_operand 1 "" ""))
5418 (clobber (reg:SI 15))]
5419 ;;- Do not use operand 1 for most machines.
5422 [(set_attr "type" "call")])
5424 (define_insn "*call_address_sp64"
5425 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
5426 (match_operand 1 "" ""))
5427 (clobber (reg:DI 15))]
5428 ;;- Do not use operand 1 for most machines.
5431 [(set_attr "type" "call")])
5433 (define_insn "*call_symbolic_sp64"
5434 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
5435 (match_operand 1 "" ""))
5436 (clobber (reg:DI 15))]
5437 ;;- Do not use operand 1 for most machines.
5440 [(set_attr "type" "call")])
5442 ;; This is a call that wants a structure value.
5443 ;; There is no such critter for v9 (??? we may need one anyway).
5444 (define_insn "*call_address_struct_value_sp32"
5445 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5446 (match_operand 1 "" ""))
5447 (match_operand 2 "immediate_operand" "")
5448 (clobber (reg:SI 15))]
5449 ;;- Do not use operand 1 for most machines.
5450 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
5451 "call %a0,%1\;nop\;unimp %2"
5452 [(set_attr "type" "call_no_delay_slot")])
5454 ;; This is a call that wants a structure value.
5455 ;; There is no such critter for v9 (??? we may need one anyway).
5456 (define_insn "*call_symbolic_struct_value_sp32"
5457 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5458 (match_operand 1 "" ""))
5459 (match_operand 2 "immediate_operand" "")
5460 (clobber (reg:SI 15))]
5461 ;;- Do not use operand 1 for most machines.
5462 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
5463 "call %a0,%1\;nop\;unimp %2"
5464 [(set_attr "type" "call_no_delay_slot")])
5466 ;; This is a call that may want a structure value. This is used for
5468 (define_insn "*call_address_untyped_struct_value_sp32"
5469 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
5470 (match_operand 1 "" ""))
5471 (match_operand 2 "immediate_operand" "")
5472 (clobber (reg:SI 15))]
5473 ;;- Do not use operand 1 for most machines.
5474 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
5475 "call %a0,%1\;nop\;nop"
5476 [(set_attr "type" "call_no_delay_slot")])
5478 ;; This is a call that wants a structure value.
5479 (define_insn "*call_symbolic_untyped_struct_value_sp32"
5480 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
5481 (match_operand 1 "" ""))
5482 (match_operand 2 "immediate_operand" "")
5483 (clobber (reg:SI 15))]
5484 ;;- Do not use operand 1 for most machines.
5485 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
5486 "call %a0,%1\;nop\;nop"
5487 [(set_attr "type" "call_no_delay_slot")])
5489 (define_expand "call_value"
5490 ;; Note that this expression is not used for generating RTL.
5491 ;; All the RTL is generated explicitly below.
5492 [(set (match_operand 0 "register_operand" "=rf")
5493 (call (match_operand:SI 1 "" "")
5494 (match_operand 4 "" "")))]
5495 ;; operand 2 is stack_size_rtx
5496 ;; operand 3 is next_arg_register
5500 rtx fn_rtx, nregs_rtx;
5503 if (GET_MODE (operands[1]) != FUNCTION_MODE)
5506 fn_rtx = operands[1];
5510 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, REGNO (operands[3]) - 8);
5512 nregs_rtx = gen_rtx (CONST_INT, VOIDmode, 6);
5514 nregs_rtx = const0_rtx;
5518 gen_rtx (SET, VOIDmode, operands[0],
5519 gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx)),
5520 gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 15)));
5522 emit_call_insn (gen_rtx (PARALLEL, VOIDmode, vec));
5527 (define_insn "*call_value_address_sp32"
5528 [(set (match_operand 0 "" "=rf")
5529 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
5530 (match_operand 2 "" "")))
5531 (clobber (reg:SI 15))]
5532 ;;- Do not use operand 2 for most machines.
5535 [(set_attr "type" "call")])
5537 (define_insn "*call_value_symbolic_sp32"
5538 [(set (match_operand 0 "" "=rf")
5539 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
5540 (match_operand 2 "" "")))
5541 (clobber (reg:SI 15))]
5542 ;;- Do not use operand 2 for most machines.
5545 [(set_attr "type" "call")])
5547 (define_insn "*call_value_address_sp64"
5548 [(set (match_operand 0 "" "=rf")
5549 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
5550 (match_operand 2 "" "")))
5551 (clobber (reg:DI 15))]
5552 ;;- Do not use operand 2 for most machines.
5555 [(set_attr "type" "call")])
5557 (define_insn "*call_value_symbolic_sp64"
5558 [(set (match_operand 0 "" "=rf")
5559 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
5560 (match_operand 2 "" "")))
5561 (clobber (reg:DI 15))]
5562 ;;- Do not use operand 2 for most machines.
5565 [(set_attr "type" "call")])
5567 (define_expand "untyped_call"
5568 [(parallel [(call (match_operand 0 "" "")
5570 (match_operand 1 "" "")
5571 (match_operand 2 "" "")])]
5577 /* Pass constm1 to indicate that it may expect a structure value, but
5578 we don't know what size it is. */
5579 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
5581 for (i = 0; i < XVECLEN (operands[2], 0); i++)
5583 rtx set = XVECEXP (operands[2], 0, i);
5584 emit_move_insn (SET_DEST (set), SET_SRC (set));
5587 /* The optimizer does not know that the call sets the function value
5588 registers we stored in the result block. We avoid problems by
5589 claiming that all hard registers are used and clobbered at this
5591 emit_insn (gen_blockage ());
5596 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
5597 ;; all of memory. This blocks insns from being moved across this point.
5599 (define_insn "blockage"
5600 [(unspec_volatile [(const_int 0)] 0)]
5604 ;; Prepare to return any type including a structure value.
5606 (define_expand "untyped_return"
5607 [(match_operand:BLK 0 "memory_operand" "")
5608 (match_operand 1 "" "")]
5612 rtx valreg1 = gen_rtx (REG, DImode, 24);
5613 rtx valreg2 = gen_rtx (REG, TARGET_ARCH64 ? TFmode : DFmode, 32);
5614 rtx result = operands[0];
5616 if (! TARGET_ARCH64)
5618 rtx rtnreg = gen_rtx (REG, SImode, (leaf_function ? 15 : 31));
5619 rtx value = gen_reg_rtx (SImode);
5621 /* Fetch the instruction where we will return to and see if it's an unimp
5622 instruction (the most significant 10 bits will be zero). If so,
5623 update the return address to skip the unimp instruction. */
5624 emit_move_insn (value,
5625 gen_rtx (MEM, SImode, plus_constant (rtnreg, 8)));
5626 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
5627 emit_insn (gen_update_return (rtnreg, value));
5630 /* Reload the function value registers. */
5631 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
5632 emit_move_insn (valreg2,
5633 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
5634 plus_constant (XEXP (result, 0), 8)));
5636 /* Put USE insns before the return. */
5637 emit_insn (gen_rtx (USE, VOIDmode, valreg1));
5638 emit_insn (gen_rtx (USE, VOIDmode, valreg2));
5640 /* Construct the return. */
5641 expand_null_return ();
5646 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
5647 ;; and parts of the compiler don't want to believe that the add is needed.
5649 (define_insn "update_return"
5650 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
5651 (match_operand:SI 1 "register_operand" "r")] 1)]
5653 "cmp %1,0\;be,a .+8\;add %0,4,%0"
5654 [(set_attr "type" "multi")])
5656 (define_insn "return"
5660 "* return output_return (operands);"
5661 [(set_attr "type" "multi")])
5668 (define_expand "indirect_jump"
5669 [(set (pc) (match_operand 0 "address_operand" "p"))]
5673 (define_insn "*branch_sp32"
5674 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
5677 [(set_attr "type" "uncond_branch")])
5679 (define_insn "*branch_sp64"
5680 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
5683 [(set_attr "type" "uncond_branch")])
5685 ;; ??? Doesn't work with -mflat.
5686 (define_expand "nonlocal_goto"
5687 [(match_operand:SI 0 "" "")
5688 (match_operand:SI 1 "general_operand" "")
5689 (match_operand:SI 2 "general_operand" "")
5690 (match_operand:SI 3 "general_operand" "")]
5694 rtx chain = operands[0];
5695 rtx fp = operands[1];
5696 rtx stack = operands[2];
5697 rtx lab = operands[3];
5699 /* Trap instruction to flush all the register windows. */
5700 emit_insn (gen_flush_register_windows ());
5702 /* Load the fp value for the containing fn into %fp. This is needed
5703 because STACK refers to %fp. Note that virtual register instantiation
5704 fails if the virtual %fp isn't set from a register. */
5705 if (GET_CODE (fp) != REG)
5706 fp = force_reg (Pmode, fp);
5707 emit_move_insn (virtual_stack_vars_rtx, fp);
5709 /* Find the containing function's current nonlocal goto handler,
5710 which will do any cleanups and then jump to the label. */
5711 emit_move_insn (gen_rtx (REG, Pmode, 8), lab);
5713 /* Restore %fp from stack pointer value for containing function.
5714 The restore insn that follows will move this to %sp,
5715 and reload the appropriate value into %fp. */
5716 emit_move_insn (frame_pointer_rtx, stack);
5718 /* Put in the static chain register the nonlocal label address. */
5719 emit_move_insn (static_chain_rtx, chain);
5721 /* USE of frame_pointer_rtx added for consistency; not clear if
5723 emit_insn (gen_rtx (USE, VOIDmode, frame_pointer_rtx));
5724 emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
5725 emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
5726 /* Return, restoring reg window and jumping to goto handler. */
5727 emit_insn (gen_goto_handler_and_restore ());
5732 ;; Special trap insn to flush register windows.
5733 (define_insn "flush_register_windows"
5734 [(unspec_volatile [(const_int 0)] 1)]
5736 ;; ??? Use TARGET_V9 instead?
5737 "* return TARGET_ARCH64 ? \"flushw\" : \"ta 3\";"
5738 [(set_attr "type" "misc")])
5740 (define_insn "goto_handler_and_restore"
5741 [(unspec_volatile [(const_int 0)] 2)
5744 "jmp %%o0+0\;restore"
5745 [(set_attr "type" "misc")
5746 (set_attr "length" "2")])
5748 ;; Implement setjmp. Step one, set up the buffer.
5750 (define_expand "builtin_setjmp_setup"
5751 [(unspec [(match_operand 0 "" "")] 3)]
5756 emit_insn (gen_setjmp_64 ());
5758 emit_insn (gen_setjmp_32 ());
5762 (define_expand "setjmp_32"
5763 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
5764 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
5767 { operands[0] = frame_pointer_rtx; }")
5769 (define_expand "setjmp_64"
5770 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
5771 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
5774 { operands[0] = frame_pointer_rtx; }")
5776 ;; Special pattern for the FLUSH instruction.
5778 (define_insn "flush"
5779 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)]
5781 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
5782 [(set_attr "type" "misc")])
5786 ;; The scan instruction searches from the most significant bit while ffs
5787 ;; searches from the least significant bit. The bit index and treatment of
5788 ;; zero also differ. It takes at least 7 instructions to get the proper
5789 ;; result. Here is an obvious 8 instruction sequence.
5791 (define_insn "ffssi2"
5792 [(set (match_operand:SI 0 "register_operand" "=&r")
5793 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
5794 (clobber (match_scratch:SI 2 "=&r"))]
5795 "TARGET_SPARCLITE || TARGET_SPARCLET"
5799 output_asm_insn (\"and %%g0,0,%%g0\", operands);
5800 return \"sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0\";
5802 [(set_attr "type" "multi")
5803 (set_attr "length" "8")])
5805 ;; ??? This should be a define expand, so that the extra instruction have
5806 ;; a chance of being optimized away.
5808 (define_insn "ffsdi2"
5809 [(set (match_operand:DI 0 "register_operand" "=&r")
5810 (ffs:DI (match_operand:DI 1 "register_operand" "r")))
5811 (clobber (match_scratch:DI 2 "=&r"))]
5813 "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,0,%0"
5814 [(set_attr "type" "multi")
5815 (set_attr "length" "5")])
5817 ;; Split up troublesome insns for better scheduling. */
5819 ;; The following patterns are straightforward. They can be applied
5820 ;; either before or after register allocation.
5823 [(set (match_operand 0 "splittable_symbolic_memory_operand" "")
5824 (match_operand 1 "reg_or_0_operand" ""))
5825 (clobber (match_operand:SI 2 "register_operand" ""))]
5827 [(set (match_dup 2) (high:SI (match_dup 3)))
5828 (set (match_dup 4) (match_dup 1))]
5831 operands[3] = XEXP (operands[0], 0);
5832 operands[4] = gen_rtx (MEM, GET_MODE (operands[0]),
5833 gen_rtx (LO_SUM, SImode, operands[2], operands[3]));
5834 MEM_IN_STRUCT_P (operands[4]) = MEM_IN_STRUCT_P (operands[0]);
5835 MEM_VOLATILE_P (operands[4]) = MEM_VOLATILE_P (operands[0]);
5836 RTX_UNCHANGING_P (operands[4]) = RTX_UNCHANGING_P (operands[0]);
5840 [(set (match_operand 0 "splittable_immediate_memory_operand" "")
5841 (match_operand 1 "general_operand" ""))
5842 (clobber (match_operand:SI 2 "register_operand" ""))]
5844 [(set (match_dup 3) (match_dup 1))]
5847 rtx addr = legitimize_pic_address (XEXP (operands[0], 0),
5848 GET_MODE (operands[0]),
5850 operands[3] = gen_rtx (MEM, GET_MODE (operands[0]), addr);
5851 MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[0]);
5852 MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[0]);
5853 RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[0]);
5857 [(set (match_operand 0 "register_operand" "")
5858 (match_operand 1 "splittable_immediate_memory_operand" ""))]
5860 [(set (match_dup 0) (match_dup 2))]
5863 rtx addr = legitimize_pic_address (XEXP (operands[1], 0),
5864 GET_MODE (operands[1]),
5866 operands[2] = gen_rtx (MEM, GET_MODE (operands[1]), addr);
5867 MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]);
5868 MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]);
5869 RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]);
5872 ;; Sign- and Zero-extend operations can have symbolic memory operands.
5875 [(set (match_operand 0 "register_operand" "")
5876 (match_operator 1 "extend_op" [(match_operand 2 "splittable_immediate_memory_operand" "")]))]
5878 [(set (match_dup 0) (match_op_dup 1 [(match_dup 3)]))]
5881 rtx addr = legitimize_pic_address (XEXP (operands[2], 0),
5882 GET_MODE (operands[2]),
5884 operands[3] = gen_rtx (MEM, GET_MODE (operands[2]), addr);
5885 MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[2]);
5886 MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[2]);
5887 RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[2]);
5891 [(set (match_operand:SI 0 "register_operand" "")
5892 (match_operand:SI 1 "immediate_operand" ""))]
5893 "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5894 || GET_CODE (operands[1]) == CONST
5895 || GET_CODE (operands[1]) == LABEL_REF)"
5896 [(set (match_dup 0) (high:SI (match_dup 1)))
5898 (lo_sum:SI (match_dup 0) (match_dup 1)))]
5901 ;; LABEL_REFs are not modified by `legitimize_pic_address'
5902 ;; so do not recurse infinitely in the PIC case.
5904 [(set (match_operand:SI 0 "register_operand" "")
5905 (match_operand:SI 1 "immediate_operand" ""))]
5906 "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF
5907 || GET_CODE (operands[1]) == CONST)"
5908 [(set (match_dup 0) (match_dup 1))]
5911 operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]);
5914 ;; These split sne/seq insns. The forms of the resulting insns are
5915 ;; somewhat bogus, but they avoid extra patterns and show data dependency.
5916 ;; Nothing will look at these in detail after splitting has occurred.
5918 ;; ??? v9 DImode versions are missing because addc and subc use %icc.
5921 [(set (match_operand:SI 0 "register_operand" "")
5922 (ne:SI (match_operand:SI 1 "register_operand" "")
5924 (clobber (reg:CC 100))]
5926 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5928 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
5932 [(set (match_operand:SI 0 "register_operand" "")
5933 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5935 (clobber (reg:CC 100))]
5937 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5939 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
5943 [(set (match_operand:SI 0 "register_operand" "")
5944 (eq:SI (match_operand:SI 1 "register_operand" "")
5946 (clobber (reg:CC 100))]
5948 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5950 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
5954 [(set (match_operand:SI 0 "register_operand" "")
5955 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5957 (clobber (reg:CC 100))]
5959 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5961 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
5965 [(set (match_operand:SI 0 "register_operand" "")
5966 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
5968 (match_operand:SI 2 "register_operand" "")))
5969 (clobber (reg:CC 100))]
5971 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5973 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
5978 [(set (match_operand:SI 0 "register_operand" "")
5979 (minus:SI (match_operand:SI 2 "register_operand" "")
5980 (ne:SI (match_operand:SI 1 "register_operand" "")
5982 (clobber (reg:CC 100))]
5984 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5986 (set (match_dup 0) (minus:SI (match_dup 2)
5987 (ltu:SI (reg:CC 100) (const_int 0))))]
5991 [(set (match_operand:SI 0 "register_operand" "")
5992 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
5994 (match_operand:SI 2 "register_operand" "")))
5995 (clobber (reg:CC 100))]
5997 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
5999 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
6004 [(set (match_operand:SI 0 "register_operand" "")
6005 (minus:SI (match_operand:SI 2 "register_operand" "")
6006 (eq:SI (match_operand:SI 1 "register_operand" "")
6008 (clobber (reg:CC 100))]
6010 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
6012 (set (match_dup 0) (minus:SI (match_dup 2)
6013 (geu:SI (reg:CC 100) (const_int 0))))]
6016 ;; Peepholes go at the end.
6018 ;; Optimize consecutive loads or stores into ldd and std when possible.
6019 ;; The conditions in which we do this are very restricted and are
6020 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6023 [(set (match_operand:SI 0 "memory_operand" "")
6025 (set (match_operand:SI 1 "memory_operand" "")
6028 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[1])
6029 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
6033 [(set (match_operand:SI 0 "memory_operand" "")
6035 (set (match_operand:SI 1 "memory_operand" "")
6038 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[1])
6039 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
6043 [(set (match_operand:SI 0 "register_operand" "=rf")
6044 (match_operand:SI 1 "memory_operand" ""))
6045 (set (match_operand:SI 2 "register_operand" "=rf")
6046 (match_operand:SI 3 "memory_operand" ""))]
6047 "registers_ok_for_ldd_peep (operands[0], operands[2])
6048 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
6049 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
6053 [(set (match_operand:SI 0 "memory_operand" "")
6054 (match_operand:SI 1 "register_operand" "rf"))
6055 (set (match_operand:SI 2 "memory_operand" "")
6056 (match_operand:SI 3 "register_operand" "rf"))]
6057 "registers_ok_for_ldd_peep (operands[1], operands[3])
6058 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
6059 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
6063 [(set (match_operand:SF 0 "register_operand" "=fr")
6064 (match_operand:SF 1 "memory_operand" ""))
6065 (set (match_operand:SF 2 "register_operand" "=fr")
6066 (match_operand:SF 3 "memory_operand" ""))]
6067 "registers_ok_for_ldd_peep (operands[0], operands[2])
6068 && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
6069 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
6073 [(set (match_operand:SF 0 "memory_operand" "")
6074 (match_operand:SF 1 "register_operand" "fr"))
6075 (set (match_operand:SF 2 "memory_operand" "")
6076 (match_operand:SF 3 "register_operand" "fr"))]
6077 "registers_ok_for_ldd_peep (operands[1], operands[3])
6078 && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
6079 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
6083 [(set (match_operand:SI 0 "register_operand" "=rf")
6084 (match_operand:SI 1 "memory_operand" ""))
6085 (set (match_operand:SI 2 "register_operand" "=rf")
6086 (match_operand:SI 3 "memory_operand" ""))]
6087 "registers_ok_for_ldd_peep (operands[2], operands[0])
6088 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
6089 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
6093 [(set (match_operand:SI 0 "memory_operand" "")
6094 (match_operand:SI 1 "register_operand" "rf"))
6095 (set (match_operand:SI 2 "memory_operand" "")
6096 (match_operand:SI 3 "register_operand" "rf"))]
6097 "registers_ok_for_ldd_peep (operands[3], operands[1])
6098 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
6099 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
6103 [(set (match_operand:SF 0 "register_operand" "=fr")
6104 (match_operand:SF 1 "memory_operand" ""))
6105 (set (match_operand:SF 2 "register_operand" "=fr")
6106 (match_operand:SF 3 "memory_operand" ""))]
6107 "registers_ok_for_ldd_peep (operands[2], operands[0])
6108 && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
6109 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
6113 [(set (match_operand:SF 0 "memory_operand" "")
6114 (match_operand:SF 1 "register_operand" "fr"))
6115 (set (match_operand:SF 2 "memory_operand" "")
6116 (match_operand:SF 3 "register_operand" "fr"))]
6117 "registers_ok_for_ldd_peep (operands[3], operands[1])
6118 && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
6119 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
6122 ;; Optimize the case of following a reg-reg move with a test
6123 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
6124 ;; This can result from a float to fix conversion.
6127 [(set (match_operand:SI 0 "register_operand" "=r")
6128 (match_operand:SI 1 "register_operand" "r"))
6130 (compare:CC (match_operand:SI 2 "register_operand" "r")
6132 "(rtx_equal_p (operands[2], operands[0])
6133 || rtx_equal_p (operands[2], operands[1]))
6134 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
6138 [(set (match_operand:DI 0 "register_operand" "=r")
6139 (match_operand:DI 1 "register_operand" "r"))
6141 (compare:CCX (match_operand:DI 2 "register_operand" "r")
6144 && (rtx_equal_p (operands[2], operands[0])
6145 || rtx_equal_p (operands[2], operands[1]))
6146 && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])"
6149 ;; Do {sign,zero}-extended compares somewhat more efficiently.
6150 ;; ??? Is this now the Right Way to do this? Or will SCRATCH
6151 ;; eventually have some impact here?
6154 [(set (match_operand:HI 0 "register_operand" "")
6155 (match_operand:HI 1 "memory_operand" ""))
6156 (set (match_operand:SI 2 "register_operand" "")
6157 (sign_extend:SI (match_dup 0)))
6159 (compare:CC (match_dup 2)
6162 "ldsh %1,%0\;orcc %0,0,%2")
6165 [(set (match_operand:HI 0 "register_operand" "")
6166 (match_operand:HI 1 "memory_operand" ""))
6167 (set (match_operand:DI 2 "register_operand" "")
6168 (sign_extend:DI (match_dup 0)))
6170 (compare:CCX (match_dup 2)
6173 "ldsh %1,%0\;orcc %0,0,%2")
6176 [(set (match_operand:QI 0 "register_operand" "")
6177 (match_operand:QI 1 "memory_operand" ""))
6178 (set (match_operand:SI 2 "register_operand" "")
6179 (sign_extend:SI (match_dup 0)))
6181 (compare:CC (match_dup 2)
6184 "ldsb %1,%0\;orcc %0,0,%2")
6187 [(set (match_operand:QI 0 "register_operand" "")
6188 (match_operand:QI 1 "memory_operand" ""))
6189 (set (match_operand:DI 2 "register_operand" "")
6190 (sign_extend:DI (match_dup 0)))
6192 (compare:CCX (match_dup 2)
6195 "ldsb %1,%0\;orcc %0,0,%2")
6197 ;; Floating-point move peepholes
6198 ;; ??? v9: Do we want similar ones?
6201 [(set (match_operand:SI 0 "register_operand" "=r")
6202 (lo_sum:SI (match_dup 0)
6203 (match_operand:SI 1 "immediate_operand" "i")))
6204 (set (match_operand:DF 2 "register_operand" "=er")
6205 (mem:DF (match_dup 0)))]
6206 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
6209 /* Go by way of output_move_double in case the register in operand 2
6210 is not properly aligned for ldd. */
6211 operands[1] = gen_rtx (MEM, DFmode,
6212 gen_rtx (LO_SUM, SImode, operands[0], operands[1]));
6213 operands[0] = operands[2];
6214 return output_move_double (operands);
6218 [(set (match_operand:SI 0 "register_operand" "=r")
6219 (lo_sum:SI (match_dup 0)
6220 (match_operand:SI 1 "immediate_operand" "i")))
6221 (set (match_operand:SF 2 "register_operand" "=fr")
6222 (mem:SF (match_dup 0)))]
6223 "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)"
6224 "ld [%0+%%lo(%a1)],%2")
6226 ;; Return peepholes. First the "normal" ones.
6227 ;; These are necessary to catch insns ending up in the epilogue delay list.
6229 (define_insn "*return_qi"
6230 [(set (match_operand:QI 0 "restore_operand" "")
6231 (match_operand:QI 1 "arith_operand" "rI"))
6233 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
6236 if (! TARGET_ARCH64 && current_function_returns_struct)
6237 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
6239 return \"ret\;restore %%g0,%1,%Y0\";
6241 [(set_attr "type" "multi")])
6243 (define_insn "*return_hi"
6244 [(set (match_operand:HI 0 "restore_operand" "")
6245 (match_operand:HI 1 "arith_operand" "rI"))
6247 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
6250 if (! TARGET_ARCH64 && current_function_returns_struct)
6251 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
6253 return \"ret\;restore %%g0,%1,%Y0\";
6255 [(set_attr "type" "multi")])
6257 (define_insn "*return_si"
6258 [(set (match_operand:SI 0 "restore_operand" "")
6259 (match_operand:SI 1 "arith_operand" "rI"))
6261 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
6264 if (! TARGET_ARCH64 && current_function_returns_struct)
6265 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
6267 return \"ret\;restore %%g0,%1,%Y0\";
6269 [(set_attr "type" "multi")])
6271 ;; The following pattern is only generated by delayed-branch scheduling,
6272 ;; when the insn winds up in the epilogue. This can only happen when
6273 ;; ! TARGET_FPU because otherwise fp return values are in %f0.
6274 (define_insn "*return_sf_no_fpu"
6275 [(set (match_operand:SF 0 "restore_operand" "r")
6276 (match_operand:SF 1 "register_operand" "r"))
6278 "! TARGET_FPU && ! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
6281 if (! TARGET_ARCH64 && current_function_returns_struct)
6282 return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
6284 return \"ret\;restore %%g0,%1,%Y0\";
6286 [(set_attr "type" "multi")])
6288 (define_insn "*return_addsi"
6289 [(set (match_operand:SI 0 "restore_operand" "")
6290 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
6291 (match_operand:SI 2 "arith_operand" "rI")))
6293 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0
6294 && (register_operand (operands[1], SImode)
6295 || register_operand (operands[2], SImode))"
6298 if (! TARGET_ARCH64 && current_function_returns_struct)
6299 return \"jmp %%i7+12\;restore %r1,%2,%Y0\";
6301 return \"ret\;restore %r1,%2,%Y0\";
6303 [(set_attr "type" "multi")])
6305 (define_insn "*return_di"
6306 [(set (match_operand:DI 0 "restore_operand" "")
6307 (match_operand:DI 1 "arith_double_operand" "rHI"))
6309 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
6310 "ret\;restore %%g0,%1,%Y0"
6311 [(set_attr "type" "multi")])
6313 (define_insn "*return_adddi"
6314 [(set (match_operand:DI 0 "restore_operand" "")
6315 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
6316 (match_operand:DI 2 "arith_double_operand" "rHI")))
6318 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
6319 "ret\;restore %r1,%2,%Y0"
6320 [(set_attr "type" "multi")])
6322 ;; The following pattern is only generated by delayed-branch scheduling,
6323 ;; when the insn winds up in the epilogue.
6324 (define_insn "*return_sf"
6326 (match_operand:SF 0 "register_operand" "f"))
6329 "ret\;fmovs %0,%%f0"
6330 [(set_attr "type" "multi")])
6332 ;; Now peepholes to do a call followed by a jump.
6335 [(parallel [(set (match_operand 0 "" "")
6336 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
6337 (match_operand 2 "" "")))
6338 (clobber (reg:SI 15))])
6339 (set (pc) (label_ref (match_operand 3 "" "")))]
6340 "short_branch (INSN_UID (insn), INSN_UID (operands[3])) && in_same_eh_region (insn, operands[3]) && in_same_eh_region (insn, ins1)"
6341 "call %a1,%2\;add %%o7,(%l3-.-4),%%o7")
6344 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
6345 (match_operand 1 "" ""))
6346 (clobber (reg:SI 15))])
6347 (set (pc) (label_ref (match_operand 2 "" "")))]
6348 "short_branch (INSN_UID (insn), INSN_UID (operands[2])) && in_same_eh_region (insn, operands[2]) && in_same_eh_region (insn, ins1)"
6349 "call %a0,%1\;add %%o7,(%l2-.-4),%%o7")
6352 [(parallel [(set (match_operand 0 "" "")
6353 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
6354 (match_operand 2 "" "")))
6355 (clobber (reg:DI 15))])
6356 (set (pc) (label_ref (match_operand 3 "" "")))]
6357 "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[3])) && in_same_eh_region (insn, operands[3]) && in_same_eh_region (insn, ins1)"
6358 "call %a1,%2\;add %%o7,(%l3-.-4),%%o7")
6361 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
6362 (match_operand 1 "" ""))
6363 (clobber (reg:DI 15))])
6364 (set (pc) (label_ref (match_operand 2 "" "")))]
6365 "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[2])) && in_same_eh_region (insn, operands[2]) && in_same_eh_region (insn, ins1)"
6366 "call %a0,%1\;add %%o7,(%l2-.-4),%%o7")
6368 ;; Other miscellaneous peepholes.
6370 ;; (reg:SI 100) is created by the {add,neg,sub}di patterns.
6372 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
6373 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6375 (clobber (reg:CC 100))])
6376 (set (reg:CC 100) (compare (match_dup 0) (const_int 0)))]
6380 ;; After a nonlocal goto, we need to restore the PIC register, but only
6381 ;; if we need it. So do nothing much here, but we'll check for this in
6384 (define_insn "nonlocal_goto_receiver"
6385 [(unspec_volatile [(const_int 0)] 4)]