1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92-98, 1999 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 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
28 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
33 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
39 ;; 11 embmedany_sethi, embmedany_brsum
40 ;; 12 movsf_const_high
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
49 ;; UNSPEC_VOLATILE: 0 blockage
50 ;; 1 flush_register_windows
51 ;; 2 goto_handler_and_restore
52 ;; 3 goto_handler_and_restore_v9*
54 ;; 5 nonlocal_goto_receiver
57 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
58 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
59 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
60 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
61 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
63 ;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to
64 ;; test TARGET_LIVE_G0 if we have TARGET_ARCH64.
66 ;; Attribute for cpu type.
67 ;; These must match the values for enum processor_type in sparc.h.
68 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
69 (const (symbol_ref "sparc_cpu_attr")))
71 ;; Attribute for the instruction set.
72 ;; At present we only need to distinguish v9/!v9, but for clarity we
73 ;; test TARGET_V8 too.
74 (define_attr "isa" "v6,v8,v9,sparclet"
76 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
77 (symbol_ref "TARGET_V8") (const_string "v8")
78 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
79 (const_string "v6"))))
82 (define_attr "arch" "arch32bit,arch64bit"
84 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
85 (const_string "arch32bit"))))
87 ;; Whether -mlive-g0 is in effect.
88 (define_attr "live_g0" "no,yes"
90 (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")]
91 (const_string "no"))))
93 ;; Insn type. Used to default other attribute values.
95 ;; type "unary" insns have one input operand (1) and one output operand (0)
96 ;; type "binary" insns have two input operands (1,2) and one output (0)
97 ;; type "compare" insns have one or two input operands (0,1) and no output
98 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
101 "move,unary,binary,compare,load,sload,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,return,address,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrt,cmove,multi,misc"
102 (const_string "binary"))
104 ;; Set true if insn uses call-clobbered intermediate register.
105 (define_attr "use_clobbered" "false,true"
106 (if_then_else (and (eq_attr "type" "address")
107 (match_operand 0 "clobbered_register" ""))
108 (const_string "true")
109 (const_string "false")))
111 ;; Length (in # of insns).
112 (define_attr "length" ""
113 (cond [(eq_attr "type" "load,sload,fpload")
114 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
115 (const_int 2) (const_int 1))
117 (eq_attr "type" "store,fpstore")
118 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
119 (const_int 2) (const_int 1))
121 (eq_attr "type" "address") (const_int 2)
123 (eq_attr "type" "binary")
124 (if_then_else (ior (match_operand 2 "arith_operand" "")
125 (match_operand 2 "arith_double_operand" ""))
126 (const_int 1) (const_int 3))
128 (eq_attr "type" "multi") (const_int 2)
130 (eq_attr "type" "move,unary")
131 (if_then_else (ior (match_operand 1 "arith_operand" "")
132 (match_operand 1 "arith_double_operand" ""))
133 (const_int 1) (const_int 2))]
137 (define_asm_attributes
138 [(set_attr "length" "1")
139 (set_attr "type" "multi")])
141 ;; Attributes for instruction and branch scheduling
143 (define_attr "in_call_delay" "false,true"
144 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,return,multi")
145 (const_string "false")
146 (eq_attr "type" "load,fpload,store,fpstore")
147 (if_then_else (eq_attr "length" "1")
148 (const_string "true")
149 (const_string "false"))
150 (eq_attr "type" "address")
151 (if_then_else (eq_attr "use_clobbered" "false")
152 (const_string "true")
153 (const_string "false"))]
154 (if_then_else (eq_attr "length" "1")
155 (const_string "true")
156 (const_string "false"))))
158 (define_delay (eq_attr "type" "call")
159 [(eq_attr "in_call_delay" "true") (nil) (nil)])
161 (define_attr "leaf_function" "false,true"
162 (const (symbol_ref "current_function_uses_only_leaf_regs")))
164 (define_attr "in_return_delay" "false,true"
165 (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
166 (eq_attr "length" "1"))
167 (eq_attr "leaf_function" "false"))
168 (match_insn "eligible_for_return_delay"))
169 (const_string "true")
170 (const_string "false")))
172 (define_delay (and (eq_attr "type" "return")
173 (eq_attr "isa" "v9"))
174 [(eq_attr "in_return_delay" "true") (nil) (nil)])
176 ;; ??? Should implement the notion of predelay slots for floating point
177 ;; branches. This would allow us to remove the nop always inserted before
178 ;; a floating point branch.
180 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
181 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
182 ;; This is because doing so will add several pipeline stalls to the path
183 ;; that the load/store did not come from. Unfortunately, there is no way
184 ;; to prevent fill_eager_delay_slots from using load/store without completely
185 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
186 ;; because it prevents us from moving back the final store of inner loops.
188 (define_attr "in_branch_delay" "false,true"
189 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
190 (eq_attr "length" "1"))
191 (const_string "true")
192 (const_string "false")))
194 (define_attr "in_uncond_branch_delay" "false,true"
195 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
196 (eq_attr "length" "1"))
197 (const_string "true")
198 (const_string "false")))
200 (define_attr "in_annul_branch_delay" "false,true"
201 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
202 (eq_attr "length" "1"))
203 (const_string "true")
204 (const_string "false")))
206 (define_delay (eq_attr "type" "branch")
207 [(eq_attr "in_branch_delay" "true")
208 (nil) (eq_attr "in_annul_branch_delay" "true")])
210 (define_delay (eq_attr "type" "uncond_branch")
211 [(eq_attr "in_uncond_branch_delay" "true")
214 ;; Function units of the SPARC
216 ;; (define_function_unit {name} {num-units} {n-users} {test}
217 ;; {ready-delay} {issue-delay} [{conflict-list}])
220 ;; (Noted only for documentation; units that take one cycle do not need to
223 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
226 ;; (define_function_unit "alu" 1 0
227 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
229 ;; ---- cypress CY7C602 scheduling:
230 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
232 (define_function_unit "memory" 1 0
233 (and (eq_attr "cpu" "cypress")
234 (eq_attr "type" "load,sload,fpload"))
237 ;; SPARC has two floating-point units: the FP ALU,
238 ;; and the FP MUL/DIV/SQRT unit.
239 ;; Instruction timings on the CY7C602 are as follows
253 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
254 ;; More insns cause the chip to stall.
256 (define_function_unit "fp_alu" 1 0
257 (and (eq_attr "cpu" "cypress")
258 (eq_attr "type" "fp,fpmove"))
261 (define_function_unit "fp_mds" 1 0
262 (and (eq_attr "cpu" "cypress")
263 (eq_attr "type" "fpmul"))
266 (define_function_unit "fp_mds" 1 0
267 (and (eq_attr "cpu" "cypress")
268 (eq_attr "type" "fpdivs,fpdivd"))
271 (define_function_unit "fp_mds" 1 0
272 (and (eq_attr "cpu" "cypress")
273 (eq_attr "type" "fpsqrt"))
276 ;; ----- The TMS390Z55 scheduling
277 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
278 ;; one ld/st, one fp.
279 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
281 (define_function_unit "memory" 1 0
282 (and (eq_attr "cpu" "supersparc")
283 (eq_attr "type" "load,sload"))
286 (define_function_unit "memory" 1 0
287 (and (eq_attr "cpu" "supersparc")
288 (eq_attr "type" "fpload"))
291 (define_function_unit "memory" 1 0
292 (and (eq_attr "cpu" "supersparc")
293 (eq_attr "type" "store,fpstore"))
296 (define_function_unit "shift" 1 0
297 (and (eq_attr "cpu" "supersparc")
298 (eq_attr "type" "shift"))
301 ;; There are only two write ports to the integer register file
302 ;; A store also uses a write port
304 (define_function_unit "iwport" 2 0
305 (and (eq_attr "cpu" "supersparc")
306 (eq_attr "type" "load,sload,store,shift,ialu"))
309 ;; Timings; throughput/latency
310 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
318 (define_function_unit "fp_alu" 1 0
319 (and (eq_attr "cpu" "supersparc")
320 (eq_attr "type" "fp,fpmove,fpcmp"))
323 (define_function_unit "fp_mds" 1 0
324 (and (eq_attr "cpu" "supersparc")
325 (eq_attr "type" "fpmul"))
328 (define_function_unit "fp_mds" 1 0
329 (and (eq_attr "cpu" "supersparc")
330 (eq_attr "type" "fpdivs"))
333 (define_function_unit "fp_mds" 1 0
334 (and (eq_attr "cpu" "supersparc")
335 (eq_attr "type" "fpdivd"))
338 (define_function_unit "fp_mds" 1 0
339 (and (eq_attr "cpu" "supersparc")
340 (eq_attr "type" "fpsqrt"))
343 (define_function_unit "fp_mds" 1 0
344 (and (eq_attr "cpu" "supersparc")
345 (eq_attr "type" "imul"))
348 ;; ----- hypersparc/sparclite86x scheduling
349 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
350 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
351 ;; II/FF case is only when loading a 32 bit hi/lo constant
352 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
353 ;; Memory delivers its result in one cycle to IU
355 (define_function_unit "memory" 1 0
356 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
357 (eq_attr "type" "load,sload,fpload"))
360 (define_function_unit "memory" 1 0
361 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
362 (eq_attr "type" "store,fpstore"))
365 (define_function_unit "fp_alu" 1 0
366 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
367 (eq_attr "type" "fp,fpmove,fpcmp"))
370 (define_function_unit "fp_mds" 1 0
371 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
372 (eq_attr "type" "fpmul"))
375 (define_function_unit "fp_mds" 1 0
376 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
377 (eq_attr "type" "fpdivs"))
380 (define_function_unit "fp_mds" 1 0
381 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
382 (eq_attr "type" "fpdivd"))
385 (define_function_unit "fp_mds" 1 0
386 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
387 (eq_attr "type" "fpsqrt"))
390 (define_function_unit "fp_mds" 1 0
391 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
392 (eq_attr "type" "imul"))
395 ;; ----- sparclet tsc701 scheduling
396 ;; The tsc701 issues 1 insn per cycle.
397 ;; Results may be written back out of order.
399 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
401 (define_function_unit "tsc701_load" 4 1
402 (and (eq_attr "cpu" "tsc701")
403 (eq_attr "type" "load,sload"))
406 ;; Stores take 2(?) extra cycles to complete.
407 ;; It is desirable to not have any memory operation in the following 2 cycles.
408 ;; (??? or 2 memory ops in the case of std).
410 (define_function_unit "tsc701_store" 1 0
411 (and (eq_attr "cpu" "tsc701")
412 (eq_attr "type" "store"))
414 [(eq_attr "type" "load,sload,store")])
416 ;; The multiply unit has a latency of 5.
417 (define_function_unit "tsc701_mul" 1 0
418 (and (eq_attr "cpu" "tsc701")
419 (eq_attr "type" "imul"))
422 ;; ----- The UltraSPARC-1 scheduling
423 ;; UltraSPARC has two integer units. Shift instructions can only execute
424 ;; on IE0. Condition code setting instructions, call, and jmpl (including
425 ;; the ret and retl pseudo-instructions) can only execute on IE1.
426 ;; Branch on register uses IE1, but branch on condition code does not.
427 ;; Conditional moves take 2 cycles. No other instruction can issue in the
428 ;; same cycle as a conditional move.
429 ;; Multiply and divide take many cycles during which no other instructions
431 ;; Memory delivers its result in two cycles (except for signed loads,
432 ;; which take one cycle more). One memory instruction can be issued per
435 (define_function_unit "memory" 1 0
436 (and (eq_attr "cpu" "ultrasparc")
437 (eq_attr "type" "load,fpload"))
440 (define_function_unit "memory" 1 0
441 (and (eq_attr "cpu" "ultrasparc")
442 (eq_attr "type" "sload"))
445 (define_function_unit "memory" 1 0
446 (and (eq_attr "cpu" "ultrasparc")
447 (eq_attr "type" "store,fpstore"))
450 (define_function_unit "ieuN" 2 0
451 (and (eq_attr "cpu" "ultrasparc")
452 (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,call_no_delay_slot,uncond_branch"))
455 (define_function_unit "ieu0" 1 0
456 (and (eq_attr "cpu" "ultrasparc")
457 (eq_attr "type" "shift"))
460 (define_function_unit "ieu0" 1 0
461 (and (eq_attr "cpu" "ultrasparc")
462 (eq_attr "type" "cmove"))
465 (define_function_unit "ieu1" 1 0
466 (and (eq_attr "cpu" "ultrasparc")
467 (eq_attr "type" "compare,call,call_no_delay_slot,uncond_branch"))
470 (define_function_unit "cti" 1 0
471 (and (eq_attr "cpu" "ultrasparc")
472 (eq_attr "type" "branch"))
475 ;; Timings; throughput/latency
476 ;; FMOV 1/1 fmov, fabs, fneg
478 ;; FADD 1/4 add/sub, format conv, compar
484 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
486 ;; ??? This is really bogus because the timings really depend upon
487 ;; who uses the result. We should record who the user is with
488 ;; more descriptive 'type' attribute names and account for these
489 ;; issues in ultrasparc_adjust_cost.
491 (define_function_unit "fadd" 1 0
492 (and (eq_attr "cpu" "ultrasparc")
493 (eq_attr "type" "fpmove"))
496 (define_function_unit "fadd" 1 0
497 (and (eq_attr "cpu" "ultrasparc")
498 (eq_attr "type" "fpcmove"))
501 (define_function_unit "fadd" 1 0
502 (and (eq_attr "cpu" "ultrasparc")
503 (eq_attr "type" "fp"))
506 (define_function_unit "fadd" 1 0
507 (and (eq_attr "cpu" "ultrasparc")
508 (eq_attr "type" "fpcmp"))
511 (define_function_unit "fmul" 1 0
512 (and (eq_attr "cpu" "ultrasparc")
513 (eq_attr "type" "fpmul"))
516 (define_function_unit "fadd" 1 0
517 (and (eq_attr "cpu" "ultrasparc")
518 (eq_attr "type" "fpcmove"))
521 (define_function_unit "fmul" 1 0
522 (and (eq_attr "cpu" "ultrasparc")
523 (eq_attr "type" "fpdivs"))
526 (define_function_unit "fmul" 1 0
527 (and (eq_attr "cpu" "ultrasparc")
528 (eq_attr "type" "fpdivd"))
531 (define_function_unit "fmul" 1 0
532 (and (eq_attr "cpu" "ultrasparc")
533 (eq_attr "type" "fpsqrt"))
536 ;; Compare instructions.
537 ;; This controls RTL generation and register allocation.
539 ;; We generate RTL for comparisons and branches by having the cmpxx
540 ;; patterns store away the operands. Then, the scc and bcc patterns
541 ;; emit RTL for both the compare and the branch.
543 ;; We do this because we want to generate different code for an sne and
544 ;; seq insn. In those cases, if the second operand of the compare is not
545 ;; const0_rtx, we want to compute the xor of the two operands and test
548 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
549 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
550 ;; insns that actually require more than one machine instruction.
552 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
554 (define_expand "cmpsi"
556 (compare:CC (match_operand:SI 0 "register_operand" "")
557 (match_operand:SI 1 "arith_operand" "")))]
561 sparc_compare_op0 = operands[0];
562 sparc_compare_op1 = operands[1];
566 (define_expand "cmpdi"
568 (compare:CCX (match_operand:DI 0 "register_operand" "")
569 (match_operand:DI 1 "arith_double_operand" "")))]
573 sparc_compare_op0 = operands[0];
574 sparc_compare_op1 = operands[1];
578 (define_expand "cmpsf"
579 ;; The 96 here isn't ever used by anyone.
581 (compare:CCFP (match_operand:SF 0 "register_operand" "")
582 (match_operand:SF 1 "register_operand" "")))]
586 sparc_compare_op0 = operands[0];
587 sparc_compare_op1 = operands[1];
591 (define_expand "cmpdf"
592 ;; The 96 here isn't ever used by anyone.
594 (compare:CCFP (match_operand:DF 0 "register_operand" "")
595 (match_operand:DF 1 "register_operand" "")))]
599 sparc_compare_op0 = operands[0];
600 sparc_compare_op1 = operands[1];
604 (define_expand "cmptf"
605 ;; The 96 here isn't ever used by anyone.
607 (compare:CCFP (match_operand:TF 0 "register_operand" "")
608 (match_operand:TF 1 "register_operand" "")))]
612 sparc_compare_op0 = operands[0];
613 sparc_compare_op1 = operands[1];
617 ;; Now the compare DEFINE_INSNs.
619 (define_insn "*cmpsi_insn"
621 (compare:CC (match_operand:SI 0 "register_operand" "r")
622 (match_operand:SI 1 "arith_operand" "rI")))]
625 [(set_attr "type" "compare")])
627 (define_insn "*cmpdi_sp64"
629 (compare:CCX (match_operand:DI 0 "register_operand" "r")
630 (match_operand:DI 1 "arith_double_operand" "rHI")))]
633 [(set_attr "type" "compare")])
635 (define_insn "*cmpsf_fpe"
636 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
637 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
638 (match_operand:SF 2 "register_operand" "f")))]
643 return \"fcmpes\\t%0, %1, %2\";
644 return \"fcmpes\\t%1, %2\";
646 [(set_attr "type" "fpcmp")])
648 (define_insn "*cmpdf_fpe"
649 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
650 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
651 (match_operand:DF 2 "register_operand" "e")))]
656 return \"fcmped\\t%0, %1, %2\";
657 return \"fcmped\\t%1, %2\";
659 [(set_attr "type" "fpcmp")])
661 (define_insn "*cmptf_fpe"
662 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
663 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
664 (match_operand:TF 2 "register_operand" "e")))]
665 "TARGET_FPU && TARGET_HARD_QUAD"
669 return \"fcmpeq\\t%0, %1, %2\";
670 return \"fcmpeq\\t%1, %2\";
672 [(set_attr "type" "fpcmp")])
674 (define_insn "*cmpsf_fp"
675 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
676 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
677 (match_operand:SF 2 "register_operand" "f")))]
682 return \"fcmps\\t%0, %1, %2\";
683 return \"fcmps\\t%1, %2\";
685 [(set_attr "type" "fpcmp")])
687 (define_insn "*cmpdf_fp"
688 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
689 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
690 (match_operand:DF 2 "register_operand" "e")))]
695 return \"fcmpd\\t%0, %1, %2\";
696 return \"fcmpd\\t%1, %2\";
698 [(set_attr "type" "fpcmp")])
700 (define_insn "*cmptf_fp"
701 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
702 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
703 (match_operand:TF 2 "register_operand" "e")))]
704 "TARGET_FPU && TARGET_HARD_QUAD"
708 return \"fcmpq\\t%0, %1, %2\";
709 return \"fcmpq\\t%1, %2\";
711 [(set_attr "type" "fpcmp")])
713 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
714 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
715 ;; the same code as v8 (the addx/subx method has more applications). The
716 ;; exception to this is "reg != 0" which can be done in one instruction on v9
717 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
720 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
721 ;; generate addcc/subcc instructions.
723 (define_expand "seqsi_special"
725 (xor:SI (match_operand:SI 1 "register_operand" "")
726 (match_operand:SI 2 "register_operand" "")))
727 (parallel [(set (match_operand:SI 0 "register_operand" "")
728 (eq:SI (match_dup 3) (const_int 0)))
729 (clobber (reg:CC 100))])]
731 "{ operands[3] = gen_reg_rtx (SImode); }")
733 (define_expand "seqdi_special"
735 (xor:DI (match_operand:DI 1 "register_operand" "")
736 (match_operand:DI 2 "register_operand" "")))
737 (set (match_operand:DI 0 "register_operand" "")
738 (eq:DI (match_dup 3) (const_int 0)))]
740 "{ operands[3] = gen_reg_rtx (DImode); }")
742 (define_expand "snesi_special"
744 (xor:SI (match_operand:SI 1 "register_operand" "")
745 (match_operand:SI 2 "register_operand" "")))
746 (parallel [(set (match_operand:SI 0 "register_operand" "")
747 (ne:SI (match_dup 3) (const_int 0)))
748 (clobber (reg:CC 100))])]
750 "{ operands[3] = gen_reg_rtx (SImode); }")
752 (define_expand "snedi_special"
754 (xor:DI (match_operand:DI 1 "register_operand" "")
755 (match_operand:DI 2 "register_operand" "")))
756 (set (match_operand:DI 0 "register_operand" "")
757 (ne:DI (match_dup 3) (const_int 0)))]
759 "{ operands[3] = gen_reg_rtx (DImode); }")
761 (define_expand "seqdi_special_trunc"
763 (xor:DI (match_operand:DI 1 "register_operand" "")
764 (match_operand:DI 2 "register_operand" "")))
765 (set (match_operand:SI 0 "register_operand" "")
766 (eq:SI (match_dup 3) (const_int 0)))]
768 "{ operands[3] = gen_reg_rtx (DImode); }")
770 (define_expand "snedi_special_trunc"
772 (xor:DI (match_operand:DI 1 "register_operand" "")
773 (match_operand:DI 2 "register_operand" "")))
774 (set (match_operand:SI 0 "register_operand" "")
775 (ne:SI (match_dup 3) (const_int 0)))]
777 "{ operands[3] = gen_reg_rtx (DImode); }")
779 (define_expand "seqsi_special_extend"
781 (xor:SI (match_operand:SI 1 "register_operand" "")
782 (match_operand:SI 2 "register_operand" "")))
783 (parallel [(set (match_operand:DI 0 "register_operand" "")
784 (eq:DI (match_dup 3) (const_int 0)))
785 (clobber (reg:CC 100))])]
787 "{ operands[3] = gen_reg_rtx (SImode); }")
789 (define_expand "snesi_special_extend"
791 (xor:SI (match_operand:SI 1 "register_operand" "")
792 (match_operand:SI 2 "register_operand" "")))
793 (parallel [(set (match_operand:DI 0 "register_operand" "")
794 (ne:DI (match_dup 3) (const_int 0)))
795 (clobber (reg:CC 100))])]
797 "{ operands[3] = gen_reg_rtx (SImode); }")
799 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
800 ;; However, the code handles both SImode and DImode.
802 [(set (match_operand:SI 0 "intreg_operand" "")
803 (eq:SI (match_dup 1) (const_int 0)))]
807 if (GET_MODE (sparc_compare_op0) == SImode)
811 if (GET_MODE (operands[0]) == SImode)
812 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
814 else if (! TARGET_ARCH64)
817 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
822 else if (GET_MODE (sparc_compare_op0) == DImode)
828 else if (GET_MODE (operands[0]) == SImode)
829 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
832 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
837 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
839 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
840 emit_insn (gen_sne (operands[0]));
845 if (gen_v9_scc (EQ, operands))
852 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
853 ;; However, the code handles both SImode and DImode.
855 [(set (match_operand:SI 0 "intreg_operand" "")
856 (ne:SI (match_dup 1) (const_int 0)))]
860 if (GET_MODE (sparc_compare_op0) == SImode)
864 if (GET_MODE (operands[0]) == SImode)
865 pat = gen_snesi_special (operands[0], sparc_compare_op0,
867 else if (! TARGET_ARCH64)
870 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
875 else if (GET_MODE (sparc_compare_op0) == DImode)
881 else if (GET_MODE (operands[0]) == SImode)
882 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
885 pat = gen_snedi_special (operands[0], sparc_compare_op0,
890 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
892 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
893 emit_insn (gen_sne (operands[0]));
898 if (gen_v9_scc (NE, operands))
906 [(set (match_operand:SI 0 "intreg_operand" "")
907 (gt:SI (match_dup 1) (const_int 0)))]
911 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
913 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
914 emit_insn (gen_sne (operands[0]));
919 if (gen_v9_scc (GT, operands))
927 [(set (match_operand:SI 0 "intreg_operand" "")
928 (lt:SI (match_dup 1) (const_int 0)))]
932 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
934 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
935 emit_insn (gen_sne (operands[0]));
940 if (gen_v9_scc (LT, operands))
948 [(set (match_operand:SI 0 "intreg_operand" "")
949 (ge:SI (match_dup 1) (const_int 0)))]
953 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
955 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
956 emit_insn (gen_sne (operands[0]));
961 if (gen_v9_scc (GE, operands))
969 [(set (match_operand:SI 0 "intreg_operand" "")
970 (le:SI (match_dup 1) (const_int 0)))]
974 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
976 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
977 emit_insn (gen_sne (operands[0]));
982 if (gen_v9_scc (LE, operands))
989 (define_expand "sgtu"
990 [(set (match_operand:SI 0 "intreg_operand" "")
991 (gtu:SI (match_dup 1) (const_int 0)))]
999 /* We can do ltu easily, so if both operands are registers, swap them and
1001 if ((GET_CODE (sparc_compare_op0) == REG
1002 || GET_CODE (sparc_compare_op0) == SUBREG)
1003 && (GET_CODE (sparc_compare_op1) == REG
1004 || GET_CODE (sparc_compare_op1) == SUBREG))
1006 tem = sparc_compare_op0;
1007 sparc_compare_op0 = sparc_compare_op1;
1008 sparc_compare_op1 = tem;
1009 pat = gen_sltu (operands[0]);
1010 if (pat == NULL_RTX)
1018 if (gen_v9_scc (GTU, operands))
1024 (define_expand "sltu"
1025 [(set (match_operand:SI 0 "intreg_operand" "")
1026 (ltu:SI (match_dup 1) (const_int 0)))]
1032 if (gen_v9_scc (LTU, operands))
1035 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1038 (define_expand "sgeu"
1039 [(set (match_operand:SI 0 "intreg_operand" "")
1040 (geu:SI (match_dup 1) (const_int 0)))]
1046 if (gen_v9_scc (GEU, operands))
1049 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1052 (define_expand "sleu"
1053 [(set (match_operand:SI 0 "intreg_operand" "")
1054 (leu:SI (match_dup 1) (const_int 0)))]
1062 /* We can do geu easily, so if both operands are registers, swap them and
1064 if ((GET_CODE (sparc_compare_op0) == REG
1065 || GET_CODE (sparc_compare_op0) == SUBREG)
1066 && (GET_CODE (sparc_compare_op1) == REG
1067 || GET_CODE (sparc_compare_op1) == SUBREG))
1069 tem = sparc_compare_op0;
1070 sparc_compare_op0 = sparc_compare_op1;
1071 sparc_compare_op1 = tem;
1072 pat = gen_sgeu (operands[0]);
1073 if (pat == NULL_RTX)
1081 if (gen_v9_scc (LEU, operands))
1087 ;; Now the DEFINE_INSNs for the scc cases.
1089 ;; The SEQ and SNE patterns are special because they can be done
1090 ;; without any branching and do not involve a COMPARE. We want
1091 ;; them to always use the splitz below so the results can be
1094 (define_insn "*snesi_zero"
1095 [(set (match_operand:SI 0 "register_operand" "=r")
1096 (ne:SI (match_operand:SI 1 "register_operand" "r")
1098 (clobber (reg:CC 100))]
1101 [(set_attr "length" "2")])
1104 [(set (match_operand:SI 0 "register_operand" "")
1105 (ne:SI (match_operand:SI 1 "register_operand" "")
1107 (clobber (reg:CC 100))]
1109 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1111 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1114 (define_insn "*neg_snesi_zero"
1115 [(set (match_operand:SI 0 "register_operand" "=r")
1116 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1118 (clobber (reg:CC 100))]
1121 [(set_attr "length" "2")])
1124 [(set (match_operand:SI 0 "register_operand" "")
1125 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1127 (clobber (reg:CC 100))]
1129 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1131 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1134 (define_insn "*snesi_zero_extend"
1135 [(set (match_operand:DI 0 "register_operand" "=r")
1136 (ne:DI (match_operand:SI 1 "register_operand" "r")
1138 (clobber (reg:CC 100))]
1141 [(set_attr "type" "unary")
1142 (set_attr "length" "2")])
1145 [(set (match_operand:DI 0 "register_operand" "")
1146 (ne:DI (match_operand:SI 1 "register_operand" "")
1148 (clobber (reg:CC 100))]
1150 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1152 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1154 (ltu:SI (reg:CC_NOOV 100)
1158 (define_insn "*snedi_zero"
1159 [(set (match_operand:DI 0 "register_operand" "=&r")
1160 (ne:DI (match_operand:DI 1 "register_operand" "r")
1164 [(set_attr "type" "cmove")
1165 (set_attr "length" "2")])
1168 [(set (match_operand:DI 0 "register_operand" "")
1169 (ne:DI (match_operand:DI 1 "register_operand" "")
1172 [(set (match_dup 0) (const_int 0))
1173 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1179 (define_insn "*neg_snedi_zero"
1180 [(set (match_operand:DI 0 "register_operand" "=&r")
1181 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1185 [(set_attr "type" "cmove")
1186 (set_attr "length" "2")])
1189 [(set (match_operand:DI 0 "register_operand" "")
1190 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1193 [(set (match_dup 0) (const_int 0))
1194 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1200 (define_insn "*snedi_zero_trunc"
1201 [(set (match_operand:SI 0 "register_operand" "=&r")
1202 (ne:SI (match_operand:DI 1 "register_operand" "r")
1206 [(set_attr "type" "cmove")
1207 (set_attr "length" "2")])
1210 [(set (match_operand:SI 0 "register_operand" "")
1211 (ne:SI (match_operand:DI 1 "register_operand" "")
1214 [(set (match_dup 0) (const_int 0))
1215 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1221 (define_insn "*seqsi_zero"
1222 [(set (match_operand:SI 0 "register_operand" "=r")
1223 (eq:SI (match_operand:SI 1 "register_operand" "r")
1225 (clobber (reg:CC 100))]
1228 [(set_attr "length" "2")])
1231 [(set (match_operand:SI 0 "register_operand" "")
1232 (eq:SI (match_operand:SI 1 "register_operand" "")
1234 (clobber (reg:CC 100))]
1236 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1238 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1241 (define_insn "*neg_seqsi_zero"
1242 [(set (match_operand:SI 0 "register_operand" "=r")
1243 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1245 (clobber (reg:CC 100))]
1248 [(set_attr "length" "2")])
1251 [(set (match_operand:SI 0 "register_operand" "")
1252 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1254 (clobber (reg:CC 100))]
1256 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1258 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1261 (define_insn "*seqsi_zero_extend"
1262 [(set (match_operand:DI 0 "register_operand" "=r")
1263 (eq:DI (match_operand:SI 1 "register_operand" "r")
1265 (clobber (reg:CC 100))]
1268 [(set_attr "type" "unary")
1269 (set_attr "length" "2")])
1272 [(set (match_operand:DI 0 "register_operand" "")
1273 (eq:DI (match_operand:SI 1 "register_operand" "")
1275 (clobber (reg:CC 100))]
1277 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1279 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1281 (ltu:SI (reg:CC_NOOV 100)
1285 (define_insn "*seqdi_zero"
1286 [(set (match_operand:DI 0 "register_operand" "=&r")
1287 (eq:DI (match_operand:DI 1 "register_operand" "r")
1291 [(set_attr "type" "cmove")
1292 (set_attr "length" "2")])
1295 [(set (match_operand:DI 0 "register_operand" "")
1296 (eq:DI (match_operand:DI 1 "register_operand" "")
1299 [(set (match_dup 0) (const_int 0))
1300 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1306 (define_insn "*neg_seqdi_zero"
1307 [(set (match_operand:DI 0 "register_operand" "=&r")
1308 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1312 [(set_attr "type" "cmove")
1313 (set_attr "length" "2")])
1316 [(set (match_operand:DI 0 "register_operand" "")
1317 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1320 [(set (match_dup 0) (const_int 0))
1321 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1327 (define_insn "*seqdi_zero_trunc"
1328 [(set (match_operand:SI 0 "register_operand" "=&r")
1329 (eq:SI (match_operand:DI 1 "register_operand" "r")
1333 [(set_attr "type" "cmove")
1334 (set_attr "length" "2")])
1337 [(set (match_operand:SI 0 "register_operand" "")
1338 (eq:SI (match_operand:DI 1 "register_operand" "")
1341 [(set (match_dup 0) (const_int 0))
1342 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1348 ;; We can also do (x + (i == 0)) and related, so put them in.
1349 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1352 (define_insn "*x_plus_i_ne_0"
1353 [(set (match_operand:SI 0 "register_operand" "=r")
1354 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1356 (match_operand:SI 2 "register_operand" "r")))
1357 (clobber (reg:CC 100))]
1360 [(set_attr "length" "2")])
1363 [(set (match_operand:SI 0 "register_operand" "")
1364 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1366 (match_operand:SI 2 "register_operand" "")))
1367 (clobber (reg:CC 100))]
1369 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1371 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1375 (define_insn "*x_minus_i_ne_0"
1376 [(set (match_operand:SI 0 "register_operand" "=r")
1377 (minus:SI (match_operand:SI 2 "register_operand" "r")
1378 (ne:SI (match_operand:SI 1 "register_operand" "r")
1380 (clobber (reg:CC 100))]
1383 [(set_attr "length" "2")])
1386 [(set (match_operand:SI 0 "register_operand" "")
1387 (minus:SI (match_operand:SI 2 "register_operand" "")
1388 (ne:SI (match_operand:SI 1 "register_operand" "")
1390 (clobber (reg:CC 100))]
1392 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1394 (set (match_dup 0) (minus:SI (match_dup 2)
1395 (ltu:SI (reg:CC 100) (const_int 0))))]
1398 (define_insn "*x_plus_i_eq_0"
1399 [(set (match_operand:SI 0 "register_operand" "=r")
1400 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1402 (match_operand:SI 2 "register_operand" "r")))
1403 (clobber (reg:CC 100))]
1406 [(set_attr "length" "2")])
1409 [(set (match_operand:SI 0 "register_operand" "")
1410 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1412 (match_operand:SI 2 "register_operand" "")))
1413 (clobber (reg:CC 100))]
1415 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1417 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1421 (define_insn "*x_minus_i_eq_0"
1422 [(set (match_operand:SI 0 "register_operand" "=r")
1423 (minus:SI (match_operand:SI 2 "register_operand" "r")
1424 (eq:SI (match_operand:SI 1 "register_operand" "r")
1426 (clobber (reg:CC 100))]
1429 [(set_attr "length" "2")])
1432 [(set (match_operand:SI 0 "register_operand" "")
1433 (minus:SI (match_operand:SI 2 "register_operand" "")
1434 (eq:SI (match_operand:SI 1 "register_operand" "")
1436 (clobber (reg:CC 100))]
1438 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1440 (set (match_dup 0) (minus:SI (match_dup 2)
1441 (geu:SI (reg:CC 100) (const_int 0))))]
1444 ;; We can also do GEU and LTU directly, but these operate after a compare.
1445 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1448 (define_insn "*sltu_insn"
1449 [(set (match_operand:SI 0 "register_operand" "=r")
1450 (ltu:SI (reg:CC 100) (const_int 0)))]
1452 "addx\\t%%g0, 0, %0"
1453 [(set_attr "type" "misc")
1454 (set_attr "length" "1")])
1456 (define_insn "*neg_sltu_insn"
1457 [(set (match_operand:SI 0 "register_operand" "=r")
1458 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1460 "subx\\t%%g0, 0, %0"
1461 [(set_attr "type" "misc")
1462 (set_attr "length" "1")])
1464 ;; ??? Combine should canonicalize these next two to the same pattern.
1465 (define_insn "*neg_sltu_minus_x"
1466 [(set (match_operand:SI 0 "register_operand" "=r")
1467 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1468 (match_operand:SI 1 "arith_operand" "rI")))]
1470 "subx\\t%%g0, %1, %0"
1471 [(set_attr "type" "misc")
1472 (set_attr "length" "1")])
1474 (define_insn "*neg_sltu_plus_x"
1475 [(set (match_operand:SI 0 "register_operand" "=r")
1476 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1477 (match_operand:SI 1 "arith_operand" "rI"))))]
1479 "subx\\t%%g0, %1, %0"
1480 [(set_attr "type" "misc")
1481 (set_attr "length" "1")])
1483 (define_insn "*sgeu_insn"
1484 [(set (match_operand:SI 0 "register_operand" "=r")
1485 (geu:SI (reg:CC 100) (const_int 0)))]
1487 "subx\\t%%g0, -1, %0"
1488 [(set_attr "type" "misc")
1489 (set_attr "length" "1")])
1491 (define_insn "*neg_sgeu_insn"
1492 [(set (match_operand:SI 0 "register_operand" "=r")
1493 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1495 "addx\\t%%g0, -1, %0"
1496 [(set_attr "type" "misc")
1497 (set_attr "length" "1")])
1499 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1500 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1503 (define_insn "*sltu_plus_x"
1504 [(set (match_operand:SI 0 "register_operand" "=r")
1505 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1506 (match_operand:SI 1 "arith_operand" "rI")))]
1508 "addx\\t%%g0, %1, %0"
1509 [(set_attr "type" "misc")
1510 (set_attr "length" "1")])
1512 (define_insn "*sltu_plus_x_plus_y"
1513 [(set (match_operand:SI 0 "register_operand" "=r")
1514 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1515 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1516 (match_operand:SI 2 "arith_operand" "rI"))))]
1519 [(set_attr "type" "misc")
1520 (set_attr "length" "1")])
1522 (define_insn "*x_minus_sltu"
1523 [(set (match_operand:SI 0 "register_operand" "=r")
1524 (minus:SI (match_operand:SI 1 "register_operand" "r")
1525 (ltu:SI (reg:CC 100) (const_int 0))))]
1528 [(set_attr "type" "misc")
1529 (set_attr "length" "1")])
1531 ;; ??? Combine should canonicalize these next two to the same pattern.
1532 (define_insn "*x_minus_y_minus_sltu"
1533 [(set (match_operand:SI 0 "register_operand" "=r")
1534 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1535 (match_operand:SI 2 "arith_operand" "rI"))
1536 (ltu:SI (reg:CC 100) (const_int 0))))]
1538 "subx\\t%r1, %2, %0"
1539 [(set_attr "type" "misc")
1540 (set_attr "length" "1")])
1542 (define_insn "*x_minus_sltu_plus_y"
1543 [(set (match_operand:SI 0 "register_operand" "=r")
1544 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1545 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1546 (match_operand:SI 2 "arith_operand" "rI"))))]
1548 "subx\\t%r1, %2, %0"
1549 [(set_attr "type" "misc")
1550 (set_attr "length" "1")])
1552 (define_insn "*sgeu_plus_x"
1553 [(set (match_operand:SI 0 "register_operand" "=r")
1554 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1555 (match_operand:SI 1 "register_operand" "r")))]
1558 [(set_attr "type" "misc")
1559 (set_attr "length" "1")])
1561 (define_insn "*x_minus_sgeu"
1562 [(set (match_operand:SI 0 "register_operand" "=r")
1563 (minus:SI (match_operand:SI 1 "register_operand" "r")
1564 (geu:SI (reg:CC 100) (const_int 0))))]
1567 [(set_attr "type" "misc")
1568 (set_attr "length" "1")])
1571 [(set (match_operand:SI 0 "register_operand" "=r")
1572 (match_operator:SI 2 "noov_compare_op"
1573 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1575 ;; 32 bit LTU/GEU are better implemented using addx/subx
1576 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1577 && (GET_MODE (operands[1]) == CCXmode
1578 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1579 [(set (match_dup 0) (const_int 0))
1581 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1587 ;; These control RTL generation for conditional jump insns
1589 ;; The quad-word fp compare library routines all return nonzero to indicate
1590 ;; true, which is different from the equivalent libgcc routines, so we must
1591 ;; handle them specially here.
1593 (define_expand "beq"
1595 (if_then_else (eq (match_dup 1) (const_int 0))
1596 (label_ref (match_operand 0 "" ""))
1601 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1602 && GET_CODE (sparc_compare_op0) == REG
1603 && GET_MODE (sparc_compare_op0) == DImode)
1605 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1608 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1610 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1611 emit_jump_insn (gen_bne (operands[0]));
1614 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1617 (define_expand "bne"
1619 (if_then_else (ne (match_dup 1) (const_int 0))
1620 (label_ref (match_operand 0 "" ""))
1625 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1626 && GET_CODE (sparc_compare_op0) == REG
1627 && GET_MODE (sparc_compare_op0) == DImode)
1629 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1632 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1634 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1635 emit_jump_insn (gen_bne (operands[0]));
1638 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1641 (define_expand "bgt"
1643 (if_then_else (gt (match_dup 1) (const_int 0))
1644 (label_ref (match_operand 0 "" ""))
1649 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1650 && GET_CODE (sparc_compare_op0) == REG
1651 && GET_MODE (sparc_compare_op0) == DImode)
1653 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1656 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1658 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1659 emit_jump_insn (gen_bne (operands[0]));
1662 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1665 (define_expand "bgtu"
1667 (if_then_else (gtu (match_dup 1) (const_int 0))
1668 (label_ref (match_operand 0 "" ""))
1672 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1675 (define_expand "blt"
1677 (if_then_else (lt (match_dup 1) (const_int 0))
1678 (label_ref (match_operand 0 "" ""))
1683 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1684 && GET_CODE (sparc_compare_op0) == REG
1685 && GET_MODE (sparc_compare_op0) == DImode)
1687 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1690 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1692 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1693 emit_jump_insn (gen_bne (operands[0]));
1696 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1699 (define_expand "bltu"
1701 (if_then_else (ltu (match_dup 1) (const_int 0))
1702 (label_ref (match_operand 0 "" ""))
1706 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1709 (define_expand "bge"
1711 (if_then_else (ge (match_dup 1) (const_int 0))
1712 (label_ref (match_operand 0 "" ""))
1717 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1718 && GET_CODE (sparc_compare_op0) == REG
1719 && GET_MODE (sparc_compare_op0) == DImode)
1721 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1724 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1726 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1727 emit_jump_insn (gen_bne (operands[0]));
1730 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1733 (define_expand "bgeu"
1735 (if_then_else (geu (match_dup 1) (const_int 0))
1736 (label_ref (match_operand 0 "" ""))
1740 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1743 (define_expand "ble"
1745 (if_then_else (le (match_dup 1) (const_int 0))
1746 (label_ref (match_operand 0 "" ""))
1751 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1752 && GET_CODE (sparc_compare_op0) == REG
1753 && GET_MODE (sparc_compare_op0) == DImode)
1755 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1758 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1760 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1761 emit_jump_insn (gen_bne (operands[0]));
1764 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1767 (define_expand "bleu"
1769 (if_then_else (leu (match_dup 1) (const_int 0))
1770 (label_ref (match_operand 0 "" ""))
1774 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1777 ;; Now match both normal and inverted jump.
1779 ;; XXX fpcmp nop braindamage
1780 (define_insn "*normal_branch"
1782 (if_then_else (match_operator 0 "noov_compare_op"
1783 [(reg 100) (const_int 0)])
1784 (label_ref (match_operand 1 "" ""))
1789 return output_cbranch (operands[0], 1, 0,
1790 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1791 ! final_sequence, insn);
1793 [(set_attr "type" "branch")])
1795 ;; XXX fpcmp nop braindamage
1796 (define_insn "*inverted_branch"
1798 (if_then_else (match_operator 0 "noov_compare_op"
1799 [(reg 100) (const_int 0)])
1801 (label_ref (match_operand 1 "" ""))))]
1805 return output_cbranch (operands[0], 1, 1,
1806 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1807 ! final_sequence, insn);
1809 [(set_attr "type" "branch")])
1811 ;; XXX fpcmp nop braindamage
1812 (define_insn "*normal_fp_branch"
1814 (if_then_else (match_operator 1 "comparison_operator"
1815 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1817 (label_ref (match_operand 2 "" ""))
1822 return output_cbranch (operands[1], 2, 0,
1823 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1824 ! final_sequence, insn);
1826 [(set_attr "type" "branch")])
1828 ;; XXX fpcmp nop braindamage
1829 (define_insn "*inverted_fp_branch"
1831 (if_then_else (match_operator 1 "comparison_operator"
1832 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1835 (label_ref (match_operand 2 "" ""))))]
1839 return output_cbranch (operands[1], 2, 1,
1840 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1841 ! final_sequence, insn);
1843 [(set_attr "type" "branch")])
1845 ;; XXX fpcmp nop braindamage
1846 (define_insn "*normal_fpe_branch"
1848 (if_then_else (match_operator 1 "comparison_operator"
1849 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1851 (label_ref (match_operand 2 "" ""))
1856 return output_cbranch (operands[1], 2, 0,
1857 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1858 ! final_sequence, insn);
1860 [(set_attr "type" "branch")])
1862 ;; XXX fpcmp nop braindamage
1863 (define_insn "*inverted_fpe_branch"
1865 (if_then_else (match_operator 1 "comparison_operator"
1866 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1869 (label_ref (match_operand 2 "" ""))))]
1873 return output_cbranch (operands[1], 2, 1,
1874 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1875 ! final_sequence, insn);
1877 [(set_attr "type" "branch")])
1879 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1880 ;; in the architecture.
1882 ;; There are no 32 bit brreg insns.
1885 (define_insn "*normal_int_branch_sp64"
1887 (if_then_else (match_operator 0 "v9_regcmp_op"
1888 [(match_operand:DI 1 "register_operand" "r")
1890 (label_ref (match_operand 2 "" ""))
1895 return output_v9branch (operands[0], 1, 2, 0,
1896 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1897 ! final_sequence, insn);
1899 [(set_attr "type" "branch")])
1902 (define_insn "*inverted_int_branch_sp64"
1904 (if_then_else (match_operator 0 "v9_regcmp_op"
1905 [(match_operand:DI 1 "register_operand" "r")
1908 (label_ref (match_operand 2 "" ""))))]
1912 return output_v9branch (operands[0], 1, 2, 1,
1913 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1914 ! final_sequence, insn);
1916 [(set_attr "type" "branch")])
1918 ;; Load program counter insns.
1920 (define_insn "get_pc"
1921 [(clobber (reg:SI 15))
1922 (set (match_operand 0 "register_operand" "=r")
1923 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
1924 "flag_pic && REGNO (operands[0]) == 23"
1925 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
1926 [(set_attr "length" "3")])
1928 ;; Currently unused...
1929 ;; (define_insn "get_pc_via_rdpc"
1930 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
1933 ;; [(set_attr "type" "move")])
1936 ;; Move instructions
1938 (define_expand "movqi"
1939 [(set (match_operand:QI 0 "general_operand" "")
1940 (match_operand:QI 1 "general_operand" ""))]
1944 /* Working with CONST_INTs is easier, so convert
1945 a double if needed. */
1946 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1948 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
1950 else if (GET_CODE (operands[1]) == CONST_INT)
1952 /* And further, we know for all QI cases that only the
1953 low byte is significant, which we can always process
1954 in a single insn. So mask it now. */
1955 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
1958 /* Handle sets of MEM first. */
1959 if (GET_CODE (operands[0]) == MEM)
1961 /* This checks TARGET_LIVE_G0 for us. */
1962 if (reg_or_0_operand (operands[1], QImode))
1965 if (! reload_in_progress)
1967 operands[0] = validize_mem (operands[0]);
1968 operands[1] = force_reg (QImode, operands[1]);
1972 /* Fixup PIC cases. */
1975 if (CONSTANT_P (operands[1])
1976 && pic_address_needs_scratch (operands[1]))
1977 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1979 if (symbolic_operand (operands[1], QImode))
1981 operands[1] = legitimize_pic_address (operands[1],
1983 (reload_in_progress ?
1990 /* All QI constants require only one insn, so proceed. */
1996 (define_insn "*movqi_insn"
1997 [(set (match_operand:QI 0 "general_operand" "=r,r,m")
1998 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1999 "(register_operand (operands[0], QImode)
2000 || reg_or_0_operand (operands[1], QImode))"
2005 [(set_attr "type" "move,load,store")
2006 (set_attr "length" "1")])
2008 (define_expand "movhi"
2009 [(set (match_operand:HI 0 "general_operand" "")
2010 (match_operand:HI 1 "general_operand" ""))]
2014 /* Working with CONST_INTs is easier, so convert
2015 a double if needed. */
2016 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2017 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2019 /* Handle sets of MEM first. */
2020 if (GET_CODE (operands[0]) == MEM)
2022 /* This checks TARGET_LIVE_G0 for us. */
2023 if (reg_or_0_operand (operands[1], HImode))
2026 if (! reload_in_progress)
2028 operands[0] = validize_mem (operands[0]);
2029 operands[1] = force_reg (HImode, operands[1]);
2033 /* Fixup PIC cases. */
2036 if (CONSTANT_P (operands[1])
2037 && pic_address_needs_scratch (operands[1]))
2038 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2040 if (symbolic_operand (operands[1], HImode))
2042 operands[1] = legitimize_pic_address (operands[1],
2044 (reload_in_progress ?
2051 /* This makes sure we will not get rematched due to splittage. */
2052 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2054 else if (CONSTANT_P (operands[1])
2055 && GET_CODE (operands[1]) != HIGH
2056 && GET_CODE (operands[1]) != LO_SUM)
2058 sparc_emit_set_const32 (operands[0], operands[1]);
2065 (define_insn "*movhi_const64_special"
2066 [(set (match_operand:HI 0 "register_operand" "=r")
2067 (match_operand:HI 1 "const64_high_operand" ""))]
2069 "sethi\\t%%hi(%a1), %0"
2070 [(set_attr "type" "move")
2071 (set_attr "length" "1")])
2073 (define_insn "*movhi_insn"
2074 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
2075 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2076 "(register_operand (operands[0], HImode)
2077 || reg_or_0_operand (operands[1], HImode))"
2080 sethi\\t%%hi(%a1), %0
2083 [(set_attr "type" "move,move,load,store")
2084 (set_attr "length" "1")])
2086 ;; We always work with constants here.
2087 (define_insn "*movhi_lo_sum"
2088 [(set (match_operand:HI 0 "register_operand" "=r")
2089 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2090 (match_operand:HI 2 "arith_operand" "I")))]
2093 [(set_attr "type" "ialu")
2094 (set_attr "length" "1")])
2096 (define_expand "movsi"
2097 [(set (match_operand:SI 0 "general_operand" "")
2098 (match_operand:SI 1 "general_operand" ""))]
2102 /* Working with CONST_INTs is easier, so convert
2103 a double if needed. */
2104 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2105 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2107 /* Handle sets of MEM first. */
2108 if (GET_CODE (operands[0]) == MEM)
2110 /* This checks TARGET_LIVE_G0 for us. */
2111 if (reg_or_0_operand (operands[1], SImode))
2114 if (! reload_in_progress)
2116 operands[0] = validize_mem (operands[0]);
2117 operands[1] = force_reg (SImode, operands[1]);
2121 /* Fixup PIC cases. */
2124 if (CONSTANT_P (operands[1])
2125 && pic_address_needs_scratch (operands[1]))
2126 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2128 if (GET_CODE (operands[1]) == LABEL_REF)
2131 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2135 if (symbolic_operand (operands[1], SImode))
2137 operands[1] = legitimize_pic_address (operands[1],
2139 (reload_in_progress ?
2146 /* If we are trying to toss an integer constant into the
2147 FPU registers, force it into memory. */
2148 if (GET_CODE (operands[0]) == REG
2149 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2150 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2151 && CONSTANT_P (operands[1]))
2152 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2155 /* This makes sure we will not get rematched due to splittage. */
2156 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2158 else if (CONSTANT_P (operands[1])
2159 && GET_CODE (operands[1]) != HIGH
2160 && GET_CODE (operands[1]) != LO_SUM)
2162 sparc_emit_set_const32 (operands[0], operands[1]);
2169 ;; Special LIVE_G0 pattern to obtain zero in a register.
2170 (define_insn "*movsi_zero_liveg0"
2171 [(set (match_operand:SI 0 "register_operand" "=r")
2172 (match_operand:SI 1 "zero_operand" "J"))]
2175 [(set_attr "type" "binary")
2176 (set_attr "length" "1")])
2178 ;; This is needed to show CSE exactly which bits are set
2179 ;; in a 64-bit register by sethi instructions.
2180 (define_insn "*movsi_const64_special"
2181 [(set (match_operand:SI 0 "register_operand" "=r")
2182 (match_operand:SI 1 "const64_high_operand" ""))]
2184 "sethi\\t%%hi(%a1), %0"
2185 [(set_attr "type" "move")
2186 (set_attr "length" "1")])
2188 (define_insn "*movsi_insn"
2189 [(set (match_operand:SI 0 "general_operand" "=r,f,r,r,r,f,m,m,d")
2190 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2191 "(register_operand (operands[0], SImode)
2192 || reg_or_0_operand (operands[1], SImode))"
2196 sethi\\t%%hi(%a1), %0
2203 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2204 (set_attr "length" "1")])
2206 (define_insn "*movsi_lo_sum"
2207 [(set (match_operand:SI 0 "register_operand" "=r")
2208 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2209 (match_operand:SI 2 "immediate_operand" "in")))]
2211 "or\\t%1, %%lo(%a2), %0"
2212 [(set_attr "type" "ialu")
2213 (set_attr "length" "1")])
2215 (define_insn "*movsi_high"
2216 [(set (match_operand:SI 0 "register_operand" "=r")
2217 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2219 "sethi\\t%%hi(%a1), %0"
2220 [(set_attr "type" "move")
2221 (set_attr "length" "1")])
2223 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2224 ;; so that CSE won't optimize the address computation away.
2225 (define_insn "movsi_lo_sum_pic"
2226 [(set (match_operand:SI 0 "register_operand" "=r")
2227 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2228 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2230 "or\\t%1, %%lo(%a2), %0"
2231 [(set_attr "type" "ialu")
2232 (set_attr "length" "1")])
2234 (define_insn "movsi_high_pic"
2235 [(set (match_operand:SI 0 "register_operand" "=r")
2236 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2237 "flag_pic && check_pic (1)"
2238 "sethi\\t%%hi(%a1), %0"
2239 [(set_attr "type" "move")
2240 (set_attr "length" "1")])
2242 (define_expand "movsi_pic_label_ref"
2243 [(set (match_dup 3) (high:SI
2244 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2246 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2247 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2248 (set (match_operand:SI 0 "register_operand" "=r")
2249 (minus:SI (match_dup 5) (match_dup 4)))]
2253 current_function_uses_pic_offset_table = 1;
2254 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2255 operands[3] = gen_reg_rtx (SImode);
2256 operands[4] = gen_reg_rtx (SImode);
2257 operands[5] = pic_offset_table_rtx;
2260 (define_insn "*movsi_high_pic_label_ref"
2261 [(set (match_operand:SI 0 "register_operand" "=r")
2263 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2264 (match_operand:SI 2 "" "")] 5)))]
2266 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2267 [(set_attr "type" "move")
2268 (set_attr "length" "1")])
2270 (define_insn "*movsi_lo_sum_pic_label_ref"
2271 [(set (match_operand:SI 0 "register_operand" "=r")
2272 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2273 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2274 (match_operand:SI 3 "" "")] 5)))]
2276 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2277 [(set_attr "type" "ialu")
2278 (set_attr "length" "1")])
2280 (define_expand "movdi"
2281 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2282 (match_operand:DI 1 "general_operand" ""))]
2286 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2287 if (GET_CODE (operands[1]) == CONST_DOUBLE
2288 #if HOST_BITS_PER_WIDE_INT == 32
2289 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2290 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2291 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2292 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2295 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2297 /* Handle MEM cases first. */
2298 if (GET_CODE (operands[0]) == MEM)
2300 /* If it's a REG, we can always do it.
2301 The const zero case is more complex, on v9
2302 we can always perform it. */
2303 if (register_operand (operands[1], DImode)
2305 && (operands[1] == const0_rtx)))
2308 if (! reload_in_progress)
2310 operands[0] = validize_mem (operands[0]);
2311 operands[1] = force_reg (DImode, operands[1]);
2317 if (CONSTANT_P (operands[1])
2318 && pic_address_needs_scratch (operands[1]))
2319 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2321 if (GET_CODE (operands[1]) == LABEL_REF)
2323 if (! TARGET_ARCH64)
2325 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2329 if (symbolic_operand (operands[1], DImode))
2331 operands[1] = legitimize_pic_address (operands[1],
2333 (reload_in_progress ?
2340 /* If we are trying to toss an integer constant into the
2341 FPU registers, force it into memory. */
2342 if (GET_CODE (operands[0]) == REG
2343 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2344 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2345 && CONSTANT_P (operands[1]))
2346 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2349 /* This makes sure we will not get rematched due to splittage. */
2350 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2352 else if (TARGET_ARCH64
2353 && CONSTANT_P (operands[1])
2354 && GET_CODE (operands[1]) != HIGH
2355 && GET_CODE (operands[1]) != LO_SUM)
2357 sparc_emit_set_const64 (operands[0], operands[1]);
2365 ;; Be careful, fmovd does not exist when !arch64.
2366 ;; We match MEM moves directly when we have correct even
2367 ;; numbered registers, but fall into splits otherwise.
2368 ;; The constraint ordering here is really important to
2369 ;; avoid insane problems in reload, especially for patterns
2372 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2373 ;; (const_int -5016)))
2376 (define_insn "*movdi_insn_sp32"
2377 [(set (match_operand:DI 0 "general_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2378 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2380 (register_operand (operands[0], DImode)
2381 || register_operand (operands[1], DImode))"
2394 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2395 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2397 ;; The following are generated by sparc_emit_set_const64
2398 (define_insn "*movdi_sp64_dbl"
2399 [(set (match_operand:DI 0 "register_operand" "=r")
2400 (match_operand:DI 1 "const64_operand" ""))]
2402 && HOST_BITS_PER_WIDE_INT != 64)"
2404 [(set_attr "type" "move")
2405 (set_attr "length" "1")])
2407 ;; This is needed to show CSE exactly which bits are set
2408 ;; in a 64-bit register by sethi instructions.
2409 (define_insn "*movdi_const64_special"
2410 [(set (match_operand:DI 0 "register_operand" "=r")
2411 (match_operand:DI 1 "const64_high_operand" ""))]
2413 "sethi\\t%%hi(%a1), %0"
2414 [(set_attr "type" "move")
2415 (set_attr "length" "1")])
2417 (define_insn "*movdi_insn_sp64"
2418 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,m,?e,?e,?m,b")
2419 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2421 (register_operand (operands[0], DImode)
2422 || reg_or_0_operand (operands[1], DImode))"
2425 sethi\\t%%hi(%a1), %0
2433 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove")
2434 (set_attr "length" "1")])
2436 (define_expand "movdi_pic_label_ref"
2437 [(set (match_dup 3) (high:DI
2438 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2440 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2441 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2442 (set (match_operand:DI 0 "register_operand" "=r")
2443 (minus:DI (match_dup 5) (match_dup 4)))]
2444 "TARGET_ARCH64 && flag_pic"
2447 current_function_uses_pic_offset_table = 1;
2448 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2449 operands[3] = gen_reg_rtx (DImode);
2450 operands[4] = gen_reg_rtx (DImode);
2451 operands[5] = pic_offset_table_rtx;
2454 (define_insn "*movdi_high_pic_label_ref"
2455 [(set (match_operand:DI 0 "register_operand" "=r")
2457 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2458 (match_operand:DI 2 "" "")] 5)))]
2459 "TARGET_ARCH64 && flag_pic"
2460 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2461 [(set_attr "type" "move")
2462 (set_attr "length" "1")])
2464 (define_insn "*movdi_lo_sum_pic_label_ref"
2465 [(set (match_operand:DI 0 "register_operand" "=r")
2466 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2467 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2468 (match_operand:DI 3 "" "")] 5)))]
2469 "TARGET_ARCH64 && flag_pic"
2470 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2471 [(set_attr "type" "ialu")
2472 (set_attr "length" "1")])
2474 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2475 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2477 (define_insn "movdi_lo_sum_pic"
2478 [(set (match_operand:DI 0 "register_operand" "=r")
2479 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2480 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2481 "TARGET_ARCH64 && flag_pic"
2482 "or\\t%1, %%lo(%a2), %0"
2483 [(set_attr "type" "ialu")
2484 (set_attr "length" "1")])
2486 (define_insn "movdi_high_pic"
2487 [(set (match_operand:DI 0 "register_operand" "=r")
2488 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2489 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2490 "sethi\\t%%hi(%a1), %0"
2491 [(set_attr "type" "move")
2492 (set_attr "length" "1")])
2494 (define_insn "*sethi_di_medlow_embmedany_pic"
2495 [(set (match_operand:DI 0 "register_operand" "=r")
2496 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2497 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2498 "sethi\\t%%lo(%a1), %0"
2499 [(set_attr "type" "move")
2500 (set_attr "length" "1")])
2502 (define_insn "*sethi_di_medlow"
2503 [(set (match_operand:DI 0 "register_operand" "=r")
2504 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2505 "TARGET_CM_MEDLOW && check_pic (1)"
2506 "sethi\\t%%hi(%a1), %0"
2507 [(set_attr "type" "move")
2508 (set_attr "length" "1")])
2510 (define_insn "*losum_di_medlow"
2511 [(set (match_operand:DI 0 "register_operand" "=r")
2512 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2513 (match_operand:DI 2 "symbolic_operand" "")))]
2515 "or\\t%1, %%lo(%a2), %0"
2516 [(set_attr "type" "ialu")
2517 (set_attr "length" "1")])
2519 (define_insn "seth44"
2520 [(set (match_operand:DI 0 "register_operand" "=r")
2521 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2523 "sethi\\t%%h44(%a1), %0"
2524 [(set_attr "type" "move")
2525 (set_attr "length" "1")])
2527 (define_insn "setm44"
2528 [(set (match_operand:DI 0 "register_operand" "=r")
2529 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2530 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2532 "or\\t%1, %%m44(%a2), %0"
2533 [(set_attr "type" "move")
2534 (set_attr "length" "1")])
2536 (define_insn "setl44"
2537 [(set (match_operand:DI 0 "register_operand" "=r")
2538 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2539 (match_operand:DI 2 "symbolic_operand" "")))]
2541 "or\\t%1, %%l44(%a2), %0"
2542 [(set_attr "type" "ialu")
2543 (set_attr "length" "1")])
2545 (define_insn "sethh"
2546 [(set (match_operand:DI 0 "register_operand" "=r")
2547 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2549 "sethi\\t%%hh(%a1), %0"
2550 [(set_attr "type" "move")
2551 (set_attr "length" "1")])
2553 (define_insn "setlm"
2554 [(set (match_operand:DI 0 "register_operand" "=r")
2555 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2557 "sethi\\t%%lm(%a1), %0"
2558 [(set_attr "type" "move")
2559 (set_attr "length" "1")])
2561 (define_insn "sethm"
2562 [(set (match_operand:DI 0 "register_operand" "=r")
2563 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2564 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2566 "or\\t%1, %%hm(%a2), %0"
2567 [(set_attr "type" "ialu")
2568 (set_attr "length" "1")])
2570 (define_insn "setlo"
2571 [(set (match_operand:DI 0 "register_operand" "=r")
2572 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2573 (match_operand:DI 2 "symbolic_operand" "")))]
2575 "or\\t%1, %%lo(%a2), %0"
2576 [(set_attr "type" "ialu")
2577 (set_attr "length" "1")])
2579 (define_insn "embmedany_sethi"
2580 [(set (match_operand:DI 0 "register_operand" "=r")
2581 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2582 "TARGET_CM_EMBMEDANY && check_pic (1)"
2583 "sethi\\t%%hi(%a1), %0"
2584 [(set_attr "type" "move")
2585 (set_attr "length" "1")])
2587 (define_insn "embmedany_losum"
2588 [(set (match_operand:DI 0 "register_operand" "=r")
2589 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2590 (match_operand:DI 2 "data_segment_operand" "")))]
2591 "TARGET_CM_EMBMEDANY"
2592 "add\\t%1, %%lo(%a2), %0"
2593 [(set_attr "type" "ialu")
2594 (set_attr "length" "1")])
2596 (define_insn "embmedany_brsum"
2597 [(set (match_operand:DI 0 "register_operand" "=r")
2598 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2599 "TARGET_CM_EMBMEDANY"
2601 [(set_attr "length" "1")])
2603 (define_insn "embmedany_textuhi"
2604 [(set (match_operand:DI 0 "register_operand" "=r")
2605 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2606 "TARGET_CM_EMBMEDANY && check_pic (1)"
2607 "sethi\\t%%uhi(%a1), %0"
2608 [(set_attr "type" "move")
2609 (set_attr "length" "1")])
2611 (define_insn "embmedany_texthi"
2612 [(set (match_operand:DI 0 "register_operand" "=r")
2613 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2614 "TARGET_CM_EMBMEDANY && check_pic (1)"
2615 "sethi\\t%%hi(%a1), %0"
2616 [(set_attr "type" "move")
2617 (set_attr "length" "1")])
2619 (define_insn "embmedany_textulo"
2620 [(set (match_operand:DI 0 "register_operand" "=r")
2621 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2622 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2623 "TARGET_CM_EMBMEDANY"
2624 "or\\t%1, %%ulo(%a2), %0"
2625 [(set_attr "type" "ialu")
2626 (set_attr "length" "1")])
2628 (define_insn "embmedany_textlo"
2629 [(set (match_operand:DI 0 "register_operand" "=r")
2630 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2631 (match_operand:DI 2 "text_segment_operand" "")))]
2632 "TARGET_CM_EMBMEDANY"
2633 "or\\t%1, %%lo(%a2), %0"
2634 [(set_attr "type" "ialu")
2635 (set_attr "length" "1")])
2637 ;; Now some patterns to help reload out a bit.
2638 (define_expand "reload_indi"
2639 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2640 (match_operand:DI 1 "immediate_operand" "")
2641 (match_operand:TI 2 "register_operand" "=&r")])]
2643 || TARGET_CM_EMBMEDANY)
2647 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2648 gen_rtx_REG (DImode, REGNO (operands[2])));
2652 (define_expand "reload_outdi"
2653 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2654 (match_operand:DI 1 "immediate_operand" "")
2655 (match_operand:TI 2 "register_operand" "=&r")])]
2657 || TARGET_CM_EMBMEDANY)
2661 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2662 gen_rtx_REG (DImode, REGNO (operands[2])));
2666 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2668 [(set (match_operand:DI 0 "register_operand" "")
2669 (match_operand:DI 1 "const_int_operand" ""))]
2670 "! TARGET_ARCH64 && reload_completed"
2671 [(clobber (const_int 0))]
2674 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2675 (INTVAL (operands[1]) < 0) ?
2678 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2684 [(set (match_operand:DI 0 "register_operand" "")
2685 (match_operand:DI 1 "const_double_operand" ""))]
2686 "! TARGET_ARCH64 && reload_completed"
2687 [(clobber (const_int 0))]
2690 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2691 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2693 /* Slick... but this trick loses if this subreg constant part
2694 can be done in one insn. */
2695 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2696 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2697 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2699 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2700 gen_highpart (SImode, operands[0])));
2704 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2705 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2711 [(set (match_operand:DI 0 "register_operand" "")
2712 (match_operand:DI 1 "register_operand" ""))]
2713 "! TARGET_ARCH64 && reload_completed"
2714 [(clobber (const_int 0))]
2717 rtx set_dest = operands[0];
2718 rtx set_src = operands[1];
2722 if (GET_CODE (set_dest) == SUBREG)
2723 set_dest = alter_subreg (set_dest);
2724 if (GET_CODE (set_src) == SUBREG)
2725 set_src = alter_subreg (set_src);
2727 dest1 = gen_highpart (SImode, set_dest);
2728 dest2 = gen_lowpart (SImode, set_dest);
2729 src1 = gen_highpart (SImode, set_src);
2730 src2 = gen_lowpart (SImode, set_src);
2732 /* Now emit using the real source and destination we found, swapping
2733 the order if we detect overlap. */
2734 if (reg_overlap_mentioned_p (dest1, src2))
2736 emit_insn (gen_movsi (dest2, src2));
2737 emit_insn (gen_movsi (dest1, src1));
2741 emit_insn (gen_movsi (dest1, src1));
2742 emit_insn (gen_movsi (dest2, src2));
2747 ;; Now handle the cases of memory moves from/to non-even
2748 ;; DI mode register pairs.
2750 [(set (match_operand:DI 0 "register_operand" "")
2751 (match_operand:DI 1 "memory_operand" ""))]
2754 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2755 [(clobber (const_int 0))]
2758 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2759 rtx word1 = change_address (operands[1], SImode,
2760 plus_constant_for_output (XEXP (word0, 0), 4));
2761 rtx high_part = gen_highpart (SImode, operands[0]);
2762 rtx low_part = gen_lowpart (SImode, operands[0]);
2764 if (reg_overlap_mentioned_p (high_part, word1))
2766 emit_insn (gen_movsi (low_part, word1));
2767 emit_insn (gen_movsi (high_part, word0));
2771 emit_insn (gen_movsi (high_part, word0));
2772 emit_insn (gen_movsi (low_part, word1));
2778 [(set (match_operand:DI 0 "memory_operand" "")
2779 (match_operand:DI 1 "register_operand" ""))]
2782 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2783 [(clobber (const_int 0))]
2786 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2787 rtx word1 = change_address (operands[0], SImode,
2788 plus_constant_for_output (XEXP (word0, 0), 4));
2789 rtx high_part = gen_highpart (SImode, operands[1]);
2790 rtx low_part = gen_lowpart (SImode, operands[1]);
2792 emit_insn (gen_movsi (word0, high_part));
2793 emit_insn (gen_movsi (word1, low_part));
2798 ;; Floating point move insns
2800 (define_insn "*clear_sf"
2801 [(set (match_operand:SF 0 "general_operand" "=f")
2802 (match_operand:SF 1 "" ""))]
2804 && GET_CODE (operands[1]) == CONST_DOUBLE
2805 && GET_CODE (operands[0]) == REG
2806 && fp_zero_operand (operands[1])"
2808 [(set_attr "type" "fpmove")
2809 (set_attr "length" "1")])
2811 (define_insn "*movsf_const_intreg"
2812 [(set (match_operand:SF 0 "general_operand" "=f,r")
2813 (match_operand:SF 1 "" "m,F"))]
2815 && GET_CODE (operands[1]) == CONST_DOUBLE
2816 && GET_CODE (operands[0]) == REG"
2822 if (which_alternative == 0)
2823 return \"ld\\t%1, %0\";
2825 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2826 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2827 if (SPARC_SIMM13_P (i) || SPARC_SETHI_P (i))
2829 operands[1] = GEN_INT (i);
2830 if (SPARC_SIMM13_P (INTVAL (operands[1])))
2831 return \"mov\\t%1, %0\";
2832 else if (SPARC_SETHI_P (INTVAL (operands[1])))
2833 return \"sethi\\t%%hi(%a1), %0\";
2840 [(set_attr "type" "move")
2841 (set_attr "length" "1")])
2843 ;; There isn't much I can do about this, if I change the
2844 ;; mode then flow info gets really confused because the
2845 ;; destination no longer looks the same. Ho hum...
2846 (define_insn "*movsf_const_high"
2847 [(set (match_operand:SF 0 "register_operand" "=r")
2848 (unspec:SF [(match_operand 1 "const_int_operand" "")] 12))]
2850 "sethi\\t%%hi(%a1), %0"
2851 [(set_attr "type" "move")
2852 (set_attr "length" "1")])
2854 (define_insn "*movsf_const_lo"
2855 [(set (match_operand:SF 0 "register_operand" "=r")
2856 (unspec:SF [(match_operand 1 "register_operand" "r")
2857 (match_operand 2 "const_int_operand" "")] 17))]
2859 "or\\t%1, %%lo(%a2), %0"
2860 [(set_attr "type" "move")
2861 (set_attr "length" "1")])
2864 [(set (match_operand:SF 0 "register_operand" "")
2865 (match_operand:SF 1 "const_double_operand" ""))]
2867 && (GET_CODE (operands[0]) == REG
2868 && REGNO (operands[0]) < 32)"
2869 [(set (match_dup 0) (unspec:SF [(match_dup 1)] 12))
2870 (set (match_dup 0) (unspec:SF [(match_dup 0) (match_dup 1)] 17))]
2876 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2877 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2878 operands[1] = GEN_INT (i);
2881 (define_expand "movsf"
2882 [(set (match_operand:SF 0 "general_operand" "")
2883 (match_operand:SF 1 "general_operand" ""))]
2887 /* Force SFmode constants into memory. */
2888 if (GET_CODE (operands[0]) == REG
2889 && CONSTANT_P (operands[1]))
2892 && GET_CODE (operands[1]) == CONST_DOUBLE
2893 && fp_zero_operand (operands[1]))
2896 /* emit_group_store will send such bogosity to us when it is
2897 not storing directly into memory. So fix this up to avoid
2898 crashes in output_constant_pool. */
2899 if (operands [1] == const0_rtx)
2900 operands[1] = CONST0_RTX (SFmode);
2901 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2905 /* Handle sets of MEM first. */
2906 if (GET_CODE (operands[0]) == MEM)
2908 if (register_operand (operands[1], SFmode))
2911 if (! reload_in_progress)
2913 operands[0] = validize_mem (operands[0]);
2914 operands[1] = force_reg (SFmode, operands[1]);
2918 /* Fixup PIC cases. */
2921 if (CONSTANT_P (operands[1])
2922 && pic_address_needs_scratch (operands[1]))
2923 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2925 if (symbolic_operand (operands[1], SFmode))
2927 operands[1] = legitimize_pic_address (operands[1],
2929 (reload_in_progress ?
2939 (define_insn "*movsf_insn"
2940 [(set (match_operand:SF 0 "general_operand" "=f,f,m,r,r,m")
2941 (match_operand:SF 1 "input_operand" "f,m,f,r,m,r"))]
2943 && (register_operand (operands[0], SFmode)
2944 || register_operand (operands[1], SFmode))"
2952 [(set_attr "type" "fpmove,fpload,fpstore,move,load,store")
2953 (set_attr "length" "1")])
2955 ;; Exactly the same as above, except that all `f' cases are deleted.
2956 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2959 (define_insn "*movsf_no_f_insn"
2960 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
2961 (match_operand:SF 1 "input_operand" "r,m,r"))]
2963 && (register_operand (operands[0], SFmode)
2964 || register_operand (operands[1], SFmode))"
2969 [(set_attr "type" "move,load,store")
2970 (set_attr "length" "1")])
2972 (define_insn "*clear_df"
2973 [(set (match_operand:DF 0 "general_operand" "=e")
2974 (match_operand:DF 1 "" ""))]
2976 && GET_CODE (operands[1]) == CONST_DOUBLE
2977 && GET_CODE (operands[0]) == REG
2978 && fp_zero_operand (operands[1])"
2980 [(set_attr "type" "fpmove")
2981 (set_attr "length" "1")])
2983 (define_insn "*movdf_const_intreg_sp32"
2984 [(set (match_operand:DF 0 "general_operand" "=e,e,r")
2985 (match_operand:DF 1 "" "T,o,F"))]
2986 "TARGET_FPU && ! TARGET_ARCH64
2987 && GET_CODE (operands[1]) == CONST_DOUBLE
2988 && GET_CODE (operands[0]) == REG"
2991 if (which_alternative == 0)
2992 return \"ldd\\t%1, %0\";
2996 [(set_attr "type" "move")
2997 (set_attr "length" "1,2,2")])
2999 ;; Now that we redo life analysis with a clean slate after
3000 ;; instruction splitting for sched2 this can work.
3001 (define_insn "*movdf_const_intreg_sp64"
3002 [(set (match_operand:DF 0 "general_operand" "=e,e,r")
3003 (match_operand:DF 1 "" "m,o,F"))]
3006 && GET_CODE (operands[1]) == CONST_DOUBLE
3007 && GET_CODE (operands[0]) == REG"
3010 if (which_alternative == 0)
3011 return \"ldd\\t%1, %0\";
3015 [(set_attr "type" "move")
3016 (set_attr "length" "1")])
3019 [(set (match_operand:DF 0 "register_operand" "")
3020 (match_operand:DF 1 "const_double_operand" ""))]
3022 && GET_CODE (operands[1]) == CONST_DOUBLE
3023 && (GET_CODE (operands[0]) == REG
3024 && REGNO (operands[0]) < 32)
3025 && reload_completed"
3026 [(clobber (const_int 0))]
3032 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3033 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3034 if (GET_CODE (operands[0]) == SUBREG)
3035 operands[0] = alter_subreg (operands[0]);
3036 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3040 #if HOST_BITS_PER_WIDE_INT == 64
3043 val = ((HOST_WIDE_INT)l[1] |
3044 ((HOST_WIDE_INT)l[0] << 32));
3045 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3047 emit_insn (gen_movdi (operands[0],
3048 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3054 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3057 /* Slick... but this trick loses if this subreg constant part
3058 can be done in one insn. */
3060 && !(SPARC_SETHI_P (l[0])
3061 || SPARC_SIMM13_P (l[0])))
3063 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3064 gen_highpart (SImode, operands[0])));
3068 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3075 (define_expand "movdf"
3076 [(set (match_operand:DF 0 "general_operand" "")
3077 (match_operand:DF 1 "general_operand" ""))]
3081 /* Force DFmode constants into memory. */
3082 if (GET_CODE (operands[0]) == REG
3083 && CONSTANT_P (operands[1]))
3086 && GET_CODE (operands[1]) == CONST_DOUBLE
3087 && fp_zero_operand (operands[1]))
3090 /* emit_group_store will send such bogosity to us when it is
3091 not storing directly into memory. So fix this up to avoid
3092 crashes in output_constant_pool. */
3093 if (operands [1] == const0_rtx)
3094 operands[1] = CONST0_RTX (DFmode);
3095 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3099 /* Handle MEM cases first. */
3100 if (GET_CODE (operands[0]) == MEM)
3102 if (register_operand (operands[1], DFmode))
3105 if (! reload_in_progress)
3107 operands[0] = validize_mem (operands[0]);
3108 operands[1] = force_reg (DFmode, operands[1]);
3112 /* Fixup PIC cases. */
3115 if (CONSTANT_P (operands[1])
3116 && pic_address_needs_scratch (operands[1]))
3117 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3119 if (symbolic_operand (operands[1], DFmode))
3121 operands[1] = legitimize_pic_address (operands[1],
3123 (reload_in_progress ?
3133 ;; Be careful, fmovd does not exist when !v9.
3134 (define_insn "*movdf_insn_sp32"
3135 [(set (match_operand:DF 0 "general_operand" "=e,T,U,T,e,r,r,o,e,o")
3136 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3139 && (register_operand (operands[0], DFmode)
3140 || register_operand (operands[1], DFmode))"
3152 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3153 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3155 (define_insn "*movdf_no_e_insn_sp32"
3156 [(set (match_operand:DF 0 "general_operand" "=U,T,r,r,o")
3157 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3160 && (register_operand (operands[0], DFmode)
3161 || register_operand (operands[1], DFmode))"
3168 [(set_attr "type" "load,store,*,*,*")
3169 (set_attr "length" "1,1,2,2,2")])
3171 ;; We have available v9 double floats but not 64-bit
3172 ;; integer registers.
3173 (define_insn "*movdf_insn_v9only"
3174 [(set (match_operand:DF 0 "general_operand" "=e,e,m,U,T,r,r,o")
3175 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3179 && (register_operand (operands[0], DFmode)
3180 || register_operand (operands[1], DFmode))"
3190 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3191 (set_attr "length" "1,1,1,1,1,2,2,2")])
3193 ;; We have available both v9 double floats and 64-bit
3194 ;; integer registers.
3195 (define_insn "*movdf_insn_sp64"
3196 [(set (match_operand:DF 0 "general_operand" "=e,e,m,r,r,m")
3197 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3201 && (register_operand (operands[0], DFmode)
3202 || register_operand (operands[1], DFmode))"
3210 [(set_attr "type" "fpmove,load,store,move,load,store")
3211 (set_attr "length" "1")])
3213 (define_insn "*movdf_no_e_insn_sp64"
3214 [(set (match_operand:DF 0 "general_operand" "=r,r,m")
3215 (match_operand:DF 1 "input_operand" "r,m,r"))]
3218 && (register_operand (operands[0], DFmode)
3219 || register_operand (operands[1], DFmode))"
3224 [(set_attr "type" "move,load,store")
3225 (set_attr "length" "1")])
3227 ;; Ok, now the splits to handle all the multi insn and
3228 ;; mis-aligned memory address cases.
3229 ;; In these splits please take note that we must be
3230 ;; careful when V9 but not ARCH64 because the integer
3231 ;; register DFmode cases must be handled.
3233 [(set (match_operand:DF 0 "register_operand" "")
3234 (match_operand:DF 1 "register_operand" ""))]
3237 && ((GET_CODE (operands[0]) == REG
3238 && REGNO (operands[0]) < 32)
3239 || (GET_CODE (operands[0]) == SUBREG
3240 && GET_CODE (SUBREG_REG (operands[0])) == REG
3241 && REGNO (SUBREG_REG (operands[0])) < 32))))
3242 && reload_completed"
3243 [(clobber (const_int 0))]
3246 rtx set_dest = operands[0];
3247 rtx set_src = operands[1];
3251 if (GET_CODE (set_dest) == SUBREG)
3252 set_dest = alter_subreg (set_dest);
3253 if (GET_CODE (set_src) == SUBREG)
3254 set_src = alter_subreg (set_src);
3256 dest1 = gen_highpart (SFmode, set_dest);
3257 dest2 = gen_lowpart (SFmode, set_dest);
3258 src1 = gen_highpart (SFmode, set_src);
3259 src2 = gen_lowpart (SFmode, set_src);
3261 /* Now emit using the real source and destination we found, swapping
3262 the order if we detect overlap. */
3263 if (reg_overlap_mentioned_p (dest1, src2))
3265 emit_insn (gen_movsf (dest2, src2));
3266 emit_insn (gen_movsf (dest1, src1));
3270 emit_insn (gen_movsf (dest1, src1));
3271 emit_insn (gen_movsf (dest2, src2));
3277 [(set (match_operand:DF 0 "register_operand" "")
3278 (match_operand:DF 1 "memory_operand" ""))]
3281 && ((GET_CODE (operands[0]) == REG
3282 && REGNO (operands[0]) < 32)
3283 || (GET_CODE (operands[0]) == SUBREG
3284 && GET_CODE (SUBREG_REG (operands[0])) == REG
3285 && REGNO (SUBREG_REG (operands[0])) < 32))))
3286 && (reload_completed
3287 && (((REGNO (operands[0])) % 2) != 0
3288 || ! mem_min_alignment (operands[1], 8))
3289 && offsettable_memref_p (operands[1])))"
3290 [(clobber (const_int 0))]
3293 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3294 rtx word1 = change_address (operands[1], SFmode,
3295 plus_constant_for_output (XEXP (word0, 0), 4));
3297 if (GET_CODE (operands[0]) == SUBREG)
3298 operands[0] = alter_subreg (operands[0]);
3300 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3302 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3304 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3309 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3311 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3318 [(set (match_operand:DF 0 "memory_operand" "")
3319 (match_operand:DF 1 "register_operand" ""))]
3322 && ((GET_CODE (operands[1]) == REG
3323 && REGNO (operands[1]) < 32)
3324 || (GET_CODE (operands[1]) == SUBREG
3325 && GET_CODE (SUBREG_REG (operands[1])) == REG
3326 && REGNO (SUBREG_REG (operands[1])) < 32))))
3327 && (reload_completed
3328 && (((REGNO (operands[1])) % 2) != 0
3329 || ! mem_min_alignment (operands[0], 8))
3330 && offsettable_memref_p (operands[0])))"
3331 [(clobber (const_int 0))]
3334 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3335 rtx word1 = change_address (operands[0], SFmode,
3336 plus_constant_for_output (XEXP (word0, 0), 4));
3338 if (GET_CODE (operands[1]) == SUBREG)
3339 operands[1] = alter_subreg (operands[1]);
3340 emit_insn (gen_movsf (word0,
3341 gen_highpart (SFmode, operands[1])));
3342 emit_insn (gen_movsf (word1,
3343 gen_lowpart (SFmode, operands[1])));
3347 (define_expand "movtf"
3348 [(set (match_operand:TF 0 "general_operand" "")
3349 (match_operand:TF 1 "general_operand" ""))]
3353 /* Force TFmode constants into memory. */
3354 if (GET_CODE (operands[0]) == REG
3355 && CONSTANT_P (operands[1]))
3357 /* emit_group_store will send such bogosity to us when it is
3358 not storing directly into memory. So fix this up to avoid
3359 crashes in output_constant_pool. */
3360 if (operands [1] == const0_rtx)
3361 operands[1] = CONST0_RTX (TFmode);
3362 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3366 /* Handle MEM cases first, note that only v9 guarentees
3367 full 16-byte alignment for quads. */
3368 if (GET_CODE (operands[0]) == MEM)
3370 if (register_operand (operands[1], TFmode))
3373 if (! reload_in_progress)
3375 operands[0] = validize_mem (operands[0]);
3376 operands[1] = force_reg (TFmode, operands[1]);
3380 /* Fixup PIC cases. */
3383 if (CONSTANT_P (operands[1])
3384 && pic_address_needs_scratch (operands[1]))
3385 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3387 if (symbolic_operand (operands[1], TFmode))
3389 operands[1] = legitimize_pic_address (operands[1],
3391 (reload_in_progress ?
3401 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3402 ;; we must split them all. :-(
3403 (define_insn "*movtf_insn_sp32"
3404 [(set (match_operand:TF 0 "general_operand" "=e,o,U,o,e,r,r,o")
3405 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3408 && (register_operand (operands[0], TFmode)
3409 || register_operand (operands[1], TFmode))"
3411 [(set_attr "length" "4")])
3413 ;; Exactly the same as above, except that all `e' cases are deleted.
3414 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3417 (define_insn "*movtf_no_e_insn_sp32"
3418 [(set (match_operand:TF 0 "general_operand" "=U,o,r,r,o")
3419 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3422 && (register_operand (operands[0], TFmode)
3423 || register_operand (operands[1], TFmode))"
3425 [(set_attr "length" "4")])
3427 ;; Now handle the float reg cases directly when arch64,
3428 ;; hard_quad, and proper reg number alignment are all true.
3429 (define_insn "*movtf_insn_hq_sp64"
3430 [(set (match_operand:TF 0 "general_operand" "=e,e,m,r,r,o")
3431 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3436 && (register_operand (operands[0], TFmode)
3437 || register_operand (operands[1], TFmode))"
3445 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3446 (set_attr "length" "1,1,1,2,2,2")])
3448 ;; Now we allow the integer register cases even when
3449 ;; only arch64 is true.
3450 (define_insn "*movtf_insn_sp64"
3451 [(set (match_operand:TF 0 "general_operand" "=e,o,r,o,e,r")
3452 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3455 && ! TARGET_HARD_QUAD
3456 && (register_operand (operands[0], TFmode)
3457 || register_operand (operands[1], TFmode))"
3459 [(set_attr "length" "2")])
3461 (define_insn "*movtf_no_e_insn_sp64"
3462 [(set (match_operand:TF 0 "general_operand" "=r,o,r")
3463 (match_operand:TF 1 "input_operand" "o,r,r"))]
3466 && (register_operand (operands[0], TFmode)
3467 || register_operand (operands[1], TFmode))"
3469 [(set_attr "length" "2")])
3471 ;; Now all the splits to handle multi-insn TF mode moves.
3473 [(set (match_operand:TF 0 "register_operand" "")
3474 (match_operand:TF 1 "register_operand" ""))]
3478 && ! TARGET_HARD_QUAD))"
3479 [(clobber (const_int 0))]
3482 rtx set_dest = operands[0];
3483 rtx set_src = operands[1];
3487 if (GET_CODE (set_dest) == SUBREG)
3488 set_dest = alter_subreg (set_dest);
3489 if (GET_CODE (set_src) == SUBREG)
3490 set_src = alter_subreg (set_src);
3492 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3493 dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
3494 dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
3495 src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0);
3496 src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0);
3498 /* Now emit using the real source and destination we found, swapping
3499 the order if we detect overlap. */
3500 if (reg_overlap_mentioned_p (dest1, src2))
3502 emit_insn (gen_movdf (dest2, src2));
3503 emit_insn (gen_movdf (dest1, src1));
3507 emit_insn (gen_movdf (dest1, src1));
3508 emit_insn (gen_movdf (dest2, src2));
3514 [(set (match_operand:TF 0 "register_operand" "")
3515 (match_operand:TF 1 "memory_operand" ""))]
3517 && offsettable_memref_p (operands[1]))"
3518 [(clobber (const_int 0))]
3521 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3522 rtx word1 = change_address (operands[1], DFmode,
3523 plus_constant_for_output (XEXP (word0, 0), 8));
3526 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3527 dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
3528 dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
3530 /* Now output, ordering such that we don't clobber any registers
3531 mentioned in the address. */
3532 if (reg_overlap_mentioned_p (dest1, word1))
3535 emit_insn (gen_movdf (dest2, word1));
3536 emit_insn (gen_movdf (dest1, word0));
3540 emit_insn (gen_movdf (dest1, word0));
3541 emit_insn (gen_movdf (dest2, word1));
3547 [(set (match_operand:TF 0 "memory_operand" "")
3548 (match_operand:TF 1 "register_operand" ""))]
3550 && offsettable_memref_p (operands[0]))"
3551 [(clobber (const_int 0))]
3554 rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
3555 rtx word1 = change_address (operands[0], DFmode,
3556 plus_constant_for_output (XEXP (word0, 0), 8));
3559 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3560 src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
3561 src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
3562 emit_insn (gen_movdf (word0, src1));
3563 emit_insn (gen_movdf (word1, src2));
3567 ;; Sparc V9 conditional move instructions.
3569 ;; We can handle larger constants here for some flavors, but for now we keep
3570 ;; it simple and only allow those constants supported by all flavours.
3571 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3572 ;; 3 contains the constant if one is present, but we handle either for
3573 ;; generality (sparc.c puts a constant in operand 2).
3575 (define_expand "movqicc"
3576 [(set (match_operand:QI 0 "register_operand" "")
3577 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3578 (match_operand:QI 2 "arith10_operand" "")
3579 (match_operand:QI 3 "arith10_operand" "")))]
3583 enum rtx_code code = GET_CODE (operands[1]);
3585 if (GET_MODE (sparc_compare_op0) == DImode
3589 if (sparc_compare_op1 == const0_rtx
3590 && GET_CODE (sparc_compare_op0) == REG
3591 && GET_MODE (sparc_compare_op0) == DImode
3592 && v9_regcmp_p (code))
3594 operands[1] = gen_rtx_fmt_ee (code, DImode,
3595 sparc_compare_op0, sparc_compare_op1);
3599 rtx cc_reg = gen_compare_reg (code,
3600 sparc_compare_op0, sparc_compare_op1);
3601 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3605 (define_expand "movhicc"
3606 [(set (match_operand:HI 0 "register_operand" "")
3607 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3608 (match_operand:HI 2 "arith10_operand" "")
3609 (match_operand:HI 3 "arith10_operand" "")))]
3613 enum rtx_code code = GET_CODE (operands[1]);
3615 if (GET_MODE (sparc_compare_op0) == DImode
3619 if (sparc_compare_op1 == const0_rtx
3620 && GET_CODE (sparc_compare_op0) == REG
3621 && GET_MODE (sparc_compare_op0) == DImode
3622 && v9_regcmp_p (code))
3624 operands[1] = gen_rtx_fmt_ee (code, DImode,
3625 sparc_compare_op0, sparc_compare_op1);
3629 rtx cc_reg = gen_compare_reg (code,
3630 sparc_compare_op0, sparc_compare_op1);
3631 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3635 (define_expand "movsicc"
3636 [(set (match_operand:SI 0 "register_operand" "")
3637 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3638 (match_operand:SI 2 "arith10_operand" "")
3639 (match_operand:SI 3 "arith10_operand" "")))]
3643 enum rtx_code code = GET_CODE (operands[1]);
3644 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3646 if (sparc_compare_op1 == const0_rtx
3647 && GET_CODE (sparc_compare_op0) == REG
3648 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3650 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3651 sparc_compare_op0, sparc_compare_op1);
3655 rtx cc_reg = gen_compare_reg (code,
3656 sparc_compare_op0, sparc_compare_op1);
3657 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3658 cc_reg, const0_rtx);
3662 (define_expand "movdicc"
3663 [(set (match_operand:DI 0 "register_operand" "")
3664 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3665 (match_operand:DI 2 "arith10_double_operand" "")
3666 (match_operand:DI 3 "arith10_double_operand" "")))]
3670 enum rtx_code code = GET_CODE (operands[1]);
3672 if (sparc_compare_op1 == const0_rtx
3673 && GET_CODE (sparc_compare_op0) == REG
3674 && GET_MODE (sparc_compare_op0) == DImode
3675 && v9_regcmp_p (code))
3677 operands[1] = gen_rtx_fmt_ee (code, DImode,
3678 sparc_compare_op0, sparc_compare_op1);
3682 rtx cc_reg = gen_compare_reg (code,
3683 sparc_compare_op0, sparc_compare_op1);
3684 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3685 cc_reg, const0_rtx);
3689 (define_expand "movsfcc"
3690 [(set (match_operand:SF 0 "register_operand" "")
3691 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3692 (match_operand:SF 2 "register_operand" "")
3693 (match_operand:SF 3 "register_operand" "")))]
3694 "TARGET_V9 && TARGET_FPU"
3697 enum rtx_code code = GET_CODE (operands[1]);
3699 if (GET_MODE (sparc_compare_op0) == DImode
3703 if (sparc_compare_op1 == const0_rtx
3704 && GET_CODE (sparc_compare_op0) == REG
3705 && GET_MODE (sparc_compare_op0) == DImode
3706 && v9_regcmp_p (code))
3708 operands[1] = gen_rtx_fmt_ee (code, DImode,
3709 sparc_compare_op0, sparc_compare_op1);
3713 rtx cc_reg = gen_compare_reg (code,
3714 sparc_compare_op0, sparc_compare_op1);
3715 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3719 (define_expand "movdfcc"
3720 [(set (match_operand:DF 0 "register_operand" "")
3721 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3722 (match_operand:DF 2 "register_operand" "")
3723 (match_operand:DF 3 "register_operand" "")))]
3724 "TARGET_V9 && TARGET_FPU"
3727 enum rtx_code code = GET_CODE (operands[1]);
3729 if (GET_MODE (sparc_compare_op0) == DImode
3733 if (sparc_compare_op1 == const0_rtx
3734 && GET_CODE (sparc_compare_op0) == REG
3735 && GET_MODE (sparc_compare_op0) == DImode
3736 && v9_regcmp_p (code))
3738 operands[1] = gen_rtx_fmt_ee (code, DImode,
3739 sparc_compare_op0, sparc_compare_op1);
3743 rtx cc_reg = gen_compare_reg (code,
3744 sparc_compare_op0, sparc_compare_op1);
3745 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3749 (define_expand "movtfcc"
3750 [(set (match_operand:TF 0 "register_operand" "")
3751 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3752 (match_operand:TF 2 "register_operand" "")
3753 (match_operand:TF 3 "register_operand" "")))]
3754 "TARGET_V9 && TARGET_FPU"
3757 enum rtx_code code = GET_CODE (operands[1]);
3759 if (GET_MODE (sparc_compare_op0) == DImode
3763 if (sparc_compare_op1 == const0_rtx
3764 && GET_CODE (sparc_compare_op0) == REG
3765 && GET_MODE (sparc_compare_op0) == DImode
3766 && v9_regcmp_p (code))
3768 operands[1] = gen_rtx_fmt_ee (code, DImode,
3769 sparc_compare_op0, sparc_compare_op1);
3773 rtx cc_reg = gen_compare_reg (code,
3774 sparc_compare_op0, sparc_compare_op1);
3775 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3779 ;; Conditional move define_insns.
3781 (define_insn "*movqi_cc_sp64"
3782 [(set (match_operand:QI 0 "register_operand" "=r,r")
3783 (if_then_else:QI (match_operator 1 "comparison_operator"
3784 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3786 (match_operand:QI 3 "arith11_operand" "rL,0")
3787 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3790 mov%C1\\t%x2, %3, %0
3791 mov%c1\\t%x2, %4, %0"
3792 [(set_attr "type" "cmove")
3793 (set_attr "length" "1")])
3795 (define_insn "*movhi_cc_sp64"
3796 [(set (match_operand:HI 0 "register_operand" "=r,r")
3797 (if_then_else:HI (match_operator 1 "comparison_operator"
3798 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3800 (match_operand:HI 3 "arith11_operand" "rL,0")
3801 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3804 mov%C1\\t%x2, %3, %0
3805 mov%c1\\t%x2, %4, %0"
3806 [(set_attr "type" "cmove")
3807 (set_attr "length" "1")])
3809 (define_insn "*movsi_cc_sp64"
3810 [(set (match_operand:SI 0 "register_operand" "=r,r")
3811 (if_then_else:SI (match_operator 1 "comparison_operator"
3812 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3814 (match_operand:SI 3 "arith11_operand" "rL,0")
3815 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3818 mov%C1\\t%x2, %3, %0
3819 mov%c1\\t%x2, %4, %0"
3820 [(set_attr "type" "cmove")
3821 (set_attr "length" "1")])
3823 ;; ??? The constraints of operands 3,4 need work.
3824 (define_insn "*movdi_cc_sp64"
3825 [(set (match_operand:DI 0 "register_operand" "=r,r")
3826 (if_then_else:DI (match_operator 1 "comparison_operator"
3827 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3829 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3830 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3833 mov%C1\\t%x2, %3, %0
3834 mov%c1\\t%x2, %4, %0"
3835 [(set_attr "type" "cmove")
3836 (set_attr "length" "1")])
3838 (define_insn "*movdi_cc_sp64_trunc"
3839 [(set (match_operand:SI 0 "register_operand" "=r,r")
3840 (if_then_else:SI (match_operator 1 "comparison_operator"
3841 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3843 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3844 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3847 mov%C1\\t%x2, %3, %0
3848 mov%c1\\t%x2, %4, %0"
3849 [(set_attr "type" "cmove")
3850 (set_attr "length" "1")])
3852 (define_insn "*movsf_cc_sp64"
3853 [(set (match_operand:SF 0 "register_operand" "=f,f")
3854 (if_then_else:SF (match_operator 1 "comparison_operator"
3855 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3857 (match_operand:SF 3 "register_operand" "f,0")
3858 (match_operand:SF 4 "register_operand" "0,f")))]
3859 "TARGET_V9 && TARGET_FPU"
3861 fmovs%C1\\t%x2, %3, %0
3862 fmovs%c1\\t%x2, %4, %0"
3863 [(set_attr "type" "fpcmove")
3864 (set_attr "length" "1")])
3866 (define_insn "*movdf_cc_sp64"
3867 [(set (match_operand:DF 0 "register_operand" "=e,e")
3868 (if_then_else:DF (match_operator 1 "comparison_operator"
3869 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3871 (match_operand:DF 3 "register_operand" "e,0")
3872 (match_operand:DF 4 "register_operand" "0,e")))]
3873 "TARGET_V9 && TARGET_FPU"
3875 fmovd%C1\\t%x2, %3, %0
3876 fmovd%c1\\t%x2, %4, %0"
3877 [(set_attr "type" "fpcmove")
3878 (set_attr "length" "1")])
3880 (define_insn "*movtf_cc_sp64"
3881 [(set (match_operand:TF 0 "register_operand" "=e,e")
3882 (if_then_else:TF (match_operator 1 "comparison_operator"
3883 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3885 (match_operand:TF 3 "register_operand" "e,0")
3886 (match_operand:TF 4 "register_operand" "0,e")))]
3887 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3889 fmovq%C1\\t%x2, %3, %0
3890 fmovq%c1\\t%x2, %4, %0"
3891 [(set_attr "type" "fpcmove")
3892 (set_attr "length" "1")])
3894 (define_insn "*movqi_cc_reg_sp64"
3895 [(set (match_operand:QI 0 "register_operand" "=r,r")
3896 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3897 [(match_operand:DI 2 "register_operand" "r,r")
3899 (match_operand:QI 3 "arith10_operand" "rM,0")
3900 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3903 movr%D1\\t%2, %r3, %0
3904 movr%d1\\t%2, %r4, %0"
3905 [(set_attr "type" "cmove")
3906 (set_attr "length" "1")])
3908 (define_insn "*movhi_cc_reg_sp64"
3909 [(set (match_operand:HI 0 "register_operand" "=r,r")
3910 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3911 [(match_operand:DI 2 "register_operand" "r,r")
3913 (match_operand:HI 3 "arith10_operand" "rM,0")
3914 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3917 movr%D1\\t%2, %r3, %0
3918 movr%d1\\t%2, %r4, %0"
3919 [(set_attr "type" "cmove")
3920 (set_attr "length" "1")])
3922 (define_insn "*movsi_cc_reg_sp64"
3923 [(set (match_operand:SI 0 "register_operand" "=r,r")
3924 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3925 [(match_operand:DI 2 "register_operand" "r,r")
3927 (match_operand:SI 3 "arith10_operand" "rM,0")
3928 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3931 movr%D1\\t%2, %r3, %0
3932 movr%d1\\t%2, %r4, %0"
3933 [(set_attr "type" "cmove")
3934 (set_attr "length" "1")])
3936 ;; ??? The constraints of operands 3,4 need work.
3937 (define_insn "*movdi_cc_reg_sp64"
3938 [(set (match_operand:DI 0 "register_operand" "=r,r")
3939 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3940 [(match_operand:DI 2 "register_operand" "r,r")
3942 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3943 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3946 movr%D1\\t%2, %r3, %0
3947 movr%d1\\t%2, %r4, %0"
3948 [(set_attr "type" "cmove")
3949 (set_attr "length" "1")])
3951 (define_insn "*movdi_cc_reg_sp64_trunc"
3952 [(set (match_operand:SI 0 "register_operand" "=r,r")
3953 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3954 [(match_operand:DI 2 "register_operand" "r,r")
3956 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3957 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3960 movr%D1\\t%2, %r3, %0
3961 movr%d1\\t%2, %r4, %0"
3962 [(set_attr "type" "cmove")
3963 (set_attr "length" "1")])
3965 (define_insn "*movsf_cc_reg_sp64"
3966 [(set (match_operand:SF 0 "register_operand" "=f,f")
3967 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3968 [(match_operand:DI 2 "register_operand" "r,r")
3970 (match_operand:SF 3 "register_operand" "f,0")
3971 (match_operand:SF 4 "register_operand" "0,f")))]
3972 "TARGET_ARCH64 && TARGET_FPU"
3974 fmovrs%D1\\t%2, %3, %0
3975 fmovrs%d1\\t%2, %4, %0"
3976 [(set_attr "type" "fpcmove")
3977 (set_attr "length" "1")])
3979 (define_insn "*movdf_cc_reg_sp64"
3980 [(set (match_operand:DF 0 "register_operand" "=e,e")
3981 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3982 [(match_operand:DI 2 "register_operand" "r,r")
3984 (match_operand:DF 3 "register_operand" "e,0")
3985 (match_operand:DF 4 "register_operand" "0,e")))]
3986 "TARGET_ARCH64 && TARGET_FPU"
3988 fmovrd%D1\\t%2, %3, %0
3989 fmovrd%d1\\t%2, %4, %0"
3990 [(set_attr "type" "fpcmove")
3991 (set_attr "length" "1")])
3993 (define_insn "*movtf_cc_reg_sp64"
3994 [(set (match_operand:TF 0 "register_operand" "=e,e")
3995 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3996 [(match_operand:DI 2 "register_operand" "r,r")
3998 (match_operand:TF 3 "register_operand" "e,0")
3999 (match_operand:TF 4 "register_operand" "0,e")))]
4000 "TARGET_ARCH64 && TARGET_FPU"
4002 fmovrq%D1\\t%2, %3, %0
4003 fmovrq%d1\\t%2, %4, %0"
4004 [(set_attr "type" "fpcmove")
4005 (set_attr "length" "1")])
4007 ;;- zero extension instructions
4009 ;; These patterns originally accepted general_operands, however, slightly
4010 ;; better code is generated by only accepting register_operands, and then
4011 ;; letting combine generate the ldu[hb] insns.
4013 (define_expand "zero_extendhisi2"
4014 [(set (match_operand:SI 0 "register_operand" "")
4015 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4019 rtx temp = gen_reg_rtx (SImode);
4020 rtx shift_16 = GEN_INT (16);
4021 int op1_subword = 0;
4023 if (GET_CODE (operand1) == SUBREG)
4025 op1_subword = SUBREG_WORD (operand1);
4026 operand1 = XEXP (operand1, 0);
4029 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4032 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4036 (define_insn "*zero_extendhisi2_insn"
4037 [(set (match_operand:SI 0 "register_operand" "=r")
4038 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4041 [(set_attr "type" "load")
4042 (set_attr "length" "1")])
4044 (define_expand "zero_extendqihi2"
4045 [(set (match_operand:HI 0 "register_operand" "")
4046 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4050 (define_insn "*zero_extendqihi2_insn"
4051 [(set (match_operand:HI 0 "register_operand" "=r,r")
4052 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4053 "GET_CODE (operands[1]) != CONST_INT"
4057 [(set_attr "type" "unary,load")
4058 (set_attr "length" "1")])
4060 (define_expand "zero_extendqisi2"
4061 [(set (match_operand:SI 0 "register_operand" "")
4062 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4066 (define_insn "*zero_extendqisi2_insn"
4067 [(set (match_operand:SI 0 "register_operand" "=r,r")
4068 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4069 "GET_CODE (operands[1]) != CONST_INT"
4073 [(set_attr "type" "unary,load")
4074 (set_attr "length" "1")])
4076 (define_expand "zero_extendqidi2"
4077 [(set (match_operand:DI 0 "register_operand" "")
4078 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4082 (define_insn "*zero_extendqidi2_insn"
4083 [(set (match_operand:DI 0 "register_operand" "=r,r")
4084 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4085 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4089 [(set_attr "type" "unary,load")
4090 (set_attr "length" "1")])
4092 (define_expand "zero_extendhidi2"
4093 [(set (match_operand:DI 0 "register_operand" "")
4094 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4098 rtx temp = gen_reg_rtx (DImode);
4099 rtx shift_48 = GEN_INT (48);
4100 int op1_subword = 0;
4102 if (GET_CODE (operand1) == SUBREG)
4104 op1_subword = SUBREG_WORD (operand1);
4105 operand1 = XEXP (operand1, 0);
4108 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4111 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4115 (define_insn "*zero_extendhidi2_insn"
4116 [(set (match_operand:DI 0 "register_operand" "=r")
4117 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4120 [(set_attr "type" "load")
4121 (set_attr "length" "1")])
4124 ;; ??? Write truncdisi pattern using sra?
4126 (define_expand "zero_extendsidi2"
4127 [(set (match_operand:DI 0 "register_operand" "")
4128 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4132 (define_insn "*zero_extendsidi2_insn_sp64"
4133 [(set (match_operand:DI 0 "register_operand" "=r,r")
4134 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4135 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4139 [(set_attr "type" "shift,load")
4140 (set_attr "length" "1")])
4142 (define_insn "*zero_extendsidi2_insn_sp32"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4147 [(set_attr "type" "unary")
4148 (set_attr "length" "2")])
4151 [(set (match_operand:DI 0 "register_operand" "")
4152 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4153 "! TARGET_ARCH64 && reload_completed"
4154 [(set (match_dup 2) (match_dup 3))
4155 (set (match_dup 4) (match_dup 5))]
4160 if (GET_CODE (operands[0]) == SUBREG)
4161 operands[0] = alter_subreg (operands[0]);
4163 dest1 = gen_highpart (SImode, operands[0]);
4164 dest2 = gen_lowpart (SImode, operands[0]);
4166 /* Swap the order in case of overlap. */
4167 if (REGNO (dest1) == REGNO (operands[1]))
4169 operands[2] = dest2;
4170 operands[3] = operands[1];
4171 operands[4] = dest1;
4172 operands[5] = const0_rtx;
4176 operands[2] = dest1;
4177 operands[3] = const0_rtx;
4178 operands[4] = dest2;
4179 operands[5] = operands[1];
4183 ;; Simplify comparisons of extended values.
4185 (define_insn "*cmp_zero_extendqisi2"
4187 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4190 "andcc\\t%0, 0xff, %%g0"
4191 [(set_attr "type" "compare")
4192 (set_attr "length" "1")])
4194 (define_insn "*cmp_zero_extendqisi2_set"
4196 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4198 (set (match_operand:SI 0 "register_operand" "=r")
4199 (zero_extend:SI (match_dup 1)))]
4201 "andcc\\t%1, 0xff, %0"
4202 [(set_attr "type" "compare")
4203 (set_attr "length" "1")])
4205 (define_insn "*cmp_zero_extendqidi2"
4207 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4210 "andcc\\t%0, 0xff, %%g0"
4211 [(set_attr "type" "compare")
4212 (set_attr "length" "1")])
4214 (define_insn "*cmp_zero_extendqidi2_set"
4216 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4218 (set (match_operand:DI 0 "register_operand" "=r")
4219 (zero_extend:DI (match_dup 1)))]
4221 "andcc\\t%1, 0xff, %0"
4222 [(set_attr "type" "compare")
4223 (set_attr "length" "1")])
4225 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4227 (define_insn "*cmp_siqi_trunc"
4229 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4232 "andcc\\t%0, 0xff, %%g0"
4233 [(set_attr "type" "compare")
4234 (set_attr "length" "1")])
4236 (define_insn "*cmp_siqi_trunc_set"
4238 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4240 (set (match_operand:QI 0 "register_operand" "=r")
4241 (subreg:QI (match_dup 1) 0))]
4243 "andcc\\t%1, 0xff, %0"
4244 [(set_attr "type" "compare")
4245 (set_attr "length" "1")])
4247 (define_insn "*cmp_diqi_trunc"
4249 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4252 "andcc\\t%0, 0xff, %%g0"
4253 [(set_attr "type" "compare")
4254 (set_attr "length" "1")])
4256 (define_insn "*cmp_diqi_trunc_set"
4258 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4260 (set (match_operand:QI 0 "register_operand" "=r")
4261 (subreg:QI (match_dup 1) 0))]
4263 "andcc\\t%1, 0xff, %0"
4264 [(set_attr "type" "compare")
4265 (set_attr "length" "1")])
4267 ;;- sign extension instructions
4269 ;; These patterns originally accepted general_operands, however, slightly
4270 ;; better code is generated by only accepting register_operands, and then
4271 ;; letting combine generate the lds[hb] insns.
4273 (define_expand "extendhisi2"
4274 [(set (match_operand:SI 0 "register_operand" "")
4275 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4279 rtx temp = gen_reg_rtx (SImode);
4280 rtx shift_16 = GEN_INT (16);
4281 int op1_subword = 0;
4283 if (GET_CODE (operand1) == SUBREG)
4285 op1_subword = SUBREG_WORD (operand1);
4286 operand1 = XEXP (operand1, 0);
4289 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4292 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4296 (define_insn "*sign_extendhisi2_insn"
4297 [(set (match_operand:SI 0 "register_operand" "=r")
4298 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4301 [(set_attr "type" "sload")
4302 (set_attr "length" "1")])
4304 (define_expand "extendqihi2"
4305 [(set (match_operand:HI 0 "register_operand" "")
4306 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4310 rtx temp = gen_reg_rtx (SImode);
4311 rtx shift_24 = GEN_INT (24);
4312 int op1_subword = 0;
4313 int op0_subword = 0;
4315 if (GET_CODE (operand1) == SUBREG)
4317 op1_subword = SUBREG_WORD (operand1);
4318 operand1 = XEXP (operand1, 0);
4320 if (GET_CODE (operand0) == SUBREG)
4322 op0_subword = SUBREG_WORD (operand0);
4323 operand0 = XEXP (operand0, 0);
4325 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4328 if (GET_MODE (operand0) != SImode)
4329 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4330 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4334 (define_insn "*sign_extendqihi2_insn"
4335 [(set (match_operand:HI 0 "register_operand" "=r")
4336 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4339 [(set_attr "type" "sload")
4340 (set_attr "length" "1")])
4342 (define_expand "extendqisi2"
4343 [(set (match_operand:SI 0 "register_operand" "")
4344 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4348 rtx temp = gen_reg_rtx (SImode);
4349 rtx shift_24 = GEN_INT (24);
4350 int op1_subword = 0;
4352 if (GET_CODE (operand1) == SUBREG)
4354 op1_subword = SUBREG_WORD (operand1);
4355 operand1 = XEXP (operand1, 0);
4358 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4361 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4365 (define_insn "*sign_extendqisi2_insn"
4366 [(set (match_operand:SI 0 "register_operand" "=r")
4367 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4370 [(set_attr "type" "sload")
4371 (set_attr "length" "1")])
4373 (define_expand "extendqidi2"
4374 [(set (match_operand:DI 0 "register_operand" "")
4375 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4379 rtx temp = gen_reg_rtx (DImode);
4380 rtx shift_56 = GEN_INT (56);
4381 int op1_subword = 0;
4383 if (GET_CODE (operand1) == SUBREG)
4385 op1_subword = SUBREG_WORD (operand1);
4386 operand1 = XEXP (operand1, 0);
4389 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4392 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4396 (define_insn "*sign_extendqidi2_insn"
4397 [(set (match_operand:DI 0 "register_operand" "=r")
4398 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4401 [(set_attr "type" "sload")
4402 (set_attr "length" "1")])
4404 (define_expand "extendhidi2"
4405 [(set (match_operand:DI 0 "register_operand" "")
4406 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4410 rtx temp = gen_reg_rtx (DImode);
4411 rtx shift_48 = GEN_INT (48);
4412 int op1_subword = 0;
4414 if (GET_CODE (operand1) == SUBREG)
4416 op1_subword = SUBREG_WORD (operand1);
4417 operand1 = XEXP (operand1, 0);
4420 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4423 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4427 (define_insn "*sign_extendhidi2_insn"
4428 [(set (match_operand:DI 0 "register_operand" "=r")
4429 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4432 [(set_attr "type" "sload")
4433 (set_attr "length" "1")])
4435 (define_expand "extendsidi2"
4436 [(set (match_operand:DI 0 "register_operand" "")
4437 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4441 (define_insn "*sign_extendsidi2_insn"
4442 [(set (match_operand:DI 0 "register_operand" "=r,r")
4443 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4448 [(set_attr "type" "shift,sload")
4449 (set_attr "length" "1")])
4451 ;; Special pattern for optimizing bit-field compares. This is needed
4452 ;; because combine uses this as a canonical form.
4454 (define_insn "*cmp_zero_extract"
4457 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4458 (match_operand:SI 1 "small_int_or_double" "n")
4459 (match_operand:SI 2 "small_int_or_double" "n"))
4462 && ((GET_CODE (operands[2]) == CONST_INT
4463 && INTVAL (operands[2]) > 19)
4464 || (GET_CODE (operands[2]) == CONST_DOUBLE
4465 && CONST_DOUBLE_LOW (operands[2]) > 19))"
4468 int len = (GET_CODE (operands[1]) == CONST_INT
4469 ? INTVAL (operands[1])
4470 : CONST_DOUBLE_LOW (operands[1]));
4472 (GET_CODE (operands[2]) == CONST_INT
4473 ? INTVAL (operands[2])
4474 : CONST_DOUBLE_LOW (operands[2])) - len;
4475 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4477 operands[1] = GEN_INT (mask);
4478 return \"andcc\\t%0, %1, %%g0\";
4480 [(set_attr "type" "compare")
4481 (set_attr "length" "1")])
4483 (define_insn "*cmp_zero_extract_sp64"
4486 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4487 (match_operand:SI 1 "small_int_or_double" "n")
4488 (match_operand:SI 2 "small_int_or_double" "n"))
4491 && ((GET_CODE (operands[2]) == CONST_INT
4492 && INTVAL (operands[2]) > 51)
4493 || (GET_CODE (operands[2]) == CONST_DOUBLE
4494 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4497 int len = (GET_CODE (operands[1]) == CONST_INT
4498 ? INTVAL (operands[1])
4499 : CONST_DOUBLE_LOW (operands[1]));
4501 (GET_CODE (operands[2]) == CONST_INT
4502 ? INTVAL (operands[2])
4503 : CONST_DOUBLE_LOW (operands[2])) - len;
4504 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4506 operands[1] = GEN_INT (mask);
4507 return \"andcc\\t%0, %1, %%g0\";
4509 [(set_attr "type" "compare")
4510 (set_attr "length" "1")])
4512 ;; Conversions between float, double and long double.
4514 (define_insn "extendsfdf2"
4515 [(set (match_operand:DF 0 "register_operand" "=e")
4517 (match_operand:SF 1 "register_operand" "f")))]
4520 [(set_attr "type" "fp")
4521 (set_attr "length" "1")])
4523 (define_insn "extendsftf2"
4524 [(set (match_operand:TF 0 "register_operand" "=e")
4526 (match_operand:SF 1 "register_operand" "f")))]
4527 "TARGET_FPU && TARGET_HARD_QUAD"
4529 [(set_attr "type" "fp")
4530 (set_attr "length" "1")])
4532 (define_insn "extenddftf2"
4533 [(set (match_operand:TF 0 "register_operand" "=e")
4535 (match_operand:DF 1 "register_operand" "e")))]
4536 "TARGET_FPU && TARGET_HARD_QUAD"
4538 [(set_attr "type" "fp")
4539 (set_attr "length" "1")])
4541 (define_insn "truncdfsf2"
4542 [(set (match_operand:SF 0 "register_operand" "=f")
4544 (match_operand:DF 1 "register_operand" "e")))]
4547 [(set_attr "type" "fp")
4548 (set_attr "length" "1")])
4550 (define_insn "trunctfsf2"
4551 [(set (match_operand:SF 0 "register_operand" "=f")
4553 (match_operand:TF 1 "register_operand" "e")))]
4554 "TARGET_FPU && TARGET_HARD_QUAD"
4556 [(set_attr "type" "fp")
4557 (set_attr "length" "1")])
4559 (define_insn "trunctfdf2"
4560 [(set (match_operand:DF 0 "register_operand" "=e")
4562 (match_operand:TF 1 "register_operand" "e")))]
4563 "TARGET_FPU && TARGET_HARD_QUAD"
4565 [(set_attr "type" "fp")
4566 (set_attr "length" "1")])
4568 ;; Conversion between fixed point and floating point.
4570 (define_insn "floatsisf2"
4571 [(set (match_operand:SF 0 "register_operand" "=f")
4572 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4575 [(set_attr "type" "fp")
4576 (set_attr "length" "1")])
4578 (define_insn "floatsidf2"
4579 [(set (match_operand:DF 0 "register_operand" "=e")
4580 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4583 [(set_attr "type" "fp")
4584 (set_attr "length" "1")])
4586 (define_insn "floatsitf2"
4587 [(set (match_operand:TF 0 "register_operand" "=e")
4588 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4589 "TARGET_FPU && TARGET_HARD_QUAD"
4591 [(set_attr "type" "fp")
4592 (set_attr "length" "1")])
4594 ;; Now the same for 64 bit sources.
4596 (define_insn "floatdisf2"
4597 [(set (match_operand:SF 0 "register_operand" "=f")
4598 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4599 "TARGET_V9 && TARGET_FPU"
4601 [(set_attr "type" "fp")
4602 (set_attr "length" "1")])
4604 (define_insn "floatdidf2"
4605 [(set (match_operand:DF 0 "register_operand" "=e")
4606 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4607 "TARGET_V9 && TARGET_FPU"
4609 [(set_attr "type" "fp")
4610 (set_attr "length" "1")])
4612 (define_insn "floatditf2"
4613 [(set (match_operand:TF 0 "register_operand" "=e")
4614 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4615 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4617 [(set_attr "type" "fp")
4618 (set_attr "length" "1")])
4620 ;; Convert a float to an actual integer.
4621 ;; Truncation is performed as part of the conversion.
4623 (define_insn "fix_truncsfsi2"
4624 [(set (match_operand:SI 0 "register_operand" "=f")
4625 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4628 [(set_attr "type" "fp")
4629 (set_attr "length" "1")])
4631 (define_insn "fix_truncdfsi2"
4632 [(set (match_operand:SI 0 "register_operand" "=f")
4633 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4636 [(set_attr "type" "fp")
4637 (set_attr "length" "1")])
4639 (define_insn "fix_trunctfsi2"
4640 [(set (match_operand:SI 0 "register_operand" "=f")
4641 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4642 "TARGET_FPU && TARGET_HARD_QUAD"
4644 [(set_attr "type" "fp")
4645 (set_attr "length" "1")])
4647 ;; Now the same, for V9 targets
4649 (define_insn "fix_truncsfdi2"
4650 [(set (match_operand:DI 0 "register_operand" "=e")
4651 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4652 "TARGET_V9 && TARGET_FPU"
4654 [(set_attr "type" "fp")
4655 (set_attr "length" "1")])
4657 (define_insn "fix_truncdfdi2"
4658 [(set (match_operand:DI 0 "register_operand" "=e")
4659 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4660 "TARGET_V9 && TARGET_FPU"
4662 [(set_attr "type" "fp")
4663 (set_attr "length" "1")])
4665 (define_insn "fix_trunctfdi2"
4666 [(set (match_operand:DI 0 "register_operand" "=e")
4667 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4668 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4670 [(set_attr "type" "fp")
4671 (set_attr "length" "1")])
4673 ;;- arithmetic instructions
4675 (define_expand "adddi3"
4676 [(set (match_operand:DI 0 "register_operand" "=r")
4677 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4678 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4682 if (! TARGET_ARCH64)
4684 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4685 gen_rtx_SET (VOIDmode, operands[0],
4686 gen_rtx_PLUS (DImode, operands[1],
4688 gen_rtx_CLOBBER (VOIDmode,
4689 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4692 if (arith_double_4096_operand(operands[2], DImode))
4694 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4695 gen_rtx_MINUS (DImode, operands[1],
4701 (define_insn "adddi3_insn_sp32"
4702 [(set (match_operand:DI 0 "register_operand" "=r")
4703 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4704 (match_operand:DI 2 "arith_double_operand" "rHI")))
4705 (clobber (reg:CC 100))]
4708 [(set_attr "length" "2")])
4711 [(set (match_operand:DI 0 "register_operand" "=r")
4712 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4713 (match_operand:DI 2 "arith_double_operand" "rHI")))
4714 (clobber (reg:CC 100))]
4715 "! TARGET_ARCH64 && reload_completed"
4716 [(parallel [(set (reg:CC_NOOV 100)
4717 (compare:CC_NOOV (plus:SI (match_dup 4)
4721 (plus:SI (match_dup 4) (match_dup 5)))])
4723 (plus:SI (plus:SI (match_dup 7)
4725 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4728 operands[3] = gen_lowpart (SImode, operands[0]);
4729 operands[4] = gen_lowpart (SImode, operands[1]);
4730 operands[5] = gen_lowpart (SImode, operands[2]);
4731 operands[6] = gen_highpart (SImode, operands[0]);
4732 operands[7] = gen_highpart (SImode, operands[1]);
4733 if (GET_CODE (operands[2]) == CONST_INT)
4735 if (INTVAL (operands[2]) < 0)
4736 operands[8] = constm1_rtx;
4738 operands[8] = const0_rtx;
4741 operands[8] = gen_highpart (SImode, operands[2]);
4745 [(set (match_operand:DI 0 "register_operand" "=r")
4746 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
4747 (match_operand:DI 2 "arith_double_operand" "rHI")))
4748 (clobber (reg:CC 100))]
4749 "! TARGET_ARCH64 && reload_completed"
4750 [(parallel [(set (reg:CC_NOOV 100)
4751 (compare:CC_NOOV (minus:SI (match_dup 4)
4755 (minus:SI (match_dup 4) (match_dup 5)))])
4757 (minus:SI (minus:SI (match_dup 7)
4759 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4762 operands[3] = gen_lowpart (SImode, operands[0]);
4763 operands[4] = gen_lowpart (SImode, operands[1]);
4764 operands[5] = gen_lowpart (SImode, operands[2]);
4765 operands[6] = gen_highpart (SImode, operands[0]);
4766 operands[7] = gen_highpart (SImode, operands[1]);
4767 if (GET_CODE (operands[2]) == CONST_INT)
4769 if (INTVAL (operands[2]) < 0)
4770 operands[8] = constm1_rtx;
4772 operands[8] = const0_rtx;
4775 operands[8] = gen_highpart (SImode, operands[2]);
4778 ;; LTU here means "carry set"
4780 [(set (match_operand:SI 0 "register_operand" "=r")
4781 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4782 (match_operand:SI 2 "arith_operand" "rI"))
4783 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4786 [(set_attr "type" "unary")
4787 (set_attr "length" "1")])
4789 (define_insn "*addx_extend_sp32"
4790 [(set (match_operand:DI 0 "register_operand" "=r")
4791 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4792 (match_operand:SI 2 "arith_operand" "rI"))
4793 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4796 [(set_attr "type" "unary")
4797 (set_attr "length" "2")])
4800 [(set (match_operand:DI 0 "register_operand" "")
4801 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
4802 (match_operand:SI 2 "arith_operand" ""))
4803 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4804 "! TARGET_ARCH64 && reload_completed"
4805 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4806 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4807 (set (match_dup 4) (const_int 0))]
4808 "operands[3] = gen_lowpart (SImode, operands[0]);
4809 operands[4] = gen_highpart (SImode, operands[1]);")
4811 (define_insn "*addx_extend_sp64"
4812 [(set (match_operand:DI 0 "register_operand" "=r")
4813 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4814 (match_operand:SI 2 "arith_operand" "rI"))
4815 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4817 "addx\\t%r1, %2, %0"
4818 [(set_attr "type" "misc")
4819 (set_attr "length" "1")])
4822 [(set (match_operand:SI 0 "register_operand" "=r")
4823 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4824 (match_operand:SI 2 "arith_operand" "rI"))
4825 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4827 "subx\\t%r1, %2, %0"
4828 [(set_attr "type" "misc")
4829 (set_attr "length" "1")])
4831 (define_insn "*subx_extend_sp64"
4832 [(set (match_operand:DI 0 "register_operand" "=r")
4833 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4834 (match_operand:SI 2 "arith_operand" "rI"))
4835 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4837 "subx\\t%r1, %2, %0"
4838 [(set_attr "type" "misc")
4839 (set_attr "length" "1")])
4841 (define_insn "*subx_extend"
4842 [(set (match_operand:DI 0 "register_operand" "=r")
4843 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4844 (match_operand:SI 2 "arith_operand" "rI"))
4845 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4848 [(set_attr "type" "unary")
4849 (set_attr "length" "2")])
4852 [(set (match_operand:DI 0 "register_operand" "=r")
4853 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4854 (match_operand:SI 2 "arith_operand" "rI"))
4855 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4856 "! TARGET_ARCH64 && reload_completed"
4857 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4858 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4859 (set (match_dup 4) (const_int 0))]
4860 "operands[3] = gen_lowpart (SImode, operands[0]);
4861 operands[4] = gen_highpart (SImode, operands[0]);")
4864 [(set (match_operand:DI 0 "register_operand" "=r")
4865 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4866 (match_operand:DI 2 "register_operand" "r")))
4867 (clobber (reg:CC 100))]
4870 [(set_attr "type" "multi")
4871 (set_attr "length" "2")])
4874 [(set (match_operand:DI 0 "register_operand" "")
4875 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4876 (match_operand:DI 2 "register_operand" "")))
4877 (clobber (reg:CC 100))]
4878 "! TARGET_ARCH64 && reload_completed"
4879 [(parallel [(set (reg:CC_NOOV 100)
4880 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4882 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4884 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4885 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4886 "operands[3] = gen_lowpart (SImode, operands[2]);
4887 operands[4] = gen_highpart (SImode, operands[2]);
4888 operands[5] = gen_lowpart (SImode, operands[0]);
4889 operands[6] = gen_highpart (SImode, operands[0]);")
4891 (define_insn "*adddi3_sp64"
4892 [(set (match_operand:DI 0 "register_operand" "=r")
4893 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4894 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4897 [(set_attr "type" "binary")
4898 (set_attr "length" "1")])
4900 (define_expand "addsi3"
4901 [(set (match_operand:SI 0 "register_operand" "=r,d")
4902 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4903 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4907 if (arith_4096_operand(operands[2], DImode))
4909 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4910 gen_rtx_MINUS (SImode, operands[1],
4916 (define_insn "*addsi3"
4917 [(set (match_operand:SI 0 "register_operand" "=r,d")
4918 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4919 (match_operand:SI 2 "arith_operand" "rI,d")))]
4923 fpadd32s\\t%1, %2, %0"
4924 [(set_attr "type" "ialu,fp")
4925 (set_attr "length" "1")])
4927 (define_insn "*cmp_cc_plus"
4928 [(set (reg:CC_NOOV 100)
4929 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4930 (match_operand:SI 1 "arith_operand" "rI"))
4933 "addcc\\t%0, %1, %%g0"
4934 [(set_attr "type" "compare")
4935 (set_attr "length" "1")])
4937 (define_insn "*cmp_ccx_plus"
4938 [(set (reg:CCX_NOOV 100)
4939 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4940 (match_operand:DI 1 "arith_double_operand" "rHI"))
4943 "addcc\\t%0, %1, %%g0"
4944 [(set_attr "type" "compare")
4945 (set_attr "length" "1")])
4947 (define_insn "*cmp_cc_plus_set"
4948 [(set (reg:CC_NOOV 100)
4949 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4950 (match_operand:SI 2 "arith_operand" "rI"))
4952 (set (match_operand:SI 0 "register_operand" "=r")
4953 (plus:SI (match_dup 1) (match_dup 2)))]
4955 "addcc\\t%1, %2, %0"
4956 [(set_attr "type" "compare")
4957 (set_attr "length" "1")])
4959 (define_insn "*cmp_ccx_plus_set"
4960 [(set (reg:CCX_NOOV 100)
4961 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4962 (match_operand:DI 2 "arith_double_operand" "rHI"))
4964 (set (match_operand:DI 0 "register_operand" "=r")
4965 (plus:DI (match_dup 1) (match_dup 2)))]
4967 "addcc\\t%1, %2, %0"
4968 [(set_attr "type" "compare")
4969 (set_attr "length" "1")])
4971 (define_expand "subdi3"
4972 [(set (match_operand:DI 0 "register_operand" "=r")
4973 (minus:DI (match_operand:DI 1 "register_operand" "r")
4974 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4978 if (! TARGET_ARCH64)
4980 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4981 gen_rtx_SET (VOIDmode, operands[0],
4982 gen_rtx_MINUS (DImode, operands[1],
4984 gen_rtx_CLOBBER (VOIDmode,
4985 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4988 if (arith_double_4096_operand(operands[2], DImode))
4990 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4991 gen_rtx_PLUS (DImode, operands[1],
4997 (define_insn "*subdi3_sp32"
4998 [(set (match_operand:DI 0 "register_operand" "=r")
4999 (minus:DI (match_operand:DI 1 "register_operand" "r")
5000 (match_operand:DI 2 "arith_double_operand" "rHI")))
5001 (clobber (reg:CC 100))]
5004 [(set_attr "length" "2")])
5007 [(set (match_operand:DI 0 "register_operand" "")
5008 (minus:DI (match_operand:DI 1 "register_operand" "")
5009 (match_operand:DI 2 "arith_double_operand" "")))
5010 (clobber (reg:CC 100))]
5013 && (GET_CODE (operands[2]) == CONST_INT
5014 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5015 [(clobber (const_int 0))]
5020 highp = gen_highpart (SImode, operands[2]);
5021 lowp = gen_lowpart (SImode, operands[2]);
5022 if ((lowp == const0_rtx)
5023 && (operands[0] == operands[1]))
5025 emit_insn (gen_rtx_SET (VOIDmode,
5026 gen_highpart (SImode, operands[0]),
5027 gen_rtx_MINUS (SImode,
5028 gen_highpart (SImode, operands[1]),
5033 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5034 gen_lowpart (SImode, operands[1]),
5036 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5037 gen_highpart (SImode, operands[1]),
5044 [(set (match_operand:DI 0 "register_operand" "")
5045 (minus:DI (match_operand:DI 1 "register_operand" "")
5046 (match_operand:DI 2 "register_operand" "")))
5047 (clobber (reg:CC 100))]
5049 && reload_completed"
5050 [(clobber (const_int 0))]
5053 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5054 gen_lowpart (SImode, operands[1]),
5055 gen_lowpart (SImode, operands[2])));
5056 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5057 gen_highpart (SImode, operands[1]),
5058 gen_highpart (SImode, operands[2])));
5063 [(set (match_operand:DI 0 "register_operand" "=r")
5064 (minus:DI (match_operand:DI 1 "register_operand" "r")
5065 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5066 (clobber (reg:CC 100))]
5069 [(set_attr "type" "multi")
5070 (set_attr "length" "2")])
5073 [(set (match_operand:DI 0 "register_operand" "")
5074 (minus:DI (match_operand:DI 1 "register_operand" "")
5075 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5076 (clobber (reg:CC 100))]
5077 "! TARGET_ARCH64 && reload_completed"
5078 [(parallel [(set (reg:CC_NOOV 100)
5079 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5081 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5083 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5084 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5085 "operands[3] = gen_lowpart (SImode, operands[1]);
5086 operands[4] = gen_highpart (SImode, operands[1]);
5087 operands[5] = gen_lowpart (SImode, operands[0]);
5088 operands[6] = gen_highpart (SImode, operands[0]);")
5090 (define_insn "*subdi3_sp64"
5091 [(set (match_operand:DI 0 "register_operand" "=r")
5092 (minus:DI (match_operand:DI 1 "register_operand" "r")
5093 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5096 [(set_attr "type" "binary")
5097 (set_attr "length" "1")])
5099 (define_expand "subsi3"
5100 [(set (match_operand:SI 0 "register_operand" "=r,d")
5101 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5102 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5106 if (arith_4096_operand(operands[2], DImode))
5108 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5109 gen_rtx_PLUS (SImode, operands[1],
5115 (define_insn "*subsi3"
5116 [(set (match_operand:SI 0 "register_operand" "=r,d")
5117 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5118 (match_operand:SI 2 "arith_operand" "rI,d")))]
5122 fpsub32s\\t%1, %2, %0"
5123 [(set_attr "type" "ialu,fp")
5124 (set_attr "length" "1")])
5126 (define_insn "*cmp_minus_cc"
5127 [(set (reg:CC_NOOV 100)
5128 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5129 (match_operand:SI 1 "arith_operand" "rI"))
5132 "subcc\\t%r0, %1, %%g0"
5133 [(set_attr "type" "compare")
5134 (set_attr "length" "1")])
5136 (define_insn "*cmp_minus_ccx"
5137 [(set (reg:CCX_NOOV 100)
5138 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5139 (match_operand:DI 1 "arith_double_operand" "rHI"))
5142 "subcc\\t%0, %1, %%g0"
5143 [(set_attr "type" "compare")
5144 (set_attr "length" "1")])
5146 (define_insn "cmp_minus_cc_set"
5147 [(set (reg:CC_NOOV 100)
5148 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5149 (match_operand:SI 2 "arith_operand" "rI"))
5151 (set (match_operand:SI 0 "register_operand" "=r")
5152 (minus:SI (match_dup 1) (match_dup 2)))]
5154 "subcc\\t%r1, %2, %0"
5155 [(set_attr "type" "compare")
5156 (set_attr "length" "1")])
5158 (define_insn "*cmp_minus_ccx_set"
5159 [(set (reg:CCX_NOOV 100)
5160 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5161 (match_operand:DI 2 "arith_double_operand" "rHI"))
5163 (set (match_operand:DI 0 "register_operand" "=r")
5164 (minus:DI (match_dup 1) (match_dup 2)))]
5166 "subcc\\t%1, %2, %0"
5167 [(set_attr "type" "compare")
5168 (set_attr "length" "1")])
5170 ;; Integer Multiply/Divide.
5172 ;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't
5173 ;; we used. We still use them in 32 bit v9 compilers.
5174 ;; The 64 bit v9 compiler will (/should) widen the args and use muldi3.
5176 (define_insn "mulsi3"
5177 [(set (match_operand:SI 0 "register_operand" "=r")
5178 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5179 (match_operand:SI 2 "arith_operand" "rI")))]
5182 [(set_attr "type" "imul")
5183 (set_attr "length" "1")])
5185 (define_expand "muldi3"
5186 [(set (match_operand:DI 0 "register_operand" "=r")
5187 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5188 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5189 "TARGET_ARCH64 || TARGET_V8PLUS"
5194 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5199 (define_insn "*muldi3_sp64"
5200 [(set (match_operand:DI 0 "register_operand" "=r")
5201 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5202 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5205 [(set_attr "type" "imul")
5206 (set_attr "length" "1")])
5208 ;; V8plus wide multiply.
5210 (define_insn "muldi3_v8plus"
5211 [(set (match_operand:DI 0 "register_operand" "=r,h")
5212 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5213 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5214 (clobber (match_scratch:SI 3 "=&h,X"))
5215 (clobber (match_scratch:SI 4 "=&h,X"))]
5219 if (sparc_check_64 (operands[1], insn) <= 0)
5220 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5221 if (which_alternative == 1)
5222 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5223 if (sparc_check_64 (operands[2], insn) <= 0)
5224 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5225 if (which_alternative == 1)
5226 return \"or\\t%L1, %H1, %H1\\n\\tsllx\\t%H2, 32, %L1\\n\\tor\\t%L2, %L1, %L1\\n\\tmulx\\t%H1, %L1, %L0\;srlx\\t%L0, 32, %H0\";
5228 return \"sllx\\t%H1, 32, %3\\n\\tsllx\\t%H2, 32, %4\\n\\tor\\t%L1, %3, %3\\n\\tor\\t%L2, %4, %4\\n\\tmulx\\t%3, %4, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
5230 [(set_attr "length" "9,8")])
5232 ;; It is not known whether this will match.
5234 (define_insn "*cmp_mul_set"
5235 [(set (match_operand:SI 0 "register_operand" "=r")
5236 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5237 (match_operand:SI 2 "arith_operand" "rI")))
5238 (set (reg:CC_NOOV 100)
5239 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
5241 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5242 "smulcc\\t%1, %2, %0"
5243 [(set_attr "type" "imul")
5244 (set_attr "length" "1")])
5246 (define_expand "mulsidi3"
5247 [(set (match_operand:DI 0 "register_operand" "")
5248 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5249 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5253 if (CONSTANT_P (operands[2]))
5257 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5261 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
5266 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5271 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5272 ;; registers can hold 64 bit values in the V8plus environment.
5274 (define_insn "mulsidi3_v8plus"
5275 [(set (match_operand:DI 0 "register_operand" "=h,r")
5276 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5277 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5278 (clobber (match_scratch:SI 3 "=X,&h"))]
5281 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5282 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5283 [(set_attr "length" "2,3")])
5286 (define_insn "const_mulsidi3_v8plus"
5287 [(set (match_operand:DI 0 "register_operand" "=h,r")
5288 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5289 (match_operand:SI 2 "small_int" "I,I")))
5290 (clobber (match_scratch:SI 3 "=X,&h"))]
5293 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5294 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5295 [(set_attr "length" "2,3")])
5298 (define_insn "*mulsidi3_sp32"
5299 [(set (match_operand:DI 0 "register_operand" "=r")
5300 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5301 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5305 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5307 [(set (attr "length")
5308 (if_then_else (eq_attr "isa" "sparclet")
5309 (const_int 1) (const_int 2)))])
5311 ;; Extra pattern, because sign_extend of a constant isn't valid.
5314 (define_insn "const_mulsidi3"
5315 [(set (match_operand:DI 0 "register_operand" "=r")
5316 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5317 (match_operand:SI 2 "small_int" "I")))]
5321 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5323 [(set (attr "length")
5324 (if_then_else (eq_attr "isa" "sparclet")
5325 (const_int 1) (const_int 2)))])
5327 (define_expand "smulsi3_highpart"
5328 [(set (match_operand:SI 0 "register_operand" "")
5330 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5331 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5336 if (CONSTANT_P (operands[2]))
5340 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5346 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5351 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5352 operands[2], GEN_INT (32)));
5358 (define_insn "smulsi3_highpart_v8plus"
5359 [(set (match_operand:SI 0 "register_operand" "=h,r")
5361 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5362 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5363 (match_operand:SI 3 "const_int_operand" "i,i"))))
5364 (clobber (match_scratch:SI 4 "=X,&h"))]
5367 smul %1,%2,%0\;srlx %0,%3,%0
5368 smul %1,%2,%4\;srlx %4,%3,%0"
5369 [(set_attr "length" "2")])
5371 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5374 [(set (match_operand:SI 0 "register_operand" "=h,r")
5377 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5378 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5379 (match_operand:SI 3 "const_int_operand" "i,i"))
5381 (clobber (match_scratch:SI 4 "=X,&h"))]
5384 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5385 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5386 [(set_attr "length" "2")])
5389 (define_insn "const_smulsi3_highpart_v8plus"
5390 [(set (match_operand:SI 0 "register_operand" "=h,r")
5392 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5393 (match_operand 2 "small_int" "i,i"))
5394 (match_operand:SI 3 "const_int_operand" "i,i"))))
5395 (clobber (match_scratch:SI 4 "=X,&h"))]
5398 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5399 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5400 [(set_attr "length" "2")])
5403 (define_insn "*smulsi3_highpart_sp32"
5404 [(set (match_operand:SI 0 "register_operand" "=r")
5406 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5407 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5410 && ! TARGET_LIVE_G0"
5411 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5412 [(set_attr "length" "2")])
5415 (define_insn "const_smulsi3_highpart"
5416 [(set (match_operand:SI 0 "register_operand" "=r")
5418 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5419 (match_operand:SI 2 "register_operand" "r"))
5422 && ! TARGET_LIVE_G0"
5423 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5424 [(set_attr "length" "2")])
5426 (define_expand "umulsidi3"
5427 [(set (match_operand:DI 0 "register_operand" "")
5428 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5429 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5433 if (CONSTANT_P (operands[2]))
5437 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5441 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
5446 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5452 (define_insn "umulsidi3_v8plus"
5453 [(set (match_operand:DI 0 "register_operand" "=h,r")
5454 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5455 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5456 (clobber (match_scratch:SI 3 "=X,&h"))]
5459 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5460 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5461 [(set_attr "length" "2,3")])
5464 (define_insn "*umulsidi3_sp32"
5465 [(set (match_operand:DI 0 "register_operand" "=r")
5466 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5467 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5471 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5473 [(set (attr "length")
5474 (if_then_else (eq_attr "isa" "sparclet")
5475 (const_int 1) (const_int 2)))])
5477 ;; Extra pattern, because sign_extend of a constant isn't valid.
5480 (define_insn "const_umulsidi3"
5481 [(set (match_operand:DI 0 "register_operand" "=r")
5482 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5483 (match_operand:SI 2 "uns_small_int" "")))]
5487 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5489 [(set (attr "length")
5490 (if_then_else (eq_attr "isa" "sparclet")
5491 (const_int 1) (const_int 2)))])
5494 (define_insn "const_umulsidi3_v8plus"
5495 [(set (match_operand:DI 0 "register_operand" "=h,r")
5496 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5497 (match_operand:SI 2 "uns_small_int" "")))
5498 (clobber (match_scratch:SI 3 "=X,h"))]
5501 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5502 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5503 [(set_attr "length" "2,3")])
5505 (define_expand "umulsi3_highpart"
5506 [(set (match_operand:SI 0 "register_operand" "")
5508 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5509 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5514 if (CONSTANT_P (operands[2]))
5518 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5524 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5529 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5530 operands[2], GEN_INT (32)));
5536 (define_insn "umulsi3_highpart_v8plus"
5537 [(set (match_operand:SI 0 "register_operand" "=h,r")
5539 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5540 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5541 (match_operand:SI 3 "const_int_operand" "i,i"))))
5542 (clobber (match_scratch:SI 4 "=X,h"))]
5545 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5546 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5547 [(set_attr "length" "2")])
5550 (define_insn "const_umulsi3_highpart_v8plus"
5551 [(set (match_operand:SI 0 "register_operand" "=h,r")
5553 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5554 (match_operand:SI 2 "uns_small_int" ""))
5555 (match_operand:SI 3 "const_int_operand" "i,i"))))
5556 (clobber (match_scratch:SI 4 "=X,h"))]
5559 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5560 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5561 [(set_attr "length" "2")])
5564 (define_insn "*umulsi3_highpart_sp32"
5565 [(set (match_operand:SI 0 "register_operand" "=r")
5567 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5568 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5571 && ! TARGET_LIVE_G0"
5572 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5573 [(set_attr "length" "2")])
5576 (define_insn "const_umulsi3_highpart"
5577 [(set (match_operand:SI 0 "register_operand" "=r")
5579 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5580 (match_operand:SI 2 "uns_small_int" ""))
5583 && ! TARGET_LIVE_G0"
5584 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5585 [(set_attr "length" "2")])
5587 ;; The v8 architecture specifies that there must be 3 instructions between
5588 ;; a y register write and a use of it for correct results.
5591 (define_insn "divsi3"
5592 [(set (match_operand:SI 0 "register_operand" "=r,r")
5593 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5594 (match_operand:SI 2 "input_operand" "rI,m")))
5595 (clobber (match_scratch:SI 3 "=&r,&r"))]
5597 || TARGET_DEPRECATED_V8_INSNS)
5598 && ! TARGET_LIVE_G0"
5601 if (which_alternative == 0)
5603 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0\";
5605 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5608 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5610 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
5612 [(set (attr "length")
5613 (if_then_else (eq_attr "isa" "v9")
5614 (const_int 4) (const_int 7)))])
5616 (define_insn "divdi3"
5617 [(set (match_operand:DI 0 "register_operand" "=r")
5618 (div:DI (match_operand:DI 1 "register_operand" "r")
5619 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5621 "sdivx\\t%1, %2, %0")
5623 ;; It is not known whether this will match.
5625 ;; XXX I hope it doesn't fucking match...
5626 (define_insn "*cmp_sdiv_cc_set"
5627 [(set (match_operand:SI 0 "register_operand" "=r")
5628 (div:SI (match_operand:SI 1 "register_operand" "r")
5629 (match_operand:SI 2 "arith_operand" "rI")))
5631 (compare:CC (div:SI (match_dup 1) (match_dup 2))
5633 (clobber (match_scratch:SI 3 "=&r"))]
5635 || TARGET_DEPRECATED_V8_INSNS)
5636 && ! TARGET_LIVE_G0"
5640 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5642 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5644 [(set (attr "length")
5645 (if_then_else (eq_attr "isa" "v9")
5646 (const_int 3) (const_int 6)))])
5649 (define_insn "udivsi3"
5650 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5651 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5652 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5654 || TARGET_DEPRECATED_V8_INSNS)
5655 && ! TARGET_LIVE_G0"
5658 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
5659 switch (which_alternative)
5663 return \"udiv\\t%1, %2, %0\";
5664 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
5666 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
5668 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
5671 [(set (attr "length")
5672 (if_then_else (and (eq_attr "isa" "v9")
5673 (eq_attr "alternative" "0"))
5674 (const_int 2) (const_int 5)))])
5676 (define_insn "udivdi3"
5677 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5679 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5681 "udivx\\t%1, %2, %0")
5683 ;; It is not known whether this will match.
5685 ;; XXX I hope it doesn't fucking match...
5686 (define_insn "*cmp_udiv_cc_set"
5687 [(set (match_operand:SI 0 "register_operand" "=r")
5688 (udiv:SI (match_operand:SI 1 "register_operand" "r")
5689 (match_operand:SI 2 "arith_operand" "rI")))
5691 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
5694 || TARGET_DEPRECATED_V8_INSNS)
5695 && ! TARGET_LIVE_G0"
5699 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
5701 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
5703 [(set (attr "length")
5704 (if_then_else (eq_attr "isa" "v9")
5705 (const_int 2) (const_int 5)))])
5707 ; sparclet multiply/accumulate insns
5709 (define_insn "*smacsi"
5710 [(set (match_operand:SI 0 "register_operand" "=r")
5711 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5712 (match_operand:SI 2 "arith_operand" "rI"))
5713 (match_operand:SI 3 "register_operand" "0")))]
5716 [(set_attr "type" "imul")
5717 (set_attr "length" "1")])
5719 (define_insn "*smacdi"
5720 [(set (match_operand:DI 0 "register_operand" "=r")
5721 (plus:DI (mult:DI (sign_extend:DI
5722 (match_operand:SI 1 "register_operand" "%r"))
5724 (match_operand:SI 2 "register_operand" "r")))
5725 (match_operand:DI 3 "register_operand" "0")))]
5727 "smacd\\t%1, %2, %L0"
5728 [(set_attr "type" "imul")
5729 (set_attr "length" "1")])
5731 (define_insn "*umacdi"
5732 [(set (match_operand:DI 0 "register_operand" "=r")
5733 (plus:DI (mult:DI (zero_extend:DI
5734 (match_operand:SI 1 "register_operand" "%r"))
5736 (match_operand:SI 2 "register_operand" "r")))
5737 (match_operand:DI 3 "register_operand" "0")))]
5739 "umacd\\t%1, %2, %L0"
5740 [(set_attr "type" "imul")
5741 (set_attr "length" "1")])
5743 ;;- Boolean instructions
5744 ;; We define DImode `and' so with DImode `not' we can get
5745 ;; DImode `andn'. Other combinations are possible.
5747 (define_expand "anddi3"
5748 [(set (match_operand:DI 0 "register_operand" "")
5749 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5750 (match_operand:DI 2 "arith_double_operand" "")))]
5754 (define_insn "*anddi3_sp32"
5755 [(set (match_operand:DI 0 "register_operand" "=r,b")
5756 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5757 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5762 [(set_attr "type" "ialu,fp")
5763 (set_attr "length" "2,1")])
5765 (define_insn "*anddi3_sp64"
5766 [(set (match_operand:DI 0 "register_operand" "=r,b")
5767 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5768 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5773 [(set_attr "type" "ialu,fp")
5774 (set_attr "length" "1,1")])
5776 (define_insn "andsi3"
5777 [(set (match_operand:SI 0 "register_operand" "=r,d")
5778 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5779 (match_operand:SI 2 "arith_operand" "rI,d")))]
5784 [(set_attr "type" "ialu,fp")
5785 (set_attr "length" "1,1")])
5788 [(set (match_operand:SI 0 "register_operand" "")
5789 (and:SI (match_operand:SI 1 "register_operand" "")
5790 (match_operand:SI 2 "" "")))
5791 (clobber (match_operand:SI 3 "register_operand" ""))]
5792 "GET_CODE (operands[2]) == CONST_INT
5793 && !SMALL_INT32 (operands[2])
5794 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5795 [(set (match_dup 3) (match_dup 4))
5796 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5799 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5802 ;; Split DImode logical operations requiring two instructions.
5804 [(set (match_operand:DI 0 "register_operand" "")
5805 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5806 [(match_operand:DI 2 "register_operand" "")
5807 (match_operand:DI 3 "arith_double_operand" "")]))]
5810 && ((GET_CODE (operands[0]) == REG
5811 && REGNO (operands[0]) < 32)
5812 || (GET_CODE (operands[0]) == SUBREG
5813 && GET_CODE (SUBREG_REG (operands[0])) == REG
5814 && REGNO (SUBREG_REG (operands[0])) < 32))"
5815 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5816 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5819 if (GET_CODE (operands[0]) == SUBREG)
5820 operands[0] = alter_subreg (operands[0]);
5821 operands[4] = gen_highpart (SImode, operands[0]);
5822 operands[5] = gen_lowpart (SImode, operands[0]);
5823 operands[6] = gen_highpart (SImode, operands[2]);
5824 operands[7] = gen_lowpart (SImode, operands[2]);
5825 if (GET_CODE (operands[3]) == CONST_INT)
5827 if (INTVAL (operands[3]) < 0)
5828 operands[8] = constm1_rtx;
5830 operands[8] = const0_rtx;
5833 operands[8] = gen_highpart (SImode, operands[3]);
5834 operands[9] = gen_lowpart (SImode, operands[3]);
5837 (define_insn "*and_not_di_sp32"
5838 [(set (match_operand:DI 0 "register_operand" "=r,b")
5839 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5840 (match_operand:DI 2 "register_operand" "r,b")))]
5844 fandnot1\\t%1, %2, %0"
5845 [(set_attr "type" "ialu,fp")
5846 (set_attr "length" "2,1")])
5849 [(set (match_operand:DI 0 "register_operand" "")
5850 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5851 (match_operand:DI 2 "register_operand" "")))]
5854 && ((GET_CODE (operands[0]) == REG
5855 && REGNO (operands[0]) < 32)
5856 || (GET_CODE (operands[0]) == SUBREG
5857 && GET_CODE (SUBREG_REG (operands[0])) == REG
5858 && REGNO (SUBREG_REG (operands[0])) < 32))"
5859 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5860 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5861 "if (GET_CODE (operands[0]) == SUBREG)
5862 operands[0] = alter_subreg (operands[0]);
5863 operands[3] = gen_highpart (SImode, operands[0]);
5864 operands[4] = gen_highpart (SImode, operands[1]);
5865 operands[5] = gen_highpart (SImode, operands[2]);
5866 operands[6] = gen_lowpart (SImode, operands[0]);
5867 operands[7] = gen_lowpart (SImode, operands[1]);
5868 operands[8] = gen_lowpart (SImode, operands[2]);")
5870 (define_insn "*and_not_di_sp64"
5871 [(set (match_operand:DI 0 "register_operand" "=r,b")
5872 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5873 (match_operand:DI 2 "register_operand" "r,b")))]
5877 fandnot1\\t%1, %2, %0"
5878 [(set_attr "type" "ialu,fp")
5879 (set_attr "length" "1,1")])
5881 (define_insn "*and_not_si"
5882 [(set (match_operand:SI 0 "register_operand" "=r,d")
5883 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5884 (match_operand:SI 2 "register_operand" "r,d")))]
5888 fandnot1s\\t%1, %2, %0"
5889 [(set_attr "type" "ialu,fp")
5890 (set_attr "length" "1,1")])
5892 (define_expand "iordi3"
5893 [(set (match_operand:DI 0 "register_operand" "")
5894 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5895 (match_operand:DI 2 "arith_double_operand" "")))]
5899 (define_insn "*iordi3_sp32"
5900 [(set (match_operand:DI 0 "register_operand" "=r,b")
5901 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5902 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5907 [(set_attr "type" "ialu,fp")
5908 (set_attr "length" "2,1")])
5910 (define_insn "*iordi3_sp64"
5911 [(set (match_operand:DI 0 "register_operand" "=r,b")
5912 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5913 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5918 [(set_attr "type" "ialu,fp")
5919 (set_attr "length" "1,1")])
5921 (define_insn "iorsi3"
5922 [(set (match_operand:SI 0 "register_operand" "=r,d")
5923 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
5924 (match_operand:SI 2 "arith_operand" "rI,d")))]
5929 [(set_attr "type" "ialu,fp")
5930 (set_attr "length" "1,1")])
5933 [(set (match_operand:SI 0 "register_operand" "")
5934 (ior:SI (match_operand:SI 1 "register_operand" "")
5935 (match_operand:SI 2 "" "")))
5936 (clobber (match_operand:SI 3 "register_operand" ""))]
5937 "GET_CODE (operands[2]) == CONST_INT
5938 && !SMALL_INT32 (operands[2])
5939 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5940 [(set (match_dup 3) (match_dup 4))
5941 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5944 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5947 (define_insn "*or_not_di_sp32"
5948 [(set (match_operand:DI 0 "register_operand" "=r,b")
5949 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5950 (match_operand:DI 2 "register_operand" "r,b")))]
5954 fornot1\\t%1, %2, %0"
5955 [(set_attr "type" "ialu,fp")
5956 (set_attr "length" "2,1")])
5959 [(set (match_operand:DI 0 "register_operand" "")
5960 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5961 (match_operand:DI 2 "register_operand" "")))]
5964 && ((GET_CODE (operands[0]) == REG
5965 && REGNO (operands[0]) < 32)
5966 || (GET_CODE (operands[0]) == SUBREG
5967 && GET_CODE (SUBREG_REG (operands[0])) == REG
5968 && REGNO (SUBREG_REG (operands[0])) < 32))"
5969 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5970 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5971 "if (GET_CODE (operands[0]) == SUBREG)
5972 operands[0] = alter_subreg (operands[0]);
5973 operands[3] = gen_highpart (SImode, operands[0]);
5974 operands[4] = gen_highpart (SImode, operands[1]);
5975 operands[5] = gen_highpart (SImode, operands[2]);
5976 operands[6] = gen_lowpart (SImode, operands[0]);
5977 operands[7] = gen_lowpart (SImode, operands[1]);
5978 operands[8] = gen_lowpart (SImode, operands[2]);")
5980 (define_insn "*or_not_di_sp64"
5981 [(set (match_operand:DI 0 "register_operand" "=r,b")
5982 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5983 (match_operand:DI 2 "register_operand" "r,b")))]
5987 fornot1\\t%1, %2, %0"
5988 [(set_attr "type" "ialu,fp")
5989 (set_attr "length" "1,1")])
5991 (define_insn "*or_not_si"
5992 [(set (match_operand:SI 0 "register_operand" "=r,d")
5993 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5994 (match_operand:SI 2 "register_operand" "r,d")))]
5998 fornot1s\\t%1, %2, %0"
5999 [(set_attr "type" "ialu,fp")
6000 (set_attr "length" "1,1")])
6002 (define_expand "xordi3"
6003 [(set (match_operand:DI 0 "register_operand" "")
6004 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6005 (match_operand:DI 2 "arith_double_operand" "")))]
6009 (define_insn "*xordi3_sp32"
6010 [(set (match_operand:DI 0 "register_operand" "=r,b")
6011 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6012 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6017 [(set_attr "length" "2,1")
6018 (set_attr "type" "ialu,fp")])
6020 (define_insn "*xordi3_sp64"
6021 [(set (match_operand:DI 0 "register_operand" "=r,b")
6022 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6023 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6028 [(set_attr "type" "ialu,fp")
6029 (set_attr "length" "1,1")])
6031 (define_insn "*xordi3_sp64_dbl"
6032 [(set (match_operand:DI 0 "register_operand" "=r")
6033 (xor:DI (match_operand:DI 1 "register_operand" "r")
6034 (match_operand:DI 2 "const64_operand" "")))]
6036 && HOST_BITS_PER_WIDE_INT != 64)"
6038 [(set_attr "type" "ialu")
6039 (set_attr "length" "1")])
6041 (define_insn "xorsi3"
6042 [(set (match_operand:SI 0 "register_operand" "=r,d")
6043 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6044 (match_operand:SI 2 "arith_operand" "rI,d")))]
6049 [(set_attr "type" "ialu,fp")
6050 (set_attr "length" "1,1")])
6053 [(set (match_operand:SI 0 "register_operand" "")
6054 (xor:SI (match_operand:SI 1 "register_operand" "")
6055 (match_operand:SI 2 "" "")))
6056 (clobber (match_operand:SI 3 "register_operand" ""))]
6057 "GET_CODE (operands[2]) == CONST_INT
6058 && !SMALL_INT32 (operands[2])
6059 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6060 [(set (match_dup 3) (match_dup 4))
6061 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6064 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6068 [(set (match_operand:SI 0 "register_operand" "")
6069 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6070 (match_operand:SI 2 "" ""))))
6071 (clobber (match_operand:SI 3 "register_operand" ""))]
6072 "GET_CODE (operands[2]) == CONST_INT
6073 && !SMALL_INT32 (operands[2])
6074 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6075 [(set (match_dup 3) (match_dup 4))
6076 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6079 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6082 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6083 ;; Combine now canonicalizes to the rightmost expression.
6084 (define_insn "*xor_not_di_sp32"
6085 [(set (match_operand:DI 0 "register_operand" "=r,b")
6086 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6087 (match_operand:DI 2 "register_operand" "r,b"))))]
6092 [(set_attr "length" "2,1")
6093 (set_attr "type" "ialu,fp")])
6096 [(set (match_operand:DI 0 "register_operand" "")
6097 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6098 (match_operand:DI 2 "register_operand" ""))))]
6101 && ((GET_CODE (operands[0]) == REG
6102 && REGNO (operands[0]) < 32)
6103 || (GET_CODE (operands[0]) == SUBREG
6104 && GET_CODE (SUBREG_REG (operands[0])) == REG
6105 && REGNO (SUBREG_REG (operands[0])) < 32))"
6106 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6107 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6108 "if (GET_CODE (operands[0]) == SUBREG)
6109 operands[0] = alter_subreg (operands[0]);
6110 operands[3] = gen_highpart (SImode, operands[0]);
6111 operands[4] = gen_highpart (SImode, operands[1]);
6112 operands[5] = gen_highpart (SImode, operands[2]);
6113 operands[6] = gen_lowpart (SImode, operands[0]);
6114 operands[7] = gen_lowpart (SImode, operands[1]);
6115 operands[8] = gen_lowpart (SImode, operands[2]);")
6117 (define_insn "*xor_not_di_sp64"
6118 [(set (match_operand:DI 0 "register_operand" "=r,b")
6119 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6120 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6125 [(set_attr "type" "ialu,fp")
6126 (set_attr "length" "1,1")])
6128 (define_insn "*xor_not_si"
6129 [(set (match_operand:SI 0 "register_operand" "=r,d")
6130 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6131 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6135 fxnors\\t%1, %2, %0"
6136 [(set_attr "type" "ialu,fp")
6137 (set_attr "length" "1,1")])
6139 ;; These correspond to the above in the case where we also (or only)
6140 ;; want to set the condition code.
6142 (define_insn "*cmp_cc_arith_op"
6145 (match_operator:SI 2 "cc_arithop"
6146 [(match_operand:SI 0 "arith_operand" "%r")
6147 (match_operand:SI 1 "arith_operand" "rI")])
6150 "%A2cc\\t%0, %1, %%g0"
6151 [(set_attr "type" "compare")
6152 (set_attr "length" "1")])
6154 (define_insn "*cmp_ccx_arith_op"
6157 (match_operator:DI 2 "cc_arithop"
6158 [(match_operand:DI 0 "arith_double_operand" "%r")
6159 (match_operand:DI 1 "arith_double_operand" "rHI")])
6162 "%A2cc\\t%0, %1, %%g0"
6163 [(set_attr "type" "compare")
6164 (set_attr "length" "1")])
6166 (define_insn "*cmp_cc_arith_op_set"
6169 (match_operator:SI 3 "cc_arithop"
6170 [(match_operand:SI 1 "arith_operand" "%r")
6171 (match_operand:SI 2 "arith_operand" "rI")])
6173 (set (match_operand:SI 0 "register_operand" "=r")
6176 "%A3cc\\t%1, %2, %0"
6177 [(set_attr "type" "compare")
6178 (set_attr "length" "1")])
6180 (define_insn "*cmp_ccx_arith_op_set"
6183 (match_operator:DI 3 "cc_arithop"
6184 [(match_operand:DI 1 "arith_double_operand" "%r")
6185 (match_operand:DI 2 "arith_double_operand" "rHI")])
6187 (set (match_operand:DI 0 "register_operand" "=r")
6190 "%A3cc\\t%1, %2, %0"
6191 [(set_attr "type" "compare")
6192 (set_attr "length" "1")])
6194 (define_insn "*cmp_cc_xor_not"
6197 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6198 (match_operand:SI 1 "arith_operand" "rI")))
6201 "xnorcc\\t%r0, %1, %%g0"
6202 [(set_attr "type" "compare")
6203 (set_attr "length" "1")])
6205 (define_insn "*cmp_ccx_xor_not"
6208 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6209 (match_operand:DI 1 "arith_double_operand" "rHI")))
6212 "xnorcc\\t%r0, %1, %%g0"
6213 [(set_attr "type" "compare")
6214 (set_attr "length" "1")])
6216 (define_insn "*cmp_cc_xor_not_set"
6219 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6220 (match_operand:SI 2 "arith_operand" "rI")))
6222 (set (match_operand:SI 0 "register_operand" "=r")
6223 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6225 "xnorcc\\t%r1, %2, %0"
6226 [(set_attr "type" "compare")
6227 (set_attr "length" "1")])
6229 (define_insn "*cmp_ccx_xor_not_set"
6232 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6233 (match_operand:DI 2 "arith_double_operand" "rHI")))
6235 (set (match_operand:DI 0 "register_operand" "=r")
6236 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6238 "xnorcc\\t%r1, %2, %0"
6239 [(set_attr "type" "compare")
6240 (set_attr "length" "1")])
6242 (define_insn "*cmp_cc_arith_op_not"
6245 (match_operator:SI 2 "cc_arithopn"
6246 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6247 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6250 "%B2cc\\t%r1, %0, %%g0"
6251 [(set_attr "type" "compare")
6252 (set_attr "length" "1")])
6254 (define_insn "*cmp_ccx_arith_op_not"
6257 (match_operator:DI 2 "cc_arithopn"
6258 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6259 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6262 "%B2cc\\t%r1, %0, %%g0"
6263 [(set_attr "type" "compare")
6264 (set_attr "length" "1")])
6266 (define_insn "*cmp_cc_arith_op_not_set"
6269 (match_operator:SI 3 "cc_arithopn"
6270 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6271 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6273 (set (match_operand:SI 0 "register_operand" "=r")
6276 "%B3cc\\t%r2, %1, %0"
6277 [(set_attr "type" "compare")
6278 (set_attr "length" "1")])
6280 (define_insn "*cmp_ccx_arith_op_not_set"
6283 (match_operator:DI 3 "cc_arithopn"
6284 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6285 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6287 (set (match_operand:DI 0 "register_operand" "=r")
6290 "%B3cc\\t%r2, %1, %0"
6291 [(set_attr "type" "compare")
6292 (set_attr "length" "1")])
6294 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6295 ;; does not know how to make it work for constants.
6297 (define_expand "negdi2"
6298 [(set (match_operand:DI 0 "register_operand" "=r")
6299 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6303 if (! TARGET_ARCH64)
6305 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
6306 gen_rtx_SET (VOIDmode, operand0,
6307 gen_rtx_NEG (DImode, operand1)),
6308 gen_rtx_CLOBBER (VOIDmode,
6309 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
6314 (define_insn "*negdi2_sp32"
6315 [(set (match_operand:DI 0 "register_operand" "=r")
6316 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6317 (clobber (reg:CC 100))]
6319 && ! TARGET_LIVE_G0"
6321 [(set_attr "type" "unary")
6322 (set_attr "length" "2")])
6325 [(set (match_operand:DI 0 "register_operand" "")
6326 (neg:DI (match_operand:DI 1 "register_operand" "")))
6327 (clobber (reg:CC 100))]
6330 && reload_completed"
6331 [(parallel [(set (reg:CC_NOOV 100)
6332 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6334 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6335 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6336 (ltu:SI (reg:CC 100) (const_int 0))))]
6337 "operands[2] = gen_highpart (SImode, operands[0]);
6338 operands[3] = gen_highpart (SImode, operands[1]);
6339 operands[4] = gen_lowpart (SImode, operands[0]);
6340 operands[5] = gen_lowpart (SImode, operands[1]);")
6342 (define_insn "*negdi2_sp64"
6343 [(set (match_operand:DI 0 "register_operand" "=r")
6344 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6346 "sub\\t%%g0, %1, %0"
6347 [(set_attr "type" "unary")
6348 (set_attr "length" "1")])
6350 (define_expand "negsi2"
6351 [(set (match_operand:SI 0 "register_operand" "")
6352 (neg:SI (match_operand:SI 1 "arith_operand" "")))]
6358 rtx zero_reg = gen_reg_rtx (SImode);
6360 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6361 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6362 gen_rtx_MINUS (SImode, zero_reg,
6368 (define_insn "*negsi2_not_liveg0"
6369 [(set (match_operand:SI 0 "register_operand" "=r")
6370 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6372 "sub\\t%%g0, %1, %0"
6373 [(set_attr "type" "unary")
6374 (set_attr "length" "1")])
6376 (define_insn "*cmp_cc_neg"
6377 [(set (reg:CC_NOOV 100)
6378 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6381 "subcc\\t%%g0, %0, %%g0"
6382 [(set_attr "type" "compare")
6383 (set_attr "length" "1")])
6385 (define_insn "*cmp_ccx_neg"
6386 [(set (reg:CCX_NOOV 100)
6387 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6390 "subcc\\t%%g0, %0, %%g0"
6391 [(set_attr "type" "compare")
6392 (set_attr "length" "1")])
6394 (define_insn "*cmp_cc_set_neg"
6395 [(set (reg:CC_NOOV 100)
6396 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6398 (set (match_operand:SI 0 "register_operand" "=r")
6399 (neg:SI (match_dup 1)))]
6401 "subcc\\t%%g0, %1, %0"
6402 [(set_attr "type" "compare")
6403 (set_attr "length" "1")])
6405 (define_insn "*cmp_ccx_set_neg"
6406 [(set (reg:CCX_NOOV 100)
6407 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6409 (set (match_operand:DI 0 "register_operand" "=r")
6410 (neg:DI (match_dup 1)))]
6412 "subcc\\t%%g0, %1, %0"
6413 [(set_attr "type" "compare")
6414 (set_attr "length" "1")])
6416 ;; We cannot use the "not" pseudo insn because the Sun assembler
6417 ;; does not know how to make it work for constants.
6418 (define_expand "one_cmpldi2"
6419 [(set (match_operand:DI 0 "register_operand" "")
6420 (not:DI (match_operand:DI 1 "register_operand" "")))]
6424 (define_insn "*one_cmpldi2_sp32"
6425 [(set (match_operand:DI 0 "register_operand" "=r,b")
6426 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6431 [(set_attr "type" "unary,fp")
6432 (set_attr "length" "2,1")])
6435 [(set (match_operand:DI 0 "register_operand" "")
6436 (not:DI (match_operand:DI 1 "register_operand" "")))]
6439 && ((GET_CODE (operands[0]) == REG
6440 && REGNO (operands[0]) < 32)
6441 || (GET_CODE (operands[0]) == SUBREG
6442 && GET_CODE (SUBREG_REG (operands[0])) == REG
6443 && REGNO (SUBREG_REG (operands[0])) < 32))"
6444 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6445 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6446 "if (GET_CODE (operands[0]) == SUBREG)
6447 operands[0] = alter_subreg (operands[0]);
6448 operands[2] = gen_highpart (SImode, operands[0]);
6449 operands[3] = gen_highpart (SImode, operands[1]);
6450 operands[4] = gen_lowpart (SImode, operands[0]);
6451 operands[5] = gen_lowpart (SImode, operands[1]);")
6453 (define_insn "*one_cmpldi2_sp64"
6454 [(set (match_operand:DI 0 "register_operand" "=r,b")
6455 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6460 [(set_attr "type" "unary,fp")
6461 (set_attr "length" "1")])
6463 (define_expand "one_cmplsi2"
6464 [(set (match_operand:SI 0 "register_operand" "")
6465 (not:SI (match_operand:SI 1 "arith_operand" "")))]
6470 && GET_CODE (operands[1]) == CONST_INT)
6472 rtx zero_reg = gen_reg_rtx (SImode);
6474 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6475 emit_insn (gen_rtx_SET (VOIDmode,
6477 gen_rtx_NOT (SImode,
6478 gen_rtx_XOR (SImode,
6485 (define_insn "*one_cmplsi2_not_liveg0"
6486 [(set (match_operand:SI 0 "register_operand" "=r,d")
6487 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6492 [(set_attr "type" "unary,fp")
6493 (set_attr "length" "1,1")])
6495 (define_insn "*one_cmplsi2_liveg0"
6496 [(set (match_operand:SI 0 "register_operand" "=r,d")
6497 (not:SI (match_operand:SI 1 "arith_operand" "r,d")))]
6502 [(set_attr "type" "unary,fp")
6503 (set_attr "length" "1,1")])
6505 (define_insn "*cmp_cc_not"
6507 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6510 "xnorcc\\t%%g0, %0, %%g0"
6511 [(set_attr "type" "compare")
6512 (set_attr "length" "1")])
6514 (define_insn "*cmp_ccx_not"
6516 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6519 "xnorcc\\t%%g0, %0, %%g0"
6520 [(set_attr "type" "compare")
6521 (set_attr "length" "1")])
6523 (define_insn "*cmp_cc_set_not"
6525 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6527 (set (match_operand:SI 0 "register_operand" "=r")
6528 (not:SI (match_dup 1)))]
6530 "xnorcc\\t%%g0, %1, %0"
6531 [(set_attr "type" "compare")
6532 (set_attr "length" "1")])
6534 (define_insn "*cmp_ccx_set_not"
6536 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6538 (set (match_operand:DI 0 "register_operand" "=r")
6539 (not:DI (match_dup 1)))]
6541 "xnorcc\\t%%g0, %1, %0"
6542 [(set_attr "type" "compare")
6543 (set_attr "length" "1")])
6545 ;; Floating point arithmetic instructions.
6547 (define_insn "addtf3"
6548 [(set (match_operand:TF 0 "register_operand" "=e")
6549 (plus:TF (match_operand:TF 1 "register_operand" "e")
6550 (match_operand:TF 2 "register_operand" "e")))]
6551 "TARGET_FPU && TARGET_HARD_QUAD"
6552 "faddq\\t%1, %2, %0"
6553 [(set_attr "type" "fp")
6554 (set_attr "length" "1")])
6556 (define_insn "adddf3"
6557 [(set (match_operand:DF 0 "register_operand" "=e")
6558 (plus:DF (match_operand:DF 1 "register_operand" "e")
6559 (match_operand:DF 2 "register_operand" "e")))]
6561 "faddd\\t%1, %2, %0"
6562 [(set_attr "type" "fp")
6563 (set_attr "length" "1")])
6565 (define_insn "addsf3"
6566 [(set (match_operand:SF 0 "register_operand" "=f")
6567 (plus:SF (match_operand:SF 1 "register_operand" "f")
6568 (match_operand:SF 2 "register_operand" "f")))]
6570 "fadds\\t%1, %2, %0"
6571 [(set_attr "type" "fp")
6572 (set_attr "length" "1")])
6574 (define_insn "subtf3"
6575 [(set (match_operand:TF 0 "register_operand" "=e")
6576 (minus:TF (match_operand:TF 1 "register_operand" "e")
6577 (match_operand:TF 2 "register_operand" "e")))]
6578 "TARGET_FPU && TARGET_HARD_QUAD"
6579 "fsubq\\t%1, %2, %0"
6580 [(set_attr "type" "fp")
6581 (set_attr "length" "1")])
6583 (define_insn "subdf3"
6584 [(set (match_operand:DF 0 "register_operand" "=e")
6585 (minus:DF (match_operand:DF 1 "register_operand" "e")
6586 (match_operand:DF 2 "register_operand" "e")))]
6588 "fsubd\\t%1, %2, %0"
6589 [(set_attr "type" "fp")
6590 (set_attr "length" "1")])
6592 (define_insn "subsf3"
6593 [(set (match_operand:SF 0 "register_operand" "=f")
6594 (minus:SF (match_operand:SF 1 "register_operand" "f")
6595 (match_operand:SF 2 "register_operand" "f")))]
6597 "fsubs\\t%1, %2, %0"
6598 [(set_attr "type" "fp")
6599 (set_attr "length" "1")])
6601 (define_insn "multf3"
6602 [(set (match_operand:TF 0 "register_operand" "=e")
6603 (mult:TF (match_operand:TF 1 "register_operand" "e")
6604 (match_operand:TF 2 "register_operand" "e")))]
6605 "TARGET_FPU && TARGET_HARD_QUAD"
6606 "fmulq\\t%1, %2, %0"
6607 [(set_attr "type" "fpmul")
6608 (set_attr "length" "1")])
6610 (define_insn "muldf3"
6611 [(set (match_operand:DF 0 "register_operand" "=e")
6612 (mult:DF (match_operand:DF 1 "register_operand" "e")
6613 (match_operand:DF 2 "register_operand" "e")))]
6615 "fmuld\\t%1, %2, %0"
6616 [(set_attr "type" "fpmul")
6617 (set_attr "length" "1")])
6619 (define_insn "mulsf3"
6620 [(set (match_operand:SF 0 "register_operand" "=f")
6621 (mult:SF (match_operand:SF 1 "register_operand" "f")
6622 (match_operand:SF 2 "register_operand" "f")))]
6624 "fmuls\\t%1, %2, %0"
6625 [(set_attr "type" "fpmul")
6626 (set_attr "length" "1")])
6628 (define_insn "*muldf3_extend"
6629 [(set (match_operand:DF 0 "register_operand" "=e")
6630 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6631 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6632 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6633 "fsmuld\\t%1, %2, %0"
6634 [(set_attr "type" "fpmul")
6635 (set_attr "length" "1")])
6637 (define_insn "*multf3_extend"
6638 [(set (match_operand:TF 0 "register_operand" "=e")
6639 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6640 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6641 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6642 "fdmulq\\t%1, %2, %0"
6643 [(set_attr "type" "fpmul")
6644 (set_attr "length" "1")])
6646 ;; don't have timing for quad-prec. divide.
6647 (define_insn "divtf3"
6648 [(set (match_operand:TF 0 "register_operand" "=e")
6649 (div:TF (match_operand:TF 1 "register_operand" "e")
6650 (match_operand:TF 2 "register_operand" "e")))]
6651 "TARGET_FPU && TARGET_HARD_QUAD"
6652 "fdivq\\t%1, %2, %0"
6653 [(set_attr "type" "fpdivd")
6654 (set_attr "length" "1")])
6656 (define_insn "divdf3"
6657 [(set (match_operand:DF 0 "register_operand" "=e")
6658 (div:DF (match_operand:DF 1 "register_operand" "e")
6659 (match_operand:DF 2 "register_operand" "e")))]
6661 "fdivd\\t%1, %2, %0"
6662 [(set_attr "type" "fpdivd")
6663 (set_attr "length" "1")])
6665 (define_insn "divsf3"
6666 [(set (match_operand:SF 0 "register_operand" "=f")
6667 (div:SF (match_operand:SF 1 "register_operand" "f")
6668 (match_operand:SF 2 "register_operand" "f")))]
6670 "fdivs\\t%1, %2, %0"
6671 [(set_attr "type" "fpdivs")
6672 (set_attr "length" "1")])
6674 (define_expand "negtf2"
6675 [(set (match_operand:TF 0 "register_operand" "=e,e")
6676 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6680 (define_insn "*negtf2_notv9"
6681 [(set (match_operand:TF 0 "register_operand" "=e,e")
6682 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6683 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6689 [(set_attr "type" "fpmove")
6690 (set_attr "length" "1,2")])
6693 [(set (match_operand:TF 0 "register_operand" "")
6694 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6698 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6699 [(set (match_dup 2) (neg:SF (match_dup 3)))
6700 (set (match_dup 4) (match_dup 5))
6701 (set (match_dup 6) (match_dup 7))]
6702 "if (GET_CODE (operands[0]) == SUBREG)
6703 operands[0] = alter_subreg (operands[0]);
6704 if (GET_CODE (operands[1]) == SUBREG)
6705 operands[1] = alter_subreg (operands[1]);
6706 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6707 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6708 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6709 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6710 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6711 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6713 (define_insn "*negtf2_v9"
6714 [(set (match_operand:TF 0 "register_operand" "=e,e")
6715 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6716 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6717 "TARGET_FPU && TARGET_V9"
6721 [(set_attr "type" "fpmove")
6722 (set_attr "length" "1,2")])
6725 [(set (match_operand:TF 0 "register_operand" "")
6726 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6730 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6731 [(set (match_dup 2) (neg:DF (match_dup 3)))
6732 (set (match_dup 4) (match_dup 5))]
6733 "if (GET_CODE (operands[0]) == SUBREG)
6734 operands[0] = alter_subreg (operands[0]);
6735 if (GET_CODE (operands[1]) == SUBREG)
6736 operands[1] = alter_subreg (operands[1]);
6737 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6738 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6739 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6740 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6742 (define_expand "negdf2"
6743 [(set (match_operand:DF 0 "register_operand" "")
6744 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6748 (define_insn "*negdf2_notv9"
6749 [(set (match_operand:DF 0 "register_operand" "=e,e")
6750 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6751 "TARGET_FPU && ! TARGET_V9"
6755 [(set_attr "type" "fpmove")
6756 (set_attr "length" "1,2")])
6759 [(set (match_operand:DF 0 "register_operand" "")
6760 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6764 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6765 [(set (match_dup 2) (neg:SF (match_dup 3)))
6766 (set (match_dup 4) (match_dup 5))]
6767 "if (GET_CODE (operands[0]) == SUBREG)
6768 operands[0] = alter_subreg (operands[0]);
6769 if (GET_CODE (operands[1]) == SUBREG)
6770 operands[1] = alter_subreg (operands[1]);
6771 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6772 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6773 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6774 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6776 (define_insn "*negdf2_v9"
6777 [(set (match_operand:DF 0 "register_operand" "=e")
6778 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6779 "TARGET_FPU && TARGET_V9"
6781 [(set_attr "type" "fpmove")
6782 (set_attr "length" "1")])
6784 (define_insn "negsf2"
6785 [(set (match_operand:SF 0 "register_operand" "=f")
6786 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6789 [(set_attr "type" "fpmove")
6790 (set_attr "length" "1")])
6792 (define_expand "abstf2"
6793 [(set (match_operand:TF 0 "register_operand" "")
6794 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6798 (define_insn "*abstf2_notv9"
6799 [(set (match_operand:TF 0 "register_operand" "=e,e")
6800 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6801 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6802 "TARGET_FPU && ! TARGET_V9"
6806 [(set_attr "type" "fpmove")
6807 (set_attr "length" "1,2")])
6810 [(set (match_operand:TF 0 "register_operand" "=e,e")
6811 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6815 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6816 [(set (match_dup 2) (abs:SF (match_dup 3)))
6817 (set (match_dup 4) (match_dup 5))
6818 (set (match_dup 6) (match_dup 7))]
6819 "if (GET_CODE (operands[0]) == SUBREG)
6820 operands[0] = alter_subreg (operands[0]);
6821 if (GET_CODE (operands[1]) == SUBREG)
6822 operands[1] = alter_subreg (operands[1]);
6823 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6824 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6825 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6826 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6827 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6828 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6830 (define_insn "*abstf2_hq_v9"
6831 [(set (match_operand:TF 0 "register_operand" "=e,e")
6832 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6833 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6837 [(set_attr "type" "fpmove")
6838 (set_attr "length" "1")])
6840 (define_insn "*abstf2_v9"
6841 [(set (match_operand:TF 0 "register_operand" "=e,e")
6842 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6843 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6847 [(set_attr "type" "fpmove")
6848 (set_attr "length" "1,2")])
6851 [(set (match_operand:TF 0 "register_operand" "=e,e")
6852 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6856 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6857 [(set (match_dup 2) (abs:DF (match_dup 3)))
6858 (set (match_dup 4) (match_dup 5))]
6859 "if (GET_CODE (operands[0]) == SUBREG)
6860 operands[0] = alter_subreg (operands[0]);
6861 if (GET_CODE (operands[1]) == SUBREG)
6862 operands[1] = alter_subreg (operands[1]);
6863 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6864 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6865 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6866 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6868 (define_expand "absdf2"
6869 [(set (match_operand:DF 0 "register_operand" "")
6870 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6874 (define_insn "*absdf2_notv9"
6875 [(set (match_operand:DF 0 "register_operand" "=e,e")
6876 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6877 "TARGET_FPU && ! TARGET_V9"
6881 [(set_attr "type" "fpmove")
6882 (set_attr "length" "1,2")])
6885 [(set (match_operand:DF 0 "register_operand" "=e,e")
6886 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6890 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6891 [(set (match_dup 2) (abs:SF (match_dup 3)))
6892 (set (match_dup 4) (match_dup 5))]
6893 "if (GET_CODE (operands[0]) == SUBREG)
6894 operands[0] = alter_subreg (operands[0]);
6895 if (GET_CODE (operands[1]) == SUBREG)
6896 operands[1] = alter_subreg (operands[1]);
6897 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6898 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6899 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6900 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6902 (define_insn "*absdf2_v9"
6903 [(set (match_operand:DF 0 "register_operand" "=e")
6904 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6905 "TARGET_FPU && TARGET_V9"
6907 [(set_attr "type" "fpmove")
6908 (set_attr "length" "1")])
6910 (define_insn "abssf2"
6911 [(set (match_operand:SF 0 "register_operand" "=f")
6912 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6915 [(set_attr "type" "fpmove")
6916 (set_attr "length" "1")])
6918 (define_insn "sqrttf2"
6919 [(set (match_operand:TF 0 "register_operand" "=e")
6920 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6921 "TARGET_FPU && TARGET_HARD_QUAD"
6923 [(set_attr "type" "fpsqrt")
6924 (set_attr "length" "1")])
6926 (define_insn "sqrtdf2"
6927 [(set (match_operand:DF 0 "register_operand" "=e")
6928 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6931 [(set_attr "type" "fpsqrt")
6932 (set_attr "length" "1")])
6934 (define_insn "sqrtsf2"
6935 [(set (match_operand:SF 0 "register_operand" "=f")
6936 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6939 [(set_attr "type" "fpsqrt")
6940 (set_attr "length" "1")])
6942 ;;- arithmetic shift instructions
6944 (define_insn "ashlsi3"
6945 [(set (match_operand:SI 0 "register_operand" "=r")
6946 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6947 (match_operand:SI 2 "arith_operand" "rI")))]
6951 if (GET_CODE (operands[2]) == CONST_INT
6952 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
6953 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6955 return \"sll\\t%1, %2, %0\";
6957 [(set_attr "type" "shift")
6958 (set_attr "length" "1")])
6960 ;; We special case multiplication by two, as add can be done
6961 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
6962 (define_insn "*ashlsi3_const1"
6963 [(set (match_operand:SI 0 "register_operand" "=r")
6964 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6968 [(set_attr "type" "binary")
6969 (set_attr "length" "1")])
6971 (define_expand "ashldi3"
6972 [(set (match_operand:DI 0 "register_operand" "=r")
6973 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6974 (match_operand:SI 2 "arith_operand" "rI")))]
6975 "TARGET_ARCH64 || TARGET_V8PLUS"
6978 if (! TARGET_ARCH64)
6980 if (GET_CODE (operands[2]) == CONST_INT)
6982 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6987 ;; We special case multiplication by two, as add can be done
6988 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
6989 (define_insn "*ashldi3_const1"
6990 [(set (match_operand:DI 0 "register_operand" "=r")
6991 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6995 [(set_attr "type" "binary")
6996 (set_attr "length" "1")])
6998 (define_insn "*ashldi3_sp64"
6999 [(set (match_operand:DI 0 "register_operand" "=r")
7000 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7001 (match_operand:SI 2 "arith_operand" "rI")))]
7005 if (GET_CODE (operands[2]) == CONST_INT
7006 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7007 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7009 return \"sllx\\t%1, %2, %0\";
7011 [(set_attr "type" "shift")
7012 (set_attr "length" "1")])
7015 (define_insn "ashldi3_v8plus"
7016 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7017 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7018 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7019 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7021 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7022 [(set_attr "length" "5,5,6")])
7024 ;; Optimize (1LL<<x)-1
7025 ;; XXX this also needs to be fixed to handle equal subregs
7026 ;; XXX first before we could re-enable it.
7028 [(set (match_operand:DI 0 "register_operand" "=h")
7029 (plus:DI (ashift:DI (const_int 1)
7030 (match_operand:SI 2 "arith_operand" "rI"))
7032 "0 && TARGET_V8PLUS"
7035 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
7036 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7037 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7039 [(set_attr "length" "4")])
7041 (define_insn "*cmp_cc_ashift_1"
7042 [(set (reg:CC_NOOV 100)
7043 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7047 "addcc\\t%0, %0, %%g0"
7048 [(set_attr "type" "compare")
7049 (set_attr "length" "1")])
7051 (define_insn "*cmp_cc_set_ashift_1"
7052 [(set (reg:CC_NOOV 100)
7053 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7056 (set (match_operand:SI 0 "register_operand" "=r")
7057 (ashift:SI (match_dup 1) (const_int 1)))]
7059 "addcc\\t%1, %1, %0"
7060 [(set_attr "type" "compare")
7061 (set_attr "length" "1")])
7063 (define_insn "ashrsi3"
7064 [(set (match_operand:SI 0 "register_operand" "=r")
7065 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7066 (match_operand:SI 2 "arith_operand" "rI")))]
7070 if (GET_CODE (operands[2]) == CONST_INT
7071 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7072 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7074 return \"sra\\t%1, %2, %0\";
7076 [(set_attr "type" "shift")
7077 (set_attr "length" "1")])
7079 (define_insn "*ashrsi3_extend"
7080 [(set (match_operand:DI 0 "register_operand" "=r")
7081 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7082 (match_operand:SI 2 "arith_operand" "r"))))]
7085 [(set_attr "type" "shift")
7086 (set_attr "length" "1")])
7088 ;; This handles the case as above, but with constant shift instead of
7089 ;; register. Combiner "simplifies" it for us a little bit though.
7090 (define_insn "*ashrsi3_extend2"
7091 [(set (match_operand:DI 0 "register_operand" "=r")
7092 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7094 (match_operand:SI 2 "small_int_or_double" "n")))]
7096 && ((GET_CODE (operands[2]) == CONST_INT
7097 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7098 || (GET_CODE (operands[2]) == CONST_DOUBLE
7099 && !CONST_DOUBLE_HIGH (operands[2])
7100 && CONST_DOUBLE_LOW (operands[2]) >= 32
7101 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7104 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7106 return \"sra\\t%1, %2, %0\";
7108 [(set_attr "type" "shift")
7109 (set_attr "length" "1")])
7111 (define_expand "ashrdi3"
7112 [(set (match_operand:DI 0 "register_operand" "=r")
7113 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7114 (match_operand:SI 2 "arith_operand" "rI")))]
7115 "TARGET_ARCH64 || TARGET_V8PLUS"
7118 if (! TARGET_ARCH64)
7120 if (GET_CODE (operands[2]) == CONST_INT)
7121 FAIL; /* prefer generic code in this case */
7122 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7128 [(set (match_operand:DI 0 "register_operand" "=r")
7129 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7130 (match_operand:SI 2 "arith_operand" "rI")))]
7134 if (GET_CODE (operands[2]) == CONST_INT
7135 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7136 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7138 return \"srax\\t%1, %2, %0\";
7140 [(set_attr "type" "shift")
7141 (set_attr "length" "1")])
7144 (define_insn "ashrdi3_v8plus"
7145 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7146 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7147 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7148 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7150 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7151 [(set_attr "length" "5,5,6")])
7153 (define_insn "lshrsi3"
7154 [(set (match_operand:SI 0 "register_operand" "=r")
7155 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7156 (match_operand:SI 2 "arith_operand" "rI")))]
7160 if (GET_CODE (operands[2]) == CONST_INT
7161 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7162 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7164 return \"srl\\t%1, %2, %0\";
7166 [(set_attr "type" "shift")
7167 (set_attr "length" "1")])
7169 ;; This handles the case where
7170 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7171 ;; but combiner "simplifies" it for us.
7172 (define_insn "*lshrsi3_extend"
7173 [(set (match_operand:DI 0 "register_operand" "=r")
7174 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7175 (match_operand:SI 2 "arith_operand" "r")) 0)
7176 (match_operand 3 "" "")))]
7178 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7179 && CONST_DOUBLE_HIGH (operands[3]) == 0
7180 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7181 #if HOST_BITS_PER_WIDE_INT >= 64
7182 || (GET_CODE (operands[3]) == CONST_INT
7183 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
7187 [(set_attr "type" "shift")
7188 (set_attr "length" "1")])
7190 ;; This handles the case where
7191 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7192 ;; but combiner "simplifies" it for us.
7193 (define_insn "*lshrsi3_extend2"
7194 [(set (match_operand:DI 0 "register_operand" "=r")
7195 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7196 (match_operand 2 "small_int_or_double" "n")
7199 && ((GET_CODE (operands[2]) == CONST_INT
7200 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7201 || (GET_CODE (operands[2]) == CONST_DOUBLE
7202 && CONST_DOUBLE_HIGH (operands[2]) == 0
7203 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7206 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7208 return \"srl\\t%1, %2, %0\";
7210 [(set_attr "type" "shift")
7211 (set_attr "length" "1")])
7213 (define_expand "lshrdi3"
7214 [(set (match_operand:DI 0 "register_operand" "=r")
7215 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7216 (match_operand:SI 2 "arith_operand" "rI")))]
7217 "TARGET_ARCH64 || TARGET_V8PLUS"
7220 if (! TARGET_ARCH64)
7222 if (GET_CODE (operands[2]) == CONST_INT)
7224 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7230 [(set (match_operand:DI 0 "register_operand" "=r")
7231 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7232 (match_operand:SI 2 "arith_operand" "rI")))]
7236 if (GET_CODE (operands[2]) == CONST_INT
7237 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7238 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7240 return \"srlx\\t%1, %2, %0\";
7242 [(set_attr "type" "shift")
7243 (set_attr "length" "1")])
7246 (define_insn "lshrdi3_v8plus"
7247 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7248 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7249 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7250 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7252 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7253 [(set_attr "length" "5,5,6")])
7255 ;; Unconditional and other jump instructions
7256 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7257 ;; following insn is never executed. This saves us a nop. Dbx does not
7258 ;; handle such branches though, so we only use them when optimizing.
7260 [(set (pc) (label_ref (match_operand 0 "" "")))]
7264 /* TurboSparc is reported to have problems with
7267 i.e. an empty loop with the annul bit set. The workaround is to use
7271 if (! TARGET_V9 && flag_delayed_branch
7272 && (insn_addresses[INSN_UID (operands[0])]
7273 == insn_addresses[INSN_UID (insn)]))
7274 return \"b\\t%l0%#\";
7276 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7278 [(set_attr "type" "uncond_branch")])
7280 (define_expand "tablejump"
7281 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7282 (use (label_ref (match_operand 1 "" "")))])]
7286 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7289 /* In pic mode, our address differences are against the base of the
7290 table. Add that base value back in; CSE ought to be able to combine
7291 the two address loads. */
7295 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7297 if (CASE_VECTOR_MODE != Pmode)
7298 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7299 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7300 operands[0] = memory_address (Pmode, tmp);
7304 (define_insn "*tablejump_sp32"
7305 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7306 (use (label_ref (match_operand 1 "" "")))]
7309 [(set_attr "type" "uncond_branch")])
7311 (define_insn "*tablejump_sp64"
7312 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7313 (use (label_ref (match_operand 1 "" "")))]
7316 [(set_attr "type" "uncond_branch")])
7318 ;; This pattern recognizes the "instruction" that appears in
7319 ;; a function call that wants a structure value,
7320 ;; to inform the called function if compiled with Sun CC.
7321 ;(define_insn "*unimp_insn"
7322 ; [(match_operand:SI 0 "immediate_operand" "")]
7323 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7325 ; [(set_attr "type" "marker")])
7327 ;;- jump to subroutine
7328 (define_expand "call"
7329 ;; Note that this expression is not used for generating RTL.
7330 ;; All the RTL is generated explicitly below.
7331 [(call (match_operand 0 "call_operand" "")
7332 (match_operand 3 "" "i"))]
7333 ;; operands[2] is next_arg_register
7334 ;; operands[3] is struct_value_size_rtx.
7338 rtx fn_rtx, nregs_rtx;
7340 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7343 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7345 /* This is really a PIC sequence. We want to represent
7346 it as a funny jump so its delay slots can be filled.
7348 ??? But if this really *is* a CALL, will not it clobber the
7349 call-clobbered registers? We lose this if it is a JUMP_INSN.
7350 Why cannot we have delay slots filled if it were a CALL? */
7352 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7354 (gen_rtx_PARALLEL (VOIDmode,
7356 gen_rtx_SET (VOIDmode, pc_rtx,
7357 XEXP (operands[0], 0)),
7358 GEN_INT (INTVAL (operands[3]) & 0xfff),
7359 gen_rtx_CLOBBER (VOIDmode,
7360 gen_rtx_REG (Pmode, 15)))));
7363 (gen_rtx_PARALLEL (VOIDmode,
7365 gen_rtx_SET (VOIDmode, pc_rtx,
7366 XEXP (operands[0], 0)),
7367 gen_rtx_CLOBBER (VOIDmode,
7368 gen_rtx_REG (Pmode, 15)))));
7372 fn_rtx = operands[0];
7374 /* Count the number of parameter registers being used by this call.
7375 if that argument is NULL, it means we are using them all, which
7376 means 6 on the sparc. */
7379 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7381 nregs_rtx = GEN_INT (6);
7383 nregs_rtx = const0_rtx;
7386 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7388 (gen_rtx_PARALLEL (VOIDmode,
7389 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7390 GEN_INT (INTVAL (operands[3]) & 0xfff),
7391 gen_rtx_CLOBBER (VOIDmode,
7392 gen_rtx_REG (Pmode, 15)))));
7395 (gen_rtx_PARALLEL (VOIDmode,
7396 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7397 gen_rtx_CLOBBER (VOIDmode,
7398 gen_rtx_REG (Pmode, 15)))));
7402 /* If this call wants a structure value,
7403 emit an unimp insn to let the called function know about this. */
7404 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7406 rtx insn = emit_insn (operands[3]);
7407 SCHED_GROUP_P (insn) = 1;
7414 ;; We can't use the same pattern for these two insns, because then registers
7415 ;; in the address may not be properly reloaded.
7417 (define_insn "*call_address_sp32"
7418 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7419 (match_operand 1 "" ""))
7420 (clobber (reg:SI 15))]
7421 ;;- Do not use operand 1 for most machines.
7424 [(set_attr "type" "call")])
7426 (define_insn "*call_symbolic_sp32"
7427 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7428 (match_operand 1 "" ""))
7429 (clobber (reg:SI 15))]
7430 ;;- Do not use operand 1 for most machines.
7433 [(set_attr "type" "call")])
7435 (define_insn "*call_address_sp64"
7436 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
7437 (match_operand 1 "" ""))
7438 (clobber (reg:DI 15))]
7439 ;;- Do not use operand 1 for most machines.
7442 [(set_attr "type" "call")])
7444 (define_insn "*call_symbolic_sp64"
7445 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
7446 (match_operand 1 "" ""))
7447 (clobber (reg:DI 15))]
7448 ;;- Do not use operand 1 for most machines.
7451 [(set_attr "type" "call")])
7453 ;; This is a call that wants a structure value.
7454 ;; There is no such critter for v9 (??? we may need one anyway).
7455 (define_insn "*call_address_struct_value_sp32"
7456 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7457 (match_operand 1 "" ""))
7458 (match_operand 2 "immediate_operand" "")
7459 (clobber (reg:SI 15))]
7460 ;;- Do not use operand 1 for most machines.
7461 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7462 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7463 [(set_attr "type" "call_no_delay_slot")])
7465 ;; This is a call that wants a structure value.
7466 ;; There is no such critter for v9 (??? we may need one anyway).
7467 (define_insn "*call_symbolic_struct_value_sp32"
7468 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7469 (match_operand 1 "" ""))
7470 (match_operand 2 "immediate_operand" "")
7471 (clobber (reg:SI 15))]
7472 ;;- Do not use operand 1 for most machines.
7473 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7474 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7475 [(set_attr "type" "call_no_delay_slot")])
7477 ;; This is a call that may want a structure value. This is used for
7479 (define_insn "*call_address_untyped_struct_value_sp32"
7480 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7481 (match_operand 1 "" ""))
7482 (match_operand 2 "immediate_operand" "")
7483 (clobber (reg:SI 15))]
7484 ;;- Do not use operand 1 for most machines.
7485 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7486 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7487 [(set_attr "type" "call_no_delay_slot")])
7489 ;; This is a call that wants a structure value.
7490 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7491 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7492 (match_operand 1 "" ""))
7493 (match_operand 2 "immediate_operand" "")
7494 (clobber (reg:SI 15))]
7495 ;;- Do not use operand 1 for most machines.
7496 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7497 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7498 [(set_attr "type" "call_no_delay_slot")])
7500 (define_expand "call_value"
7501 ;; Note that this expression is not used for generating RTL.
7502 ;; All the RTL is generated explicitly below.
7503 [(set (match_operand 0 "register_operand" "=rf")
7504 (call (match_operand:SI 1 "" "")
7505 (match_operand 4 "" "")))]
7506 ;; operand 2 is stack_size_rtx
7507 ;; operand 3 is next_arg_register
7511 rtx fn_rtx, nregs_rtx;
7514 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7517 fn_rtx = operands[1];
7521 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7523 nregs_rtx = GEN_INT (6);
7525 nregs_rtx = const0_rtx;
7529 gen_rtx_SET (VOIDmode, operands[0],
7530 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7531 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7533 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7538 (define_insn "*call_value_address_sp32"
7539 [(set (match_operand 0 "" "=rf")
7540 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7541 (match_operand 2 "" "")))
7542 (clobber (reg:SI 15))]
7543 ;;- Do not use operand 2 for most machines.
7546 [(set_attr "type" "call")])
7548 (define_insn "*call_value_symbolic_sp32"
7549 [(set (match_operand 0 "" "=rf")
7550 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7551 (match_operand 2 "" "")))
7552 (clobber (reg:SI 15))]
7553 ;;- Do not use operand 2 for most machines.
7556 [(set_attr "type" "call")])
7558 (define_insn "*call_value_address_sp64"
7559 [(set (match_operand 0 "" "")
7560 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
7561 (match_operand 2 "" "")))
7562 (clobber (reg:DI 15))]
7563 ;;- Do not use operand 2 for most machines.
7566 [(set_attr "type" "call")])
7568 (define_insn "*call_value_symbolic_sp64"
7569 [(set (match_operand 0 "" "")
7570 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
7571 (match_operand 2 "" "")))
7572 (clobber (reg:DI 15))]
7573 ;;- Do not use operand 2 for most machines.
7576 [(set_attr "type" "call")])
7578 (define_expand "untyped_call"
7579 [(parallel [(call (match_operand 0 "" "")
7581 (match_operand 1 "" "")
7582 (match_operand 2 "" "")])]
7588 /* Pass constm1 to indicate that it may expect a structure value, but
7589 we don't know what size it is. */
7590 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7592 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7594 rtx set = XVECEXP (operands[2], 0, i);
7595 emit_move_insn (SET_DEST (set), SET_SRC (set));
7598 /* The optimizer does not know that the call sets the function value
7599 registers we stored in the result block. We avoid problems by
7600 claiming that all hard registers are used and clobbered at this
7602 emit_insn (gen_blockage ());
7607 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7608 ;; all of memory. This blocks insns from being moved across this point.
7610 (define_insn "blockage"
7611 [(unspec_volatile [(const_int 0)] 0)]
7614 [(set_attr "length" "0")])
7616 ;; Prepare to return any type including a structure value.
7618 (define_expand "untyped_return"
7619 [(match_operand:BLK 0 "memory_operand" "")
7620 (match_operand 1 "" "")]
7624 rtx valreg1 = gen_rtx_REG (DImode, 24);
7625 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7626 rtx result = operands[0];
7628 if (! TARGET_ARCH64)
7630 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7632 rtx value = gen_reg_rtx (SImode);
7634 /* Fetch the instruction where we will return to and see if it's an unimp
7635 instruction (the most significant 10 bits will be zero). If so,
7636 update the return address to skip the unimp instruction. */
7637 emit_move_insn (value,
7638 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7639 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7640 emit_insn (gen_update_return (rtnreg, value));
7643 /* Reload the function value registers. */
7644 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
7645 emit_move_insn (valreg2,
7646 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
7647 plus_constant (XEXP (result, 0), 8)));
7649 /* Put USE insns before the return. */
7650 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7651 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7653 /* Construct the return. */
7654 expand_null_return ();
7659 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7660 ;; and parts of the compiler don't want to believe that the add is needed.
7662 (define_insn "update_return"
7663 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7664 (match_operand:SI 1 "register_operand" "r")] 1)]
7666 "cmp %1,0\;be,a .+8\;add %0,4,%0"
7667 [(set_attr "type" "multi")])
7669 (define_insn "return"
7673 "* return output_return (operands);"
7674 [(set_attr "type" "return")])
7677 [(set (match_operand:SI 0 "register_operand" "=r")
7678 (match_operand:SI 1 "arith_operand" "rI"))
7680 (use (reg:SI 31))])]
7681 "sparc_return_peephole_ok (operands[0], operands[1])"
7682 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
7688 [(set_attr "type" "ialu")
7689 (set_attr "length" "1")])
7691 (define_expand "indirect_jump"
7692 [(set (pc) (match_operand 0 "address_operand" "p"))]
7696 (define_insn "*branch_sp32"
7697 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7700 [(set_attr "type" "uncond_branch")])
7702 (define_insn "*branch_sp64"
7703 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7706 [(set_attr "type" "uncond_branch")])
7708 ;; ??? Doesn't work with -mflat.
7709 (define_expand "nonlocal_goto"
7710 [(match_operand:SI 0 "general_operand" "")
7711 (match_operand:SI 1 "general_operand" "")
7712 (match_operand:SI 2 "general_operand" "")
7713 (match_operand:SI 3 "" "")]
7718 rtx chain = operands[0];
7720 rtx fp = operands[1];
7721 rtx stack = operands[2];
7722 rtx lab = operands[3];
7725 /* Trap instruction to flush all the register windows. */
7726 emit_insn (gen_flush_register_windows ());
7728 /* Load the fp value for the containing fn into %fp. This is needed
7729 because STACK refers to %fp. Note that virtual register instantiation
7730 fails if the virtual %fp isn't set from a register. */
7731 if (GET_CODE (fp) != REG)
7732 fp = force_reg (Pmode, fp);
7733 emit_move_insn (virtual_stack_vars_rtx, fp);
7735 /* Find the containing function's current nonlocal goto handler,
7736 which will do any cleanups and then jump to the label. */
7737 labreg = gen_rtx_REG (Pmode, 8);
7738 emit_move_insn (labreg, lab);
7740 /* Restore %fp from stack pointer value for containing function.
7741 The restore insn that follows will move this to %sp,
7742 and reload the appropriate value into %fp. */
7743 emit_move_insn (frame_pointer_rtx, stack);
7745 /* USE of frame_pointer_rtx added for consistency; not clear if
7747 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7748 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7751 /* Return, restoring reg window and jumping to goto handler. */
7752 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7753 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7755 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
7760 /* Put in the static chain register the nonlocal label address. */
7761 emit_move_insn (static_chain_rtx, chain);
7764 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7765 emit_insn (gen_goto_handler_and_restore (labreg));
7770 ;; Special trap insn to flush register windows.
7771 (define_insn "flush_register_windows"
7772 [(unspec_volatile [(const_int 0)] 1)]
7774 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
7775 [(set_attr "type" "misc")
7776 (set_attr "length" "1")])
7778 (define_insn "goto_handler_and_restore"
7779 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
7781 "jmp\\t%0+0\\n\\trestore"
7782 [(set_attr "type" "misc")
7783 (set_attr "length" "2")])
7785 ;;(define_insn "goto_handler_and_restore_v9"
7786 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7787 ;; (match_operand:SI 1 "register_operand" "=r,r")
7788 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7789 ;; "TARGET_V9 && ! TARGET_ARCH64"
7791 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7792 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7793 ;; [(set_attr "type" "misc")
7794 ;; (set_attr "length" "2,3")])
7796 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7797 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7798 ;; (match_operand:DI 1 "register_operand" "=r,r")
7799 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7800 ;; "TARGET_V9 && TARGET_ARCH64"
7802 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7803 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7804 ;; [(set_attr "type" "misc")
7805 ;; (set_attr "length" "2,3")])
7807 ;; Pattern for use after a setjmp to store FP and the return register
7808 ;; into the stack area.
7810 (define_expand "setjmp"
7816 emit_insn (gen_setjmp_64 ());
7818 emit_insn (gen_setjmp_32 ());
7822 (define_expand "setjmp_32"
7823 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7824 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7827 { operands[0] = frame_pointer_rtx; }")
7829 (define_expand "setjmp_64"
7830 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7831 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7834 { operands[0] = frame_pointer_rtx; }")
7836 ;; Special pattern for the FLUSH instruction.
7838 (define_insn "flush"
7839 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 4)]
7841 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
7842 [(set_attr "type" "misc")
7843 (set_attr "length" "1")])
7847 ;; The scan instruction searches from the most significant bit while ffs
7848 ;; searches from the least significant bit. The bit index and treatment of
7849 ;; zero also differ. It takes at least 7 instructions to get the proper
7850 ;; result. Here is an obvious 8 instruction sequence.
7853 (define_insn "ffssi2"
7854 [(set (match_operand:SI 0 "register_operand" "=&r")
7855 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7856 (clobber (match_scratch:SI 2 "=&r"))]
7857 "TARGET_SPARCLITE || TARGET_SPARCLET"
7861 output_asm_insn (\"and %%g0,0,%%g0\", operands);
7862 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\";
7864 [(set_attr "type" "multi")
7865 (set_attr "length" "8")])
7867 ;; ??? This should be a define expand, so that the extra instruction have
7868 ;; a chance of being optimized away.
7870 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
7871 ;; does, but no one uses that and we don't have a switch for it.
7873 ;(define_insn "ffsdi2"
7874 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7875 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7876 ; (clobber (match_scratch:DI 2 "=&r"))]
7878 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
7879 ; [(set_attr "type" "multi")
7880 ; (set_attr "length" "4")])
7883 ;; Peepholes go at the end.
7885 ;; Optimize consecutive loads or stores into ldd and std when possible.
7886 ;; The conditions in which we do this are very restricted and are
7887 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7890 [(set (match_operand:SI 0 "memory_operand" "")
7892 (set (match_operand:SI 1 "memory_operand" "")
7895 && ! MEM_VOLATILE_P (operands[0])
7896 && ! MEM_VOLATILE_P (operands[1])
7897 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
7901 [(set (match_operand:SI 0 "memory_operand" "")
7903 (set (match_operand:SI 1 "memory_operand" "")
7906 && ! MEM_VOLATILE_P (operands[0])
7907 && ! MEM_VOLATILE_P (operands[1])
7908 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
7912 [(set (match_operand:SI 0 "register_operand" "=rf")
7913 (match_operand:SI 1 "memory_operand" ""))
7914 (set (match_operand:SI 2 "register_operand" "=rf")
7915 (match_operand:SI 3 "memory_operand" ""))]
7916 "registers_ok_for_ldd_peep (operands[0], operands[2])
7917 && ! MEM_VOLATILE_P (operands[1])
7918 && ! MEM_VOLATILE_P (operands[3])
7919 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7923 [(set (match_operand:SI 0 "memory_operand" "")
7924 (match_operand:SI 1 "register_operand" "rf"))
7925 (set (match_operand:SI 2 "memory_operand" "")
7926 (match_operand:SI 3 "register_operand" "rf"))]
7927 "registers_ok_for_ldd_peep (operands[1], operands[3])
7928 && ! MEM_VOLATILE_P (operands[0])
7929 && ! MEM_VOLATILE_P (operands[2])
7930 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
7934 [(set (match_operand:SF 0 "register_operand" "=fr")
7935 (match_operand:SF 1 "memory_operand" ""))
7936 (set (match_operand:SF 2 "register_operand" "=fr")
7937 (match_operand:SF 3 "memory_operand" ""))]
7938 "registers_ok_for_ldd_peep (operands[0], operands[2])
7939 && ! MEM_VOLATILE_P (operands[1])
7940 && ! MEM_VOLATILE_P (operands[3])
7941 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7945 [(set (match_operand:SF 0 "memory_operand" "")
7946 (match_operand:SF 1 "register_operand" "fr"))
7947 (set (match_operand:SF 2 "memory_operand" "")
7948 (match_operand:SF 3 "register_operand" "fr"))]
7949 "registers_ok_for_ldd_peep (operands[1], operands[3])
7950 && ! MEM_VOLATILE_P (operands[0])
7951 && ! MEM_VOLATILE_P (operands[2])
7952 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
7956 [(set (match_operand:SI 0 "register_operand" "=rf")
7957 (match_operand:SI 1 "memory_operand" ""))
7958 (set (match_operand:SI 2 "register_operand" "=rf")
7959 (match_operand:SI 3 "memory_operand" ""))]
7960 "registers_ok_for_ldd_peep (operands[2], operands[0])
7961 && ! MEM_VOLATILE_P (operands[3])
7962 && ! MEM_VOLATILE_P (operands[1])
7963 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
7967 [(set (match_operand:SI 0 "memory_operand" "")
7968 (match_operand:SI 1 "register_operand" "rf"))
7969 (set (match_operand:SI 2 "memory_operand" "")
7970 (match_operand:SI 3 "register_operand" "rf"))]
7971 "registers_ok_for_ldd_peep (operands[3], operands[1])
7972 && ! MEM_VOLATILE_P (operands[2])
7973 && ! MEM_VOLATILE_P (operands[0])
7974 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
7978 [(set (match_operand:SF 0 "register_operand" "=fr")
7979 (match_operand:SF 1 "memory_operand" ""))
7980 (set (match_operand:SF 2 "register_operand" "=fr")
7981 (match_operand:SF 3 "memory_operand" ""))]
7982 "registers_ok_for_ldd_peep (operands[2], operands[0])
7983 && ! MEM_VOLATILE_P (operands[3])
7984 && ! MEM_VOLATILE_P (operands[1])
7985 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
7989 [(set (match_operand:SF 0 "memory_operand" "")
7990 (match_operand:SF 1 "register_operand" "fr"))
7991 (set (match_operand:SF 2 "memory_operand" "")
7992 (match_operand:SF 3 "register_operand" "fr"))]
7993 "registers_ok_for_ldd_peep (operands[3], operands[1])
7994 && ! MEM_VOLATILE_P (operands[2])
7995 && ! MEM_VOLATILE_P (operands[0])
7996 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
7999 ;; Optimize the case of following a reg-reg move with a test
8000 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8001 ;; This can result from a float to fix conversion.
8004 [(set (match_operand:SI 0 "register_operand" "=r")
8005 (match_operand:SI 1 "register_operand" "r"))
8007 (compare:CC (match_operand:SI 2 "register_operand" "r")
8009 "(rtx_equal_p (operands[2], operands[0])
8010 || rtx_equal_p (operands[2], operands[1]))
8011 && ! FP_REG_P (operands[0])
8012 && ! FP_REG_P (operands[1])"
8016 [(set (match_operand:DI 0 "register_operand" "=r")
8017 (match_operand:DI 1 "register_operand" "r"))
8019 (compare:CCX (match_operand:DI 2 "register_operand" "r")
8022 && (rtx_equal_p (operands[2], operands[0])
8023 || rtx_equal_p (operands[2], operands[1]))
8024 && ! FP_REG_P (operands[0])
8025 && ! FP_REG_P (operands[1])"
8028 ;; Return peepholes. First the "normal" ones.
8029 ;; These are necessary to catch insns ending up in the epilogue delay list.
8031 (define_insn "*return_qi"
8032 [(set (match_operand:QI 0 "restore_operand" "")
8033 (match_operand:QI 1 "arith_operand" "rI"))
8035 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8038 if (! TARGET_ARCH64 && current_function_returns_struct)
8039 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8040 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8041 || IN_OR_GLOBAL_P (operands[1])))
8042 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8044 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8046 [(set_attr "type" "multi")])
8048 (define_insn "*return_hi"
8049 [(set (match_operand:HI 0 "restore_operand" "")
8050 (match_operand:HI 1 "arith_operand" "rI"))
8052 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8055 if (! TARGET_ARCH64 && current_function_returns_struct)
8056 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8057 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8058 || IN_OR_GLOBAL_P (operands[1])))
8059 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8061 return \"ret\;restore %%g0, %1, %Y0\";
8063 [(set_attr "type" "multi")])
8065 (define_insn "*return_si"
8066 [(set (match_operand:SI 0 "restore_operand" "")
8067 (match_operand:SI 1 "arith_operand" "rI"))
8069 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8072 if (! TARGET_ARCH64 && current_function_returns_struct)
8073 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8074 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8075 || IN_OR_GLOBAL_P (operands[1])))
8076 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8078 return \"ret\;restore %%g0, %1, %Y0\";
8080 [(set_attr "type" "multi")])
8082 ;; The following pattern is only generated by delayed-branch scheduling,
8083 ;; when the insn winds up in the epilogue. This can happen not only when
8084 ;; ! TARGET_FPU because we move complex types around by parts using
8086 (define_insn "*return_sf_no_fpu"
8087 [(set (match_operand:SF 0 "restore_operand" "r")
8088 (match_operand:SF 1 "register_operand" "r"))
8090 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8093 if (! TARGET_ARCH64 && current_function_returns_struct)
8094 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8095 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8096 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8098 return \"ret\;restore %%g0, %1, %Y0\";
8100 [(set_attr "type" "multi")])
8102 (define_insn "*return_addsi"
8103 [(set (match_operand:SI 0 "restore_operand" "")
8104 (plus:SI (match_operand:SI 1 "register_operand" "r")
8105 (match_operand:SI 2 "arith_operand" "rI")))
8107 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8110 if (! TARGET_ARCH64 && current_function_returns_struct)
8111 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8112 /* If operands are global or in registers, can use return */
8113 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8114 && (GET_CODE (operands[2]) == CONST_INT
8115 || IN_OR_GLOBAL_P (operands[2])))
8116 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8118 return \"ret\;restore %r1, %2, %Y0\";
8120 [(set_attr "type" "multi")])
8122 (define_insn "*return_di"
8123 [(set (match_operand:DI 0 "restore_operand" "")
8124 (match_operand:DI 1 "arith_double_operand" "rHI"))
8126 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8127 "ret\;restore %%g0, %1, %Y0"
8128 [(set_attr "type" "multi")])
8130 (define_insn "*return_adddi"
8131 [(set (match_operand:DI 0 "restore_operand" "")
8132 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8133 (match_operand:DI 2 "arith_double_operand" "rHI")))
8135 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8136 "ret\;restore %r1, %2, %Y0"
8137 [(set_attr "type" "multi")])
8139 ;; The following pattern is only generated by delayed-branch scheduling,
8140 ;; when the insn winds up in the epilogue.
8141 (define_insn "*return_sf"
8143 (match_operand:SF 0 "register_operand" "f"))
8146 "ret\;fmovs\\t%0, %%f0"
8147 [(set_attr "type" "multi")])
8149 ;; Now peepholes to do a call followed by a jump.
8152 [(parallel [(set (match_operand 0 "" "")
8153 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8154 (match_operand 2 "" "")))
8155 (clobber (reg:SI 15))])
8156 (set (pc) (label_ref (match_operand 3 "" "")))]
8157 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8158 && in_same_eh_region (insn, operands[3])
8159 && in_same_eh_region (insn, ins1)"
8160 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8163 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8164 (match_operand 1 "" ""))
8165 (clobber (reg:SI 15))])
8166 (set (pc) (label_ref (match_operand 2 "" "")))]
8167 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8168 && in_same_eh_region (insn, operands[2])
8169 && in_same_eh_region (insn, ins1)"
8170 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8173 [(parallel [(set (match_operand 0 "" "")
8174 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
8175 (match_operand 2 "" "")))
8176 (clobber (reg:DI 15))])
8177 (set (pc) (label_ref (match_operand 3 "" "")))]
8179 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8180 && in_same_eh_region (insn, operands[3])
8181 && in_same_eh_region (insn, ins1)"
8182 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8185 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
8186 (match_operand 1 "" ""))
8187 (clobber (reg:DI 15))])
8188 (set (pc) (label_ref (match_operand 2 "" "")))]
8190 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8191 && in_same_eh_region (insn, operands[2])
8192 && in_same_eh_region (insn, ins1)"
8193 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8195 ;; After a nonlocal goto, we need to restore the PIC register, but only
8196 ;; if we need it. So do nothing much here, but we'll check for this in
8199 ;; Make sure this unspec_volatile number agrees with finalize_pic.
8200 (define_insn "nonlocal_goto_receiver"
8201 [(unspec_volatile [(const_int 0)] 5)]
8204 [(set_attr "length" "0")])
8207 [(trap_if (const_int 1) (const_int 5))]
8210 [(set_attr "type" "misc")
8211 (set_attr "length" "1")])
8213 (define_expand "conditional_trap"
8214 [(trap_if (match_operator 0 "noov_compare_op"
8215 [(match_dup 2) (match_dup 3)])
8216 (match_operand:SI 1 "arith_operand" ""))]
8218 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8219 sparc_compare_op0, sparc_compare_op1);
8220 operands[3] = const0_rtx;")
8223 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8224 (match_operand:SI 1 "arith_operand" "rM"))]
8227 [(set_attr "type" "misc")
8228 (set_attr "length" "1")])
8231 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8232 (match_operand:SI 1 "arith_operand" "rM"))]
8235 [(set_attr "type" "misc")
8236 (set_attr "length" "1")])