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,fpsqrts,fpsqrtd,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 "eligible_for_return_delay" "false,true"
165 (symbol_ref "eligible_for_return_delay(insn)"))
167 (define_attr "in_return_delay" "false,true"
168 (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
169 (eq_attr "length" "1"))
170 (eq_attr "leaf_function" "false"))
171 (eq_attr "eligible_for_return_delay" "false"))
172 (const_string "true")
173 (const_string "false")))
175 (define_delay (and (eq_attr "type" "return")
176 (eq_attr "isa" "v9"))
177 [(eq_attr "in_return_delay" "true") (nil) (nil)])
179 ;; ??? Should implement the notion of predelay slots for floating point
180 ;; branches. This would allow us to remove the nop always inserted before
181 ;; a floating point branch.
183 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
184 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
185 ;; This is because doing so will add several pipeline stalls to the path
186 ;; that the load/store did not come from. Unfortunately, there is no way
187 ;; to prevent fill_eager_delay_slots from using load/store without completely
188 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
189 ;; because it prevents us from moving back the final store of inner loops.
191 (define_attr "in_branch_delay" "false,true"
192 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
193 (eq_attr "length" "1"))
194 (const_string "true")
195 (const_string "false")))
197 (define_attr "in_uncond_branch_delay" "false,true"
198 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
199 (eq_attr "length" "1"))
200 (const_string "true")
201 (const_string "false")))
203 (define_attr "in_annul_branch_delay" "false,true"
204 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
205 (eq_attr "length" "1"))
206 (const_string "true")
207 (const_string "false")))
209 (define_delay (eq_attr "type" "branch")
210 [(eq_attr "in_branch_delay" "true")
211 (nil) (eq_attr "in_annul_branch_delay" "true")])
213 (define_delay (eq_attr "type" "uncond_branch")
214 [(eq_attr "in_uncond_branch_delay" "true")
217 ;; Function units of the SPARC
219 ;; (define_function_unit {name} {num-units} {n-users} {test}
220 ;; {ready-delay} {issue-delay} [{conflict-list}])
223 ;; (Noted only for documentation; units that take one cycle do not need to
226 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
229 ;; (define_function_unit "alu" 1 0
230 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
232 ;; ---- cypress CY7C602 scheduling:
233 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
235 (define_function_unit "memory" 1 0
236 (and (eq_attr "cpu" "cypress")
237 (eq_attr "type" "load,sload,fpload"))
240 ;; SPARC has two floating-point units: the FP ALU,
241 ;; and the FP MUL/DIV/SQRT unit.
242 ;; Instruction timings on the CY7C602 are as follows
256 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
257 ;; More insns cause the chip to stall.
259 (define_function_unit "fp_alu" 1 0
260 (and (eq_attr "cpu" "cypress")
261 (eq_attr "type" "fp,fpmove"))
264 (define_function_unit "fp_mds" 1 0
265 (and (eq_attr "cpu" "cypress")
266 (eq_attr "type" "fpmul"))
269 (define_function_unit "fp_mds" 1 0
270 (and (eq_attr "cpu" "cypress")
271 (eq_attr "type" "fpdivs,fpdivd"))
274 (define_function_unit "fp_mds" 1 0
275 (and (eq_attr "cpu" "cypress")
276 (eq_attr "type" "fpsqrts,fpsqrtd"))
279 ;; ----- The TMS390Z55 scheduling
280 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
281 ;; one ld/st, one fp.
282 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
284 (define_function_unit "memory" 1 0
285 (and (eq_attr "cpu" "supersparc")
286 (eq_attr "type" "load,sload"))
289 (define_function_unit "memory" 1 0
290 (and (eq_attr "cpu" "supersparc")
291 (eq_attr "type" "fpload"))
294 (define_function_unit "memory" 1 0
295 (and (eq_attr "cpu" "supersparc")
296 (eq_attr "type" "store,fpstore"))
299 (define_function_unit "shift" 1 0
300 (and (eq_attr "cpu" "supersparc")
301 (eq_attr "type" "shift"))
304 ;; There are only two write ports to the integer register file
305 ;; A store also uses a write port
307 (define_function_unit "iwport" 2 0
308 (and (eq_attr "cpu" "supersparc")
309 (eq_attr "type" "load,sload,store,shift,ialu"))
312 ;; Timings; throughput/latency
313 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
321 (define_function_unit "fp_alu" 1 0
322 (and (eq_attr "cpu" "supersparc")
323 (eq_attr "type" "fp,fpmove,fpcmp"))
326 (define_function_unit "fp_mds" 1 0
327 (and (eq_attr "cpu" "supersparc")
328 (eq_attr "type" "fpmul"))
331 (define_function_unit "fp_mds" 1 0
332 (and (eq_attr "cpu" "supersparc")
333 (eq_attr "type" "fpdivs"))
336 (define_function_unit "fp_mds" 1 0
337 (and (eq_attr "cpu" "supersparc")
338 (eq_attr "type" "fpdivd"))
341 (define_function_unit "fp_mds" 1 0
342 (and (eq_attr "cpu" "supersparc")
343 (eq_attr "type" "fpsqrts,fpsqrtd"))
346 (define_function_unit "fp_mds" 1 0
347 (and (eq_attr "cpu" "supersparc")
348 (eq_attr "type" "imul"))
351 ;; ----- hypersparc/sparclite86x scheduling
352 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
353 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
354 ;; II/FF case is only when loading a 32 bit hi/lo constant
355 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
356 ;; Memory delivers its result in one cycle to IU
358 (define_function_unit "memory" 1 0
359 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
360 (eq_attr "type" "load,sload,fpload"))
363 (define_function_unit "memory" 1 0
364 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
365 (eq_attr "type" "store,fpstore"))
368 (define_function_unit "sparclite86x_branch" 1 0
369 (and (eq_attr "cpu" "sparclite86x")
370 (eq_attr "type" "branch"))
373 ;; integer multiply insns
374 (define_function_unit "sparclite86x_shift" 1 0
375 (and (eq_attr "cpu" "sparclite86x")
376 (eq_attr "type" "shift"))
379 (define_function_unit "fp_alu" 1 0
380 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
381 (eq_attr "type" "fp,fpmove,fpcmp"))
384 (define_function_unit "fp_mds" 1 0
385 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
386 (eq_attr "type" "fpmul"))
389 (define_function_unit "fp_mds" 1 0
390 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
391 (eq_attr "type" "fpdivs"))
394 (define_function_unit "fp_mds" 1 0
395 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
396 (eq_attr "type" "fpdivd"))
399 (define_function_unit "fp_mds" 1 0
400 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
401 (eq_attr "type" "fpsqrts,fpsqrtd"))
404 (define_function_unit "fp_mds" 1 0
405 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
406 (eq_attr "type" "imul"))
409 ;; ----- sparclet tsc701 scheduling
410 ;; The tsc701 issues 1 insn per cycle.
411 ;; Results may be written back out of order.
413 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
415 (define_function_unit "tsc701_load" 4 1
416 (and (eq_attr "cpu" "tsc701")
417 (eq_attr "type" "load,sload"))
420 ;; Stores take 2(?) extra cycles to complete.
421 ;; It is desirable to not have any memory operation in the following 2 cycles.
422 ;; (??? or 2 memory ops in the case of std).
424 (define_function_unit "tsc701_store" 1 0
425 (and (eq_attr "cpu" "tsc701")
426 (eq_attr "type" "store"))
428 [(eq_attr "type" "load,sload,store")])
430 ;; The multiply unit has a latency of 5.
431 (define_function_unit "tsc701_mul" 1 0
432 (and (eq_attr "cpu" "tsc701")
433 (eq_attr "type" "imul"))
436 ;; ----- The UltraSPARC-1 scheduling
437 ;; UltraSPARC has two integer units. Shift instructions can only execute
438 ;; on IE0. Condition code setting instructions, call, and jmpl (including
439 ;; the ret and retl pseudo-instructions) can only execute on IE1.
440 ;; Branch on register uses IE1, but branch on condition code does not.
441 ;; Conditional moves take 2 cycles. No other instruction can issue in the
442 ;; same cycle as a conditional move.
443 ;; Multiply and divide take many cycles during which no other instructions
445 ;; Memory delivers its result in two cycles (except for signed loads,
446 ;; which take one cycle more). One memory instruction can be issued per
449 (define_function_unit "memory" 1 0
450 (and (eq_attr "cpu" "ultrasparc")
451 (eq_attr "type" "load,fpload"))
454 (define_function_unit "memory" 1 0
455 (and (eq_attr "cpu" "ultrasparc")
456 (eq_attr "type" "sload"))
459 (define_function_unit "memory" 1 0
460 (and (eq_attr "cpu" "ultrasparc")
461 (eq_attr "type" "store,fpstore"))
464 (define_function_unit "ieuN" 2 0
465 (and (eq_attr "cpu" "ultrasparc")
466 (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,call_no_delay_slot,uncond_branch"))
469 (define_function_unit "ieu0" 1 0
470 (and (eq_attr "cpu" "ultrasparc")
471 (eq_attr "type" "shift"))
474 (define_function_unit "ieu0" 1 0
475 (and (eq_attr "cpu" "ultrasparc")
476 (eq_attr "type" "cmove"))
479 (define_function_unit "ieu1" 1 0
480 (and (eq_attr "cpu" "ultrasparc")
481 (eq_attr "type" "compare,call,call_no_delay_slot,uncond_branch"))
484 (define_function_unit "cti" 1 0
485 (and (eq_attr "cpu" "ultrasparc")
486 (eq_attr "type" "branch"))
489 ;; Timings; throughput/latency
490 ;; FMOV 1/1 fmov, fabs, fneg
492 ;; FADD 1/3 add/sub, format conv, compar
498 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
500 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
501 ;; use the FPM multiplier for final rounding 3 cycles before the
502 ;; end of their latency and we have no real way to model that.
504 ;; ??? This is really bogus because the timings really depend upon
505 ;; who uses the result. We should record who the user is with
506 ;; more descriptive 'type' attribute names and account for these
507 ;; issues in ultrasparc_adjust_cost.
509 (define_function_unit "fadd" 1 0
510 (and (eq_attr "cpu" "ultrasparc")
511 (eq_attr "type" "fpmove"))
514 (define_function_unit "fadd" 1 0
515 (and (eq_attr "cpu" "ultrasparc")
516 (eq_attr "type" "fpcmove"))
519 (define_function_unit "fadd" 1 0
520 (and (eq_attr "cpu" "ultrasparc")
521 (eq_attr "type" "fp"))
524 (define_function_unit "fadd" 1 0
525 (and (eq_attr "cpu" "ultrasparc")
526 (eq_attr "type" "fpcmp"))
529 (define_function_unit "fmul" 1 0
530 (and (eq_attr "cpu" "ultrasparc")
531 (eq_attr "type" "fpmul"))
534 (define_function_unit "fadd" 1 0
535 (and (eq_attr "cpu" "ultrasparc")
536 (eq_attr "type" "fpcmove"))
539 (define_function_unit "fdiv" 1 0
540 (and (eq_attr "cpu" "ultrasparc")
541 (eq_attr "type" "fpdivs"))
544 (define_function_unit "fdiv" 1 0
545 (and (eq_attr "cpu" "ultrasparc")
546 (eq_attr "type" "fpdivd"))
549 (define_function_unit "fdiv" 1 0
550 (and (eq_attr "cpu" "ultrasparc")
551 (eq_attr "type" "fpsqrts"))
554 (define_function_unit "fdiv" 1 0
555 (and (eq_attr "cpu" "ultrasparc")
556 (eq_attr "type" "fpsqrtd"))
559 ;; Compare instructions.
560 ;; This controls RTL generation and register allocation.
562 ;; We generate RTL for comparisons and branches by having the cmpxx
563 ;; patterns store away the operands. Then, the scc and bcc patterns
564 ;; emit RTL for both the compare and the branch.
566 ;; We do this because we want to generate different code for an sne and
567 ;; seq insn. In those cases, if the second operand of the compare is not
568 ;; const0_rtx, we want to compute the xor of the two operands and test
571 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
572 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
573 ;; insns that actually require more than one machine instruction.
575 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
577 (define_expand "cmpsi"
579 (compare:CC (match_operand:SI 0 "register_operand" "")
580 (match_operand:SI 1 "arith_operand" "")))]
584 sparc_compare_op0 = operands[0];
585 sparc_compare_op1 = operands[1];
589 (define_expand "cmpdi"
591 (compare:CCX (match_operand:DI 0 "register_operand" "")
592 (match_operand:DI 1 "arith_double_operand" "")))]
596 sparc_compare_op0 = operands[0];
597 sparc_compare_op1 = operands[1];
601 (define_expand "cmpsf"
602 ;; The 96 here isn't ever used by anyone.
604 (compare:CCFP (match_operand:SF 0 "register_operand" "")
605 (match_operand:SF 1 "register_operand" "")))]
609 sparc_compare_op0 = operands[0];
610 sparc_compare_op1 = operands[1];
614 (define_expand "cmpdf"
615 ;; The 96 here isn't ever used by anyone.
617 (compare:CCFP (match_operand:DF 0 "register_operand" "")
618 (match_operand:DF 1 "register_operand" "")))]
622 sparc_compare_op0 = operands[0];
623 sparc_compare_op1 = operands[1];
627 (define_expand "cmptf"
628 ;; The 96 here isn't ever used by anyone.
630 (compare:CCFP (match_operand:TF 0 "register_operand" "")
631 (match_operand:TF 1 "register_operand" "")))]
632 "TARGET_FPU && TARGET_HARD_QUAD"
635 sparc_compare_op0 = operands[0];
636 sparc_compare_op1 = operands[1];
640 ;; Now the compare DEFINE_INSNs.
642 (define_insn "*cmpsi_insn"
644 (compare:CC (match_operand:SI 0 "register_operand" "r")
645 (match_operand:SI 1 "arith_operand" "rI")))]
648 [(set_attr "type" "compare")])
650 (define_insn "*cmpdi_sp64"
652 (compare:CCX (match_operand:DI 0 "register_operand" "r")
653 (match_operand:DI 1 "arith_double_operand" "rHI")))]
656 [(set_attr "type" "compare")])
658 (define_insn "*cmpsf_fpe"
659 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
660 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
661 (match_operand:SF 2 "register_operand" "f")))]
666 return \"fcmpes\\t%0, %1, %2\";
667 return \"fcmpes\\t%1, %2\";
669 [(set_attr "type" "fpcmp")])
671 (define_insn "*cmpdf_fpe"
672 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
673 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
674 (match_operand:DF 2 "register_operand" "e")))]
679 return \"fcmped\\t%0, %1, %2\";
680 return \"fcmped\\t%1, %2\";
682 [(set_attr "type" "fpcmp")])
684 (define_insn "*cmptf_fpe"
685 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
686 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
687 (match_operand:TF 2 "register_operand" "e")))]
688 "TARGET_FPU && TARGET_HARD_QUAD"
692 return \"fcmpeq\\t%0, %1, %2\";
693 return \"fcmpeq\\t%1, %2\";
695 [(set_attr "type" "fpcmp")])
697 (define_insn "*cmpsf_fp"
698 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
699 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
700 (match_operand:SF 2 "register_operand" "f")))]
705 return \"fcmps\\t%0, %1, %2\";
706 return \"fcmps\\t%1, %2\";
708 [(set_attr "type" "fpcmp")])
710 (define_insn "*cmpdf_fp"
711 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
712 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
713 (match_operand:DF 2 "register_operand" "e")))]
718 return \"fcmpd\\t%0, %1, %2\";
719 return \"fcmpd\\t%1, %2\";
721 [(set_attr "type" "fpcmp")])
723 (define_insn "*cmptf_fp"
724 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
725 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
726 (match_operand:TF 2 "register_operand" "e")))]
727 "TARGET_FPU && TARGET_HARD_QUAD"
731 return \"fcmpq\\t%0, %1, %2\";
732 return \"fcmpq\\t%1, %2\";
734 [(set_attr "type" "fpcmp")])
736 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
737 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
738 ;; the same code as v8 (the addx/subx method has more applications). The
739 ;; exception to this is "reg != 0" which can be done in one instruction on v9
740 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
743 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
744 ;; generate addcc/subcc instructions.
746 (define_expand "seqsi_special"
748 (xor:SI (match_operand:SI 1 "register_operand" "")
749 (match_operand:SI 2 "register_operand" "")))
750 (parallel [(set (match_operand:SI 0 "register_operand" "")
751 (eq:SI (match_dup 3) (const_int 0)))
752 (clobber (reg:CC 100))])]
754 "{ operands[3] = gen_reg_rtx (SImode); }")
756 (define_expand "seqdi_special"
758 (xor:DI (match_operand:DI 1 "register_operand" "")
759 (match_operand:DI 2 "register_operand" "")))
760 (set (match_operand:DI 0 "register_operand" "")
761 (eq:DI (match_dup 3) (const_int 0)))]
763 "{ operands[3] = gen_reg_rtx (DImode); }")
765 (define_expand "snesi_special"
767 (xor:SI (match_operand:SI 1 "register_operand" "")
768 (match_operand:SI 2 "register_operand" "")))
769 (parallel [(set (match_operand:SI 0 "register_operand" "")
770 (ne:SI (match_dup 3) (const_int 0)))
771 (clobber (reg:CC 100))])]
773 "{ operands[3] = gen_reg_rtx (SImode); }")
775 (define_expand "snedi_special"
777 (xor:DI (match_operand:DI 1 "register_operand" "")
778 (match_operand:DI 2 "register_operand" "")))
779 (set (match_operand:DI 0 "register_operand" "")
780 (ne:DI (match_dup 3) (const_int 0)))]
782 "{ operands[3] = gen_reg_rtx (DImode); }")
784 (define_expand "seqdi_special_trunc"
786 (xor:DI (match_operand:DI 1 "register_operand" "")
787 (match_operand:DI 2 "register_operand" "")))
788 (set (match_operand:SI 0 "register_operand" "")
789 (eq:SI (match_dup 3) (const_int 0)))]
791 "{ operands[3] = gen_reg_rtx (DImode); }")
793 (define_expand "snedi_special_trunc"
795 (xor:DI (match_operand:DI 1 "register_operand" "")
796 (match_operand:DI 2 "register_operand" "")))
797 (set (match_operand:SI 0 "register_operand" "")
798 (ne:SI (match_dup 3) (const_int 0)))]
800 "{ operands[3] = gen_reg_rtx (DImode); }")
802 (define_expand "seqsi_special_extend"
804 (xor:SI (match_operand:SI 1 "register_operand" "")
805 (match_operand:SI 2 "register_operand" "")))
806 (parallel [(set (match_operand:DI 0 "register_operand" "")
807 (eq:DI (match_dup 3) (const_int 0)))
808 (clobber (reg:CC 100))])]
810 "{ operands[3] = gen_reg_rtx (SImode); }")
812 (define_expand "snesi_special_extend"
814 (xor:SI (match_operand:SI 1 "register_operand" "")
815 (match_operand:SI 2 "register_operand" "")))
816 (parallel [(set (match_operand:DI 0 "register_operand" "")
817 (ne:DI (match_dup 3) (const_int 0)))
818 (clobber (reg:CC 100))])]
820 "{ operands[3] = gen_reg_rtx (SImode); }")
822 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
823 ;; However, the code handles both SImode and DImode.
825 [(set (match_operand:SI 0 "intreg_operand" "")
826 (eq:SI (match_dup 1) (const_int 0)))]
830 if (GET_MODE (sparc_compare_op0) == SImode)
834 if (GET_MODE (operands[0]) == SImode)
835 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
837 else if (! TARGET_ARCH64)
840 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
845 else if (GET_MODE (sparc_compare_op0) == DImode)
851 else if (GET_MODE (operands[0]) == SImode)
852 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
855 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
862 if (gen_v9_scc (EQ, operands))
869 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
870 ;; However, the code handles both SImode and DImode.
872 [(set (match_operand:SI 0 "intreg_operand" "")
873 (ne:SI (match_dup 1) (const_int 0)))]
877 if (GET_MODE (sparc_compare_op0) == SImode)
881 if (GET_MODE (operands[0]) == SImode)
882 pat = gen_snesi_special (operands[0], sparc_compare_op0,
884 else if (! TARGET_ARCH64)
887 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
892 else if (GET_MODE (sparc_compare_op0) == DImode)
898 else if (GET_MODE (operands[0]) == SImode)
899 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
902 pat = gen_snedi_special (operands[0], sparc_compare_op0,
909 if (gen_v9_scc (NE, operands))
917 [(set (match_operand:SI 0 "intreg_operand" "")
918 (gt:SI (match_dup 1) (const_int 0)))]
924 if (gen_v9_scc (GT, operands))
932 [(set (match_operand:SI 0 "intreg_operand" "")
933 (lt:SI (match_dup 1) (const_int 0)))]
939 if (gen_v9_scc (LT, operands))
947 [(set (match_operand:SI 0 "intreg_operand" "")
948 (ge:SI (match_dup 1) (const_int 0)))]
954 if (gen_v9_scc (GE, operands))
962 [(set (match_operand:SI 0 "intreg_operand" "")
963 (le:SI (match_dup 1) (const_int 0)))]
969 if (gen_v9_scc (LE, operands))
976 (define_expand "sgtu"
977 [(set (match_operand:SI 0 "intreg_operand" "")
978 (gtu:SI (match_dup 1) (const_int 0)))]
986 /* We can do ltu easily, so if both operands are registers, swap them and
988 if ((GET_CODE (sparc_compare_op0) == REG
989 || GET_CODE (sparc_compare_op0) == SUBREG)
990 && (GET_CODE (sparc_compare_op1) == REG
991 || GET_CODE (sparc_compare_op1) == SUBREG))
993 tem = sparc_compare_op0;
994 sparc_compare_op0 = sparc_compare_op1;
995 sparc_compare_op1 = tem;
996 pat = gen_sltu (operands[0]);
1005 if (gen_v9_scc (GTU, operands))
1011 (define_expand "sltu"
1012 [(set (match_operand:SI 0 "intreg_operand" "")
1013 (ltu:SI (match_dup 1) (const_int 0)))]
1019 if (gen_v9_scc (LTU, operands))
1022 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1025 (define_expand "sgeu"
1026 [(set (match_operand:SI 0 "intreg_operand" "")
1027 (geu:SI (match_dup 1) (const_int 0)))]
1033 if (gen_v9_scc (GEU, operands))
1036 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1039 (define_expand "sleu"
1040 [(set (match_operand:SI 0 "intreg_operand" "")
1041 (leu:SI (match_dup 1) (const_int 0)))]
1049 /* We can do geu easily, so if both operands are registers, swap them and
1051 if ((GET_CODE (sparc_compare_op0) == REG
1052 || GET_CODE (sparc_compare_op0) == SUBREG)
1053 && (GET_CODE (sparc_compare_op1) == REG
1054 || GET_CODE (sparc_compare_op1) == SUBREG))
1056 tem = sparc_compare_op0;
1057 sparc_compare_op0 = sparc_compare_op1;
1058 sparc_compare_op1 = tem;
1059 pat = gen_sgeu (operands[0]);
1060 if (pat == NULL_RTX)
1068 if (gen_v9_scc (LEU, operands))
1074 ;; Now the DEFINE_INSNs for the scc cases.
1076 ;; The SEQ and SNE patterns are special because they can be done
1077 ;; without any branching and do not involve a COMPARE. We want
1078 ;; them to always use the splitz below so the results can be
1081 (define_insn "*snesi_zero"
1082 [(set (match_operand:SI 0 "register_operand" "=r")
1083 (ne:SI (match_operand:SI 1 "register_operand" "r")
1085 (clobber (reg:CC 100))]
1088 [(set_attr "length" "2")])
1091 [(set (match_operand:SI 0 "register_operand" "")
1092 (ne:SI (match_operand:SI 1 "register_operand" "")
1094 (clobber (reg:CC 100))]
1096 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1098 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1101 (define_insn "*neg_snesi_zero"
1102 [(set (match_operand:SI 0 "register_operand" "=r")
1103 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1105 (clobber (reg:CC 100))]
1108 [(set_attr "length" "2")])
1111 [(set (match_operand:SI 0 "register_operand" "")
1112 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1114 (clobber (reg:CC 100))]
1116 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1118 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1121 (define_insn "*snesi_zero_extend"
1122 [(set (match_operand:DI 0 "register_operand" "=r")
1123 (ne:DI (match_operand:SI 1 "register_operand" "r")
1125 (clobber (reg:CC 100))]
1128 [(set_attr "type" "unary")
1129 (set_attr "length" "2")])
1132 [(set (match_operand:DI 0 "register_operand" "")
1133 (ne:DI (match_operand:SI 1 "register_operand" "")
1135 (clobber (reg:CC 100))]
1137 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1139 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1141 (ltu:SI (reg:CC_NOOV 100)
1145 (define_insn "*snedi_zero"
1146 [(set (match_operand:DI 0 "register_operand" "=&r")
1147 (ne:DI (match_operand:DI 1 "register_operand" "r")
1151 [(set_attr "type" "cmove")
1152 (set_attr "length" "2")])
1155 [(set (match_operand:DI 0 "register_operand" "")
1156 (ne:DI (match_operand:DI 1 "register_operand" "")
1159 [(set (match_dup 0) (const_int 0))
1160 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1166 (define_insn "*neg_snedi_zero"
1167 [(set (match_operand:DI 0 "register_operand" "=&r")
1168 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1172 [(set_attr "type" "cmove")
1173 (set_attr "length" "2")])
1176 [(set (match_operand:DI 0 "register_operand" "")
1177 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1180 [(set (match_dup 0) (const_int 0))
1181 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1187 (define_insn "*snedi_zero_trunc"
1188 [(set (match_operand:SI 0 "register_operand" "=&r")
1189 (ne:SI (match_operand:DI 1 "register_operand" "r")
1193 [(set_attr "type" "cmove")
1194 (set_attr "length" "2")])
1197 [(set (match_operand:SI 0 "register_operand" "")
1198 (ne:SI (match_operand:DI 1 "register_operand" "")
1201 [(set (match_dup 0) (const_int 0))
1202 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1208 (define_insn "*seqsi_zero"
1209 [(set (match_operand:SI 0 "register_operand" "=r")
1210 (eq:SI (match_operand:SI 1 "register_operand" "r")
1212 (clobber (reg:CC 100))]
1215 [(set_attr "length" "2")])
1218 [(set (match_operand:SI 0 "register_operand" "")
1219 (eq:SI (match_operand:SI 1 "register_operand" "")
1221 (clobber (reg:CC 100))]
1223 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1225 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1228 (define_insn "*neg_seqsi_zero"
1229 [(set (match_operand:SI 0 "register_operand" "=r")
1230 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1232 (clobber (reg:CC 100))]
1235 [(set_attr "length" "2")])
1238 [(set (match_operand:SI 0 "register_operand" "")
1239 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1241 (clobber (reg:CC 100))]
1243 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1245 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1248 (define_insn "*seqsi_zero_extend"
1249 [(set (match_operand:DI 0 "register_operand" "=r")
1250 (eq:DI (match_operand:SI 1 "register_operand" "r")
1252 (clobber (reg:CC 100))]
1255 [(set_attr "type" "unary")
1256 (set_attr "length" "2")])
1259 [(set (match_operand:DI 0 "register_operand" "")
1260 (eq:DI (match_operand:SI 1 "register_operand" "")
1262 (clobber (reg:CC 100))]
1264 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1266 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1268 (ltu:SI (reg:CC_NOOV 100)
1272 (define_insn "*seqdi_zero"
1273 [(set (match_operand:DI 0 "register_operand" "=&r")
1274 (eq:DI (match_operand:DI 1 "register_operand" "r")
1278 [(set_attr "type" "cmove")
1279 (set_attr "length" "2")])
1282 [(set (match_operand:DI 0 "register_operand" "")
1283 (eq:DI (match_operand:DI 1 "register_operand" "")
1286 [(set (match_dup 0) (const_int 0))
1287 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1293 (define_insn "*neg_seqdi_zero"
1294 [(set (match_operand:DI 0 "register_operand" "=&r")
1295 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1299 [(set_attr "type" "cmove")
1300 (set_attr "length" "2")])
1303 [(set (match_operand:DI 0 "register_operand" "")
1304 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1307 [(set (match_dup 0) (const_int 0))
1308 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1314 (define_insn "*seqdi_zero_trunc"
1315 [(set (match_operand:SI 0 "register_operand" "=&r")
1316 (eq:SI (match_operand:DI 1 "register_operand" "r")
1320 [(set_attr "type" "cmove")
1321 (set_attr "length" "2")])
1324 [(set (match_operand:SI 0 "register_operand" "")
1325 (eq:SI (match_operand:DI 1 "register_operand" "")
1328 [(set (match_dup 0) (const_int 0))
1329 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1335 ;; We can also do (x + (i == 0)) and related, so put them in.
1336 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1339 (define_insn "*x_plus_i_ne_0"
1340 [(set (match_operand:SI 0 "register_operand" "=r")
1341 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1343 (match_operand:SI 2 "register_operand" "r")))
1344 (clobber (reg:CC 100))]
1347 [(set_attr "length" "2")])
1350 [(set (match_operand:SI 0 "register_operand" "")
1351 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1353 (match_operand:SI 2 "register_operand" "")))
1354 (clobber (reg:CC 100))]
1356 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1358 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1362 (define_insn "*x_minus_i_ne_0"
1363 [(set (match_operand:SI 0 "register_operand" "=r")
1364 (minus:SI (match_operand:SI 2 "register_operand" "r")
1365 (ne:SI (match_operand:SI 1 "register_operand" "r")
1367 (clobber (reg:CC 100))]
1370 [(set_attr "length" "2")])
1373 [(set (match_operand:SI 0 "register_operand" "")
1374 (minus:SI (match_operand:SI 2 "register_operand" "")
1375 (ne:SI (match_operand:SI 1 "register_operand" "")
1377 (clobber (reg:CC 100))]
1379 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1381 (set (match_dup 0) (minus:SI (match_dup 2)
1382 (ltu:SI (reg:CC 100) (const_int 0))))]
1385 (define_insn "*x_plus_i_eq_0"
1386 [(set (match_operand:SI 0 "register_operand" "=r")
1387 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1389 (match_operand:SI 2 "register_operand" "r")))
1390 (clobber (reg:CC 100))]
1393 [(set_attr "length" "2")])
1396 [(set (match_operand:SI 0 "register_operand" "")
1397 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1399 (match_operand:SI 2 "register_operand" "")))
1400 (clobber (reg:CC 100))]
1402 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1404 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1408 (define_insn "*x_minus_i_eq_0"
1409 [(set (match_operand:SI 0 "register_operand" "=r")
1410 (minus:SI (match_operand:SI 2 "register_operand" "r")
1411 (eq:SI (match_operand:SI 1 "register_operand" "r")
1413 (clobber (reg:CC 100))]
1416 [(set_attr "length" "2")])
1419 [(set (match_operand:SI 0 "register_operand" "")
1420 (minus:SI (match_operand:SI 2 "register_operand" "")
1421 (eq:SI (match_operand:SI 1 "register_operand" "")
1423 (clobber (reg:CC 100))]
1425 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1427 (set (match_dup 0) (minus:SI (match_dup 2)
1428 (geu:SI (reg:CC 100) (const_int 0))))]
1431 ;; We can also do GEU and LTU directly, but these operate after a compare.
1432 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1435 (define_insn "*sltu_insn"
1436 [(set (match_operand:SI 0 "register_operand" "=r")
1437 (ltu:SI (reg:CC 100) (const_int 0)))]
1439 "addx\\t%%g0, 0, %0"
1440 [(set_attr "type" "misc")
1441 (set_attr "length" "1")])
1443 (define_insn "*neg_sltu_insn"
1444 [(set (match_operand:SI 0 "register_operand" "=r")
1445 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1447 "subx\\t%%g0, 0, %0"
1448 [(set_attr "type" "misc")
1449 (set_attr "length" "1")])
1451 ;; ??? Combine should canonicalize these next two to the same pattern.
1452 (define_insn "*neg_sltu_minus_x"
1453 [(set (match_operand:SI 0 "register_operand" "=r")
1454 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1455 (match_operand:SI 1 "arith_operand" "rI")))]
1457 "subx\\t%%g0, %1, %0"
1458 [(set_attr "type" "misc")
1459 (set_attr "length" "1")])
1461 (define_insn "*neg_sltu_plus_x"
1462 [(set (match_operand:SI 0 "register_operand" "=r")
1463 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1464 (match_operand:SI 1 "arith_operand" "rI"))))]
1466 "subx\\t%%g0, %1, %0"
1467 [(set_attr "type" "misc")
1468 (set_attr "length" "1")])
1470 (define_insn "*sgeu_insn"
1471 [(set (match_operand:SI 0 "register_operand" "=r")
1472 (geu:SI (reg:CC 100) (const_int 0)))]
1474 "subx\\t%%g0, -1, %0"
1475 [(set_attr "type" "misc")
1476 (set_attr "length" "1")])
1478 (define_insn "*neg_sgeu_insn"
1479 [(set (match_operand:SI 0 "register_operand" "=r")
1480 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1482 "addx\\t%%g0, -1, %0"
1483 [(set_attr "type" "misc")
1484 (set_attr "length" "1")])
1486 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1487 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1490 (define_insn "*sltu_plus_x"
1491 [(set (match_operand:SI 0 "register_operand" "=r")
1492 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1493 (match_operand:SI 1 "arith_operand" "rI")))]
1495 "addx\\t%%g0, %1, %0"
1496 [(set_attr "type" "misc")
1497 (set_attr "length" "1")])
1499 (define_insn "*sltu_plus_x_plus_y"
1500 [(set (match_operand:SI 0 "register_operand" "=r")
1501 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1502 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1503 (match_operand:SI 2 "arith_operand" "rI"))))]
1506 [(set_attr "type" "misc")
1507 (set_attr "length" "1")])
1509 (define_insn "*x_minus_sltu"
1510 [(set (match_operand:SI 0 "register_operand" "=r")
1511 (minus:SI (match_operand:SI 1 "register_operand" "r")
1512 (ltu:SI (reg:CC 100) (const_int 0))))]
1515 [(set_attr "type" "misc")
1516 (set_attr "length" "1")])
1518 ;; ??? Combine should canonicalize these next two to the same pattern.
1519 (define_insn "*x_minus_y_minus_sltu"
1520 [(set (match_operand:SI 0 "register_operand" "=r")
1521 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1522 (match_operand:SI 2 "arith_operand" "rI"))
1523 (ltu:SI (reg:CC 100) (const_int 0))))]
1525 "subx\\t%r1, %2, %0"
1526 [(set_attr "type" "misc")
1527 (set_attr "length" "1")])
1529 (define_insn "*x_minus_sltu_plus_y"
1530 [(set (match_operand:SI 0 "register_operand" "=r")
1531 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1532 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1533 (match_operand:SI 2 "arith_operand" "rI"))))]
1535 "subx\\t%r1, %2, %0"
1536 [(set_attr "type" "misc")
1537 (set_attr "length" "1")])
1539 (define_insn "*sgeu_plus_x"
1540 [(set (match_operand:SI 0 "register_operand" "=r")
1541 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1542 (match_operand:SI 1 "register_operand" "r")))]
1545 [(set_attr "type" "misc")
1546 (set_attr "length" "1")])
1548 (define_insn "*x_minus_sgeu"
1549 [(set (match_operand:SI 0 "register_operand" "=r")
1550 (minus:SI (match_operand:SI 1 "register_operand" "r")
1551 (geu:SI (reg:CC 100) (const_int 0))))]
1554 [(set_attr "type" "misc")
1555 (set_attr "length" "1")])
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (match_operator:SI 2 "noov_compare_op"
1560 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1562 ;; 32 bit LTU/GEU are better implemented using addx/subx
1563 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1564 && (GET_MODE (operands[1]) == CCXmode
1565 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1566 [(set (match_dup 0) (const_int 0))
1568 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1574 ;; These control RTL generation for conditional jump insns
1576 ;; The quad-word fp compare library routines all return nonzero to indicate
1577 ;; true, which is different from the equivalent libgcc routines, so we must
1578 ;; handle them specially here.
1580 (define_expand "beq"
1582 (if_then_else (eq (match_dup 1) (const_int 0))
1583 (label_ref (match_operand 0 "" ""))
1588 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1589 && GET_CODE (sparc_compare_op0) == REG
1590 && GET_MODE (sparc_compare_op0) == DImode)
1592 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1595 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1598 (define_expand "bne"
1600 (if_then_else (ne (match_dup 1) (const_int 0))
1601 (label_ref (match_operand 0 "" ""))
1606 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1607 && GET_CODE (sparc_compare_op0) == REG
1608 && GET_MODE (sparc_compare_op0) == DImode)
1610 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1613 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1616 (define_expand "bgt"
1618 (if_then_else (gt (match_dup 1) (const_int 0))
1619 (label_ref (match_operand 0 "" ""))
1624 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1625 && GET_CODE (sparc_compare_op0) == REG
1626 && GET_MODE (sparc_compare_op0) == DImode)
1628 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1631 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1634 (define_expand "bgtu"
1636 (if_then_else (gtu (match_dup 1) (const_int 0))
1637 (label_ref (match_operand 0 "" ""))
1641 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1644 (define_expand "blt"
1646 (if_then_else (lt (match_dup 1) (const_int 0))
1647 (label_ref (match_operand 0 "" ""))
1652 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1653 && GET_CODE (sparc_compare_op0) == REG
1654 && GET_MODE (sparc_compare_op0) == DImode)
1656 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1659 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1662 (define_expand "bltu"
1664 (if_then_else (ltu (match_dup 1) (const_int 0))
1665 (label_ref (match_operand 0 "" ""))
1669 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1672 (define_expand "bge"
1674 (if_then_else (ge (match_dup 1) (const_int 0))
1675 (label_ref (match_operand 0 "" ""))
1680 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1681 && GET_CODE (sparc_compare_op0) == REG
1682 && GET_MODE (sparc_compare_op0) == DImode)
1684 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1687 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1690 (define_expand "bgeu"
1692 (if_then_else (geu (match_dup 1) (const_int 0))
1693 (label_ref (match_operand 0 "" ""))
1697 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1700 (define_expand "ble"
1702 (if_then_else (le (match_dup 1) (const_int 0))
1703 (label_ref (match_operand 0 "" ""))
1708 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1709 && GET_CODE (sparc_compare_op0) == REG
1710 && GET_MODE (sparc_compare_op0) == DImode)
1712 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1715 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1718 (define_expand "bleu"
1720 (if_then_else (leu (match_dup 1) (const_int 0))
1721 (label_ref (match_operand 0 "" ""))
1725 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1728 ;; Now match both normal and inverted jump.
1730 ;; XXX fpcmp nop braindamage
1731 (define_insn "*normal_branch"
1733 (if_then_else (match_operator 0 "noov_compare_op"
1734 [(reg 100) (const_int 0)])
1735 (label_ref (match_operand 1 "" ""))
1740 return output_cbranch (operands[0], 1, 0,
1741 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1742 ! final_sequence, insn);
1744 [(set_attr "type" "branch")])
1746 ;; XXX fpcmp nop braindamage
1747 (define_insn "*inverted_branch"
1749 (if_then_else (match_operator 0 "noov_compare_op"
1750 [(reg 100) (const_int 0)])
1752 (label_ref (match_operand 1 "" ""))))]
1756 return output_cbranch (operands[0], 1, 1,
1757 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1758 ! final_sequence, insn);
1760 [(set_attr "type" "branch")])
1762 ;; XXX fpcmp nop braindamage
1763 (define_insn "*normal_fp_branch"
1765 (if_then_else (match_operator 1 "comparison_operator"
1766 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1768 (label_ref (match_operand 2 "" ""))
1773 return output_cbranch (operands[1], 2, 0,
1774 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1775 ! final_sequence, insn);
1777 [(set_attr "type" "branch")])
1779 ;; XXX fpcmp nop braindamage
1780 (define_insn "*inverted_fp_branch"
1782 (if_then_else (match_operator 1 "comparison_operator"
1783 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1786 (label_ref (match_operand 2 "" ""))))]
1790 return output_cbranch (operands[1], 2, 1,
1791 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1792 ! final_sequence, insn);
1794 [(set_attr "type" "branch")])
1796 ;; XXX fpcmp nop braindamage
1797 (define_insn "*normal_fpe_branch"
1799 (if_then_else (match_operator 1 "comparison_operator"
1800 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1802 (label_ref (match_operand 2 "" ""))
1807 return output_cbranch (operands[1], 2, 0,
1808 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1809 ! final_sequence, insn);
1811 [(set_attr "type" "branch")])
1813 ;; XXX fpcmp nop braindamage
1814 (define_insn "*inverted_fpe_branch"
1816 (if_then_else (match_operator 1 "comparison_operator"
1817 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1820 (label_ref (match_operand 2 "" ""))))]
1824 return output_cbranch (operands[1], 2, 1,
1825 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1826 ! final_sequence, insn);
1828 [(set_attr "type" "branch")])
1830 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1831 ;; in the architecture.
1833 ;; There are no 32 bit brreg insns.
1836 (define_insn "*normal_int_branch_sp64"
1838 (if_then_else (match_operator 0 "v9_regcmp_op"
1839 [(match_operand:DI 1 "register_operand" "r")
1841 (label_ref (match_operand 2 "" ""))
1846 return output_v9branch (operands[0], 1, 2, 0,
1847 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1848 ! final_sequence, insn);
1850 [(set_attr "type" "branch")])
1853 (define_insn "*inverted_int_branch_sp64"
1855 (if_then_else (match_operator 0 "v9_regcmp_op"
1856 [(match_operand:DI 1 "register_operand" "r")
1859 (label_ref (match_operand 2 "" ""))))]
1863 return output_v9branch (operands[0], 1, 2, 1,
1864 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1865 ! final_sequence, insn);
1867 [(set_attr "type" "branch")])
1869 ;; Load program counter insns.
1871 (define_insn "get_pc"
1872 [(clobber (reg:SI 15))
1873 (set (match_operand 0 "register_operand" "=r")
1874 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
1875 "flag_pic && REGNO (operands[0]) == 23"
1876 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
1877 [(set_attr "length" "3")])
1879 ;; Currently unused...
1880 ;; (define_insn "get_pc_via_rdpc"
1881 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
1884 ;; [(set_attr "type" "move")])
1887 ;; Move instructions
1889 (define_expand "movqi"
1890 [(set (match_operand:QI 0 "general_operand" "")
1891 (match_operand:QI 1 "general_operand" ""))]
1895 /* Working with CONST_INTs is easier, so convert
1896 a double if needed. */
1897 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1899 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
1901 else if (GET_CODE (operands[1]) == CONST_INT)
1903 /* And further, we know for all QI cases that only the
1904 low byte is significant, which we can always process
1905 in a single insn. So mask it now. */
1906 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
1909 /* Handle sets of MEM first. */
1910 if (GET_CODE (operands[0]) == MEM)
1912 /* This checks TARGET_LIVE_G0 for us. */
1913 if (reg_or_0_operand (operands[1], QImode))
1916 if (! reload_in_progress)
1918 operands[0] = validize_mem (operands[0]);
1919 operands[1] = force_reg (QImode, operands[1]);
1923 /* Fixup PIC cases. */
1926 if (CONSTANT_P (operands[1])
1927 && pic_address_needs_scratch (operands[1]))
1928 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1930 if (symbolic_operand (operands[1], QImode))
1932 operands[1] = legitimize_pic_address (operands[1],
1934 (reload_in_progress ?
1941 /* All QI constants require only one insn, so proceed. */
1947 (define_insn "*movqi_insn"
1948 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1949 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1950 "(register_operand (operands[0], QImode)
1951 || reg_or_0_operand (operands[1], QImode))"
1956 [(set_attr "type" "move,load,store")
1957 (set_attr "length" "1")])
1959 (define_expand "movhi"
1960 [(set (match_operand:HI 0 "general_operand" "")
1961 (match_operand:HI 1 "general_operand" ""))]
1965 /* Working with CONST_INTs is easier, so convert
1966 a double if needed. */
1967 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1968 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1970 /* Handle sets of MEM first. */
1971 if (GET_CODE (operands[0]) == MEM)
1973 /* This checks TARGET_LIVE_G0 for us. */
1974 if (reg_or_0_operand (operands[1], HImode))
1977 if (! reload_in_progress)
1979 operands[0] = validize_mem (operands[0]);
1980 operands[1] = force_reg (HImode, operands[1]);
1984 /* Fixup PIC cases. */
1987 if (CONSTANT_P (operands[1])
1988 && pic_address_needs_scratch (operands[1]))
1989 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1991 if (symbolic_operand (operands[1], HImode))
1993 operands[1] = legitimize_pic_address (operands[1],
1995 (reload_in_progress ?
2002 /* This makes sure we will not get rematched due to splittage. */
2003 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2005 else if (CONSTANT_P (operands[1])
2006 && GET_CODE (operands[1]) != HIGH
2007 && GET_CODE (operands[1]) != LO_SUM)
2009 sparc_emit_set_const32 (operands[0], operands[1]);
2016 (define_insn "*movhi_const64_special"
2017 [(set (match_operand:HI 0 "register_operand" "=r")
2018 (match_operand:HI 1 "const64_high_operand" ""))]
2020 "sethi\\t%%hi(%a1), %0"
2021 [(set_attr "type" "move")
2022 (set_attr "length" "1")])
2024 (define_insn "*movhi_insn"
2025 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2026 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2027 "(register_operand (operands[0], HImode)
2028 || reg_or_0_operand (operands[1], HImode))"
2031 sethi\\t%%hi(%a1), %0
2034 [(set_attr "type" "move,move,load,store")
2035 (set_attr "length" "1")])
2037 ;; We always work with constants here.
2038 (define_insn "*movhi_lo_sum"
2039 [(set (match_operand:HI 0 "register_operand" "=r")
2040 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2041 (match_operand:HI 2 "arith_operand" "I")))]
2044 [(set_attr "type" "ialu")
2045 (set_attr "length" "1")])
2047 (define_expand "movsi"
2048 [(set (match_operand:SI 0 "general_operand" "")
2049 (match_operand:SI 1 "general_operand" ""))]
2053 /* Working with CONST_INTs is easier, so convert
2054 a double if needed. */
2055 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2056 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2058 /* Handle sets of MEM first. */
2059 if (GET_CODE (operands[0]) == MEM)
2061 /* This checks TARGET_LIVE_G0 for us. */
2062 if (reg_or_0_operand (operands[1], SImode))
2065 if (! reload_in_progress)
2067 operands[0] = validize_mem (operands[0]);
2068 operands[1] = force_reg (SImode, operands[1]);
2072 /* Fixup PIC cases. */
2075 if (CONSTANT_P (operands[1])
2076 && pic_address_needs_scratch (operands[1]))
2077 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2079 if (GET_CODE (operands[1]) == LABEL_REF)
2082 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2086 if (symbolic_operand (operands[1], SImode))
2088 operands[1] = legitimize_pic_address (operands[1],
2090 (reload_in_progress ?
2097 /* If we are trying to toss an integer constant into the
2098 FPU registers, force it into memory. */
2099 if (GET_CODE (operands[0]) == REG
2100 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2101 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2102 && CONSTANT_P (operands[1]))
2103 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2106 /* This makes sure we will not get rematched due to splittage. */
2107 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2109 else if (CONSTANT_P (operands[1])
2110 && GET_CODE (operands[1]) != HIGH
2111 && GET_CODE (operands[1]) != LO_SUM)
2113 sparc_emit_set_const32 (operands[0], operands[1]);
2120 ;; Special LIVE_G0 pattern to obtain zero in a register.
2121 (define_insn "*movsi_zero_liveg0"
2122 [(set (match_operand:SI 0 "register_operand" "=r")
2123 (match_operand:SI 1 "zero_operand" "J"))]
2126 [(set_attr "type" "binary")
2127 (set_attr "length" "1")])
2129 ;; This is needed to show CSE exactly which bits are set
2130 ;; in a 64-bit register by sethi instructions.
2131 (define_insn "*movsi_const64_special"
2132 [(set (match_operand:SI 0 "register_operand" "=r")
2133 (match_operand:SI 1 "const64_high_operand" ""))]
2135 "sethi\\t%%hi(%a1), %0"
2136 [(set_attr "type" "move")
2137 (set_attr "length" "1")])
2139 (define_insn "*movsi_insn"
2140 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2141 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2142 "(register_operand (operands[0], SImode)
2143 || reg_or_0_operand (operands[1], SImode))"
2147 sethi\\t%%hi(%a1), %0
2154 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2155 (set_attr "length" "1")])
2157 (define_insn "*movsi_lo_sum"
2158 [(set (match_operand:SI 0 "register_operand" "=r")
2159 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2160 (match_operand:SI 2 "immediate_operand" "in")))]
2162 "or\\t%1, %%lo(%a2), %0"
2163 [(set_attr "type" "ialu")
2164 (set_attr "length" "1")])
2166 (define_insn "*movsi_high"
2167 [(set (match_operand:SI 0 "register_operand" "=r")
2168 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2170 "sethi\\t%%hi(%a1), %0"
2171 [(set_attr "type" "move")
2172 (set_attr "length" "1")])
2174 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2175 ;; so that CSE won't optimize the address computation away.
2176 (define_insn "movsi_lo_sum_pic"
2177 [(set (match_operand:SI 0 "register_operand" "=r")
2178 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2179 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2181 "or\\t%1, %%lo(%a2), %0"
2182 [(set_attr "type" "ialu")
2183 (set_attr "length" "1")])
2185 (define_insn "movsi_high_pic"
2186 [(set (match_operand:SI 0 "register_operand" "=r")
2187 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2188 "flag_pic && check_pic (1)"
2189 "sethi\\t%%hi(%a1), %0"
2190 [(set_attr "type" "move")
2191 (set_attr "length" "1")])
2193 (define_expand "movsi_pic_label_ref"
2194 [(set (match_dup 3) (high:SI
2195 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2197 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2198 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2199 (set (match_operand:SI 0 "register_operand" "=r")
2200 (minus:SI (match_dup 5) (match_dup 4)))]
2204 current_function_uses_pic_offset_table = 1;
2205 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2206 operands[3] = gen_reg_rtx (SImode);
2207 operands[4] = gen_reg_rtx (SImode);
2208 operands[5] = pic_offset_table_rtx;
2211 (define_insn "*movsi_high_pic_label_ref"
2212 [(set (match_operand:SI 0 "register_operand" "=r")
2214 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2215 (match_operand:SI 2 "" "")] 5)))]
2217 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2218 [(set_attr "type" "move")
2219 (set_attr "length" "1")])
2221 (define_insn "*movsi_lo_sum_pic_label_ref"
2222 [(set (match_operand:SI 0 "register_operand" "=r")
2223 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2224 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2225 (match_operand:SI 3 "" "")] 5)))]
2227 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2228 [(set_attr "type" "ialu")
2229 (set_attr "length" "1")])
2231 (define_expand "movdi"
2232 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2233 (match_operand:DI 1 "general_operand" ""))]
2237 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2238 if (GET_CODE (operands[1]) == CONST_DOUBLE
2239 #if HOST_BITS_PER_WIDE_INT == 32
2240 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2241 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2242 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2243 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2246 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2248 /* Handle MEM cases first. */
2249 if (GET_CODE (operands[0]) == MEM)
2251 /* If it's a REG, we can always do it.
2252 The const zero case is more complex, on v9
2253 we can always perform it. */
2254 if (register_operand (operands[1], DImode)
2256 && (operands[1] == const0_rtx)))
2259 if (! reload_in_progress)
2261 operands[0] = validize_mem (operands[0]);
2262 operands[1] = force_reg (DImode, operands[1]);
2268 if (CONSTANT_P (operands[1])
2269 && pic_address_needs_scratch (operands[1]))
2270 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2272 if (GET_CODE (operands[1]) == LABEL_REF)
2274 if (! TARGET_ARCH64)
2276 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2280 if (symbolic_operand (operands[1], DImode))
2282 operands[1] = legitimize_pic_address (operands[1],
2284 (reload_in_progress ?
2291 /* If we are trying to toss an integer constant into the
2292 FPU registers, force it into memory. */
2293 if (GET_CODE (operands[0]) == REG
2294 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2295 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2296 && CONSTANT_P (operands[1]))
2297 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2300 /* This makes sure we will not get rematched due to splittage. */
2301 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2303 else if (TARGET_ARCH64
2304 && CONSTANT_P (operands[1])
2305 && GET_CODE (operands[1]) != HIGH
2306 && GET_CODE (operands[1]) != LO_SUM)
2308 sparc_emit_set_const64 (operands[0], operands[1]);
2316 ;; Be careful, fmovd does not exist when !arch64.
2317 ;; We match MEM moves directly when we have correct even
2318 ;; numbered registers, but fall into splits otherwise.
2319 ;; The constraint ordering here is really important to
2320 ;; avoid insane problems in reload, especially for patterns
2323 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2324 ;; (const_int -5016)))
2327 (define_insn "*movdi_insn_sp32"
2328 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2329 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2331 (register_operand (operands[0], DImode)
2332 || register_operand (operands[1], DImode))"
2345 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2346 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2348 ;; The following are generated by sparc_emit_set_const64
2349 (define_insn "*movdi_sp64_dbl"
2350 [(set (match_operand:DI 0 "register_operand" "=r")
2351 (match_operand:DI 1 "const64_operand" ""))]
2353 && HOST_BITS_PER_WIDE_INT != 64)"
2355 [(set_attr "type" "move")
2356 (set_attr "length" "1")])
2358 ;; This is needed to show CSE exactly which bits are set
2359 ;; in a 64-bit register by sethi instructions.
2360 (define_insn "*movdi_const64_special"
2361 [(set (match_operand:DI 0 "register_operand" "=r")
2362 (match_operand:DI 1 "const64_high_operand" ""))]
2364 "sethi\\t%%hi(%a1), %0"
2365 [(set_attr "type" "move")
2366 (set_attr "length" "1")])
2368 (define_insn "*movdi_insn_sp64"
2369 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2370 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2372 (register_operand (operands[0], DImode)
2373 || reg_or_0_operand (operands[1], DImode))"
2376 sethi\\t%%hi(%a1), %0
2384 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove")
2385 (set_attr "length" "1")])
2387 (define_expand "movdi_pic_label_ref"
2388 [(set (match_dup 3) (high:DI
2389 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2391 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2392 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2393 (set (match_operand:DI 0 "register_operand" "=r")
2394 (minus:DI (match_dup 5) (match_dup 4)))]
2395 "TARGET_ARCH64 && flag_pic"
2398 current_function_uses_pic_offset_table = 1;
2399 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2400 operands[3] = gen_reg_rtx (DImode);
2401 operands[4] = gen_reg_rtx (DImode);
2402 operands[5] = pic_offset_table_rtx;
2405 (define_insn "*movdi_high_pic_label_ref"
2406 [(set (match_operand:DI 0 "register_operand" "=r")
2408 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2409 (match_operand:DI 2 "" "")] 5)))]
2410 "TARGET_ARCH64 && flag_pic"
2411 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2412 [(set_attr "type" "move")
2413 (set_attr "length" "1")])
2415 (define_insn "*movdi_lo_sum_pic_label_ref"
2416 [(set (match_operand:DI 0 "register_operand" "=r")
2417 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2418 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2419 (match_operand:DI 3 "" "")] 5)))]
2420 "TARGET_ARCH64 && flag_pic"
2421 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2422 [(set_attr "type" "ialu")
2423 (set_attr "length" "1")])
2425 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2426 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2428 (define_insn "movdi_lo_sum_pic"
2429 [(set (match_operand:DI 0 "register_operand" "=r")
2430 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2431 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2432 "TARGET_ARCH64 && flag_pic"
2433 "or\\t%1, %%lo(%a2), %0"
2434 [(set_attr "type" "ialu")
2435 (set_attr "length" "1")])
2437 (define_insn "movdi_high_pic"
2438 [(set (match_operand:DI 0 "register_operand" "=r")
2439 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2440 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2441 "sethi\\t%%hi(%a1), %0"
2442 [(set_attr "type" "move")
2443 (set_attr "length" "1")])
2445 (define_insn "*sethi_di_medlow_embmedany_pic"
2446 [(set (match_operand:DI 0 "register_operand" "=r")
2447 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))
2448 ;; The clobber is here because emit_move_sequence assumes the worst case.
2449 (clobber (reg:DI 1))]
2450 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2451 "sethi\\t%%hi(%a1), %0"
2452 [(set_attr "type" "move")
2453 (set_attr "length" "1")])
2455 (define_insn "*sethi_di_medlow"
2456 [(set (match_operand:DI 0 "register_operand" "=r")
2457 (high:DI (match_operand:DI 1 "symbolic_operand" "")))
2458 ;; The clobber is here because emit_move_sequence assumes the worst case.
2459 (clobber (reg:DI 1))]
2460 "TARGET_CM_MEDLOW && check_pic (1)"
2461 "sethi\\t%%hi(%a1), %0"
2462 [(set_attr "type" "move")
2463 (set_attr "length" "1")])
2465 (define_insn "*losum_di_medlow"
2466 [(set (match_operand:DI 0 "register_operand" "=r")
2467 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2468 (match_operand:DI 2 "symbolic_operand" "")))]
2470 "or\\t%1, %%lo(%a2), %0"
2471 [(set_attr "type" "ialu")
2472 (set_attr "length" "1")])
2474 (define_insn "seth44"
2475 [(set (match_operand:DI 0 "register_operand" "=r")
2476 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2478 "sethi\\t%%h44(%a1), %0"
2479 [(set_attr "type" "move")
2480 (set_attr "length" "1")])
2482 (define_insn "setm44"
2483 [(set (match_operand:DI 0 "register_operand" "=r")
2484 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2485 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2487 "or\\t%1, %%m44(%a2), %0"
2488 [(set_attr "type" "move")
2489 (set_attr "length" "1")])
2491 (define_insn "setl44"
2492 [(set (match_operand:DI 0 "register_operand" "=r")
2493 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2494 (match_operand:DI 2 "symbolic_operand" "")))]
2496 "or\\t%1, %%l44(%a2), %0"
2497 [(set_attr "type" "ialu")
2498 (set_attr "length" "1")])
2500 (define_insn "sethh"
2501 [(set (match_operand:DI 0 "register_operand" "=r")
2502 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2504 "sethi\\t%%hh(%a1), %0"
2505 [(set_attr "type" "move")
2506 (set_attr "length" "1")])
2508 (define_insn "setlm"
2509 [(set (match_operand:DI 0 "register_operand" "=r")
2510 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2512 "sethi\\t%%lm(%a1), %0"
2513 [(set_attr "type" "move")
2514 (set_attr "length" "1")])
2516 (define_insn "sethm"
2517 [(set (match_operand:DI 0 "register_operand" "=r")
2518 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2519 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2521 "or\\t%1, %%hm(%a2), %0"
2522 [(set_attr "type" "ialu")
2523 (set_attr "length" "1")])
2525 (define_insn "setlo"
2526 [(set (match_operand:DI 0 "register_operand" "=r")
2527 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2528 (match_operand:DI 2 "symbolic_operand" "")))]
2530 "or\\t%1, %%lo(%a2), %0"
2531 [(set_attr "type" "ialu")
2532 (set_attr "length" "1")])
2534 (define_insn "embmedany_sethi"
2535 [(set (match_operand:DI 0 "register_operand" "=r")
2536 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2537 "TARGET_CM_EMBMEDANY && check_pic (1)"
2538 "sethi\\t%%hi(%a1), %0"
2539 [(set_attr "type" "move")
2540 (set_attr "length" "1")])
2542 (define_insn "embmedany_losum"
2543 [(set (match_operand:DI 0 "register_operand" "=r")
2544 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2545 (match_operand:DI 2 "data_segment_operand" "")))]
2546 "TARGET_CM_EMBMEDANY"
2547 "add\\t%1, %%lo(%a2), %0"
2548 [(set_attr "type" "ialu")
2549 (set_attr "length" "1")])
2551 (define_insn "embmedany_brsum"
2552 [(set (match_operand:DI 0 "register_operand" "=r")
2553 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2554 "TARGET_CM_EMBMEDANY"
2556 [(set_attr "length" "1")])
2558 (define_insn "embmedany_textuhi"
2559 [(set (match_operand:DI 0 "register_operand" "=r")
2560 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2561 "TARGET_CM_EMBMEDANY && check_pic (1)"
2562 "sethi\\t%%uhi(%a1), %0"
2563 [(set_attr "type" "move")
2564 (set_attr "length" "1")])
2566 (define_insn "embmedany_texthi"
2567 [(set (match_operand:DI 0 "register_operand" "=r")
2568 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2569 "TARGET_CM_EMBMEDANY && check_pic (1)"
2570 "sethi\\t%%hi(%a1), %0"
2571 [(set_attr "type" "move")
2572 (set_attr "length" "1")])
2574 (define_insn "embmedany_textulo"
2575 [(set (match_operand:DI 0 "register_operand" "=r")
2576 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2577 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2578 "TARGET_CM_EMBMEDANY"
2579 "or\\t%1, %%ulo(%a2), %0"
2580 [(set_attr "type" "ialu")
2581 (set_attr "length" "1")])
2583 (define_insn "embmedany_textlo"
2584 [(set (match_operand:DI 0 "register_operand" "=r")
2585 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2586 (match_operand:DI 2 "text_segment_operand" "")))]
2587 "TARGET_CM_EMBMEDANY"
2588 "or\\t%1, %%lo(%a2), %0"
2589 [(set_attr "type" "ialu")
2590 (set_attr "length" "1")])
2592 ;; Now some patterns to help reload out a bit.
2593 (define_expand "reload_indi"
2594 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2595 (match_operand:DI 1 "immediate_operand" "")
2596 (match_operand:TI 2 "register_operand" "=&r")])]
2598 || TARGET_CM_EMBMEDANY)
2602 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2603 gen_rtx_REG (DImode, REGNO (operands[2])));
2607 (define_expand "reload_outdi"
2608 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2609 (match_operand:DI 1 "immediate_operand" "")
2610 (match_operand:TI 2 "register_operand" "=&r")])]
2612 || TARGET_CM_EMBMEDANY)
2616 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2617 gen_rtx_REG (DImode, REGNO (operands[2])));
2621 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2623 [(set (match_operand:DI 0 "register_operand" "")
2624 (match_operand:DI 1 "const_int_operand" ""))]
2625 "! TARGET_ARCH64 && reload_completed"
2626 [(clobber (const_int 0))]
2629 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2630 (INTVAL (operands[1]) < 0) ?
2633 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2639 [(set (match_operand:DI 0 "register_operand" "")
2640 (match_operand:DI 1 "const_double_operand" ""))]
2641 "! TARGET_ARCH64 && reload_completed"
2642 [(clobber (const_int 0))]
2645 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2646 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2648 /* Slick... but this trick loses if this subreg constant part
2649 can be done in one insn. */
2650 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2651 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2652 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2654 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2655 gen_highpart (SImode, operands[0])));
2659 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2660 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2666 [(set (match_operand:DI 0 "register_operand" "")
2667 (match_operand:DI 1 "register_operand" ""))]
2668 "! TARGET_ARCH64 && reload_completed"
2669 [(clobber (const_int 0))]
2672 rtx set_dest = operands[0];
2673 rtx set_src = operands[1];
2677 if (GET_CODE (set_dest) == SUBREG)
2678 set_dest = alter_subreg (set_dest);
2679 if (GET_CODE (set_src) == SUBREG)
2680 set_src = alter_subreg (set_src);
2682 dest1 = gen_highpart (SImode, set_dest);
2683 dest2 = gen_lowpart (SImode, set_dest);
2684 src1 = gen_highpart (SImode, set_src);
2685 src2 = gen_lowpart (SImode, set_src);
2687 /* Now emit using the real source and destination we found, swapping
2688 the order if we detect overlap. */
2689 if (reg_overlap_mentioned_p (dest1, src2))
2691 emit_insn (gen_movsi (dest2, src2));
2692 emit_insn (gen_movsi (dest1, src1));
2696 emit_insn (gen_movsi (dest1, src1));
2697 emit_insn (gen_movsi (dest2, src2));
2702 ;; Now handle the cases of memory moves from/to non-even
2703 ;; DI mode register pairs.
2705 [(set (match_operand:DI 0 "register_operand" "")
2706 (match_operand:DI 1 "memory_operand" ""))]
2709 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2710 [(clobber (const_int 0))]
2713 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2714 rtx word1 = change_address (operands[1], SImode,
2715 plus_constant_for_output (XEXP (word0, 0), 4));
2716 rtx high_part = gen_highpart (SImode, operands[0]);
2717 rtx low_part = gen_lowpart (SImode, operands[0]);
2719 if (reg_overlap_mentioned_p (high_part, word1))
2721 emit_insn (gen_movsi (low_part, word1));
2722 emit_insn (gen_movsi (high_part, word0));
2726 emit_insn (gen_movsi (high_part, word0));
2727 emit_insn (gen_movsi (low_part, word1));
2733 [(set (match_operand:DI 0 "memory_operand" "")
2734 (match_operand:DI 1 "register_operand" ""))]
2737 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2738 [(clobber (const_int 0))]
2741 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2742 rtx word1 = change_address (operands[0], SImode,
2743 plus_constant_for_output (XEXP (word0, 0), 4));
2744 rtx high_part = gen_highpart (SImode, operands[1]);
2745 rtx low_part = gen_lowpart (SImode, operands[1]);
2747 emit_insn (gen_movsi (word0, high_part));
2748 emit_insn (gen_movsi (word1, low_part));
2753 ;; Floating point move insns
2755 (define_insn "*clear_sf"
2756 [(set (match_operand:SF 0 "register_operand" "=f")
2757 (match_operand:SF 1 "" ""))]
2759 && GET_CODE (operands[1]) == CONST_DOUBLE
2760 && GET_CODE (operands[0]) == REG
2761 && fp_zero_operand (operands[1])"
2763 [(set_attr "type" "fpmove")
2764 (set_attr "length" "1")])
2766 (define_insn "*movsf_const_intreg"
2767 [(set (match_operand:SF 0 "register_operand" "=f,r")
2768 (match_operand:SF 1 "const_double_operand" "m,F"))]
2775 if (which_alternative == 0)
2776 return \"ld\\t%1, %0\";
2778 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2779 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2780 if (SPARC_SIMM13_P (i) || SPARC_SETHI_P (i))
2782 operands[1] = GEN_INT (i);
2783 if (SPARC_SIMM13_P (INTVAL (operands[1])))
2784 return \"mov\\t%1, %0\";
2785 else if (SPARC_SETHI_P (INTVAL (operands[1])))
2786 return \"sethi\\t%%hi(%a1), %0\";
2793 [(set_attr "type" "move")
2794 (set_attr "length" "1,2")])
2796 ;; There isn't much I can do about this, if I change the
2797 ;; mode then flow info gets really confused because the
2798 ;; destination no longer looks the same. Ho hum...
2799 (define_insn "*movsf_const_high"
2800 [(set (match_operand:SF 0 "register_operand" "=r")
2801 (unspec:SF [(match_operand 1 "const_int_operand" "")] 12))]
2803 "sethi\\t%%hi(%a1), %0"
2804 [(set_attr "type" "move")
2805 (set_attr "length" "1")])
2807 (define_insn "*movsf_const_lo"
2808 [(set (match_operand:SF 0 "register_operand" "=r")
2809 (unspec:SF [(match_operand:SF 1 "register_operand" "r")
2810 (match_operand 2 "const_int_operand" "")] 17))]
2812 "or\\t%1, %%lo(%a2), %0"
2813 [(set_attr "type" "move")
2814 (set_attr "length" "1")])
2817 [(set (match_operand:SF 0 "register_operand" "")
2818 (match_operand:SF 1 "const_double_operand" ""))]
2820 && (GET_CODE (operands[0]) == REG
2821 && REGNO (operands[0]) < 32)"
2822 [(set (match_dup 0) (unspec:SF [(match_dup 1)] 12))
2823 (set (match_dup 0) (unspec:SF [(match_dup 0) (match_dup 1)] 17))]
2829 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2830 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2831 operands[1] = GEN_INT (i);
2834 (define_expand "movsf"
2835 [(set (match_operand:SF 0 "general_operand" "")
2836 (match_operand:SF 1 "general_operand" ""))]
2840 /* Force SFmode constants into memory. */
2841 if (GET_CODE (operands[0]) == REG
2842 && CONSTANT_P (operands[1]))
2845 && GET_CODE (operands[1]) == CONST_DOUBLE
2846 && fp_zero_operand (operands[1]))
2849 /* emit_group_store will send such bogosity to us when it is
2850 not storing directly into memory. So fix this up to avoid
2851 crashes in output_constant_pool. */
2852 if (operands [1] == const0_rtx)
2853 operands[1] = CONST0_RTX (SFmode);
2854 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2858 /* Handle sets of MEM first. */
2859 if (GET_CODE (operands[0]) == MEM)
2861 if (register_operand (operands[1], SFmode))
2864 if (! reload_in_progress)
2866 operands[0] = validize_mem (operands[0]);
2867 operands[1] = force_reg (SFmode, operands[1]);
2871 /* Fixup PIC cases. */
2874 if (CONSTANT_P (operands[1])
2875 && pic_address_needs_scratch (operands[1]))
2876 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2878 if (symbolic_operand (operands[1], SFmode))
2880 operands[1] = legitimize_pic_address (operands[1],
2882 (reload_in_progress ?
2892 (define_insn "*movsf_insn"
2893 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,r,r,m")
2894 (match_operand:SF 1 "input_operand" "f,m,f,r,m,r"))]
2896 && (register_operand (operands[0], SFmode)
2897 || register_operand (operands[1], SFmode))"
2905 [(set_attr "type" "fpmove,fpload,fpstore,move,load,store")
2906 (set_attr "length" "1")])
2908 ;; Exactly the same as above, except that all `f' cases are deleted.
2909 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2912 (define_insn "*movsf_no_f_insn"
2913 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
2914 (match_operand:SF 1 "input_operand" "r,m,r"))]
2916 && (register_operand (operands[0], SFmode)
2917 || register_operand (operands[1], SFmode))"
2922 [(set_attr "type" "move,load,store")
2923 (set_attr "length" "1")])
2925 (define_insn "*clear_df"
2926 [(set (match_operand:DF 0 "register_operand" "=e")
2927 (match_operand:DF 1 "const_double_operand" ""))]
2929 && fp_zero_operand (operands[1])"
2931 [(set_attr "type" "fpmove")
2932 (set_attr "length" "1")])
2934 (define_insn "*movdf_const_intreg_sp32"
2935 [(set (match_operand:DF 0 "register_operand" "=e,e,r")
2936 (match_operand:DF 1 "const_double_operand" "T,o,F"))]
2937 "TARGET_FPU && ! TARGET_ARCH64"
2942 [(set_attr "type" "move")
2943 (set_attr "length" "1,2,2")])
2945 ;; Now that we redo life analysis with a clean slate after
2946 ;; instruction splitting for sched2 this can work.
2947 (define_insn "*movdf_const_intreg_sp64"
2948 [(set (match_operand:DF 0 "register_operand" "=e,r")
2949 (match_operand:DF 1 "const_double_operand" "m,F"))]
2950 "TARGET_FPU && TARGET_ARCH64"
2954 [(set_attr "type" "move")
2955 (set_attr "length" "1,2")])
2958 [(set (match_operand:DF 0 "register_operand" "")
2959 (match_operand:DF 1 "const_double_operand" ""))]
2961 && (GET_CODE (operands[0]) == REG
2962 && REGNO (operands[0]) < 32)
2963 && reload_completed"
2964 [(clobber (const_int 0))]
2970 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2971 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2972 if (GET_CODE (operands[0]) == SUBREG)
2973 operands[0] = alter_subreg (operands[0]);
2974 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2978 #if HOST_BITS_PER_WIDE_INT == 64
2981 val = ((HOST_WIDE_INT)l[1] |
2982 ((HOST_WIDE_INT)l[0] << 32));
2983 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
2985 emit_insn (gen_movdi (operands[0],
2986 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
2992 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2995 /* Slick... but this trick loses if this subreg constant part
2996 can be done in one insn. */
2998 && !(SPARC_SETHI_P (l[0])
2999 || SPARC_SIMM13_P (l[0])))
3001 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3002 gen_highpart (SImode, operands[0])));
3006 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3013 (define_expand "movdf"
3014 [(set (match_operand:DF 0 "general_operand" "")
3015 (match_operand:DF 1 "general_operand" ""))]
3019 /* Force DFmode constants into memory. */
3020 if (GET_CODE (operands[0]) == REG
3021 && CONSTANT_P (operands[1]))
3024 && GET_CODE (operands[1]) == CONST_DOUBLE
3025 && fp_zero_operand (operands[1]))
3028 /* emit_group_store will send such bogosity to us when it is
3029 not storing directly into memory. So fix this up to avoid
3030 crashes in output_constant_pool. */
3031 if (operands [1] == const0_rtx)
3032 operands[1] = CONST0_RTX (DFmode);
3033 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3037 /* Handle MEM cases first. */
3038 if (GET_CODE (operands[0]) == MEM)
3040 if (register_operand (operands[1], DFmode))
3043 if (! reload_in_progress)
3045 operands[0] = validize_mem (operands[0]);
3046 operands[1] = force_reg (DFmode, operands[1]);
3050 /* Fixup PIC cases. */
3053 if (CONSTANT_P (operands[1])
3054 && pic_address_needs_scratch (operands[1]))
3055 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3057 if (symbolic_operand (operands[1], DFmode))
3059 operands[1] = legitimize_pic_address (operands[1],
3061 (reload_in_progress ?
3071 ;; Be careful, fmovd does not exist when !v9.
3072 (define_insn "*movdf_insn_sp32"
3073 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,e,r,r,o,e,o")
3074 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3077 && (register_operand (operands[0], DFmode)
3078 || register_operand (operands[1], DFmode))"
3090 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3091 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3093 (define_insn "*movdf_no_e_insn_sp32"
3094 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,r,r,o")
3095 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3098 && (register_operand (operands[0], DFmode)
3099 || register_operand (operands[1], DFmode))"
3106 [(set_attr "type" "load,store,*,*,*")
3107 (set_attr "length" "1,1,2,2,2")])
3109 ;; We have available v9 double floats but not 64-bit
3110 ;; integer registers.
3111 (define_insn "*movdf_insn_v9only"
3112 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o")
3113 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3117 && (register_operand (operands[0], DFmode)
3118 || register_operand (operands[1], DFmode))"
3128 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3129 (set_attr "length" "1,1,1,1,1,2,2,2")])
3131 ;; We have available both v9 double floats and 64-bit
3132 ;; integer registers.
3133 (define_insn "*movdf_insn_sp64"
3134 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,r,r,m")
3135 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3139 && (register_operand (operands[0], DFmode)
3140 || register_operand (operands[1], DFmode))"
3148 [(set_attr "type" "fpmove,load,store,move,load,store")
3149 (set_attr "length" "1")])
3151 (define_insn "*movdf_no_e_insn_sp64"
3152 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3153 (match_operand:DF 1 "input_operand" "r,m,r"))]
3156 && (register_operand (operands[0], DFmode)
3157 || register_operand (operands[1], DFmode))"
3162 [(set_attr "type" "move,load,store")
3163 (set_attr "length" "1")])
3165 ;; Ok, now the splits to handle all the multi insn and
3166 ;; mis-aligned memory address cases.
3167 ;; In these splits please take note that we must be
3168 ;; careful when V9 but not ARCH64 because the integer
3169 ;; register DFmode cases must be handled.
3171 [(set (match_operand:DF 0 "register_operand" "")
3172 (match_operand:DF 1 "register_operand" ""))]
3175 && ((GET_CODE (operands[0]) == REG
3176 && REGNO (operands[0]) < 32)
3177 || (GET_CODE (operands[0]) == SUBREG
3178 && GET_CODE (SUBREG_REG (operands[0])) == REG
3179 && REGNO (SUBREG_REG (operands[0])) < 32))))
3180 && reload_completed"
3181 [(clobber (const_int 0))]
3184 rtx set_dest = operands[0];
3185 rtx set_src = operands[1];
3189 if (GET_CODE (set_dest) == SUBREG)
3190 set_dest = alter_subreg (set_dest);
3191 if (GET_CODE (set_src) == SUBREG)
3192 set_src = alter_subreg (set_src);
3194 dest1 = gen_highpart (SFmode, set_dest);
3195 dest2 = gen_lowpart (SFmode, set_dest);
3196 src1 = gen_highpart (SFmode, set_src);
3197 src2 = gen_lowpart (SFmode, set_src);
3199 /* Now emit using the real source and destination we found, swapping
3200 the order if we detect overlap. */
3201 if (reg_overlap_mentioned_p (dest1, src2))
3203 emit_insn (gen_movsf (dest2, src2));
3204 emit_insn (gen_movsf (dest1, src1));
3208 emit_insn (gen_movsf (dest1, src1));
3209 emit_insn (gen_movsf (dest2, src2));
3215 [(set (match_operand:DF 0 "register_operand" "")
3216 (match_operand:DF 1 "memory_operand" ""))]
3219 && ((GET_CODE (operands[0]) == REG
3220 && REGNO (operands[0]) < 32)
3221 || (GET_CODE (operands[0]) == SUBREG
3222 && GET_CODE (SUBREG_REG (operands[0])) == REG
3223 && REGNO (SUBREG_REG (operands[0])) < 32))))
3224 && (reload_completed
3225 && (((REGNO (operands[0])) % 2) != 0
3226 || ! mem_min_alignment (operands[1], 8))
3227 && offsettable_memref_p (operands[1])))"
3228 [(clobber (const_int 0))]
3231 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3232 rtx word1 = change_address (operands[1], SFmode,
3233 plus_constant_for_output (XEXP (word0, 0), 4));
3235 if (GET_CODE (operands[0]) == SUBREG)
3236 operands[0] = alter_subreg (operands[0]);
3238 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3240 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3242 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3247 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3249 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3256 [(set (match_operand:DF 0 "memory_operand" "")
3257 (match_operand:DF 1 "register_operand" ""))]
3260 && ((GET_CODE (operands[1]) == REG
3261 && REGNO (operands[1]) < 32)
3262 || (GET_CODE (operands[1]) == SUBREG
3263 && GET_CODE (SUBREG_REG (operands[1])) == REG
3264 && REGNO (SUBREG_REG (operands[1])) < 32))))
3265 && (reload_completed
3266 && (((REGNO (operands[1])) % 2) != 0
3267 || ! mem_min_alignment (operands[0], 8))
3268 && offsettable_memref_p (operands[0])))"
3269 [(clobber (const_int 0))]
3272 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3273 rtx word1 = change_address (operands[0], SFmode,
3274 plus_constant_for_output (XEXP (word0, 0), 4));
3276 if (GET_CODE (operands[1]) == SUBREG)
3277 operands[1] = alter_subreg (operands[1]);
3278 emit_insn (gen_movsf (word0,
3279 gen_highpart (SFmode, operands[1])));
3280 emit_insn (gen_movsf (word1,
3281 gen_lowpart (SFmode, operands[1])));
3285 (define_expand "movtf"
3286 [(set (match_operand:TF 0 "general_operand" "")
3287 (match_operand:TF 1 "general_operand" ""))]
3291 /* Force TFmode constants into memory. */
3292 if (GET_CODE (operands[0]) == REG
3293 && CONSTANT_P (operands[1]))
3295 /* emit_group_store will send such bogosity to us when it is
3296 not storing directly into memory. So fix this up to avoid
3297 crashes in output_constant_pool. */
3298 if (operands [1] == const0_rtx)
3299 operands[1] = CONST0_RTX (TFmode);
3300 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3304 /* Handle MEM cases first, note that only v9 guarentees
3305 full 16-byte alignment for quads. */
3306 if (GET_CODE (operands[0]) == MEM)
3308 if (register_operand (operands[1], TFmode))
3311 if (! reload_in_progress)
3313 operands[0] = validize_mem (operands[0]);
3314 operands[1] = force_reg (TFmode, operands[1]);
3318 /* Fixup PIC cases. */
3321 if (CONSTANT_P (operands[1])
3322 && pic_address_needs_scratch (operands[1]))
3323 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3325 if (symbolic_operand (operands[1], TFmode))
3327 operands[1] = legitimize_pic_address (operands[1],
3329 (reload_in_progress ?
3339 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3340 ;; we must split them all. :-(
3341 (define_insn "*movtf_insn_sp32"
3342 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,e,r,r,o")
3343 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3346 && (register_operand (operands[0], TFmode)
3347 || register_operand (operands[1], TFmode))"
3349 [(set_attr "length" "4")])
3351 ;; Exactly the same as above, except that all `e' cases are deleted.
3352 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3355 (define_insn "*movtf_no_e_insn_sp32"
3356 [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o")
3357 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3360 && (register_operand (operands[0], TFmode)
3361 || register_operand (operands[1], TFmode))"
3363 [(set_attr "length" "4")])
3365 ;; Now handle the float reg cases directly when arch64,
3366 ;; hard_quad, and proper reg number alignment are all true.
3367 (define_insn "*movtf_insn_hq_sp64"
3368 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,r,r,o")
3369 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3374 && (register_operand (operands[0], TFmode)
3375 || register_operand (operands[1], TFmode))"
3383 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3384 (set_attr "length" "1,1,1,2,2,2")])
3386 ;; Now we allow the integer register cases even when
3387 ;; only arch64 is true.
3388 (define_insn "*movtf_insn_sp64"
3389 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r")
3390 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3393 && ! TARGET_HARD_QUAD
3394 && (register_operand (operands[0], TFmode)
3395 || register_operand (operands[1], TFmode))"
3397 [(set_attr "length" "2")])
3399 (define_insn "*movtf_no_e_insn_sp64"
3400 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r")
3401 (match_operand:TF 1 "input_operand" "o,r,r"))]
3404 && (register_operand (operands[0], TFmode)
3405 || register_operand (operands[1], TFmode))"
3407 [(set_attr "length" "2")])
3409 ;; Now all the splits to handle multi-insn TF mode moves.
3411 [(set (match_operand:TF 0 "register_operand" "")
3412 (match_operand:TF 1 "register_operand" ""))]
3416 && ! TARGET_HARD_QUAD))"
3417 [(clobber (const_int 0))]
3420 rtx set_dest = operands[0];
3421 rtx set_src = operands[1];
3425 if (GET_CODE (set_dest) == SUBREG)
3426 set_dest = alter_subreg (set_dest);
3427 if (GET_CODE (set_src) == SUBREG)
3428 set_src = alter_subreg (set_src);
3430 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3431 dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
3432 dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
3433 src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0);
3434 src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0);
3436 /* Now emit using the real source and destination we found, swapping
3437 the order if we detect overlap. */
3438 if (reg_overlap_mentioned_p (dest1, src2))
3440 emit_insn (gen_movdf (dest2, src2));
3441 emit_insn (gen_movdf (dest1, src1));
3445 emit_insn (gen_movdf (dest1, src1));
3446 emit_insn (gen_movdf (dest2, src2));
3452 [(set (match_operand:TF 0 "register_operand" "")
3453 (match_operand:TF 1 "memory_operand" ""))]
3455 && offsettable_memref_p (operands[1]))"
3456 [(clobber (const_int 0))]
3459 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3460 rtx word1 = change_address (operands[1], DFmode,
3461 plus_constant_for_output (XEXP (word0, 0), 8));
3464 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3465 dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
3466 dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
3468 /* Now output, ordering such that we don't clobber any registers
3469 mentioned in the address. */
3470 if (reg_overlap_mentioned_p (dest1, word1))
3473 emit_insn (gen_movdf (dest2, word1));
3474 emit_insn (gen_movdf (dest1, word0));
3478 emit_insn (gen_movdf (dest1, word0));
3479 emit_insn (gen_movdf (dest2, word1));
3485 [(set (match_operand:TF 0 "memory_operand" "")
3486 (match_operand:TF 1 "register_operand" ""))]
3488 && offsettable_memref_p (operands[0]))"
3489 [(clobber (const_int 0))]
3492 rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
3493 rtx word1 = change_address (operands[0], DFmode,
3494 plus_constant_for_output (XEXP (word0, 0), 8));
3497 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3498 src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
3499 src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
3500 emit_insn (gen_movdf (word0, src1));
3501 emit_insn (gen_movdf (word1, src2));
3505 ;; Sparc V9 conditional move instructions.
3507 ;; We can handle larger constants here for some flavors, but for now we keep
3508 ;; it simple and only allow those constants supported by all flavours.
3509 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3510 ;; 3 contains the constant if one is present, but we handle either for
3511 ;; generality (sparc.c puts a constant in operand 2).
3513 (define_expand "movqicc"
3514 [(set (match_operand:QI 0 "register_operand" "")
3515 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3516 (match_operand:QI 2 "arith10_operand" "")
3517 (match_operand:QI 3 "arith10_operand" "")))]
3521 enum rtx_code code = GET_CODE (operands[1]);
3523 if (GET_MODE (sparc_compare_op0) == DImode
3527 if (sparc_compare_op1 == const0_rtx
3528 && GET_CODE (sparc_compare_op0) == REG
3529 && GET_MODE (sparc_compare_op0) == DImode
3530 && v9_regcmp_p (code))
3532 operands[1] = gen_rtx_fmt_ee (code, DImode,
3533 sparc_compare_op0, sparc_compare_op1);
3537 rtx cc_reg = gen_compare_reg (code,
3538 sparc_compare_op0, sparc_compare_op1);
3539 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3543 (define_expand "movhicc"
3544 [(set (match_operand:HI 0 "register_operand" "")
3545 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3546 (match_operand:HI 2 "arith10_operand" "")
3547 (match_operand:HI 3 "arith10_operand" "")))]
3551 enum rtx_code code = GET_CODE (operands[1]);
3553 if (GET_MODE (sparc_compare_op0) == DImode
3557 if (sparc_compare_op1 == const0_rtx
3558 && GET_CODE (sparc_compare_op0) == REG
3559 && GET_MODE (sparc_compare_op0) == DImode
3560 && v9_regcmp_p (code))
3562 operands[1] = gen_rtx_fmt_ee (code, DImode,
3563 sparc_compare_op0, sparc_compare_op1);
3567 rtx cc_reg = gen_compare_reg (code,
3568 sparc_compare_op0, sparc_compare_op1);
3569 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3573 (define_expand "movsicc"
3574 [(set (match_operand:SI 0 "register_operand" "")
3575 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3576 (match_operand:SI 2 "arith10_operand" "")
3577 (match_operand:SI 3 "arith10_operand" "")))]
3581 enum rtx_code code = GET_CODE (operands[1]);
3582 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3584 if (sparc_compare_op1 == const0_rtx
3585 && GET_CODE (sparc_compare_op0) == REG
3586 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3588 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3589 sparc_compare_op0, sparc_compare_op1);
3593 rtx cc_reg = gen_compare_reg (code,
3594 sparc_compare_op0, sparc_compare_op1);
3595 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3596 cc_reg, const0_rtx);
3600 (define_expand "movdicc"
3601 [(set (match_operand:DI 0 "register_operand" "")
3602 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3603 (match_operand:DI 2 "arith10_double_operand" "")
3604 (match_operand:DI 3 "arith10_double_operand" "")))]
3608 enum rtx_code code = GET_CODE (operands[1]);
3610 if (sparc_compare_op1 == const0_rtx
3611 && GET_CODE (sparc_compare_op0) == REG
3612 && GET_MODE (sparc_compare_op0) == DImode
3613 && v9_regcmp_p (code))
3615 operands[1] = gen_rtx_fmt_ee (code, DImode,
3616 sparc_compare_op0, sparc_compare_op1);
3620 rtx cc_reg = gen_compare_reg (code,
3621 sparc_compare_op0, sparc_compare_op1);
3622 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3623 cc_reg, const0_rtx);
3627 (define_expand "movsfcc"
3628 [(set (match_operand:SF 0 "register_operand" "")
3629 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3630 (match_operand:SF 2 "register_operand" "")
3631 (match_operand:SF 3 "register_operand" "")))]
3632 "TARGET_V9 && TARGET_FPU"
3635 enum rtx_code code = GET_CODE (operands[1]);
3637 if (GET_MODE (sparc_compare_op0) == DImode
3641 if (sparc_compare_op1 == const0_rtx
3642 && GET_CODE (sparc_compare_op0) == REG
3643 && GET_MODE (sparc_compare_op0) == DImode
3644 && v9_regcmp_p (code))
3646 operands[1] = gen_rtx_fmt_ee (code, DImode,
3647 sparc_compare_op0, sparc_compare_op1);
3651 rtx cc_reg = gen_compare_reg (code,
3652 sparc_compare_op0, sparc_compare_op1);
3653 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3657 (define_expand "movdfcc"
3658 [(set (match_operand:DF 0 "register_operand" "")
3659 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3660 (match_operand:DF 2 "register_operand" "")
3661 (match_operand:DF 3 "register_operand" "")))]
3662 "TARGET_V9 && TARGET_FPU"
3665 enum rtx_code code = GET_CODE (operands[1]);
3667 if (GET_MODE (sparc_compare_op0) == DImode
3671 if (sparc_compare_op1 == const0_rtx
3672 && GET_CODE (sparc_compare_op0) == REG
3673 && GET_MODE (sparc_compare_op0) == DImode
3674 && v9_regcmp_p (code))
3676 operands[1] = gen_rtx_fmt_ee (code, DImode,
3677 sparc_compare_op0, sparc_compare_op1);
3681 rtx cc_reg = gen_compare_reg (code,
3682 sparc_compare_op0, sparc_compare_op1);
3683 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3687 (define_expand "movtfcc"
3688 [(set (match_operand:TF 0 "register_operand" "")
3689 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3690 (match_operand:TF 2 "register_operand" "")
3691 (match_operand:TF 3 "register_operand" "")))]
3692 "TARGET_V9 && TARGET_FPU"
3695 enum rtx_code code = GET_CODE (operands[1]);
3697 if (GET_MODE (sparc_compare_op0) == DImode
3701 if (sparc_compare_op1 == const0_rtx
3702 && GET_CODE (sparc_compare_op0) == REG
3703 && GET_MODE (sparc_compare_op0) == DImode
3704 && v9_regcmp_p (code))
3706 operands[1] = gen_rtx_fmt_ee (code, DImode,
3707 sparc_compare_op0, sparc_compare_op1);
3711 rtx cc_reg = gen_compare_reg (code,
3712 sparc_compare_op0, sparc_compare_op1);
3713 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3717 ;; Conditional move define_insns.
3719 (define_insn "*movqi_cc_sp64"
3720 [(set (match_operand:QI 0 "register_operand" "=r,r")
3721 (if_then_else:QI (match_operator 1 "comparison_operator"
3722 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3724 (match_operand:QI 3 "arith11_operand" "rL,0")
3725 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3728 mov%C1\\t%x2, %3, %0
3729 mov%c1\\t%x2, %4, %0"
3730 [(set_attr "type" "cmove")
3731 (set_attr "length" "1")])
3733 (define_insn "*movhi_cc_sp64"
3734 [(set (match_operand:HI 0 "register_operand" "=r,r")
3735 (if_then_else:HI (match_operator 1 "comparison_operator"
3736 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3738 (match_operand:HI 3 "arith11_operand" "rL,0")
3739 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3742 mov%C1\\t%x2, %3, %0
3743 mov%c1\\t%x2, %4, %0"
3744 [(set_attr "type" "cmove")
3745 (set_attr "length" "1")])
3747 (define_insn "*movsi_cc_sp64"
3748 [(set (match_operand:SI 0 "register_operand" "=r,r")
3749 (if_then_else:SI (match_operator 1 "comparison_operator"
3750 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3752 (match_operand:SI 3 "arith11_operand" "rL,0")
3753 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3756 mov%C1\\t%x2, %3, %0
3757 mov%c1\\t%x2, %4, %0"
3758 [(set_attr "type" "cmove")
3759 (set_attr "length" "1")])
3761 ;; ??? The constraints of operands 3,4 need work.
3762 (define_insn "*movdi_cc_sp64"
3763 [(set (match_operand:DI 0 "register_operand" "=r,r")
3764 (if_then_else:DI (match_operator 1 "comparison_operator"
3765 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3767 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3768 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3771 mov%C1\\t%x2, %3, %0
3772 mov%c1\\t%x2, %4, %0"
3773 [(set_attr "type" "cmove")
3774 (set_attr "length" "1")])
3776 (define_insn "*movdi_cc_sp64_trunc"
3777 [(set (match_operand:SI 0 "register_operand" "=r,r")
3778 (if_then_else:SI (match_operator 1 "comparison_operator"
3779 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3781 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3782 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3785 mov%C1\\t%x2, %3, %0
3786 mov%c1\\t%x2, %4, %0"
3787 [(set_attr "type" "cmove")
3788 (set_attr "length" "1")])
3790 (define_insn "*movsf_cc_sp64"
3791 [(set (match_operand:SF 0 "register_operand" "=f,f")
3792 (if_then_else:SF (match_operator 1 "comparison_operator"
3793 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3795 (match_operand:SF 3 "register_operand" "f,0")
3796 (match_operand:SF 4 "register_operand" "0,f")))]
3797 "TARGET_V9 && TARGET_FPU"
3799 fmovs%C1\\t%x2, %3, %0
3800 fmovs%c1\\t%x2, %4, %0"
3801 [(set_attr "type" "fpcmove")
3802 (set_attr "length" "1")])
3804 (define_insn "*movdf_cc_sp64"
3805 [(set (match_operand:DF 0 "register_operand" "=e,e")
3806 (if_then_else:DF (match_operator 1 "comparison_operator"
3807 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3809 (match_operand:DF 3 "register_operand" "e,0")
3810 (match_operand:DF 4 "register_operand" "0,e")))]
3811 "TARGET_V9 && TARGET_FPU"
3813 fmovd%C1\\t%x2, %3, %0
3814 fmovd%c1\\t%x2, %4, %0"
3815 [(set_attr "type" "fpcmove")
3816 (set_attr "length" "1")])
3818 (define_insn "*movtf_cc_sp64"
3819 [(set (match_operand:TF 0 "register_operand" "=e,e")
3820 (if_then_else:TF (match_operator 1 "comparison_operator"
3821 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3823 (match_operand:TF 3 "register_operand" "e,0")
3824 (match_operand:TF 4 "register_operand" "0,e")))]
3825 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3827 fmovq%C1\\t%x2, %3, %0
3828 fmovq%c1\\t%x2, %4, %0"
3829 [(set_attr "type" "fpcmove")
3830 (set_attr "length" "1")])
3832 (define_insn "*movqi_cc_reg_sp64"
3833 [(set (match_operand:QI 0 "register_operand" "=r,r")
3834 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3835 [(match_operand:DI 2 "register_operand" "r,r")
3837 (match_operand:QI 3 "arith10_operand" "rM,0")
3838 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3841 movr%D1\\t%2, %r3, %0
3842 movr%d1\\t%2, %r4, %0"
3843 [(set_attr "type" "cmove")
3844 (set_attr "length" "1")])
3846 (define_insn "*movhi_cc_reg_sp64"
3847 [(set (match_operand:HI 0 "register_operand" "=r,r")
3848 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3849 [(match_operand:DI 2 "register_operand" "r,r")
3851 (match_operand:HI 3 "arith10_operand" "rM,0")
3852 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3855 movr%D1\\t%2, %r3, %0
3856 movr%d1\\t%2, %r4, %0"
3857 [(set_attr "type" "cmove")
3858 (set_attr "length" "1")])
3860 (define_insn "*movsi_cc_reg_sp64"
3861 [(set (match_operand:SI 0 "register_operand" "=r,r")
3862 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3863 [(match_operand:DI 2 "register_operand" "r,r")
3865 (match_operand:SI 3 "arith10_operand" "rM,0")
3866 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3869 movr%D1\\t%2, %r3, %0
3870 movr%d1\\t%2, %r4, %0"
3871 [(set_attr "type" "cmove")
3872 (set_attr "length" "1")])
3874 ;; ??? The constraints of operands 3,4 need work.
3875 (define_insn "*movdi_cc_reg_sp64"
3876 [(set (match_operand:DI 0 "register_operand" "=r,r")
3877 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3878 [(match_operand:DI 2 "register_operand" "r,r")
3880 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3881 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3884 movr%D1\\t%2, %r3, %0
3885 movr%d1\\t%2, %r4, %0"
3886 [(set_attr "type" "cmove")
3887 (set_attr "length" "1")])
3889 (define_insn "*movdi_cc_reg_sp64_trunc"
3890 [(set (match_operand:SI 0 "register_operand" "=r,r")
3891 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3892 [(match_operand:DI 2 "register_operand" "r,r")
3894 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3895 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3898 movr%D1\\t%2, %r3, %0
3899 movr%d1\\t%2, %r4, %0"
3900 [(set_attr "type" "cmove")
3901 (set_attr "length" "1")])
3903 (define_insn "*movsf_cc_reg_sp64"
3904 [(set (match_operand:SF 0 "register_operand" "=f,f")
3905 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3906 [(match_operand:DI 2 "register_operand" "r,r")
3908 (match_operand:SF 3 "register_operand" "f,0")
3909 (match_operand:SF 4 "register_operand" "0,f")))]
3910 "TARGET_ARCH64 && TARGET_FPU"
3912 fmovrs%D1\\t%2, %3, %0
3913 fmovrs%d1\\t%2, %4, %0"
3914 [(set_attr "type" "fpcmove")
3915 (set_attr "length" "1")])
3917 (define_insn "*movdf_cc_reg_sp64"
3918 [(set (match_operand:DF 0 "register_operand" "=e,e")
3919 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3920 [(match_operand:DI 2 "register_operand" "r,r")
3922 (match_operand:DF 3 "register_operand" "e,0")
3923 (match_operand:DF 4 "register_operand" "0,e")))]
3924 "TARGET_ARCH64 && TARGET_FPU"
3926 fmovrd%D1\\t%2, %3, %0
3927 fmovrd%d1\\t%2, %4, %0"
3928 [(set_attr "type" "fpcmove")
3929 (set_attr "length" "1")])
3931 (define_insn "*movtf_cc_reg_sp64"
3932 [(set (match_operand:TF 0 "register_operand" "=e,e")
3933 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3934 [(match_operand:DI 2 "register_operand" "r,r")
3936 (match_operand:TF 3 "register_operand" "e,0")
3937 (match_operand:TF 4 "register_operand" "0,e")))]
3938 "TARGET_ARCH64 && TARGET_FPU"
3940 fmovrq%D1\\t%2, %3, %0
3941 fmovrq%d1\\t%2, %4, %0"
3942 [(set_attr "type" "fpcmove")
3943 (set_attr "length" "1")])
3945 ;;- zero extension instructions
3947 ;; These patterns originally accepted general_operands, however, slightly
3948 ;; better code is generated by only accepting register_operands, and then
3949 ;; letting combine generate the ldu[hb] insns.
3951 (define_expand "zero_extendhisi2"
3952 [(set (match_operand:SI 0 "register_operand" "")
3953 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3957 rtx temp = gen_reg_rtx (SImode);
3958 rtx shift_16 = GEN_INT (16);
3959 int op1_subword = 0;
3961 if (GET_CODE (operand1) == SUBREG)
3963 op1_subword = SUBREG_WORD (operand1);
3964 operand1 = XEXP (operand1, 0);
3967 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
3969 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3973 (define_insn "*zero_extendhisi2_insn"
3974 [(set (match_operand:SI 0 "register_operand" "=r")
3975 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3978 [(set_attr "type" "load")
3979 (set_attr "length" "1")])
3981 (define_expand "zero_extendqihi2"
3982 [(set (match_operand:HI 0 "register_operand" "")
3983 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3987 (define_insn "*zero_extendqihi2_insn"
3988 [(set (match_operand:HI 0 "register_operand" "=r,r")
3989 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3990 "GET_CODE (operands[1]) != CONST_INT"
3994 [(set_attr "type" "unary,load")
3995 (set_attr "length" "1")])
3997 (define_expand "zero_extendqisi2"
3998 [(set (match_operand:SI 0 "register_operand" "")
3999 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4003 (define_insn "*zero_extendqisi2_insn"
4004 [(set (match_operand:SI 0 "register_operand" "=r,r")
4005 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4006 "GET_CODE (operands[1]) != CONST_INT"
4010 [(set_attr "type" "unary,load")
4011 (set_attr "length" "1")])
4013 (define_expand "zero_extendqidi2"
4014 [(set (match_operand:DI 0 "register_operand" "")
4015 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4019 (define_insn "*zero_extendqidi2_insn"
4020 [(set (match_operand:DI 0 "register_operand" "=r,r")
4021 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4022 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4026 [(set_attr "type" "unary,load")
4027 (set_attr "length" "1")])
4029 (define_expand "zero_extendhidi2"
4030 [(set (match_operand:DI 0 "register_operand" "")
4031 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4035 rtx temp = gen_reg_rtx (DImode);
4036 rtx shift_48 = GEN_INT (48);
4037 int op1_subword = 0;
4039 if (GET_CODE (operand1) == SUBREG)
4041 op1_subword = SUBREG_WORD (operand1);
4042 operand1 = XEXP (operand1, 0);
4045 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4047 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4051 (define_insn "*zero_extendhidi2_insn"
4052 [(set (match_operand:DI 0 "register_operand" "=r")
4053 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4056 [(set_attr "type" "load")
4057 (set_attr "length" "1")])
4060 ;; ??? Write truncdisi pattern using sra?
4062 (define_expand "zero_extendsidi2"
4063 [(set (match_operand:DI 0 "register_operand" "")
4064 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4068 (define_insn "*zero_extendsidi2_insn_sp64"
4069 [(set (match_operand:DI 0 "register_operand" "=r,r")
4070 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4071 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4075 [(set_attr "type" "shift,load")
4076 (set_attr "length" "1")])
4078 (define_insn "*zero_extendsidi2_insn_sp32"
4079 [(set (match_operand:DI 0 "register_operand" "=r")
4080 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4083 [(set_attr "type" "unary")
4084 (set_attr "length" "2")])
4087 [(set (match_operand:DI 0 "register_operand" "")
4088 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4089 "! TARGET_ARCH64 && reload_completed"
4090 [(set (match_dup 2) (match_dup 3))
4091 (set (match_dup 4) (match_dup 5))]
4096 if (GET_CODE (operands[0]) == SUBREG)
4097 operands[0] = alter_subreg (operands[0]);
4099 dest1 = gen_highpart (SImode, operands[0]);
4100 dest2 = gen_lowpart (SImode, operands[0]);
4102 /* Swap the order in case of overlap. */
4103 if (REGNO (dest1) == REGNO (operands[1]))
4105 operands[2] = dest2;
4106 operands[3] = operands[1];
4107 operands[4] = dest1;
4108 operands[5] = const0_rtx;
4112 operands[2] = dest1;
4113 operands[3] = const0_rtx;
4114 operands[4] = dest2;
4115 operands[5] = operands[1];
4119 ;; Simplify comparisons of extended values.
4121 (define_insn "*cmp_zero_extendqisi2"
4123 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4126 "andcc\\t%0, 0xff, %%g0"
4127 [(set_attr "type" "compare")
4128 (set_attr "length" "1")])
4130 (define_insn "*cmp_zero_extendqisi2_set"
4132 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4134 (set (match_operand:SI 0 "register_operand" "=r")
4135 (zero_extend:SI (match_dup 1)))]
4137 "andcc\\t%1, 0xff, %0"
4138 [(set_attr "type" "compare")
4139 (set_attr "length" "1")])
4141 (define_insn "*cmp_zero_extendqidi2"
4143 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4146 "andcc\\t%0, 0xff, %%g0"
4147 [(set_attr "type" "compare")
4148 (set_attr "length" "1")])
4150 (define_insn "*cmp_zero_extendqidi2_set"
4152 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4154 (set (match_operand:DI 0 "register_operand" "=r")
4155 (zero_extend:DI (match_dup 1)))]
4157 "andcc\\t%1, 0xff, %0"
4158 [(set_attr "type" "compare")
4159 (set_attr "length" "1")])
4161 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4163 (define_insn "*cmp_siqi_trunc"
4165 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4168 "andcc\\t%0, 0xff, %%g0"
4169 [(set_attr "type" "compare")
4170 (set_attr "length" "1")])
4172 (define_insn "*cmp_siqi_trunc_set"
4174 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4176 (set (match_operand:QI 0 "register_operand" "=r")
4177 (subreg:QI (match_dup 1) 0))]
4179 "andcc\\t%1, 0xff, %0"
4180 [(set_attr "type" "compare")
4181 (set_attr "length" "1")])
4183 (define_insn "*cmp_diqi_trunc"
4185 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4188 "andcc\\t%0, 0xff, %%g0"
4189 [(set_attr "type" "compare")
4190 (set_attr "length" "1")])
4192 (define_insn "*cmp_diqi_trunc_set"
4194 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4196 (set (match_operand:QI 0 "register_operand" "=r")
4197 (subreg:QI (match_dup 1) 0))]
4199 "andcc\\t%1, 0xff, %0"
4200 [(set_attr "type" "compare")
4201 (set_attr "length" "1")])
4203 ;;- sign extension instructions
4205 ;; These patterns originally accepted general_operands, however, slightly
4206 ;; better code is generated by only accepting register_operands, and then
4207 ;; letting combine generate the lds[hb] insns.
4209 (define_expand "extendhisi2"
4210 [(set (match_operand:SI 0 "register_operand" "")
4211 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4215 rtx temp = gen_reg_rtx (SImode);
4216 rtx shift_16 = GEN_INT (16);
4217 int op1_subword = 0;
4219 if (GET_CODE (operand1) == SUBREG)
4221 op1_subword = SUBREG_WORD (operand1);
4222 operand1 = XEXP (operand1, 0);
4225 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4227 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4231 (define_insn "*sign_extendhisi2_insn"
4232 [(set (match_operand:SI 0 "register_operand" "=r")
4233 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4236 [(set_attr "type" "sload")
4237 (set_attr "length" "1")])
4239 (define_expand "extendqihi2"
4240 [(set (match_operand:HI 0 "register_operand" "")
4241 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4245 rtx temp = gen_reg_rtx (SImode);
4246 rtx shift_24 = GEN_INT (24);
4247 int op1_subword = 0;
4248 int op0_subword = 0;
4250 if (GET_CODE (operand1) == SUBREG)
4252 op1_subword = SUBREG_WORD (operand1);
4253 operand1 = XEXP (operand1, 0);
4255 if (GET_CODE (operand0) == SUBREG)
4257 op0_subword = SUBREG_WORD (operand0);
4258 operand0 = XEXP (operand0, 0);
4260 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4262 if (GET_MODE (operand0) != SImode)
4263 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4264 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4268 (define_insn "*sign_extendqihi2_insn"
4269 [(set (match_operand:HI 0 "register_operand" "=r")
4270 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4273 [(set_attr "type" "sload")
4274 (set_attr "length" "1")])
4276 (define_expand "extendqisi2"
4277 [(set (match_operand:SI 0 "register_operand" "")
4278 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4282 rtx temp = gen_reg_rtx (SImode);
4283 rtx shift_24 = GEN_INT (24);
4284 int op1_subword = 0;
4286 if (GET_CODE (operand1) == SUBREG)
4288 op1_subword = SUBREG_WORD (operand1);
4289 operand1 = XEXP (operand1, 0);
4292 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4294 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4298 (define_insn "*sign_extendqisi2_insn"
4299 [(set (match_operand:SI 0 "register_operand" "=r")
4300 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4303 [(set_attr "type" "sload")
4304 (set_attr "length" "1")])
4306 (define_expand "extendqidi2"
4307 [(set (match_operand:DI 0 "register_operand" "")
4308 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4312 rtx temp = gen_reg_rtx (DImode);
4313 rtx shift_56 = GEN_INT (56);
4314 int op1_subword = 0;
4316 if (GET_CODE (operand1) == SUBREG)
4318 op1_subword = SUBREG_WORD (operand1);
4319 operand1 = XEXP (operand1, 0);
4322 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4324 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4328 (define_insn "*sign_extendqidi2_insn"
4329 [(set (match_operand:DI 0 "register_operand" "=r")
4330 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4333 [(set_attr "type" "sload")
4334 (set_attr "length" "1")])
4336 (define_expand "extendhidi2"
4337 [(set (match_operand:DI 0 "register_operand" "")
4338 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4342 rtx temp = gen_reg_rtx (DImode);
4343 rtx shift_48 = GEN_INT (48);
4344 int op1_subword = 0;
4346 if (GET_CODE (operand1) == SUBREG)
4348 op1_subword = SUBREG_WORD (operand1);
4349 operand1 = XEXP (operand1, 0);
4352 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4354 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4358 (define_insn "*sign_extendhidi2_insn"
4359 [(set (match_operand:DI 0 "register_operand" "=r")
4360 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4363 [(set_attr "type" "sload")
4364 (set_attr "length" "1")])
4366 (define_expand "extendsidi2"
4367 [(set (match_operand:DI 0 "register_operand" "")
4368 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4372 (define_insn "*sign_extendsidi2_insn"
4373 [(set (match_operand:DI 0 "register_operand" "=r,r")
4374 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4379 [(set_attr "type" "shift,sload")
4380 (set_attr "length" "1")])
4382 ;; Special pattern for optimizing bit-field compares. This is needed
4383 ;; because combine uses this as a canonical form.
4385 (define_insn "*cmp_zero_extract"
4388 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4389 (match_operand:SI 1 "small_int_or_double" "n")
4390 (match_operand:SI 2 "small_int_or_double" "n"))
4393 && ((GET_CODE (operands[2]) == CONST_INT
4394 && INTVAL (operands[2]) > 19)
4395 || (GET_CODE (operands[2]) == CONST_DOUBLE
4396 && CONST_DOUBLE_LOW (operands[2]) > 19))"
4399 int len = (GET_CODE (operands[1]) == CONST_INT
4400 ? INTVAL (operands[1])
4401 : CONST_DOUBLE_LOW (operands[1]));
4403 (GET_CODE (operands[2]) == CONST_INT
4404 ? INTVAL (operands[2])
4405 : CONST_DOUBLE_LOW (operands[2])) - len;
4406 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4408 operands[1] = GEN_INT (mask);
4409 return \"andcc\\t%0, %1, %%g0\";
4411 [(set_attr "type" "compare")
4412 (set_attr "length" "1")])
4414 (define_insn "*cmp_zero_extract_sp64"
4417 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4418 (match_operand:SI 1 "small_int_or_double" "n")
4419 (match_operand:SI 2 "small_int_or_double" "n"))
4422 && ((GET_CODE (operands[2]) == CONST_INT
4423 && INTVAL (operands[2]) > 51)
4424 || (GET_CODE (operands[2]) == CONST_DOUBLE
4425 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4428 int len = (GET_CODE (operands[1]) == CONST_INT
4429 ? INTVAL (operands[1])
4430 : CONST_DOUBLE_LOW (operands[1]));
4432 (GET_CODE (operands[2]) == CONST_INT
4433 ? INTVAL (operands[2])
4434 : CONST_DOUBLE_LOW (operands[2])) - len;
4435 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4437 operands[1] = GEN_INT (mask);
4438 return \"andcc\\t%0, %1, %%g0\";
4440 [(set_attr "type" "compare")
4441 (set_attr "length" "1")])
4443 ;; Conversions between float, double and long double.
4445 (define_insn "extendsfdf2"
4446 [(set (match_operand:DF 0 "register_operand" "=e")
4448 (match_operand:SF 1 "register_operand" "f")))]
4451 [(set_attr "type" "fp")
4452 (set_attr "length" "1")])
4454 (define_insn "extendsftf2"
4455 [(set (match_operand:TF 0 "register_operand" "=e")
4457 (match_operand:SF 1 "register_operand" "f")))]
4458 "TARGET_FPU && TARGET_HARD_QUAD"
4460 [(set_attr "type" "fp")
4461 (set_attr "length" "1")])
4463 (define_insn "extenddftf2"
4464 [(set (match_operand:TF 0 "register_operand" "=e")
4466 (match_operand:DF 1 "register_operand" "e")))]
4467 "TARGET_FPU && TARGET_HARD_QUAD"
4469 [(set_attr "type" "fp")
4470 (set_attr "length" "1")])
4472 (define_insn "truncdfsf2"
4473 [(set (match_operand:SF 0 "register_operand" "=f")
4475 (match_operand:DF 1 "register_operand" "e")))]
4478 [(set_attr "type" "fp")
4479 (set_attr "length" "1")])
4481 (define_insn "trunctfsf2"
4482 [(set (match_operand:SF 0 "register_operand" "=f")
4484 (match_operand:TF 1 "register_operand" "e")))]
4485 "TARGET_FPU && TARGET_HARD_QUAD"
4487 [(set_attr "type" "fp")
4488 (set_attr "length" "1")])
4490 (define_insn "trunctfdf2"
4491 [(set (match_operand:DF 0 "register_operand" "=e")
4493 (match_operand:TF 1 "register_operand" "e")))]
4494 "TARGET_FPU && TARGET_HARD_QUAD"
4496 [(set_attr "type" "fp")
4497 (set_attr "length" "1")])
4499 ;; Conversion between fixed point and floating point.
4501 (define_insn "floatsisf2"
4502 [(set (match_operand:SF 0 "register_operand" "=f")
4503 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4506 [(set_attr "type" "fp")
4507 (set_attr "length" "1")])
4509 (define_insn "floatsidf2"
4510 [(set (match_operand:DF 0 "register_operand" "=e")
4511 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4514 [(set_attr "type" "fp")
4515 (set_attr "length" "1")])
4517 (define_insn "floatsitf2"
4518 [(set (match_operand:TF 0 "register_operand" "=e")
4519 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4520 "TARGET_FPU && TARGET_HARD_QUAD"
4522 [(set_attr "type" "fp")
4523 (set_attr "length" "1")])
4525 ;; Now the same for 64 bit sources.
4527 (define_insn "floatdisf2"
4528 [(set (match_operand:SF 0 "register_operand" "=f")
4529 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4530 "TARGET_V9 && TARGET_FPU"
4532 [(set_attr "type" "fp")
4533 (set_attr "length" "1")])
4535 (define_insn "floatdidf2"
4536 [(set (match_operand:DF 0 "register_operand" "=e")
4537 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4538 "TARGET_V9 && TARGET_FPU"
4540 [(set_attr "type" "fp")
4541 (set_attr "length" "1")])
4543 (define_insn "floatditf2"
4544 [(set (match_operand:TF 0 "register_operand" "=e")
4545 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4546 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4548 [(set_attr "type" "fp")
4549 (set_attr "length" "1")])
4551 ;; Convert a float to an actual integer.
4552 ;; Truncation is performed as part of the conversion.
4554 (define_insn "fix_truncsfsi2"
4555 [(set (match_operand:SI 0 "register_operand" "=f")
4556 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4559 [(set_attr "type" "fp")
4560 (set_attr "length" "1")])
4562 (define_insn "fix_truncdfsi2"
4563 [(set (match_operand:SI 0 "register_operand" "=f")
4564 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4567 [(set_attr "type" "fp")
4568 (set_attr "length" "1")])
4570 (define_insn "fix_trunctfsi2"
4571 [(set (match_operand:SI 0 "register_operand" "=f")
4572 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4573 "TARGET_FPU && TARGET_HARD_QUAD"
4575 [(set_attr "type" "fp")
4576 (set_attr "length" "1")])
4578 ;; Now the same, for V9 targets
4580 (define_insn "fix_truncsfdi2"
4581 [(set (match_operand:DI 0 "register_operand" "=e")
4582 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4583 "TARGET_V9 && TARGET_FPU"
4585 [(set_attr "type" "fp")
4586 (set_attr "length" "1")])
4588 (define_insn "fix_truncdfdi2"
4589 [(set (match_operand:DI 0 "register_operand" "=e")
4590 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4591 "TARGET_V9 && TARGET_FPU"
4593 [(set_attr "type" "fp")
4594 (set_attr "length" "1")])
4596 (define_insn "fix_trunctfdi2"
4597 [(set (match_operand:DI 0 "register_operand" "=e")
4598 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4599 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4601 [(set_attr "type" "fp")
4602 (set_attr "length" "1")])
4604 ;;- arithmetic instructions
4606 (define_expand "adddi3"
4607 [(set (match_operand:DI 0 "register_operand" "=r")
4608 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4609 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4613 if (! TARGET_ARCH64)
4615 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4616 gen_rtx_SET (VOIDmode, operands[0],
4617 gen_rtx_PLUS (DImode, operands[1],
4619 gen_rtx_CLOBBER (VOIDmode,
4620 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4623 if (arith_double_4096_operand(operands[2], DImode))
4625 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4626 gen_rtx_MINUS (DImode, operands[1],
4632 (define_insn "adddi3_insn_sp32"
4633 [(set (match_operand:DI 0 "register_operand" "=r")
4634 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4635 (match_operand:DI 2 "arith_double_operand" "rHI")))
4636 (clobber (reg:CC 100))]
4639 [(set_attr "length" "2")])
4642 [(set (match_operand:DI 0 "register_operand" "=r")
4643 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4644 (match_operand:DI 2 "arith_double_operand" "rHI")))
4645 (clobber (reg:CC 100))]
4646 "! TARGET_ARCH64 && reload_completed"
4647 [(parallel [(set (reg:CC_NOOV 100)
4648 (compare:CC_NOOV (plus:SI (match_dup 4)
4652 (plus:SI (match_dup 4) (match_dup 5)))])
4654 (plus:SI (plus:SI (match_dup 7)
4656 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4659 operands[3] = gen_lowpart (SImode, operands[0]);
4660 operands[4] = gen_lowpart (SImode, operands[1]);
4661 operands[5] = gen_lowpart (SImode, operands[2]);
4662 operands[6] = gen_highpart (SImode, operands[0]);
4663 operands[7] = gen_highpart (SImode, operands[1]);
4664 if (GET_CODE (operands[2]) == CONST_INT)
4666 if (INTVAL (operands[2]) < 0)
4667 operands[8] = constm1_rtx;
4669 operands[8] = const0_rtx;
4672 operands[8] = gen_highpart (SImode, operands[2]);
4676 [(set (match_operand:DI 0 "register_operand" "=r")
4677 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
4678 (match_operand:DI 2 "arith_double_operand" "rHI")))
4679 (clobber (reg:CC 100))]
4680 "! TARGET_ARCH64 && reload_completed"
4681 [(parallel [(set (reg:CC_NOOV 100)
4682 (compare:CC_NOOV (minus:SI (match_dup 4)
4686 (minus:SI (match_dup 4) (match_dup 5)))])
4688 (minus:SI (minus:SI (match_dup 7)
4690 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4693 operands[3] = gen_lowpart (SImode, operands[0]);
4694 operands[4] = gen_lowpart (SImode, operands[1]);
4695 operands[5] = gen_lowpart (SImode, operands[2]);
4696 operands[6] = gen_highpart (SImode, operands[0]);
4697 operands[7] = gen_highpart (SImode, operands[1]);
4698 if (GET_CODE (operands[2]) == CONST_INT)
4700 if (INTVAL (operands[2]) < 0)
4701 operands[8] = constm1_rtx;
4703 operands[8] = const0_rtx;
4706 operands[8] = gen_highpart (SImode, operands[2]);
4709 ;; LTU here means "carry set"
4711 [(set (match_operand:SI 0 "register_operand" "=r")
4712 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4713 (match_operand:SI 2 "arith_operand" "rI"))
4714 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4717 [(set_attr "type" "unary")
4718 (set_attr "length" "1")])
4720 (define_insn "*addx_extend_sp32"
4721 [(set (match_operand:DI 0 "register_operand" "=r")
4722 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4723 (match_operand:SI 2 "arith_operand" "rI"))
4724 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4727 [(set_attr "type" "unary")
4728 (set_attr "length" "2")])
4731 [(set (match_operand:DI 0 "register_operand" "")
4732 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
4733 (match_operand:SI 2 "arith_operand" ""))
4734 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4735 "! TARGET_ARCH64 && reload_completed"
4736 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4737 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4738 (set (match_dup 4) (const_int 0))]
4739 "operands[3] = gen_lowpart (SImode, operands[0]);
4740 operands[4] = gen_highpart (SImode, operands[1]);")
4742 (define_insn "*addx_extend_sp64"
4743 [(set (match_operand:DI 0 "register_operand" "=r")
4744 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4745 (match_operand:SI 2 "arith_operand" "rI"))
4746 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4748 "addx\\t%r1, %2, %0"
4749 [(set_attr "type" "misc")
4750 (set_attr "length" "1")])
4753 [(set (match_operand:SI 0 "register_operand" "=r")
4754 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4755 (match_operand:SI 2 "arith_operand" "rI"))
4756 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4758 "subx\\t%r1, %2, %0"
4759 [(set_attr "type" "misc")
4760 (set_attr "length" "1")])
4762 (define_insn "*subx_extend_sp64"
4763 [(set (match_operand:DI 0 "register_operand" "=r")
4764 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4765 (match_operand:SI 2 "arith_operand" "rI"))
4766 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4768 "subx\\t%r1, %2, %0"
4769 [(set_attr "type" "misc")
4770 (set_attr "length" "1")])
4772 (define_insn "*subx_extend"
4773 [(set (match_operand:DI 0 "register_operand" "=r")
4774 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4775 (match_operand:SI 2 "arith_operand" "rI"))
4776 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4779 [(set_attr "type" "unary")
4780 (set_attr "length" "2")])
4783 [(set (match_operand:DI 0 "register_operand" "=r")
4784 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4785 (match_operand:SI 2 "arith_operand" "rI"))
4786 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4787 "! TARGET_ARCH64 && reload_completed"
4788 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4789 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4790 (set (match_dup 4) (const_int 0))]
4791 "operands[3] = gen_lowpart (SImode, operands[0]);
4792 operands[4] = gen_highpart (SImode, operands[0]);")
4795 [(set (match_operand:DI 0 "register_operand" "=r")
4796 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4797 (match_operand:DI 2 "register_operand" "r")))
4798 (clobber (reg:CC 100))]
4801 [(set_attr "type" "multi")
4802 (set_attr "length" "2")])
4805 [(set (match_operand:DI 0 "register_operand" "")
4806 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4807 (match_operand:DI 2 "register_operand" "")))
4808 (clobber (reg:CC 100))]
4809 "! TARGET_ARCH64 && reload_completed"
4810 [(parallel [(set (reg:CC_NOOV 100)
4811 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4813 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4815 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4816 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4817 "operands[3] = gen_lowpart (SImode, operands[2]);
4818 operands[4] = gen_highpart (SImode, operands[2]);
4819 operands[5] = gen_lowpart (SImode, operands[0]);
4820 operands[6] = gen_highpart (SImode, operands[0]);")
4822 (define_insn "*adddi3_sp64"
4823 [(set (match_operand:DI 0 "register_operand" "=r")
4824 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4825 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4828 [(set_attr "type" "binary")
4829 (set_attr "length" "1")])
4831 (define_expand "addsi3"
4832 [(set (match_operand:SI 0 "register_operand" "=r,d")
4833 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4834 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4838 if (arith_4096_operand(operands[2], DImode))
4840 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4841 gen_rtx_MINUS (SImode, operands[1],
4847 (define_insn "*addsi3"
4848 [(set (match_operand:SI 0 "register_operand" "=r,d")
4849 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4850 (match_operand:SI 2 "arith_operand" "rI,d")))]
4854 fpadd32s\\t%1, %2, %0"
4855 [(set_attr "type" "ialu,fp")
4856 (set_attr "length" "1")])
4858 (define_insn "*cmp_cc_plus"
4859 [(set (reg:CC_NOOV 100)
4860 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4861 (match_operand:SI 1 "arith_operand" "rI"))
4864 "addcc\\t%0, %1, %%g0"
4865 [(set_attr "type" "compare")
4866 (set_attr "length" "1")])
4868 (define_insn "*cmp_ccx_plus"
4869 [(set (reg:CCX_NOOV 100)
4870 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4871 (match_operand:DI 1 "arith_double_operand" "rHI"))
4874 "addcc\\t%0, %1, %%g0"
4875 [(set_attr "type" "compare")
4876 (set_attr "length" "1")])
4878 (define_insn "*cmp_cc_plus_set"
4879 [(set (reg:CC_NOOV 100)
4880 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4881 (match_operand:SI 2 "arith_operand" "rI"))
4883 (set (match_operand:SI 0 "register_operand" "=r")
4884 (plus:SI (match_dup 1) (match_dup 2)))]
4886 "addcc\\t%1, %2, %0"
4887 [(set_attr "type" "compare")
4888 (set_attr "length" "1")])
4890 (define_insn "*cmp_ccx_plus_set"
4891 [(set (reg:CCX_NOOV 100)
4892 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4893 (match_operand:DI 2 "arith_double_operand" "rHI"))
4895 (set (match_operand:DI 0 "register_operand" "=r")
4896 (plus:DI (match_dup 1) (match_dup 2)))]
4898 "addcc\\t%1, %2, %0"
4899 [(set_attr "type" "compare")
4900 (set_attr "length" "1")])
4902 (define_expand "subdi3"
4903 [(set (match_operand:DI 0 "register_operand" "=r")
4904 (minus:DI (match_operand:DI 1 "register_operand" "r")
4905 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4909 if (! TARGET_ARCH64)
4911 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4912 gen_rtx_SET (VOIDmode, operands[0],
4913 gen_rtx_MINUS (DImode, operands[1],
4915 gen_rtx_CLOBBER (VOIDmode,
4916 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4919 if (arith_double_4096_operand(operands[2], DImode))
4921 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4922 gen_rtx_PLUS (DImode, operands[1],
4928 (define_insn "*subdi3_sp32"
4929 [(set (match_operand:DI 0 "register_operand" "=r")
4930 (minus:DI (match_operand:DI 1 "register_operand" "r")
4931 (match_operand:DI 2 "arith_double_operand" "rHI")))
4932 (clobber (reg:CC 100))]
4935 [(set_attr "length" "2")])
4938 [(set (match_operand:DI 0 "register_operand" "")
4939 (minus:DI (match_operand:DI 1 "register_operand" "")
4940 (match_operand:DI 2 "arith_double_operand" "")))
4941 (clobber (reg:CC 100))]
4944 && (GET_CODE (operands[2]) == CONST_INT
4945 || GET_CODE (operands[2]) == CONST_DOUBLE)"
4946 [(clobber (const_int 0))]
4951 highp = gen_highpart (SImode, operands[2]);
4952 lowp = gen_lowpart (SImode, operands[2]);
4953 if ((lowp == const0_rtx)
4954 && (operands[0] == operands[1]))
4956 emit_insn (gen_rtx_SET (VOIDmode,
4957 gen_highpart (SImode, operands[0]),
4958 gen_rtx_MINUS (SImode,
4959 gen_highpart (SImode, operands[1]),
4964 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
4965 gen_lowpart (SImode, operands[1]),
4967 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
4968 gen_highpart (SImode, operands[1]),
4975 [(set (match_operand:DI 0 "register_operand" "")
4976 (minus:DI (match_operand:DI 1 "register_operand" "")
4977 (match_operand:DI 2 "register_operand" "")))
4978 (clobber (reg:CC 100))]
4980 && reload_completed"
4981 [(clobber (const_int 0))]
4984 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
4985 gen_lowpart (SImode, operands[1]),
4986 gen_lowpart (SImode, operands[2])));
4987 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
4988 gen_highpart (SImode, operands[1]),
4989 gen_highpart (SImode, operands[2])));
4994 [(set (match_operand:DI 0 "register_operand" "=r")
4995 (minus:DI (match_operand:DI 1 "register_operand" "r")
4996 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4997 (clobber (reg:CC 100))]
5000 [(set_attr "type" "multi")
5001 (set_attr "length" "2")])
5004 [(set (match_operand:DI 0 "register_operand" "")
5005 (minus:DI (match_operand:DI 1 "register_operand" "")
5006 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5007 (clobber (reg:CC 100))]
5008 "! TARGET_ARCH64 && reload_completed"
5009 [(parallel [(set (reg:CC_NOOV 100)
5010 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5012 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5014 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5015 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5016 "operands[3] = gen_lowpart (SImode, operands[1]);
5017 operands[4] = gen_highpart (SImode, operands[1]);
5018 operands[5] = gen_lowpart (SImode, operands[0]);
5019 operands[6] = gen_highpart (SImode, operands[0]);")
5021 (define_insn "*subdi3_sp64"
5022 [(set (match_operand:DI 0 "register_operand" "=r")
5023 (minus:DI (match_operand:DI 1 "register_operand" "r")
5024 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5027 [(set_attr "type" "binary")
5028 (set_attr "length" "1")])
5030 (define_expand "subsi3"
5031 [(set (match_operand:SI 0 "register_operand" "=r,d")
5032 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5033 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5037 if (arith_4096_operand(operands[2], DImode))
5039 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5040 gen_rtx_PLUS (SImode, operands[1],
5046 (define_insn "*subsi3"
5047 [(set (match_operand:SI 0 "register_operand" "=r,d")
5048 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5049 (match_operand:SI 2 "arith_operand" "rI,d")))]
5053 fpsub32s\\t%1, %2, %0"
5054 [(set_attr "type" "ialu,fp")
5055 (set_attr "length" "1")])
5057 (define_insn "*cmp_minus_cc"
5058 [(set (reg:CC_NOOV 100)
5059 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5060 (match_operand:SI 1 "arith_operand" "rI"))
5063 "subcc\\t%r0, %1, %%g0"
5064 [(set_attr "type" "compare")
5065 (set_attr "length" "1")])
5067 (define_insn "*cmp_minus_ccx"
5068 [(set (reg:CCX_NOOV 100)
5069 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5070 (match_operand:DI 1 "arith_double_operand" "rHI"))
5073 "subcc\\t%0, %1, %%g0"
5074 [(set_attr "type" "compare")
5075 (set_attr "length" "1")])
5077 (define_insn "cmp_minus_cc_set"
5078 [(set (reg:CC_NOOV 100)
5079 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5080 (match_operand:SI 2 "arith_operand" "rI"))
5082 (set (match_operand:SI 0 "register_operand" "=r")
5083 (minus:SI (match_dup 1) (match_dup 2)))]
5085 "subcc\\t%r1, %2, %0"
5086 [(set_attr "type" "compare")
5087 (set_attr "length" "1")])
5089 (define_insn "*cmp_minus_ccx_set"
5090 [(set (reg:CCX_NOOV 100)
5091 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5092 (match_operand:DI 2 "arith_double_operand" "rHI"))
5094 (set (match_operand:DI 0 "register_operand" "=r")
5095 (minus:DI (match_dup 1) (match_dup 2)))]
5097 "subcc\\t%1, %2, %0"
5098 [(set_attr "type" "compare")
5099 (set_attr "length" "1")])
5101 ;; Integer Multiply/Divide.
5103 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5104 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5106 (define_insn "mulsi3"
5107 [(set (match_operand:SI 0 "register_operand" "=r")
5108 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5109 (match_operand:SI 2 "arith_operand" "rI")))]
5112 [(set_attr "type" "imul")
5113 (set_attr "length" "1")])
5115 (define_expand "muldi3"
5116 [(set (match_operand:DI 0 "register_operand" "=r")
5117 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5118 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5119 "TARGET_ARCH64 || TARGET_V8PLUS"
5124 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5129 (define_insn "*muldi3_sp64"
5130 [(set (match_operand:DI 0 "register_operand" "=r")
5131 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5132 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5135 [(set_attr "type" "imul")
5136 (set_attr "length" "1")])
5138 ;; V8plus wide multiply.
5140 (define_insn "muldi3_v8plus"
5141 [(set (match_operand:DI 0 "register_operand" "=r,h")
5142 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5143 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5144 (clobber (match_scratch:SI 3 "=&h,X"))
5145 (clobber (match_scratch:SI 4 "=&h,X"))]
5149 if (sparc_check_64 (operands[1], insn) <= 0)
5150 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5151 if (which_alternative == 1)
5152 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5153 if (sparc_check_64 (operands[2], insn) <= 0)
5154 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5155 if (which_alternative == 1)
5156 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\";
5158 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\";
5160 [(set_attr "length" "9,8")])
5162 (define_insn "*cmp_mul_set"
5164 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5165 (match_operand:SI 2 "arith_operand" "rI"))
5167 (set (match_operand:SI 0 "register_operand" "=r")
5168 (mult:SI (match_dup 1) (match_dup 2)))]
5169 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5170 "smulcc\\t%1, %2, %0"
5171 [(set_attr "type" "imul")
5172 (set_attr "length" "1")])
5174 (define_expand "mulsidi3"
5175 [(set (match_operand:DI 0 "register_operand" "")
5176 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5177 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5181 if (CONSTANT_P (operands[2]))
5184 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5187 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5193 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5198 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5199 ;; registers can hold 64 bit values in the V8plus environment.
5201 (define_insn "mulsidi3_v8plus"
5202 [(set (match_operand:DI 0 "register_operand" "=h,r")
5203 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5204 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5205 (clobber (match_scratch:SI 3 "=X,&h"))]
5208 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5209 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5210 [(set_attr "length" "2,3")])
5213 (define_insn "const_mulsidi3_v8plus"
5214 [(set (match_operand:DI 0 "register_operand" "=h,r")
5215 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5216 (match_operand:SI 2 "small_int" "I,I")))
5217 (clobber (match_scratch:SI 3 "=X,&h"))]
5220 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5221 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5222 [(set_attr "length" "2,3")])
5225 (define_insn "*mulsidi3_sp32"
5226 [(set (match_operand:DI 0 "register_operand" "=r")
5227 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5228 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5232 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5234 [(set (attr "length")
5235 (if_then_else (eq_attr "isa" "sparclet")
5236 (const_int 1) (const_int 2)))])
5238 (define_insn "*mulsidi3_sp64"
5239 [(set (match_operand:DI 0 "register_operand" "=r")
5240 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5241 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5242 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5244 [(set_attr "length" "1")])
5246 ;; Extra pattern, because sign_extend of a constant isn't valid.
5249 (define_insn "const_mulsidi3_sp32"
5250 [(set (match_operand:DI 0 "register_operand" "=r")
5251 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5252 (match_operand:SI 2 "small_int" "I")))]
5256 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5258 [(set (attr "length")
5259 (if_then_else (eq_attr "isa" "sparclet")
5260 (const_int 1) (const_int 2)))])
5262 (define_insn "const_mulsidi3_sp64"
5263 [(set (match_operand:DI 0 "register_operand" "=r")
5264 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5265 (match_operand:SI 2 "small_int" "I")))]
5266 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5268 [(set_attr "length" "1")])
5270 (define_expand "smulsi3_highpart"
5271 [(set (match_operand:SI 0 "register_operand" "")
5273 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5274 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5276 "TARGET_HARD_MUL && TARGET_ARCH32"
5279 if (CONSTANT_P (operands[2]))
5283 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5289 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5294 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5295 operands[2], GEN_INT (32)));
5301 (define_insn "smulsi3_highpart_v8plus"
5302 [(set (match_operand:SI 0 "register_operand" "=h,r")
5304 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5305 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5306 (match_operand:SI 3 "const_int_operand" "i,i"))))
5307 (clobber (match_scratch:SI 4 "=X,&h"))]
5310 smul %1,%2,%0\;srlx %0,%3,%0
5311 smul %1,%2,%4\;srlx %4,%3,%0"
5312 [(set_attr "length" "2")])
5314 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5317 [(set (match_operand:SI 0 "register_operand" "=h,r")
5320 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5321 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5322 (match_operand:SI 3 "const_int_operand" "i,i"))
5324 (clobber (match_scratch:SI 4 "=X,&h"))]
5327 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5328 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5329 [(set_attr "length" "2")])
5332 (define_insn "const_smulsi3_highpart_v8plus"
5333 [(set (match_operand:SI 0 "register_operand" "=h,r")
5335 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5336 (match_operand 2 "small_int" "i,i"))
5337 (match_operand:SI 3 "const_int_operand" "i,i"))))
5338 (clobber (match_scratch:SI 4 "=X,&h"))]
5341 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5342 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5343 [(set_attr "length" "2")])
5346 (define_insn "*smulsi3_highpart_sp32"
5347 [(set (match_operand:SI 0 "register_operand" "=r")
5349 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5350 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5352 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5353 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5354 [(set_attr "length" "2")])
5357 (define_insn "const_smulsi3_highpart"
5358 [(set (match_operand:SI 0 "register_operand" "=r")
5360 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5361 (match_operand:SI 2 "register_operand" "r"))
5363 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5364 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5365 [(set_attr "length" "2")])
5367 (define_expand "umulsidi3"
5368 [(set (match_operand:DI 0 "register_operand" "")
5369 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5370 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5374 if (CONSTANT_P (operands[2]))
5377 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5380 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5386 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5392 (define_insn "umulsidi3_v8plus"
5393 [(set (match_operand:DI 0 "register_operand" "=h,r")
5394 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5395 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5396 (clobber (match_scratch:SI 3 "=X,&h"))]
5399 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5400 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5401 [(set_attr "length" "2,3")])
5404 (define_insn "*umulsidi3_sp32"
5405 [(set (match_operand:DI 0 "register_operand" "=r")
5406 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5407 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5411 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5413 [(set (attr "length")
5414 (if_then_else (eq_attr "isa" "sparclet")
5415 (const_int 1) (const_int 2)))])
5417 (define_insn "*umulsidi3_sp64"
5418 [(set (match_operand:DI 0 "register_operand" "=r")
5419 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5420 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5421 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5423 [(set_attr "length" "1")])
5425 ;; Extra pattern, because sign_extend of a constant isn't valid.
5428 (define_insn "const_umulsidi3_sp32"
5429 [(set (match_operand:DI 0 "register_operand" "=r")
5430 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5431 (match_operand:SI 2 "uns_small_int" "")))]
5435 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5437 [(set (attr "length")
5438 (if_then_else (eq_attr "isa" "sparclet")
5439 (const_int 1) (const_int 2)))])
5441 (define_insn "const_umulsidi3_sp64"
5442 [(set (match_operand:DI 0 "register_operand" "=r")
5443 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5444 (match_operand:SI 2 "uns_small_int" "")))]
5445 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5447 [(set_attr "length" "1")])
5450 (define_insn "const_umulsidi3_v8plus"
5451 [(set (match_operand:DI 0 "register_operand" "=h,r")
5452 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5453 (match_operand:SI 2 "uns_small_int" "")))
5454 (clobber (match_scratch:SI 3 "=X,h"))]
5457 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5458 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5459 [(set_attr "length" "2,3")])
5461 (define_expand "umulsi3_highpart"
5462 [(set (match_operand:SI 0 "register_operand" "")
5464 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5465 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5467 "TARGET_HARD_MUL && TARGET_ARCH32"
5470 if (CONSTANT_P (operands[2]))
5474 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5480 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5485 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5486 operands[2], GEN_INT (32)));
5492 (define_insn "umulsi3_highpart_v8plus"
5493 [(set (match_operand:SI 0 "register_operand" "=h,r")
5495 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5496 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5497 (match_operand:SI 3 "const_int_operand" "i,i"))))
5498 (clobber (match_scratch:SI 4 "=X,h"))]
5501 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5502 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5503 [(set_attr "length" "2")])
5506 (define_insn "const_umulsi3_highpart_v8plus"
5507 [(set (match_operand:SI 0 "register_operand" "=h,r")
5509 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5510 (match_operand:SI 2 "uns_small_int" ""))
5511 (match_operand:SI 3 "const_int_operand" "i,i"))))
5512 (clobber (match_scratch:SI 4 "=X,h"))]
5515 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5516 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5517 [(set_attr "length" "2")])
5520 (define_insn "*umulsi3_highpart_sp32"
5521 [(set (match_operand:SI 0 "register_operand" "=r")
5523 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5524 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5526 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5527 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5528 [(set_attr "length" "2")])
5531 (define_insn "const_umulsi3_highpart"
5532 [(set (match_operand:SI 0 "register_operand" "=r")
5534 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5535 (match_operand:SI 2 "uns_small_int" ""))
5537 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5538 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5539 [(set_attr "length" "2")])
5541 ;; The v8 architecture specifies that there must be 3 instructions between
5542 ;; a y register write and a use of it for correct results.
5544 (define_expand "divsi3"
5545 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5546 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5547 (match_operand:SI 2 "input_operand" "rI,m")))
5548 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5549 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5554 operands[3] = gen_reg_rtx(SImode);
5555 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5556 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5562 (define_insn "divsi3_sp32"
5563 [(set (match_operand:SI 0 "register_operand" "=r,r")
5564 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5565 (match_operand:SI 2 "input_operand" "rI,m")))
5566 (clobber (match_scratch:SI 3 "=&r,&r"))]
5567 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5571 if (which_alternative == 0)
5573 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5575 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5578 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5580 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
5582 [(set (attr "length")
5583 (if_then_else (eq_attr "isa" "v9")
5584 (const_int 4) (const_int 7)))])
5586 (define_insn "divsi3_sp64"
5587 [(set (match_operand:SI 0 "register_operand" "=r")
5588 (div:SI (match_operand:SI 1 "register_operand" "r")
5589 (match_operand:SI 2 "input_operand" "rI")))
5590 (use (match_operand:SI 3 "register_operand" "r"))]
5591 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5592 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5593 [(set_attr "length" "2")])
5595 (define_insn "divdi3"
5596 [(set (match_operand:DI 0 "register_operand" "=r")
5597 (div:DI (match_operand:DI 1 "register_operand" "r")
5598 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5600 "sdivx\\t%1, %2, %0")
5602 (define_insn "*cmp_sdiv_cc_set"
5604 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5605 (match_operand:SI 2 "arith_operand" "rI"))
5607 (set (match_operand:SI 0 "register_operand" "=r")
5608 (div:SI (match_dup 1) (match_dup 2)))
5609 (clobber (match_scratch:SI 3 "=&r"))]
5610 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5614 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5616 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5618 [(set (attr "length")
5619 (if_then_else (eq_attr "isa" "v9")
5620 (const_int 3) (const_int 6)))])
5623 (define_expand "udivsi3"
5624 [(set (match_operand:SI 0 "register_operand" "")
5625 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5626 (match_operand:SI 2 "input_operand" "")))]
5627 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && ! TARGET_LIVE_G0"
5630 (define_insn "udivsi3_sp32"
5631 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5632 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5633 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5635 || TARGET_DEPRECATED_V8_INSNS)
5636 && TARGET_ARCH32 && ! TARGET_LIVE_G0"
5639 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
5640 switch (which_alternative)
5643 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
5645 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
5647 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
5650 [(set_attr "length" "5")])
5652 (define_insn "udivsi3_sp64"
5653 [(set (match_operand:SI 0 "register_operand" "=r")
5654 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5655 (match_operand:SI 2 "input_operand" "rI")))]
5656 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5657 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
5658 [(set_attr "length" "2")])
5660 (define_insn "udivdi3"
5661 [(set (match_operand:DI 0 "register_operand" "=r")
5662 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5663 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5665 "udivx\\t%1, %2, %0")
5667 (define_insn "*cmp_udiv_cc_set"
5669 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5670 (match_operand:SI 2 "arith_operand" "rI"))
5672 (set (match_operand:SI 0 "register_operand" "=r")
5673 (udiv:SI (match_dup 1) (match_dup 2)))]
5675 || TARGET_DEPRECATED_V8_INSNS)
5676 && ! TARGET_LIVE_G0"
5680 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
5682 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
5684 [(set (attr "length")
5685 (if_then_else (eq_attr "isa" "v9")
5686 (const_int 2) (const_int 5)))])
5688 ; sparclet multiply/accumulate insns
5690 (define_insn "*smacsi"
5691 [(set (match_operand:SI 0 "register_operand" "=r")
5692 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5693 (match_operand:SI 2 "arith_operand" "rI"))
5694 (match_operand:SI 3 "register_operand" "0")))]
5697 [(set_attr "type" "imul")
5698 (set_attr "length" "1")])
5700 (define_insn "*smacdi"
5701 [(set (match_operand:DI 0 "register_operand" "=r")
5702 (plus:DI (mult:DI (sign_extend:DI
5703 (match_operand:SI 1 "register_operand" "%r"))
5705 (match_operand:SI 2 "register_operand" "r")))
5706 (match_operand:DI 3 "register_operand" "0")))]
5708 "smacd\\t%1, %2, %L0"
5709 [(set_attr "type" "imul")
5710 (set_attr "length" "1")])
5712 (define_insn "*umacdi"
5713 [(set (match_operand:DI 0 "register_operand" "=r")
5714 (plus:DI (mult:DI (zero_extend:DI
5715 (match_operand:SI 1 "register_operand" "%r"))
5717 (match_operand:SI 2 "register_operand" "r")))
5718 (match_operand:DI 3 "register_operand" "0")))]
5720 "umacd\\t%1, %2, %L0"
5721 [(set_attr "type" "imul")
5722 (set_attr "length" "1")])
5724 ;;- Boolean instructions
5725 ;; We define DImode `and' so with DImode `not' we can get
5726 ;; DImode `andn'. Other combinations are possible.
5728 (define_expand "anddi3"
5729 [(set (match_operand:DI 0 "register_operand" "")
5730 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5731 (match_operand:DI 2 "arith_double_operand" "")))]
5735 (define_insn "*anddi3_sp32"
5736 [(set (match_operand:DI 0 "register_operand" "=r,b")
5737 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5738 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5743 [(set_attr "type" "ialu,fp")
5744 (set_attr "length" "2,1")])
5746 (define_insn "*anddi3_sp64"
5747 [(set (match_operand:DI 0 "register_operand" "=r,b")
5748 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5749 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5754 [(set_attr "type" "ialu,fp")
5755 (set_attr "length" "1,1")])
5757 (define_insn "andsi3"
5758 [(set (match_operand:SI 0 "register_operand" "=r,d")
5759 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5760 (match_operand:SI 2 "arith_operand" "rI,d")))]
5765 [(set_attr "type" "ialu,fp")
5766 (set_attr "length" "1,1")])
5769 [(set (match_operand:SI 0 "register_operand" "")
5770 (and:SI (match_operand:SI 1 "register_operand" "")
5771 (match_operand:SI 2 "" "")))
5772 (clobber (match_operand:SI 3 "register_operand" ""))]
5773 "GET_CODE (operands[2]) == CONST_INT
5774 && !SMALL_INT32 (operands[2])
5775 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5776 [(set (match_dup 3) (match_dup 4))
5777 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5780 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5783 ;; Split DImode logical operations requiring two instructions.
5785 [(set (match_operand:DI 0 "register_operand" "")
5786 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5787 [(match_operand:DI 2 "register_operand" "")
5788 (match_operand:DI 3 "arith_double_operand" "")]))]
5791 && ((GET_CODE (operands[0]) == REG
5792 && REGNO (operands[0]) < 32)
5793 || (GET_CODE (operands[0]) == SUBREG
5794 && GET_CODE (SUBREG_REG (operands[0])) == REG
5795 && REGNO (SUBREG_REG (operands[0])) < 32))"
5796 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5797 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5800 if (GET_CODE (operands[0]) == SUBREG)
5801 operands[0] = alter_subreg (operands[0]);
5802 operands[4] = gen_highpart (SImode, operands[0]);
5803 operands[5] = gen_lowpart (SImode, operands[0]);
5804 operands[6] = gen_highpart (SImode, operands[2]);
5805 operands[7] = gen_lowpart (SImode, operands[2]);
5806 if (GET_CODE (operands[3]) == CONST_INT)
5808 if (INTVAL (operands[3]) < 0)
5809 operands[8] = constm1_rtx;
5811 operands[8] = const0_rtx;
5814 operands[8] = gen_highpart (SImode, operands[3]);
5815 operands[9] = gen_lowpart (SImode, operands[3]);
5818 (define_insn "*and_not_di_sp32"
5819 [(set (match_operand:DI 0 "register_operand" "=r,b")
5820 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5821 (match_operand:DI 2 "register_operand" "r,b")))]
5825 fandnot1\\t%1, %2, %0"
5826 [(set_attr "type" "ialu,fp")
5827 (set_attr "length" "2,1")])
5830 [(set (match_operand:DI 0 "register_operand" "")
5831 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5832 (match_operand:DI 2 "register_operand" "")))]
5835 && ((GET_CODE (operands[0]) == REG
5836 && REGNO (operands[0]) < 32)
5837 || (GET_CODE (operands[0]) == SUBREG
5838 && GET_CODE (SUBREG_REG (operands[0])) == REG
5839 && REGNO (SUBREG_REG (operands[0])) < 32))"
5840 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5841 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5842 "if (GET_CODE (operands[0]) == SUBREG)
5843 operands[0] = alter_subreg (operands[0]);
5844 operands[3] = gen_highpart (SImode, operands[0]);
5845 operands[4] = gen_highpart (SImode, operands[1]);
5846 operands[5] = gen_highpart (SImode, operands[2]);
5847 operands[6] = gen_lowpart (SImode, operands[0]);
5848 operands[7] = gen_lowpart (SImode, operands[1]);
5849 operands[8] = gen_lowpart (SImode, operands[2]);")
5851 (define_insn "*and_not_di_sp64"
5852 [(set (match_operand:DI 0 "register_operand" "=r,b")
5853 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5854 (match_operand:DI 2 "register_operand" "r,b")))]
5858 fandnot1\\t%1, %2, %0"
5859 [(set_attr "type" "ialu,fp")
5860 (set_attr "length" "1,1")])
5862 (define_insn "*and_not_si"
5863 [(set (match_operand:SI 0 "register_operand" "=r,d")
5864 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5865 (match_operand:SI 2 "register_operand" "r,d")))]
5869 fandnot1s\\t%1, %2, %0"
5870 [(set_attr "type" "ialu,fp")
5871 (set_attr "length" "1,1")])
5873 (define_expand "iordi3"
5874 [(set (match_operand:DI 0 "register_operand" "")
5875 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5876 (match_operand:DI 2 "arith_double_operand" "")))]
5880 (define_insn "*iordi3_sp32"
5881 [(set (match_operand:DI 0 "register_operand" "=r,b")
5882 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5883 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5888 [(set_attr "type" "ialu,fp")
5889 (set_attr "length" "2,1")])
5891 (define_insn "*iordi3_sp64"
5892 [(set (match_operand:DI 0 "register_operand" "=r,b")
5893 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5894 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5899 [(set_attr "type" "ialu,fp")
5900 (set_attr "length" "1,1")])
5902 (define_insn "iorsi3"
5903 [(set (match_operand:SI 0 "register_operand" "=r,d")
5904 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
5905 (match_operand:SI 2 "arith_operand" "rI,d")))]
5910 [(set_attr "type" "ialu,fp")
5911 (set_attr "length" "1,1")])
5914 [(set (match_operand:SI 0 "register_operand" "")
5915 (ior:SI (match_operand:SI 1 "register_operand" "")
5916 (match_operand:SI 2 "" "")))
5917 (clobber (match_operand:SI 3 "register_operand" ""))]
5918 "GET_CODE (operands[2]) == CONST_INT
5919 && !SMALL_INT32 (operands[2])
5920 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5921 [(set (match_dup 3) (match_dup 4))
5922 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5925 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5928 (define_insn "*or_not_di_sp32"
5929 [(set (match_operand:DI 0 "register_operand" "=r,b")
5930 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5931 (match_operand:DI 2 "register_operand" "r,b")))]
5935 fornot1\\t%1, %2, %0"
5936 [(set_attr "type" "ialu,fp")
5937 (set_attr "length" "2,1")])
5940 [(set (match_operand:DI 0 "register_operand" "")
5941 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5942 (match_operand:DI 2 "register_operand" "")))]
5945 && ((GET_CODE (operands[0]) == REG
5946 && REGNO (operands[0]) < 32)
5947 || (GET_CODE (operands[0]) == SUBREG
5948 && GET_CODE (SUBREG_REG (operands[0])) == REG
5949 && REGNO (SUBREG_REG (operands[0])) < 32))"
5950 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5951 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5952 "if (GET_CODE (operands[0]) == SUBREG)
5953 operands[0] = alter_subreg (operands[0]);
5954 operands[3] = gen_highpart (SImode, operands[0]);
5955 operands[4] = gen_highpart (SImode, operands[1]);
5956 operands[5] = gen_highpart (SImode, operands[2]);
5957 operands[6] = gen_lowpart (SImode, operands[0]);
5958 operands[7] = gen_lowpart (SImode, operands[1]);
5959 operands[8] = gen_lowpart (SImode, operands[2]);")
5961 (define_insn "*or_not_di_sp64"
5962 [(set (match_operand:DI 0 "register_operand" "=r,b")
5963 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5964 (match_operand:DI 2 "register_operand" "r,b")))]
5968 fornot1\\t%1, %2, %0"
5969 [(set_attr "type" "ialu,fp")
5970 (set_attr "length" "1,1")])
5972 (define_insn "*or_not_si"
5973 [(set (match_operand:SI 0 "register_operand" "=r,d")
5974 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5975 (match_operand:SI 2 "register_operand" "r,d")))]
5979 fornot1s\\t%1, %2, %0"
5980 [(set_attr "type" "ialu,fp")
5981 (set_attr "length" "1,1")])
5983 (define_expand "xordi3"
5984 [(set (match_operand:DI 0 "register_operand" "")
5985 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
5986 (match_operand:DI 2 "arith_double_operand" "")))]
5990 (define_insn "*xordi3_sp32"
5991 [(set (match_operand:DI 0 "register_operand" "=r,b")
5992 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5993 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5998 [(set_attr "length" "2,1")
5999 (set_attr "type" "ialu,fp")])
6001 (define_insn "*xordi3_sp64"
6002 [(set (match_operand:DI 0 "register_operand" "=r,b")
6003 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6004 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6009 [(set_attr "type" "ialu,fp")
6010 (set_attr "length" "1,1")])
6012 (define_insn "*xordi3_sp64_dbl"
6013 [(set (match_operand:DI 0 "register_operand" "=r")
6014 (xor:DI (match_operand:DI 1 "register_operand" "r")
6015 (match_operand:DI 2 "const64_operand" "")))]
6017 && HOST_BITS_PER_WIDE_INT != 64)"
6019 [(set_attr "type" "ialu")
6020 (set_attr "length" "1")])
6022 (define_insn "xorsi3"
6023 [(set (match_operand:SI 0 "register_operand" "=r,d")
6024 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6025 (match_operand:SI 2 "arith_operand" "rI,d")))]
6030 [(set_attr "type" "ialu,fp")
6031 (set_attr "length" "1,1")])
6034 [(set (match_operand:SI 0 "register_operand" "")
6035 (xor:SI (match_operand:SI 1 "register_operand" "")
6036 (match_operand:SI 2 "" "")))
6037 (clobber (match_operand:SI 3 "register_operand" ""))]
6038 "GET_CODE (operands[2]) == CONST_INT
6039 && !SMALL_INT32 (operands[2])
6040 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6041 [(set (match_dup 3) (match_dup 4))
6042 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6045 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6049 [(set (match_operand:SI 0 "register_operand" "")
6050 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6051 (match_operand:SI 2 "" ""))))
6052 (clobber (match_operand:SI 3 "register_operand" ""))]
6053 "GET_CODE (operands[2]) == CONST_INT
6054 && !SMALL_INT32 (operands[2])
6055 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6056 [(set (match_dup 3) (match_dup 4))
6057 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6060 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6063 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6064 ;; Combine now canonicalizes to the rightmost expression.
6065 (define_insn "*xor_not_di_sp32"
6066 [(set (match_operand:DI 0 "register_operand" "=r,b")
6067 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6068 (match_operand:DI 2 "register_operand" "r,b"))))]
6073 [(set_attr "length" "2,1")
6074 (set_attr "type" "ialu,fp")])
6077 [(set (match_operand:DI 0 "register_operand" "")
6078 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6079 (match_operand:DI 2 "register_operand" ""))))]
6082 && ((GET_CODE (operands[0]) == REG
6083 && REGNO (operands[0]) < 32)
6084 || (GET_CODE (operands[0]) == SUBREG
6085 && GET_CODE (SUBREG_REG (operands[0])) == REG
6086 && REGNO (SUBREG_REG (operands[0])) < 32))"
6087 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6088 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6089 "if (GET_CODE (operands[0]) == SUBREG)
6090 operands[0] = alter_subreg (operands[0]);
6091 operands[3] = gen_highpart (SImode, operands[0]);
6092 operands[4] = gen_highpart (SImode, operands[1]);
6093 operands[5] = gen_highpart (SImode, operands[2]);
6094 operands[6] = gen_lowpart (SImode, operands[0]);
6095 operands[7] = gen_lowpart (SImode, operands[1]);
6096 operands[8] = gen_lowpart (SImode, operands[2]);")
6098 (define_insn "*xor_not_di_sp64"
6099 [(set (match_operand:DI 0 "register_operand" "=r,b")
6100 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6101 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6106 [(set_attr "type" "ialu,fp")
6107 (set_attr "length" "1,1")])
6109 (define_insn "*xor_not_si"
6110 [(set (match_operand:SI 0 "register_operand" "=r,d")
6111 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6112 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6116 fxnors\\t%1, %2, %0"
6117 [(set_attr "type" "ialu,fp")
6118 (set_attr "length" "1,1")])
6120 ;; These correspond to the above in the case where we also (or only)
6121 ;; want to set the condition code.
6123 (define_insn "*cmp_cc_arith_op"
6126 (match_operator:SI 2 "cc_arithop"
6127 [(match_operand:SI 0 "arith_operand" "%r")
6128 (match_operand:SI 1 "arith_operand" "rI")])
6131 "%A2cc\\t%0, %1, %%g0"
6132 [(set_attr "type" "compare")
6133 (set_attr "length" "1")])
6135 (define_insn "*cmp_ccx_arith_op"
6138 (match_operator:DI 2 "cc_arithop"
6139 [(match_operand:DI 0 "arith_double_operand" "%r")
6140 (match_operand:DI 1 "arith_double_operand" "rHI")])
6143 "%A2cc\\t%0, %1, %%g0"
6144 [(set_attr "type" "compare")
6145 (set_attr "length" "1")])
6147 (define_insn "*cmp_cc_arith_op_set"
6150 (match_operator:SI 3 "cc_arithop"
6151 [(match_operand:SI 1 "arith_operand" "%r")
6152 (match_operand:SI 2 "arith_operand" "rI")])
6154 (set (match_operand:SI 0 "register_operand" "=r")
6157 "%A3cc\\t%1, %2, %0"
6158 [(set_attr "type" "compare")
6159 (set_attr "length" "1")])
6161 (define_insn "*cmp_ccx_arith_op_set"
6164 (match_operator:DI 3 "cc_arithop"
6165 [(match_operand:DI 1 "arith_double_operand" "%r")
6166 (match_operand:DI 2 "arith_double_operand" "rHI")])
6168 (set (match_operand:DI 0 "register_operand" "=r")
6171 "%A3cc\\t%1, %2, %0"
6172 [(set_attr "type" "compare")
6173 (set_attr "length" "1")])
6175 (define_insn "*cmp_cc_xor_not"
6178 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6179 (match_operand:SI 1 "arith_operand" "rI")))
6182 "xnorcc\\t%r0, %1, %%g0"
6183 [(set_attr "type" "compare")
6184 (set_attr "length" "1")])
6186 (define_insn "*cmp_ccx_xor_not"
6189 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6190 (match_operand:DI 1 "arith_double_operand" "rHI")))
6193 "xnorcc\\t%r0, %1, %%g0"
6194 [(set_attr "type" "compare")
6195 (set_attr "length" "1")])
6197 (define_insn "*cmp_cc_xor_not_set"
6200 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6201 (match_operand:SI 2 "arith_operand" "rI")))
6203 (set (match_operand:SI 0 "register_operand" "=r")
6204 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6206 "xnorcc\\t%r1, %2, %0"
6207 [(set_attr "type" "compare")
6208 (set_attr "length" "1")])
6210 (define_insn "*cmp_ccx_xor_not_set"
6213 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6214 (match_operand:DI 2 "arith_double_operand" "rHI")))
6216 (set (match_operand:DI 0 "register_operand" "=r")
6217 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6219 "xnorcc\\t%r1, %2, %0"
6220 [(set_attr "type" "compare")
6221 (set_attr "length" "1")])
6223 (define_insn "*cmp_cc_arith_op_not"
6226 (match_operator:SI 2 "cc_arithopn"
6227 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6228 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6231 "%B2cc\\t%r1, %0, %%g0"
6232 [(set_attr "type" "compare")
6233 (set_attr "length" "1")])
6235 (define_insn "*cmp_ccx_arith_op_not"
6238 (match_operator:DI 2 "cc_arithopn"
6239 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6240 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6243 "%B2cc\\t%r1, %0, %%g0"
6244 [(set_attr "type" "compare")
6245 (set_attr "length" "1")])
6247 (define_insn "*cmp_cc_arith_op_not_set"
6250 (match_operator:SI 3 "cc_arithopn"
6251 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6252 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6254 (set (match_operand:SI 0 "register_operand" "=r")
6257 "%B3cc\\t%r2, %1, %0"
6258 [(set_attr "type" "compare")
6259 (set_attr "length" "1")])
6261 (define_insn "*cmp_ccx_arith_op_not_set"
6264 (match_operator:DI 3 "cc_arithopn"
6265 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6266 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6268 (set (match_operand:DI 0 "register_operand" "=r")
6271 "%B3cc\\t%r2, %1, %0"
6272 [(set_attr "type" "compare")
6273 (set_attr "length" "1")])
6275 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6276 ;; does not know how to make it work for constants.
6278 (define_expand "negdi2"
6279 [(set (match_operand:DI 0 "register_operand" "=r")
6280 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6284 if (! TARGET_ARCH64)
6286 emit_insn (gen_rtx_PARALLEL
6289 gen_rtx_SET (VOIDmode, operand0,
6290 gen_rtx_NEG (DImode, operand1)),
6291 gen_rtx_CLOBBER (VOIDmode,
6292 gen_rtx_REG (CCmode,
6298 (define_insn "*negdi2_sp32"
6299 [(set (match_operand:DI 0 "register_operand" "=r")
6300 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6301 (clobber (reg:CC 100))]
6303 && ! TARGET_LIVE_G0"
6305 [(set_attr "type" "unary")
6306 (set_attr "length" "2")])
6309 [(set (match_operand:DI 0 "register_operand" "")
6310 (neg:DI (match_operand:DI 1 "register_operand" "")))
6311 (clobber (reg:CC 100))]
6314 && reload_completed"
6315 [(parallel [(set (reg:CC_NOOV 100)
6316 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6318 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6319 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6320 (ltu:SI (reg:CC 100) (const_int 0))))]
6321 "operands[2] = gen_highpart (SImode, operands[0]);
6322 operands[3] = gen_highpart (SImode, operands[1]);
6323 operands[4] = gen_lowpart (SImode, operands[0]);
6324 operands[5] = gen_lowpart (SImode, operands[1]);")
6326 (define_insn "*negdi2_sp64"
6327 [(set (match_operand:DI 0 "register_operand" "=r")
6328 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6330 "sub\\t%%g0, %1, %0"
6331 [(set_attr "type" "unary")
6332 (set_attr "length" "1")])
6334 (define_expand "negsi2"
6335 [(set (match_operand:SI 0 "register_operand" "")
6336 (neg:SI (match_operand:SI 1 "arith_operand" "")))]
6342 rtx zero_reg = gen_reg_rtx (SImode);
6344 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6345 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6346 gen_rtx_MINUS (SImode, zero_reg,
6352 (define_insn "*negsi2_not_liveg0"
6353 [(set (match_operand:SI 0 "register_operand" "=r")
6354 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6356 "sub\\t%%g0, %1, %0"
6357 [(set_attr "type" "unary")
6358 (set_attr "length" "1")])
6360 (define_insn "*cmp_cc_neg"
6361 [(set (reg:CC_NOOV 100)
6362 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6365 "subcc\\t%%g0, %0, %%g0"
6366 [(set_attr "type" "compare")
6367 (set_attr "length" "1")])
6369 (define_insn "*cmp_ccx_neg"
6370 [(set (reg:CCX_NOOV 100)
6371 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6374 "subcc\\t%%g0, %0, %%g0"
6375 [(set_attr "type" "compare")
6376 (set_attr "length" "1")])
6378 (define_insn "*cmp_cc_set_neg"
6379 [(set (reg:CC_NOOV 100)
6380 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6382 (set (match_operand:SI 0 "register_operand" "=r")
6383 (neg:SI (match_dup 1)))]
6385 "subcc\\t%%g0, %1, %0"
6386 [(set_attr "type" "compare")
6387 (set_attr "length" "1")])
6389 (define_insn "*cmp_ccx_set_neg"
6390 [(set (reg:CCX_NOOV 100)
6391 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6393 (set (match_operand:DI 0 "register_operand" "=r")
6394 (neg:DI (match_dup 1)))]
6396 "subcc\\t%%g0, %1, %0"
6397 [(set_attr "type" "compare")
6398 (set_attr "length" "1")])
6400 ;; We cannot use the "not" pseudo insn because the Sun assembler
6401 ;; does not know how to make it work for constants.
6402 (define_expand "one_cmpldi2"
6403 [(set (match_operand:DI 0 "register_operand" "")
6404 (not:DI (match_operand:DI 1 "register_operand" "")))]
6408 (define_insn "*one_cmpldi2_sp32"
6409 [(set (match_operand:DI 0 "register_operand" "=r,b")
6410 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6415 [(set_attr "type" "unary,fp")
6416 (set_attr "length" "2,1")])
6419 [(set (match_operand:DI 0 "register_operand" "")
6420 (not:DI (match_operand:DI 1 "register_operand" "")))]
6423 && ((GET_CODE (operands[0]) == REG
6424 && REGNO (operands[0]) < 32)
6425 || (GET_CODE (operands[0]) == SUBREG
6426 && GET_CODE (SUBREG_REG (operands[0])) == REG
6427 && REGNO (SUBREG_REG (operands[0])) < 32))"
6428 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6429 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6430 "if (GET_CODE (operands[0]) == SUBREG)
6431 operands[0] = alter_subreg (operands[0]);
6432 operands[2] = gen_highpart (SImode, operands[0]);
6433 operands[3] = gen_highpart (SImode, operands[1]);
6434 operands[4] = gen_lowpart (SImode, operands[0]);
6435 operands[5] = gen_lowpart (SImode, operands[1]);")
6437 (define_insn "*one_cmpldi2_sp64"
6438 [(set (match_operand:DI 0 "register_operand" "=r,b")
6439 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6444 [(set_attr "type" "unary,fp")
6445 (set_attr "length" "1")])
6447 (define_expand "one_cmplsi2"
6448 [(set (match_operand:SI 0 "register_operand" "")
6449 (not:SI (match_operand:SI 1 "arith_operand" "")))]
6454 && GET_CODE (operands[1]) == CONST_INT)
6456 rtx zero_reg = gen_reg_rtx (SImode);
6458 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6459 emit_insn (gen_rtx_SET (VOIDmode,
6461 gen_rtx_NOT (SImode,
6462 gen_rtx_XOR (SImode,
6469 (define_insn "*one_cmplsi2_not_liveg0"
6470 [(set (match_operand:SI 0 "register_operand" "=r,d")
6471 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6476 [(set_attr "type" "unary,fp")
6477 (set_attr "length" "1,1")])
6479 (define_insn "*one_cmplsi2_liveg0"
6480 [(set (match_operand:SI 0 "register_operand" "=r,d")
6481 (not:SI (match_operand:SI 1 "arith_operand" "r,d")))]
6486 [(set_attr "type" "unary,fp")
6487 (set_attr "length" "1,1")])
6489 (define_insn "*cmp_cc_not"
6491 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6494 "xnorcc\\t%%g0, %0, %%g0"
6495 [(set_attr "type" "compare")
6496 (set_attr "length" "1")])
6498 (define_insn "*cmp_ccx_not"
6500 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6503 "xnorcc\\t%%g0, %0, %%g0"
6504 [(set_attr "type" "compare")
6505 (set_attr "length" "1")])
6507 (define_insn "*cmp_cc_set_not"
6509 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6511 (set (match_operand:SI 0 "register_operand" "=r")
6512 (not:SI (match_dup 1)))]
6514 "xnorcc\\t%%g0, %1, %0"
6515 [(set_attr "type" "compare")
6516 (set_attr "length" "1")])
6518 (define_insn "*cmp_ccx_set_not"
6520 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6522 (set (match_operand:DI 0 "register_operand" "=r")
6523 (not:DI (match_dup 1)))]
6525 "xnorcc\\t%%g0, %1, %0"
6526 [(set_attr "type" "compare")
6527 (set_attr "length" "1")])
6529 ;; Floating point arithmetic instructions.
6531 (define_insn "addtf3"
6532 [(set (match_operand:TF 0 "register_operand" "=e")
6533 (plus:TF (match_operand:TF 1 "register_operand" "e")
6534 (match_operand:TF 2 "register_operand" "e")))]
6535 "TARGET_FPU && TARGET_HARD_QUAD"
6536 "faddq\\t%1, %2, %0"
6537 [(set_attr "type" "fp")
6538 (set_attr "length" "1")])
6540 (define_insn "adddf3"
6541 [(set (match_operand:DF 0 "register_operand" "=e")
6542 (plus:DF (match_operand:DF 1 "register_operand" "e")
6543 (match_operand:DF 2 "register_operand" "e")))]
6545 "faddd\\t%1, %2, %0"
6546 [(set_attr "type" "fp")
6547 (set_attr "length" "1")])
6549 (define_insn "addsf3"
6550 [(set (match_operand:SF 0 "register_operand" "=f")
6551 (plus:SF (match_operand:SF 1 "register_operand" "f")
6552 (match_operand:SF 2 "register_operand" "f")))]
6554 "fadds\\t%1, %2, %0"
6555 [(set_attr "type" "fp")
6556 (set_attr "length" "1")])
6558 (define_insn "subtf3"
6559 [(set (match_operand:TF 0 "register_operand" "=e")
6560 (minus:TF (match_operand:TF 1 "register_operand" "e")
6561 (match_operand:TF 2 "register_operand" "e")))]
6562 "TARGET_FPU && TARGET_HARD_QUAD"
6563 "fsubq\\t%1, %2, %0"
6564 [(set_attr "type" "fp")
6565 (set_attr "length" "1")])
6567 (define_insn "subdf3"
6568 [(set (match_operand:DF 0 "register_operand" "=e")
6569 (minus:DF (match_operand:DF 1 "register_operand" "e")
6570 (match_operand:DF 2 "register_operand" "e")))]
6572 "fsubd\\t%1, %2, %0"
6573 [(set_attr "type" "fp")
6574 (set_attr "length" "1")])
6576 (define_insn "subsf3"
6577 [(set (match_operand:SF 0 "register_operand" "=f")
6578 (minus:SF (match_operand:SF 1 "register_operand" "f")
6579 (match_operand:SF 2 "register_operand" "f")))]
6581 "fsubs\\t%1, %2, %0"
6582 [(set_attr "type" "fp")
6583 (set_attr "length" "1")])
6585 (define_insn "multf3"
6586 [(set (match_operand:TF 0 "register_operand" "=e")
6587 (mult:TF (match_operand:TF 1 "register_operand" "e")
6588 (match_operand:TF 2 "register_operand" "e")))]
6589 "TARGET_FPU && TARGET_HARD_QUAD"
6590 "fmulq\\t%1, %2, %0"
6591 [(set_attr "type" "fpmul")
6592 (set_attr "length" "1")])
6594 (define_insn "muldf3"
6595 [(set (match_operand:DF 0 "register_operand" "=e")
6596 (mult:DF (match_operand:DF 1 "register_operand" "e")
6597 (match_operand:DF 2 "register_operand" "e")))]
6599 "fmuld\\t%1, %2, %0"
6600 [(set_attr "type" "fpmul")
6601 (set_attr "length" "1")])
6603 (define_insn "mulsf3"
6604 [(set (match_operand:SF 0 "register_operand" "=f")
6605 (mult:SF (match_operand:SF 1 "register_operand" "f")
6606 (match_operand:SF 2 "register_operand" "f")))]
6608 "fmuls\\t%1, %2, %0"
6609 [(set_attr "type" "fpmul")
6610 (set_attr "length" "1")])
6612 (define_insn "*muldf3_extend"
6613 [(set (match_operand:DF 0 "register_operand" "=e")
6614 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6615 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6616 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6617 "fsmuld\\t%1, %2, %0"
6618 [(set_attr "type" "fpmul")
6619 (set_attr "length" "1")])
6621 (define_insn "*multf3_extend"
6622 [(set (match_operand:TF 0 "register_operand" "=e")
6623 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6624 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6625 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6626 "fdmulq\\t%1, %2, %0"
6627 [(set_attr "type" "fpmul")
6628 (set_attr "length" "1")])
6630 ;; don't have timing for quad-prec. divide.
6631 (define_insn "divtf3"
6632 [(set (match_operand:TF 0 "register_operand" "=e")
6633 (div:TF (match_operand:TF 1 "register_operand" "e")
6634 (match_operand:TF 2 "register_operand" "e")))]
6635 "TARGET_FPU && TARGET_HARD_QUAD"
6636 "fdivq\\t%1, %2, %0"
6637 [(set_attr "type" "fpdivd")
6638 (set_attr "length" "1")])
6640 (define_insn "divdf3"
6641 [(set (match_operand:DF 0 "register_operand" "=e")
6642 (div:DF (match_operand:DF 1 "register_operand" "e")
6643 (match_operand:DF 2 "register_operand" "e")))]
6645 "fdivd\\t%1, %2, %0"
6646 [(set_attr "type" "fpdivd")
6647 (set_attr "length" "1")])
6649 (define_insn "divsf3"
6650 [(set (match_operand:SF 0 "register_operand" "=f")
6651 (div:SF (match_operand:SF 1 "register_operand" "f")
6652 (match_operand:SF 2 "register_operand" "f")))]
6654 "fdivs\\t%1, %2, %0"
6655 [(set_attr "type" "fpdivs")
6656 (set_attr "length" "1")])
6658 (define_expand "negtf2"
6659 [(set (match_operand:TF 0 "register_operand" "=e,e")
6660 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6664 (define_insn "*negtf2_notv9"
6665 [(set (match_operand:TF 0 "register_operand" "=e,e")
6666 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6667 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6673 [(set_attr "type" "fpmove")
6674 (set_attr "length" "1,2")])
6677 [(set (match_operand:TF 0 "register_operand" "")
6678 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6682 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6683 [(set (match_dup 2) (neg:SF (match_dup 3)))
6684 (set (match_dup 4) (match_dup 5))
6685 (set (match_dup 6) (match_dup 7))]
6686 "if (GET_CODE (operands[0]) == SUBREG)
6687 operands[0] = alter_subreg (operands[0]);
6688 if (GET_CODE (operands[1]) == SUBREG)
6689 operands[1] = alter_subreg (operands[1]);
6690 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6691 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6692 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6693 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6694 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6695 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6697 (define_insn "*negtf2_v9"
6698 [(set (match_operand:TF 0 "register_operand" "=e,e")
6699 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6700 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6701 "TARGET_FPU && TARGET_V9"
6705 [(set_attr "type" "fpmove")
6706 (set_attr "length" "1,2")])
6709 [(set (match_operand:TF 0 "register_operand" "")
6710 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6714 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6715 [(set (match_dup 2) (neg:DF (match_dup 3)))
6716 (set (match_dup 4) (match_dup 5))]
6717 "if (GET_CODE (operands[0]) == SUBREG)
6718 operands[0] = alter_subreg (operands[0]);
6719 if (GET_CODE (operands[1]) == SUBREG)
6720 operands[1] = alter_subreg (operands[1]);
6721 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6722 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6723 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6724 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6726 (define_expand "negdf2"
6727 [(set (match_operand:DF 0 "register_operand" "")
6728 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6732 (define_insn "*negdf2_notv9"
6733 [(set (match_operand:DF 0 "register_operand" "=e,e")
6734 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6735 "TARGET_FPU && ! TARGET_V9"
6739 [(set_attr "type" "fpmove")
6740 (set_attr "length" "1,2")])
6743 [(set (match_operand:DF 0 "register_operand" "")
6744 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6748 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6749 [(set (match_dup 2) (neg:SF (match_dup 3)))
6750 (set (match_dup 4) (match_dup 5))]
6751 "if (GET_CODE (operands[0]) == SUBREG)
6752 operands[0] = alter_subreg (operands[0]);
6753 if (GET_CODE (operands[1]) == SUBREG)
6754 operands[1] = alter_subreg (operands[1]);
6755 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6756 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6757 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6758 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6760 (define_insn "*negdf2_v9"
6761 [(set (match_operand:DF 0 "register_operand" "=e")
6762 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6763 "TARGET_FPU && TARGET_V9"
6765 [(set_attr "type" "fpmove")
6766 (set_attr "length" "1")])
6768 (define_insn "negsf2"
6769 [(set (match_operand:SF 0 "register_operand" "=f")
6770 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6773 [(set_attr "type" "fpmove")
6774 (set_attr "length" "1")])
6776 (define_expand "abstf2"
6777 [(set (match_operand:TF 0 "register_operand" "")
6778 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6782 (define_insn "*abstf2_notv9"
6783 [(set (match_operand:TF 0 "register_operand" "=e,e")
6784 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6785 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6786 "TARGET_FPU && ! TARGET_V9"
6790 [(set_attr "type" "fpmove")
6791 (set_attr "length" "1,2")])
6794 [(set (match_operand:TF 0 "register_operand" "=e,e")
6795 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6799 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6800 [(set (match_dup 2) (abs:SF (match_dup 3)))
6801 (set (match_dup 4) (match_dup 5))
6802 (set (match_dup 6) (match_dup 7))]
6803 "if (GET_CODE (operands[0]) == SUBREG)
6804 operands[0] = alter_subreg (operands[0]);
6805 if (GET_CODE (operands[1]) == SUBREG)
6806 operands[1] = alter_subreg (operands[1]);
6807 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6808 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6809 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6810 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6811 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6812 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6814 (define_insn "*abstf2_hq_v9"
6815 [(set (match_operand:TF 0 "register_operand" "=e,e")
6816 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6817 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6821 [(set_attr "type" "fpmove")
6822 (set_attr "length" "1")])
6824 (define_insn "*abstf2_v9"
6825 [(set (match_operand:TF 0 "register_operand" "=e,e")
6826 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6827 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6831 [(set_attr "type" "fpmove")
6832 (set_attr "length" "1,2")])
6835 [(set (match_operand:TF 0 "register_operand" "=e,e")
6836 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6840 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6841 [(set (match_dup 2) (abs:DF (match_dup 3)))
6842 (set (match_dup 4) (match_dup 5))]
6843 "if (GET_CODE (operands[0]) == SUBREG)
6844 operands[0] = alter_subreg (operands[0]);
6845 if (GET_CODE (operands[1]) == SUBREG)
6846 operands[1] = alter_subreg (operands[1]);
6847 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6848 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6849 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6850 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6852 (define_expand "absdf2"
6853 [(set (match_operand:DF 0 "register_operand" "")
6854 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6858 (define_insn "*absdf2_notv9"
6859 [(set (match_operand:DF 0 "register_operand" "=e,e")
6860 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6861 "TARGET_FPU && ! TARGET_V9"
6865 [(set_attr "type" "fpmove")
6866 (set_attr "length" "1,2")])
6869 [(set (match_operand:DF 0 "register_operand" "=e,e")
6870 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6874 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6875 [(set (match_dup 2) (abs:SF (match_dup 3)))
6876 (set (match_dup 4) (match_dup 5))]
6877 "if (GET_CODE (operands[0]) == SUBREG)
6878 operands[0] = alter_subreg (operands[0]);
6879 if (GET_CODE (operands[1]) == SUBREG)
6880 operands[1] = alter_subreg (operands[1]);
6881 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6882 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6883 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6884 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6886 (define_insn "*absdf2_v9"
6887 [(set (match_operand:DF 0 "register_operand" "=e")
6888 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6889 "TARGET_FPU && TARGET_V9"
6891 [(set_attr "type" "fpmove")
6892 (set_attr "length" "1")])
6894 (define_insn "abssf2"
6895 [(set (match_operand:SF 0 "register_operand" "=f")
6896 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6899 [(set_attr "type" "fpmove")
6900 (set_attr "length" "1")])
6902 (define_insn "sqrttf2"
6903 [(set (match_operand:TF 0 "register_operand" "=e")
6904 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6905 "TARGET_FPU && TARGET_HARD_QUAD"
6907 [(set_attr "type" "fpsqrtd")
6908 (set_attr "length" "1")])
6910 (define_insn "sqrtdf2"
6911 [(set (match_operand:DF 0 "register_operand" "=e")
6912 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6915 [(set_attr "type" "fpsqrtd")
6916 (set_attr "length" "1")])
6918 (define_insn "sqrtsf2"
6919 [(set (match_operand:SF 0 "register_operand" "=f")
6920 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6923 [(set_attr "type" "fpsqrts")
6924 (set_attr "length" "1")])
6926 ;;- arithmetic shift instructions
6928 (define_insn "ashlsi3"
6929 [(set (match_operand:SI 0 "register_operand" "=r")
6930 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6931 (match_operand:SI 2 "arith_operand" "rI")))]
6935 if (GET_CODE (operands[2]) == CONST_INT
6936 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
6937 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6939 return \"sll\\t%1, %2, %0\";
6941 [(set_attr "type" "shift")
6942 (set_attr "length" "1")])
6944 ;; We special case multiplication by two, as add can be done
6945 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
6946 (define_insn "*ashlsi3_const1"
6947 [(set (match_operand:SI 0 "register_operand" "=r")
6948 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6952 [(set_attr "type" "binary")
6953 (set_attr "length" "1")])
6955 (define_expand "ashldi3"
6956 [(set (match_operand:DI 0 "register_operand" "=r")
6957 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6958 (match_operand:SI 2 "arith_operand" "rI")))]
6959 "TARGET_ARCH64 || TARGET_V8PLUS"
6962 if (! TARGET_ARCH64)
6964 if (GET_CODE (operands[2]) == CONST_INT)
6966 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6971 ;; We special case multiplication by two, as add can be done
6972 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
6973 (define_insn "*ashldi3_const1"
6974 [(set (match_operand:DI 0 "register_operand" "=r")
6975 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6979 [(set_attr "type" "binary")
6980 (set_attr "length" "1")])
6982 (define_insn "*ashldi3_sp64"
6983 [(set (match_operand:DI 0 "register_operand" "=r")
6984 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6985 (match_operand:SI 2 "arith_operand" "rI")))]
6989 if (GET_CODE (operands[2]) == CONST_INT
6990 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
6991 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6993 return \"sllx\\t%1, %2, %0\";
6995 [(set_attr "type" "shift")
6996 (set_attr "length" "1")])
6999 (define_insn "ashldi3_v8plus"
7000 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7001 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7002 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7003 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7005 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7006 [(set_attr "length" "5,5,6")])
7008 ;; Optimize (1LL<<x)-1
7009 ;; XXX this also needs to be fixed to handle equal subregs
7010 ;; XXX first before we could re-enable it.
7012 [(set (match_operand:DI 0 "register_operand" "=h")
7013 (plus:DI (ashift:DI (const_int 1)
7014 (match_operand:SI 2 "arith_operand" "rI"))
7016 "0 && TARGET_V8PLUS"
7019 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
7020 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7021 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7023 [(set_attr "length" "4")])
7025 (define_insn "*cmp_cc_ashift_1"
7026 [(set (reg:CC_NOOV 100)
7027 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7031 "addcc\\t%0, %0, %%g0"
7032 [(set_attr "type" "compare")
7033 (set_attr "length" "1")])
7035 (define_insn "*cmp_cc_set_ashift_1"
7036 [(set (reg:CC_NOOV 100)
7037 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7040 (set (match_operand:SI 0 "register_operand" "=r")
7041 (ashift:SI (match_dup 1) (const_int 1)))]
7043 "addcc\\t%1, %1, %0"
7044 [(set_attr "type" "compare")
7045 (set_attr "length" "1")])
7047 (define_insn "ashrsi3"
7048 [(set (match_operand:SI 0 "register_operand" "=r")
7049 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7050 (match_operand:SI 2 "arith_operand" "rI")))]
7054 if (GET_CODE (operands[2]) == CONST_INT
7055 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7056 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7058 return \"sra\\t%1, %2, %0\";
7060 [(set_attr "type" "shift")
7061 (set_attr "length" "1")])
7063 (define_insn "*ashrsi3_extend"
7064 [(set (match_operand:DI 0 "register_operand" "=r")
7065 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7066 (match_operand:SI 2 "arith_operand" "r"))))]
7069 [(set_attr "type" "shift")
7070 (set_attr "length" "1")])
7072 ;; This handles the case as above, but with constant shift instead of
7073 ;; register. Combiner "simplifies" it for us a little bit though.
7074 (define_insn "*ashrsi3_extend2"
7075 [(set (match_operand:DI 0 "register_operand" "=r")
7076 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7078 (match_operand:SI 2 "small_int_or_double" "n")))]
7080 && ((GET_CODE (operands[2]) == CONST_INT
7081 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7082 || (GET_CODE (operands[2]) == CONST_DOUBLE
7083 && !CONST_DOUBLE_HIGH (operands[2])
7084 && CONST_DOUBLE_LOW (operands[2]) >= 32
7085 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7088 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7090 return \"sra\\t%1, %2, %0\";
7092 [(set_attr "type" "shift")
7093 (set_attr "length" "1")])
7095 (define_expand "ashrdi3"
7096 [(set (match_operand:DI 0 "register_operand" "=r")
7097 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7098 (match_operand:SI 2 "arith_operand" "rI")))]
7099 "TARGET_ARCH64 || TARGET_V8PLUS"
7102 if (! TARGET_ARCH64)
7104 if (GET_CODE (operands[2]) == CONST_INT)
7105 FAIL; /* prefer generic code in this case */
7106 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
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")))]
7118 if (GET_CODE (operands[2]) == CONST_INT
7119 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7120 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7122 return \"srax\\t%1, %2, %0\";
7124 [(set_attr "type" "shift")
7125 (set_attr "length" "1")])
7128 (define_insn "ashrdi3_v8plus"
7129 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7130 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7131 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7132 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7134 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7135 [(set_attr "length" "5,5,6")])
7137 (define_insn "lshrsi3"
7138 [(set (match_operand:SI 0 "register_operand" "=r")
7139 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7140 (match_operand:SI 2 "arith_operand" "rI")))]
7144 if (GET_CODE (operands[2]) == CONST_INT
7145 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7146 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7148 return \"srl\\t%1, %2, %0\";
7150 [(set_attr "type" "shift")
7151 (set_attr "length" "1")])
7153 ;; This handles the case where
7154 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7155 ;; but combiner "simplifies" it for us.
7156 (define_insn "*lshrsi3_extend"
7157 [(set (match_operand:DI 0 "register_operand" "=r")
7158 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7159 (match_operand:SI 2 "arith_operand" "r")) 0)
7160 (match_operand 3 "" "")))]
7162 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7163 && CONST_DOUBLE_HIGH (operands[3]) == 0
7164 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7165 #if HOST_BITS_PER_WIDE_INT >= 64
7166 || (GET_CODE (operands[3]) == CONST_INT
7167 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
7171 [(set_attr "type" "shift")
7172 (set_attr "length" "1")])
7174 ;; This handles the case where
7175 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7176 ;; but combiner "simplifies" it for us.
7177 (define_insn "*lshrsi3_extend2"
7178 [(set (match_operand:DI 0 "register_operand" "=r")
7179 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7180 (match_operand 2 "small_int_or_double" "n")
7183 && ((GET_CODE (operands[2]) == CONST_INT
7184 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7185 || (GET_CODE (operands[2]) == CONST_DOUBLE
7186 && CONST_DOUBLE_HIGH (operands[2]) == 0
7187 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7190 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7192 return \"srl\\t%1, %2, %0\";
7194 [(set_attr "type" "shift")
7195 (set_attr "length" "1")])
7197 (define_expand "lshrdi3"
7198 [(set (match_operand:DI 0 "register_operand" "=r")
7199 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7200 (match_operand:SI 2 "arith_operand" "rI")))]
7201 "TARGET_ARCH64 || TARGET_V8PLUS"
7204 if (! TARGET_ARCH64)
7206 if (GET_CODE (operands[2]) == CONST_INT)
7208 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
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")))]
7220 if (GET_CODE (operands[2]) == CONST_INT
7221 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7222 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7224 return \"srlx\\t%1, %2, %0\";
7226 [(set_attr "type" "shift")
7227 (set_attr "length" "1")])
7230 (define_insn "lshrdi3_v8plus"
7231 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7232 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7233 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7234 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7236 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7237 [(set_attr "length" "5,5,6")])
7240 [(set (match_operand:SI 0 "register_operand" "=r")
7241 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7243 (match_operand:SI 2 "small_int_or_double" "n")))]
7245 && ((GET_CODE (operands[2]) == CONST_INT
7246 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7247 || (GET_CODE (operands[2]) == CONST_DOUBLE
7248 && !CONST_DOUBLE_HIGH (operands[2])
7249 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7252 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7254 return \"srax\\t%1, %2, %0\";
7256 [(set_attr "type" "shift")
7257 (set_attr "length" "1")])
7260 [(set (match_operand:SI 0 "register_operand" "=r")
7261 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7263 (match_operand:SI 2 "small_int_or_double" "n")))]
7265 && ((GET_CODE (operands[2]) == CONST_INT
7266 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7267 || (GET_CODE (operands[2]) == CONST_DOUBLE
7268 && !CONST_DOUBLE_HIGH (operands[2])
7269 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7272 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7274 return \"srlx\\t%1, %2, %0\";
7276 [(set_attr "type" "shift")
7277 (set_attr "length" "1")])
7280 [(set (match_operand:SI 0 "register_operand" "=r")
7281 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7282 (match_operand:SI 2 "small_int_or_double" "n")) 0)
7283 (match_operand:SI 3 "small_int_or_double" "n")))]
7285 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7286 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7287 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7288 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7291 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7293 return \"srax\\t%1, %2, %0\";
7295 [(set_attr "type" "shift")
7296 (set_attr "length" "1")])
7299 [(set (match_operand:SI 0 "register_operand" "=r")
7300 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7301 (match_operand:SI 2 "small_int_or_double" "n")) 0)
7302 (match_operand:SI 3 "small_int_or_double" "n")))]
7304 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7305 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7306 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7307 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7310 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7312 return \"srlx\\t%1, %2, %0\";
7314 [(set_attr "type" "shift")
7315 (set_attr "length" "1")])
7317 ;; Unconditional and other jump instructions
7318 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7319 ;; following insn is never executed. This saves us a nop. Dbx does not
7320 ;; handle such branches though, so we only use them when optimizing.
7322 [(set (pc) (label_ref (match_operand 0 "" "")))]
7326 /* TurboSparc is reported to have problems with
7329 i.e. an empty loop with the annul bit set. The workaround is to use
7333 if (! TARGET_V9 && flag_delayed_branch
7334 && (insn_addresses[INSN_UID (operands[0])]
7335 == insn_addresses[INSN_UID (insn)]))
7336 return \"b\\t%l0%#\";
7338 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7340 [(set_attr "type" "uncond_branch")])
7342 (define_expand "tablejump"
7343 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7344 (use (label_ref (match_operand 1 "" "")))])]
7348 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7351 /* In pic mode, our address differences are against the base of the
7352 table. Add that base value back in; CSE ought to be able to combine
7353 the two address loads. */
7357 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7359 if (CASE_VECTOR_MODE != Pmode)
7360 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7361 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7362 operands[0] = memory_address (Pmode, tmp);
7366 (define_insn "*tablejump_sp32"
7367 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7368 (use (label_ref (match_operand 1 "" "")))]
7371 [(set_attr "type" "uncond_branch")])
7373 (define_insn "*tablejump_sp64"
7374 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7375 (use (label_ref (match_operand 1 "" "")))]
7378 [(set_attr "type" "uncond_branch")])
7380 ;; This pattern recognizes the "instruction" that appears in
7381 ;; a function call that wants a structure value,
7382 ;; to inform the called function if compiled with Sun CC.
7383 ;(define_insn "*unimp_insn"
7384 ; [(match_operand:SI 0 "immediate_operand" "")]
7385 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7387 ; [(set_attr "type" "marker")])
7389 ;;- jump to subroutine
7390 (define_expand "call"
7391 ;; Note that this expression is not used for generating RTL.
7392 ;; All the RTL is generated explicitly below.
7393 [(call (match_operand 0 "call_operand" "")
7394 (match_operand 3 "" "i"))]
7395 ;; operands[2] is next_arg_register
7396 ;; operands[3] is struct_value_size_rtx.
7400 rtx fn_rtx, nregs_rtx;
7402 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7405 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7407 /* This is really a PIC sequence. We want to represent
7408 it as a funny jump so its delay slots can be filled.
7410 ??? But if this really *is* a CALL, will not it clobber the
7411 call-clobbered registers? We lose this if it is a JUMP_INSN.
7412 Why cannot we have delay slots filled if it were a CALL? */
7414 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7419 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7421 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7427 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7428 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7432 fn_rtx = operands[0];
7434 /* Count the number of parameter registers being used by this call.
7435 if that argument is NULL, it means we are using them all, which
7436 means 6 on the sparc. */
7439 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7441 nregs_rtx = GEN_INT (6);
7443 nregs_rtx = const0_rtx;
7446 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7450 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7452 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7457 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7458 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7462 /* If this call wants a structure value,
7463 emit an unimp insn to let the called function know about this. */
7464 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7466 rtx insn = emit_insn (operands[3]);
7467 SCHED_GROUP_P (insn) = 1;
7474 ;; We can't use the same pattern for these two insns, because then registers
7475 ;; in the address may not be properly reloaded.
7477 (define_insn "*call_address_sp32"
7478 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7479 (match_operand 1 "" ""))
7480 (clobber (reg:SI 15))]
7481 ;;- Do not use operand 1 for most machines.
7484 [(set_attr "type" "call")])
7486 (define_insn "*call_symbolic_sp32"
7487 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7488 (match_operand 1 "" ""))
7489 (clobber (reg:SI 15))]
7490 ;;- Do not use operand 1 for most machines.
7493 [(set_attr "type" "call")])
7495 (define_insn "*call_address_sp64"
7496 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
7497 (match_operand 1 "" ""))
7498 (clobber (reg:DI 15))]
7499 ;;- Do not use operand 1 for most machines.
7502 [(set_attr "type" "call")])
7504 (define_insn "*call_symbolic_sp64"
7505 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
7506 (match_operand 1 "" ""))
7507 (clobber (reg:DI 15))]
7508 ;;- Do not use operand 1 for most machines.
7511 [(set_attr "type" "call")])
7513 ;; This is a call that wants a structure value.
7514 ;; There is no such critter for v9 (??? we may need one anyway).
7515 (define_insn "*call_address_struct_value_sp32"
7516 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7517 (match_operand 1 "" ""))
7518 (match_operand 2 "immediate_operand" "")
7519 (clobber (reg:SI 15))]
7520 ;;- Do not use operand 1 for most machines.
7521 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7522 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7523 [(set_attr "type" "call_no_delay_slot")])
7525 ;; This is a call that wants a structure value.
7526 ;; There is no such critter for v9 (??? we may need one anyway).
7527 (define_insn "*call_symbolic_struct_value_sp32"
7528 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7529 (match_operand 1 "" ""))
7530 (match_operand 2 "immediate_operand" "")
7531 (clobber (reg:SI 15))]
7532 ;;- Do not use operand 1 for most machines.
7533 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7534 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7535 [(set_attr "type" "call_no_delay_slot")])
7537 ;; This is a call that may want a structure value. This is used for
7539 (define_insn "*call_address_untyped_struct_value_sp32"
7540 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7541 (match_operand 1 "" ""))
7542 (match_operand 2 "immediate_operand" "")
7543 (clobber (reg:SI 15))]
7544 ;;- Do not use operand 1 for most machines.
7545 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7546 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7547 [(set_attr "type" "call_no_delay_slot")])
7549 ;; This is a call that wants a structure value.
7550 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7551 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7552 (match_operand 1 "" ""))
7553 (match_operand 2 "immediate_operand" "")
7554 (clobber (reg:SI 15))]
7555 ;;- Do not use operand 1 for most machines.
7556 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7557 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7558 [(set_attr "type" "call_no_delay_slot")])
7560 (define_expand "call_value"
7561 ;; Note that this expression is not used for generating RTL.
7562 ;; All the RTL is generated explicitly below.
7563 [(set (match_operand 0 "register_operand" "=rf")
7564 (call (match_operand:SI 1 "" "")
7565 (match_operand 4 "" "")))]
7566 ;; operand 2 is stack_size_rtx
7567 ;; operand 3 is next_arg_register
7571 rtx fn_rtx, nregs_rtx;
7574 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7577 fn_rtx = operands[1];
7581 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7583 nregs_rtx = GEN_INT (6);
7585 nregs_rtx = const0_rtx;
7589 gen_rtx_SET (VOIDmode, operands[0],
7590 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7591 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7593 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7598 (define_insn "*call_value_address_sp32"
7599 [(set (match_operand 0 "" "=rf")
7600 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7601 (match_operand 2 "" "")))
7602 (clobber (reg:SI 15))]
7603 ;;- Do not use operand 2 for most machines.
7606 [(set_attr "type" "call")])
7608 (define_insn "*call_value_symbolic_sp32"
7609 [(set (match_operand 0 "" "=rf")
7610 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7611 (match_operand 2 "" "")))
7612 (clobber (reg:SI 15))]
7613 ;;- Do not use operand 2 for most machines.
7616 [(set_attr "type" "call")])
7618 (define_insn "*call_value_address_sp64"
7619 [(set (match_operand 0 "" "")
7620 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
7621 (match_operand 2 "" "")))
7622 (clobber (reg:DI 15))]
7623 ;;- Do not use operand 2 for most machines.
7626 [(set_attr "type" "call")])
7628 (define_insn "*call_value_symbolic_sp64"
7629 [(set (match_operand 0 "" "")
7630 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
7631 (match_operand 2 "" "")))
7632 (clobber (reg:DI 15))]
7633 ;;- Do not use operand 2 for most machines.
7636 [(set_attr "type" "call")])
7638 (define_expand "untyped_call"
7639 [(parallel [(call (match_operand 0 "" "")
7641 (match_operand 1 "" "")
7642 (match_operand 2 "" "")])]
7648 /* Pass constm1 to indicate that it may expect a structure value, but
7649 we don't know what size it is. */
7650 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7652 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7654 rtx set = XVECEXP (operands[2], 0, i);
7655 emit_move_insn (SET_DEST (set), SET_SRC (set));
7658 /* The optimizer does not know that the call sets the function value
7659 registers we stored in the result block. We avoid problems by
7660 claiming that all hard registers are used and clobbered at this
7662 emit_insn (gen_blockage ());
7667 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7668 ;; all of memory. This blocks insns from being moved across this point.
7670 (define_insn "blockage"
7671 [(unspec_volatile [(const_int 0)] 0)]
7674 [(set_attr "length" "0")])
7676 ;; Prepare to return any type including a structure value.
7678 (define_expand "untyped_return"
7679 [(match_operand:BLK 0 "memory_operand" "")
7680 (match_operand 1 "" "")]
7684 rtx valreg1 = gen_rtx_REG (DImode, 24);
7685 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7686 rtx result = operands[0];
7688 if (! TARGET_ARCH64)
7690 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7692 rtx value = gen_reg_rtx (SImode);
7694 /* Fetch the instruction where we will return to and see if it's an unimp
7695 instruction (the most significant 10 bits will be zero). If so,
7696 update the return address to skip the unimp instruction. */
7697 emit_move_insn (value,
7698 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7699 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7700 emit_insn (gen_update_return (rtnreg, value));
7703 /* Reload the function value registers. */
7704 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
7705 emit_move_insn (valreg2,
7706 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
7707 plus_constant (XEXP (result, 0), 8)));
7709 /* Put USE insns before the return. */
7710 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7711 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7713 /* Construct the return. */
7714 expand_null_return ();
7719 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7720 ;; and parts of the compiler don't want to believe that the add is needed.
7722 (define_insn "update_return"
7723 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7724 (match_operand:SI 1 "register_operand" "r")] 1)]
7726 "cmp %1,0\;be,a .+8\;add %0,4,%0"
7727 [(set_attr "type" "multi")])
7729 (define_insn "return"
7733 "* return output_return (operands);"
7734 [(set_attr "type" "return")])
7737 [(set (match_operand:SI 0 "register_operand" "=r")
7738 (match_operand:SI 1 "arith_operand" "rI"))
7740 (use (reg:SI 31))])]
7741 "sparc_return_peephole_ok (operands[0], operands[1])"
7742 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
7748 [(set_attr "type" "ialu")
7749 (set_attr "length" "1")])
7751 (define_expand "indirect_jump"
7752 [(set (pc) (match_operand 0 "address_operand" "p"))]
7756 (define_insn "*branch_sp32"
7757 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7760 [(set_attr "type" "uncond_branch")])
7762 (define_insn "*branch_sp64"
7763 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7766 [(set_attr "type" "uncond_branch")])
7768 ;; ??? Doesn't work with -mflat.
7769 (define_expand "nonlocal_goto"
7770 [(match_operand:SI 0 "general_operand" "")
7771 (match_operand:SI 1 "general_operand" "")
7772 (match_operand:SI 2 "general_operand" "")
7773 (match_operand:SI 3 "" "")]
7778 rtx chain = operands[0];
7780 rtx fp = operands[1];
7781 rtx stack = operands[2];
7782 rtx lab = operands[3];
7785 /* Trap instruction to flush all the register windows. */
7786 emit_insn (gen_flush_register_windows ());
7788 /* Load the fp value for the containing fn into %fp. This is needed
7789 because STACK refers to %fp. Note that virtual register instantiation
7790 fails if the virtual %fp isn't set from a register. */
7791 if (GET_CODE (fp) != REG)
7792 fp = force_reg (Pmode, fp);
7793 emit_move_insn (virtual_stack_vars_rtx, fp);
7795 /* Find the containing function's current nonlocal goto handler,
7796 which will do any cleanups and then jump to the label. */
7797 labreg = gen_rtx_REG (Pmode, 8);
7798 emit_move_insn (labreg, lab);
7800 /* Restore %fp from stack pointer value for containing function.
7801 The restore insn that follows will move this to %sp,
7802 and reload the appropriate value into %fp. */
7803 emit_move_insn (frame_pointer_rtx, stack);
7805 /* USE of frame_pointer_rtx added for consistency; not clear if
7807 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7808 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7811 /* Return, restoring reg window and jumping to goto handler. */
7812 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7813 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7815 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
7820 /* Put in the static chain register the nonlocal label address. */
7821 emit_move_insn (static_chain_rtx, chain);
7824 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7825 emit_insn (gen_goto_handler_and_restore (labreg));
7830 ;; Special trap insn to flush register windows.
7831 (define_insn "flush_register_windows"
7832 [(unspec_volatile [(const_int 0)] 1)]
7834 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
7835 [(set_attr "type" "misc")
7836 (set_attr "length" "1")])
7838 (define_insn "goto_handler_and_restore"
7839 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
7840 "GET_MODE (operands[0]) == Pmode"
7841 "jmp\\t%0+0\\n\\trestore"
7842 [(set_attr "type" "misc")
7843 (set_attr "length" "2")])
7845 ;;(define_insn "goto_handler_and_restore_v9"
7846 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7847 ;; (match_operand:SI 1 "register_operand" "=r,r")
7848 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7849 ;; "TARGET_V9 && ! TARGET_ARCH64"
7851 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7852 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7853 ;; [(set_attr "type" "misc")
7854 ;; (set_attr "length" "2,3")])
7856 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7857 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7858 ;; (match_operand:DI 1 "register_operand" "=r,r")
7859 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7860 ;; "TARGET_V9 && TARGET_ARCH64"
7862 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7863 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7864 ;; [(set_attr "type" "misc")
7865 ;; (set_attr "length" "2,3")])
7867 ;; Pattern for use after a setjmp to store FP and the return register
7868 ;; into the stack area.
7870 (define_expand "setjmp"
7876 emit_insn (gen_setjmp_64 ());
7878 emit_insn (gen_setjmp_32 ());
7882 (define_expand "setjmp_32"
7883 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7884 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7887 { operands[0] = frame_pointer_rtx; }")
7889 (define_expand "setjmp_64"
7890 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7891 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7894 { operands[0] = frame_pointer_rtx; }")
7896 ;; Special pattern for the FLUSH instruction.
7898 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7899 ; of the define_insn otherwise missing a mode. We make "flush", aka
7900 ; gen_flush, the default one since sparc_initialize_trampoline uses
7901 ; it on SImode mem values.
7903 (define_insn "flush"
7904 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
7906 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
7907 [(set_attr "type" "misc")])
7909 (define_insn "flushdi"
7910 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
7912 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
7913 [(set_attr "type" "misc")])
7918 ;; The scan instruction searches from the most significant bit while ffs
7919 ;; searches from the least significant bit. The bit index and treatment of
7920 ;; zero also differ. It takes at least 7 instructions to get the proper
7921 ;; result. Here is an obvious 8 instruction sequence.
7924 (define_insn "ffssi2"
7925 [(set (match_operand:SI 0 "register_operand" "=&r")
7926 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7927 (clobber (match_scratch:SI 2 "=&r"))]
7928 "TARGET_SPARCLITE || TARGET_SPARCLET"
7932 output_asm_insn (\"and %%g0,0,%%g0\", operands);
7933 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\";
7935 [(set_attr "type" "multi")
7936 (set_attr "length" "8")])
7938 ;; ??? This should be a define expand, so that the extra instruction have
7939 ;; a chance of being optimized away.
7941 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
7942 ;; does, but no one uses that and we don't have a switch for it.
7944 ;(define_insn "ffsdi2"
7945 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7946 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7947 ; (clobber (match_scratch:DI 2 "=&r"))]
7949 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
7950 ; [(set_attr "type" "multi")
7951 ; (set_attr "length" "4")])
7955 ;; Peepholes go at the end.
7957 ;; Optimize consecutive loads or stores into ldd and std when possible.
7958 ;; The conditions in which we do this are very restricted and are
7959 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7962 [(set (match_operand:SI 0 "memory_operand" "")
7964 (set (match_operand:SI 1 "memory_operand" "")
7967 && ! MEM_VOLATILE_P (operands[0])
7968 && ! MEM_VOLATILE_P (operands[1])
7969 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
7973 [(set (match_operand:SI 0 "memory_operand" "")
7975 (set (match_operand:SI 1 "memory_operand" "")
7978 && ! MEM_VOLATILE_P (operands[0])
7979 && ! MEM_VOLATILE_P (operands[1])
7980 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
7984 [(set (match_operand:SI 0 "register_operand" "=rf")
7985 (match_operand:SI 1 "memory_operand" ""))
7986 (set (match_operand:SI 2 "register_operand" "=rf")
7987 (match_operand:SI 3 "memory_operand" ""))]
7988 "registers_ok_for_ldd_peep (operands[0], operands[2])
7989 && ! MEM_VOLATILE_P (operands[1])
7990 && ! MEM_VOLATILE_P (operands[3])
7991 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7995 [(set (match_operand:SI 0 "memory_operand" "")
7996 (match_operand:SI 1 "register_operand" "rf"))
7997 (set (match_operand:SI 2 "memory_operand" "")
7998 (match_operand:SI 3 "register_operand" "rf"))]
7999 "registers_ok_for_ldd_peep (operands[1], operands[3])
8000 && ! MEM_VOLATILE_P (operands[0])
8001 && ! MEM_VOLATILE_P (operands[2])
8002 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8006 [(set (match_operand:SF 0 "register_operand" "=fr")
8007 (match_operand:SF 1 "memory_operand" ""))
8008 (set (match_operand:SF 2 "register_operand" "=fr")
8009 (match_operand:SF 3 "memory_operand" ""))]
8010 "registers_ok_for_ldd_peep (operands[0], operands[2])
8011 && ! MEM_VOLATILE_P (operands[1])
8012 && ! MEM_VOLATILE_P (operands[3])
8013 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8017 [(set (match_operand:SF 0 "memory_operand" "")
8018 (match_operand:SF 1 "register_operand" "fr"))
8019 (set (match_operand:SF 2 "memory_operand" "")
8020 (match_operand:SF 3 "register_operand" "fr"))]
8021 "registers_ok_for_ldd_peep (operands[1], operands[3])
8022 && ! MEM_VOLATILE_P (operands[0])
8023 && ! MEM_VOLATILE_P (operands[2])
8024 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8028 [(set (match_operand:SI 0 "register_operand" "=rf")
8029 (match_operand:SI 1 "memory_operand" ""))
8030 (set (match_operand:SI 2 "register_operand" "=rf")
8031 (match_operand:SI 3 "memory_operand" ""))]
8032 "registers_ok_for_ldd_peep (operands[2], operands[0])
8033 && ! MEM_VOLATILE_P (operands[3])
8034 && ! MEM_VOLATILE_P (operands[1])
8035 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8039 [(set (match_operand:SI 0 "memory_operand" "")
8040 (match_operand:SI 1 "register_operand" "rf"))
8041 (set (match_operand:SI 2 "memory_operand" "")
8042 (match_operand:SI 3 "register_operand" "rf"))]
8043 "registers_ok_for_ldd_peep (operands[3], operands[1])
8044 && ! MEM_VOLATILE_P (operands[2])
8045 && ! MEM_VOLATILE_P (operands[0])
8046 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8050 [(set (match_operand:SF 0 "register_operand" "=fr")
8051 (match_operand:SF 1 "memory_operand" ""))
8052 (set (match_operand:SF 2 "register_operand" "=fr")
8053 (match_operand:SF 3 "memory_operand" ""))]
8054 "registers_ok_for_ldd_peep (operands[2], operands[0])
8055 && ! MEM_VOLATILE_P (operands[3])
8056 && ! MEM_VOLATILE_P (operands[1])
8057 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8061 [(set (match_operand:SF 0 "memory_operand" "")
8062 (match_operand:SF 1 "register_operand" "fr"))
8063 (set (match_operand:SF 2 "memory_operand" "")
8064 (match_operand:SF 3 "register_operand" "fr"))]
8065 "registers_ok_for_ldd_peep (operands[3], operands[1])
8066 && ! MEM_VOLATILE_P (operands[2])
8067 && ! MEM_VOLATILE_P (operands[0])
8068 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8071 ;; Optimize the case of following a reg-reg move with a test
8072 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8073 ;; This can result from a float to fix conversion.
8076 [(set (match_operand:SI 0 "register_operand" "=r")
8077 (match_operand:SI 1 "register_operand" "r"))
8079 (compare:CC (match_operand:SI 2 "register_operand" "r")
8081 "(rtx_equal_p (operands[2], operands[0])
8082 || rtx_equal_p (operands[2], operands[1]))
8083 && ! FP_REG_P (operands[0])
8084 && ! FP_REG_P (operands[1])"
8088 [(set (match_operand:DI 0 "register_operand" "=r")
8089 (match_operand:DI 1 "register_operand" "r"))
8091 (compare:CCX (match_operand:DI 2 "register_operand" "r")
8094 && (rtx_equal_p (operands[2], operands[0])
8095 || rtx_equal_p (operands[2], operands[1]))
8096 && ! FP_REG_P (operands[0])
8097 && ! FP_REG_P (operands[1])"
8100 ;; Return peepholes. First the "normal" ones.
8101 ;; These are necessary to catch insns ending up in the epilogue delay list.
8103 (define_insn "*return_qi"
8104 [(set (match_operand:QI 0 "restore_operand" "")
8105 (match_operand:QI 1 "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 %%g0, %1, %Y0\";
8112 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8113 || IN_OR_GLOBAL_P (operands[1])))
8114 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8116 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8118 [(set_attr "type" "multi")])
8120 (define_insn "*return_hi"
8121 [(set (match_operand:HI 0 "restore_operand" "")
8122 (match_operand:HI 1 "arith_operand" "rI"))
8124 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8127 if (! TARGET_ARCH64 && current_function_returns_struct)
8128 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8129 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8130 || IN_OR_GLOBAL_P (operands[1])))
8131 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8133 return \"ret\;restore %%g0, %1, %Y0\";
8135 [(set_attr "type" "multi")])
8137 (define_insn "*return_si"
8138 [(set (match_operand:SI 0 "restore_operand" "")
8139 (match_operand:SI 1 "arith_operand" "rI"))
8141 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8144 if (! TARGET_ARCH64 && current_function_returns_struct)
8145 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8146 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8147 || IN_OR_GLOBAL_P (operands[1])))
8148 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8150 return \"ret\;restore %%g0, %1, %Y0\";
8152 [(set_attr "type" "multi")])
8154 ;; The following pattern is only generated by delayed-branch scheduling,
8155 ;; when the insn winds up in the epilogue. This can happen not only when
8156 ;; ! TARGET_FPU because we move complex types around by parts using
8158 (define_insn "*return_sf_no_fpu"
8159 [(set (match_operand:SF 0 "restore_operand" "=r")
8160 (match_operand:SF 1 "register_operand" "r"))
8162 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8165 if (! TARGET_ARCH64 && current_function_returns_struct)
8166 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8167 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8168 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8170 return \"ret\;restore %%g0, %1, %Y0\";
8172 [(set_attr "type" "multi")])
8174 (define_insn "*return_addsi"
8175 [(set (match_operand:SI 0 "restore_operand" "")
8176 (plus:SI (match_operand:SI 1 "register_operand" "r")
8177 (match_operand:SI 2 "arith_operand" "rI")))
8179 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8182 if (! TARGET_ARCH64 && current_function_returns_struct)
8183 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8184 /* If operands are global or in registers, can use return */
8185 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8186 && (GET_CODE (operands[2]) == CONST_INT
8187 || IN_OR_GLOBAL_P (operands[2])))
8188 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8190 return \"ret\;restore %r1, %2, %Y0\";
8192 [(set_attr "type" "multi")])
8194 (define_insn "*return_losum_si"
8195 [(set (match_operand:SI 0 "restore_operand" "")
8196 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8197 (match_operand:SI 2 "immediate_operand" "in")))
8199 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0 && ! TARGET_CM_MEDMID"
8202 if (! TARGET_ARCH64 && current_function_returns_struct)
8203 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8204 /* If operands are global or in registers, can use return */
8205 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8206 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8208 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8210 [(set_attr "type" "multi")])
8212 (define_insn "*return_di"
8213 [(set (match_operand:DI 0 "restore_operand" "")
8214 (match_operand:DI 1 "arith_double_operand" "rHI"))
8216 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8217 "ret\;restore %%g0, %1, %Y0"
8218 [(set_attr "type" "multi")])
8220 (define_insn "*return_adddi"
8221 [(set (match_operand:DI 0 "restore_operand" "")
8222 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8223 (match_operand:DI 2 "arith_double_operand" "rHI")))
8225 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8226 "ret\;restore %r1, %2, %Y0"
8227 [(set_attr "type" "multi")])
8229 (define_insn "*return_losum_di"
8230 [(set (match_operand:DI 0 "restore_operand" "")
8231 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8232 (match_operand:DI 2 "immediate_operand" "in")))
8234 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
8235 "ret\;restore %r1, %%lo(a2), %Y0"
8236 [(set_attr "type" "multi")])
8238 ;; The following pattern is only generated by delayed-branch scheduling,
8239 ;; when the insn winds up in the epilogue.
8240 (define_insn "*return_sf"
8242 (match_operand:SF 0 "register_operand" "f"))
8245 "ret\;fmovs\\t%0, %%f0"
8246 [(set_attr "type" "multi")])
8248 ;; Now peepholes to do a call followed by a jump.
8251 [(parallel [(set (match_operand 0 "" "")
8252 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8253 (match_operand 2 "" "")))
8254 (clobber (reg:SI 15))])
8255 (set (pc) (label_ref (match_operand 3 "" "")))]
8256 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8257 && in_same_eh_region (insn, operands[3])
8258 && in_same_eh_region (insn, ins1)"
8259 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8262 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8263 (match_operand 1 "" ""))
8264 (clobber (reg:SI 15))])
8265 (set (pc) (label_ref (match_operand 2 "" "")))]
8266 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8267 && in_same_eh_region (insn, operands[2])
8268 && in_same_eh_region (insn, ins1)"
8269 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8272 [(parallel [(set (match_operand 0 "" "")
8273 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
8274 (match_operand 2 "" "")))
8275 (clobber (reg:DI 15))])
8276 (set (pc) (label_ref (match_operand 3 "" "")))]
8278 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8279 && in_same_eh_region (insn, operands[3])
8280 && in_same_eh_region (insn, ins1)"
8281 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8284 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
8285 (match_operand 1 "" ""))
8286 (clobber (reg:DI 15))])
8287 (set (pc) (label_ref (match_operand 2 "" "")))]
8289 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8290 && in_same_eh_region (insn, operands[2])
8291 && in_same_eh_region (insn, ins1)"
8292 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8294 ;; After a nonlocal goto, we need to restore the PIC register, but only
8295 ;; if we need it. So do nothing much here, but we'll check for this in
8298 ;; Make sure this unspec_volatile number agrees with finalize_pic.
8299 (define_insn "nonlocal_goto_receiver"
8300 [(unspec_volatile [(const_int 0)] 5)]
8303 [(set_attr "length" "0")])
8306 [(trap_if (const_int 1) (const_int 5))]
8309 [(set_attr "type" "misc")
8310 (set_attr "length" "1")])
8312 (define_expand "conditional_trap"
8313 [(trap_if (match_operator 0 "noov_compare_op"
8314 [(match_dup 2) (match_dup 3)])
8315 (match_operand:SI 1 "arith_operand" ""))]
8317 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8318 sparc_compare_op0, sparc_compare_op1);
8319 operands[3] = const0_rtx;")
8322 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8323 (match_operand:SI 1 "arith_operand" "rM"))]
8326 [(set_attr "type" "misc")
8327 (set_attr "length" "1")])
8330 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8331 (match_operand:SI 1 "arith_operand" "rM"))]
8334 [(set_attr "type" "misc")
8335 (set_attr "length" "1")])