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 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2449 "sethi\\t%%hi(%a1), %0"
2450 [(set_attr "type" "move")
2451 (set_attr "length" "1")])
2453 (define_insn "*sethi_di_medlow"
2454 [(set (match_operand:DI 0 "register_operand" "=r")
2455 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2456 "TARGET_CM_MEDLOW && check_pic (1)"
2457 "sethi\\t%%hi(%a1), %0"
2458 [(set_attr "type" "move")
2459 (set_attr "length" "1")])
2461 (define_insn "*losum_di_medlow"
2462 [(set (match_operand:DI 0 "register_operand" "=r")
2463 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2464 (match_operand:DI 2 "symbolic_operand" "")))]
2466 "or\\t%1, %%lo(%a2), %0"
2467 [(set_attr "type" "ialu")
2468 (set_attr "length" "1")])
2470 (define_insn "seth44"
2471 [(set (match_operand:DI 0 "register_operand" "=r")
2472 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2474 "sethi\\t%%h44(%a1), %0"
2475 [(set_attr "type" "move")
2476 (set_attr "length" "1")])
2478 (define_insn "setm44"
2479 [(set (match_operand:DI 0 "register_operand" "=r")
2480 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2481 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2483 "or\\t%1, %%m44(%a2), %0"
2484 [(set_attr "type" "move")
2485 (set_attr "length" "1")])
2487 (define_insn "setl44"
2488 [(set (match_operand:DI 0 "register_operand" "=r")
2489 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2490 (match_operand:DI 2 "symbolic_operand" "")))]
2492 "or\\t%1, %%l44(%a2), %0"
2493 [(set_attr "type" "ialu")
2494 (set_attr "length" "1")])
2496 (define_insn "sethh"
2497 [(set (match_operand:DI 0 "register_operand" "=r")
2498 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2500 "sethi\\t%%hh(%a1), %0"
2501 [(set_attr "type" "move")
2502 (set_attr "length" "1")])
2504 (define_insn "setlm"
2505 [(set (match_operand:DI 0 "register_operand" "=r")
2506 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2508 "sethi\\t%%lm(%a1), %0"
2509 [(set_attr "type" "move")
2510 (set_attr "length" "1")])
2512 (define_insn "sethm"
2513 [(set (match_operand:DI 0 "register_operand" "=r")
2514 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2515 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2517 "or\\t%1, %%hm(%a2), %0"
2518 [(set_attr "type" "ialu")
2519 (set_attr "length" "1")])
2521 (define_insn "setlo"
2522 [(set (match_operand:DI 0 "register_operand" "=r")
2523 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2524 (match_operand:DI 2 "symbolic_operand" "")))]
2526 "or\\t%1, %%lo(%a2), %0"
2527 [(set_attr "type" "ialu")
2528 (set_attr "length" "1")])
2530 (define_insn "embmedany_sethi"
2531 [(set (match_operand:DI 0 "register_operand" "=r")
2532 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2533 "TARGET_CM_EMBMEDANY && check_pic (1)"
2534 "sethi\\t%%hi(%a1), %0"
2535 [(set_attr "type" "move")
2536 (set_attr "length" "1")])
2538 (define_insn "embmedany_losum"
2539 [(set (match_operand:DI 0 "register_operand" "=r")
2540 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2541 (match_operand:DI 2 "data_segment_operand" "")))]
2542 "TARGET_CM_EMBMEDANY"
2543 "add\\t%1, %%lo(%a2), %0"
2544 [(set_attr "type" "ialu")
2545 (set_attr "length" "1")])
2547 (define_insn "embmedany_brsum"
2548 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2550 "TARGET_CM_EMBMEDANY"
2552 [(set_attr "length" "1")])
2554 (define_insn "embmedany_textuhi"
2555 [(set (match_operand:DI 0 "register_operand" "=r")
2556 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2557 "TARGET_CM_EMBMEDANY && check_pic (1)"
2558 "sethi\\t%%uhi(%a1), %0"
2559 [(set_attr "type" "move")
2560 (set_attr "length" "1")])
2562 (define_insn "embmedany_texthi"
2563 [(set (match_operand:DI 0 "register_operand" "=r")
2564 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2565 "TARGET_CM_EMBMEDANY && check_pic (1)"
2566 "sethi\\t%%hi(%a1), %0"
2567 [(set_attr "type" "move")
2568 (set_attr "length" "1")])
2570 (define_insn "embmedany_textulo"
2571 [(set (match_operand:DI 0 "register_operand" "=r")
2572 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2573 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2574 "TARGET_CM_EMBMEDANY"
2575 "or\\t%1, %%ulo(%a2), %0"
2576 [(set_attr "type" "ialu")
2577 (set_attr "length" "1")])
2579 (define_insn "embmedany_textlo"
2580 [(set (match_operand:DI 0 "register_operand" "=r")
2581 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2582 (match_operand:DI 2 "text_segment_operand" "")))]
2583 "TARGET_CM_EMBMEDANY"
2584 "or\\t%1, %%lo(%a2), %0"
2585 [(set_attr "type" "ialu")
2586 (set_attr "length" "1")])
2588 ;; Now some patterns to help reload out a bit.
2589 (define_expand "reload_indi"
2590 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2591 (match_operand:DI 1 "immediate_operand" "")
2592 (match_operand:TI 2 "register_operand" "=&r")])]
2594 || TARGET_CM_EMBMEDANY)
2598 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2599 gen_rtx_REG (DImode, REGNO (operands[2])));
2603 (define_expand "reload_outdi"
2604 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2605 (match_operand:DI 1 "immediate_operand" "")
2606 (match_operand:TI 2 "register_operand" "=&r")])]
2608 || TARGET_CM_EMBMEDANY)
2612 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2613 gen_rtx_REG (DImode, REGNO (operands[2])));
2617 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2619 [(set (match_operand:DI 0 "register_operand" "")
2620 (match_operand:DI 1 "const_int_operand" ""))]
2621 "! TARGET_ARCH64 && reload_completed"
2622 [(clobber (const_int 0))]
2625 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2626 (INTVAL (operands[1]) < 0) ?
2629 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2635 [(set (match_operand:DI 0 "register_operand" "")
2636 (match_operand:DI 1 "const_double_operand" ""))]
2637 "! TARGET_ARCH64 && reload_completed"
2638 [(clobber (const_int 0))]
2641 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2642 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2644 /* Slick... but this trick loses if this subreg constant part
2645 can be done in one insn. */
2646 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2647 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2648 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2650 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2651 gen_highpart (SImode, operands[0])));
2655 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2656 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2662 [(set (match_operand:DI 0 "register_operand" "")
2663 (match_operand:DI 1 "register_operand" ""))]
2664 "! TARGET_ARCH64 && reload_completed"
2665 [(clobber (const_int 0))]
2668 rtx set_dest = operands[0];
2669 rtx set_src = operands[1];
2673 if (GET_CODE (set_dest) == SUBREG)
2674 set_dest = alter_subreg (set_dest);
2675 if (GET_CODE (set_src) == SUBREG)
2676 set_src = alter_subreg (set_src);
2678 dest1 = gen_highpart (SImode, set_dest);
2679 dest2 = gen_lowpart (SImode, set_dest);
2680 src1 = gen_highpart (SImode, set_src);
2681 src2 = gen_lowpart (SImode, set_src);
2683 /* Now emit using the real source and destination we found, swapping
2684 the order if we detect overlap. */
2685 if (reg_overlap_mentioned_p (dest1, src2))
2687 emit_insn (gen_movsi (dest2, src2));
2688 emit_insn (gen_movsi (dest1, src1));
2692 emit_insn (gen_movsi (dest1, src1));
2693 emit_insn (gen_movsi (dest2, src2));
2698 ;; Now handle the cases of memory moves from/to non-even
2699 ;; DI mode register pairs.
2701 [(set (match_operand:DI 0 "register_operand" "")
2702 (match_operand:DI 1 "memory_operand" ""))]
2705 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2706 [(clobber (const_int 0))]
2709 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2710 rtx word1 = change_address (operands[1], SImode,
2711 plus_constant_for_output (XEXP (word0, 0), 4));
2712 rtx high_part = gen_highpart (SImode, operands[0]);
2713 rtx low_part = gen_lowpart (SImode, operands[0]);
2715 if (reg_overlap_mentioned_p (high_part, word1))
2717 emit_insn (gen_movsi (low_part, word1));
2718 emit_insn (gen_movsi (high_part, word0));
2722 emit_insn (gen_movsi (high_part, word0));
2723 emit_insn (gen_movsi (low_part, word1));
2729 [(set (match_operand:DI 0 "memory_operand" "")
2730 (match_operand:DI 1 "register_operand" ""))]
2733 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2734 [(clobber (const_int 0))]
2737 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2738 rtx word1 = change_address (operands[0], SImode,
2739 plus_constant_for_output (XEXP (word0, 0), 4));
2740 rtx high_part = gen_highpart (SImode, operands[1]);
2741 rtx low_part = gen_lowpart (SImode, operands[1]);
2743 emit_insn (gen_movsi (word0, high_part));
2744 emit_insn (gen_movsi (word1, low_part));
2749 ;; Floating point move insns
2751 (define_insn "*clear_sf"
2752 [(set (match_operand:SF 0 "register_operand" "=f")
2753 (match_operand:SF 1 "const_double_operand" ""))]
2755 && fp_zero_operand (operands[1])"
2757 [(set_attr "type" "fpmove")
2758 (set_attr "length" "1")])
2760 (define_insn "*clear_sfp"
2761 [(set (match_operand:SF 0 "memory_operand" "=m")
2762 (match_operand:SF 1 "const_double_operand" ""))]
2764 && fp_zero_operand (operands[1])"
2766 [(set_attr "type" "store")
2767 (set_attr "length" "1")])
2769 (define_insn "*movsf_const_intreg"
2770 [(set (match_operand:SF 0 "register_operand" "=f,r")
2771 (match_operand:SF 1 "const_double_operand" "m#F,F"))]
2778 if (which_alternative == 0)
2779 return \"ld\\t%1, %0\";
2781 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2782 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2783 if (SPARC_SIMM13_P (i) || SPARC_SETHI_P (i))
2785 operands[1] = GEN_INT (i);
2786 if (SPARC_SIMM13_P (INTVAL (operands[1])))
2787 return \"mov\\t%1, %0\";
2788 else if (SPARC_SETHI_P (INTVAL (operands[1])))
2789 return \"sethi\\t%%hi(%a1), %0\";
2796 [(set_attr "type" "move")
2797 (set_attr "length" "1,2")])
2799 ;; There isn't much I can do about this, if I change the
2800 ;; mode then flow info gets really confused because the
2801 ;; destination no longer looks the same. Ho hum...
2802 (define_insn "*movsf_const_high"
2803 [(set (match_operand:SF 0 "register_operand" "=r")
2804 (unspec:SF [(match_operand 1 "const_int_operand" "")] 12))]
2806 "sethi\\t%%hi(%a1), %0"
2807 [(set_attr "type" "move")
2808 (set_attr "length" "1")])
2810 (define_insn "*movsf_const_lo"
2811 [(set (match_operand:SF 0 "register_operand" "=r")
2812 (unspec:SF [(match_operand:SF 1 "register_operand" "r")
2813 (match_operand 2 "const_int_operand" "")] 17))]
2815 "or\\t%1, %%lo(%a2), %0"
2816 [(set_attr "type" "move")
2817 (set_attr "length" "1")])
2820 [(set (match_operand:SF 0 "register_operand" "")
2821 (match_operand:SF 1 "const_double_operand" ""))]
2823 && (GET_CODE (operands[0]) == REG
2824 && REGNO (operands[0]) < 32)"
2825 [(set (match_dup 0) (unspec:SF [(match_dup 1)] 12))
2826 (set (match_dup 0) (unspec:SF [(match_dup 0) (match_dup 1)] 17))]
2832 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2833 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2834 operands[1] = GEN_INT (i);
2837 (define_expand "movsf"
2838 [(set (match_operand:SF 0 "general_operand" "")
2839 (match_operand:SF 1 "general_operand" ""))]
2843 /* Force SFmode constants into memory. */
2844 if (GET_CODE (operands[0]) == REG
2845 && CONSTANT_P (operands[1]))
2848 && GET_CODE (operands[1]) == CONST_DOUBLE
2849 && fp_zero_operand (operands[1]))
2852 /* emit_group_store will send such bogosity to us when it is
2853 not storing directly into memory. So fix this up to avoid
2854 crashes in output_constant_pool. */
2855 if (operands [1] == const0_rtx)
2856 operands[1] = CONST0_RTX (SFmode);
2857 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2861 /* Handle sets of MEM first. */
2862 if (GET_CODE (operands[0]) == MEM)
2864 if (register_operand (operands[1], SFmode))
2867 if (! reload_in_progress)
2869 operands[0] = validize_mem (operands[0]);
2870 operands[1] = force_reg (SFmode, operands[1]);
2874 /* Fixup PIC cases. */
2877 if (CONSTANT_P (operands[1])
2878 && pic_address_needs_scratch (operands[1]))
2879 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2881 if (symbolic_operand (operands[1], SFmode))
2883 operands[1] = legitimize_pic_address (operands[1],
2885 (reload_in_progress ?
2895 (define_insn "*movsf_insn"
2896 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,r,r,m")
2897 (match_operand:SF 1 "input_operand" "f,m,f,r,m,r"))]
2899 && (register_operand (operands[0], SFmode)
2900 || register_operand (operands[1], SFmode))"
2908 [(set_attr "type" "fpmove,fpload,fpstore,move,load,store")
2909 (set_attr "length" "1")])
2911 ;; Exactly the same as above, except that all `f' cases are deleted.
2912 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2915 (define_insn "*movsf_no_f_insn"
2916 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
2917 (match_operand:SF 1 "input_operand" "r,m,r"))]
2919 && (register_operand (operands[0], SFmode)
2920 || register_operand (operands[1], SFmode))"
2925 [(set_attr "type" "move,load,store")
2926 (set_attr "length" "1")])
2928 (define_insn "*clear_df"
2929 [(set (match_operand:DF 0 "register_operand" "=e")
2930 (match_operand:DF 1 "const_double_operand" ""))]
2932 && fp_zero_operand (operands[1])"
2934 [(set_attr "type" "fpmove")
2935 (set_attr "length" "1")])
2937 (define_insn "*clear_dfp"
2938 [(set (match_operand:DF 0 "memory_operand" "=m")
2939 (match_operand:DF 1 "const_double_operand" ""))]
2942 && fp_zero_operand (operands[1])"
2944 [(set_attr "type" "store")
2945 (set_attr "length" "1")])
2947 (define_insn "*movdf_const_intreg_sp32"
2948 [(set (match_operand:DF 0 "register_operand" "=e,e,?r")
2949 (match_operand:DF 1 "const_double_operand" "T#F,o#F,F"))]
2950 "TARGET_FPU && ! TARGET_ARCH64"
2955 [(set_attr "type" "move")
2956 (set_attr "length" "1,2,2")])
2958 ;; Now that we redo life analysis with a clean slate after
2959 ;; instruction splitting for sched2 this can work.
2960 (define_insn "*movdf_const_intreg_sp64"
2961 [(set (match_operand:DF 0 "register_operand" "=e,?r")
2962 (match_operand:DF 1 "const_double_operand" "m#F,F"))]
2963 "TARGET_FPU && TARGET_ARCH64"
2967 [(set_attr "type" "move")
2968 (set_attr "length" "1,2")])
2971 [(set (match_operand:DF 0 "register_operand" "")
2972 (match_operand:DF 1 "const_double_operand" ""))]
2974 && (GET_CODE (operands[0]) == REG
2975 && REGNO (operands[0]) < 32)
2976 && reload_completed"
2977 [(clobber (const_int 0))]
2983 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2984 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2985 if (GET_CODE (operands[0]) == SUBREG)
2986 operands[0] = alter_subreg (operands[0]);
2987 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2991 #if HOST_BITS_PER_WIDE_INT == 64
2994 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2995 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2996 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
2998 emit_insn (gen_movdi (operands[0],
2999 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3005 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3008 /* Slick... but this trick loses if this subreg constant part
3009 can be done in one insn. */
3011 && !(SPARC_SETHI_P (l[0])
3012 || SPARC_SIMM13_P (l[0])))
3014 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3015 gen_highpart (SImode, operands[0])));
3019 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3026 (define_expand "movdf"
3027 [(set (match_operand:DF 0 "general_operand" "")
3028 (match_operand:DF 1 "general_operand" ""))]
3032 /* Force DFmode constants into memory. */
3033 if (GET_CODE (operands[0]) == REG
3034 && CONSTANT_P (operands[1]))
3037 && GET_CODE (operands[1]) == CONST_DOUBLE
3038 && fp_zero_operand (operands[1]))
3041 /* emit_group_store will send such bogosity to us when it is
3042 not storing directly into memory. So fix this up to avoid
3043 crashes in output_constant_pool. */
3044 if (operands [1] == const0_rtx)
3045 operands[1] = CONST0_RTX (DFmode);
3046 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3050 /* Handle MEM cases first. */
3051 if (GET_CODE (operands[0]) == MEM)
3053 if (register_operand (operands[1], DFmode))
3056 if (! reload_in_progress)
3058 operands[0] = validize_mem (operands[0]);
3059 operands[1] = force_reg (DFmode, operands[1]);
3063 /* Fixup PIC cases. */
3066 if (CONSTANT_P (operands[1])
3067 && pic_address_needs_scratch (operands[1]))
3068 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3070 if (symbolic_operand (operands[1], DFmode))
3072 operands[1] = legitimize_pic_address (operands[1],
3074 (reload_in_progress ?
3084 ;; Be careful, fmovd does not exist when !v9.
3085 (define_insn "*movdf_insn_sp32"
3086 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,e,r,r,o,e,o")
3087 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3090 && (register_operand (operands[0], DFmode)
3091 || register_operand (operands[1], DFmode))"
3103 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3104 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3106 (define_insn "*movdf_no_e_insn_sp32"
3107 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,r,r,o")
3108 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3111 && (register_operand (operands[0], DFmode)
3112 || register_operand (operands[1], DFmode))"
3119 [(set_attr "type" "load,store,*,*,*")
3120 (set_attr "length" "1,1,2,2,2")])
3122 ;; We have available v9 double floats but not 64-bit
3123 ;; integer registers.
3124 (define_insn "*movdf_insn_v9only"
3125 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o")
3126 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3130 && (register_operand (operands[0], DFmode)
3131 || register_operand (operands[1], DFmode))"
3141 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3142 (set_attr "length" "1,1,1,1,1,2,2,2")])
3144 ;; We have available both v9 double floats and 64-bit
3145 ;; integer registers.
3146 (define_insn "*movdf_insn_sp64"
3147 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,r,r,m")
3148 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3152 && (register_operand (operands[0], DFmode)
3153 || register_operand (operands[1], DFmode))"
3161 [(set_attr "type" "fpmove,load,store,move,load,store")
3162 (set_attr "length" "1")])
3164 (define_insn "*movdf_no_e_insn_sp64"
3165 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3166 (match_operand:DF 1 "input_operand" "r,m,r"))]
3169 && (register_operand (operands[0], DFmode)
3170 || register_operand (operands[1], DFmode))"
3175 [(set_attr "type" "move,load,store")
3176 (set_attr "length" "1")])
3178 ;; Ok, now the splits to handle all the multi insn and
3179 ;; mis-aligned memory address cases.
3180 ;; In these splits please take note that we must be
3181 ;; careful when V9 but not ARCH64 because the integer
3182 ;; register DFmode cases must be handled.
3184 [(set (match_operand:DF 0 "register_operand" "")
3185 (match_operand:DF 1 "register_operand" ""))]
3188 && ((GET_CODE (operands[0]) == REG
3189 && REGNO (operands[0]) < 32)
3190 || (GET_CODE (operands[0]) == SUBREG
3191 && GET_CODE (SUBREG_REG (operands[0])) == REG
3192 && REGNO (SUBREG_REG (operands[0])) < 32))))
3193 && reload_completed"
3194 [(clobber (const_int 0))]
3197 rtx set_dest = operands[0];
3198 rtx set_src = operands[1];
3202 if (GET_CODE (set_dest) == SUBREG)
3203 set_dest = alter_subreg (set_dest);
3204 if (GET_CODE (set_src) == SUBREG)
3205 set_src = alter_subreg (set_src);
3207 dest1 = gen_highpart (SFmode, set_dest);
3208 dest2 = gen_lowpart (SFmode, set_dest);
3209 src1 = gen_highpart (SFmode, set_src);
3210 src2 = gen_lowpart (SFmode, set_src);
3212 /* Now emit using the real source and destination we found, swapping
3213 the order if we detect overlap. */
3214 if (reg_overlap_mentioned_p (dest1, src2))
3216 emit_insn (gen_movsf (dest2, src2));
3217 emit_insn (gen_movsf (dest1, src1));
3221 emit_insn (gen_movsf (dest1, src1));
3222 emit_insn (gen_movsf (dest2, src2));
3228 [(set (match_operand:DF 0 "register_operand" "")
3229 (match_operand:DF 1 "memory_operand" ""))]
3232 && ((GET_CODE (operands[0]) == REG
3233 && REGNO (operands[0]) < 32)
3234 || (GET_CODE (operands[0]) == SUBREG
3235 && GET_CODE (SUBREG_REG (operands[0])) == REG
3236 && REGNO (SUBREG_REG (operands[0])) < 32))))
3237 && (reload_completed
3238 && (((REGNO (operands[0])) % 2) != 0
3239 || ! mem_min_alignment (operands[1], 8))
3240 && offsettable_memref_p (operands[1])))"
3241 [(clobber (const_int 0))]
3244 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3245 rtx word1 = change_address (operands[1], SFmode,
3246 plus_constant_for_output (XEXP (word0, 0), 4));
3248 if (GET_CODE (operands[0]) == SUBREG)
3249 operands[0] = alter_subreg (operands[0]);
3251 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3253 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3255 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3260 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3262 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3269 [(set (match_operand:DF 0 "memory_operand" "")
3270 (match_operand:DF 1 "register_operand" ""))]
3273 && ((GET_CODE (operands[1]) == REG
3274 && REGNO (operands[1]) < 32)
3275 || (GET_CODE (operands[1]) == SUBREG
3276 && GET_CODE (SUBREG_REG (operands[1])) == REG
3277 && REGNO (SUBREG_REG (operands[1])) < 32))))
3278 && (reload_completed
3279 && (((REGNO (operands[1])) % 2) != 0
3280 || ! mem_min_alignment (operands[0], 8))
3281 && offsettable_memref_p (operands[0])))"
3282 [(clobber (const_int 0))]
3285 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3286 rtx word1 = change_address (operands[0], SFmode,
3287 plus_constant_for_output (XEXP (word0, 0), 4));
3289 if (GET_CODE (operands[1]) == SUBREG)
3290 operands[1] = alter_subreg (operands[1]);
3291 emit_insn (gen_movsf (word0,
3292 gen_highpart (SFmode, operands[1])));
3293 emit_insn (gen_movsf (word1,
3294 gen_lowpart (SFmode, operands[1])));
3298 (define_insn "*clear_tf"
3299 [(set (match_operand:TF 0 "register_operand" "=e")
3300 (match_operand:TF 1 "const_double_operand" ""))]
3302 && fp_zero_operand (operands[1])"
3304 [(set_attr "type" "fpmove")
3305 (set_attr "length" "2")])
3308 [(set (match_operand:TF 0 "register_operand" "")
3309 (match_operand:TF 1 "const_double_operand" ""))]
3310 "TARGET_VIS && reload_completed
3311 && fp_zero_operand (operands[1])"
3312 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3313 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3316 operands[1] = CONST0_RTX (DFmode);
3320 (define_insn "*clear_tfp"
3321 [(set (match_operand:TF 0 "memory_operand" "=m")
3322 (match_operand:TF 1 "const_double_operand" ""))]
3325 && fp_zero_operand (operands[1])"
3327 [(set_attr "type" "fpmove")
3328 (set_attr "length" "2")])
3331 [(set (match_operand:TF 0 "memory_operand" "=m")
3332 (match_operand:TF 1 "const_double_operand" ""))]
3334 && TARGET_V9 && reload_completed
3335 && fp_zero_operand (operands[1])"
3336 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3337 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3340 operands[1] = CONST0_RTX (DFmode);
3344 (define_expand "movtf"
3345 [(set (match_operand:TF 0 "general_operand" "")
3346 (match_operand:TF 1 "general_operand" ""))]
3350 /* Force TFmode constants into memory. */
3351 if (GET_CODE (operands[0]) == REG
3352 && CONSTANT_P (operands[1]))
3355 && GET_CODE (operands[1]) == CONST_DOUBLE
3356 && fp_zero_operand (operands[1]))
3359 /* emit_group_store will send such bogosity to us when it is
3360 not storing directly into memory. So fix this up to avoid
3361 crashes in output_constant_pool. */
3362 if (operands [1] == const0_rtx)
3363 operands[1] = CONST0_RTX (TFmode);
3364 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3368 /* Handle MEM cases first, note that only v9 guarentees
3369 full 16-byte alignment for quads. */
3370 if (GET_CODE (operands[0]) == MEM)
3372 if (register_operand (operands[1], TFmode))
3375 if (! reload_in_progress)
3377 operands[0] = validize_mem (operands[0]);
3378 operands[1] = force_reg (TFmode, operands[1]);
3382 /* Fixup PIC cases. */
3385 if (CONSTANT_P (operands[1])
3386 && pic_address_needs_scratch (operands[1]))
3387 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3389 if (symbolic_operand (operands[1], TFmode))
3391 operands[1] = legitimize_pic_address (operands[1],
3393 (reload_in_progress ?
3403 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3404 ;; we must split them all. :-(
3405 (define_insn "*movtf_insn_sp32"
3406 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,e,r,r,o")
3407 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3410 && (register_operand (operands[0], TFmode)
3411 || register_operand (operands[1], TFmode))"
3413 [(set_attr "length" "4")])
3415 ;; Exactly the same as above, except that all `e' cases are deleted.
3416 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3419 (define_insn "*movtf_no_e_insn_sp32"
3420 [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o")
3421 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3424 && (register_operand (operands[0], TFmode)
3425 || register_operand (operands[1], TFmode))"
3427 [(set_attr "length" "4")])
3429 ;; Now handle the float reg cases directly when arch64,
3430 ;; hard_quad, and proper reg number alignment are all true.
3431 (define_insn "*movtf_insn_hq_sp64"
3432 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,r,r,o")
3433 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3438 && (register_operand (operands[0], TFmode)
3439 || register_operand (operands[1], TFmode))"
3447 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3448 (set_attr "length" "1,1,1,2,2,2")])
3450 ;; Now we allow the integer register cases even when
3451 ;; only arch64 is true.
3452 (define_insn "*movtf_insn_sp64"
3453 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r")
3454 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3457 && ! TARGET_HARD_QUAD
3458 && (register_operand (operands[0], TFmode)
3459 || register_operand (operands[1], TFmode))"
3461 [(set_attr "length" "2")])
3463 (define_insn "*movtf_no_e_insn_sp64"
3464 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r")
3465 (match_operand:TF 1 "input_operand" "o,r,r"))]
3468 && (register_operand (operands[0], TFmode)
3469 || register_operand (operands[1], TFmode))"
3471 [(set_attr "length" "2")])
3473 ;; Now all the splits to handle multi-insn TF mode moves.
3475 [(set (match_operand:TF 0 "register_operand" "")
3476 (match_operand:TF 1 "register_operand" ""))]
3480 && ! TARGET_HARD_QUAD))"
3481 [(clobber (const_int 0))]
3484 rtx set_dest = operands[0];
3485 rtx set_src = operands[1];
3489 if (GET_CODE (set_dest) == SUBREG)
3490 set_dest = alter_subreg (set_dest);
3491 if (GET_CODE (set_src) == SUBREG)
3492 set_src = alter_subreg (set_src);
3494 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3495 dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
3496 dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
3497 src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0);
3498 src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0);
3500 /* Now emit using the real source and destination we found, swapping
3501 the order if we detect overlap. */
3502 if (reg_overlap_mentioned_p (dest1, src2))
3504 emit_insn (gen_movdf (dest2, src2));
3505 emit_insn (gen_movdf (dest1, src1));
3509 emit_insn (gen_movdf (dest1, src1));
3510 emit_insn (gen_movdf (dest2, src2));
3516 [(set (match_operand:TF 0 "register_operand" "")
3517 (match_operand:TF 1 "memory_operand" ""))]
3519 && offsettable_memref_p (operands[1]))"
3520 [(clobber (const_int 0))]
3523 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3524 rtx word1 = change_address (operands[1], DFmode,
3525 plus_constant_for_output (XEXP (word0, 0), 8));
3528 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3529 dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
3530 dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
3532 /* Now output, ordering such that we don't clobber any registers
3533 mentioned in the address. */
3534 if (reg_overlap_mentioned_p (dest1, word1))
3537 emit_insn (gen_movdf (dest2, word1));
3538 emit_insn (gen_movdf (dest1, word0));
3542 emit_insn (gen_movdf (dest1, word0));
3543 emit_insn (gen_movdf (dest2, word1));
3549 [(set (match_operand:TF 0 "memory_operand" "")
3550 (match_operand:TF 1 "register_operand" ""))]
3552 && offsettable_memref_p (operands[0]))"
3553 [(clobber (const_int 0))]
3556 rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
3557 rtx word1 = change_address (operands[0], DFmode,
3558 plus_constant_for_output (XEXP (word0, 0), 8));
3561 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3562 src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
3563 src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
3564 emit_insn (gen_movdf (word0, src1));
3565 emit_insn (gen_movdf (word1, src2));
3569 ;; Sparc V9 conditional move instructions.
3571 ;; We can handle larger constants here for some flavors, but for now we keep
3572 ;; it simple and only allow those constants supported by all flavours.
3573 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3574 ;; 3 contains the constant if one is present, but we handle either for
3575 ;; generality (sparc.c puts a constant in operand 2).
3577 (define_expand "movqicc"
3578 [(set (match_operand:QI 0 "register_operand" "")
3579 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3580 (match_operand:QI 2 "arith10_operand" "")
3581 (match_operand:QI 3 "arith10_operand" "")))]
3585 enum rtx_code code = GET_CODE (operands[1]);
3587 if (GET_MODE (sparc_compare_op0) == DImode
3591 if (sparc_compare_op1 == const0_rtx
3592 && GET_CODE (sparc_compare_op0) == REG
3593 && GET_MODE (sparc_compare_op0) == DImode
3594 && v9_regcmp_p (code))
3596 operands[1] = gen_rtx_fmt_ee (code, DImode,
3597 sparc_compare_op0, sparc_compare_op1);
3601 rtx cc_reg = gen_compare_reg (code,
3602 sparc_compare_op0, sparc_compare_op1);
3603 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3607 (define_expand "movhicc"
3608 [(set (match_operand:HI 0 "register_operand" "")
3609 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3610 (match_operand:HI 2 "arith10_operand" "")
3611 (match_operand:HI 3 "arith10_operand" "")))]
3615 enum rtx_code code = GET_CODE (operands[1]);
3617 if (GET_MODE (sparc_compare_op0) == DImode
3621 if (sparc_compare_op1 == const0_rtx
3622 && GET_CODE (sparc_compare_op0) == REG
3623 && GET_MODE (sparc_compare_op0) == DImode
3624 && v9_regcmp_p (code))
3626 operands[1] = gen_rtx_fmt_ee (code, DImode,
3627 sparc_compare_op0, sparc_compare_op1);
3631 rtx cc_reg = gen_compare_reg (code,
3632 sparc_compare_op0, sparc_compare_op1);
3633 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3637 (define_expand "movsicc"
3638 [(set (match_operand:SI 0 "register_operand" "")
3639 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3640 (match_operand:SI 2 "arith10_operand" "")
3641 (match_operand:SI 3 "arith10_operand" "")))]
3645 enum rtx_code code = GET_CODE (operands[1]);
3646 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3648 if (sparc_compare_op1 == const0_rtx
3649 && GET_CODE (sparc_compare_op0) == REG
3650 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3652 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3653 sparc_compare_op0, sparc_compare_op1);
3657 rtx cc_reg = gen_compare_reg (code,
3658 sparc_compare_op0, sparc_compare_op1);
3659 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3660 cc_reg, const0_rtx);
3664 (define_expand "movdicc"
3665 [(set (match_operand:DI 0 "register_operand" "")
3666 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3667 (match_operand:DI 2 "arith10_double_operand" "")
3668 (match_operand:DI 3 "arith10_double_operand" "")))]
3672 enum rtx_code code = GET_CODE (operands[1]);
3674 if (sparc_compare_op1 == const0_rtx
3675 && GET_CODE (sparc_compare_op0) == REG
3676 && GET_MODE (sparc_compare_op0) == DImode
3677 && v9_regcmp_p (code))
3679 operands[1] = gen_rtx_fmt_ee (code, DImode,
3680 sparc_compare_op0, sparc_compare_op1);
3684 rtx cc_reg = gen_compare_reg (code,
3685 sparc_compare_op0, sparc_compare_op1);
3686 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3687 cc_reg, const0_rtx);
3691 (define_expand "movsfcc"
3692 [(set (match_operand:SF 0 "register_operand" "")
3693 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3694 (match_operand:SF 2 "register_operand" "")
3695 (match_operand:SF 3 "register_operand" "")))]
3696 "TARGET_V9 && TARGET_FPU"
3699 enum rtx_code code = GET_CODE (operands[1]);
3701 if (GET_MODE (sparc_compare_op0) == DImode
3705 if (sparc_compare_op1 == const0_rtx
3706 && GET_CODE (sparc_compare_op0) == REG
3707 && GET_MODE (sparc_compare_op0) == DImode
3708 && v9_regcmp_p (code))
3710 operands[1] = gen_rtx_fmt_ee (code, DImode,
3711 sparc_compare_op0, sparc_compare_op1);
3715 rtx cc_reg = gen_compare_reg (code,
3716 sparc_compare_op0, sparc_compare_op1);
3717 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3721 (define_expand "movdfcc"
3722 [(set (match_operand:DF 0 "register_operand" "")
3723 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3724 (match_operand:DF 2 "register_operand" "")
3725 (match_operand:DF 3 "register_operand" "")))]
3726 "TARGET_V9 && TARGET_FPU"
3729 enum rtx_code code = GET_CODE (operands[1]);
3731 if (GET_MODE (sparc_compare_op0) == DImode
3735 if (sparc_compare_op1 == const0_rtx
3736 && GET_CODE (sparc_compare_op0) == REG
3737 && GET_MODE (sparc_compare_op0) == DImode
3738 && v9_regcmp_p (code))
3740 operands[1] = gen_rtx_fmt_ee (code, DImode,
3741 sparc_compare_op0, sparc_compare_op1);
3745 rtx cc_reg = gen_compare_reg (code,
3746 sparc_compare_op0, sparc_compare_op1);
3747 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3751 (define_expand "movtfcc"
3752 [(set (match_operand:TF 0 "register_operand" "")
3753 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3754 (match_operand:TF 2 "register_operand" "")
3755 (match_operand:TF 3 "register_operand" "")))]
3756 "TARGET_V9 && TARGET_FPU"
3759 enum rtx_code code = GET_CODE (operands[1]);
3761 if (GET_MODE (sparc_compare_op0) == DImode
3765 if (sparc_compare_op1 == const0_rtx
3766 && GET_CODE (sparc_compare_op0) == REG
3767 && GET_MODE (sparc_compare_op0) == DImode
3768 && v9_regcmp_p (code))
3770 operands[1] = gen_rtx_fmt_ee (code, DImode,
3771 sparc_compare_op0, sparc_compare_op1);
3775 rtx cc_reg = gen_compare_reg (code,
3776 sparc_compare_op0, sparc_compare_op1);
3777 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3781 ;; Conditional move define_insns.
3783 (define_insn "*movqi_cc_sp64"
3784 [(set (match_operand:QI 0 "register_operand" "=r,r")
3785 (if_then_else:QI (match_operator 1 "comparison_operator"
3786 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3788 (match_operand:QI 3 "arith11_operand" "rL,0")
3789 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3792 mov%C1\\t%x2, %3, %0
3793 mov%c1\\t%x2, %4, %0"
3794 [(set_attr "type" "cmove")
3795 (set_attr "length" "1")])
3797 (define_insn "*movhi_cc_sp64"
3798 [(set (match_operand:HI 0 "register_operand" "=r,r")
3799 (if_then_else:HI (match_operator 1 "comparison_operator"
3800 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3802 (match_operand:HI 3 "arith11_operand" "rL,0")
3803 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3806 mov%C1\\t%x2, %3, %0
3807 mov%c1\\t%x2, %4, %0"
3808 [(set_attr "type" "cmove")
3809 (set_attr "length" "1")])
3811 (define_insn "*movsi_cc_sp64"
3812 [(set (match_operand:SI 0 "register_operand" "=r,r")
3813 (if_then_else:SI (match_operator 1 "comparison_operator"
3814 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3816 (match_operand:SI 3 "arith11_operand" "rL,0")
3817 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3820 mov%C1\\t%x2, %3, %0
3821 mov%c1\\t%x2, %4, %0"
3822 [(set_attr "type" "cmove")
3823 (set_attr "length" "1")])
3825 ;; ??? The constraints of operands 3,4 need work.
3826 (define_insn "*movdi_cc_sp64"
3827 [(set (match_operand:DI 0 "register_operand" "=r,r")
3828 (if_then_else:DI (match_operator 1 "comparison_operator"
3829 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3831 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3832 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3835 mov%C1\\t%x2, %3, %0
3836 mov%c1\\t%x2, %4, %0"
3837 [(set_attr "type" "cmove")
3838 (set_attr "length" "1")])
3840 (define_insn "*movdi_cc_sp64_trunc"
3841 [(set (match_operand:SI 0 "register_operand" "=r,r")
3842 (if_then_else:SI (match_operator 1 "comparison_operator"
3843 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3845 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3846 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3849 mov%C1\\t%x2, %3, %0
3850 mov%c1\\t%x2, %4, %0"
3851 [(set_attr "type" "cmove")
3852 (set_attr "length" "1")])
3854 (define_insn "*movsf_cc_sp64"
3855 [(set (match_operand:SF 0 "register_operand" "=f,f")
3856 (if_then_else:SF (match_operator 1 "comparison_operator"
3857 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3859 (match_operand:SF 3 "register_operand" "f,0")
3860 (match_operand:SF 4 "register_operand" "0,f")))]
3861 "TARGET_V9 && TARGET_FPU"
3863 fmovs%C1\\t%x2, %3, %0
3864 fmovs%c1\\t%x2, %4, %0"
3865 [(set_attr "type" "fpcmove")
3866 (set_attr "length" "1")])
3868 (define_insn "*movdf_cc_sp64"
3869 [(set (match_operand:DF 0 "register_operand" "=e,e")
3870 (if_then_else:DF (match_operator 1 "comparison_operator"
3871 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3873 (match_operand:DF 3 "register_operand" "e,0")
3874 (match_operand:DF 4 "register_operand" "0,e")))]
3875 "TARGET_V9 && TARGET_FPU"
3877 fmovd%C1\\t%x2, %3, %0
3878 fmovd%c1\\t%x2, %4, %0"
3879 [(set_attr "type" "fpcmove")
3880 (set_attr "length" "1")])
3882 (define_insn "*movtf_cc_sp64"
3883 [(set (match_operand:TF 0 "register_operand" "=e,e")
3884 (if_then_else:TF (match_operator 1 "comparison_operator"
3885 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3887 (match_operand:TF 3 "register_operand" "e,0")
3888 (match_operand:TF 4 "register_operand" "0,e")))]
3889 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3891 fmovq%C1\\t%x2, %3, %0
3892 fmovq%c1\\t%x2, %4, %0"
3893 [(set_attr "type" "fpcmove")
3894 (set_attr "length" "1")])
3896 (define_insn "*movqi_cc_reg_sp64"
3897 [(set (match_operand:QI 0 "register_operand" "=r,r")
3898 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3899 [(match_operand:DI 2 "register_operand" "r,r")
3901 (match_operand:QI 3 "arith10_operand" "rM,0")
3902 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3905 movr%D1\\t%2, %r3, %0
3906 movr%d1\\t%2, %r4, %0"
3907 [(set_attr "type" "cmove")
3908 (set_attr "length" "1")])
3910 (define_insn "*movhi_cc_reg_sp64"
3911 [(set (match_operand:HI 0 "register_operand" "=r,r")
3912 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3913 [(match_operand:DI 2 "register_operand" "r,r")
3915 (match_operand:HI 3 "arith10_operand" "rM,0")
3916 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3919 movr%D1\\t%2, %r3, %0
3920 movr%d1\\t%2, %r4, %0"
3921 [(set_attr "type" "cmove")
3922 (set_attr "length" "1")])
3924 (define_insn "*movsi_cc_reg_sp64"
3925 [(set (match_operand:SI 0 "register_operand" "=r,r")
3926 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3927 [(match_operand:DI 2 "register_operand" "r,r")
3929 (match_operand:SI 3 "arith10_operand" "rM,0")
3930 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3933 movr%D1\\t%2, %r3, %0
3934 movr%d1\\t%2, %r4, %0"
3935 [(set_attr "type" "cmove")
3936 (set_attr "length" "1")])
3938 ;; ??? The constraints of operands 3,4 need work.
3939 (define_insn "*movdi_cc_reg_sp64"
3940 [(set (match_operand:DI 0 "register_operand" "=r,r")
3941 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3942 [(match_operand:DI 2 "register_operand" "r,r")
3944 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3945 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3948 movr%D1\\t%2, %r3, %0
3949 movr%d1\\t%2, %r4, %0"
3950 [(set_attr "type" "cmove")
3951 (set_attr "length" "1")])
3953 (define_insn "*movdi_cc_reg_sp64_trunc"
3954 [(set (match_operand:SI 0 "register_operand" "=r,r")
3955 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3956 [(match_operand:DI 2 "register_operand" "r,r")
3958 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3959 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3962 movr%D1\\t%2, %r3, %0
3963 movr%d1\\t%2, %r4, %0"
3964 [(set_attr "type" "cmove")
3965 (set_attr "length" "1")])
3967 (define_insn "*movsf_cc_reg_sp64"
3968 [(set (match_operand:SF 0 "register_operand" "=f,f")
3969 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3970 [(match_operand:DI 2 "register_operand" "r,r")
3972 (match_operand:SF 3 "register_operand" "f,0")
3973 (match_operand:SF 4 "register_operand" "0,f")))]
3974 "TARGET_ARCH64 && TARGET_FPU"
3976 fmovrs%D1\\t%2, %3, %0
3977 fmovrs%d1\\t%2, %4, %0"
3978 [(set_attr "type" "fpcmove")
3979 (set_attr "length" "1")])
3981 (define_insn "*movdf_cc_reg_sp64"
3982 [(set (match_operand:DF 0 "register_operand" "=e,e")
3983 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3984 [(match_operand:DI 2 "register_operand" "r,r")
3986 (match_operand:DF 3 "register_operand" "e,0")
3987 (match_operand:DF 4 "register_operand" "0,e")))]
3988 "TARGET_ARCH64 && TARGET_FPU"
3990 fmovrd%D1\\t%2, %3, %0
3991 fmovrd%d1\\t%2, %4, %0"
3992 [(set_attr "type" "fpcmove")
3993 (set_attr "length" "1")])
3995 (define_insn "*movtf_cc_reg_sp64"
3996 [(set (match_operand:TF 0 "register_operand" "=e,e")
3997 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3998 [(match_operand:DI 2 "register_operand" "r,r")
4000 (match_operand:TF 3 "register_operand" "e,0")
4001 (match_operand:TF 4 "register_operand" "0,e")))]
4002 "TARGET_ARCH64 && TARGET_FPU"
4004 fmovrq%D1\\t%2, %3, %0
4005 fmovrq%d1\\t%2, %4, %0"
4006 [(set_attr "type" "fpcmove")
4007 (set_attr "length" "1")])
4009 ;;- zero extension instructions
4011 ;; These patterns originally accepted general_operands, however, slightly
4012 ;; better code is generated by only accepting register_operands, and then
4013 ;; letting combine generate the ldu[hb] insns.
4015 (define_expand "zero_extendhisi2"
4016 [(set (match_operand:SI 0 "register_operand" "")
4017 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4021 rtx temp = gen_reg_rtx (SImode);
4022 rtx shift_16 = GEN_INT (16);
4023 int op1_subword = 0;
4025 if (GET_CODE (operand1) == SUBREG)
4027 op1_subword = SUBREG_WORD (operand1);
4028 operand1 = XEXP (operand1, 0);
4031 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4033 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4037 (define_insn "*zero_extendhisi2_insn"
4038 [(set (match_operand:SI 0 "register_operand" "=r")
4039 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4042 [(set_attr "type" "load")
4043 (set_attr "length" "1")])
4045 (define_expand "zero_extendqihi2"
4046 [(set (match_operand:HI 0 "register_operand" "")
4047 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4051 (define_insn "*zero_extendqihi2_insn"
4052 [(set (match_operand:HI 0 "register_operand" "=r,r")
4053 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4054 "GET_CODE (operands[1]) != CONST_INT"
4058 [(set_attr "type" "unary,load")
4059 (set_attr "length" "1")])
4061 (define_expand "zero_extendqisi2"
4062 [(set (match_operand:SI 0 "register_operand" "")
4063 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4067 (define_insn "*zero_extendqisi2_insn"
4068 [(set (match_operand:SI 0 "register_operand" "=r,r")
4069 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4070 "GET_CODE (operands[1]) != CONST_INT"
4074 [(set_attr "type" "unary,load")
4075 (set_attr "length" "1")])
4077 (define_expand "zero_extendqidi2"
4078 [(set (match_operand:DI 0 "register_operand" "")
4079 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4083 (define_insn "*zero_extendqidi2_insn"
4084 [(set (match_operand:DI 0 "register_operand" "=r,r")
4085 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4086 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4090 [(set_attr "type" "unary,load")
4091 (set_attr "length" "1")])
4093 (define_expand "zero_extendhidi2"
4094 [(set (match_operand:DI 0 "register_operand" "")
4095 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4099 rtx temp = gen_reg_rtx (DImode);
4100 rtx shift_48 = GEN_INT (48);
4101 int op1_subword = 0;
4103 if (GET_CODE (operand1) == SUBREG)
4105 op1_subword = SUBREG_WORD (operand1);
4106 operand1 = XEXP (operand1, 0);
4109 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4111 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4115 (define_insn "*zero_extendhidi2_insn"
4116 [(set (match_operand:DI 0 "register_operand" "=r")
4117 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4120 [(set_attr "type" "load")
4121 (set_attr "length" "1")])
4124 ;; ??? Write truncdisi pattern using sra?
4126 (define_expand "zero_extendsidi2"
4127 [(set (match_operand:DI 0 "register_operand" "")
4128 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4132 (define_insn "*zero_extendsidi2_insn_sp64"
4133 [(set (match_operand:DI 0 "register_operand" "=r,r")
4134 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4135 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4139 [(set_attr "type" "shift,load")
4140 (set_attr "length" "1")])
4142 (define_insn "*zero_extendsidi2_insn_sp32"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4147 [(set_attr "type" "unary")
4148 (set_attr "length" "2")])
4151 [(set (match_operand:DI 0 "register_operand" "")
4152 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4153 "! TARGET_ARCH64 && reload_completed"
4154 [(set (match_dup 2) (match_dup 3))
4155 (set (match_dup 4) (match_dup 5))]
4160 if (GET_CODE (operands[0]) == SUBREG)
4161 operands[0] = alter_subreg (operands[0]);
4163 dest1 = gen_highpart (SImode, operands[0]);
4164 dest2 = gen_lowpart (SImode, operands[0]);
4166 /* Swap the order in case of overlap. */
4167 if (REGNO (dest1) == REGNO (operands[1]))
4169 operands[2] = dest2;
4170 operands[3] = operands[1];
4171 operands[4] = dest1;
4172 operands[5] = const0_rtx;
4176 operands[2] = dest1;
4177 operands[3] = const0_rtx;
4178 operands[4] = dest2;
4179 operands[5] = operands[1];
4183 ;; Simplify comparisons of extended values.
4185 (define_insn "*cmp_zero_extendqisi2"
4187 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4190 "andcc\\t%0, 0xff, %%g0"
4191 [(set_attr "type" "compare")
4192 (set_attr "length" "1")])
4194 (define_insn "*cmp_zero_extendqisi2_set"
4196 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4198 (set (match_operand:SI 0 "register_operand" "=r")
4199 (zero_extend:SI (match_dup 1)))]
4201 "andcc\\t%1, 0xff, %0"
4202 [(set_attr "type" "compare")
4203 (set_attr "length" "1")])
4205 (define_insn "*cmp_zero_extendqidi2"
4207 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4210 "andcc\\t%0, 0xff, %%g0"
4211 [(set_attr "type" "compare")
4212 (set_attr "length" "1")])
4214 (define_insn "*cmp_zero_extendqidi2_set"
4216 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4218 (set (match_operand:DI 0 "register_operand" "=r")
4219 (zero_extend:DI (match_dup 1)))]
4221 "andcc\\t%1, 0xff, %0"
4222 [(set_attr "type" "compare")
4223 (set_attr "length" "1")])
4225 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4227 (define_insn "*cmp_siqi_trunc"
4229 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4232 "andcc\\t%0, 0xff, %%g0"
4233 [(set_attr "type" "compare")
4234 (set_attr "length" "1")])
4236 (define_insn "*cmp_siqi_trunc_set"
4238 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4240 (set (match_operand:QI 0 "register_operand" "=r")
4241 (subreg:QI (match_dup 1) 0))]
4243 "andcc\\t%1, 0xff, %0"
4244 [(set_attr "type" "compare")
4245 (set_attr "length" "1")])
4247 (define_insn "*cmp_diqi_trunc"
4249 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4252 "andcc\\t%0, 0xff, %%g0"
4253 [(set_attr "type" "compare")
4254 (set_attr "length" "1")])
4256 (define_insn "*cmp_diqi_trunc_set"
4258 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4260 (set (match_operand:QI 0 "register_operand" "=r")
4261 (subreg:QI (match_dup 1) 0))]
4263 "andcc\\t%1, 0xff, %0"
4264 [(set_attr "type" "compare")
4265 (set_attr "length" "1")])
4267 ;;- sign extension instructions
4269 ;; These patterns originally accepted general_operands, however, slightly
4270 ;; better code is generated by only accepting register_operands, and then
4271 ;; letting combine generate the lds[hb] insns.
4273 (define_expand "extendhisi2"
4274 [(set (match_operand:SI 0 "register_operand" "")
4275 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4279 rtx temp = gen_reg_rtx (SImode);
4280 rtx shift_16 = GEN_INT (16);
4281 int op1_subword = 0;
4283 if (GET_CODE (operand1) == SUBREG)
4285 op1_subword = SUBREG_WORD (operand1);
4286 operand1 = XEXP (operand1, 0);
4289 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4291 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4295 (define_insn "*sign_extendhisi2_insn"
4296 [(set (match_operand:SI 0 "register_operand" "=r")
4297 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4300 [(set_attr "type" "sload")
4301 (set_attr "length" "1")])
4303 (define_expand "extendqihi2"
4304 [(set (match_operand:HI 0 "register_operand" "")
4305 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4309 rtx temp = gen_reg_rtx (SImode);
4310 rtx shift_24 = GEN_INT (24);
4311 int op1_subword = 0;
4312 int op0_subword = 0;
4314 if (GET_CODE (operand1) == SUBREG)
4316 op1_subword = SUBREG_WORD (operand1);
4317 operand1 = XEXP (operand1, 0);
4319 if (GET_CODE (operand0) == SUBREG)
4321 op0_subword = SUBREG_WORD (operand0);
4322 operand0 = XEXP (operand0, 0);
4324 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4326 if (GET_MODE (operand0) != SImode)
4327 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4328 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4332 (define_insn "*sign_extendqihi2_insn"
4333 [(set (match_operand:HI 0 "register_operand" "=r")
4334 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4337 [(set_attr "type" "sload")
4338 (set_attr "length" "1")])
4340 (define_expand "extendqisi2"
4341 [(set (match_operand:SI 0 "register_operand" "")
4342 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4346 rtx temp = gen_reg_rtx (SImode);
4347 rtx shift_24 = GEN_INT (24);
4348 int op1_subword = 0;
4350 if (GET_CODE (operand1) == SUBREG)
4352 op1_subword = SUBREG_WORD (operand1);
4353 operand1 = XEXP (operand1, 0);
4356 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4358 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4362 (define_insn "*sign_extendqisi2_insn"
4363 [(set (match_operand:SI 0 "register_operand" "=r")
4364 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4367 [(set_attr "type" "sload")
4368 (set_attr "length" "1")])
4370 (define_expand "extendqidi2"
4371 [(set (match_operand:DI 0 "register_operand" "")
4372 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4376 rtx temp = gen_reg_rtx (DImode);
4377 rtx shift_56 = GEN_INT (56);
4378 int op1_subword = 0;
4380 if (GET_CODE (operand1) == SUBREG)
4382 op1_subword = SUBREG_WORD (operand1);
4383 operand1 = XEXP (operand1, 0);
4386 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4388 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4392 (define_insn "*sign_extendqidi2_insn"
4393 [(set (match_operand:DI 0 "register_operand" "=r")
4394 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4397 [(set_attr "type" "sload")
4398 (set_attr "length" "1")])
4400 (define_expand "extendhidi2"
4401 [(set (match_operand:DI 0 "register_operand" "")
4402 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4406 rtx temp = gen_reg_rtx (DImode);
4407 rtx shift_48 = GEN_INT (48);
4408 int op1_subword = 0;
4410 if (GET_CODE (operand1) == SUBREG)
4412 op1_subword = SUBREG_WORD (operand1);
4413 operand1 = XEXP (operand1, 0);
4416 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4418 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4422 (define_insn "*sign_extendhidi2_insn"
4423 [(set (match_operand:DI 0 "register_operand" "=r")
4424 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4427 [(set_attr "type" "sload")
4428 (set_attr "length" "1")])
4430 (define_expand "extendsidi2"
4431 [(set (match_operand:DI 0 "register_operand" "")
4432 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4436 (define_insn "*sign_extendsidi2_insn"
4437 [(set (match_operand:DI 0 "register_operand" "=r,r")
4438 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4443 [(set_attr "type" "shift,sload")
4444 (set_attr "length" "1")])
4446 ;; Special pattern for optimizing bit-field compares. This is needed
4447 ;; because combine uses this as a canonical form.
4449 (define_insn "*cmp_zero_extract"
4452 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4453 (match_operand:SI 1 "small_int_or_double" "n")
4454 (match_operand:SI 2 "small_int_or_double" "n"))
4457 && ((GET_CODE (operands[2]) == CONST_INT
4458 && INTVAL (operands[2]) > 19)
4459 || (GET_CODE (operands[2]) == CONST_DOUBLE
4460 && CONST_DOUBLE_LOW (operands[2]) > 19))"
4463 int len = (GET_CODE (operands[1]) == CONST_INT
4464 ? INTVAL (operands[1])
4465 : CONST_DOUBLE_LOW (operands[1]));
4467 (GET_CODE (operands[2]) == CONST_INT
4468 ? INTVAL (operands[2])
4469 : CONST_DOUBLE_LOW (operands[2])) - len;
4470 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4472 operands[1] = GEN_INT (mask);
4473 return \"andcc\\t%0, %1, %%g0\";
4475 [(set_attr "type" "compare")
4476 (set_attr "length" "1")])
4478 (define_insn "*cmp_zero_extract_sp64"
4481 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4482 (match_operand:SI 1 "small_int_or_double" "n")
4483 (match_operand:SI 2 "small_int_or_double" "n"))
4486 && ((GET_CODE (operands[2]) == CONST_INT
4487 && INTVAL (operands[2]) > 51)
4488 || (GET_CODE (operands[2]) == CONST_DOUBLE
4489 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4492 int len = (GET_CODE (operands[1]) == CONST_INT
4493 ? INTVAL (operands[1])
4494 : CONST_DOUBLE_LOW (operands[1]));
4496 (GET_CODE (operands[2]) == CONST_INT
4497 ? INTVAL (operands[2])
4498 : CONST_DOUBLE_LOW (operands[2])) - len;
4499 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4501 operands[1] = GEN_INT (mask);
4502 return \"andcc\\t%0, %1, %%g0\";
4504 [(set_attr "type" "compare")
4505 (set_attr "length" "1")])
4507 ;; Conversions between float, double and long double.
4509 (define_insn "extendsfdf2"
4510 [(set (match_operand:DF 0 "register_operand" "=e")
4512 (match_operand:SF 1 "register_operand" "f")))]
4515 [(set_attr "type" "fp")
4516 (set_attr "length" "1")])
4518 (define_insn "extendsftf2"
4519 [(set (match_operand:TF 0 "register_operand" "=e")
4521 (match_operand:SF 1 "register_operand" "f")))]
4522 "TARGET_FPU && TARGET_HARD_QUAD"
4524 [(set_attr "type" "fp")
4525 (set_attr "length" "1")])
4527 (define_insn "extenddftf2"
4528 [(set (match_operand:TF 0 "register_operand" "=e")
4530 (match_operand:DF 1 "register_operand" "e")))]
4531 "TARGET_FPU && TARGET_HARD_QUAD"
4533 [(set_attr "type" "fp")
4534 (set_attr "length" "1")])
4536 (define_insn "truncdfsf2"
4537 [(set (match_operand:SF 0 "register_operand" "=f")
4539 (match_operand:DF 1 "register_operand" "e")))]
4542 [(set_attr "type" "fp")
4543 (set_attr "length" "1")])
4545 (define_insn "trunctfsf2"
4546 [(set (match_operand:SF 0 "register_operand" "=f")
4548 (match_operand:TF 1 "register_operand" "e")))]
4549 "TARGET_FPU && TARGET_HARD_QUAD"
4551 [(set_attr "type" "fp")
4552 (set_attr "length" "1")])
4554 (define_insn "trunctfdf2"
4555 [(set (match_operand:DF 0 "register_operand" "=e")
4557 (match_operand:TF 1 "register_operand" "e")))]
4558 "TARGET_FPU && TARGET_HARD_QUAD"
4560 [(set_attr "type" "fp")
4561 (set_attr "length" "1")])
4563 ;; Conversion between fixed point and floating point.
4565 (define_insn "floatsisf2"
4566 [(set (match_operand:SF 0 "register_operand" "=f")
4567 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4570 [(set_attr "type" "fp")
4571 (set_attr "length" "1")])
4573 (define_insn "floatsidf2"
4574 [(set (match_operand:DF 0 "register_operand" "=e")
4575 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4578 [(set_attr "type" "fp")
4579 (set_attr "length" "1")])
4581 (define_insn "floatsitf2"
4582 [(set (match_operand:TF 0 "register_operand" "=e")
4583 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4584 "TARGET_FPU && TARGET_HARD_QUAD"
4586 [(set_attr "type" "fp")
4587 (set_attr "length" "1")])
4589 ;; Now the same for 64 bit sources.
4591 (define_insn "floatdisf2"
4592 [(set (match_operand:SF 0 "register_operand" "=f")
4593 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4594 "TARGET_V9 && TARGET_FPU"
4596 [(set_attr "type" "fp")
4597 (set_attr "length" "1")])
4599 (define_insn "floatdidf2"
4600 [(set (match_operand:DF 0 "register_operand" "=e")
4601 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4602 "TARGET_V9 && TARGET_FPU"
4604 [(set_attr "type" "fp")
4605 (set_attr "length" "1")])
4607 (define_insn "floatditf2"
4608 [(set (match_operand:TF 0 "register_operand" "=e")
4609 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4610 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4612 [(set_attr "type" "fp")
4613 (set_attr "length" "1")])
4615 ;; Convert a float to an actual integer.
4616 ;; Truncation is performed as part of the conversion.
4618 (define_insn "fix_truncsfsi2"
4619 [(set (match_operand:SI 0 "register_operand" "=f")
4620 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4623 [(set_attr "type" "fp")
4624 (set_attr "length" "1")])
4626 (define_insn "fix_truncdfsi2"
4627 [(set (match_operand:SI 0 "register_operand" "=f")
4628 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4631 [(set_attr "type" "fp")
4632 (set_attr "length" "1")])
4634 (define_insn "fix_trunctfsi2"
4635 [(set (match_operand:SI 0 "register_operand" "=f")
4636 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4637 "TARGET_FPU && TARGET_HARD_QUAD"
4639 [(set_attr "type" "fp")
4640 (set_attr "length" "1")])
4642 ;; Now the same, for V9 targets
4644 (define_insn "fix_truncsfdi2"
4645 [(set (match_operand:DI 0 "register_operand" "=e")
4646 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4647 "TARGET_V9 && TARGET_FPU"
4649 [(set_attr "type" "fp")
4650 (set_attr "length" "1")])
4652 (define_insn "fix_truncdfdi2"
4653 [(set (match_operand:DI 0 "register_operand" "=e")
4654 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4655 "TARGET_V9 && TARGET_FPU"
4657 [(set_attr "type" "fp")
4658 (set_attr "length" "1")])
4660 (define_insn "fix_trunctfdi2"
4661 [(set (match_operand:DI 0 "register_operand" "=e")
4662 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4663 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4665 [(set_attr "type" "fp")
4666 (set_attr "length" "1")])
4668 ;;- arithmetic instructions
4670 (define_expand "adddi3"
4671 [(set (match_operand:DI 0 "register_operand" "=r")
4672 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4673 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4677 if (! TARGET_ARCH64)
4679 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4680 gen_rtx_SET (VOIDmode, operands[0],
4681 gen_rtx_PLUS (DImode, operands[1],
4683 gen_rtx_CLOBBER (VOIDmode,
4684 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4687 if (arith_double_4096_operand(operands[2], DImode))
4689 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4690 gen_rtx_MINUS (DImode, operands[1],
4696 (define_insn "adddi3_insn_sp32"
4697 [(set (match_operand:DI 0 "register_operand" "=r")
4698 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4699 (match_operand:DI 2 "arith_double_operand" "rHI")))
4700 (clobber (reg:CC 100))]
4703 [(set_attr "length" "2")])
4706 [(set (match_operand:DI 0 "register_operand" "=r")
4707 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4708 (match_operand:DI 2 "arith_double_operand" "rHI")))
4709 (clobber (reg:CC 100))]
4710 "! TARGET_ARCH64 && reload_completed"
4711 [(parallel [(set (reg:CC_NOOV 100)
4712 (compare:CC_NOOV (plus:SI (match_dup 4)
4716 (plus:SI (match_dup 4) (match_dup 5)))])
4718 (plus:SI (plus:SI (match_dup 7)
4720 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4723 operands[3] = gen_lowpart (SImode, operands[0]);
4724 operands[4] = gen_lowpart (SImode, operands[1]);
4725 operands[5] = gen_lowpart (SImode, operands[2]);
4726 operands[6] = gen_highpart (SImode, operands[0]);
4727 operands[7] = gen_highpart (SImode, operands[1]);
4728 if (GET_CODE (operands[2]) == CONST_INT)
4730 if (INTVAL (operands[2]) < 0)
4731 operands[8] = constm1_rtx;
4733 operands[8] = const0_rtx;
4736 operands[8] = gen_highpart (SImode, operands[2]);
4740 [(set (match_operand:DI 0 "register_operand" "=r")
4741 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
4742 (match_operand:DI 2 "arith_double_operand" "rHI")))
4743 (clobber (reg:CC 100))]
4744 "! TARGET_ARCH64 && reload_completed"
4745 [(parallel [(set (reg:CC_NOOV 100)
4746 (compare:CC_NOOV (minus:SI (match_dup 4)
4750 (minus:SI (match_dup 4) (match_dup 5)))])
4752 (minus:SI (minus:SI (match_dup 7)
4754 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4757 operands[3] = gen_lowpart (SImode, operands[0]);
4758 operands[4] = gen_lowpart (SImode, operands[1]);
4759 operands[5] = gen_lowpart (SImode, operands[2]);
4760 operands[6] = gen_highpart (SImode, operands[0]);
4761 operands[7] = gen_highpart (SImode, operands[1]);
4762 if (GET_CODE (operands[2]) == CONST_INT)
4764 if (INTVAL (operands[2]) < 0)
4765 operands[8] = constm1_rtx;
4767 operands[8] = const0_rtx;
4770 operands[8] = gen_highpart (SImode, operands[2]);
4773 ;; LTU here means "carry set"
4775 [(set (match_operand:SI 0 "register_operand" "=r")
4776 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4777 (match_operand:SI 2 "arith_operand" "rI"))
4778 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4781 [(set_attr "type" "unary")
4782 (set_attr "length" "1")])
4784 (define_insn "*addx_extend_sp32"
4785 [(set (match_operand:DI 0 "register_operand" "=r")
4786 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4787 (match_operand:SI 2 "arith_operand" "rI"))
4788 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4791 [(set_attr "type" "unary")
4792 (set_attr "length" "2")])
4795 [(set (match_operand:DI 0 "register_operand" "")
4796 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
4797 (match_operand:SI 2 "arith_operand" ""))
4798 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4799 "! TARGET_ARCH64 && reload_completed"
4800 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4801 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4802 (set (match_dup 4) (const_int 0))]
4803 "operands[3] = gen_lowpart (SImode, operands[0]);
4804 operands[4] = gen_highpart (SImode, operands[1]);")
4806 (define_insn "*addx_extend_sp64"
4807 [(set (match_operand:DI 0 "register_operand" "=r")
4808 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4809 (match_operand:SI 2 "arith_operand" "rI"))
4810 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4812 "addx\\t%r1, %2, %0"
4813 [(set_attr "type" "misc")
4814 (set_attr "length" "1")])
4817 [(set (match_operand:SI 0 "register_operand" "=r")
4818 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4819 (match_operand:SI 2 "arith_operand" "rI"))
4820 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4822 "subx\\t%r1, %2, %0"
4823 [(set_attr "type" "misc")
4824 (set_attr "length" "1")])
4826 (define_insn "*subx_extend_sp64"
4827 [(set (match_operand:DI 0 "register_operand" "=r")
4828 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4829 (match_operand:SI 2 "arith_operand" "rI"))
4830 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4832 "subx\\t%r1, %2, %0"
4833 [(set_attr "type" "misc")
4834 (set_attr "length" "1")])
4836 (define_insn "*subx_extend"
4837 [(set (match_operand:DI 0 "register_operand" "=r")
4838 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4839 (match_operand:SI 2 "arith_operand" "rI"))
4840 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4843 [(set_attr "type" "unary")
4844 (set_attr "length" "2")])
4847 [(set (match_operand:DI 0 "register_operand" "=r")
4848 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4849 (match_operand:SI 2 "arith_operand" "rI"))
4850 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4851 "! TARGET_ARCH64 && reload_completed"
4852 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4853 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4854 (set (match_dup 4) (const_int 0))]
4855 "operands[3] = gen_lowpart (SImode, operands[0]);
4856 operands[4] = gen_highpart (SImode, operands[0]);")
4859 [(set (match_operand:DI 0 "register_operand" "=r")
4860 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4861 (match_operand:DI 2 "register_operand" "r")))
4862 (clobber (reg:CC 100))]
4865 [(set_attr "type" "multi")
4866 (set_attr "length" "2")])
4869 [(set (match_operand:DI 0 "register_operand" "")
4870 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4871 (match_operand:DI 2 "register_operand" "")))
4872 (clobber (reg:CC 100))]
4873 "! TARGET_ARCH64 && reload_completed"
4874 [(parallel [(set (reg:CC_NOOV 100)
4875 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4877 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4879 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4880 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4881 "operands[3] = gen_lowpart (SImode, operands[2]);
4882 operands[4] = gen_highpart (SImode, operands[2]);
4883 operands[5] = gen_lowpart (SImode, operands[0]);
4884 operands[6] = gen_highpart (SImode, operands[0]);")
4886 (define_insn "*adddi3_sp64"
4887 [(set (match_operand:DI 0 "register_operand" "=r")
4888 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4889 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4892 [(set_attr "type" "binary")
4893 (set_attr "length" "1")])
4895 (define_expand "addsi3"
4896 [(set (match_operand:SI 0 "register_operand" "=r,d")
4897 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4898 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4902 if (arith_4096_operand(operands[2], DImode))
4904 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4905 gen_rtx_MINUS (SImode, operands[1],
4911 (define_insn "*addsi3"
4912 [(set (match_operand:SI 0 "register_operand" "=r,d")
4913 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4914 (match_operand:SI 2 "arith_operand" "rI,d")))]
4918 fpadd32s\\t%1, %2, %0"
4919 [(set_attr "type" "ialu,fp")
4920 (set_attr "length" "1")])
4922 (define_insn "*cmp_cc_plus"
4923 [(set (reg:CC_NOOV 100)
4924 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4925 (match_operand:SI 1 "arith_operand" "rI"))
4928 "addcc\\t%0, %1, %%g0"
4929 [(set_attr "type" "compare")
4930 (set_attr "length" "1")])
4932 (define_insn "*cmp_ccx_plus"
4933 [(set (reg:CCX_NOOV 100)
4934 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4935 (match_operand:DI 1 "arith_double_operand" "rHI"))
4938 "addcc\\t%0, %1, %%g0"
4939 [(set_attr "type" "compare")
4940 (set_attr "length" "1")])
4942 (define_insn "*cmp_cc_plus_set"
4943 [(set (reg:CC_NOOV 100)
4944 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4945 (match_operand:SI 2 "arith_operand" "rI"))
4947 (set (match_operand:SI 0 "register_operand" "=r")
4948 (plus:SI (match_dup 1) (match_dup 2)))]
4950 "addcc\\t%1, %2, %0"
4951 [(set_attr "type" "compare")
4952 (set_attr "length" "1")])
4954 (define_insn "*cmp_ccx_plus_set"
4955 [(set (reg:CCX_NOOV 100)
4956 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4957 (match_operand:DI 2 "arith_double_operand" "rHI"))
4959 (set (match_operand:DI 0 "register_operand" "=r")
4960 (plus:DI (match_dup 1) (match_dup 2)))]
4962 "addcc\\t%1, %2, %0"
4963 [(set_attr "type" "compare")
4964 (set_attr "length" "1")])
4966 (define_expand "subdi3"
4967 [(set (match_operand:DI 0 "register_operand" "=r")
4968 (minus:DI (match_operand:DI 1 "register_operand" "r")
4969 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4973 if (! TARGET_ARCH64)
4975 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4976 gen_rtx_SET (VOIDmode, operands[0],
4977 gen_rtx_MINUS (DImode, operands[1],
4979 gen_rtx_CLOBBER (VOIDmode,
4980 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4983 if (arith_double_4096_operand(operands[2], DImode))
4985 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4986 gen_rtx_PLUS (DImode, operands[1],
4992 (define_insn "*subdi3_sp32"
4993 [(set (match_operand:DI 0 "register_operand" "=r")
4994 (minus:DI (match_operand:DI 1 "register_operand" "r")
4995 (match_operand:DI 2 "arith_double_operand" "rHI")))
4996 (clobber (reg:CC 100))]
4999 [(set_attr "length" "2")])
5002 [(set (match_operand:DI 0 "register_operand" "")
5003 (minus:DI (match_operand:DI 1 "register_operand" "")
5004 (match_operand:DI 2 "arith_double_operand" "")))
5005 (clobber (reg:CC 100))]
5008 && (GET_CODE (operands[2]) == CONST_INT
5009 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5010 [(clobber (const_int 0))]
5015 highp = gen_highpart (SImode, operands[2]);
5016 lowp = gen_lowpart (SImode, operands[2]);
5017 if ((lowp == const0_rtx)
5018 && (operands[0] == operands[1]))
5020 emit_insn (gen_rtx_SET (VOIDmode,
5021 gen_highpart (SImode, operands[0]),
5022 gen_rtx_MINUS (SImode,
5023 gen_highpart (SImode, operands[1]),
5028 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5029 gen_lowpart (SImode, operands[1]),
5031 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5032 gen_highpart (SImode, operands[1]),
5039 [(set (match_operand:DI 0 "register_operand" "")
5040 (minus:DI (match_operand:DI 1 "register_operand" "")
5041 (match_operand:DI 2 "register_operand" "")))
5042 (clobber (reg:CC 100))]
5044 && reload_completed"
5045 [(clobber (const_int 0))]
5048 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5049 gen_lowpart (SImode, operands[1]),
5050 gen_lowpart (SImode, operands[2])));
5051 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5052 gen_highpart (SImode, operands[1]),
5053 gen_highpart (SImode, operands[2])));
5058 [(set (match_operand:DI 0 "register_operand" "=r")
5059 (minus:DI (match_operand:DI 1 "register_operand" "r")
5060 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5061 (clobber (reg:CC 100))]
5064 [(set_attr "type" "multi")
5065 (set_attr "length" "2")])
5068 [(set (match_operand:DI 0 "register_operand" "")
5069 (minus:DI (match_operand:DI 1 "register_operand" "")
5070 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5071 (clobber (reg:CC 100))]
5072 "! TARGET_ARCH64 && reload_completed"
5073 [(parallel [(set (reg:CC_NOOV 100)
5074 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5076 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5078 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5079 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5080 "operands[3] = gen_lowpart (SImode, operands[1]);
5081 operands[4] = gen_highpart (SImode, operands[1]);
5082 operands[5] = gen_lowpart (SImode, operands[0]);
5083 operands[6] = gen_highpart (SImode, operands[0]);")
5085 (define_insn "*subdi3_sp64"
5086 [(set (match_operand:DI 0 "register_operand" "=r")
5087 (minus:DI (match_operand:DI 1 "register_operand" "r")
5088 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5091 [(set_attr "type" "binary")
5092 (set_attr "length" "1")])
5094 (define_expand "subsi3"
5095 [(set (match_operand:SI 0 "register_operand" "=r,d")
5096 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5097 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5101 if (arith_4096_operand(operands[2], DImode))
5103 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5104 gen_rtx_PLUS (SImode, operands[1],
5110 (define_insn "*subsi3"
5111 [(set (match_operand:SI 0 "register_operand" "=r,d")
5112 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5113 (match_operand:SI 2 "arith_operand" "rI,d")))]
5117 fpsub32s\\t%1, %2, %0"
5118 [(set_attr "type" "ialu,fp")
5119 (set_attr "length" "1")])
5121 (define_insn "*cmp_minus_cc"
5122 [(set (reg:CC_NOOV 100)
5123 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5124 (match_operand:SI 1 "arith_operand" "rI"))
5127 "subcc\\t%r0, %1, %%g0"
5128 [(set_attr "type" "compare")
5129 (set_attr "length" "1")])
5131 (define_insn "*cmp_minus_ccx"
5132 [(set (reg:CCX_NOOV 100)
5133 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5134 (match_operand:DI 1 "arith_double_operand" "rHI"))
5137 "subcc\\t%0, %1, %%g0"
5138 [(set_attr "type" "compare")
5139 (set_attr "length" "1")])
5141 (define_insn "cmp_minus_cc_set"
5142 [(set (reg:CC_NOOV 100)
5143 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5144 (match_operand:SI 2 "arith_operand" "rI"))
5146 (set (match_operand:SI 0 "register_operand" "=r")
5147 (minus:SI (match_dup 1) (match_dup 2)))]
5149 "subcc\\t%r1, %2, %0"
5150 [(set_attr "type" "compare")
5151 (set_attr "length" "1")])
5153 (define_insn "*cmp_minus_ccx_set"
5154 [(set (reg:CCX_NOOV 100)
5155 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5156 (match_operand:DI 2 "arith_double_operand" "rHI"))
5158 (set (match_operand:DI 0 "register_operand" "=r")
5159 (minus:DI (match_dup 1) (match_dup 2)))]
5161 "subcc\\t%1, %2, %0"
5162 [(set_attr "type" "compare")
5163 (set_attr "length" "1")])
5165 ;; Integer Multiply/Divide.
5167 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5168 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5170 (define_insn "mulsi3"
5171 [(set (match_operand:SI 0 "register_operand" "=r")
5172 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5173 (match_operand:SI 2 "arith_operand" "rI")))]
5176 [(set_attr "type" "imul")
5177 (set_attr "length" "1")])
5179 (define_expand "muldi3"
5180 [(set (match_operand:DI 0 "register_operand" "=r")
5181 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5182 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5183 "TARGET_ARCH64 || TARGET_V8PLUS"
5188 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5193 (define_insn "*muldi3_sp64"
5194 [(set (match_operand:DI 0 "register_operand" "=r")
5195 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5196 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5199 [(set_attr "type" "imul")
5200 (set_attr "length" "1")])
5202 ;; V8plus wide multiply.
5204 (define_insn "muldi3_v8plus"
5205 [(set (match_operand:DI 0 "register_operand" "=r,h")
5206 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5207 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5208 (clobber (match_scratch:SI 3 "=&h,X"))
5209 (clobber (match_scratch:SI 4 "=&h,X"))]
5213 if (sparc_check_64 (operands[1], insn) <= 0)
5214 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5215 if (which_alternative == 1)
5216 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5217 if (sparc_check_64 (operands[2], insn) <= 0)
5218 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5219 if (which_alternative == 1)
5220 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\";
5222 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\";
5224 [(set_attr "length" "9,8")])
5226 (define_insn "*cmp_mul_set"
5228 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5229 (match_operand:SI 2 "arith_operand" "rI"))
5231 (set (match_operand:SI 0 "register_operand" "=r")
5232 (mult:SI (match_dup 1) (match_dup 2)))]
5233 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5234 "smulcc\\t%1, %2, %0"
5235 [(set_attr "type" "imul")
5236 (set_attr "length" "1")])
5238 (define_expand "mulsidi3"
5239 [(set (match_operand:DI 0 "register_operand" "")
5240 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5241 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5245 if (CONSTANT_P (operands[2]))
5248 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5251 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5257 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5262 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5263 ;; registers can hold 64 bit values in the V8plus environment.
5265 (define_insn "mulsidi3_v8plus"
5266 [(set (match_operand:DI 0 "register_operand" "=h,r")
5267 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5268 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5269 (clobber (match_scratch:SI 3 "=X,&h"))]
5272 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5273 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5274 [(set_attr "length" "2,3")])
5277 (define_insn "const_mulsidi3_v8plus"
5278 [(set (match_operand:DI 0 "register_operand" "=h,r")
5279 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5280 (match_operand:SI 2 "small_int" "I,I")))
5281 (clobber (match_scratch:SI 3 "=X,&h"))]
5284 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5285 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5286 [(set_attr "length" "2,3")])
5289 (define_insn "*mulsidi3_sp32"
5290 [(set (match_operand:DI 0 "register_operand" "=r")
5291 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5292 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5296 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5298 [(set (attr "length")
5299 (if_then_else (eq_attr "isa" "sparclet")
5300 (const_int 1) (const_int 2)))])
5302 (define_insn "*mulsidi3_sp64"
5303 [(set (match_operand:DI 0 "register_operand" "=r")
5304 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5305 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5306 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5308 [(set_attr "length" "1")])
5310 ;; Extra pattern, because sign_extend of a constant isn't valid.
5313 (define_insn "const_mulsidi3_sp32"
5314 [(set (match_operand:DI 0 "register_operand" "=r")
5315 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5316 (match_operand:SI 2 "small_int" "I")))]
5320 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5322 [(set (attr "length")
5323 (if_then_else (eq_attr "isa" "sparclet")
5324 (const_int 1) (const_int 2)))])
5326 (define_insn "const_mulsidi3_sp64"
5327 [(set (match_operand:DI 0 "register_operand" "=r")
5328 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5329 (match_operand:SI 2 "small_int" "I")))]
5330 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5332 [(set_attr "length" "1")])
5334 (define_expand "smulsi3_highpart"
5335 [(set (match_operand:SI 0 "register_operand" "")
5337 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5338 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5340 "TARGET_HARD_MUL && TARGET_ARCH32"
5343 if (CONSTANT_P (operands[2]))
5347 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5353 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5358 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5359 operands[2], GEN_INT (32)));
5365 (define_insn "smulsi3_highpart_v8plus"
5366 [(set (match_operand:SI 0 "register_operand" "=h,r")
5368 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5369 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5370 (match_operand:SI 3 "const_int_operand" "i,i"))))
5371 (clobber (match_scratch:SI 4 "=X,&h"))]
5374 smul %1,%2,%0\;srlx %0,%3,%0
5375 smul %1,%2,%4\;srlx %4,%3,%0"
5376 [(set_attr "length" "2")])
5378 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5381 [(set (match_operand:SI 0 "register_operand" "=h,r")
5384 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5385 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5386 (match_operand:SI 3 "const_int_operand" "i,i"))
5388 (clobber (match_scratch:SI 4 "=X,&h"))]
5391 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5392 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5393 [(set_attr "length" "2")])
5396 (define_insn "const_smulsi3_highpart_v8plus"
5397 [(set (match_operand:SI 0 "register_operand" "=h,r")
5399 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5400 (match_operand 2 "small_int" "i,i"))
5401 (match_operand:SI 3 "const_int_operand" "i,i"))))
5402 (clobber (match_scratch:SI 4 "=X,&h"))]
5405 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5406 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5407 [(set_attr "length" "2")])
5410 (define_insn "*smulsi3_highpart_sp32"
5411 [(set (match_operand:SI 0 "register_operand" "=r")
5413 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5414 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5416 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5417 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5418 [(set_attr "length" "2")])
5421 (define_insn "const_smulsi3_highpart"
5422 [(set (match_operand:SI 0 "register_operand" "=r")
5424 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5425 (match_operand:SI 2 "register_operand" "r"))
5427 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5428 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5429 [(set_attr "length" "2")])
5431 (define_expand "umulsidi3"
5432 [(set (match_operand:DI 0 "register_operand" "")
5433 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5434 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5438 if (CONSTANT_P (operands[2]))
5441 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5444 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5450 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5456 (define_insn "umulsidi3_v8plus"
5457 [(set (match_operand:DI 0 "register_operand" "=h,r")
5458 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5459 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5460 (clobber (match_scratch:SI 3 "=X,&h"))]
5463 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5464 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5465 [(set_attr "length" "2,3")])
5468 (define_insn "*umulsidi3_sp32"
5469 [(set (match_operand:DI 0 "register_operand" "=r")
5470 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5471 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5475 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5477 [(set (attr "length")
5478 (if_then_else (eq_attr "isa" "sparclet")
5479 (const_int 1) (const_int 2)))])
5481 (define_insn "*umulsidi3_sp64"
5482 [(set (match_operand:DI 0 "register_operand" "=r")
5483 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5484 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5485 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5487 [(set_attr "length" "1")])
5489 ;; Extra pattern, because sign_extend of a constant isn't valid.
5492 (define_insn "const_umulsidi3_sp32"
5493 [(set (match_operand:DI 0 "register_operand" "=r")
5494 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5495 (match_operand:SI 2 "uns_small_int" "")))]
5499 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5501 [(set (attr "length")
5502 (if_then_else (eq_attr "isa" "sparclet")
5503 (const_int 1) (const_int 2)))])
5505 (define_insn "const_umulsidi3_sp64"
5506 [(set (match_operand:DI 0 "register_operand" "=r")
5507 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5508 (match_operand:SI 2 "uns_small_int" "")))]
5509 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5511 [(set_attr "length" "1")])
5514 (define_insn "const_umulsidi3_v8plus"
5515 [(set (match_operand:DI 0 "register_operand" "=h,r")
5516 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5517 (match_operand:SI 2 "uns_small_int" "")))
5518 (clobber (match_scratch:SI 3 "=X,h"))]
5521 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5522 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5523 [(set_attr "length" "2,3")])
5525 (define_expand "umulsi3_highpart"
5526 [(set (match_operand:SI 0 "register_operand" "")
5528 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5529 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5531 "TARGET_HARD_MUL && TARGET_ARCH32"
5534 if (CONSTANT_P (operands[2]))
5538 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5544 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5549 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5550 operands[2], GEN_INT (32)));
5556 (define_insn "umulsi3_highpart_v8plus"
5557 [(set (match_operand:SI 0 "register_operand" "=h,r")
5559 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5560 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5561 (match_operand:SI 3 "const_int_operand" "i,i"))))
5562 (clobber (match_scratch:SI 4 "=X,h"))]
5565 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5566 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5567 [(set_attr "length" "2")])
5570 (define_insn "const_umulsi3_highpart_v8plus"
5571 [(set (match_operand:SI 0 "register_operand" "=h,r")
5573 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5574 (match_operand:SI 2 "uns_small_int" ""))
5575 (match_operand:SI 3 "const_int_operand" "i,i"))))
5576 (clobber (match_scratch:SI 4 "=X,h"))]
5579 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5580 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5581 [(set_attr "length" "2")])
5584 (define_insn "*umulsi3_highpart_sp32"
5585 [(set (match_operand:SI 0 "register_operand" "=r")
5587 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5588 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5590 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5591 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5592 [(set_attr "length" "2")])
5595 (define_insn "const_umulsi3_highpart"
5596 [(set (match_operand:SI 0 "register_operand" "=r")
5598 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5599 (match_operand:SI 2 "uns_small_int" ""))
5601 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
5602 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5603 [(set_attr "length" "2")])
5605 ;; The v8 architecture specifies that there must be 3 instructions between
5606 ;; a y register write and a use of it for correct results.
5608 (define_expand "divsi3"
5609 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5610 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5611 (match_operand:SI 2 "input_operand" "rI,m")))
5612 (clobber (match_scratch:SI 3 "=&r,&r"))])]
5613 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5618 operands[3] = gen_reg_rtx(SImode);
5619 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5620 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5626 (define_insn "divsi3_sp32"
5627 [(set (match_operand:SI 0 "register_operand" "=r,r")
5628 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5629 (match_operand:SI 2 "input_operand" "rI,m")))
5630 (clobber (match_scratch:SI 3 "=&r,&r"))]
5631 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5635 if (which_alternative == 0)
5637 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
5639 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5642 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5644 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\";
5646 [(set (attr "length")
5647 (if_then_else (eq_attr "isa" "v9")
5648 (const_int 4) (const_int 7)))])
5650 (define_insn "divsi3_sp64"
5651 [(set (match_operand:SI 0 "register_operand" "=r")
5652 (div:SI (match_operand:SI 1 "register_operand" "r")
5653 (match_operand:SI 2 "input_operand" "rI")))
5654 (use (match_operand:SI 3 "register_operand" "r"))]
5655 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5656 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
5657 [(set_attr "length" "2")])
5659 (define_insn "divdi3"
5660 [(set (match_operand:DI 0 "register_operand" "=r")
5661 (div:DI (match_operand:DI 1 "register_operand" "r")
5662 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5664 "sdivx\\t%1, %2, %0")
5666 (define_insn "*cmp_sdiv_cc_set"
5668 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5669 (match_operand:SI 2 "arith_operand" "rI"))
5671 (set (match_operand:SI 0 "register_operand" "=r")
5672 (div:SI (match_dup 1) (match_dup 2)))
5673 (clobber (match_scratch:SI 3 "=&r"))]
5674 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5678 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5680 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5682 [(set (attr "length")
5683 (if_then_else (eq_attr "isa" "v9")
5684 (const_int 3) (const_int 6)))])
5687 (define_expand "udivsi3"
5688 [(set (match_operand:SI 0 "register_operand" "")
5689 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5690 (match_operand:SI 2 "input_operand" "")))]
5691 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && ! TARGET_LIVE_G0"
5694 (define_insn "udivsi3_sp32"
5695 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5696 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5697 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5699 || TARGET_DEPRECATED_V8_INSNS)
5700 && TARGET_ARCH32 && ! TARGET_LIVE_G0"
5703 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
5704 switch (which_alternative)
5707 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
5709 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
5711 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
5714 [(set_attr "length" "5")])
5716 (define_insn "udivsi3_sp64"
5717 [(set (match_operand:SI 0 "register_operand" "=r")
5718 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5719 (match_operand:SI 2 "input_operand" "rI")))]
5720 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5721 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
5722 [(set_attr "length" "2")])
5724 (define_insn "udivdi3"
5725 [(set (match_operand:DI 0 "register_operand" "=r")
5726 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5727 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5729 "udivx\\t%1, %2, %0")
5731 (define_insn "*cmp_udiv_cc_set"
5733 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5734 (match_operand:SI 2 "arith_operand" "rI"))
5736 (set (match_operand:SI 0 "register_operand" "=r")
5737 (udiv:SI (match_dup 1) (match_dup 2)))]
5739 || TARGET_DEPRECATED_V8_INSNS)
5740 && ! TARGET_LIVE_G0"
5744 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
5746 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
5748 [(set (attr "length")
5749 (if_then_else (eq_attr "isa" "v9")
5750 (const_int 2) (const_int 5)))])
5752 ; sparclet multiply/accumulate insns
5754 (define_insn "*smacsi"
5755 [(set (match_operand:SI 0 "register_operand" "=r")
5756 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5757 (match_operand:SI 2 "arith_operand" "rI"))
5758 (match_operand:SI 3 "register_operand" "0")))]
5761 [(set_attr "type" "imul")
5762 (set_attr "length" "1")])
5764 (define_insn "*smacdi"
5765 [(set (match_operand:DI 0 "register_operand" "=r")
5766 (plus:DI (mult:DI (sign_extend:DI
5767 (match_operand:SI 1 "register_operand" "%r"))
5769 (match_operand:SI 2 "register_operand" "r")))
5770 (match_operand:DI 3 "register_operand" "0")))]
5772 "smacd\\t%1, %2, %L0"
5773 [(set_attr "type" "imul")
5774 (set_attr "length" "1")])
5776 (define_insn "*umacdi"
5777 [(set (match_operand:DI 0 "register_operand" "=r")
5778 (plus:DI (mult:DI (zero_extend:DI
5779 (match_operand:SI 1 "register_operand" "%r"))
5781 (match_operand:SI 2 "register_operand" "r")))
5782 (match_operand:DI 3 "register_operand" "0")))]
5784 "umacd\\t%1, %2, %L0"
5785 [(set_attr "type" "imul")
5786 (set_attr "length" "1")])
5788 ;;- Boolean instructions
5789 ;; We define DImode `and' so with DImode `not' we can get
5790 ;; DImode `andn'. Other combinations are possible.
5792 (define_expand "anddi3"
5793 [(set (match_operand:DI 0 "register_operand" "")
5794 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5795 (match_operand:DI 2 "arith_double_operand" "")))]
5799 (define_insn "*anddi3_sp32"
5800 [(set (match_operand:DI 0 "register_operand" "=r,b")
5801 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5802 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5807 [(set_attr "type" "ialu,fp")
5808 (set_attr "length" "2,1")])
5810 (define_insn "*anddi3_sp64"
5811 [(set (match_operand:DI 0 "register_operand" "=r,b")
5812 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5813 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5818 [(set_attr "type" "ialu,fp")
5819 (set_attr "length" "1,1")])
5821 (define_insn "andsi3"
5822 [(set (match_operand:SI 0 "register_operand" "=r,d")
5823 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5824 (match_operand:SI 2 "arith_operand" "rI,d")))]
5829 [(set_attr "type" "ialu,fp")
5830 (set_attr "length" "1,1")])
5833 [(set (match_operand:SI 0 "register_operand" "")
5834 (and:SI (match_operand:SI 1 "register_operand" "")
5835 (match_operand:SI 2 "" "")))
5836 (clobber (match_operand:SI 3 "register_operand" ""))]
5837 "GET_CODE (operands[2]) == CONST_INT
5838 && !SMALL_INT32 (operands[2])
5839 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5840 [(set (match_dup 3) (match_dup 4))
5841 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5844 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5847 ;; Split DImode logical operations requiring two instructions.
5849 [(set (match_operand:DI 0 "register_operand" "")
5850 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5851 [(match_operand:DI 2 "register_operand" "")
5852 (match_operand:DI 3 "arith_double_operand" "")]))]
5855 && ((GET_CODE (operands[0]) == REG
5856 && REGNO (operands[0]) < 32)
5857 || (GET_CODE (operands[0]) == SUBREG
5858 && GET_CODE (SUBREG_REG (operands[0])) == REG
5859 && REGNO (SUBREG_REG (operands[0])) < 32))"
5860 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5861 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5864 if (GET_CODE (operands[0]) == SUBREG)
5865 operands[0] = alter_subreg (operands[0]);
5866 operands[4] = gen_highpart (SImode, operands[0]);
5867 operands[5] = gen_lowpart (SImode, operands[0]);
5868 operands[6] = gen_highpart (SImode, operands[2]);
5869 operands[7] = gen_lowpart (SImode, operands[2]);
5870 if (GET_CODE (operands[3]) == CONST_INT)
5872 if (INTVAL (operands[3]) < 0)
5873 operands[8] = constm1_rtx;
5875 operands[8] = const0_rtx;
5878 operands[8] = gen_highpart (SImode, operands[3]);
5879 operands[9] = gen_lowpart (SImode, operands[3]);
5882 (define_insn "*and_not_di_sp32"
5883 [(set (match_operand:DI 0 "register_operand" "=r,b")
5884 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5885 (match_operand:DI 2 "register_operand" "r,b")))]
5889 fandnot1\\t%1, %2, %0"
5890 [(set_attr "type" "ialu,fp")
5891 (set_attr "length" "2,1")])
5894 [(set (match_operand:DI 0 "register_operand" "")
5895 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5896 (match_operand:DI 2 "register_operand" "")))]
5899 && ((GET_CODE (operands[0]) == REG
5900 && REGNO (operands[0]) < 32)
5901 || (GET_CODE (operands[0]) == SUBREG
5902 && GET_CODE (SUBREG_REG (operands[0])) == REG
5903 && REGNO (SUBREG_REG (operands[0])) < 32))"
5904 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5905 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5906 "if (GET_CODE (operands[0]) == SUBREG)
5907 operands[0] = alter_subreg (operands[0]);
5908 operands[3] = gen_highpart (SImode, operands[0]);
5909 operands[4] = gen_highpart (SImode, operands[1]);
5910 operands[5] = gen_highpart (SImode, operands[2]);
5911 operands[6] = gen_lowpart (SImode, operands[0]);
5912 operands[7] = gen_lowpart (SImode, operands[1]);
5913 operands[8] = gen_lowpart (SImode, operands[2]);")
5915 (define_insn "*and_not_di_sp64"
5916 [(set (match_operand:DI 0 "register_operand" "=r,b")
5917 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5918 (match_operand:DI 2 "register_operand" "r,b")))]
5922 fandnot1\\t%1, %2, %0"
5923 [(set_attr "type" "ialu,fp")
5924 (set_attr "length" "1,1")])
5926 (define_insn "*and_not_si"
5927 [(set (match_operand:SI 0 "register_operand" "=r,d")
5928 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5929 (match_operand:SI 2 "register_operand" "r,d")))]
5933 fandnot1s\\t%1, %2, %0"
5934 [(set_attr "type" "ialu,fp")
5935 (set_attr "length" "1,1")])
5937 (define_expand "iordi3"
5938 [(set (match_operand:DI 0 "register_operand" "")
5939 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5940 (match_operand:DI 2 "arith_double_operand" "")))]
5944 (define_insn "*iordi3_sp32"
5945 [(set (match_operand:DI 0 "register_operand" "=r,b")
5946 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5947 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5952 [(set_attr "type" "ialu,fp")
5953 (set_attr "length" "2,1")])
5955 (define_insn "*iordi3_sp64"
5956 [(set (match_operand:DI 0 "register_operand" "=r,b")
5957 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5958 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5963 [(set_attr "type" "ialu,fp")
5964 (set_attr "length" "1,1")])
5966 (define_insn "iorsi3"
5967 [(set (match_operand:SI 0 "register_operand" "=r,d")
5968 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
5969 (match_operand:SI 2 "arith_operand" "rI,d")))]
5974 [(set_attr "type" "ialu,fp")
5975 (set_attr "length" "1,1")])
5978 [(set (match_operand:SI 0 "register_operand" "")
5979 (ior:SI (match_operand:SI 1 "register_operand" "")
5980 (match_operand:SI 2 "" "")))
5981 (clobber (match_operand:SI 3 "register_operand" ""))]
5982 "GET_CODE (operands[2]) == CONST_INT
5983 && !SMALL_INT32 (operands[2])
5984 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5985 [(set (match_dup 3) (match_dup 4))
5986 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5989 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5992 (define_insn "*or_not_di_sp32"
5993 [(set (match_operand:DI 0 "register_operand" "=r,b")
5994 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5995 (match_operand:DI 2 "register_operand" "r,b")))]
5999 fornot1\\t%1, %2, %0"
6000 [(set_attr "type" "ialu,fp")
6001 (set_attr "length" "2,1")])
6004 [(set (match_operand:DI 0 "register_operand" "")
6005 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6006 (match_operand:DI 2 "register_operand" "")))]
6009 && ((GET_CODE (operands[0]) == REG
6010 && REGNO (operands[0]) < 32)
6011 || (GET_CODE (operands[0]) == SUBREG
6012 && GET_CODE (SUBREG_REG (operands[0])) == REG
6013 && REGNO (SUBREG_REG (operands[0])) < 32))"
6014 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6015 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6016 "if (GET_CODE (operands[0]) == SUBREG)
6017 operands[0] = alter_subreg (operands[0]);
6018 operands[3] = gen_highpart (SImode, operands[0]);
6019 operands[4] = gen_highpart (SImode, operands[1]);
6020 operands[5] = gen_highpart (SImode, operands[2]);
6021 operands[6] = gen_lowpart (SImode, operands[0]);
6022 operands[7] = gen_lowpart (SImode, operands[1]);
6023 operands[8] = gen_lowpart (SImode, operands[2]);")
6025 (define_insn "*or_not_di_sp64"
6026 [(set (match_operand:DI 0 "register_operand" "=r,b")
6027 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6028 (match_operand:DI 2 "register_operand" "r,b")))]
6032 fornot1\\t%1, %2, %0"
6033 [(set_attr "type" "ialu,fp")
6034 (set_attr "length" "1,1")])
6036 (define_insn "*or_not_si"
6037 [(set (match_operand:SI 0 "register_operand" "=r,d")
6038 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6039 (match_operand:SI 2 "register_operand" "r,d")))]
6043 fornot1s\\t%1, %2, %0"
6044 [(set_attr "type" "ialu,fp")
6045 (set_attr "length" "1,1")])
6047 (define_expand "xordi3"
6048 [(set (match_operand:DI 0 "register_operand" "")
6049 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6050 (match_operand:DI 2 "arith_double_operand" "")))]
6054 (define_insn "*xordi3_sp32"
6055 [(set (match_operand:DI 0 "register_operand" "=r,b")
6056 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6057 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6062 [(set_attr "length" "2,1")
6063 (set_attr "type" "ialu,fp")])
6065 (define_insn "*xordi3_sp64"
6066 [(set (match_operand:DI 0 "register_operand" "=r,b")
6067 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6068 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6073 [(set_attr "type" "ialu,fp")
6074 (set_attr "length" "1,1")])
6076 (define_insn "*xordi3_sp64_dbl"
6077 [(set (match_operand:DI 0 "register_operand" "=r")
6078 (xor:DI (match_operand:DI 1 "register_operand" "r")
6079 (match_operand:DI 2 "const64_operand" "")))]
6081 && HOST_BITS_PER_WIDE_INT != 64)"
6083 [(set_attr "type" "ialu")
6084 (set_attr "length" "1")])
6086 (define_insn "xorsi3"
6087 [(set (match_operand:SI 0 "register_operand" "=r,d")
6088 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6089 (match_operand:SI 2 "arith_operand" "rI,d")))]
6094 [(set_attr "type" "ialu,fp")
6095 (set_attr "length" "1,1")])
6098 [(set (match_operand:SI 0 "register_operand" "")
6099 (xor:SI (match_operand:SI 1 "register_operand" "")
6100 (match_operand:SI 2 "" "")))
6101 (clobber (match_operand:SI 3 "register_operand" ""))]
6102 "GET_CODE (operands[2]) == CONST_INT
6103 && !SMALL_INT32 (operands[2])
6104 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6105 [(set (match_dup 3) (match_dup 4))
6106 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6109 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6113 [(set (match_operand:SI 0 "register_operand" "")
6114 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6115 (match_operand:SI 2 "" ""))))
6116 (clobber (match_operand:SI 3 "register_operand" ""))]
6117 "GET_CODE (operands[2]) == CONST_INT
6118 && !SMALL_INT32 (operands[2])
6119 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6120 [(set (match_dup 3) (match_dup 4))
6121 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6124 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6127 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6128 ;; Combine now canonicalizes to the rightmost expression.
6129 (define_insn "*xor_not_di_sp32"
6130 [(set (match_operand:DI 0 "register_operand" "=r,b")
6131 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6132 (match_operand:DI 2 "register_operand" "r,b"))))]
6137 [(set_attr "length" "2,1")
6138 (set_attr "type" "ialu,fp")])
6141 [(set (match_operand:DI 0 "register_operand" "")
6142 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6143 (match_operand:DI 2 "register_operand" ""))))]
6146 && ((GET_CODE (operands[0]) == REG
6147 && REGNO (operands[0]) < 32)
6148 || (GET_CODE (operands[0]) == SUBREG
6149 && GET_CODE (SUBREG_REG (operands[0])) == REG
6150 && REGNO (SUBREG_REG (operands[0])) < 32))"
6151 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6152 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6153 "if (GET_CODE (operands[0]) == SUBREG)
6154 operands[0] = alter_subreg (operands[0]);
6155 operands[3] = gen_highpart (SImode, operands[0]);
6156 operands[4] = gen_highpart (SImode, operands[1]);
6157 operands[5] = gen_highpart (SImode, operands[2]);
6158 operands[6] = gen_lowpart (SImode, operands[0]);
6159 operands[7] = gen_lowpart (SImode, operands[1]);
6160 operands[8] = gen_lowpart (SImode, operands[2]);")
6162 (define_insn "*xor_not_di_sp64"
6163 [(set (match_operand:DI 0 "register_operand" "=r,b")
6164 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6165 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6170 [(set_attr "type" "ialu,fp")
6171 (set_attr "length" "1,1")])
6173 (define_insn "*xor_not_si"
6174 [(set (match_operand:SI 0 "register_operand" "=r,d")
6175 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6176 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6180 fxnors\\t%1, %2, %0"
6181 [(set_attr "type" "ialu,fp")
6182 (set_attr "length" "1,1")])
6184 ;; These correspond to the above in the case where we also (or only)
6185 ;; want to set the condition code.
6187 (define_insn "*cmp_cc_arith_op"
6190 (match_operator:SI 2 "cc_arithop"
6191 [(match_operand:SI 0 "arith_operand" "%r")
6192 (match_operand:SI 1 "arith_operand" "rI")])
6195 "%A2cc\\t%0, %1, %%g0"
6196 [(set_attr "type" "compare")
6197 (set_attr "length" "1")])
6199 (define_insn "*cmp_ccx_arith_op"
6202 (match_operator:DI 2 "cc_arithop"
6203 [(match_operand:DI 0 "arith_double_operand" "%r")
6204 (match_operand:DI 1 "arith_double_operand" "rHI")])
6207 "%A2cc\\t%0, %1, %%g0"
6208 [(set_attr "type" "compare")
6209 (set_attr "length" "1")])
6211 (define_insn "*cmp_cc_arith_op_set"
6214 (match_operator:SI 3 "cc_arithop"
6215 [(match_operand:SI 1 "arith_operand" "%r")
6216 (match_operand:SI 2 "arith_operand" "rI")])
6218 (set (match_operand:SI 0 "register_operand" "=r")
6221 "%A3cc\\t%1, %2, %0"
6222 [(set_attr "type" "compare")
6223 (set_attr "length" "1")])
6225 (define_insn "*cmp_ccx_arith_op_set"
6228 (match_operator:DI 3 "cc_arithop"
6229 [(match_operand:DI 1 "arith_double_operand" "%r")
6230 (match_operand:DI 2 "arith_double_operand" "rHI")])
6232 (set (match_operand:DI 0 "register_operand" "=r")
6235 "%A3cc\\t%1, %2, %0"
6236 [(set_attr "type" "compare")
6237 (set_attr "length" "1")])
6239 (define_insn "*cmp_cc_xor_not"
6242 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6243 (match_operand:SI 1 "arith_operand" "rI")))
6246 "xnorcc\\t%r0, %1, %%g0"
6247 [(set_attr "type" "compare")
6248 (set_attr "length" "1")])
6250 (define_insn "*cmp_ccx_xor_not"
6253 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6254 (match_operand:DI 1 "arith_double_operand" "rHI")))
6257 "xnorcc\\t%r0, %1, %%g0"
6258 [(set_attr "type" "compare")
6259 (set_attr "length" "1")])
6261 (define_insn "*cmp_cc_xor_not_set"
6264 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6265 (match_operand:SI 2 "arith_operand" "rI")))
6267 (set (match_operand:SI 0 "register_operand" "=r")
6268 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6270 "xnorcc\\t%r1, %2, %0"
6271 [(set_attr "type" "compare")
6272 (set_attr "length" "1")])
6274 (define_insn "*cmp_ccx_xor_not_set"
6277 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6278 (match_operand:DI 2 "arith_double_operand" "rHI")))
6280 (set (match_operand:DI 0 "register_operand" "=r")
6281 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6283 "xnorcc\\t%r1, %2, %0"
6284 [(set_attr "type" "compare")
6285 (set_attr "length" "1")])
6287 (define_insn "*cmp_cc_arith_op_not"
6290 (match_operator:SI 2 "cc_arithopn"
6291 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6292 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6295 "%B2cc\\t%r1, %0, %%g0"
6296 [(set_attr "type" "compare")
6297 (set_attr "length" "1")])
6299 (define_insn "*cmp_ccx_arith_op_not"
6302 (match_operator:DI 2 "cc_arithopn"
6303 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6304 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6307 "%B2cc\\t%r1, %0, %%g0"
6308 [(set_attr "type" "compare")
6309 (set_attr "length" "1")])
6311 (define_insn "*cmp_cc_arith_op_not_set"
6314 (match_operator:SI 3 "cc_arithopn"
6315 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6316 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6318 (set (match_operand:SI 0 "register_operand" "=r")
6321 "%B3cc\\t%r2, %1, %0"
6322 [(set_attr "type" "compare")
6323 (set_attr "length" "1")])
6325 (define_insn "*cmp_ccx_arith_op_not_set"
6328 (match_operator:DI 3 "cc_arithopn"
6329 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6330 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6332 (set (match_operand:DI 0 "register_operand" "=r")
6335 "%B3cc\\t%r2, %1, %0"
6336 [(set_attr "type" "compare")
6337 (set_attr "length" "1")])
6339 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6340 ;; does not know how to make it work for constants.
6342 (define_expand "negdi2"
6343 [(set (match_operand:DI 0 "register_operand" "=r")
6344 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6348 if (! TARGET_ARCH64)
6350 emit_insn (gen_rtx_PARALLEL
6353 gen_rtx_SET (VOIDmode, operand0,
6354 gen_rtx_NEG (DImode, operand1)),
6355 gen_rtx_CLOBBER (VOIDmode,
6356 gen_rtx_REG (CCmode,
6362 (define_insn "*negdi2_sp32"
6363 [(set (match_operand:DI 0 "register_operand" "=r")
6364 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6365 (clobber (reg:CC 100))]
6367 && ! TARGET_LIVE_G0"
6369 [(set_attr "type" "unary")
6370 (set_attr "length" "2")])
6373 [(set (match_operand:DI 0 "register_operand" "")
6374 (neg:DI (match_operand:DI 1 "register_operand" "")))
6375 (clobber (reg:CC 100))]
6378 && reload_completed"
6379 [(parallel [(set (reg:CC_NOOV 100)
6380 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6382 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6383 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6384 (ltu:SI (reg:CC 100) (const_int 0))))]
6385 "operands[2] = gen_highpart (SImode, operands[0]);
6386 operands[3] = gen_highpart (SImode, operands[1]);
6387 operands[4] = gen_lowpart (SImode, operands[0]);
6388 operands[5] = gen_lowpart (SImode, operands[1]);")
6390 (define_insn "*negdi2_sp64"
6391 [(set (match_operand:DI 0 "register_operand" "=r")
6392 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6394 "sub\\t%%g0, %1, %0"
6395 [(set_attr "type" "unary")
6396 (set_attr "length" "1")])
6398 (define_expand "negsi2"
6399 [(set (match_operand:SI 0 "register_operand" "")
6400 (neg:SI (match_operand:SI 1 "arith_operand" "")))]
6406 rtx zero_reg = gen_reg_rtx (SImode);
6408 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6409 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6410 gen_rtx_MINUS (SImode, zero_reg,
6416 (define_insn "*negsi2_not_liveg0"
6417 [(set (match_operand:SI 0 "register_operand" "=r")
6418 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6420 "sub\\t%%g0, %1, %0"
6421 [(set_attr "type" "unary")
6422 (set_attr "length" "1")])
6424 (define_insn "*cmp_cc_neg"
6425 [(set (reg:CC_NOOV 100)
6426 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6429 "subcc\\t%%g0, %0, %%g0"
6430 [(set_attr "type" "compare")
6431 (set_attr "length" "1")])
6433 (define_insn "*cmp_ccx_neg"
6434 [(set (reg:CCX_NOOV 100)
6435 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6438 "subcc\\t%%g0, %0, %%g0"
6439 [(set_attr "type" "compare")
6440 (set_attr "length" "1")])
6442 (define_insn "*cmp_cc_set_neg"
6443 [(set (reg:CC_NOOV 100)
6444 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6446 (set (match_operand:SI 0 "register_operand" "=r")
6447 (neg:SI (match_dup 1)))]
6449 "subcc\\t%%g0, %1, %0"
6450 [(set_attr "type" "compare")
6451 (set_attr "length" "1")])
6453 (define_insn "*cmp_ccx_set_neg"
6454 [(set (reg:CCX_NOOV 100)
6455 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6457 (set (match_operand:DI 0 "register_operand" "=r")
6458 (neg:DI (match_dup 1)))]
6460 "subcc\\t%%g0, %1, %0"
6461 [(set_attr "type" "compare")
6462 (set_attr "length" "1")])
6464 ;; We cannot use the "not" pseudo insn because the Sun assembler
6465 ;; does not know how to make it work for constants.
6466 (define_expand "one_cmpldi2"
6467 [(set (match_operand:DI 0 "register_operand" "")
6468 (not:DI (match_operand:DI 1 "register_operand" "")))]
6472 (define_insn "*one_cmpldi2_sp32"
6473 [(set (match_operand:DI 0 "register_operand" "=r,b")
6474 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6479 [(set_attr "type" "unary,fp")
6480 (set_attr "length" "2,1")])
6483 [(set (match_operand:DI 0 "register_operand" "")
6484 (not:DI (match_operand:DI 1 "register_operand" "")))]
6487 && ((GET_CODE (operands[0]) == REG
6488 && REGNO (operands[0]) < 32)
6489 || (GET_CODE (operands[0]) == SUBREG
6490 && GET_CODE (SUBREG_REG (operands[0])) == REG
6491 && REGNO (SUBREG_REG (operands[0])) < 32))"
6492 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6493 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6494 "if (GET_CODE (operands[0]) == SUBREG)
6495 operands[0] = alter_subreg (operands[0]);
6496 operands[2] = gen_highpart (SImode, operands[0]);
6497 operands[3] = gen_highpart (SImode, operands[1]);
6498 operands[4] = gen_lowpart (SImode, operands[0]);
6499 operands[5] = gen_lowpart (SImode, operands[1]);")
6501 (define_insn "*one_cmpldi2_sp64"
6502 [(set (match_operand:DI 0 "register_operand" "=r,b")
6503 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6508 [(set_attr "type" "unary,fp")
6509 (set_attr "length" "1")])
6511 (define_expand "one_cmplsi2"
6512 [(set (match_operand:SI 0 "register_operand" "")
6513 (not:SI (match_operand:SI 1 "arith_operand" "")))]
6518 && GET_CODE (operands[1]) == CONST_INT)
6520 rtx zero_reg = gen_reg_rtx (SImode);
6522 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6523 emit_insn (gen_rtx_SET (VOIDmode,
6525 gen_rtx_NOT (SImode,
6526 gen_rtx_XOR (SImode,
6533 (define_insn "*one_cmplsi2_not_liveg0"
6534 [(set (match_operand:SI 0 "register_operand" "=r,d")
6535 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6540 [(set_attr "type" "unary,fp")
6541 (set_attr "length" "1,1")])
6543 (define_insn "*one_cmplsi2_liveg0"
6544 [(set (match_operand:SI 0 "register_operand" "=r,d")
6545 (not:SI (match_operand:SI 1 "arith_operand" "r,d")))]
6550 [(set_attr "type" "unary,fp")
6551 (set_attr "length" "1,1")])
6553 (define_insn "*cmp_cc_not"
6555 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6558 "xnorcc\\t%%g0, %0, %%g0"
6559 [(set_attr "type" "compare")
6560 (set_attr "length" "1")])
6562 (define_insn "*cmp_ccx_not"
6564 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6567 "xnorcc\\t%%g0, %0, %%g0"
6568 [(set_attr "type" "compare")
6569 (set_attr "length" "1")])
6571 (define_insn "*cmp_cc_set_not"
6573 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6575 (set (match_operand:SI 0 "register_operand" "=r")
6576 (not:SI (match_dup 1)))]
6578 "xnorcc\\t%%g0, %1, %0"
6579 [(set_attr "type" "compare")
6580 (set_attr "length" "1")])
6582 (define_insn "*cmp_ccx_set_not"
6584 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6586 (set (match_operand:DI 0 "register_operand" "=r")
6587 (not:DI (match_dup 1)))]
6589 "xnorcc\\t%%g0, %1, %0"
6590 [(set_attr "type" "compare")
6591 (set_attr "length" "1")])
6593 ;; Floating point arithmetic instructions.
6595 (define_insn "addtf3"
6596 [(set (match_operand:TF 0 "register_operand" "=e")
6597 (plus:TF (match_operand:TF 1 "register_operand" "e")
6598 (match_operand:TF 2 "register_operand" "e")))]
6599 "TARGET_FPU && TARGET_HARD_QUAD"
6600 "faddq\\t%1, %2, %0"
6601 [(set_attr "type" "fp")
6602 (set_attr "length" "1")])
6604 (define_insn "adddf3"
6605 [(set (match_operand:DF 0 "register_operand" "=e")
6606 (plus:DF (match_operand:DF 1 "register_operand" "e")
6607 (match_operand:DF 2 "register_operand" "e")))]
6609 "faddd\\t%1, %2, %0"
6610 [(set_attr "type" "fp")
6611 (set_attr "length" "1")])
6613 (define_insn "addsf3"
6614 [(set (match_operand:SF 0 "register_operand" "=f")
6615 (plus:SF (match_operand:SF 1 "register_operand" "f")
6616 (match_operand:SF 2 "register_operand" "f")))]
6618 "fadds\\t%1, %2, %0"
6619 [(set_attr "type" "fp")
6620 (set_attr "length" "1")])
6622 (define_insn "subtf3"
6623 [(set (match_operand:TF 0 "register_operand" "=e")
6624 (minus:TF (match_operand:TF 1 "register_operand" "e")
6625 (match_operand:TF 2 "register_operand" "e")))]
6626 "TARGET_FPU && TARGET_HARD_QUAD"
6627 "fsubq\\t%1, %2, %0"
6628 [(set_attr "type" "fp")
6629 (set_attr "length" "1")])
6631 (define_insn "subdf3"
6632 [(set (match_operand:DF 0 "register_operand" "=e")
6633 (minus:DF (match_operand:DF 1 "register_operand" "e")
6634 (match_operand:DF 2 "register_operand" "e")))]
6636 "fsubd\\t%1, %2, %0"
6637 [(set_attr "type" "fp")
6638 (set_attr "length" "1")])
6640 (define_insn "subsf3"
6641 [(set (match_operand:SF 0 "register_operand" "=f")
6642 (minus:SF (match_operand:SF 1 "register_operand" "f")
6643 (match_operand:SF 2 "register_operand" "f")))]
6645 "fsubs\\t%1, %2, %0"
6646 [(set_attr "type" "fp")
6647 (set_attr "length" "1")])
6649 (define_insn "multf3"
6650 [(set (match_operand:TF 0 "register_operand" "=e")
6651 (mult:TF (match_operand:TF 1 "register_operand" "e")
6652 (match_operand:TF 2 "register_operand" "e")))]
6653 "TARGET_FPU && TARGET_HARD_QUAD"
6654 "fmulq\\t%1, %2, %0"
6655 [(set_attr "type" "fpmul")
6656 (set_attr "length" "1")])
6658 (define_insn "muldf3"
6659 [(set (match_operand:DF 0 "register_operand" "=e")
6660 (mult:DF (match_operand:DF 1 "register_operand" "e")
6661 (match_operand:DF 2 "register_operand" "e")))]
6663 "fmuld\\t%1, %2, %0"
6664 [(set_attr "type" "fpmul")
6665 (set_attr "length" "1")])
6667 (define_insn "mulsf3"
6668 [(set (match_operand:SF 0 "register_operand" "=f")
6669 (mult:SF (match_operand:SF 1 "register_operand" "f")
6670 (match_operand:SF 2 "register_operand" "f")))]
6672 "fmuls\\t%1, %2, %0"
6673 [(set_attr "type" "fpmul")
6674 (set_attr "length" "1")])
6676 (define_insn "*muldf3_extend"
6677 [(set (match_operand:DF 0 "register_operand" "=e")
6678 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6679 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6680 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6681 "fsmuld\\t%1, %2, %0"
6682 [(set_attr "type" "fpmul")
6683 (set_attr "length" "1")])
6685 (define_insn "*multf3_extend"
6686 [(set (match_operand:TF 0 "register_operand" "=e")
6687 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6688 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6689 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6690 "fdmulq\\t%1, %2, %0"
6691 [(set_attr "type" "fpmul")
6692 (set_attr "length" "1")])
6694 ;; don't have timing for quad-prec. divide.
6695 (define_insn "divtf3"
6696 [(set (match_operand:TF 0 "register_operand" "=e")
6697 (div:TF (match_operand:TF 1 "register_operand" "e")
6698 (match_operand:TF 2 "register_operand" "e")))]
6699 "TARGET_FPU && TARGET_HARD_QUAD"
6700 "fdivq\\t%1, %2, %0"
6701 [(set_attr "type" "fpdivd")
6702 (set_attr "length" "1")])
6704 (define_insn "divdf3"
6705 [(set (match_operand:DF 0 "register_operand" "=e")
6706 (div:DF (match_operand:DF 1 "register_operand" "e")
6707 (match_operand:DF 2 "register_operand" "e")))]
6709 "fdivd\\t%1, %2, %0"
6710 [(set_attr "type" "fpdivd")
6711 (set_attr "length" "1")])
6713 (define_insn "divsf3"
6714 [(set (match_operand:SF 0 "register_operand" "=f")
6715 (div:SF (match_operand:SF 1 "register_operand" "f")
6716 (match_operand:SF 2 "register_operand" "f")))]
6718 "fdivs\\t%1, %2, %0"
6719 [(set_attr "type" "fpdivs")
6720 (set_attr "length" "1")])
6722 (define_expand "negtf2"
6723 [(set (match_operand:TF 0 "register_operand" "=e,e")
6724 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6728 (define_insn "*negtf2_notv9"
6729 [(set (match_operand:TF 0 "register_operand" "=e,e")
6730 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6731 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6737 [(set_attr "type" "fpmove")
6738 (set_attr "length" "1,2")])
6741 [(set (match_operand:TF 0 "register_operand" "")
6742 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6746 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6747 [(set (match_dup 2) (neg:SF (match_dup 3)))
6748 (set (match_dup 4) (match_dup 5))
6749 (set (match_dup 6) (match_dup 7))]
6750 "if (GET_CODE (operands[0]) == SUBREG)
6751 operands[0] = alter_subreg (operands[0]);
6752 if (GET_CODE (operands[1]) == SUBREG)
6753 operands[1] = alter_subreg (operands[1]);
6754 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6755 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6756 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6757 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6758 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6759 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6761 (define_insn "*negtf2_v9"
6762 [(set (match_operand:TF 0 "register_operand" "=e,e")
6763 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6764 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6765 "TARGET_FPU && TARGET_V9"
6769 [(set_attr "type" "fpmove")
6770 (set_attr "length" "1,2")])
6773 [(set (match_operand:TF 0 "register_operand" "")
6774 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6778 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6779 [(set (match_dup 2) (neg:DF (match_dup 3)))
6780 (set (match_dup 4) (match_dup 5))]
6781 "if (GET_CODE (operands[0]) == SUBREG)
6782 operands[0] = alter_subreg (operands[0]);
6783 if (GET_CODE (operands[1]) == SUBREG)
6784 operands[1] = alter_subreg (operands[1]);
6785 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6786 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6787 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6788 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6790 (define_expand "negdf2"
6791 [(set (match_operand:DF 0 "register_operand" "")
6792 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6796 (define_insn "*negdf2_notv9"
6797 [(set (match_operand:DF 0 "register_operand" "=e,e")
6798 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6799 "TARGET_FPU && ! TARGET_V9"
6803 [(set_attr "type" "fpmove")
6804 (set_attr "length" "1,2")])
6807 [(set (match_operand:DF 0 "register_operand" "")
6808 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6812 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6813 [(set (match_dup 2) (neg:SF (match_dup 3)))
6814 (set (match_dup 4) (match_dup 5))]
6815 "if (GET_CODE (operands[0]) == SUBREG)
6816 operands[0] = alter_subreg (operands[0]);
6817 if (GET_CODE (operands[1]) == SUBREG)
6818 operands[1] = alter_subreg (operands[1]);
6819 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6820 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6821 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6822 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6824 (define_insn "*negdf2_v9"
6825 [(set (match_operand:DF 0 "register_operand" "=e")
6826 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6827 "TARGET_FPU && TARGET_V9"
6829 [(set_attr "type" "fpmove")
6830 (set_attr "length" "1")])
6832 (define_insn "negsf2"
6833 [(set (match_operand:SF 0 "register_operand" "=f")
6834 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6837 [(set_attr "type" "fpmove")
6838 (set_attr "length" "1")])
6840 (define_expand "abstf2"
6841 [(set (match_operand:TF 0 "register_operand" "")
6842 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6846 (define_insn "*abstf2_notv9"
6847 [(set (match_operand:TF 0 "register_operand" "=e,e")
6848 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6849 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6850 "TARGET_FPU && ! TARGET_V9"
6854 [(set_attr "type" "fpmove")
6855 (set_attr "length" "1,2")])
6858 [(set (match_operand:TF 0 "register_operand" "=e,e")
6859 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6863 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6864 [(set (match_dup 2) (abs:SF (match_dup 3)))
6865 (set (match_dup 4) (match_dup 5))
6866 (set (match_dup 6) (match_dup 7))]
6867 "if (GET_CODE (operands[0]) == SUBREG)
6868 operands[0] = alter_subreg (operands[0]);
6869 if (GET_CODE (operands[1]) == SUBREG)
6870 operands[1] = alter_subreg (operands[1]);
6871 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6872 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6873 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6874 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6875 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6876 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6878 (define_insn "*abstf2_hq_v9"
6879 [(set (match_operand:TF 0 "register_operand" "=e,e")
6880 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6881 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6885 [(set_attr "type" "fpmove")
6886 (set_attr "length" "1")])
6888 (define_insn "*abstf2_v9"
6889 [(set (match_operand:TF 0 "register_operand" "=e,e")
6890 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6891 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6895 [(set_attr "type" "fpmove")
6896 (set_attr "length" "1,2")])
6899 [(set (match_operand:TF 0 "register_operand" "=e,e")
6900 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6904 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6905 [(set (match_dup 2) (abs:DF (match_dup 3)))
6906 (set (match_dup 4) (match_dup 5))]
6907 "if (GET_CODE (operands[0]) == SUBREG)
6908 operands[0] = alter_subreg (operands[0]);
6909 if (GET_CODE (operands[1]) == SUBREG)
6910 operands[1] = alter_subreg (operands[1]);
6911 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6912 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6913 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6914 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6916 (define_expand "absdf2"
6917 [(set (match_operand:DF 0 "register_operand" "")
6918 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6922 (define_insn "*absdf2_notv9"
6923 [(set (match_operand:DF 0 "register_operand" "=e,e")
6924 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6925 "TARGET_FPU && ! TARGET_V9"
6929 [(set_attr "type" "fpmove")
6930 (set_attr "length" "1,2")])
6933 [(set (match_operand:DF 0 "register_operand" "=e,e")
6934 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6938 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6939 [(set (match_dup 2) (abs:SF (match_dup 3)))
6940 (set (match_dup 4) (match_dup 5))]
6941 "if (GET_CODE (operands[0]) == SUBREG)
6942 operands[0] = alter_subreg (operands[0]);
6943 if (GET_CODE (operands[1]) == SUBREG)
6944 operands[1] = alter_subreg (operands[1]);
6945 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6946 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6947 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6948 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6950 (define_insn "*absdf2_v9"
6951 [(set (match_operand:DF 0 "register_operand" "=e")
6952 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6953 "TARGET_FPU && TARGET_V9"
6955 [(set_attr "type" "fpmove")
6956 (set_attr "length" "1")])
6958 (define_insn "abssf2"
6959 [(set (match_operand:SF 0 "register_operand" "=f")
6960 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6963 [(set_attr "type" "fpmove")
6964 (set_attr "length" "1")])
6966 (define_insn "sqrttf2"
6967 [(set (match_operand:TF 0 "register_operand" "=e")
6968 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6969 "TARGET_FPU && TARGET_HARD_QUAD"
6971 [(set_attr "type" "fpsqrtd")
6972 (set_attr "length" "1")])
6974 (define_insn "sqrtdf2"
6975 [(set (match_operand:DF 0 "register_operand" "=e")
6976 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6979 [(set_attr "type" "fpsqrtd")
6980 (set_attr "length" "1")])
6982 (define_insn "sqrtsf2"
6983 [(set (match_operand:SF 0 "register_operand" "=f")
6984 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6987 [(set_attr "type" "fpsqrts")
6988 (set_attr "length" "1")])
6990 ;;- arithmetic shift instructions
6992 (define_insn "ashlsi3"
6993 [(set (match_operand:SI 0 "register_operand" "=r")
6994 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6995 (match_operand:SI 2 "arith_operand" "rI")))]
6999 if (GET_CODE (operands[2]) == CONST_INT
7000 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7001 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7003 return \"sll\\t%1, %2, %0\";
7005 [(set_attr "type" "shift")
7006 (set_attr "length" "1")])
7008 ;; We special case multiplication by two, as add can be done
7009 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7010 (define_insn "*ashlsi3_const1"
7011 [(set (match_operand:SI 0 "register_operand" "=r")
7012 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7016 [(set_attr "type" "binary")
7017 (set_attr "length" "1")])
7019 (define_expand "ashldi3"
7020 [(set (match_operand:DI 0 "register_operand" "=r")
7021 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7022 (match_operand:SI 2 "arith_operand" "rI")))]
7023 "TARGET_ARCH64 || TARGET_V8PLUS"
7026 if (! TARGET_ARCH64)
7028 if (GET_CODE (operands[2]) == CONST_INT)
7030 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7035 ;; We special case multiplication by two, as add can be done
7036 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7037 (define_insn "*ashldi3_const1"
7038 [(set (match_operand:DI 0 "register_operand" "=r")
7039 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7043 [(set_attr "type" "binary")
7044 (set_attr "length" "1")])
7046 (define_insn "*ashldi3_sp64"
7047 [(set (match_operand:DI 0 "register_operand" "=r")
7048 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7049 (match_operand:SI 2 "arith_operand" "rI")))]
7053 if (GET_CODE (operands[2]) == CONST_INT
7054 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7055 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7057 return \"sllx\\t%1, %2, %0\";
7059 [(set_attr "type" "shift")
7060 (set_attr "length" "1")])
7063 (define_insn "ashldi3_v8plus"
7064 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7065 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7066 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7067 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7069 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7070 [(set_attr "length" "5,5,6")])
7072 ;; Optimize (1LL<<x)-1
7073 ;; XXX this also needs to be fixed to handle equal subregs
7074 ;; XXX first before we could re-enable it.
7076 [(set (match_operand:DI 0 "register_operand" "=h")
7077 (plus:DI (ashift:DI (const_int 1)
7078 (match_operand:SI 2 "arith_operand" "rI"))
7080 "0 && TARGET_V8PLUS"
7083 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
7084 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7085 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7087 [(set_attr "length" "4")])
7089 (define_insn "*cmp_cc_ashift_1"
7090 [(set (reg:CC_NOOV 100)
7091 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7095 "addcc\\t%0, %0, %%g0"
7096 [(set_attr "type" "compare")
7097 (set_attr "length" "1")])
7099 (define_insn "*cmp_cc_set_ashift_1"
7100 [(set (reg:CC_NOOV 100)
7101 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7104 (set (match_operand:SI 0 "register_operand" "=r")
7105 (ashift:SI (match_dup 1) (const_int 1)))]
7107 "addcc\\t%1, %1, %0"
7108 [(set_attr "type" "compare")
7109 (set_attr "length" "1")])
7111 (define_insn "ashrsi3"
7112 [(set (match_operand:SI 0 "register_operand" "=r")
7113 (ashiftrt:SI (match_operand:SI 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]) > 31)
7120 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7122 return \"sra\\t%1, %2, %0\";
7124 [(set_attr "type" "shift")
7125 (set_attr "length" "1")])
7127 (define_insn "*ashrsi3_extend"
7128 [(set (match_operand:DI 0 "register_operand" "=r")
7129 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7130 (match_operand:SI 2 "arith_operand" "r"))))]
7133 [(set_attr "type" "shift")
7134 (set_attr "length" "1")])
7136 ;; This handles the case as above, but with constant shift instead of
7137 ;; register. Combiner "simplifies" it for us a little bit though.
7138 (define_insn "*ashrsi3_extend2"
7139 [(set (match_operand:DI 0 "register_operand" "=r")
7140 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7142 (match_operand:SI 2 "small_int_or_double" "n")))]
7144 && ((GET_CODE (operands[2]) == CONST_INT
7145 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7146 || (GET_CODE (operands[2]) == CONST_DOUBLE
7147 && !CONST_DOUBLE_HIGH (operands[2])
7148 && CONST_DOUBLE_LOW (operands[2]) >= 32
7149 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7152 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7154 return \"sra\\t%1, %2, %0\";
7156 [(set_attr "type" "shift")
7157 (set_attr "length" "1")])
7159 (define_expand "ashrdi3"
7160 [(set (match_operand:DI 0 "register_operand" "=r")
7161 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7162 (match_operand:SI 2 "arith_operand" "rI")))]
7163 "TARGET_ARCH64 || TARGET_V8PLUS"
7166 if (! TARGET_ARCH64)
7168 if (GET_CODE (operands[2]) == CONST_INT)
7169 FAIL; /* prefer generic code in this case */
7170 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7176 [(set (match_operand:DI 0 "register_operand" "=r")
7177 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7178 (match_operand:SI 2 "arith_operand" "rI")))]
7182 if (GET_CODE (operands[2]) == CONST_INT
7183 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7184 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7186 return \"srax\\t%1, %2, %0\";
7188 [(set_attr "type" "shift")
7189 (set_attr "length" "1")])
7192 (define_insn "ashrdi3_v8plus"
7193 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7194 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7195 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7196 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7198 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7199 [(set_attr "length" "5,5,6")])
7201 (define_insn "lshrsi3"
7202 [(set (match_operand:SI 0 "register_operand" "=r")
7203 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7204 (match_operand:SI 2 "arith_operand" "rI")))]
7208 if (GET_CODE (operands[2]) == CONST_INT
7209 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7210 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7212 return \"srl\\t%1, %2, %0\";
7214 [(set_attr "type" "shift")
7215 (set_attr "length" "1")])
7217 ;; This handles the case where
7218 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7219 ;; but combiner "simplifies" it for us.
7220 (define_insn "*lshrsi3_extend"
7221 [(set (match_operand:DI 0 "register_operand" "=r")
7222 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7223 (match_operand:SI 2 "arith_operand" "r")) 0)
7224 (match_operand 3 "" "")))]
7226 && ((GET_CODE (operands[3]) == CONST_DOUBLE
7227 && CONST_DOUBLE_HIGH (operands[3]) == 0
7228 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7229 #if HOST_BITS_PER_WIDE_INT >= 64
7230 || (GET_CODE (operands[3]) == CONST_INT
7231 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
7235 [(set_attr "type" "shift")
7236 (set_attr "length" "1")])
7238 ;; This handles the case where
7239 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7240 ;; but combiner "simplifies" it for us.
7241 (define_insn "*lshrsi3_extend2"
7242 [(set (match_operand:DI 0 "register_operand" "=r")
7243 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7244 (match_operand 2 "small_int_or_double" "n")
7247 && ((GET_CODE (operands[2]) == CONST_INT
7248 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7249 || (GET_CODE (operands[2]) == CONST_DOUBLE
7250 && CONST_DOUBLE_HIGH (operands[2]) == 0
7251 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7254 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7256 return \"srl\\t%1, %2, %0\";
7258 [(set_attr "type" "shift")
7259 (set_attr "length" "1")])
7261 (define_expand "lshrdi3"
7262 [(set (match_operand:DI 0 "register_operand" "=r")
7263 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7264 (match_operand:SI 2 "arith_operand" "rI")))]
7265 "TARGET_ARCH64 || TARGET_V8PLUS"
7268 if (! TARGET_ARCH64)
7270 if (GET_CODE (operands[2]) == CONST_INT)
7272 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7278 [(set (match_operand:DI 0 "register_operand" "=r")
7279 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7280 (match_operand:SI 2 "arith_operand" "rI")))]
7284 if (GET_CODE (operands[2]) == CONST_INT
7285 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7286 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7288 return \"srlx\\t%1, %2, %0\";
7290 [(set_attr "type" "shift")
7291 (set_attr "length" "1")])
7294 (define_insn "lshrdi3_v8plus"
7295 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7296 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7297 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7298 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7300 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7301 [(set_attr "length" "5,5,6")])
7304 [(set (match_operand:SI 0 "register_operand" "=r")
7305 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7307 (match_operand:SI 2 "small_int_or_double" "n")))]
7309 && ((GET_CODE (operands[2]) == CONST_INT
7310 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7311 || (GET_CODE (operands[2]) == CONST_DOUBLE
7312 && !CONST_DOUBLE_HIGH (operands[2])
7313 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7316 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7318 return \"srax\\t%1, %2, %0\";
7320 [(set_attr "type" "shift")
7321 (set_attr "length" "1")])
7324 [(set (match_operand:SI 0 "register_operand" "=r")
7325 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7327 (match_operand:SI 2 "small_int_or_double" "n")))]
7329 && ((GET_CODE (operands[2]) == CONST_INT
7330 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7331 || (GET_CODE (operands[2]) == CONST_DOUBLE
7332 && !CONST_DOUBLE_HIGH (operands[2])
7333 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7336 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7338 return \"srlx\\t%1, %2, %0\";
7340 [(set_attr "type" "shift")
7341 (set_attr "length" "1")])
7344 [(set (match_operand:SI 0 "register_operand" "=r")
7345 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7346 (match_operand:SI 2 "small_int_or_double" "n")) 0)
7347 (match_operand:SI 3 "small_int_or_double" "n")))]
7349 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7350 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7351 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7352 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7355 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7357 return \"srax\\t%1, %2, %0\";
7359 [(set_attr "type" "shift")
7360 (set_attr "length" "1")])
7363 [(set (match_operand:SI 0 "register_operand" "=r")
7364 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7365 (match_operand:SI 2 "small_int_or_double" "n")) 0)
7366 (match_operand:SI 3 "small_int_or_double" "n")))]
7368 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7369 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7370 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7371 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7374 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7376 return \"srlx\\t%1, %2, %0\";
7378 [(set_attr "type" "shift")
7379 (set_attr "length" "1")])
7381 ;; Unconditional and other jump instructions
7382 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7383 ;; following insn is never executed. This saves us a nop. Dbx does not
7384 ;; handle such branches though, so we only use them when optimizing.
7386 [(set (pc) (label_ref (match_operand 0 "" "")))]
7390 /* TurboSparc is reported to have problems with
7393 i.e. an empty loop with the annul bit set. The workaround is to use
7397 if (! TARGET_V9 && flag_delayed_branch
7398 && (insn_addresses[INSN_UID (operands[0])]
7399 == insn_addresses[INSN_UID (insn)]))
7400 return \"b\\t%l0%#\";
7402 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7404 [(set_attr "type" "uncond_branch")])
7406 (define_expand "tablejump"
7407 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7408 (use (label_ref (match_operand 1 "" "")))])]
7412 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7415 /* In pic mode, our address differences are against the base of the
7416 table. Add that base value back in; CSE ought to be able to combine
7417 the two address loads. */
7421 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7423 if (CASE_VECTOR_MODE != Pmode)
7424 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7425 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7426 operands[0] = memory_address (Pmode, tmp);
7430 (define_insn "*tablejump_sp32"
7431 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7432 (use (label_ref (match_operand 1 "" "")))]
7435 [(set_attr "type" "uncond_branch")])
7437 (define_insn "*tablejump_sp64"
7438 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7439 (use (label_ref (match_operand 1 "" "")))]
7442 [(set_attr "type" "uncond_branch")])
7444 ;; This pattern recognizes the "instruction" that appears in
7445 ;; a function call that wants a structure value,
7446 ;; to inform the called function if compiled with Sun CC.
7447 ;(define_insn "*unimp_insn"
7448 ; [(match_operand:SI 0 "immediate_operand" "")]
7449 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7451 ; [(set_attr "type" "marker")])
7453 ;;- jump to subroutine
7454 (define_expand "call"
7455 ;; Note that this expression is not used for generating RTL.
7456 ;; All the RTL is generated explicitly below.
7457 [(call (match_operand 0 "call_operand" "")
7458 (match_operand 3 "" "i"))]
7459 ;; operands[2] is next_arg_register
7460 ;; operands[3] is struct_value_size_rtx.
7464 rtx fn_rtx, nregs_rtx;
7466 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7469 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7471 /* This is really a PIC sequence. We want to represent
7472 it as a funny jump so its delay slots can be filled.
7474 ??? But if this really *is* a CALL, will not it clobber the
7475 call-clobbered registers? We lose this if it is a JUMP_INSN.
7476 Why cannot we have delay slots filled if it were a CALL? */
7478 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7483 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7485 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7491 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7492 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7496 fn_rtx = operands[0];
7498 /* Count the number of parameter registers being used by this call.
7499 if that argument is NULL, it means we are using them all, which
7500 means 6 on the sparc. */
7503 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7505 nregs_rtx = GEN_INT (6);
7507 nregs_rtx = const0_rtx;
7510 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7514 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7516 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7521 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7522 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7526 /* If this call wants a structure value,
7527 emit an unimp insn to let the called function know about this. */
7528 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7530 rtx insn = emit_insn (operands[3]);
7531 SCHED_GROUP_P (insn) = 1;
7538 ;; We can't use the same pattern for these two insns, because then registers
7539 ;; in the address may not be properly reloaded.
7541 (define_insn "*call_address_sp32"
7542 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7543 (match_operand 1 "" ""))
7544 (clobber (reg:SI 15))]
7545 ;;- Do not use operand 1 for most machines.
7548 [(set_attr "type" "call")])
7550 (define_insn "*call_symbolic_sp32"
7551 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7552 (match_operand 1 "" ""))
7553 (clobber (reg:SI 15))]
7554 ;;- Do not use operand 1 for most machines.
7557 [(set_attr "type" "call")])
7559 (define_insn "*call_address_sp64"
7560 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
7561 (match_operand 1 "" ""))
7562 (clobber (reg:DI 15))]
7563 ;;- Do not use operand 1 for most machines.
7566 [(set_attr "type" "call")])
7568 (define_insn "*call_symbolic_sp64"
7569 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
7570 (match_operand 1 "" ""))
7571 (clobber (reg:DI 15))]
7572 ;;- Do not use operand 1 for most machines.
7575 [(set_attr "type" "call")])
7577 ;; This is a call that wants a structure value.
7578 ;; There is no such critter for v9 (??? we may need one anyway).
7579 (define_insn "*call_address_struct_value_sp32"
7580 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7581 (match_operand 1 "" ""))
7582 (match_operand 2 "immediate_operand" "")
7583 (clobber (reg:SI 15))]
7584 ;;- Do not use operand 1 for most machines.
7585 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7586 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7587 [(set_attr "type" "call_no_delay_slot")])
7589 ;; This is a call that wants a structure value.
7590 ;; There is no such critter for v9 (??? we may need one anyway).
7591 (define_insn "*call_symbolic_struct_value_sp32"
7592 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7593 (match_operand 1 "" ""))
7594 (match_operand 2 "immediate_operand" "")
7595 (clobber (reg:SI 15))]
7596 ;;- Do not use operand 1 for most machines.
7597 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7598 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7599 [(set_attr "type" "call_no_delay_slot")])
7601 ;; This is a call that may want a structure value. This is used for
7603 (define_insn "*call_address_untyped_struct_value_sp32"
7604 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7605 (match_operand 1 "" ""))
7606 (match_operand 2 "immediate_operand" "")
7607 (clobber (reg:SI 15))]
7608 ;;- Do not use operand 1 for most machines.
7609 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7610 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7611 [(set_attr "type" "call_no_delay_slot")])
7613 ;; This is a call that wants a structure value.
7614 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7615 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7616 (match_operand 1 "" ""))
7617 (match_operand 2 "immediate_operand" "")
7618 (clobber (reg:SI 15))]
7619 ;;- Do not use operand 1 for most machines.
7620 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7621 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7622 [(set_attr "type" "call_no_delay_slot")])
7624 (define_expand "call_value"
7625 ;; Note that this expression is not used for generating RTL.
7626 ;; All the RTL is generated explicitly below.
7627 [(set (match_operand 0 "register_operand" "=rf")
7628 (call (match_operand:SI 1 "" "")
7629 (match_operand 4 "" "")))]
7630 ;; operand 2 is stack_size_rtx
7631 ;; operand 3 is next_arg_register
7635 rtx fn_rtx, nregs_rtx;
7638 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7641 fn_rtx = operands[1];
7645 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7647 nregs_rtx = GEN_INT (6);
7649 nregs_rtx = const0_rtx;
7653 gen_rtx_SET (VOIDmode, operands[0],
7654 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7655 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7657 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7662 (define_insn "*call_value_address_sp32"
7663 [(set (match_operand 0 "" "=rf")
7664 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7665 (match_operand 2 "" "")))
7666 (clobber (reg:SI 15))]
7667 ;;- Do not use operand 2 for most machines.
7670 [(set_attr "type" "call")])
7672 (define_insn "*call_value_symbolic_sp32"
7673 [(set (match_operand 0 "" "=rf")
7674 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7675 (match_operand 2 "" "")))
7676 (clobber (reg:SI 15))]
7677 ;;- Do not use operand 2 for most machines.
7680 [(set_attr "type" "call")])
7682 (define_insn "*call_value_address_sp64"
7683 [(set (match_operand 0 "" "")
7684 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
7685 (match_operand 2 "" "")))
7686 (clobber (reg:DI 15))]
7687 ;;- Do not use operand 2 for most machines.
7690 [(set_attr "type" "call")])
7692 (define_insn "*call_value_symbolic_sp64"
7693 [(set (match_operand 0 "" "")
7694 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
7695 (match_operand 2 "" "")))
7696 (clobber (reg:DI 15))]
7697 ;;- Do not use operand 2 for most machines.
7700 [(set_attr "type" "call")])
7702 (define_expand "untyped_call"
7703 [(parallel [(call (match_operand 0 "" "")
7705 (match_operand 1 "" "")
7706 (match_operand 2 "" "")])]
7712 /* Pass constm1 to indicate that it may expect a structure value, but
7713 we don't know what size it is. */
7714 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7716 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7718 rtx set = XVECEXP (operands[2], 0, i);
7719 emit_move_insn (SET_DEST (set), SET_SRC (set));
7722 /* The optimizer does not know that the call sets the function value
7723 registers we stored in the result block. We avoid problems by
7724 claiming that all hard registers are used and clobbered at this
7726 emit_insn (gen_blockage ());
7731 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7732 ;; all of memory. This blocks insns from being moved across this point.
7734 (define_insn "blockage"
7735 [(unspec_volatile [(const_int 0)] 0)]
7738 [(set_attr "length" "0")])
7740 ;; Prepare to return any type including a structure value.
7742 (define_expand "untyped_return"
7743 [(match_operand:BLK 0 "memory_operand" "")
7744 (match_operand 1 "" "")]
7748 rtx valreg1 = gen_rtx_REG (DImode, 24);
7749 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7750 rtx result = operands[0];
7752 if (! TARGET_ARCH64)
7754 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7756 rtx value = gen_reg_rtx (SImode);
7758 /* Fetch the instruction where we will return to and see if it's an unimp
7759 instruction (the most significant 10 bits will be zero). If so,
7760 update the return address to skip the unimp instruction. */
7761 emit_move_insn (value,
7762 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7763 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7764 emit_insn (gen_update_return (rtnreg, value));
7767 /* Reload the function value registers. */
7768 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
7769 emit_move_insn (valreg2,
7770 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
7771 plus_constant (XEXP (result, 0), 8)));
7773 /* Put USE insns before the return. */
7774 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7775 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7777 /* Construct the return. */
7778 expand_null_return ();
7783 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7784 ;; and parts of the compiler don't want to believe that the add is needed.
7786 (define_insn "update_return"
7787 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7788 (match_operand:SI 1 "register_operand" "r")] 1)]
7790 "cmp %1,0\;be,a .+8\;add %0,4,%0"
7791 [(set_attr "type" "multi")])
7793 (define_insn "return"
7797 "* return output_return (operands);"
7798 [(set_attr "type" "return")])
7801 [(set (match_operand:SI 0 "register_operand" "=r")
7802 (match_operand:SI 1 "arith_operand" "rI"))
7804 (use (reg:SI 31))])]
7805 "sparc_return_peephole_ok (operands[0], operands[1])"
7806 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
7812 [(set_attr "type" "ialu")
7813 (set_attr "length" "1")])
7815 (define_expand "indirect_jump"
7816 [(set (pc) (match_operand 0 "address_operand" "p"))]
7820 (define_insn "*branch_sp32"
7821 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7824 [(set_attr "type" "uncond_branch")])
7826 (define_insn "*branch_sp64"
7827 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7830 [(set_attr "type" "uncond_branch")])
7832 ;; ??? Doesn't work with -mflat.
7833 (define_expand "nonlocal_goto"
7834 [(match_operand:SI 0 "general_operand" "")
7835 (match_operand:SI 1 "general_operand" "")
7836 (match_operand:SI 2 "general_operand" "")
7837 (match_operand:SI 3 "" "")]
7842 rtx chain = operands[0];
7844 rtx fp = operands[1];
7845 rtx stack = operands[2];
7846 rtx lab = operands[3];
7849 /* Trap instruction to flush all the register windows. */
7850 emit_insn (gen_flush_register_windows ());
7852 /* Load the fp value for the containing fn into %fp. This is needed
7853 because STACK refers to %fp. Note that virtual register instantiation
7854 fails if the virtual %fp isn't set from a register. */
7855 if (GET_CODE (fp) != REG)
7856 fp = force_reg (Pmode, fp);
7857 emit_move_insn (virtual_stack_vars_rtx, fp);
7859 /* Find the containing function's current nonlocal goto handler,
7860 which will do any cleanups and then jump to the label. */
7861 labreg = gen_rtx_REG (Pmode, 8);
7862 emit_move_insn (labreg, lab);
7864 /* Restore %fp from stack pointer value for containing function.
7865 The restore insn that follows will move this to %sp,
7866 and reload the appropriate value into %fp. */
7867 emit_move_insn (frame_pointer_rtx, stack);
7869 /* USE of frame_pointer_rtx added for consistency; not clear if
7871 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7872 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7875 /* Return, restoring reg window and jumping to goto handler. */
7876 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7877 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7879 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
7884 /* Put in the static chain register the nonlocal label address. */
7885 emit_move_insn (static_chain_rtx, chain);
7888 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7889 emit_insn (gen_goto_handler_and_restore (labreg));
7894 ;; Special trap insn to flush register windows.
7895 (define_insn "flush_register_windows"
7896 [(unspec_volatile [(const_int 0)] 1)]
7898 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
7899 [(set_attr "type" "misc")
7900 (set_attr "length" "1")])
7902 (define_insn "goto_handler_and_restore"
7903 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
7904 "GET_MODE (operands[0]) == Pmode"
7905 "jmp\\t%0+0\\n\\trestore"
7906 [(set_attr "type" "misc")
7907 (set_attr "length" "2")])
7909 ;;(define_insn "goto_handler_and_restore_v9"
7910 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7911 ;; (match_operand:SI 1 "register_operand" "=r,r")
7912 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7913 ;; "TARGET_V9 && ! TARGET_ARCH64"
7915 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7916 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7917 ;; [(set_attr "type" "misc")
7918 ;; (set_attr "length" "2,3")])
7920 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7921 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7922 ;; (match_operand:DI 1 "register_operand" "=r,r")
7923 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7924 ;; "TARGET_V9 && TARGET_ARCH64"
7926 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
7927 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7928 ;; [(set_attr "type" "misc")
7929 ;; (set_attr "length" "2,3")])
7931 ;; Pattern for use after a setjmp to store FP and the return register
7932 ;; into the stack area.
7934 (define_expand "setjmp"
7940 emit_insn (gen_setjmp_64 ());
7942 emit_insn (gen_setjmp_32 ());
7946 (define_expand "setjmp_32"
7947 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7948 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7951 { operands[0] = frame_pointer_rtx; }")
7953 (define_expand "setjmp_64"
7954 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7955 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7958 { operands[0] = frame_pointer_rtx; }")
7960 ;; Special pattern for the FLUSH instruction.
7962 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7963 ; of the define_insn otherwise missing a mode. We make "flush", aka
7964 ; gen_flush, the default one since sparc_initialize_trampoline uses
7965 ; it on SImode mem values.
7967 (define_insn "flush"
7968 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
7970 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
7971 [(set_attr "type" "misc")])
7973 (define_insn "flushdi"
7974 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
7976 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
7977 [(set_attr "type" "misc")])
7982 ;; The scan instruction searches from the most significant bit while ffs
7983 ;; searches from the least significant bit. The bit index and treatment of
7984 ;; zero also differ. It takes at least 7 instructions to get the proper
7985 ;; result. Here is an obvious 8 instruction sequence.
7988 (define_insn "ffssi2"
7989 [(set (match_operand:SI 0 "register_operand" "=&r")
7990 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7991 (clobber (match_scratch:SI 2 "=&r"))]
7992 "TARGET_SPARCLITE || TARGET_SPARCLET"
7996 output_asm_insn (\"and %%g0,0,%%g0\", operands);
7997 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\";
7999 [(set_attr "type" "multi")
8000 (set_attr "length" "8")])
8002 ;; ??? This should be a define expand, so that the extra instruction have
8003 ;; a chance of being optimized away.
8005 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8006 ;; does, but no one uses that and we don't have a switch for it.
8008 ;(define_insn "ffsdi2"
8009 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8010 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8011 ; (clobber (match_scratch:DI 2 "=&r"))]
8013 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
8014 ; [(set_attr "type" "multi")
8015 ; (set_attr "length" "4")])
8019 ;; Peepholes go at the end.
8021 ;; Optimize consecutive loads or stores into ldd and std when possible.
8022 ;; The conditions in which we do this are very restricted and are
8023 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8026 [(set (match_operand:SI 0 "memory_operand" "")
8028 (set (match_operand:SI 1 "memory_operand" "")
8031 && ! MEM_VOLATILE_P (operands[0])
8032 && ! MEM_VOLATILE_P (operands[1])
8033 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8037 [(set (match_operand:SI 0 "memory_operand" "")
8039 (set (match_operand:SI 1 "memory_operand" "")
8042 && ! MEM_VOLATILE_P (operands[0])
8043 && ! MEM_VOLATILE_P (operands[1])
8044 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8048 [(set (match_operand:SI 0 "register_operand" "=rf")
8049 (match_operand:SI 1 "memory_operand" ""))
8050 (set (match_operand:SI 2 "register_operand" "=rf")
8051 (match_operand:SI 3 "memory_operand" ""))]
8052 "registers_ok_for_ldd_peep (operands[0], operands[2])
8053 && ! MEM_VOLATILE_P (operands[1])
8054 && ! MEM_VOLATILE_P (operands[3])
8055 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8059 [(set (match_operand:SI 0 "memory_operand" "")
8060 (match_operand:SI 1 "register_operand" "rf"))
8061 (set (match_operand:SI 2 "memory_operand" "")
8062 (match_operand:SI 3 "register_operand" "rf"))]
8063 "registers_ok_for_ldd_peep (operands[1], operands[3])
8064 && ! MEM_VOLATILE_P (operands[0])
8065 && ! MEM_VOLATILE_P (operands[2])
8066 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8070 [(set (match_operand:SF 0 "register_operand" "=fr")
8071 (match_operand:SF 1 "memory_operand" ""))
8072 (set (match_operand:SF 2 "register_operand" "=fr")
8073 (match_operand:SF 3 "memory_operand" ""))]
8074 "registers_ok_for_ldd_peep (operands[0], operands[2])
8075 && ! MEM_VOLATILE_P (operands[1])
8076 && ! MEM_VOLATILE_P (operands[3])
8077 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8081 [(set (match_operand:SF 0 "memory_operand" "")
8082 (match_operand:SF 1 "register_operand" "fr"))
8083 (set (match_operand:SF 2 "memory_operand" "")
8084 (match_operand:SF 3 "register_operand" "fr"))]
8085 "registers_ok_for_ldd_peep (operands[1], operands[3])
8086 && ! MEM_VOLATILE_P (operands[0])
8087 && ! MEM_VOLATILE_P (operands[2])
8088 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8092 [(set (match_operand:SI 0 "register_operand" "=rf")
8093 (match_operand:SI 1 "memory_operand" ""))
8094 (set (match_operand:SI 2 "register_operand" "=rf")
8095 (match_operand:SI 3 "memory_operand" ""))]
8096 "registers_ok_for_ldd_peep (operands[2], operands[0])
8097 && ! MEM_VOLATILE_P (operands[3])
8098 && ! MEM_VOLATILE_P (operands[1])
8099 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8103 [(set (match_operand:SI 0 "memory_operand" "")
8104 (match_operand:SI 1 "register_operand" "rf"))
8105 (set (match_operand:SI 2 "memory_operand" "")
8106 (match_operand:SI 3 "register_operand" "rf"))]
8107 "registers_ok_for_ldd_peep (operands[3], operands[1])
8108 && ! MEM_VOLATILE_P (operands[2])
8109 && ! MEM_VOLATILE_P (operands[0])
8110 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8114 [(set (match_operand:SF 0 "register_operand" "=fr")
8115 (match_operand:SF 1 "memory_operand" ""))
8116 (set (match_operand:SF 2 "register_operand" "=fr")
8117 (match_operand:SF 3 "memory_operand" ""))]
8118 "registers_ok_for_ldd_peep (operands[2], operands[0])
8119 && ! MEM_VOLATILE_P (operands[3])
8120 && ! MEM_VOLATILE_P (operands[1])
8121 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8125 [(set (match_operand:SF 0 "memory_operand" "")
8126 (match_operand:SF 1 "register_operand" "fr"))
8127 (set (match_operand:SF 2 "memory_operand" "")
8128 (match_operand:SF 3 "register_operand" "fr"))]
8129 "registers_ok_for_ldd_peep (operands[3], operands[1])
8130 && ! MEM_VOLATILE_P (operands[2])
8131 && ! MEM_VOLATILE_P (operands[0])
8132 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8135 ;; Optimize the case of following a reg-reg move with a test
8136 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8137 ;; This can result from a float to fix conversion.
8140 [(set (match_operand:SI 0 "register_operand" "=r")
8141 (match_operand:SI 1 "register_operand" "r"))
8143 (compare:CC (match_operand:SI 2 "register_operand" "r")
8145 "(rtx_equal_p (operands[2], operands[0])
8146 || rtx_equal_p (operands[2], operands[1]))
8147 && ! FP_REG_P (operands[0])
8148 && ! FP_REG_P (operands[1])"
8152 [(set (match_operand:DI 0 "register_operand" "=r")
8153 (match_operand:DI 1 "register_operand" "r"))
8155 (compare:CCX (match_operand:DI 2 "register_operand" "r")
8158 && (rtx_equal_p (operands[2], operands[0])
8159 || rtx_equal_p (operands[2], operands[1]))
8160 && ! FP_REG_P (operands[0])
8161 && ! FP_REG_P (operands[1])"
8164 ;; Return peepholes. First the "normal" ones.
8165 ;; These are necessary to catch insns ending up in the epilogue delay list.
8167 (define_insn "*return_qi"
8168 [(set (match_operand:QI 0 "restore_operand" "")
8169 (match_operand:QI 1 "arith_operand" "rI"))
8171 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8174 if (! TARGET_ARCH64 && current_function_returns_struct)
8175 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8176 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8177 || IN_OR_GLOBAL_P (operands[1])))
8178 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8180 return \"ret\\n\\trestore %%g0, %1, %Y0\";
8182 [(set_attr "type" "multi")])
8184 (define_insn "*return_hi"
8185 [(set (match_operand:HI 0 "restore_operand" "")
8186 (match_operand:HI 1 "arith_operand" "rI"))
8188 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8191 if (! TARGET_ARCH64 && current_function_returns_struct)
8192 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8193 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8194 || IN_OR_GLOBAL_P (operands[1])))
8195 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8197 return \"ret\;restore %%g0, %1, %Y0\";
8199 [(set_attr "type" "multi")])
8201 (define_insn "*return_si"
8202 [(set (match_operand:SI 0 "restore_operand" "")
8203 (match_operand:SI 1 "arith_operand" "rI"))
8205 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8208 if (! TARGET_ARCH64 && current_function_returns_struct)
8209 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8210 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8211 || IN_OR_GLOBAL_P (operands[1])))
8212 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8214 return \"ret\;restore %%g0, %1, %Y0\";
8216 [(set_attr "type" "multi")])
8218 ;; The following pattern is only generated by delayed-branch scheduling,
8219 ;; when the insn winds up in the epilogue. This can happen not only when
8220 ;; ! TARGET_FPU because we move complex types around by parts using
8222 (define_insn "*return_sf_no_fpu"
8223 [(set (match_operand:SF 0 "restore_operand" "=r")
8224 (match_operand:SF 1 "register_operand" "r"))
8226 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8229 if (! TARGET_ARCH64 && current_function_returns_struct)
8230 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
8231 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8232 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
8234 return \"ret\;restore %%g0, %1, %Y0\";
8236 [(set_attr "type" "multi")])
8238 (define_insn "*return_addsi"
8239 [(set (match_operand:SI 0 "restore_operand" "")
8240 (plus:SI (match_operand:SI 1 "register_operand" "r")
8241 (match_operand:SI 2 "arith_operand" "rI")))
8243 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
8246 if (! TARGET_ARCH64 && current_function_returns_struct)
8247 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
8248 /* If operands are global or in registers, can use return */
8249 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8250 && (GET_CODE (operands[2]) == CONST_INT
8251 || IN_OR_GLOBAL_P (operands[2])))
8252 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
8254 return \"ret\;restore %r1, %2, %Y0\";
8256 [(set_attr "type" "multi")])
8258 (define_insn "*return_losum_si"
8259 [(set (match_operand:SI 0 "restore_operand" "")
8260 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8261 (match_operand:SI 2 "immediate_operand" "in")))
8263 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0 && ! TARGET_CM_MEDMID"
8266 if (! TARGET_ARCH64 && current_function_returns_struct)
8267 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
8268 /* If operands are global or in registers, can use return */
8269 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8270 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
8272 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
8274 [(set_attr "type" "multi")])
8276 (define_insn "*return_di"
8277 [(set (match_operand:DI 0 "restore_operand" "")
8278 (match_operand:DI 1 "arith_double_operand" "rHI"))
8280 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8281 "ret\;restore %%g0, %1, %Y0"
8282 [(set_attr "type" "multi")])
8284 (define_insn "*return_adddi"
8285 [(set (match_operand:DI 0 "restore_operand" "")
8286 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8287 (match_operand:DI 2 "arith_double_operand" "rHI")))
8289 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
8290 "ret\;restore %r1, %2, %Y0"
8291 [(set_attr "type" "multi")])
8293 (define_insn "*return_losum_di"
8294 [(set (match_operand:DI 0 "restore_operand" "")
8295 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8296 (match_operand:DI 2 "immediate_operand" "in")))
8298 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
8299 "ret\;restore %r1, %%lo(%a2), %Y0"
8300 [(set_attr "type" "multi")])
8302 ;; The following pattern is only generated by delayed-branch scheduling,
8303 ;; when the insn winds up in the epilogue.
8304 (define_insn "*return_sf"
8306 (match_operand:SF 0 "register_operand" "f"))
8309 "ret\;fmovs\\t%0, %%f0"
8310 [(set_attr "type" "multi")])
8312 ;; Now peepholes to do a call followed by a jump.
8315 [(parallel [(set (match_operand 0 "" "")
8316 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
8317 (match_operand 2 "" "")))
8318 (clobber (reg:SI 15))])
8319 (set (pc) (label_ref (match_operand 3 "" "")))]
8320 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8321 && in_same_eh_region (insn, operands[3])
8322 && in_same_eh_region (insn, ins1)"
8323 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8326 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8327 (match_operand 1 "" ""))
8328 (clobber (reg:SI 15))])
8329 (set (pc) (label_ref (match_operand 2 "" "")))]
8330 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8331 && in_same_eh_region (insn, operands[2])
8332 && in_same_eh_region (insn, ins1)"
8333 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8336 [(parallel [(set (match_operand 0 "" "")
8337 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
8338 (match_operand 2 "" "")))
8339 (clobber (reg:DI 15))])
8340 (set (pc) (label_ref (match_operand 3 "" "")))]
8342 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8343 && in_same_eh_region (insn, operands[3])
8344 && in_same_eh_region (insn, ins1)"
8345 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8348 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
8349 (match_operand 1 "" ""))
8350 (clobber (reg:DI 15))])
8351 (set (pc) (label_ref (match_operand 2 "" "")))]
8353 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8354 && in_same_eh_region (insn, operands[2])
8355 && in_same_eh_region (insn, ins1)"
8356 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8358 ;; After a nonlocal goto, we need to restore the PIC register, but only
8359 ;; if we need it. So do nothing much here, but we'll check for this in
8362 ;; Make sure this unspec_volatile number agrees with finalize_pic.
8363 (define_insn "nonlocal_goto_receiver"
8364 [(unspec_volatile [(const_int 0)] 5)]
8367 [(set_attr "length" "0")])
8370 [(trap_if (const_int 1) (const_int 5))]
8373 [(set_attr "type" "misc")
8374 (set_attr "length" "1")])
8376 (define_expand "conditional_trap"
8377 [(trap_if (match_operator 0 "noov_compare_op"
8378 [(match_dup 2) (match_dup 3)])
8379 (match_operand:SI 1 "arith_operand" ""))]
8381 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8382 sparc_compare_op0, sparc_compare_op1);
8383 operands[3] = const0_rtx;")
8386 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8387 (match_operand:SI 1 "arith_operand" "rM"))]
8390 [(set_attr "type" "misc")
8391 (set_attr "length" "1")])
8394 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8395 (match_operand:SI 1 "arith_operand" "rM"))]
8398 [(set_attr "type" "misc")
8399 (set_attr "length" "1")])