1 ;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
29 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
34 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
40 ;; 11 embmedany_sethi, embmedany_brsum
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
48 ;; UNSPEC_VOLATILE: 0 blockage
49 ;; 1 flush_register_windows
50 ;; 2 goto_handler_and_restore
51 ;; 3 goto_handler_and_restore_v9*
53 ;; 5 do_builtin_setjmp_setup
56 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
57 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
58 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
59 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
60 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62 ;; Attribute for cpu type.
63 ;; These must match the values for enum processor_type in sparc.h.
64 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
65 (const (symbol_ref "sparc_cpu_attr")))
67 ;; Attribute for the instruction set.
68 ;; At present we only need to distinguish v9/!v9, but for clarity we
69 ;; test TARGET_V8 too.
70 (define_attr "isa" "v6,v8,v9,sparclet"
72 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
73 (symbol_ref "TARGET_V8") (const_string "v8")
74 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
75 (const_string "v6"))))
78 (define_attr "arch" "arch32bit,arch64bit"
80 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
81 (const_string "arch32bit"))))
86 "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
87 (const_string "ialu"))
89 ;; Length (in # of insns).
90 (define_attr "length" "" (const_int 1))
93 (define_attr "fptype" "single,double" (const_string "single"))
95 (define_asm_attributes
96 [(set_attr "length" "2")
97 (set_attr "type" "multi")])
99 ;; Attributes for instruction and branch scheduling
101 (define_attr "in_call_delay" "false,true"
102 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
103 (const_string "false")
104 (eq_attr "type" "load,fpload,store,fpstore")
105 (if_then_else (eq_attr "length" "1")
106 (const_string "true")
107 (const_string "false"))]
108 (if_then_else (eq_attr "length" "1")
109 (const_string "true")
110 (const_string "false"))))
112 (define_delay (eq_attr "type" "call")
113 [(eq_attr "in_call_delay" "true") (nil) (nil)])
115 (define_attr "eligible_for_sibcall_delay" "false,true"
116 (symbol_ref "eligible_for_sibcall_delay (insn)"))
118 (define_delay (eq_attr "type" "sibcall")
119 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
121 (define_attr "leaf_function" "false,true"
122 (const (symbol_ref "current_function_uses_only_leaf_regs")))
124 (define_attr "eligible_for_return_delay" "false,true"
125 (symbol_ref "eligible_for_return_delay (insn)"))
127 (define_attr "in_return_delay" "false,true"
128 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
129 (eq_attr "length" "1"))
130 (eq_attr "leaf_function" "false"))
131 (eq_attr "eligible_for_return_delay" "false"))
132 (const_string "true")
133 (const_string "false")))
135 (define_delay (and (eq_attr "type" "return")
136 (eq_attr "isa" "v9"))
137 [(eq_attr "in_return_delay" "true") (nil) (nil)])
139 ;; ??? Should implement the notion of predelay slots for floating point
140 ;; branches. This would allow us to remove the nop always inserted before
141 ;; a floating point branch.
143 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
144 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
145 ;; This is because doing so will add several pipeline stalls to the path
146 ;; that the load/store did not come from. Unfortunately, there is no way
147 ;; to prevent fill_eager_delay_slots from using load/store without completely
148 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
149 ;; because it prevents us from moving back the final store of inner loops.
151 (define_attr "in_branch_delay" "false,true"
152 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
153 (eq_attr "length" "1"))
154 (const_string "true")
155 (const_string "false")))
157 (define_attr "in_uncond_branch_delay" "false,true"
158 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
159 (eq_attr "length" "1"))
160 (const_string "true")
161 (const_string "false")))
163 (define_attr "in_annul_branch_delay" "false,true"
164 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
165 (eq_attr "length" "1"))
166 (const_string "true")
167 (const_string "false")))
169 (define_delay (eq_attr "type" "branch")
170 [(eq_attr "in_branch_delay" "true")
171 (nil) (eq_attr "in_annul_branch_delay" "true")])
173 (define_delay (eq_attr "type" "uncond_branch")
174 [(eq_attr "in_uncond_branch_delay" "true")
177 ;; Function units of the SPARC
179 ;; (define_function_unit {name} {num-units} {n-users} {test}
180 ;; {ready-delay} {issue-delay} [{conflict-list}])
183 ;; (Noted only for documentation; units that take one cycle do not need to
186 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
189 ;; ---- cypress CY7C602 scheduling:
190 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
192 (define_function_unit "memory" 1 0
193 (and (eq_attr "cpu" "cypress")
194 (eq_attr "type" "load,sload,fpload"))
197 ;; SPARC has two floating-point units: the FP ALU,
198 ;; and the FP MUL/DIV/SQRT unit.
199 ;; Instruction timings on the CY7C602 are as follows
213 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
214 ;; More insns cause the chip to stall.
216 (define_function_unit "fp_alu" 1 0
217 (and (eq_attr "cpu" "cypress")
218 (eq_attr "type" "fp,fpmove"))
221 (define_function_unit "fp_mds" 1 0
222 (and (eq_attr "cpu" "cypress")
223 (eq_attr "type" "fpmul"))
226 (define_function_unit "fp_mds" 1 0
227 (and (eq_attr "cpu" "cypress")
228 (eq_attr "type" "fpdivs,fpdivd"))
231 (define_function_unit "fp_mds" 1 0
232 (and (eq_attr "cpu" "cypress")
233 (eq_attr "type" "fpsqrts,fpsqrtd"))
236 ;; ----- The TMS390Z55 scheduling
237 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
238 ;; one ld/st, one fp.
239 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
241 (define_function_unit "memory" 1 0
242 (and (eq_attr "cpu" "supersparc")
243 (eq_attr "type" "load,sload"))
246 (define_function_unit "memory" 1 0
247 (and (eq_attr "cpu" "supersparc")
248 (eq_attr "type" "fpload"))
251 (define_function_unit "memory" 1 0
252 (and (eq_attr "cpu" "supersparc")
253 (eq_attr "type" "store,fpstore"))
256 (define_function_unit "shift" 1 0
257 (and (eq_attr "cpu" "supersparc")
258 (eq_attr "type" "shift"))
261 ;; There are only two write ports to the integer register file
262 ;; A store also uses a write port
264 (define_function_unit "iwport" 2 0
265 (and (eq_attr "cpu" "supersparc")
266 (eq_attr "type" "load,sload,store,shift,ialu"))
269 ;; Timings; throughput/latency
270 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
278 (define_function_unit "fp_alu" 1 0
279 (and (eq_attr "cpu" "supersparc")
280 (eq_attr "type" "fp,fpmove,fpcmp"))
283 (define_function_unit "fp_mds" 1 0
284 (and (eq_attr "cpu" "supersparc")
285 (eq_attr "type" "fpmul"))
288 (define_function_unit "fp_mds" 1 0
289 (and (eq_attr "cpu" "supersparc")
290 (eq_attr "type" "fpdivs"))
293 (define_function_unit "fp_mds" 1 0
294 (and (eq_attr "cpu" "supersparc")
295 (eq_attr "type" "fpdivd"))
298 (define_function_unit "fp_mds" 1 0
299 (and (eq_attr "cpu" "supersparc")
300 (eq_attr "type" "fpsqrts,fpsqrtd"))
303 (define_function_unit "fp_mds" 1 0
304 (and (eq_attr "cpu" "supersparc")
305 (eq_attr "type" "imul"))
308 ;; ----- hypersparc/sparclite86x scheduling
309 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
310 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
311 ;; II/FF case is only when loading a 32 bit hi/lo constant
312 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
313 ;; Memory delivers its result in one cycle to IU
315 (define_function_unit "memory" 1 0
316 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
317 (eq_attr "type" "load,sload,fpload"))
320 (define_function_unit "memory" 1 0
321 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
322 (eq_attr "type" "store,fpstore"))
325 (define_function_unit "sparclite86x_branch" 1 0
326 (and (eq_attr "cpu" "sparclite86x")
327 (eq_attr "type" "branch"))
330 ;; integer multiply insns
331 (define_function_unit "sparclite86x_shift" 1 0
332 (and (eq_attr "cpu" "sparclite86x")
333 (eq_attr "type" "shift"))
336 (define_function_unit "fp_alu" 1 0
337 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
338 (eq_attr "type" "fp,fpmove,fpcmp"))
341 (define_function_unit "fp_mds" 1 0
342 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
343 (eq_attr "type" "fpmul"))
346 (define_function_unit "fp_mds" 1 0
347 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
348 (eq_attr "type" "fpdivs"))
351 (define_function_unit "fp_mds" 1 0
352 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
353 (eq_attr "type" "fpdivd"))
356 (define_function_unit "fp_mds" 1 0
357 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
358 (eq_attr "type" "fpsqrts,fpsqrtd"))
361 (define_function_unit "fp_mds" 1 0
362 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
363 (eq_attr "type" "imul"))
366 ;; ----- sparclet tsc701 scheduling
367 ;; The tsc701 issues 1 insn per cycle.
368 ;; Results may be written back out of order.
370 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
372 (define_function_unit "tsc701_load" 4 1
373 (and (eq_attr "cpu" "tsc701")
374 (eq_attr "type" "load,sload"))
377 ;; Stores take 2(?) extra cycles to complete.
378 ;; It is desirable to not have any memory operation in the following 2 cycles.
379 ;; (??? or 2 memory ops in the case of std).
381 (define_function_unit "tsc701_store" 1 0
382 (and (eq_attr "cpu" "tsc701")
383 (eq_attr "type" "store"))
385 [(eq_attr "type" "load,sload,store")])
387 ;; The multiply unit has a latency of 5.
388 (define_function_unit "tsc701_mul" 1 0
389 (and (eq_attr "cpu" "tsc701")
390 (eq_attr "type" "imul"))
393 ;; ----- The UltraSPARC-1 scheduling
394 ;; UltraSPARC has two integer units. Shift instructions can only execute
395 ;; on IE0. Condition code setting instructions, call, and jmpl (including
396 ;; the ret and retl pseudo-instructions) can only execute on IE1.
397 ;; Branch on register uses IE1, but branch on condition code does not.
398 ;; Conditional moves take 2 cycles. No other instruction can issue in the
399 ;; same cycle as a conditional move.
400 ;; Multiply and divide take many cycles during which no other instructions
402 ;; Memory delivers its result in two cycles (except for signed loads,
403 ;; which take one cycle more). One memory instruction can be issued per
406 (define_function_unit "memory" 1 0
407 (and (eq_attr "cpu" "ultrasparc")
408 (eq_attr "type" "load,fpload"))
411 (define_function_unit "memory" 1 0
412 (and (eq_attr "cpu" "ultrasparc")
413 (eq_attr "type" "sload"))
416 (define_function_unit "memory" 1 0
417 (and (eq_attr "cpu" "ultrasparc")
418 (eq_attr "type" "store,fpstore"))
421 (define_function_unit "ieuN" 2 0
422 (and (eq_attr "cpu" "ultrasparc")
423 (eq_attr "type" "ialu,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
426 (define_function_unit "ieu0" 1 0
427 (and (eq_attr "cpu" "ultrasparc")
428 (eq_attr "type" "shift"))
431 (define_function_unit "ieu0" 1 0
432 (and (eq_attr "cpu" "ultrasparc")
433 (eq_attr "type" "cmove"))
436 (define_function_unit "ieu1" 1 0
437 (and (eq_attr "cpu" "ultrasparc")
438 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
441 (define_function_unit "cti" 1 0
442 (and (eq_attr "cpu" "ultrasparc")
443 (eq_attr "type" "branch"))
446 ;; Timings; throughput/latency
447 ;; FMOV 1/1 fmov, fabs, fneg
449 ;; FADD 1/3 add/sub, format conv, compar
455 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
457 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
458 ;; use the FPM multiplier for final rounding 3 cycles before the
459 ;; end of their latency and we have no real way to model that.
461 ;; ??? This is really bogus because the timings really depend upon
462 ;; who uses the result. We should record who the user is with
463 ;; more descriptive 'type' attribute names and account for these
464 ;; issues in ultrasparc_adjust_cost.
466 (define_function_unit "fadd" 1 0
467 (and (eq_attr "cpu" "ultrasparc")
468 (eq_attr "type" "fpmove"))
471 (define_function_unit "fadd" 1 0
472 (and (eq_attr "cpu" "ultrasparc")
473 (eq_attr "type" "fpcmove"))
476 (define_function_unit "fadd" 1 0
477 (and (eq_attr "cpu" "ultrasparc")
478 (eq_attr "type" "fp"))
481 (define_function_unit "fadd" 1 0
482 (and (eq_attr "cpu" "ultrasparc")
483 (eq_attr "type" "fpcmp"))
486 (define_function_unit "fmul" 1 0
487 (and (eq_attr "cpu" "ultrasparc")
488 (eq_attr "type" "fpmul"))
491 (define_function_unit "fadd" 1 0
492 (and (eq_attr "cpu" "ultrasparc")
493 (eq_attr "type" "fpcmove"))
496 (define_function_unit "fdiv" 1 0
497 (and (eq_attr "cpu" "ultrasparc")
498 (eq_attr "type" "fpdivs"))
501 (define_function_unit "fdiv" 1 0
502 (and (eq_attr "cpu" "ultrasparc")
503 (eq_attr "type" "fpdivd"))
506 (define_function_unit "fdiv" 1 0
507 (and (eq_attr "cpu" "ultrasparc")
508 (eq_attr "type" "fpsqrts"))
511 (define_function_unit "fdiv" 1 0
512 (and (eq_attr "cpu" "ultrasparc")
513 (eq_attr "type" "fpsqrtd"))
516 ;; Compare instructions.
517 ;; This controls RTL generation and register allocation.
519 ;; We generate RTL for comparisons and branches by having the cmpxx
520 ;; patterns store away the operands. Then, the scc and bcc patterns
521 ;; emit RTL for both the compare and the branch.
523 ;; We do this because we want to generate different code for an sne and
524 ;; seq insn. In those cases, if the second operand of the compare is not
525 ;; const0_rtx, we want to compute the xor of the two operands and test
528 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
529 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
530 ;; insns that actually require more than one machine instruction.
532 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
534 (define_expand "cmpsi"
536 (compare:CC (match_operand:SI 0 "register_operand" "")
537 (match_operand:SI 1 "arith_operand" "")))]
541 sparc_compare_op0 = operands[0];
542 sparc_compare_op1 = operands[1];
546 (define_expand "cmpdi"
548 (compare:CCX (match_operand:DI 0 "register_operand" "")
549 (match_operand:DI 1 "arith_double_operand" "")))]
553 sparc_compare_op0 = operands[0];
554 sparc_compare_op1 = operands[1];
558 (define_expand "cmpsf"
559 ;; The 96 here isn't ever used by anyone.
561 (compare:CCFP (match_operand:SF 0 "register_operand" "")
562 (match_operand:SF 1 "register_operand" "")))]
566 sparc_compare_op0 = operands[0];
567 sparc_compare_op1 = operands[1];
571 (define_expand "cmpdf"
572 ;; The 96 here isn't ever used by anyone.
574 (compare:CCFP (match_operand:DF 0 "register_operand" "")
575 (match_operand:DF 1 "register_operand" "")))]
579 sparc_compare_op0 = operands[0];
580 sparc_compare_op1 = operands[1];
584 (define_expand "cmptf"
585 ;; The 96 here isn't ever used by anyone.
587 (compare:CCFP (match_operand:TF 0 "register_operand" "")
588 (match_operand:TF 1 "register_operand" "")))]
592 sparc_compare_op0 = operands[0];
593 sparc_compare_op1 = operands[1];
597 ;; Now the compare DEFINE_INSNs.
599 (define_insn "*cmpsi_insn"
601 (compare:CC (match_operand:SI 0 "register_operand" "r")
602 (match_operand:SI 1 "arith_operand" "rI")))]
605 [(set_attr "type" "compare")])
607 (define_insn "*cmpdi_sp64"
609 (compare:CCX (match_operand:DI 0 "register_operand" "r")
610 (match_operand:DI 1 "arith_double_operand" "rHI")))]
613 [(set_attr "type" "compare")])
615 (define_insn "*cmpsf_fpe"
616 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
617 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
618 (match_operand:SF 2 "register_operand" "f")))]
623 return \"fcmpes\\t%0, %1, %2\";
624 return \"fcmpes\\t%1, %2\";
626 [(set_attr "type" "fpcmp")])
628 (define_insn "*cmpdf_fpe"
629 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
630 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
631 (match_operand:DF 2 "register_operand" "e")))]
636 return \"fcmped\\t%0, %1, %2\";
637 return \"fcmped\\t%1, %2\";
639 [(set_attr "type" "fpcmp")
640 (set_attr "fptype" "double")])
642 (define_insn "*cmptf_fpe"
643 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
644 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
645 (match_operand:TF 2 "register_operand" "e")))]
646 "TARGET_FPU && TARGET_HARD_QUAD"
650 return \"fcmpeq\\t%0, %1, %2\";
651 return \"fcmpeq\\t%1, %2\";
653 [(set_attr "type" "fpcmp")])
655 (define_insn "*cmpsf_fp"
656 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
657 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
658 (match_operand:SF 2 "register_operand" "f")))]
663 return \"fcmps\\t%0, %1, %2\";
664 return \"fcmps\\t%1, %2\";
666 [(set_attr "type" "fpcmp")])
668 (define_insn "*cmpdf_fp"
669 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
670 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
671 (match_operand:DF 2 "register_operand" "e")))]
676 return \"fcmpd\\t%0, %1, %2\";
677 return \"fcmpd\\t%1, %2\";
679 [(set_attr "type" "fpcmp")
680 (set_attr "fptype" "double")])
682 (define_insn "*cmptf_fp"
683 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
684 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
685 (match_operand:TF 2 "register_operand" "e")))]
686 "TARGET_FPU && TARGET_HARD_QUAD"
690 return \"fcmpq\\t%0, %1, %2\";
691 return \"fcmpq\\t%1, %2\";
693 [(set_attr "type" "fpcmp")])
695 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
696 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
697 ;; the same code as v8 (the addx/subx method has more applications). The
698 ;; exception to this is "reg != 0" which can be done in one instruction on v9
699 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
702 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
703 ;; generate addcc/subcc instructions.
705 (define_expand "seqsi_special"
707 (xor:SI (match_operand:SI 1 "register_operand" "")
708 (match_operand:SI 2 "register_operand" "")))
709 (parallel [(set (match_operand:SI 0 "register_operand" "")
710 (eq:SI (match_dup 3) (const_int 0)))
711 (clobber (reg:CC 100))])]
713 "{ operands[3] = gen_reg_rtx (SImode); }")
715 (define_expand "seqdi_special"
717 (xor:DI (match_operand:DI 1 "register_operand" "")
718 (match_operand:DI 2 "register_operand" "")))
719 (set (match_operand:DI 0 "register_operand" "")
720 (eq:DI (match_dup 3) (const_int 0)))]
722 "{ operands[3] = gen_reg_rtx (DImode); }")
724 (define_expand "snesi_special"
726 (xor:SI (match_operand:SI 1 "register_operand" "")
727 (match_operand:SI 2 "register_operand" "")))
728 (parallel [(set (match_operand:SI 0 "register_operand" "")
729 (ne:SI (match_dup 3) (const_int 0)))
730 (clobber (reg:CC 100))])]
732 "{ operands[3] = gen_reg_rtx (SImode); }")
734 (define_expand "snedi_special"
736 (xor:DI (match_operand:DI 1 "register_operand" "")
737 (match_operand:DI 2 "register_operand" "")))
738 (set (match_operand:DI 0 "register_operand" "")
739 (ne:DI (match_dup 3) (const_int 0)))]
741 "{ operands[3] = gen_reg_rtx (DImode); }")
743 (define_expand "seqdi_special_trunc"
745 (xor:DI (match_operand:DI 1 "register_operand" "")
746 (match_operand:DI 2 "register_operand" "")))
747 (set (match_operand:SI 0 "register_operand" "")
748 (eq:SI (match_dup 3) (const_int 0)))]
750 "{ operands[3] = gen_reg_rtx (DImode); }")
752 (define_expand "snedi_special_trunc"
754 (xor:DI (match_operand:DI 1 "register_operand" "")
755 (match_operand:DI 2 "register_operand" "")))
756 (set (match_operand:SI 0 "register_operand" "")
757 (ne:SI (match_dup 3) (const_int 0)))]
759 "{ operands[3] = gen_reg_rtx (DImode); }")
761 (define_expand "seqsi_special_extend"
763 (xor:SI (match_operand:SI 1 "register_operand" "")
764 (match_operand:SI 2 "register_operand" "")))
765 (parallel [(set (match_operand:DI 0 "register_operand" "")
766 (eq:DI (match_dup 3) (const_int 0)))
767 (clobber (reg:CC 100))])]
769 "{ operands[3] = gen_reg_rtx (SImode); }")
771 (define_expand "snesi_special_extend"
773 (xor:SI (match_operand:SI 1 "register_operand" "")
774 (match_operand:SI 2 "register_operand" "")))
775 (parallel [(set (match_operand:DI 0 "register_operand" "")
776 (ne:DI (match_dup 3) (const_int 0)))
777 (clobber (reg:CC 100))])]
779 "{ operands[3] = gen_reg_rtx (SImode); }")
781 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
782 ;; However, the code handles both SImode and DImode.
784 [(set (match_operand:SI 0 "intreg_operand" "")
785 (eq:SI (match_dup 1) (const_int 0)))]
789 if (GET_MODE (sparc_compare_op0) == SImode)
793 if (GET_MODE (operands[0]) == SImode)
794 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
796 else if (! TARGET_ARCH64)
799 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
804 else if (GET_MODE (sparc_compare_op0) == DImode)
810 else if (GET_MODE (operands[0]) == SImode)
811 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
814 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
819 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
821 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
822 emit_jump_insn (gen_sne (operands[0]));
827 if (gen_v9_scc (EQ, operands))
834 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
835 ;; However, the code handles both SImode and DImode.
837 [(set (match_operand:SI 0 "intreg_operand" "")
838 (ne:SI (match_dup 1) (const_int 0)))]
842 if (GET_MODE (sparc_compare_op0) == SImode)
846 if (GET_MODE (operands[0]) == SImode)
847 pat = gen_snesi_special (operands[0], sparc_compare_op0,
849 else if (! TARGET_ARCH64)
852 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
857 else if (GET_MODE (sparc_compare_op0) == DImode)
863 else if (GET_MODE (operands[0]) == SImode)
864 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
867 pat = gen_snedi_special (operands[0], sparc_compare_op0,
872 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
874 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
875 emit_jump_insn (gen_sne (operands[0]));
880 if (gen_v9_scc (NE, operands))
888 [(set (match_operand:SI 0 "intreg_operand" "")
889 (gt:SI (match_dup 1) (const_int 0)))]
893 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
895 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
896 emit_jump_insn (gen_sne (operands[0]));
901 if (gen_v9_scc (GT, operands))
909 [(set (match_operand:SI 0 "intreg_operand" "")
910 (lt:SI (match_dup 1) (const_int 0)))]
914 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
916 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
917 emit_jump_insn (gen_sne (operands[0]));
922 if (gen_v9_scc (LT, operands))
930 [(set (match_operand:SI 0 "intreg_operand" "")
931 (ge:SI (match_dup 1) (const_int 0)))]
935 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
937 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
938 emit_jump_insn (gen_sne (operands[0]));
943 if (gen_v9_scc (GE, operands))
951 [(set (match_operand:SI 0 "intreg_operand" "")
952 (le:SI (match_dup 1) (const_int 0)))]
956 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
958 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
959 emit_jump_insn (gen_sne (operands[0]));
964 if (gen_v9_scc (LE, operands))
971 (define_expand "sgtu"
972 [(set (match_operand:SI 0 "intreg_operand" "")
973 (gtu:SI (match_dup 1) (const_int 0)))]
981 /* We can do ltu easily, so if both operands are registers, swap them and
983 if ((GET_CODE (sparc_compare_op0) == REG
984 || GET_CODE (sparc_compare_op0) == SUBREG)
985 && (GET_CODE (sparc_compare_op1) == REG
986 || GET_CODE (sparc_compare_op1) == SUBREG))
988 tem = sparc_compare_op0;
989 sparc_compare_op0 = sparc_compare_op1;
990 sparc_compare_op1 = tem;
991 pat = gen_sltu (operands[0]);
1000 if (gen_v9_scc (GTU, operands))
1006 (define_expand "sltu"
1007 [(set (match_operand:SI 0 "intreg_operand" "")
1008 (ltu:SI (match_dup 1) (const_int 0)))]
1014 if (gen_v9_scc (LTU, operands))
1017 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1020 (define_expand "sgeu"
1021 [(set (match_operand:SI 0 "intreg_operand" "")
1022 (geu:SI (match_dup 1) (const_int 0)))]
1028 if (gen_v9_scc (GEU, operands))
1031 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1034 (define_expand "sleu"
1035 [(set (match_operand:SI 0 "intreg_operand" "")
1036 (leu:SI (match_dup 1) (const_int 0)))]
1044 /* We can do geu easily, so if both operands are registers, swap them and
1046 if ((GET_CODE (sparc_compare_op0) == REG
1047 || GET_CODE (sparc_compare_op0) == SUBREG)
1048 && (GET_CODE (sparc_compare_op1) == REG
1049 || GET_CODE (sparc_compare_op1) == SUBREG))
1051 tem = sparc_compare_op0;
1052 sparc_compare_op0 = sparc_compare_op1;
1053 sparc_compare_op1 = tem;
1054 pat = gen_sgeu (operands[0]);
1055 if (pat == NULL_RTX)
1063 if (gen_v9_scc (LEU, operands))
1069 ;; Now the DEFINE_INSNs for the scc cases.
1071 ;; The SEQ and SNE patterns are special because they can be done
1072 ;; without any branching and do not involve a COMPARE. We want
1073 ;; them to always use the splitz below so the results can be
1076 (define_insn "*snesi_zero"
1077 [(set (match_operand:SI 0 "register_operand" "=r")
1078 (ne:SI (match_operand:SI 1 "register_operand" "r")
1080 (clobber (reg:CC 100))]
1083 [(set_attr "length" "2")])
1086 [(set (match_operand:SI 0 "register_operand" "")
1087 (ne:SI (match_operand:SI 1 "register_operand" "")
1089 (clobber (reg:CC 100))]
1091 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1093 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1096 (define_insn "*neg_snesi_zero"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1098 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1100 (clobber (reg:CC 100))]
1103 [(set_attr "length" "2")])
1106 [(set (match_operand:SI 0 "register_operand" "")
1107 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1109 (clobber (reg:CC 100))]
1111 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1113 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1116 (define_insn "*snesi_zero_extend"
1117 [(set (match_operand:DI 0 "register_operand" "=r")
1118 (ne:DI (match_operand:SI 1 "register_operand" "r")
1120 (clobber (reg:CC 100))]
1123 [(set_attr "length" "2")])
1126 [(set (match_operand:DI 0 "register_operand" "")
1127 (ne:DI (match_operand:SI 1 "register_operand" "")
1129 (clobber (reg:CC 100))]
1131 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1133 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1135 (ltu:SI (reg:CC_NOOV 100)
1139 (define_insn "*snedi_zero"
1140 [(set (match_operand:DI 0 "register_operand" "=&r")
1141 (ne:DI (match_operand:DI 1 "register_operand" "r")
1145 [(set_attr "length" "2")])
1148 [(set (match_operand:DI 0 "register_operand" "")
1149 (ne:DI (match_operand:DI 1 "register_operand" "")
1152 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1153 [(set (match_dup 0) (const_int 0))
1154 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1160 (define_insn "*neg_snedi_zero"
1161 [(set (match_operand:DI 0 "register_operand" "=&r")
1162 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1166 [(set_attr "length" "2")])
1169 [(set (match_operand:DI 0 "register_operand" "")
1170 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1173 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1174 [(set (match_dup 0) (const_int 0))
1175 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1181 (define_insn "*snedi_zero_trunc"
1182 [(set (match_operand:SI 0 "register_operand" "=&r")
1183 (ne:SI (match_operand:DI 1 "register_operand" "r")
1187 [(set_attr "length" "2")])
1190 [(set (match_operand:SI 0 "register_operand" "")
1191 (ne:SI (match_operand:DI 1 "register_operand" "")
1194 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1195 [(set (match_dup 0) (const_int 0))
1196 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1202 (define_insn "*seqsi_zero"
1203 [(set (match_operand:SI 0 "register_operand" "=r")
1204 (eq:SI (match_operand:SI 1 "register_operand" "r")
1206 (clobber (reg:CC 100))]
1209 [(set_attr "length" "2")])
1212 [(set (match_operand:SI 0 "register_operand" "")
1213 (eq:SI (match_operand:SI 1 "register_operand" "")
1215 (clobber (reg:CC 100))]
1217 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1219 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1222 (define_insn "*neg_seqsi_zero"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1226 (clobber (reg:CC 100))]
1229 [(set_attr "length" "2")])
1232 [(set (match_operand:SI 0 "register_operand" "")
1233 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1235 (clobber (reg:CC 100))]
1237 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1239 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1242 (define_insn "*seqsi_zero_extend"
1243 [(set (match_operand:DI 0 "register_operand" "=r")
1244 (eq:DI (match_operand:SI 1 "register_operand" "r")
1246 (clobber (reg:CC 100))]
1249 [(set_attr "length" "2")])
1252 [(set (match_operand:DI 0 "register_operand" "")
1253 (eq:DI (match_operand:SI 1 "register_operand" "")
1255 (clobber (reg:CC 100))]
1257 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1259 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1261 (ltu:SI (reg:CC_NOOV 100)
1265 (define_insn "*seqdi_zero"
1266 [(set (match_operand:DI 0 "register_operand" "=&r")
1267 (eq:DI (match_operand:DI 1 "register_operand" "r")
1271 [(set_attr "length" "2")])
1274 [(set (match_operand:DI 0 "register_operand" "")
1275 (eq:DI (match_operand:DI 1 "register_operand" "")
1278 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1279 [(set (match_dup 0) (const_int 0))
1280 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1286 (define_insn "*neg_seqdi_zero"
1287 [(set (match_operand:DI 0 "register_operand" "=&r")
1288 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1292 [(set_attr "length" "2")])
1295 [(set (match_operand:DI 0 "register_operand" "")
1296 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1299 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1300 [(set (match_dup 0) (const_int 0))
1301 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1307 (define_insn "*seqdi_zero_trunc"
1308 [(set (match_operand:SI 0 "register_operand" "=&r")
1309 (eq:SI (match_operand:DI 1 "register_operand" "r")
1313 [(set_attr "length" "2")])
1316 [(set (match_operand:SI 0 "register_operand" "")
1317 (eq:SI (match_operand:DI 1 "register_operand" "")
1320 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1321 [(set (match_dup 0) (const_int 0))
1322 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1328 ;; We can also do (x + (i == 0)) and related, so put them in.
1329 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1332 (define_insn "*x_plus_i_ne_0"
1333 [(set (match_operand:SI 0 "register_operand" "=r")
1334 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1336 (match_operand:SI 2 "register_operand" "r")))
1337 (clobber (reg:CC 100))]
1340 [(set_attr "length" "2")])
1343 [(set (match_operand:SI 0 "register_operand" "")
1344 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1346 (match_operand:SI 2 "register_operand" "")))
1347 (clobber (reg:CC 100))]
1349 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1351 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1355 (define_insn "*x_minus_i_ne_0"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (minus:SI (match_operand:SI 2 "register_operand" "r")
1358 (ne:SI (match_operand:SI 1 "register_operand" "r")
1360 (clobber (reg:CC 100))]
1363 [(set_attr "length" "2")])
1366 [(set (match_operand:SI 0 "register_operand" "")
1367 (minus:SI (match_operand:SI 2 "register_operand" "")
1368 (ne:SI (match_operand:SI 1 "register_operand" "")
1370 (clobber (reg:CC 100))]
1372 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1374 (set (match_dup 0) (minus:SI (match_dup 2)
1375 (ltu:SI (reg:CC 100) (const_int 0))))]
1378 (define_insn "*x_plus_i_eq_0"
1379 [(set (match_operand:SI 0 "register_operand" "=r")
1380 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1382 (match_operand:SI 2 "register_operand" "r")))
1383 (clobber (reg:CC 100))]
1386 [(set_attr "length" "2")])
1389 [(set (match_operand:SI 0 "register_operand" "")
1390 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1392 (match_operand:SI 2 "register_operand" "")))
1393 (clobber (reg:CC 100))]
1395 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1397 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1401 (define_insn "*x_minus_i_eq_0"
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (minus:SI (match_operand:SI 2 "register_operand" "r")
1404 (eq:SI (match_operand:SI 1 "register_operand" "r")
1406 (clobber (reg:CC 100))]
1409 [(set_attr "length" "2")])
1412 [(set (match_operand:SI 0 "register_operand" "")
1413 (minus:SI (match_operand:SI 2 "register_operand" "")
1414 (eq:SI (match_operand:SI 1 "register_operand" "")
1416 (clobber (reg:CC 100))]
1418 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1420 (set (match_dup 0) (minus:SI (match_dup 2)
1421 (geu:SI (reg:CC 100) (const_int 0))))]
1424 ;; We can also do GEU and LTU directly, but these operate after a compare.
1425 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1428 (define_insn "*sltu_insn"
1429 [(set (match_operand:SI 0 "register_operand" "=r")
1430 (ltu:SI (reg:CC 100) (const_int 0)))]
1432 "addx\\t%%g0, 0, %0"
1433 [(set_attr "type" "misc")])
1435 (define_insn "*neg_sltu_insn"
1436 [(set (match_operand:SI 0 "register_operand" "=r")
1437 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1439 "subx\\t%%g0, 0, %0"
1440 [(set_attr "type" "misc")])
1442 ;; ??? Combine should canonicalize these next two to the same pattern.
1443 (define_insn "*neg_sltu_minus_x"
1444 [(set (match_operand:SI 0 "register_operand" "=r")
1445 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1446 (match_operand:SI 1 "arith_operand" "rI")))]
1448 "subx\\t%%g0, %1, %0"
1449 [(set_attr "type" "misc")])
1451 (define_insn "*neg_sltu_plus_x"
1452 [(set (match_operand:SI 0 "register_operand" "=r")
1453 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1454 (match_operand:SI 1 "arith_operand" "rI"))))]
1456 "subx\\t%%g0, %1, %0"
1457 [(set_attr "type" "misc")])
1459 (define_insn "*sgeu_insn"
1460 [(set (match_operand:SI 0 "register_operand" "=r")
1461 (geu:SI (reg:CC 100) (const_int 0)))]
1463 "subx\\t%%g0, -1, %0"
1464 [(set_attr "type" "misc")])
1466 (define_insn "*neg_sgeu_insn"
1467 [(set (match_operand:SI 0 "register_operand" "=r")
1468 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1470 "addx\\t%%g0, -1, %0"
1471 [(set_attr "type" "misc")])
1473 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1474 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1477 (define_insn "*sltu_plus_x"
1478 [(set (match_operand:SI 0 "register_operand" "=r")
1479 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1480 (match_operand:SI 1 "arith_operand" "rI")))]
1482 "addx\\t%%g0, %1, %0"
1483 [(set_attr "type" "misc")])
1485 (define_insn "*sltu_plus_x_plus_y"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1488 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1489 (match_operand:SI 2 "arith_operand" "rI"))))]
1492 [(set_attr "type" "misc")])
1494 (define_insn "*x_minus_sltu"
1495 [(set (match_operand:SI 0 "register_operand" "=r")
1496 (minus:SI (match_operand:SI 1 "register_operand" "r")
1497 (ltu:SI (reg:CC 100) (const_int 0))))]
1500 [(set_attr "type" "misc")])
1502 ;; ??? Combine should canonicalize these next two to the same pattern.
1503 (define_insn "*x_minus_y_minus_sltu"
1504 [(set (match_operand:SI 0 "register_operand" "=r")
1505 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1506 (match_operand:SI 2 "arith_operand" "rI"))
1507 (ltu:SI (reg:CC 100) (const_int 0))))]
1509 "subx\\t%r1, %2, %0"
1510 [(set_attr "type" "misc")])
1512 (define_insn "*x_minus_sltu_plus_y"
1513 [(set (match_operand:SI 0 "register_operand" "=r")
1514 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1515 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1516 (match_operand:SI 2 "arith_operand" "rI"))))]
1518 "subx\\t%r1, %2, %0"
1519 [(set_attr "type" "misc")])
1521 (define_insn "*sgeu_plus_x"
1522 [(set (match_operand:SI 0 "register_operand" "=r")
1523 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1524 (match_operand:SI 1 "register_operand" "r")))]
1527 [(set_attr "type" "misc")])
1529 (define_insn "*x_minus_sgeu"
1530 [(set (match_operand:SI 0 "register_operand" "=r")
1531 (minus:SI (match_operand:SI 1 "register_operand" "r")
1532 (geu:SI (reg:CC 100) (const_int 0))))]
1535 [(set_attr "type" "misc")])
1538 [(set (match_operand:SI 0 "register_operand" "")
1539 (match_operator:SI 2 "noov_compare_op"
1540 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1542 ;; 32 bit LTU/GEU are better implemented using addx/subx
1543 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1544 && (GET_MODE (operands[1]) == CCXmode
1545 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1546 [(set (match_dup 0) (const_int 0))
1548 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1554 ;; These control RTL generation for conditional jump insns
1556 ;; The quad-word fp compare library routines all return nonzero to indicate
1557 ;; true, which is different from the equivalent libgcc routines, so we must
1558 ;; handle them specially here.
1560 (define_expand "beq"
1562 (if_then_else (eq (match_dup 1) (const_int 0))
1563 (label_ref (match_operand 0 "" ""))
1568 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1569 && GET_CODE (sparc_compare_op0) == REG
1570 && GET_MODE (sparc_compare_op0) == DImode)
1572 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1575 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1577 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1578 emit_jump_insn (gen_bne (operands[0]));
1581 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1584 (define_expand "bne"
1586 (if_then_else (ne (match_dup 1) (const_int 0))
1587 (label_ref (match_operand 0 "" ""))
1592 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1593 && GET_CODE (sparc_compare_op0) == REG
1594 && GET_MODE (sparc_compare_op0) == DImode)
1596 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1599 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1601 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1602 emit_jump_insn (gen_bne (operands[0]));
1605 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1608 (define_expand "bgt"
1610 (if_then_else (gt (match_dup 1) (const_int 0))
1611 (label_ref (match_operand 0 "" ""))
1616 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1617 && GET_CODE (sparc_compare_op0) == REG
1618 && GET_MODE (sparc_compare_op0) == DImode)
1620 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1623 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1625 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1626 emit_jump_insn (gen_bne (operands[0]));
1629 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1632 (define_expand "bgtu"
1634 (if_then_else (gtu (match_dup 1) (const_int 0))
1635 (label_ref (match_operand 0 "" ""))
1639 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1642 (define_expand "blt"
1644 (if_then_else (lt (match_dup 1) (const_int 0))
1645 (label_ref (match_operand 0 "" ""))
1650 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1651 && GET_CODE (sparc_compare_op0) == REG
1652 && GET_MODE (sparc_compare_op0) == DImode)
1654 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1657 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1659 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1660 emit_jump_insn (gen_bne (operands[0]));
1663 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1666 (define_expand "bltu"
1668 (if_then_else (ltu (match_dup 1) (const_int 0))
1669 (label_ref (match_operand 0 "" ""))
1673 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1676 (define_expand "bge"
1678 (if_then_else (ge (match_dup 1) (const_int 0))
1679 (label_ref (match_operand 0 "" ""))
1684 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1685 && GET_CODE (sparc_compare_op0) == REG
1686 && GET_MODE (sparc_compare_op0) == DImode)
1688 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1691 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1693 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1694 emit_jump_insn (gen_bne (operands[0]));
1697 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1700 (define_expand "bgeu"
1702 (if_then_else (geu (match_dup 1) (const_int 0))
1703 (label_ref (match_operand 0 "" ""))
1707 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1710 (define_expand "ble"
1712 (if_then_else (le (match_dup 1) (const_int 0))
1713 (label_ref (match_operand 0 "" ""))
1718 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1719 && GET_CODE (sparc_compare_op0) == REG
1720 && GET_MODE (sparc_compare_op0) == DImode)
1722 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1725 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1727 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1728 emit_jump_insn (gen_bne (operands[0]));
1731 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1734 (define_expand "bleu"
1736 (if_then_else (leu (match_dup 1) (const_int 0))
1737 (label_ref (match_operand 0 "" ""))
1741 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1744 (define_expand "bunordered"
1746 (if_then_else (unordered (match_dup 1) (const_int 0))
1747 (label_ref (match_operand 0 "" ""))
1752 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1754 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1756 emit_jump_insn (gen_beq (operands[0]));
1759 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1763 (define_expand "bordered"
1765 (if_then_else (ordered (match_dup 1) (const_int 0))
1766 (label_ref (match_operand 0 "" ""))
1771 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1773 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1774 emit_jump_insn (gen_bne (operands[0]));
1777 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1781 (define_expand "bungt"
1783 (if_then_else (ungt (match_dup 1) (const_int 0))
1784 (label_ref (match_operand 0 "" ""))
1789 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1791 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1792 emit_jump_insn (gen_bgt (operands[0]));
1795 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1798 (define_expand "bunlt"
1800 (if_then_else (unlt (match_dup 1) (const_int 0))
1801 (label_ref (match_operand 0 "" ""))
1806 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1808 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1809 emit_jump_insn (gen_bne (operands[0]));
1812 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1815 (define_expand "buneq"
1817 (if_then_else (uneq (match_dup 1) (const_int 0))
1818 (label_ref (match_operand 0 "" ""))
1823 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1825 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1826 emit_jump_insn (gen_beq (operands[0]));
1829 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1832 (define_expand "bunge"
1834 (if_then_else (unge (match_dup 1) (const_int 0))
1835 (label_ref (match_operand 0 "" ""))
1840 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1842 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1843 emit_jump_insn (gen_bne (operands[0]));
1846 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1849 (define_expand "bunle"
1851 (if_then_else (unle (match_dup 1) (const_int 0))
1852 (label_ref (match_operand 0 "" ""))
1857 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1859 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1860 emit_jump_insn (gen_bne (operands[0]));
1863 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1866 (define_expand "bltgt"
1868 (if_then_else (ltgt (match_dup 1) (const_int 0))
1869 (label_ref (match_operand 0 "" ""))
1874 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1876 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1877 emit_jump_insn (gen_bne (operands[0]));
1880 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1883 ;; Now match both normal and inverted jump.
1885 ;; XXX fpcmp nop braindamage
1886 (define_insn "*normal_branch"
1888 (if_then_else (match_operator 0 "noov_compare_op"
1889 [(reg 100) (const_int 0)])
1890 (label_ref (match_operand 1 "" ""))
1895 return output_cbranch (operands[0], 1, 0,
1896 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1897 ! final_sequence, insn);
1899 [(set_attr "type" "branch")])
1901 ;; XXX fpcmp nop braindamage
1902 (define_insn "*inverted_branch"
1904 (if_then_else (match_operator 0 "noov_compare_op"
1905 [(reg 100) (const_int 0)])
1907 (label_ref (match_operand 1 "" ""))))]
1911 return output_cbranch (operands[0], 1, 1,
1912 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1913 ! final_sequence, insn);
1915 [(set_attr "type" "branch")])
1917 ;; XXX fpcmp nop braindamage
1918 (define_insn "*normal_fp_branch"
1920 (if_then_else (match_operator 1 "comparison_operator"
1921 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1923 (label_ref (match_operand 2 "" ""))
1928 return output_cbranch (operands[1], 2, 0,
1929 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1930 ! final_sequence, insn);
1932 [(set_attr "type" "branch")])
1934 ;; XXX fpcmp nop braindamage
1935 (define_insn "*inverted_fp_branch"
1937 (if_then_else (match_operator 1 "comparison_operator"
1938 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1941 (label_ref (match_operand 2 "" ""))))]
1945 return output_cbranch (operands[1], 2, 1,
1946 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1947 ! final_sequence, insn);
1949 [(set_attr "type" "branch")])
1951 ;; XXX fpcmp nop braindamage
1952 (define_insn "*normal_fpe_branch"
1954 (if_then_else (match_operator 1 "comparison_operator"
1955 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1957 (label_ref (match_operand 2 "" ""))
1962 return output_cbranch (operands[1], 2, 0,
1963 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1964 ! final_sequence, insn);
1966 [(set_attr "type" "branch")])
1968 ;; XXX fpcmp nop braindamage
1969 (define_insn "*inverted_fpe_branch"
1971 (if_then_else (match_operator 1 "comparison_operator"
1972 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1975 (label_ref (match_operand 2 "" ""))))]
1979 return output_cbranch (operands[1], 2, 1,
1980 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1981 ! final_sequence, insn);
1983 [(set_attr "type" "branch")])
1985 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1986 ;; in the architecture.
1988 ;; There are no 32 bit brreg insns.
1991 (define_insn "*normal_int_branch_sp64"
1993 (if_then_else (match_operator 0 "v9_regcmp_op"
1994 [(match_operand:DI 1 "register_operand" "r")
1996 (label_ref (match_operand 2 "" ""))
2001 return output_v9branch (operands[0], 1, 2, 0,
2002 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2003 ! final_sequence, insn);
2005 [(set_attr "type" "branch")])
2008 (define_insn "*inverted_int_branch_sp64"
2010 (if_then_else (match_operator 0 "v9_regcmp_op"
2011 [(match_operand:DI 1 "register_operand" "r")
2014 (label_ref (match_operand 2 "" ""))))]
2018 return output_v9branch (operands[0], 1, 2, 1,
2019 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2020 ! final_sequence, insn);
2022 [(set_attr "type" "branch")])
2024 ;; Load program counter insns.
2026 (define_insn "get_pc"
2027 [(clobber (reg:SI 15))
2028 (set (match_operand 0 "register_operand" "=r")
2029 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2030 "flag_pic && REGNO (operands[0]) == 23"
2031 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2032 [(set_attr "type" "multi")
2033 (set_attr "length" "3")])
2035 ;; Currently unused...
2036 ;; (define_insn "get_pc_via_rdpc"
2037 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2040 ;; [(set_attr "type" "misc")])
2043 ;; Move instructions
2045 (define_expand "movqi"
2046 [(set (match_operand:QI 0 "general_operand" "")
2047 (match_operand:QI 1 "general_operand" ""))]
2051 /* Working with CONST_INTs is easier, so convert
2052 a double if needed. */
2053 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2055 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2057 else if (GET_CODE (operands[1]) == CONST_INT)
2059 /* And further, we know for all QI cases that only the
2060 low byte is significant, which we can always process
2061 in a single insn. So mask it now. */
2062 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2065 /* Handle sets of MEM first. */
2066 if (GET_CODE (operands[0]) == MEM)
2068 if (reg_or_0_operand (operands[1], QImode))
2071 if (! reload_in_progress)
2073 operands[0] = validize_mem (operands[0]);
2074 operands[1] = force_reg (QImode, operands[1]);
2078 /* Fixup PIC cases. */
2081 if (CONSTANT_P (operands[1])
2082 && pic_address_needs_scratch (operands[1]))
2083 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2085 if (symbolic_operand (operands[1], QImode))
2087 operands[1] = legitimize_pic_address (operands[1],
2089 (reload_in_progress ?
2096 /* All QI constants require only one insn, so proceed. */
2102 (define_insn "*movqi_insn"
2103 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2104 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2105 "(register_operand (operands[0], QImode)
2106 || reg_or_0_operand (operands[1], QImode))"
2111 [(set_attr "type" "*,load,store")])
2113 (define_expand "movhi"
2114 [(set (match_operand:HI 0 "general_operand" "")
2115 (match_operand:HI 1 "general_operand" ""))]
2119 /* Working with CONST_INTs is easier, so convert
2120 a double if needed. */
2121 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2122 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2124 /* Handle sets of MEM first. */
2125 if (GET_CODE (operands[0]) == MEM)
2127 if (reg_or_0_operand (operands[1], HImode))
2130 if (! reload_in_progress)
2132 operands[0] = validize_mem (operands[0]);
2133 operands[1] = force_reg (HImode, operands[1]);
2137 /* Fixup PIC cases. */
2140 if (CONSTANT_P (operands[1])
2141 && pic_address_needs_scratch (operands[1]))
2142 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2144 if (symbolic_operand (operands[1], HImode))
2146 operands[1] = legitimize_pic_address (operands[1],
2148 (reload_in_progress ?
2155 /* This makes sure we will not get rematched due to splittage. */
2156 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2158 else if (CONSTANT_P (operands[1])
2159 && GET_CODE (operands[1]) != HIGH
2160 && GET_CODE (operands[1]) != LO_SUM)
2162 sparc_emit_set_const32 (operands[0], operands[1]);
2169 (define_insn "*movhi_const64_special"
2170 [(set (match_operand:HI 0 "register_operand" "=r")
2171 (match_operand:HI 1 "const64_high_operand" ""))]
2173 "sethi\\t%%hi(%a1), %0")
2175 (define_insn "*movhi_insn"
2176 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2177 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2178 "(register_operand (operands[0], HImode)
2179 || reg_or_0_operand (operands[1], HImode))"
2182 sethi\\t%%hi(%a1), %0
2185 [(set_attr "type" "*,*,load,store")])
2187 ;; We always work with constants here.
2188 (define_insn "*movhi_lo_sum"
2189 [(set (match_operand:HI 0 "register_operand" "=r")
2190 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2191 (match_operand:HI 2 "arith_operand" "I")))]
2195 (define_expand "movsi"
2196 [(set (match_operand:SI 0 "general_operand" "")
2197 (match_operand:SI 1 "general_operand" ""))]
2201 /* Working with CONST_INTs is easier, so convert
2202 a double if needed. */
2203 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2204 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2206 /* Handle sets of MEM first. */
2207 if (GET_CODE (operands[0]) == MEM)
2209 if (reg_or_0_operand (operands[1], SImode))
2212 if (! reload_in_progress)
2214 operands[0] = validize_mem (operands[0]);
2215 operands[1] = force_reg (SImode, operands[1]);
2219 /* Fixup PIC cases. */
2222 if (CONSTANT_P (operands[1])
2223 && pic_address_needs_scratch (operands[1]))
2224 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2226 if (GET_CODE (operands[1]) == LABEL_REF)
2229 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2233 if (symbolic_operand (operands[1], SImode))
2235 operands[1] = legitimize_pic_address (operands[1],
2237 (reload_in_progress ?
2244 /* If we are trying to toss an integer constant into the
2245 FPU registers, force it into memory. */
2246 if (GET_CODE (operands[0]) == REG
2247 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2248 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2249 && CONSTANT_P (operands[1]))
2250 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2253 /* This makes sure we will not get rematched due to splittage. */
2254 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2256 else if (CONSTANT_P (operands[1])
2257 && GET_CODE (operands[1]) != HIGH
2258 && GET_CODE (operands[1]) != LO_SUM)
2260 sparc_emit_set_const32 (operands[0], operands[1]);
2267 ;; This is needed to show CSE exactly which bits are set
2268 ;; in a 64-bit register by sethi instructions.
2269 (define_insn "*movsi_const64_special"
2270 [(set (match_operand:SI 0 "register_operand" "=r")
2271 (match_operand:SI 1 "const64_high_operand" ""))]
2273 "sethi\\t%%hi(%a1), %0")
2275 (define_insn "*movsi_insn"
2276 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2277 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2278 "(register_operand (operands[0], SImode)
2279 || reg_or_0_operand (operands[1], SImode))"
2283 sethi\\t%%hi(%a1), %0
2290 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2292 (define_insn "*movsi_lo_sum"
2293 [(set (match_operand:SI 0 "register_operand" "=r")
2294 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2295 (match_operand:SI 2 "immediate_operand" "in")))]
2297 "or\\t%1, %%lo(%a2), %0")
2299 (define_insn "*movsi_high"
2300 [(set (match_operand:SI 0 "register_operand" "=r")
2301 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2303 "sethi\\t%%hi(%a1), %0")
2305 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2306 ;; so that CSE won't optimize the address computation away.
2307 (define_insn "movsi_lo_sum_pic"
2308 [(set (match_operand:SI 0 "register_operand" "=r")
2309 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2310 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2312 "or\\t%1, %%lo(%a2), %0")
2314 (define_insn "movsi_high_pic"
2315 [(set (match_operand:SI 0 "register_operand" "=r")
2316 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2317 "flag_pic && check_pic (1)"
2318 "sethi\\t%%hi(%a1), %0")
2320 (define_expand "movsi_pic_label_ref"
2321 [(set (match_dup 3) (high:SI
2322 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2324 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2325 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2326 (set (match_operand:SI 0 "register_operand" "=r")
2327 (minus:SI (match_dup 5) (match_dup 4)))]
2331 current_function_uses_pic_offset_table = 1;
2332 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2335 operands[3] = operands[0];
2336 operands[4] = operands[0];
2340 operands[3] = gen_reg_rtx (SImode);
2341 operands[4] = gen_reg_rtx (SImode);
2343 operands[5] = pic_offset_table_rtx;
2346 (define_insn "*movsi_high_pic_label_ref"
2347 [(set (match_operand:SI 0 "register_operand" "=r")
2349 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2350 (match_operand:SI 2 "" "")] 5)))]
2352 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2354 (define_insn "*movsi_lo_sum_pic_label_ref"
2355 [(set (match_operand:SI 0 "register_operand" "=r")
2356 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2357 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2358 (match_operand:SI 3 "" "")] 5)))]
2360 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2362 (define_expand "movdi"
2363 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2364 (match_operand:DI 1 "general_operand" ""))]
2368 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2369 if (GET_CODE (operands[1]) == CONST_DOUBLE
2370 #if HOST_BITS_PER_WIDE_INT == 32
2371 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2372 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2373 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2374 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2377 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2379 /* Handle MEM cases first. */
2380 if (GET_CODE (operands[0]) == MEM)
2382 /* If it's a REG, we can always do it.
2383 The const zero case is more complex, on v9
2384 we can always perform it. */
2385 if (register_operand (operands[1], DImode)
2387 && (operands[1] == const0_rtx)))
2390 if (! reload_in_progress)
2392 operands[0] = validize_mem (operands[0]);
2393 operands[1] = force_reg (DImode, operands[1]);
2399 if (CONSTANT_P (operands[1])
2400 && pic_address_needs_scratch (operands[1]))
2401 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2403 if (GET_CODE (operands[1]) == LABEL_REF)
2405 if (! TARGET_ARCH64)
2407 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2411 if (symbolic_operand (operands[1], DImode))
2413 operands[1] = legitimize_pic_address (operands[1],
2415 (reload_in_progress ?
2422 /* If we are trying to toss an integer constant into the
2423 FPU registers, force it into memory. */
2424 if (GET_CODE (operands[0]) == REG
2425 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2426 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2427 && CONSTANT_P (operands[1]))
2428 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2431 /* This makes sure we will not get rematched due to splittage. */
2432 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2434 else if (TARGET_ARCH64
2435 && CONSTANT_P (operands[1])
2436 && GET_CODE (operands[1]) != HIGH
2437 && GET_CODE (operands[1]) != LO_SUM)
2439 sparc_emit_set_const64 (operands[0], operands[1]);
2447 ;; Be careful, fmovd does not exist when !arch64.
2448 ;; We match MEM moves directly when we have correct even
2449 ;; numbered registers, but fall into splits otherwise.
2450 ;; The constraint ordering here is really important to
2451 ;; avoid insane problems in reload, especially for patterns
2454 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2455 ;; (const_int -5016)))
2458 (define_insn "*movdi_insn_sp32"
2459 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2460 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2462 (register_operand (operands[0], DImode)
2463 || register_operand (operands[1], DImode))"
2476 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2477 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2479 ;; The following are generated by sparc_emit_set_const64
2480 (define_insn "*movdi_sp64_dbl"
2481 [(set (match_operand:DI 0 "register_operand" "=r")
2482 (match_operand:DI 1 "const64_operand" ""))]
2484 && HOST_BITS_PER_WIDE_INT != 64)"
2487 ;; This is needed to show CSE exactly which bits are set
2488 ;; in a 64-bit register by sethi instructions.
2489 (define_insn "*movdi_const64_special"
2490 [(set (match_operand:DI 0 "register_operand" "=r")
2491 (match_operand:DI 1 "const64_high_operand" ""))]
2493 "sethi\\t%%hi(%a1), %0")
2495 (define_insn "*movdi_insn_sp64_novis"
2496 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2497 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2498 "TARGET_ARCH64 && ! TARGET_VIS
2499 && (register_operand (operands[0], DImode)
2500 || reg_or_0_operand (operands[1], DImode))"
2503 sethi\\t%%hi(%a1), %0
2510 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2511 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2513 (define_insn "*movdi_insn_sp64_vis"
2514 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2515 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2516 "TARGET_ARCH64 && TARGET_VIS &&
2517 (register_operand (operands[0], DImode)
2518 || reg_or_0_operand (operands[1], DImode))"
2521 sethi\\t%%hi(%a1), %0
2529 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2530 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2532 (define_expand "movdi_pic_label_ref"
2533 [(set (match_dup 3) (high:DI
2534 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2536 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2537 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2538 (set (match_operand:DI 0 "register_operand" "=r")
2539 (minus:DI (match_dup 5) (match_dup 4)))]
2540 "TARGET_ARCH64 && flag_pic"
2543 current_function_uses_pic_offset_table = 1;
2544 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2547 operands[3] = operands[0];
2548 operands[4] = operands[0];
2552 operands[3] = gen_reg_rtx (DImode);
2553 operands[4] = gen_reg_rtx (DImode);
2555 operands[5] = pic_offset_table_rtx;
2558 (define_insn "*movdi_high_pic_label_ref"
2559 [(set (match_operand:DI 0 "register_operand" "=r")
2561 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2562 (match_operand:DI 2 "" "")] 5)))]
2563 "TARGET_ARCH64 && flag_pic"
2564 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2566 (define_insn "*movdi_lo_sum_pic_label_ref"
2567 [(set (match_operand:DI 0 "register_operand" "=r")
2568 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2569 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2570 (match_operand:DI 3 "" "")] 5)))]
2571 "TARGET_ARCH64 && flag_pic"
2572 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2574 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2575 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2577 (define_insn "movdi_lo_sum_pic"
2578 [(set (match_operand:DI 0 "register_operand" "=r")
2579 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2580 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2581 "TARGET_ARCH64 && flag_pic"
2582 "or\\t%1, %%lo(%a2), %0")
2584 (define_insn "movdi_high_pic"
2585 [(set (match_operand:DI 0 "register_operand" "=r")
2586 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2587 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2588 "sethi\\t%%hi(%a1), %0")
2590 (define_insn "*sethi_di_medlow_embmedany_pic"
2591 [(set (match_operand:DI 0 "register_operand" "=r")
2592 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2593 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2594 "sethi\\t%%hi(%a1), %0")
2596 (define_insn "*sethi_di_medlow"
2597 [(set (match_operand:DI 0 "register_operand" "=r")
2598 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2599 "TARGET_CM_MEDLOW && check_pic (1)"
2600 "sethi\\t%%hi(%a1), %0")
2602 (define_insn "*losum_di_medlow"
2603 [(set (match_operand:DI 0 "register_operand" "=r")
2604 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2605 (match_operand:DI 2 "symbolic_operand" "")))]
2607 "or\\t%1, %%lo(%a2), %0")
2609 (define_insn "seth44"
2610 [(set (match_operand:DI 0 "register_operand" "=r")
2611 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2613 "sethi\\t%%h44(%a1), %0")
2615 (define_insn "setm44"
2616 [(set (match_operand:DI 0 "register_operand" "=r")
2617 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2618 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2620 "or\\t%1, %%m44(%a2), %0")
2622 (define_insn "setl44"
2623 [(set (match_operand:DI 0 "register_operand" "=r")
2624 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2625 (match_operand:DI 2 "symbolic_operand" "")))]
2627 "or\\t%1, %%l44(%a2), %0")
2629 (define_insn "sethh"
2630 [(set (match_operand:DI 0 "register_operand" "=r")
2631 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2633 "sethi\\t%%hh(%a1), %0")
2635 (define_insn "setlm"
2636 [(set (match_operand:DI 0 "register_operand" "=r")
2637 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2639 "sethi\\t%%lm(%a1), %0")
2641 (define_insn "sethm"
2642 [(set (match_operand:DI 0 "register_operand" "=r")
2643 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2644 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2646 "or\\t%1, %%hm(%a2), %0")
2648 (define_insn "setlo"
2649 [(set (match_operand:DI 0 "register_operand" "=r")
2650 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2651 (match_operand:DI 2 "symbolic_operand" "")))]
2653 "or\\t%1, %%lo(%a2), %0")
2655 (define_insn "embmedany_sethi"
2656 [(set (match_operand:DI 0 "register_operand" "=r")
2657 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2658 "TARGET_CM_EMBMEDANY && check_pic (1)"
2659 "sethi\\t%%hi(%a1), %0")
2661 (define_insn "embmedany_losum"
2662 [(set (match_operand:DI 0 "register_operand" "=r")
2663 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2664 (match_operand:DI 2 "data_segment_operand" "")))]
2665 "TARGET_CM_EMBMEDANY"
2666 "add\\t%1, %%lo(%a2), %0")
2668 (define_insn "embmedany_brsum"
2669 [(set (match_operand:DI 0 "register_operand" "=r")
2670 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2671 "TARGET_CM_EMBMEDANY"
2674 (define_insn "embmedany_textuhi"
2675 [(set (match_operand:DI 0 "register_operand" "=r")
2676 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2677 "TARGET_CM_EMBMEDANY && check_pic (1)"
2678 "sethi\\t%%uhi(%a1), %0")
2680 (define_insn "embmedany_texthi"
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2683 "TARGET_CM_EMBMEDANY && check_pic (1)"
2684 "sethi\\t%%hi(%a1), %0")
2686 (define_insn "embmedany_textulo"
2687 [(set (match_operand:DI 0 "register_operand" "=r")
2688 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2689 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2690 "TARGET_CM_EMBMEDANY"
2691 "or\\t%1, %%ulo(%a2), %0")
2693 (define_insn "embmedany_textlo"
2694 [(set (match_operand:DI 0 "register_operand" "=r")
2695 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2696 (match_operand:DI 2 "text_segment_operand" "")))]
2697 "TARGET_CM_EMBMEDANY"
2698 "or\\t%1, %%lo(%a2), %0")
2700 ;; Now some patterns to help reload out a bit.
2701 (define_expand "reload_indi"
2702 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2703 (match_operand:DI 1 "immediate_operand" "")
2704 (match_operand:TI 2 "register_operand" "=&r")])]
2706 || TARGET_CM_EMBMEDANY)
2710 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2711 gen_rtx_REG (DImode, REGNO (operands[2])));
2715 (define_expand "reload_outdi"
2716 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2717 (match_operand:DI 1 "immediate_operand" "")
2718 (match_operand:TI 2 "register_operand" "=&r")])]
2720 || TARGET_CM_EMBMEDANY)
2724 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2725 gen_rtx_REG (DImode, REGNO (operands[2])));
2729 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2731 [(set (match_operand:DI 0 "register_operand" "")
2732 (match_operand:DI 1 "const_int_operand" ""))]
2733 "! TARGET_ARCH64 && reload_completed"
2734 [(clobber (const_int 0))]
2737 #if HOST_BITS_PER_WIDE_INT == 32
2738 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2739 (INTVAL (operands[1]) < 0) ?
2742 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2745 unsigned int low, high;
2747 low = INTVAL (operands[1]) & 0xffffffff;
2748 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2749 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2751 /* Slick... but this trick loses if this subreg constant part
2752 can be done in one insn. */
2753 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2754 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2755 gen_highpart (SImode, operands[0])));
2757 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2763 [(set (match_operand:DI 0 "register_operand" "")
2764 (match_operand:DI 1 "const_double_operand" ""))]
2765 "! TARGET_ARCH64 && reload_completed"
2766 [(clobber (const_int 0))]
2769 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2770 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2772 /* Slick... but this trick loses if this subreg constant part
2773 can be done in one insn. */
2774 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2775 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2776 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2778 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2779 gen_highpart (SImode, operands[0])));
2783 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2784 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2790 [(set (match_operand:DI 0 "register_operand" "")
2791 (match_operand:DI 1 "register_operand" ""))]
2792 "! TARGET_ARCH64 && reload_completed"
2793 [(clobber (const_int 0))]
2796 rtx set_dest = operands[0];
2797 rtx set_src = operands[1];
2801 dest1 = gen_highpart (SImode, set_dest);
2802 dest2 = gen_lowpart (SImode, set_dest);
2803 src1 = gen_highpart (SImode, set_src);
2804 src2 = gen_lowpart (SImode, set_src);
2806 /* Now emit using the real source and destination we found, swapping
2807 the order if we detect overlap. */
2808 if (reg_overlap_mentioned_p (dest1, src2))
2810 emit_insn (gen_movsi (dest2, src2));
2811 emit_insn (gen_movsi (dest1, src1));
2815 emit_insn (gen_movsi (dest1, src1));
2816 emit_insn (gen_movsi (dest2, src2));
2821 ;; Now handle the cases of memory moves from/to non-even
2822 ;; DI mode register pairs.
2824 [(set (match_operand:DI 0 "register_operand" "")
2825 (match_operand:DI 1 "memory_operand" ""))]
2828 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2829 [(clobber (const_int 0))]
2832 rtx word0 = adjust_address (operands[1], SImode, 0);
2833 rtx word1 = adjust_address (operands[1], SImode, 4);
2834 rtx high_part = gen_highpart (SImode, operands[0]);
2835 rtx low_part = gen_lowpart (SImode, operands[0]);
2837 if (reg_overlap_mentioned_p (high_part, word1))
2839 emit_insn (gen_movsi (low_part, word1));
2840 emit_insn (gen_movsi (high_part, word0));
2844 emit_insn (gen_movsi (high_part, word0));
2845 emit_insn (gen_movsi (low_part, word1));
2851 [(set (match_operand:DI 0 "memory_operand" "")
2852 (match_operand:DI 1 "register_operand" ""))]
2855 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2856 [(clobber (const_int 0))]
2859 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2860 gen_highpart (SImode, operands[1])));
2861 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2862 gen_lowpart (SImode, operands[1])));
2867 ;; Floating point move insns
2869 (define_insn "*movsf_insn_novis"
2870 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2871 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2872 "(TARGET_FPU && ! TARGET_VIS)
2873 && (register_operand (operands[0], SFmode)
2874 || register_operand (operands[1], SFmode)
2875 || fp_zero_operand (operands[1], SFmode))"
2878 if (GET_CODE (operands[1]) == CONST_DOUBLE
2879 && (which_alternative == 2
2880 || which_alternative == 3
2881 || which_alternative == 4))
2886 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2887 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2888 operands[1] = GEN_INT (i);
2891 switch (which_alternative)
2894 return \"fmovs\\t%1, %0\";
2896 return \"clr\\t%0\";
2898 return \"sethi\\t%%hi(%a1), %0\";
2900 return \"mov\\t%1, %0\";
2905 return \"ld\\t%1, %0\";
2908 return \"st\\t%r1, %0\";
2913 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2915 (define_insn "*movsf_insn_vis"
2916 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2917 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2918 "(TARGET_FPU && TARGET_VIS)
2919 && (register_operand (operands[0], SFmode)
2920 || register_operand (operands[1], SFmode)
2921 || fp_zero_operand (operands[1], SFmode))"
2924 if (GET_CODE (operands[1]) == CONST_DOUBLE
2925 && (which_alternative == 3
2926 || which_alternative == 4
2927 || which_alternative == 5))
2932 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2933 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2934 operands[1] = GEN_INT (i);
2937 switch (which_alternative)
2940 return \"fmovs\\t%1, %0\";
2942 return \"fzeros\\t%0\";
2944 return \"clr\\t%0\";
2946 return \"sethi\\t%%hi(%a1), %0\";
2948 return \"mov\\t%1, %0\";
2953 return \"ld\\t%1, %0\";
2956 return \"st\\t%r1, %0\";
2961 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2963 ;; Exactly the same as above, except that all `f' cases are deleted.
2964 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2967 (define_insn "*movsf_no_f_insn"
2968 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2969 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2971 && (register_operand (operands[0], SFmode)
2972 || register_operand (operands[1], SFmode)
2973 || fp_zero_operand (operands[1], SFmode))"
2976 if (GET_CODE (operands[1]) == CONST_DOUBLE
2977 && (which_alternative == 1
2978 || which_alternative == 2
2979 || which_alternative == 3))
2984 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2985 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2986 operands[1] = GEN_INT (i);
2989 switch (which_alternative)
2992 return \"clr\\t%0\";
2994 return \"sethi\\t%%hi(%a1), %0\";
2996 return \"mov\\t%1, %0\";
3000 return \"ld\\t%1, %0\";
3002 return \"st\\t%r1, %0\";
3007 [(set_attr "type" "*,*,*,*,load,store")])
3009 (define_insn "*movsf_lo_sum"
3010 [(set (match_operand:SF 0 "register_operand" "=r")
3011 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3012 (match_operand:SF 2 "const_double_operand" "S")))]
3013 "fp_high_losum_p (operands[2])"
3019 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3020 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3021 operands[2] = GEN_INT (i);
3022 return \"or\\t%1, %%lo(%a2), %0\";
3025 (define_insn "*movsf_high"
3026 [(set (match_operand:SF 0 "register_operand" "=r")
3027 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3028 "fp_high_losum_p (operands[1])"
3034 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3035 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3036 operands[1] = GEN_INT (i);
3037 return \"sethi\\t%%hi(%1), %0\";
3041 [(set (match_operand:SF 0 "register_operand" "")
3042 (match_operand:SF 1 "const_double_operand" ""))]
3043 "fp_high_losum_p (operands[1])
3044 && (GET_CODE (operands[0]) == REG
3045 && REGNO (operands[0]) < 32)"
3046 [(set (match_dup 0) (high:SF (match_dup 1)))
3047 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3049 (define_expand "movsf"
3050 [(set (match_operand:SF 0 "general_operand" "")
3051 (match_operand:SF 1 "general_operand" ""))]
3055 /* Force SFmode constants into memory. */
3056 if (GET_CODE (operands[0]) == REG
3057 && CONSTANT_P (operands[1]))
3059 /* emit_group_store will send such bogosity to us when it is
3060 not storing directly into memory. So fix this up to avoid
3061 crashes in output_constant_pool. */
3062 if (operands [1] == const0_rtx)
3063 operands[1] = CONST0_RTX (SFmode);
3065 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3068 /* We are able to build any SF constant in integer registers
3069 with at most 2 instructions. */
3070 if (REGNO (operands[0]) < 32)
3073 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3077 /* Handle sets of MEM first. */
3078 if (GET_CODE (operands[0]) == MEM)
3080 if (register_operand (operands[1], SFmode)
3081 || fp_zero_operand (operands[1], SFmode))
3084 if (! reload_in_progress)
3086 operands[0] = validize_mem (operands[0]);
3087 operands[1] = force_reg (SFmode, operands[1]);
3091 /* Fixup PIC cases. */
3094 if (CONSTANT_P (operands[1])
3095 && pic_address_needs_scratch (operands[1]))
3096 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3098 if (symbolic_operand (operands[1], SFmode))
3100 operands[1] = legitimize_pic_address (operands[1],
3102 (reload_in_progress ?
3112 (define_expand "movdf"
3113 [(set (match_operand:DF 0 "general_operand" "")
3114 (match_operand:DF 1 "general_operand" ""))]
3118 /* Force DFmode constants into memory. */
3119 if (GET_CODE (operands[0]) == REG
3120 && CONSTANT_P (operands[1]))
3122 /* emit_group_store will send such bogosity to us when it is
3123 not storing directly into memory. So fix this up to avoid
3124 crashes in output_constant_pool. */
3125 if (operands [1] == const0_rtx)
3126 operands[1] = CONST0_RTX (DFmode);
3128 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3129 && fp_zero_operand (operands[1], DFmode))
3132 /* We are able to build any DF constant in integer registers. */
3133 if (REGNO (operands[0]) < 32
3134 && (reload_completed || reload_in_progress))
3137 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3141 /* Handle MEM cases first. */
3142 if (GET_CODE (operands[0]) == MEM)
3144 if (register_operand (operands[1], DFmode)
3145 || fp_zero_operand (operands[1], DFmode))
3148 if (! reload_in_progress)
3150 operands[0] = validize_mem (operands[0]);
3151 operands[1] = force_reg (DFmode, operands[1]);
3155 /* Fixup PIC cases. */
3158 if (CONSTANT_P (operands[1])
3159 && pic_address_needs_scratch (operands[1]))
3160 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3162 if (symbolic_operand (operands[1], DFmode))
3164 operands[1] = legitimize_pic_address (operands[1],
3166 (reload_in_progress ?
3176 ;; Be careful, fmovd does not exist when !v9.
3177 (define_insn "*movdf_insn_sp32"
3178 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3179 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3182 && (register_operand (operands[0], DFmode)
3183 || register_operand (operands[1], DFmode)
3184 || fp_zero_operand (operands[1], DFmode))"
3196 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3197 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3199 (define_insn "*movdf_no_e_insn_sp32"
3200 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3201 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3205 && (register_operand (operands[0], DFmode)
3206 || register_operand (operands[1], DFmode)
3207 || fp_zero_operand (operands[1], DFmode))"
3214 [(set_attr "type" "load,store,*,*,*")
3215 (set_attr "length" "*,*,2,2,2")])
3217 (define_insn "*movdf_no_e_insn_v9_sp32"
3218 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3219 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3223 && (register_operand (operands[0], DFmode)
3224 || register_operand (operands[1], DFmode)
3225 || fp_zero_operand (operands[1], DFmode))"
3232 [(set_attr "type" "load,store,store,*,*")
3233 (set_attr "length" "*,*,*,2,2")])
3235 ;; We have available v9 double floats but not 64-bit
3236 ;; integer registers and no VIS.
3237 (define_insn "*movdf_insn_v9only_novis"
3238 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3239 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3244 && (register_operand (operands[0], DFmode)
3245 || register_operand (operands[1], DFmode)
3246 || fp_zero_operand (operands[1], DFmode))"
3257 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3258 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3259 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3261 ;; We have available v9 double floats but not 64-bit
3262 ;; integer registers but we have VIS.
3263 (define_insn "*movdf_insn_v9only_vis"
3264 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3265 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3269 && (register_operand (operands[0], DFmode)
3270 || register_operand (operands[1], DFmode)
3271 || fp_zero_operand (operands[1], DFmode))"
3283 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3284 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3285 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3287 ;; We have available both v9 double floats and 64-bit
3288 ;; integer registers. No VIS though.
3289 (define_insn "*movdf_insn_sp64_novis"
3290 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3291 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3295 && (register_operand (operands[0], DFmode)
3296 || register_operand (operands[1], DFmode)
3297 || fp_zero_operand (operands[1], DFmode))"
3306 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3307 (set_attr "length" "*,*,*,*,*,*,2")
3308 (set_attr "fptype" "double,*,*,*,*,*,*")])
3310 ;; We have available both v9 double floats and 64-bit
3311 ;; integer registers. And we have VIS.
3312 (define_insn "*movdf_insn_sp64_vis"
3313 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3314 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3318 && (register_operand (operands[0], DFmode)
3319 || register_operand (operands[1], DFmode)
3320 || fp_zero_operand (operands[1], DFmode))"
3330 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3331 (set_attr "length" "*,*,*,*,*,*,*,2")
3332 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3334 (define_insn "*movdf_no_e_insn_sp64"
3335 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3336 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3339 && (register_operand (operands[0], DFmode)
3340 || register_operand (operands[1], DFmode)
3341 || fp_zero_operand (operands[1], DFmode))"
3346 [(set_attr "type" "*,load,store")])
3349 [(set (match_operand:DF 0 "register_operand" "")
3350 (match_operand:DF 1 "const_double_operand" ""))]
3352 && (GET_CODE (operands[0]) == REG
3353 && REGNO (operands[0]) < 32)
3354 && ! fp_zero_operand(operands[1], DFmode)
3355 && reload_completed"
3356 [(clobber (const_int 0))]
3362 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3363 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3364 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3368 #if HOST_BITS_PER_WIDE_INT == 64
3371 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3372 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3373 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3375 emit_insn (gen_movdi (operands[0],
3376 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3381 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3384 /* Slick... but this trick loses if this subreg constant part
3385 can be done in one insn. */
3387 && !(SPARC_SETHI_P (l[0])
3388 || SPARC_SIMM13_P (l[0])))
3390 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3391 gen_highpart (SImode, operands[0])));
3395 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3402 ;; Ok, now the splits to handle all the multi insn and
3403 ;; mis-aligned memory address cases.
3404 ;; In these splits please take note that we must be
3405 ;; careful when V9 but not ARCH64 because the integer
3406 ;; register DFmode cases must be handled.
3408 [(set (match_operand:DF 0 "register_operand" "")
3409 (match_operand:DF 1 "register_operand" ""))]
3412 && ((GET_CODE (operands[0]) == REG
3413 && REGNO (operands[0]) < 32)
3414 || (GET_CODE (operands[0]) == SUBREG
3415 && GET_CODE (SUBREG_REG (operands[0])) == REG
3416 && REGNO (SUBREG_REG (operands[0])) < 32))))
3417 && reload_completed"
3418 [(clobber (const_int 0))]
3421 rtx set_dest = operands[0];
3422 rtx set_src = operands[1];
3426 dest1 = gen_highpart (SFmode, set_dest);
3427 dest2 = gen_lowpart (SFmode, set_dest);
3428 src1 = gen_highpart (SFmode, set_src);
3429 src2 = gen_lowpart (SFmode, set_src);
3431 /* Now emit using the real source and destination we found, swapping
3432 the order if we detect overlap. */
3433 if (reg_overlap_mentioned_p (dest1, src2))
3435 emit_insn (gen_movsf (dest2, src2));
3436 emit_insn (gen_movsf (dest1, src1));
3440 emit_insn (gen_movsf (dest1, src1));
3441 emit_insn (gen_movsf (dest2, src2));
3447 [(set (match_operand:DF 0 "register_operand" "")
3448 (match_operand:DF 1 "memory_operand" ""))]
3451 && (((REGNO (operands[0]) % 2) != 0)
3452 || ! mem_min_alignment (operands[1], 8))
3453 && offsettable_memref_p (operands[1])"
3454 [(clobber (const_int 0))]
3457 rtx word0 = adjust_address (operands[1], SFmode, 0);
3458 rtx word1 = adjust_address (operands[1], SFmode, 4);
3460 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3462 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3464 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3469 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3471 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3478 [(set (match_operand:DF 0 "memory_operand" "")
3479 (match_operand:DF 1 "register_operand" ""))]
3482 && (((REGNO (operands[1]) % 2) != 0)
3483 || ! mem_min_alignment (operands[0], 8))
3484 && offsettable_memref_p (operands[0])"
3485 [(clobber (const_int 0))]
3488 rtx word0 = adjust_address (operands[0], SFmode, 0);
3489 rtx word1 = adjust_address (operands[0], SFmode, 4);
3491 emit_insn (gen_movsf (word0,
3492 gen_highpart (SFmode, operands[1])));
3493 emit_insn (gen_movsf (word1,
3494 gen_lowpart (SFmode, operands[1])));
3499 [(set (match_operand:DF 0 "memory_operand" "")
3500 (match_operand:DF 1 "fp_zero_operand" ""))]
3504 && ! mem_min_alignment (operands[0], 8)))
3505 && offsettable_memref_p (operands[0])"
3506 [(clobber (const_int 0))]
3511 dest1 = adjust_address (operands[0], SFmode, 0);
3512 dest2 = adjust_address (operands[0], SFmode, 4);
3514 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3515 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3520 [(set (match_operand:DF 0 "register_operand" "")
3521 (match_operand:DF 1 "fp_zero_operand" ""))]
3524 && ((GET_CODE (operands[0]) == REG
3525 && REGNO (operands[0]) < 32)
3526 || (GET_CODE (operands[0]) == SUBREG
3527 && GET_CODE (SUBREG_REG (operands[0])) == REG
3528 && REGNO (SUBREG_REG (operands[0])) < 32))"
3529 [(clobber (const_int 0))]
3532 rtx set_dest = operands[0];
3535 dest1 = gen_highpart (SFmode, set_dest);
3536 dest2 = gen_lowpart (SFmode, set_dest);
3537 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3538 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3542 (define_expand "movtf"
3543 [(set (match_operand:TF 0 "general_operand" "")
3544 (match_operand:TF 1 "general_operand" ""))]
3548 /* Force TFmode constants into memory. */
3549 if (GET_CODE (operands[0]) == REG
3550 && CONSTANT_P (operands[1]))
3552 /* emit_group_store will send such bogosity to us when it is
3553 not storing directly into memory. So fix this up to avoid
3554 crashes in output_constant_pool. */
3555 if (operands [1] == const0_rtx)
3556 operands[1] = CONST0_RTX (TFmode);
3558 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3561 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3565 /* Handle MEM cases first, note that only v9 guarentees
3566 full 16-byte alignment for quads. */
3567 if (GET_CODE (operands[0]) == MEM)
3569 if (register_operand (operands[1], TFmode)
3570 || fp_zero_operand (operands[1], TFmode))
3573 if (! reload_in_progress)
3575 operands[0] = validize_mem (operands[0]);
3576 operands[1] = force_reg (TFmode, operands[1]);
3580 /* Fixup PIC cases. */
3583 if (CONSTANT_P (operands[1])
3584 && pic_address_needs_scratch (operands[1]))
3585 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3587 if (symbolic_operand (operands[1], TFmode))
3589 operands[1] = legitimize_pic_address (operands[1],
3591 (reload_in_progress ?
3601 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3602 ;; we must split them all. :-(
3603 (define_insn "*movtf_insn_sp32"
3604 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3605 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3609 && (register_operand (operands[0], TFmode)
3610 || register_operand (operands[1], TFmode)
3611 || fp_zero_operand (operands[1], TFmode))"
3613 [(set_attr "length" "4")])
3615 (define_insn "*movtf_insn_vis_sp32"
3616 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3617 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3621 && (register_operand (operands[0], TFmode)
3622 || register_operand (operands[1], TFmode)
3623 || fp_zero_operand (operands[1], TFmode))"
3625 [(set_attr "length" "4")])
3627 ;; Exactly the same as above, except that all `e' cases are deleted.
3628 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3631 (define_insn "*movtf_no_e_insn_sp32"
3632 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3633 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3636 && (register_operand (operands[0], TFmode)
3637 || register_operand (operands[1], TFmode)
3638 || fp_zero_operand (operands[1], TFmode))"
3640 [(set_attr "length" "4")])
3642 ;; Now handle the float reg cases directly when arch64,
3643 ;; hard_quad, and proper reg number alignment are all true.
3644 (define_insn "*movtf_insn_hq_sp64"
3645 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3646 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3651 && (register_operand (operands[0], TFmode)
3652 || register_operand (operands[1], TFmode)
3653 || fp_zero_operand (operands[1], TFmode))"
3660 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3661 (set_attr "length" "*,*,*,2,2")])
3663 (define_insn "*movtf_insn_hq_vis_sp64"
3664 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3665 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3670 && (register_operand (operands[0], TFmode)
3671 || register_operand (operands[1], TFmode)
3672 || fp_zero_operand (operands[1], TFmode))"
3680 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3681 (set_attr "length" "*,*,*,2,2,2")])
3683 ;; Now we allow the integer register cases even when
3684 ;; only arch64 is true.
3685 (define_insn "*movtf_insn_sp64"
3686 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3687 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3691 && ! TARGET_HARD_QUAD
3692 && (register_operand (operands[0], TFmode)
3693 || register_operand (operands[1], TFmode)
3694 || fp_zero_operand (operands[1], TFmode))"
3696 [(set_attr "length" "2")])
3698 (define_insn "*movtf_insn_vis_sp64"
3699 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3700 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3704 && ! TARGET_HARD_QUAD
3705 && (register_operand (operands[0], TFmode)
3706 || register_operand (operands[1], TFmode)
3707 || fp_zero_operand (operands[1], TFmode))"
3709 [(set_attr "length" "2")])
3711 (define_insn "*movtf_no_e_insn_sp64"
3712 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3713 (match_operand:TF 1 "input_operand" "orG,rG"))]
3716 && (register_operand (operands[0], TFmode)
3717 || register_operand (operands[1], TFmode)
3718 || fp_zero_operand (operands[1], TFmode))"
3720 [(set_attr "length" "2")])
3722 ;; Now all the splits to handle multi-insn TF mode moves.
3724 [(set (match_operand:TF 0 "register_operand" "")
3725 (match_operand:TF 1 "register_operand" ""))]
3729 && ! TARGET_HARD_QUAD))"
3730 [(clobber (const_int 0))]
3733 rtx set_dest = operands[0];
3734 rtx set_src = operands[1];
3738 dest1 = gen_df_reg (set_dest, 0);
3739 dest2 = gen_df_reg (set_dest, 1);
3740 src1 = gen_df_reg (set_src, 0);
3741 src2 = gen_df_reg (set_src, 1);
3743 /* Now emit using the real source and destination we found, swapping
3744 the order if we detect overlap. */
3745 if (reg_overlap_mentioned_p (dest1, src2))
3747 emit_insn (gen_movdf (dest2, src2));
3748 emit_insn (gen_movdf (dest1, src1));
3752 emit_insn (gen_movdf (dest1, src1));
3753 emit_insn (gen_movdf (dest2, src2));
3759 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3760 (match_operand:TF 1 "fp_zero_operand" ""))]
3762 [(clobber (const_int 0))]
3765 rtx set_dest = operands[0];
3768 switch (GET_CODE (set_dest))
3771 dest1 = gen_df_reg (set_dest, 0);
3772 dest2 = gen_df_reg (set_dest, 1);
3775 dest1 = adjust_address (set_dest, DFmode, 0);
3776 dest2 = adjust_address (set_dest, DFmode, 8);
3782 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3783 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3788 [(set (match_operand:TF 0 "register_operand" "")
3789 (match_operand:TF 1 "memory_operand" ""))]
3791 && offsettable_memref_p (operands[1]))"
3792 [(clobber (const_int 0))]
3795 rtx word0 = adjust_address (operands[1], DFmode, 0);
3796 rtx word1 = adjust_address (operands[1], DFmode, 8);
3797 rtx set_dest, dest1, dest2;
3799 set_dest = operands[0];
3801 dest1 = gen_df_reg (set_dest, 0);
3802 dest2 = gen_df_reg (set_dest, 1);
3804 /* Now output, ordering such that we don't clobber any registers
3805 mentioned in the address. */
3806 if (reg_overlap_mentioned_p (dest1, word1))
3809 emit_insn (gen_movdf (dest2, word1));
3810 emit_insn (gen_movdf (dest1, word0));
3814 emit_insn (gen_movdf (dest1, word0));
3815 emit_insn (gen_movdf (dest2, word1));
3821 [(set (match_operand:TF 0 "memory_operand" "")
3822 (match_operand:TF 1 "register_operand" ""))]
3824 && offsettable_memref_p (operands[0]))"
3825 [(clobber (const_int 0))]
3828 rtx set_src = operands[1];
3830 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3831 gen_df_reg (set_src, 0)));
3832 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3833 gen_df_reg (set_src, 1)));
3837 ;; Sparc V9 conditional move instructions.
3839 ;; We can handle larger constants here for some flavors, but for now we keep
3840 ;; it simple and only allow those constants supported by all flavours.
3841 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3842 ;; 3 contains the constant if one is present, but we handle either for
3843 ;; generality (sparc.c puts a constant in operand 2).
3845 (define_expand "movqicc"
3846 [(set (match_operand:QI 0 "register_operand" "")
3847 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3848 (match_operand:QI 2 "arith10_operand" "")
3849 (match_operand:QI 3 "arith10_operand" "")))]
3853 enum rtx_code code = GET_CODE (operands[1]);
3855 if (GET_MODE (sparc_compare_op0) == DImode
3859 if (sparc_compare_op1 == const0_rtx
3860 && GET_CODE (sparc_compare_op0) == REG
3861 && GET_MODE (sparc_compare_op0) == DImode
3862 && v9_regcmp_p (code))
3864 operands[1] = gen_rtx_fmt_ee (code, DImode,
3865 sparc_compare_op0, sparc_compare_op1);
3869 rtx cc_reg = gen_compare_reg (code,
3870 sparc_compare_op0, sparc_compare_op1);
3871 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3875 (define_expand "movhicc"
3876 [(set (match_operand:HI 0 "register_operand" "")
3877 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3878 (match_operand:HI 2 "arith10_operand" "")
3879 (match_operand:HI 3 "arith10_operand" "")))]
3883 enum rtx_code code = GET_CODE (operands[1]);
3885 if (GET_MODE (sparc_compare_op0) == DImode
3889 if (sparc_compare_op1 == const0_rtx
3890 && GET_CODE (sparc_compare_op0) == REG
3891 && GET_MODE (sparc_compare_op0) == DImode
3892 && v9_regcmp_p (code))
3894 operands[1] = gen_rtx_fmt_ee (code, DImode,
3895 sparc_compare_op0, sparc_compare_op1);
3899 rtx cc_reg = gen_compare_reg (code,
3900 sparc_compare_op0, sparc_compare_op1);
3901 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3905 (define_expand "movsicc"
3906 [(set (match_operand:SI 0 "register_operand" "")
3907 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3908 (match_operand:SI 2 "arith10_operand" "")
3909 (match_operand:SI 3 "arith10_operand" "")))]
3913 enum rtx_code code = GET_CODE (operands[1]);
3914 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3916 if (sparc_compare_op1 == const0_rtx
3917 && GET_CODE (sparc_compare_op0) == REG
3918 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3920 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3921 sparc_compare_op0, sparc_compare_op1);
3925 rtx cc_reg = gen_compare_reg (code,
3926 sparc_compare_op0, sparc_compare_op1);
3927 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3928 cc_reg, const0_rtx);
3932 (define_expand "movdicc"
3933 [(set (match_operand:DI 0 "register_operand" "")
3934 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3935 (match_operand:DI 2 "arith10_double_operand" "")
3936 (match_operand:DI 3 "arith10_double_operand" "")))]
3940 enum rtx_code code = GET_CODE (operands[1]);
3942 if (sparc_compare_op1 == const0_rtx
3943 && GET_CODE (sparc_compare_op0) == REG
3944 && GET_MODE (sparc_compare_op0) == DImode
3945 && v9_regcmp_p (code))
3947 operands[1] = gen_rtx_fmt_ee (code, DImode,
3948 sparc_compare_op0, sparc_compare_op1);
3952 rtx cc_reg = gen_compare_reg (code,
3953 sparc_compare_op0, sparc_compare_op1);
3954 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3955 cc_reg, const0_rtx);
3959 (define_expand "movsfcc"
3960 [(set (match_operand:SF 0 "register_operand" "")
3961 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3962 (match_operand:SF 2 "register_operand" "")
3963 (match_operand:SF 3 "register_operand" "")))]
3964 "TARGET_V9 && TARGET_FPU"
3967 enum rtx_code code = GET_CODE (operands[1]);
3969 if (GET_MODE (sparc_compare_op0) == DImode
3973 if (sparc_compare_op1 == const0_rtx
3974 && GET_CODE (sparc_compare_op0) == REG
3975 && GET_MODE (sparc_compare_op0) == DImode
3976 && v9_regcmp_p (code))
3978 operands[1] = gen_rtx_fmt_ee (code, DImode,
3979 sparc_compare_op0, sparc_compare_op1);
3983 rtx cc_reg = gen_compare_reg (code,
3984 sparc_compare_op0, sparc_compare_op1);
3985 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3989 (define_expand "movdfcc"
3990 [(set (match_operand:DF 0 "register_operand" "")
3991 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3992 (match_operand:DF 2 "register_operand" "")
3993 (match_operand:DF 3 "register_operand" "")))]
3994 "TARGET_V9 && TARGET_FPU"
3997 enum rtx_code code = GET_CODE (operands[1]);
3999 if (GET_MODE (sparc_compare_op0) == DImode
4003 if (sparc_compare_op1 == const0_rtx
4004 && GET_CODE (sparc_compare_op0) == REG
4005 && GET_MODE (sparc_compare_op0) == DImode
4006 && v9_regcmp_p (code))
4008 operands[1] = gen_rtx_fmt_ee (code, DImode,
4009 sparc_compare_op0, sparc_compare_op1);
4013 rtx cc_reg = gen_compare_reg (code,
4014 sparc_compare_op0, sparc_compare_op1);
4015 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4019 (define_expand "movtfcc"
4020 [(set (match_operand:TF 0 "register_operand" "")
4021 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4022 (match_operand:TF 2 "register_operand" "")
4023 (match_operand:TF 3 "register_operand" "")))]
4024 "TARGET_V9 && TARGET_FPU"
4027 enum rtx_code code = GET_CODE (operands[1]);
4029 if (GET_MODE (sparc_compare_op0) == DImode
4033 if (sparc_compare_op1 == const0_rtx
4034 && GET_CODE (sparc_compare_op0) == REG
4035 && GET_MODE (sparc_compare_op0) == DImode
4036 && v9_regcmp_p (code))
4038 operands[1] = gen_rtx_fmt_ee (code, DImode,
4039 sparc_compare_op0, sparc_compare_op1);
4043 rtx cc_reg = gen_compare_reg (code,
4044 sparc_compare_op0, sparc_compare_op1);
4045 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4049 ;; Conditional move define_insns.
4051 (define_insn "*movqi_cc_sp64"
4052 [(set (match_operand:QI 0 "register_operand" "=r,r")
4053 (if_then_else:QI (match_operator 1 "comparison_operator"
4054 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4056 (match_operand:QI 3 "arith11_operand" "rL,0")
4057 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4060 mov%C1\\t%x2, %3, %0
4061 mov%c1\\t%x2, %4, %0"
4062 [(set_attr "type" "cmove")])
4064 (define_insn "*movhi_cc_sp64"
4065 [(set (match_operand:HI 0 "register_operand" "=r,r")
4066 (if_then_else:HI (match_operator 1 "comparison_operator"
4067 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4069 (match_operand:HI 3 "arith11_operand" "rL,0")
4070 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4073 mov%C1\\t%x2, %3, %0
4074 mov%c1\\t%x2, %4, %0"
4075 [(set_attr "type" "cmove")])
4077 (define_insn "*movsi_cc_sp64"
4078 [(set (match_operand:SI 0 "register_operand" "=r,r")
4079 (if_then_else:SI (match_operator 1 "comparison_operator"
4080 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4082 (match_operand:SI 3 "arith11_operand" "rL,0")
4083 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4086 mov%C1\\t%x2, %3, %0
4087 mov%c1\\t%x2, %4, %0"
4088 [(set_attr "type" "cmove")])
4090 ;; ??? The constraints of operands 3,4 need work.
4091 (define_insn "*movdi_cc_sp64"
4092 [(set (match_operand:DI 0 "register_operand" "=r,r")
4093 (if_then_else:DI (match_operator 1 "comparison_operator"
4094 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4096 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4097 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4100 mov%C1\\t%x2, %3, %0
4101 mov%c1\\t%x2, %4, %0"
4102 [(set_attr "type" "cmove")])
4104 (define_insn "*movdi_cc_sp64_trunc"
4105 [(set (match_operand:SI 0 "register_operand" "=r,r")
4106 (if_then_else:SI (match_operator 1 "comparison_operator"
4107 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4109 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4110 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4113 mov%C1\\t%x2, %3, %0
4114 mov%c1\\t%x2, %4, %0"
4115 [(set_attr "type" "cmove")])
4117 (define_insn "*movsf_cc_sp64"
4118 [(set (match_operand:SF 0 "register_operand" "=f,f")
4119 (if_then_else:SF (match_operator 1 "comparison_operator"
4120 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4122 (match_operand:SF 3 "register_operand" "f,0")
4123 (match_operand:SF 4 "register_operand" "0,f")))]
4124 "TARGET_V9 && TARGET_FPU"
4126 fmovs%C1\\t%x2, %3, %0
4127 fmovs%c1\\t%x2, %4, %0"
4128 [(set_attr "type" "fpcmove")])
4130 (define_insn "movdf_cc_sp64"
4131 [(set (match_operand:DF 0 "register_operand" "=e,e")
4132 (if_then_else:DF (match_operator 1 "comparison_operator"
4133 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4135 (match_operand:DF 3 "register_operand" "e,0")
4136 (match_operand:DF 4 "register_operand" "0,e")))]
4137 "TARGET_V9 && TARGET_FPU"
4139 fmovd%C1\\t%x2, %3, %0
4140 fmovd%c1\\t%x2, %4, %0"
4141 [(set_attr "type" "fpcmove")
4142 (set_attr "fptype" "double")])
4144 (define_insn "*movtf_cc_hq_sp64"
4145 [(set (match_operand:TF 0 "register_operand" "=e,e")
4146 (if_then_else:TF (match_operator 1 "comparison_operator"
4147 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4149 (match_operand:TF 3 "register_operand" "e,0")
4150 (match_operand:TF 4 "register_operand" "0,e")))]
4151 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4153 fmovq%C1\\t%x2, %3, %0
4154 fmovq%c1\\t%x2, %4, %0"
4155 [(set_attr "type" "fpcmove")])
4157 (define_insn "*movtf_cc_sp64"
4158 [(set (match_operand:TF 0 "register_operand" "=e,e")
4159 (if_then_else:TF (match_operator 1 "comparison_operator"
4160 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4162 (match_operand:TF 3 "register_operand" "e,0")
4163 (match_operand:TF 4 "register_operand" "0,e")))]
4164 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4166 [(set_attr "length" "2")])
4169 [(set (match_operand:TF 0 "register_operand" "")
4170 (if_then_else:TF (match_operator 1 "comparison_operator"
4171 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4173 (match_operand:TF 3 "register_operand" "")
4174 (match_operand:TF 4 "register_operand" "")))]
4175 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4176 [(clobber (const_int 0))]
4179 rtx set_dest = operands[0];
4180 rtx set_srca = operands[3];
4181 rtx set_srcb = operands[4];
4182 int third = rtx_equal_p (set_dest, set_srca);
4184 rtx srca1, srca2, srcb1, srcb2;
4186 dest1 = gen_df_reg (set_dest, 0);
4187 dest2 = gen_df_reg (set_dest, 1);
4188 srca1 = gen_df_reg (set_srca, 0);
4189 srca2 = gen_df_reg (set_srca, 1);
4190 srcb1 = gen_df_reg (set_srcb, 0);
4191 srcb2 = gen_df_reg (set_srcb, 1);
4193 /* Now emit using the real source and destination we found, swapping
4194 the order if we detect overlap. */
4195 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4196 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4198 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4199 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4203 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4204 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4209 (define_insn "*movqi_cc_reg_sp64"
4210 [(set (match_operand:QI 0 "register_operand" "=r,r")
4211 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4212 [(match_operand:DI 2 "register_operand" "r,r")
4214 (match_operand:QI 3 "arith10_operand" "rM,0")
4215 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4218 movr%D1\\t%2, %r3, %0
4219 movr%d1\\t%2, %r4, %0"
4220 [(set_attr "type" "cmove")])
4222 (define_insn "*movhi_cc_reg_sp64"
4223 [(set (match_operand:HI 0 "register_operand" "=r,r")
4224 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4225 [(match_operand:DI 2 "register_operand" "r,r")
4227 (match_operand:HI 3 "arith10_operand" "rM,0")
4228 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4231 movr%D1\\t%2, %r3, %0
4232 movr%d1\\t%2, %r4, %0"
4233 [(set_attr "type" "cmove")])
4235 (define_insn "*movsi_cc_reg_sp64"
4236 [(set (match_operand:SI 0 "register_operand" "=r,r")
4237 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4238 [(match_operand:DI 2 "register_operand" "r,r")
4240 (match_operand:SI 3 "arith10_operand" "rM,0")
4241 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4244 movr%D1\\t%2, %r3, %0
4245 movr%d1\\t%2, %r4, %0"
4246 [(set_attr "type" "cmove")])
4248 ;; ??? The constraints of operands 3,4 need work.
4249 (define_insn "*movdi_cc_reg_sp64"
4250 [(set (match_operand:DI 0 "register_operand" "=r,r")
4251 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4252 [(match_operand:DI 2 "register_operand" "r,r")
4254 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4255 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4258 movr%D1\\t%2, %r3, %0
4259 movr%d1\\t%2, %r4, %0"
4260 [(set_attr "type" "cmove")])
4262 (define_insn "*movdi_cc_reg_sp64_trunc"
4263 [(set (match_operand:SI 0 "register_operand" "=r,r")
4264 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4265 [(match_operand:DI 2 "register_operand" "r,r")
4267 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4268 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4271 movr%D1\\t%2, %r3, %0
4272 movr%d1\\t%2, %r4, %0"
4273 [(set_attr "type" "cmove")])
4275 (define_insn "*movsf_cc_reg_sp64"
4276 [(set (match_operand:SF 0 "register_operand" "=f,f")
4277 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4278 [(match_operand:DI 2 "register_operand" "r,r")
4280 (match_operand:SF 3 "register_operand" "f,0")
4281 (match_operand:SF 4 "register_operand" "0,f")))]
4282 "TARGET_ARCH64 && TARGET_FPU"
4284 fmovrs%D1\\t%2, %3, %0
4285 fmovrs%d1\\t%2, %4, %0"
4286 [(set_attr "type" "fpcmove")])
4288 (define_insn "movdf_cc_reg_sp64"
4289 [(set (match_operand:DF 0 "register_operand" "=e,e")
4290 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4291 [(match_operand:DI 2 "register_operand" "r,r")
4293 (match_operand:DF 3 "register_operand" "e,0")
4294 (match_operand:DF 4 "register_operand" "0,e")))]
4295 "TARGET_ARCH64 && TARGET_FPU"
4297 fmovrd%D1\\t%2, %3, %0
4298 fmovrd%d1\\t%2, %4, %0"
4299 [(set_attr "type" "fpcmove")
4300 (set_attr "fptype" "double")])
4302 (define_insn "*movtf_cc_reg_hq_sp64"
4303 [(set (match_operand:TF 0 "register_operand" "=e,e")
4304 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4305 [(match_operand:DI 2 "register_operand" "r,r")
4307 (match_operand:TF 3 "register_operand" "e,0")
4308 (match_operand:TF 4 "register_operand" "0,e")))]
4309 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4311 fmovrq%D1\\t%2, %3, %0
4312 fmovrq%d1\\t%2, %4, %0"
4313 [(set_attr "type" "fpcmove")])
4315 (define_insn "*movtf_cc_reg_sp64"
4316 [(set (match_operand:TF 0 "register_operand" "=e,e")
4317 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4318 [(match_operand:DI 2 "register_operand" "r,r")
4320 (match_operand:TF 3 "register_operand" "e,0")
4321 (match_operand:TF 4 "register_operand" "0,e")))]
4322 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4324 [(set_attr "length" "2")])
4327 [(set (match_operand:TF 0 "register_operand" "")
4328 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4329 [(match_operand:DI 2 "register_operand" "")
4331 (match_operand:TF 3 "register_operand" "")
4332 (match_operand:TF 4 "register_operand" "")))]
4333 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4334 [(clobber (const_int 0))]
4337 rtx set_dest = operands[0];
4338 rtx set_srca = operands[3];
4339 rtx set_srcb = operands[4];
4340 int third = rtx_equal_p (set_dest, set_srca);
4342 rtx srca1, srca2, srcb1, srcb2;
4344 dest1 = gen_df_reg (set_dest, 0);
4345 dest2 = gen_df_reg (set_dest, 1);
4346 srca1 = gen_df_reg (set_srca, 0);
4347 srca2 = gen_df_reg (set_srca, 1);
4348 srcb1 = gen_df_reg (set_srcb, 0);
4349 srcb2 = gen_df_reg (set_srcb, 1);
4351 /* Now emit using the real source and destination we found, swapping
4352 the order if we detect overlap. */
4353 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4354 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4356 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4357 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4361 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4362 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4368 ;;- zero extension instructions
4370 ;; These patterns originally accepted general_operands, however, slightly
4371 ;; better code is generated by only accepting register_operands, and then
4372 ;; letting combine generate the ldu[hb] insns.
4374 (define_expand "zero_extendhisi2"
4375 [(set (match_operand:SI 0 "register_operand" "")
4376 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4380 rtx temp = gen_reg_rtx (SImode);
4381 rtx shift_16 = GEN_INT (16);
4382 int op1_subbyte = 0;
4384 if (GET_CODE (operand1) == SUBREG)
4386 op1_subbyte = SUBREG_BYTE (operand1);
4387 op1_subbyte /= GET_MODE_SIZE (SImode);
4388 op1_subbyte *= GET_MODE_SIZE (SImode);
4389 operand1 = XEXP (operand1, 0);
4392 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4394 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4398 (define_insn "*zero_extendhisi2_insn"
4399 [(set (match_operand:SI 0 "register_operand" "=r")
4400 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4403 [(set_attr "type" "load")])
4405 (define_expand "zero_extendqihi2"
4406 [(set (match_operand:HI 0 "register_operand" "")
4407 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4411 (define_insn "*zero_extendqihi2_insn"
4412 [(set (match_operand:HI 0 "register_operand" "=r,r")
4413 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4414 "GET_CODE (operands[1]) != CONST_INT"
4418 [(set_attr "type" "*,load")])
4420 (define_expand "zero_extendqisi2"
4421 [(set (match_operand:SI 0 "register_operand" "")
4422 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4426 (define_insn "*zero_extendqisi2_insn"
4427 [(set (match_operand:SI 0 "register_operand" "=r,r")
4428 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4429 "GET_CODE (operands[1]) != CONST_INT"
4433 [(set_attr "type" "*,load")])
4435 (define_expand "zero_extendqidi2"
4436 [(set (match_operand:DI 0 "register_operand" "")
4437 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4441 (define_insn "*zero_extendqidi2_insn"
4442 [(set (match_operand:DI 0 "register_operand" "=r,r")
4443 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4444 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4448 [(set_attr "type" "*,load")])
4450 (define_expand "zero_extendhidi2"
4451 [(set (match_operand:DI 0 "register_operand" "")
4452 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4456 rtx temp = gen_reg_rtx (DImode);
4457 rtx shift_48 = GEN_INT (48);
4458 int op1_subbyte = 0;
4460 if (GET_CODE (operand1) == SUBREG)
4462 op1_subbyte = SUBREG_BYTE (operand1);
4463 op1_subbyte /= GET_MODE_SIZE (DImode);
4464 op1_subbyte *= GET_MODE_SIZE (DImode);
4465 operand1 = XEXP (operand1, 0);
4468 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4470 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4474 (define_insn "*zero_extendhidi2_insn"
4475 [(set (match_operand:DI 0 "register_operand" "=r")
4476 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4479 [(set_attr "type" "load")])
4482 ;; ??? Write truncdisi pattern using sra?
4484 (define_expand "zero_extendsidi2"
4485 [(set (match_operand:DI 0 "register_operand" "")
4486 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4490 (define_insn "*zero_extendsidi2_insn_sp64"
4491 [(set (match_operand:DI 0 "register_operand" "=r,r")
4492 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4493 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4497 [(set_attr "type" "shift,load")])
4499 (define_insn "*zero_extendsidi2_insn_sp32"
4500 [(set (match_operand:DI 0 "register_operand" "=r")
4501 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4504 [(set_attr "length" "2")])
4507 [(set (match_operand:DI 0 "register_operand" "")
4508 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4509 "! TARGET_ARCH64 && reload_completed"
4510 [(set (match_dup 2) (match_dup 3))
4511 (set (match_dup 4) (match_dup 5))]
4516 dest1 = gen_highpart (SImode, operands[0]);
4517 dest2 = gen_lowpart (SImode, operands[0]);
4519 /* Swap the order in case of overlap. */
4520 if (REGNO (dest1) == REGNO (operands[1]))
4522 operands[2] = dest2;
4523 operands[3] = operands[1];
4524 operands[4] = dest1;
4525 operands[5] = const0_rtx;
4529 operands[2] = dest1;
4530 operands[3] = const0_rtx;
4531 operands[4] = dest2;
4532 operands[5] = operands[1];
4536 ;; Simplify comparisons of extended values.
4538 (define_insn "*cmp_zero_extendqisi2"
4540 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4543 "andcc\\t%0, 0xff, %%g0"
4544 [(set_attr "type" "compare")])
4546 (define_insn "*cmp_zero_qi"
4548 (compare:CC (match_operand:QI 0 "register_operand" "r")
4551 "andcc\\t%0, 0xff, %%g0"
4552 [(set_attr "type" "compare")])
4554 (define_insn "*cmp_zero_extendqisi2_set"
4556 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4558 (set (match_operand:SI 0 "register_operand" "=r")
4559 (zero_extend:SI (match_dup 1)))]
4561 "andcc\\t%1, 0xff, %0"
4562 [(set_attr "type" "compare")])
4564 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4566 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4569 (set (match_operand:SI 0 "register_operand" "=r")
4570 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4572 "andcc\\t%1, 0xff, %0"
4573 [(set_attr "type" "compare")])
4575 (define_insn "*cmp_zero_extendqidi2"
4577 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4580 "andcc\\t%0, 0xff, %%g0"
4581 [(set_attr "type" "compare")])
4583 (define_insn "*cmp_zero_qi_sp64"
4585 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4588 "andcc\\t%0, 0xff, %%g0"
4589 [(set_attr "type" "compare")])
4591 (define_insn "*cmp_zero_extendqidi2_set"
4593 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4595 (set (match_operand:DI 0 "register_operand" "=r")
4596 (zero_extend:DI (match_dup 1)))]
4598 "andcc\\t%1, 0xff, %0"
4599 [(set_attr "type" "compare")])
4601 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4603 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4606 (set (match_operand:DI 0 "register_operand" "=r")
4607 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4609 "andcc\\t%1, 0xff, %0"
4610 [(set_attr "type" "compare")])
4612 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4614 (define_insn "*cmp_siqi_trunc"
4616 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4619 "andcc\\t%0, 0xff, %%g0"
4620 [(set_attr "type" "compare")])
4622 (define_insn "*cmp_siqi_trunc_set"
4624 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4626 (set (match_operand:QI 0 "register_operand" "=r")
4627 (subreg:QI (match_dup 1) 3))]
4629 "andcc\\t%1, 0xff, %0"
4630 [(set_attr "type" "compare")])
4632 (define_insn "*cmp_diqi_trunc"
4634 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4637 "andcc\\t%0, 0xff, %%g0"
4638 [(set_attr "type" "compare")])
4640 (define_insn "*cmp_diqi_trunc_set"
4642 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4644 (set (match_operand:QI 0 "register_operand" "=r")
4645 (subreg:QI (match_dup 1) 7))]
4647 "andcc\\t%1, 0xff, %0"
4648 [(set_attr "type" "compare")])
4650 ;;- sign extension instructions
4652 ;; These patterns originally accepted general_operands, however, slightly
4653 ;; better code is generated by only accepting register_operands, and then
4654 ;; letting combine generate the lds[hb] insns.
4656 (define_expand "extendhisi2"
4657 [(set (match_operand:SI 0 "register_operand" "")
4658 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4662 rtx temp = gen_reg_rtx (SImode);
4663 rtx shift_16 = GEN_INT (16);
4664 int op1_subbyte = 0;
4666 if (GET_CODE (operand1) == SUBREG)
4668 op1_subbyte = SUBREG_BYTE (operand1);
4669 op1_subbyte /= GET_MODE_SIZE (SImode);
4670 op1_subbyte *= GET_MODE_SIZE (SImode);
4671 operand1 = XEXP (operand1, 0);
4674 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4676 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4680 (define_insn "*sign_extendhisi2_insn"
4681 [(set (match_operand:SI 0 "register_operand" "=r")
4682 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4685 [(set_attr "type" "sload")])
4687 (define_expand "extendqihi2"
4688 [(set (match_operand:HI 0 "register_operand" "")
4689 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4693 rtx temp = gen_reg_rtx (SImode);
4694 rtx shift_24 = GEN_INT (24);
4695 int op1_subbyte = 0;
4696 int op0_subbyte = 0;
4698 if (GET_CODE (operand1) == SUBREG)
4700 op1_subbyte = SUBREG_BYTE (operand1);
4701 op1_subbyte /= GET_MODE_SIZE (SImode);
4702 op1_subbyte *= GET_MODE_SIZE (SImode);
4703 operand1 = XEXP (operand1, 0);
4705 if (GET_CODE (operand0) == SUBREG)
4707 op0_subbyte = SUBREG_BYTE (operand0);
4708 op0_subbyte /= GET_MODE_SIZE (SImode);
4709 op0_subbyte *= GET_MODE_SIZE (SImode);
4710 operand0 = XEXP (operand0, 0);
4712 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4714 if (GET_MODE (operand0) != SImode)
4715 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4716 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4720 (define_insn "*sign_extendqihi2_insn"
4721 [(set (match_operand:HI 0 "register_operand" "=r")
4722 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4725 [(set_attr "type" "sload")])
4727 (define_expand "extendqisi2"
4728 [(set (match_operand:SI 0 "register_operand" "")
4729 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4733 rtx temp = gen_reg_rtx (SImode);
4734 rtx shift_24 = GEN_INT (24);
4735 int op1_subbyte = 0;
4737 if (GET_CODE (operand1) == SUBREG)
4739 op1_subbyte = SUBREG_BYTE (operand1);
4740 op1_subbyte /= GET_MODE_SIZE (SImode);
4741 op1_subbyte *= GET_MODE_SIZE (SImode);
4742 operand1 = XEXP (operand1, 0);
4745 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4747 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4751 (define_insn "*sign_extendqisi2_insn"
4752 [(set (match_operand:SI 0 "register_operand" "=r")
4753 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4756 [(set_attr "type" "sload")])
4758 (define_expand "extendqidi2"
4759 [(set (match_operand:DI 0 "register_operand" "")
4760 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4764 rtx temp = gen_reg_rtx (DImode);
4765 rtx shift_56 = GEN_INT (56);
4766 int op1_subbyte = 0;
4768 if (GET_CODE (operand1) == SUBREG)
4770 op1_subbyte = SUBREG_BYTE (operand1);
4771 op1_subbyte /= GET_MODE_SIZE (DImode);
4772 op1_subbyte *= GET_MODE_SIZE (DImode);
4773 operand1 = XEXP (operand1, 0);
4776 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4778 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4782 (define_insn "*sign_extendqidi2_insn"
4783 [(set (match_operand:DI 0 "register_operand" "=r")
4784 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4787 [(set_attr "type" "sload")])
4789 (define_expand "extendhidi2"
4790 [(set (match_operand:DI 0 "register_operand" "")
4791 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4795 rtx temp = gen_reg_rtx (DImode);
4796 rtx shift_48 = GEN_INT (48);
4797 int op1_subbyte = 0;
4799 if (GET_CODE (operand1) == SUBREG)
4801 op1_subbyte = SUBREG_BYTE (operand1);
4802 op1_subbyte /= GET_MODE_SIZE (DImode);
4803 op1_subbyte *= GET_MODE_SIZE (DImode);
4804 operand1 = XEXP (operand1, 0);
4807 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4809 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4813 (define_insn "*sign_extendhidi2_insn"
4814 [(set (match_operand:DI 0 "register_operand" "=r")
4815 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4818 [(set_attr "type" "sload")])
4820 (define_expand "extendsidi2"
4821 [(set (match_operand:DI 0 "register_operand" "")
4822 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4826 (define_insn "*sign_extendsidi2_insn"
4827 [(set (match_operand:DI 0 "register_operand" "=r,r")
4828 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4833 [(set_attr "type" "shift,sload")])
4835 ;; Special pattern for optimizing bit-field compares. This is needed
4836 ;; because combine uses this as a canonical form.
4838 (define_insn "*cmp_zero_extract"
4841 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4842 (match_operand:SI 1 "small_int_or_double" "n")
4843 (match_operand:SI 2 "small_int_or_double" "n"))
4845 "(GET_CODE (operands[2]) == CONST_INT
4846 && INTVAL (operands[2]) > 19)
4847 || (GET_CODE (operands[2]) == CONST_DOUBLE
4848 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4851 int len = (GET_CODE (operands[1]) == CONST_INT
4852 ? INTVAL (operands[1])
4853 : CONST_DOUBLE_LOW (operands[1]));
4855 (GET_CODE (operands[2]) == CONST_INT
4856 ? INTVAL (operands[2])
4857 : CONST_DOUBLE_LOW (operands[2])) - len;
4858 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4860 operands[1] = GEN_INT (mask);
4861 return \"andcc\\t%0, %1, %%g0\";
4863 [(set_attr "type" "compare")])
4865 (define_insn "*cmp_zero_extract_sp64"
4868 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4869 (match_operand:SI 1 "small_int_or_double" "n")
4870 (match_operand:SI 2 "small_int_or_double" "n"))
4873 && ((GET_CODE (operands[2]) == CONST_INT
4874 && INTVAL (operands[2]) > 51)
4875 || (GET_CODE (operands[2]) == CONST_DOUBLE
4876 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4879 int len = (GET_CODE (operands[1]) == CONST_INT
4880 ? INTVAL (operands[1])
4881 : CONST_DOUBLE_LOW (operands[1]));
4883 (GET_CODE (operands[2]) == CONST_INT
4884 ? INTVAL (operands[2])
4885 : CONST_DOUBLE_LOW (operands[2])) - len;
4886 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4888 operands[1] = GEN_INT (mask);
4889 return \"andcc\\t%0, %1, %%g0\";
4891 [(set_attr "type" "compare")])
4893 ;; Conversions between float, double and long double.
4895 (define_insn "extendsfdf2"
4896 [(set (match_operand:DF 0 "register_operand" "=e")
4898 (match_operand:SF 1 "register_operand" "f")))]
4901 [(set_attr "type" "fp")
4902 (set_attr "fptype" "double")])
4904 (define_expand "extendsftf2"
4905 [(set (match_operand:TF 0 "register_operand" "=e")
4907 (match_operand:SF 1 "register_operand" "f")))]
4908 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4911 if (! TARGET_HARD_QUAD)
4915 if (GET_CODE (operands[0]) != MEM)
4916 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4918 slot0 = operands[0];
4920 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4922 XEXP (slot0, 0), Pmode,
4923 operands[1], SFmode);
4925 if (GET_CODE (operands[0]) != MEM)
4926 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4931 (define_insn "*extendsftf2_hq"
4932 [(set (match_operand:TF 0 "register_operand" "=e")
4934 (match_operand:SF 1 "register_operand" "f")))]
4935 "TARGET_FPU && TARGET_HARD_QUAD"
4937 [(set_attr "type" "fp")])
4939 (define_expand "extenddftf2"
4940 [(set (match_operand:TF 0 "register_operand" "=e")
4942 (match_operand:DF 1 "register_operand" "e")))]
4943 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4946 if (! TARGET_HARD_QUAD)
4950 if (GET_CODE (operands[0]) != MEM)
4951 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4953 slot0 = operands[0];
4955 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
4957 XEXP (slot0, 0), Pmode,
4958 operands[1], DFmode);
4960 if (GET_CODE (operands[0]) != MEM)
4961 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4966 (define_insn "*extenddftf2_hq"
4967 [(set (match_operand:TF 0 "register_operand" "=e")
4969 (match_operand:DF 1 "register_operand" "e")))]
4970 "TARGET_FPU && TARGET_HARD_QUAD"
4972 [(set_attr "type" "fp")])
4974 (define_insn "truncdfsf2"
4975 [(set (match_operand:SF 0 "register_operand" "=f")
4977 (match_operand:DF 1 "register_operand" "e")))]
4980 [(set_attr "type" "fp")
4981 (set_attr "fptype" "double")])
4983 (define_expand "trunctfsf2"
4984 [(set (match_operand:SF 0 "register_operand" "=f")
4986 (match_operand:TF 1 "register_operand" "e")))]
4987 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4990 if (! TARGET_HARD_QUAD)
4994 if (GET_CODE (operands[1]) != MEM)
4996 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4997 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5000 slot0 = operands[1];
5002 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5003 operands[0], 0, SFmode, 1,
5004 XEXP (slot0, 0), Pmode);
5009 (define_insn "*trunctfsf2_hq"
5010 [(set (match_operand:SF 0 "register_operand" "=f")
5012 (match_operand:TF 1 "register_operand" "e")))]
5013 "TARGET_FPU && TARGET_HARD_QUAD"
5015 [(set_attr "type" "fp")])
5017 (define_expand "trunctfdf2"
5018 [(set (match_operand:DF 0 "register_operand" "=f")
5020 (match_operand:TF 1 "register_operand" "e")))]
5021 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5024 if (! TARGET_HARD_QUAD)
5028 if (GET_CODE (operands[1]) != MEM)
5030 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5031 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5034 slot0 = operands[1];
5036 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5037 operands[0], 0, DFmode, 1,
5038 XEXP (slot0, 0), Pmode);
5043 (define_insn "*trunctfdf2_hq"
5044 [(set (match_operand:DF 0 "register_operand" "=e")
5046 (match_operand:TF 1 "register_operand" "e")))]
5047 "TARGET_FPU && TARGET_HARD_QUAD"
5049 [(set_attr "type" "fp")])
5051 ;; Conversion between fixed point and floating point.
5053 (define_insn "floatsisf2"
5054 [(set (match_operand:SF 0 "register_operand" "=f")
5055 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5058 [(set_attr "type" "fp")
5059 (set_attr "fptype" "double")])
5061 (define_insn "floatsidf2"
5062 [(set (match_operand:DF 0 "register_operand" "=e")
5063 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5066 [(set_attr "type" "fp")
5067 (set_attr "fptype" "double")])
5069 (define_expand "floatsitf2"
5070 [(set (match_operand:TF 0 "register_operand" "=e")
5071 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5072 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5075 if (! TARGET_HARD_QUAD)
5079 if (GET_CODE (operands[1]) != MEM)
5080 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5082 slot0 = operands[1];
5084 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5086 XEXP (slot0, 0), Pmode,
5087 operands[1], SImode);
5089 if (GET_CODE (operands[0]) != MEM)
5090 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5095 (define_insn "*floatsitf2_hq"
5096 [(set (match_operand:TF 0 "register_operand" "=e")
5097 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5098 "TARGET_FPU && TARGET_HARD_QUAD"
5100 [(set_attr "type" "fp")])
5102 (define_expand "floatunssitf2"
5103 [(set (match_operand:TF 0 "register_operand" "=e")
5104 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5105 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5110 if (GET_CODE (operands[1]) != MEM)
5111 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5113 slot0 = operands[1];
5115 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5117 XEXP (slot0, 0), Pmode,
5118 operands[1], SImode);
5120 if (GET_CODE (operands[0]) != MEM)
5121 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5125 ;; Now the same for 64 bit sources.
5127 (define_insn "floatdisf2"
5128 [(set (match_operand:SF 0 "register_operand" "=f")
5129 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5130 "TARGET_V9 && TARGET_FPU"
5132 [(set_attr "type" "fp")
5133 (set_attr "fptype" "double")])
5135 (define_insn "floatdidf2"
5136 [(set (match_operand:DF 0 "register_operand" "=e")
5137 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5138 "TARGET_V9 && TARGET_FPU"
5140 [(set_attr "type" "fp")
5141 (set_attr "fptype" "double")])
5143 (define_expand "floatditf2"
5144 [(set (match_operand:TF 0 "register_operand" "=e")
5145 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5146 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5149 if (! TARGET_HARD_QUAD)
5153 if (GET_CODE (operands[1]) != MEM)
5154 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5156 slot0 = operands[1];
5158 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5160 XEXP (slot0, 0), Pmode,
5161 operands[1], DImode);
5163 if (GET_CODE (operands[0]) != MEM)
5164 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5169 (define_insn "*floatditf2_hq"
5170 [(set (match_operand:TF 0 "register_operand" "=e")
5171 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5172 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5174 [(set_attr "type" "fp")])
5176 (define_expand "floatunsditf2"
5177 [(set (match_operand:TF 0 "register_operand" "=e")
5178 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5179 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5184 if (GET_CODE (operands[1]) != MEM)
5185 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5187 slot0 = operands[1];
5189 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5191 XEXP (slot0, 0), Pmode,
5192 operands[1], DImode);
5194 if (GET_CODE (operands[0]) != MEM)
5195 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5199 ;; Convert a float to an actual integer.
5200 ;; Truncation is performed as part of the conversion.
5202 (define_insn "fix_truncsfsi2"
5203 [(set (match_operand:SI 0 "register_operand" "=f")
5204 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5207 [(set_attr "type" "fp")
5208 (set_attr "fptype" "double")])
5210 (define_insn "fix_truncdfsi2"
5211 [(set (match_operand:SI 0 "register_operand" "=f")
5212 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5215 [(set_attr "type" "fp")
5216 (set_attr "fptype" "double")])
5218 (define_expand "fix_trunctfsi2"
5219 [(set (match_operand:SI 0 "register_operand" "=f")
5220 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5221 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5224 if (! TARGET_HARD_QUAD)
5228 if (GET_CODE (operands[1]) != MEM)
5230 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5231 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5234 slot0 = operands[1];
5236 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5237 operands[0], 0, SImode, 1,
5238 XEXP (slot0, 0), Pmode);
5243 (define_insn "*fix_trunctfsi2_hq"
5244 [(set (match_operand:SI 0 "register_operand" "=f")
5245 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5246 "TARGET_FPU && TARGET_HARD_QUAD"
5248 [(set_attr "type" "fp")])
5250 (define_expand "fixuns_trunctfsi2"
5251 [(set (match_operand:SI 0 "register_operand" "=f")
5252 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5253 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5258 if (GET_CODE (operands[1]) != MEM)
5260 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5261 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5264 slot0 = operands[1];
5266 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5267 operands[0], 0, SImode, 1,
5268 XEXP (slot0, 0), Pmode);
5272 ;; Now the same, for V9 targets
5274 (define_insn "fix_truncsfdi2"
5275 [(set (match_operand:DI 0 "register_operand" "=e")
5276 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5277 "TARGET_V9 && TARGET_FPU"
5279 [(set_attr "type" "fp")
5280 (set_attr "fptype" "double")])
5282 (define_insn "fix_truncdfdi2"
5283 [(set (match_operand:DI 0 "register_operand" "=e")
5284 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5285 "TARGET_V9 && TARGET_FPU"
5287 [(set_attr "type" "fp")
5288 (set_attr "fptype" "double")])
5290 (define_expand "fix_trunctfdi2"
5291 [(set (match_operand:DI 0 "register_operand" "=e")
5292 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5293 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5296 if (! TARGET_HARD_QUAD)
5300 if (GET_CODE (operands[1]) != MEM)
5302 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5303 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5306 slot0 = operands[1];
5308 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5309 operands[0], 0, DImode, 1,
5310 XEXP (slot0, 0), Pmode);
5315 (define_insn "*fix_trunctfdi2_hq"
5316 [(set (match_operand:DI 0 "register_operand" "=e")
5317 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5318 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5320 [(set_attr "type" "fp")])
5322 (define_expand "fixuns_trunctfdi2"
5323 [(set (match_operand:DI 0 "register_operand" "=f")
5324 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5325 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5330 if (GET_CODE (operands[1]) != MEM)
5332 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5333 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5336 slot0 = operands[1];
5338 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5339 operands[0], 0, DImode, 1,
5340 XEXP (slot0, 0), Pmode);
5345 ;;- arithmetic instructions
5347 (define_expand "adddi3"
5348 [(set (match_operand:DI 0 "register_operand" "=r")
5349 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5350 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5356 if (! TARGET_ARCH64)
5358 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5359 gen_rtx_SET (VOIDmode, operands[0],
5360 gen_rtx_PLUS (DImode, operands[1],
5362 gen_rtx_CLOBBER (VOIDmode,
5363 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5366 if (arith_double_4096_operand(operands[2], DImode))
5368 switch (GET_CODE (operands[1]))
5370 case CONST_INT: i = INTVAL (operands[1]); break;
5371 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5373 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5374 gen_rtx_MINUS (DImode, operands[1],
5378 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5383 (define_insn "adddi3_insn_sp32"
5384 [(set (match_operand:DI 0 "register_operand" "=r")
5385 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5386 (match_operand:DI 2 "arith_double_operand" "rHI")))
5387 (clobber (reg:CC 100))]
5390 [(set_attr "length" "2")])
5393 [(set (match_operand:DI 0 "register_operand" "")
5394 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5395 (match_operand:DI 2 "arith_double_operand" "")))
5396 (clobber (reg:CC 100))]
5397 "! TARGET_ARCH64 && reload_completed"
5398 [(parallel [(set (reg:CC_NOOV 100)
5399 (compare:CC_NOOV (plus:SI (match_dup 4)
5403 (plus:SI (match_dup 4) (match_dup 5)))])
5405 (plus:SI (plus:SI (match_dup 7)
5407 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5410 operands[3] = gen_lowpart (SImode, operands[0]);
5411 operands[4] = gen_lowpart (SImode, operands[1]);
5412 operands[5] = gen_lowpart (SImode, operands[2]);
5413 operands[6] = gen_highpart (SImode, operands[0]);
5414 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5415 #if HOST_BITS_PER_WIDE_INT == 32
5416 if (GET_CODE (operands[2]) == CONST_INT)
5418 if (INTVAL (operands[2]) < 0)
5419 operands[8] = constm1_rtx;
5421 operands[8] = const0_rtx;
5425 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5429 [(set (match_operand:DI 0 "register_operand" "")
5430 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5431 (match_operand:DI 2 "arith_double_operand" "")))
5432 (clobber (reg:CC 100))]
5433 "! TARGET_ARCH64 && reload_completed"
5434 [(parallel [(set (reg:CC_NOOV 100)
5435 (compare:CC_NOOV (minus:SI (match_dup 4)
5439 (minus:SI (match_dup 4) (match_dup 5)))])
5441 (minus:SI (minus:SI (match_dup 7)
5443 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5446 operands[3] = gen_lowpart (SImode, operands[0]);
5447 operands[4] = gen_lowpart (SImode, operands[1]);
5448 operands[5] = gen_lowpart (SImode, operands[2]);
5449 operands[6] = gen_highpart (SImode, operands[0]);
5450 operands[7] = gen_highpart (SImode, operands[1]);
5451 #if HOST_BITS_PER_WIDE_INT == 32
5452 if (GET_CODE (operands[2]) == CONST_INT)
5454 if (INTVAL (operands[2]) < 0)
5455 operands[8] = constm1_rtx;
5457 operands[8] = const0_rtx;
5461 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5464 ;; LTU here means "carry set"
5466 [(set (match_operand:SI 0 "register_operand" "=r")
5467 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5468 (match_operand:SI 2 "arith_operand" "rI"))
5469 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5472 [(set_attr "type" "misc")])
5474 (define_insn "*addx_extend_sp32"
5475 [(set (match_operand:DI 0 "register_operand" "=r")
5476 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5477 (match_operand:SI 2 "arith_operand" "rI"))
5478 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5481 [(set_attr "length" "2")])
5484 [(set (match_operand:DI 0 "register_operand" "")
5485 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5486 (match_operand:SI 2 "arith_operand" ""))
5487 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5488 "! TARGET_ARCH64 && reload_completed"
5489 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5490 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5491 (set (match_dup 4) (const_int 0))]
5492 "operands[3] = gen_lowpart (SImode, operands[0]);
5493 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5495 (define_insn "*addx_extend_sp64"
5496 [(set (match_operand:DI 0 "register_operand" "=r")
5497 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5498 (match_operand:SI 2 "arith_operand" "rI"))
5499 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5501 "addx\\t%r1, %2, %0"
5502 [(set_attr "type" "misc")])
5505 [(set (match_operand:SI 0 "register_operand" "=r")
5506 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5507 (match_operand:SI 2 "arith_operand" "rI"))
5508 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5510 "subx\\t%r1, %2, %0"
5511 [(set_attr "type" "misc")])
5513 (define_insn "*subx_extend_sp64"
5514 [(set (match_operand:DI 0 "register_operand" "=r")
5515 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5516 (match_operand:SI 2 "arith_operand" "rI"))
5517 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5519 "subx\\t%r1, %2, %0"
5520 [(set_attr "type" "misc")])
5522 (define_insn "*subx_extend"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5524 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5525 (match_operand:SI 2 "arith_operand" "rI"))
5526 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5529 [(set_attr "length" "2")])
5532 [(set (match_operand:DI 0 "register_operand" "")
5533 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5534 (match_operand:SI 2 "arith_operand" ""))
5535 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5536 "! TARGET_ARCH64 && reload_completed"
5537 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5538 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5539 (set (match_dup 4) (const_int 0))]
5540 "operands[3] = gen_lowpart (SImode, operands[0]);
5541 operands[4] = gen_highpart (SImode, operands[0]);")
5544 [(set (match_operand:DI 0 "register_operand" "=r")
5545 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5546 (match_operand:DI 2 "register_operand" "r")))
5547 (clobber (reg:CC 100))]
5550 [(set_attr "length" "2")])
5553 [(set (match_operand:DI 0 "register_operand" "")
5554 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5555 (match_operand:DI 2 "register_operand" "")))
5556 (clobber (reg:CC 100))]
5557 "! TARGET_ARCH64 && reload_completed"
5558 [(parallel [(set (reg:CC_NOOV 100)
5559 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5561 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5563 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5564 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5565 "operands[3] = gen_lowpart (SImode, operands[2]);
5566 operands[4] = gen_highpart (SImode, operands[2]);
5567 operands[5] = gen_lowpart (SImode, operands[0]);
5568 operands[6] = gen_highpart (SImode, operands[0]);")
5570 (define_insn "*adddi3_sp64"
5571 [(set (match_operand:DI 0 "register_operand" "=r")
5572 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5573 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5577 (define_expand "addsi3"
5578 [(set (match_operand:SI 0 "register_operand" "=r,d")
5579 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5580 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5584 if (arith_4096_operand(operands[2], SImode))
5586 if (GET_CODE (operands[1]) == CONST_INT)
5587 emit_insn (gen_movsi (operands[0],
5588 GEN_INT (INTVAL (operands[1]) + 4096)));
5590 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5591 gen_rtx_MINUS (SImode, operands[1],
5597 (define_insn "*addsi3"
5598 [(set (match_operand:SI 0 "register_operand" "=r,d")
5599 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5600 (match_operand:SI 2 "arith_operand" "rI,d")))]
5604 fpadd32s\\t%1, %2, %0"
5605 [(set_attr "type" "*,fp")])
5607 (define_insn "*cmp_cc_plus"
5608 [(set (reg:CC_NOOV 100)
5609 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5610 (match_operand:SI 1 "arith_operand" "rI"))
5613 "addcc\\t%0, %1, %%g0"
5614 [(set_attr "type" "compare")])
5616 (define_insn "*cmp_ccx_plus"
5617 [(set (reg:CCX_NOOV 100)
5618 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5619 (match_operand:DI 1 "arith_double_operand" "rHI"))
5622 "addcc\\t%0, %1, %%g0"
5623 [(set_attr "type" "compare")])
5625 (define_insn "*cmp_cc_plus_set"
5626 [(set (reg:CC_NOOV 100)
5627 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5628 (match_operand:SI 2 "arith_operand" "rI"))
5630 (set (match_operand:SI 0 "register_operand" "=r")
5631 (plus:SI (match_dup 1) (match_dup 2)))]
5633 "addcc\\t%1, %2, %0"
5634 [(set_attr "type" "compare")])
5636 (define_insn "*cmp_ccx_plus_set"
5637 [(set (reg:CCX_NOOV 100)
5638 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5639 (match_operand:DI 2 "arith_double_operand" "rHI"))
5641 (set (match_operand:DI 0 "register_operand" "=r")
5642 (plus:DI (match_dup 1) (match_dup 2)))]
5644 "addcc\\t%1, %2, %0"
5645 [(set_attr "type" "compare")])
5647 (define_expand "subdi3"
5648 [(set (match_operand:DI 0 "register_operand" "=r")
5649 (minus:DI (match_operand:DI 1 "register_operand" "r")
5650 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5654 if (! TARGET_ARCH64)
5656 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5657 gen_rtx_SET (VOIDmode, operands[0],
5658 gen_rtx_MINUS (DImode, operands[1],
5660 gen_rtx_CLOBBER (VOIDmode,
5661 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5664 if (arith_double_4096_operand(operands[2], DImode))
5666 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5667 gen_rtx_PLUS (DImode, operands[1],
5673 (define_insn "*subdi3_sp32"
5674 [(set (match_operand:DI 0 "register_operand" "=r")
5675 (minus:DI (match_operand:DI 1 "register_operand" "r")
5676 (match_operand:DI 2 "arith_double_operand" "rHI")))
5677 (clobber (reg:CC 100))]
5680 [(set_attr "length" "2")])
5683 [(set (match_operand:DI 0 "register_operand" "")
5684 (minus:DI (match_operand:DI 1 "register_operand" "")
5685 (match_operand:DI 2 "arith_double_operand" "")))
5686 (clobber (reg:CC 100))]
5689 && (GET_CODE (operands[2]) == CONST_INT
5690 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5691 [(clobber (const_int 0))]
5696 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5697 lowp = gen_lowpart (SImode, operands[2]);
5698 if ((lowp == const0_rtx)
5699 && (operands[0] == operands[1]))
5701 emit_insn (gen_rtx_SET (VOIDmode,
5702 gen_highpart (SImode, operands[0]),
5703 gen_rtx_MINUS (SImode,
5704 gen_highpart_mode (SImode, DImode,
5710 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5711 gen_lowpart (SImode, operands[1]),
5713 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5714 gen_highpart_mode (SImode, DImode, operands[1]),
5721 [(set (match_operand:DI 0 "register_operand" "")
5722 (minus:DI (match_operand:DI 1 "register_operand" "")
5723 (match_operand:DI 2 "register_operand" "")))
5724 (clobber (reg:CC 100))]
5726 && reload_completed"
5727 [(clobber (const_int 0))]
5730 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5731 gen_lowpart (SImode, operands[1]),
5732 gen_lowpart (SImode, operands[2])));
5733 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5734 gen_highpart (SImode, operands[1]),
5735 gen_highpart (SImode, operands[2])));
5740 [(set (match_operand:DI 0 "register_operand" "=r")
5741 (minus:DI (match_operand:DI 1 "register_operand" "r")
5742 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5743 (clobber (reg:CC 100))]
5746 [(set_attr "length" "2")])
5749 [(set (match_operand:DI 0 "register_operand" "")
5750 (minus:DI (match_operand:DI 1 "register_operand" "")
5751 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5752 (clobber (reg:CC 100))]
5753 "! TARGET_ARCH64 && reload_completed"
5754 [(parallel [(set (reg:CC_NOOV 100)
5755 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5757 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5759 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5760 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5761 "operands[3] = gen_lowpart (SImode, operands[1]);
5762 operands[4] = gen_highpart (SImode, operands[1]);
5763 operands[5] = gen_lowpart (SImode, operands[0]);
5764 operands[6] = gen_highpart (SImode, operands[0]);")
5766 (define_insn "*subdi3_sp64"
5767 [(set (match_operand:DI 0 "register_operand" "=r")
5768 (minus:DI (match_operand:DI 1 "register_operand" "r")
5769 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5773 (define_expand "subsi3"
5774 [(set (match_operand:SI 0 "register_operand" "=r,d")
5775 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5776 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5780 if (arith_4096_operand(operands[2], SImode))
5782 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5783 gen_rtx_PLUS (SImode, operands[1],
5789 (define_insn "*subsi3"
5790 [(set (match_operand:SI 0 "register_operand" "=r,d")
5791 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5792 (match_operand:SI 2 "arith_operand" "rI,d")))]
5796 fpsub32s\\t%1, %2, %0"
5797 [(set_attr "type" "*,fp")])
5799 (define_insn "*cmp_minus_cc"
5800 [(set (reg:CC_NOOV 100)
5801 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5802 (match_operand:SI 1 "arith_operand" "rI"))
5805 "subcc\\t%r0, %1, %%g0"
5806 [(set_attr "type" "compare")])
5808 (define_insn "*cmp_minus_ccx"
5809 [(set (reg:CCX_NOOV 100)
5810 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5811 (match_operand:DI 1 "arith_double_operand" "rHI"))
5814 "subcc\\t%0, %1, %%g0"
5815 [(set_attr "type" "compare")])
5817 (define_insn "cmp_minus_cc_set"
5818 [(set (reg:CC_NOOV 100)
5819 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5820 (match_operand:SI 2 "arith_operand" "rI"))
5822 (set (match_operand:SI 0 "register_operand" "=r")
5823 (minus:SI (match_dup 1) (match_dup 2)))]
5825 "subcc\\t%r1, %2, %0"
5826 [(set_attr "type" "compare")])
5828 (define_insn "*cmp_minus_ccx_set"
5829 [(set (reg:CCX_NOOV 100)
5830 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5831 (match_operand:DI 2 "arith_double_operand" "rHI"))
5833 (set (match_operand:DI 0 "register_operand" "=r")
5834 (minus:DI (match_dup 1) (match_dup 2)))]
5836 "subcc\\t%1, %2, %0"
5837 [(set_attr "type" "compare")])
5839 ;; Integer Multiply/Divide.
5841 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5842 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5844 (define_insn "mulsi3"
5845 [(set (match_operand:SI 0 "register_operand" "=r")
5846 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5847 (match_operand:SI 2 "arith_operand" "rI")))]
5850 [(set_attr "type" "imul")])
5852 (define_expand "muldi3"
5853 [(set (match_operand:DI 0 "register_operand" "=r")
5854 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5855 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5856 "TARGET_ARCH64 || TARGET_V8PLUS"
5861 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5866 (define_insn "*muldi3_sp64"
5867 [(set (match_operand:DI 0 "register_operand" "=r")
5868 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5869 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5872 [(set_attr "type" "imul")])
5874 ;; V8plus wide multiply.
5876 (define_insn "muldi3_v8plus"
5877 [(set (match_operand:DI 0 "register_operand" "=r,h")
5878 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5879 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5880 (clobber (match_scratch:SI 3 "=&h,X"))
5881 (clobber (match_scratch:SI 4 "=&h,X"))]
5885 if (sparc_check_64 (operands[1], insn) <= 0)
5886 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5887 if (which_alternative == 1)
5888 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5889 if (GET_CODE (operands[2]) == CONST_INT)
5891 if (which_alternative == 1)
5892 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5894 return \"sllx\\t%H1, 32, %3\\n\\tor\\t%L1, %3, %3\\n\\tmulx\\t%3, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\";
5896 if (sparc_check_64 (operands[2], insn) <= 0)
5897 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5898 if (which_alternative == 1)
5899 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\";
5901 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\";
5903 [(set_attr "type" "multi")
5904 (set_attr "length" "9,8")])
5906 (define_insn "*cmp_mul_set"
5908 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5909 (match_operand:SI 2 "arith_operand" "rI"))
5911 (set (match_operand:SI 0 "register_operand" "=r")
5912 (mult:SI (match_dup 1) (match_dup 2)))]
5913 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5914 "smulcc\\t%1, %2, %0"
5915 [(set_attr "type" "imul")])
5917 (define_expand "mulsidi3"
5918 [(set (match_operand:DI 0 "register_operand" "")
5919 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5920 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5924 if (CONSTANT_P (operands[2]))
5927 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5930 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5936 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5941 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5942 ;; registers can hold 64 bit values in the V8plus environment.
5944 (define_insn "mulsidi3_v8plus"
5945 [(set (match_operand:DI 0 "register_operand" "=h,r")
5946 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5947 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5948 (clobber (match_scratch:SI 3 "=X,&h"))]
5951 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5952 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5953 [(set_attr "type" "multi")
5954 (set_attr "length" "2,3")])
5957 (define_insn "const_mulsidi3_v8plus"
5958 [(set (match_operand:DI 0 "register_operand" "=h,r")
5959 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5960 (match_operand:SI 2 "small_int" "I,I")))
5961 (clobber (match_scratch:SI 3 "=X,&h"))]
5964 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5965 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5966 [(set_attr "type" "multi")
5967 (set_attr "length" "2,3")])
5970 (define_insn "*mulsidi3_sp32"
5971 [(set (match_operand:DI 0 "register_operand" "=r")
5972 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5973 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5977 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5980 (if_then_else (eq_attr "isa" "sparclet")
5981 (const_string "imul") (const_string "multi")))
5982 (set (attr "length")
5983 (if_then_else (eq_attr "isa" "sparclet")
5984 (const_int 1) (const_int 2)))])
5986 (define_insn "*mulsidi3_sp64"
5987 [(set (match_operand:DI 0 "register_operand" "=r")
5988 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5989 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5990 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5992 [(set_attr "type" "imul")])
5994 ;; Extra pattern, because sign_extend of a constant isn't valid.
5997 (define_insn "const_mulsidi3_sp32"
5998 [(set (match_operand:DI 0 "register_operand" "=r")
5999 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6000 (match_operand:SI 2 "small_int" "I")))]
6004 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6007 (if_then_else (eq_attr "isa" "sparclet")
6008 (const_string "imul") (const_string "multi")))
6009 (set (attr "length")
6010 (if_then_else (eq_attr "isa" "sparclet")
6011 (const_int 1) (const_int 2)))])
6013 (define_insn "const_mulsidi3_sp64"
6014 [(set (match_operand:DI 0 "register_operand" "=r")
6015 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6016 (match_operand:SI 2 "small_int" "I")))]
6017 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6019 [(set_attr "type" "imul")])
6021 (define_expand "smulsi3_highpart"
6022 [(set (match_operand:SI 0 "register_operand" "")
6024 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6025 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6027 "TARGET_HARD_MUL && TARGET_ARCH32"
6030 if (CONSTANT_P (operands[2]))
6034 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6040 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6045 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6046 operands[2], GEN_INT (32)));
6052 (define_insn "smulsi3_highpart_v8plus"
6053 [(set (match_operand:SI 0 "register_operand" "=h,r")
6055 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6056 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6057 (match_operand:SI 3 "const_int_operand" "i,i"))))
6058 (clobber (match_scratch:SI 4 "=X,&h"))]
6061 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6062 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6063 [(set_attr "type" "multi")
6064 (set_attr "length" "2")])
6066 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6069 [(set (match_operand:SI 0 "register_operand" "=h,r")
6072 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6073 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6074 (match_operand:SI 3 "const_int_operand" "i,i"))
6076 (clobber (match_scratch:SI 4 "=X,&h"))]
6079 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6080 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6081 [(set_attr "type" "multi")
6082 (set_attr "length" "2")])
6085 (define_insn "const_smulsi3_highpart_v8plus"
6086 [(set (match_operand:SI 0 "register_operand" "=h,r")
6088 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6089 (match_operand 2 "small_int" "i,i"))
6090 (match_operand:SI 3 "const_int_operand" "i,i"))))
6091 (clobber (match_scratch:SI 4 "=X,&h"))]
6094 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6095 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6096 [(set_attr "type" "multi")
6097 (set_attr "length" "2")])
6100 (define_insn "*smulsi3_highpart_sp32"
6101 [(set (match_operand:SI 0 "register_operand" "=r")
6103 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6104 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6107 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6108 [(set_attr "type" "multi")
6109 (set_attr "length" "2")])
6112 (define_insn "const_smulsi3_highpart"
6113 [(set (match_operand:SI 0 "register_operand" "=r")
6115 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6116 (match_operand:SI 2 "register_operand" "r"))
6119 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6120 [(set_attr "type" "multi")
6121 (set_attr "length" "2")])
6123 (define_expand "umulsidi3"
6124 [(set (match_operand:DI 0 "register_operand" "")
6125 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6126 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6130 if (CONSTANT_P (operands[2]))
6133 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6136 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6142 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6148 (define_insn "umulsidi3_v8plus"
6149 [(set (match_operand:DI 0 "register_operand" "=h,r")
6150 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6151 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6152 (clobber (match_scratch:SI 3 "=X,&h"))]
6155 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6156 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6157 [(set_attr "type" "multi")
6158 (set_attr "length" "2,3")])
6161 (define_insn "*umulsidi3_sp32"
6162 [(set (match_operand:DI 0 "register_operand" "=r")
6163 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6164 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6168 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6171 (if_then_else (eq_attr "isa" "sparclet")
6172 (const_string "imul") (const_string "multi")))
6173 (set (attr "length")
6174 (if_then_else (eq_attr "isa" "sparclet")
6175 (const_int 1) (const_int 2)))])
6177 (define_insn "*umulsidi3_sp64"
6178 [(set (match_operand:DI 0 "register_operand" "=r")
6179 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6180 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6181 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6183 [(set_attr "type" "imul")])
6185 ;; Extra pattern, because sign_extend of a constant isn't valid.
6188 (define_insn "const_umulsidi3_sp32"
6189 [(set (match_operand:DI 0 "register_operand" "=r")
6190 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6191 (match_operand:SI 2 "uns_small_int" "")))]
6195 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6198 (if_then_else (eq_attr "isa" "sparclet")
6199 (const_string "imul") (const_string "multi")))
6200 (set (attr "length")
6201 (if_then_else (eq_attr "isa" "sparclet")
6202 (const_int 1) (const_int 2)))])
6204 (define_insn "const_umulsidi3_sp64"
6205 [(set (match_operand:DI 0 "register_operand" "=r")
6206 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6207 (match_operand:SI 2 "uns_small_int" "")))]
6208 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6210 [(set_attr "type" "imul")])
6213 (define_insn "const_umulsidi3_v8plus"
6214 [(set (match_operand:DI 0 "register_operand" "=h,r")
6215 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6216 (match_operand:SI 2 "uns_small_int" "")))
6217 (clobber (match_scratch:SI 3 "=X,h"))]
6220 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6221 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6222 [(set_attr "type" "multi")
6223 (set_attr "length" "2,3")])
6225 (define_expand "umulsi3_highpart"
6226 [(set (match_operand:SI 0 "register_operand" "")
6228 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6229 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6231 "TARGET_HARD_MUL && TARGET_ARCH32"
6234 if (CONSTANT_P (operands[2]))
6238 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6244 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6249 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6250 operands[2], GEN_INT (32)));
6256 (define_insn "umulsi3_highpart_v8plus"
6257 [(set (match_operand:SI 0 "register_operand" "=h,r")
6259 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6260 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6261 (match_operand:SI 3 "const_int_operand" "i,i"))))
6262 (clobber (match_scratch:SI 4 "=X,h"))]
6265 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6266 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6267 [(set_attr "type" "multi")
6268 (set_attr "length" "2")])
6271 (define_insn "const_umulsi3_highpart_v8plus"
6272 [(set (match_operand:SI 0 "register_operand" "=h,r")
6274 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6275 (match_operand:SI 2 "uns_small_int" ""))
6276 (match_operand:SI 3 "const_int_operand" "i,i"))))
6277 (clobber (match_scratch:SI 4 "=X,h"))]
6280 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6281 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6282 [(set_attr "type" "multi")
6283 (set_attr "length" "2")])
6286 (define_insn "*umulsi3_highpart_sp32"
6287 [(set (match_operand:SI 0 "register_operand" "=r")
6289 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6290 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6293 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6294 [(set_attr "type" "multi")
6295 (set_attr "length" "2")])
6298 (define_insn "const_umulsi3_highpart"
6299 [(set (match_operand:SI 0 "register_operand" "=r")
6301 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6302 (match_operand:SI 2 "uns_small_int" ""))
6305 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6306 [(set_attr "type" "multi")
6307 (set_attr "length" "2")])
6309 ;; The v8 architecture specifies that there must be 3 instructions between
6310 ;; a y register write and a use of it for correct results.
6312 (define_expand "divsi3"
6313 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6314 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6315 (match_operand:SI 2 "input_operand" "rI,m")))
6316 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6317 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6322 operands[3] = gen_reg_rtx(SImode);
6323 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6324 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6330 (define_insn "divsi3_sp32"
6331 [(set (match_operand:SI 0 "register_operand" "=r,r")
6332 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6333 (match_operand:SI 2 "input_operand" "rI,m")))
6334 (clobber (match_scratch:SI 3 "=&r,&r"))]
6335 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6339 if (which_alternative == 0)
6341 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6343 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6346 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6348 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\";
6350 [(set_attr "type" "multi")
6351 (set (attr "length")
6352 (if_then_else (eq_attr "isa" "v9")
6353 (const_int 4) (const_int 7)))])
6355 (define_insn "divsi3_sp64"
6356 [(set (match_operand:SI 0 "register_operand" "=r")
6357 (div:SI (match_operand:SI 1 "register_operand" "r")
6358 (match_operand:SI 2 "input_operand" "rI")))
6359 (use (match_operand:SI 3 "register_operand" "r"))]
6360 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6361 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6362 [(set_attr "type" "multi")
6363 (set_attr "length" "2")])
6365 (define_insn "divdi3"
6366 [(set (match_operand:DI 0 "register_operand" "=r")
6367 (div:DI (match_operand:DI 1 "register_operand" "r")
6368 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6370 "sdivx\\t%1, %2, %0"
6371 [(set_attr "type" "idiv")])
6373 (define_insn "*cmp_sdiv_cc_set"
6375 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6376 (match_operand:SI 2 "arith_operand" "rI"))
6378 (set (match_operand:SI 0 "register_operand" "=r")
6379 (div:SI (match_dup 1) (match_dup 2)))
6380 (clobber (match_scratch:SI 3 "=&r"))]
6381 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6385 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6387 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6389 [(set_attr "type" "multi")
6390 (set (attr "length")
6391 (if_then_else (eq_attr "isa" "v9")
6392 (const_int 3) (const_int 6)))])
6395 (define_expand "udivsi3"
6396 [(set (match_operand:SI 0 "register_operand" "")
6397 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6398 (match_operand:SI 2 "input_operand" "")))]
6399 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6402 (define_insn "udivsi3_sp32"
6403 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6404 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6405 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6407 || TARGET_DEPRECATED_V8_INSNS)
6411 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6412 switch (which_alternative)
6415 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6417 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6419 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6422 [(set_attr "type" "multi")
6423 (set_attr "length" "5")])
6425 (define_insn "udivsi3_sp64"
6426 [(set (match_operand:SI 0 "register_operand" "=r")
6427 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6428 (match_operand:SI 2 "input_operand" "rI")))]
6429 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6430 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6431 [(set_attr "type" "multi")
6432 (set_attr "length" "2")])
6434 (define_insn "udivdi3"
6435 [(set (match_operand:DI 0 "register_operand" "=r")
6436 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6437 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6439 "udivx\\t%1, %2, %0"
6440 [(set_attr "type" "idiv")])
6442 (define_insn "*cmp_udiv_cc_set"
6444 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6445 (match_operand:SI 2 "arith_operand" "rI"))
6447 (set (match_operand:SI 0 "register_operand" "=r")
6448 (udiv:SI (match_dup 1) (match_dup 2)))]
6450 || TARGET_DEPRECATED_V8_INSNS"
6454 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6456 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6458 [(set_attr "type" "multi")
6459 (set (attr "length")
6460 (if_then_else (eq_attr "isa" "v9")
6461 (const_int 2) (const_int 5)))])
6463 ; sparclet multiply/accumulate insns
6465 (define_insn "*smacsi"
6466 [(set (match_operand:SI 0 "register_operand" "=r")
6467 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6468 (match_operand:SI 2 "arith_operand" "rI"))
6469 (match_operand:SI 3 "register_operand" "0")))]
6472 [(set_attr "type" "imul")])
6474 (define_insn "*smacdi"
6475 [(set (match_operand:DI 0 "register_operand" "=r")
6476 (plus:DI (mult:DI (sign_extend:DI
6477 (match_operand:SI 1 "register_operand" "%r"))
6479 (match_operand:SI 2 "register_operand" "r")))
6480 (match_operand:DI 3 "register_operand" "0")))]
6482 "smacd\\t%1, %2, %L0"
6483 [(set_attr "type" "imul")])
6485 (define_insn "*umacdi"
6486 [(set (match_operand:DI 0 "register_operand" "=r")
6487 (plus:DI (mult:DI (zero_extend:DI
6488 (match_operand:SI 1 "register_operand" "%r"))
6490 (match_operand:SI 2 "register_operand" "r")))
6491 (match_operand:DI 3 "register_operand" "0")))]
6493 "umacd\\t%1, %2, %L0"
6494 [(set_attr "type" "imul")])
6496 ;;- Boolean instructions
6497 ;; We define DImode `and' so with DImode `not' we can get
6498 ;; DImode `andn'. Other combinations are possible.
6500 (define_expand "anddi3"
6501 [(set (match_operand:DI 0 "register_operand" "")
6502 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6503 (match_operand:DI 2 "arith_double_operand" "")))]
6507 (define_insn "*anddi3_sp32"
6508 [(set (match_operand:DI 0 "register_operand" "=r,b")
6509 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6510 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6515 [(set_attr "type" "*,fp")
6516 (set_attr "length" "2,*")
6517 (set_attr "fptype" "double")])
6519 (define_insn "*anddi3_sp64"
6520 [(set (match_operand:DI 0 "register_operand" "=r,b")
6521 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6522 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6527 [(set_attr "type" "*,fp")
6528 (set_attr "fptype" "double")])
6530 (define_insn "andsi3"
6531 [(set (match_operand:SI 0 "register_operand" "=r,d")
6532 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6533 (match_operand:SI 2 "arith_operand" "rI,d")))]
6538 [(set_attr "type" "*,fp")])
6541 [(set (match_operand:SI 0 "register_operand" "")
6542 (and:SI (match_operand:SI 1 "register_operand" "")
6543 (match_operand:SI 2 "" "")))
6544 (clobber (match_operand:SI 3 "register_operand" ""))]
6545 "GET_CODE (operands[2]) == CONST_INT
6546 && !SMALL_INT32 (operands[2])
6547 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6548 [(set (match_dup 3) (match_dup 4))
6549 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6552 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6555 ;; Split DImode logical operations requiring two instructions.
6557 [(set (match_operand:DI 0 "register_operand" "")
6558 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6559 [(match_operand:DI 2 "register_operand" "")
6560 (match_operand:DI 3 "arith_double_operand" "")]))]
6563 && ((GET_CODE (operands[0]) == REG
6564 && REGNO (operands[0]) < 32)
6565 || (GET_CODE (operands[0]) == SUBREG
6566 && GET_CODE (SUBREG_REG (operands[0])) == REG
6567 && REGNO (SUBREG_REG (operands[0])) < 32))"
6568 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6569 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6572 operands[4] = gen_highpart (SImode, operands[0]);
6573 operands[5] = gen_lowpart (SImode, operands[0]);
6574 operands[6] = gen_highpart (SImode, operands[2]);
6575 operands[7] = gen_lowpart (SImode, operands[2]);
6576 #if HOST_BITS_PER_WIDE_INT == 32
6577 if (GET_CODE (operands[3]) == CONST_INT)
6579 if (INTVAL (operands[3]) < 0)
6580 operands[8] = constm1_rtx;
6582 operands[8] = const0_rtx;
6586 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6587 operands[9] = gen_lowpart (SImode, operands[3]);
6590 (define_insn "*and_not_di_sp32"
6591 [(set (match_operand:DI 0 "register_operand" "=r,b")
6592 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6593 (match_operand:DI 2 "register_operand" "r,b")))]
6597 fandnot1\\t%1, %2, %0"
6598 [(set_attr "type" "*,fp")
6599 (set_attr "length" "2,*")
6600 (set_attr "fptype" "double")])
6603 [(set (match_operand:DI 0 "register_operand" "")
6604 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6605 (match_operand:DI 2 "register_operand" "")))]
6608 && ((GET_CODE (operands[0]) == REG
6609 && REGNO (operands[0]) < 32)
6610 || (GET_CODE (operands[0]) == SUBREG
6611 && GET_CODE (SUBREG_REG (operands[0])) == REG
6612 && REGNO (SUBREG_REG (operands[0])) < 32))"
6613 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6614 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6615 "operands[3] = gen_highpart (SImode, operands[0]);
6616 operands[4] = gen_highpart (SImode, operands[1]);
6617 operands[5] = gen_highpart (SImode, operands[2]);
6618 operands[6] = gen_lowpart (SImode, operands[0]);
6619 operands[7] = gen_lowpart (SImode, operands[1]);
6620 operands[8] = gen_lowpart (SImode, operands[2]);")
6622 (define_insn "*and_not_di_sp64"
6623 [(set (match_operand:DI 0 "register_operand" "=r,b")
6624 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6625 (match_operand:DI 2 "register_operand" "r,b")))]
6629 fandnot1\\t%1, %2, %0"
6630 [(set_attr "type" "*,fp")
6631 (set_attr "fptype" "double")])
6633 (define_insn "*and_not_si"
6634 [(set (match_operand:SI 0 "register_operand" "=r,d")
6635 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6636 (match_operand:SI 2 "register_operand" "r,d")))]
6640 fandnot1s\\t%1, %2, %0"
6641 [(set_attr "type" "*,fp")])
6643 (define_expand "iordi3"
6644 [(set (match_operand:DI 0 "register_operand" "")
6645 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6646 (match_operand:DI 2 "arith_double_operand" "")))]
6650 (define_insn "*iordi3_sp32"
6651 [(set (match_operand:DI 0 "register_operand" "=r,b")
6652 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6653 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6658 [(set_attr "type" "*,fp")
6659 (set_attr "length" "2,*")
6660 (set_attr "fptype" "double")])
6662 (define_insn "*iordi3_sp64"
6663 [(set (match_operand:DI 0 "register_operand" "=r,b")
6664 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6665 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6670 [(set_attr "type" "*,fp")
6671 (set_attr "fptype" "double")])
6673 (define_insn "iorsi3"
6674 [(set (match_operand:SI 0 "register_operand" "=r,d")
6675 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6676 (match_operand:SI 2 "arith_operand" "rI,d")))]
6681 [(set_attr "type" "*,fp")])
6684 [(set (match_operand:SI 0 "register_operand" "")
6685 (ior:SI (match_operand:SI 1 "register_operand" "")
6686 (match_operand:SI 2 "" "")))
6687 (clobber (match_operand:SI 3 "register_operand" ""))]
6688 "GET_CODE (operands[2]) == CONST_INT
6689 && !SMALL_INT32 (operands[2])
6690 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6691 [(set (match_dup 3) (match_dup 4))
6692 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6695 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6698 (define_insn "*or_not_di_sp32"
6699 [(set (match_operand:DI 0 "register_operand" "=r,b")
6700 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6701 (match_operand:DI 2 "register_operand" "r,b")))]
6705 fornot1\\t%1, %2, %0"
6706 [(set_attr "type" "*,fp")
6707 (set_attr "length" "2,*")
6708 (set_attr "fptype" "double")])
6711 [(set (match_operand:DI 0 "register_operand" "")
6712 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6713 (match_operand:DI 2 "register_operand" "")))]
6716 && ((GET_CODE (operands[0]) == REG
6717 && REGNO (operands[0]) < 32)
6718 || (GET_CODE (operands[0]) == SUBREG
6719 && GET_CODE (SUBREG_REG (operands[0])) == REG
6720 && REGNO (SUBREG_REG (operands[0])) < 32))"
6721 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6722 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6723 "operands[3] = gen_highpart (SImode, operands[0]);
6724 operands[4] = gen_highpart (SImode, operands[1]);
6725 operands[5] = gen_highpart (SImode, operands[2]);
6726 operands[6] = gen_lowpart (SImode, operands[0]);
6727 operands[7] = gen_lowpart (SImode, operands[1]);
6728 operands[8] = gen_lowpart (SImode, operands[2]);")
6730 (define_insn "*or_not_di_sp64"
6731 [(set (match_operand:DI 0 "register_operand" "=r,b")
6732 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6733 (match_operand:DI 2 "register_operand" "r,b")))]
6737 fornot1\\t%1, %2, %0"
6738 [(set_attr "type" "*,fp")
6739 (set_attr "fptype" "double")])
6741 (define_insn "*or_not_si"
6742 [(set (match_operand:SI 0 "register_operand" "=r,d")
6743 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6744 (match_operand:SI 2 "register_operand" "r,d")))]
6748 fornot1s\\t%1, %2, %0"
6749 [(set_attr "type" "*,fp")])
6751 (define_expand "xordi3"
6752 [(set (match_operand:DI 0 "register_operand" "")
6753 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6754 (match_operand:DI 2 "arith_double_operand" "")))]
6758 (define_insn "*xordi3_sp32"
6759 [(set (match_operand:DI 0 "register_operand" "=r,b")
6760 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6761 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6766 [(set_attr "type" "*,fp")
6767 (set_attr "length" "2,*")
6768 (set_attr "fptype" "double")])
6770 (define_insn "*xordi3_sp64"
6771 [(set (match_operand:DI 0 "register_operand" "=r,b")
6772 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6773 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6778 [(set_attr "type" "*,fp")
6779 (set_attr "fptype" "double")])
6781 (define_insn "*xordi3_sp64_dbl"
6782 [(set (match_operand:DI 0 "register_operand" "=r")
6783 (xor:DI (match_operand:DI 1 "register_operand" "r")
6784 (match_operand:DI 2 "const64_operand" "")))]
6786 && HOST_BITS_PER_WIDE_INT != 64)"
6789 (define_insn "xorsi3"
6790 [(set (match_operand:SI 0 "register_operand" "=r,d")
6791 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6792 (match_operand:SI 2 "arith_operand" "rI,d")))]
6797 [(set_attr "type" "*,fp")])
6800 [(set (match_operand:SI 0 "register_operand" "")
6801 (xor:SI (match_operand:SI 1 "register_operand" "")
6802 (match_operand:SI 2 "" "")))
6803 (clobber (match_operand:SI 3 "register_operand" ""))]
6804 "GET_CODE (operands[2]) == CONST_INT
6805 && !SMALL_INT32 (operands[2])
6806 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6807 [(set (match_dup 3) (match_dup 4))
6808 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6811 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6815 [(set (match_operand:SI 0 "register_operand" "")
6816 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6817 (match_operand:SI 2 "" ""))))
6818 (clobber (match_operand:SI 3 "register_operand" ""))]
6819 "GET_CODE (operands[2]) == CONST_INT
6820 && !SMALL_INT32 (operands[2])
6821 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6822 [(set (match_dup 3) (match_dup 4))
6823 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6826 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6829 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6830 ;; Combine now canonicalizes to the rightmost expression.
6831 (define_insn "*xor_not_di_sp32"
6832 [(set (match_operand:DI 0 "register_operand" "=r,b")
6833 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6834 (match_operand:DI 2 "register_operand" "r,b"))))]
6839 [(set_attr "type" "*,fp")
6840 (set_attr "length" "2,*")
6841 (set_attr "fptype" "double")])
6844 [(set (match_operand:DI 0 "register_operand" "")
6845 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6846 (match_operand:DI 2 "register_operand" ""))))]
6849 && ((GET_CODE (operands[0]) == REG
6850 && REGNO (operands[0]) < 32)
6851 || (GET_CODE (operands[0]) == SUBREG
6852 && GET_CODE (SUBREG_REG (operands[0])) == REG
6853 && REGNO (SUBREG_REG (operands[0])) < 32))"
6854 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6855 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6856 "operands[3] = gen_highpart (SImode, operands[0]);
6857 operands[4] = gen_highpart (SImode, operands[1]);
6858 operands[5] = gen_highpart (SImode, operands[2]);
6859 operands[6] = gen_lowpart (SImode, operands[0]);
6860 operands[7] = gen_lowpart (SImode, operands[1]);
6861 operands[8] = gen_lowpart (SImode, operands[2]);")
6863 (define_insn "*xor_not_di_sp64"
6864 [(set (match_operand:DI 0 "register_operand" "=r,b")
6865 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6866 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6871 [(set_attr "type" "*,fp")
6872 (set_attr "fptype" "double")])
6874 (define_insn "*xor_not_si"
6875 [(set (match_operand:SI 0 "register_operand" "=r,d")
6876 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6877 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6881 fxnors\\t%1, %2, %0"
6882 [(set_attr "type" "*,fp")])
6884 ;; These correspond to the above in the case where we also (or only)
6885 ;; want to set the condition code.
6887 (define_insn "*cmp_cc_arith_op"
6890 (match_operator:SI 2 "cc_arithop"
6891 [(match_operand:SI 0 "arith_operand" "%r")
6892 (match_operand:SI 1 "arith_operand" "rI")])
6895 "%A2cc\\t%0, %1, %%g0"
6896 [(set_attr "type" "compare")])
6898 (define_insn "*cmp_ccx_arith_op"
6901 (match_operator:DI 2 "cc_arithop"
6902 [(match_operand:DI 0 "arith_double_operand" "%r")
6903 (match_operand:DI 1 "arith_double_operand" "rHI")])
6906 "%A2cc\\t%0, %1, %%g0"
6907 [(set_attr "type" "compare")])
6909 (define_insn "*cmp_cc_arith_op_set"
6912 (match_operator:SI 3 "cc_arithop"
6913 [(match_operand:SI 1 "arith_operand" "%r")
6914 (match_operand:SI 2 "arith_operand" "rI")])
6916 (set (match_operand:SI 0 "register_operand" "=r")
6917 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6918 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6919 "%A3cc\\t%1, %2, %0"
6920 [(set_attr "type" "compare")])
6922 (define_insn "*cmp_ccx_arith_op_set"
6925 (match_operator:DI 3 "cc_arithop"
6926 [(match_operand:DI 1 "arith_double_operand" "%r")
6927 (match_operand:DI 2 "arith_double_operand" "rHI")])
6929 (set (match_operand:DI 0 "register_operand" "=r")
6930 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6931 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6932 "%A3cc\\t%1, %2, %0"
6933 [(set_attr "type" "compare")])
6935 (define_insn "*cmp_cc_xor_not"
6938 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6939 (match_operand:SI 1 "arith_operand" "rI")))
6942 "xnorcc\\t%r0, %1, %%g0"
6943 [(set_attr "type" "compare")])
6945 (define_insn "*cmp_ccx_xor_not"
6948 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6949 (match_operand:DI 1 "arith_double_operand" "rHI")))
6952 "xnorcc\\t%r0, %1, %%g0"
6953 [(set_attr "type" "compare")])
6955 (define_insn "*cmp_cc_xor_not_set"
6958 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6959 (match_operand:SI 2 "arith_operand" "rI")))
6961 (set (match_operand:SI 0 "register_operand" "=r")
6962 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6964 "xnorcc\\t%r1, %2, %0"
6965 [(set_attr "type" "compare")])
6967 (define_insn "*cmp_ccx_xor_not_set"
6970 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6971 (match_operand:DI 2 "arith_double_operand" "rHI")))
6973 (set (match_operand:DI 0 "register_operand" "=r")
6974 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6976 "xnorcc\\t%r1, %2, %0"
6977 [(set_attr "type" "compare")])
6979 (define_insn "*cmp_cc_arith_op_not"
6982 (match_operator:SI 2 "cc_arithopn"
6983 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6984 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6987 "%B2cc\\t%r1, %0, %%g0"
6988 [(set_attr "type" "compare")])
6990 (define_insn "*cmp_ccx_arith_op_not"
6993 (match_operator:DI 2 "cc_arithopn"
6994 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6995 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6998 "%B2cc\\t%r1, %0, %%g0"
6999 [(set_attr "type" "compare")])
7001 (define_insn "*cmp_cc_arith_op_not_set"
7004 (match_operator:SI 3 "cc_arithopn"
7005 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7006 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7008 (set (match_operand:SI 0 "register_operand" "=r")
7009 (match_operator:SI 4 "cc_arithopn"
7010 [(not:SI (match_dup 1)) (match_dup 2)]))]
7011 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7012 "%B3cc\\t%r2, %1, %0"
7013 [(set_attr "type" "compare")])
7015 (define_insn "*cmp_ccx_arith_op_not_set"
7018 (match_operator:DI 3 "cc_arithopn"
7019 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7020 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7022 (set (match_operand:DI 0 "register_operand" "=r")
7023 (match_operator:DI 4 "cc_arithopn"
7024 [(not:DI (match_dup 1)) (match_dup 2)]))]
7025 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7026 "%B3cc\\t%r2, %1, %0"
7027 [(set_attr "type" "compare")])
7029 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7030 ;; does not know how to make it work for constants.
7032 (define_expand "negdi2"
7033 [(set (match_operand:DI 0 "register_operand" "=r")
7034 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7038 if (! TARGET_ARCH64)
7040 emit_insn (gen_rtx_PARALLEL
7043 gen_rtx_SET (VOIDmode, operand0,
7044 gen_rtx_NEG (DImode, operand1)),
7045 gen_rtx_CLOBBER (VOIDmode,
7046 gen_rtx_REG (CCmode,
7052 (define_insn "*negdi2_sp32"
7053 [(set (match_operand:DI 0 "register_operand" "=r")
7054 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7055 (clobber (reg:CC 100))]
7058 [(set_attr "length" "2")])
7061 [(set (match_operand:DI 0 "register_operand" "")
7062 (neg:DI (match_operand:DI 1 "register_operand" "")))
7063 (clobber (reg:CC 100))]
7065 && reload_completed"
7066 [(parallel [(set (reg:CC_NOOV 100)
7067 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7069 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7070 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7071 (ltu:SI (reg:CC 100) (const_int 0))))]
7072 "operands[2] = gen_highpart (SImode, operands[0]);
7073 operands[3] = gen_highpart (SImode, operands[1]);
7074 operands[4] = gen_lowpart (SImode, operands[0]);
7075 operands[5] = gen_lowpart (SImode, operands[1]);")
7077 (define_insn "*negdi2_sp64"
7078 [(set (match_operand:DI 0 "register_operand" "=r")
7079 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7081 "sub\\t%%g0, %1, %0")
7083 (define_insn "negsi2"
7084 [(set (match_operand:SI 0 "register_operand" "=r")
7085 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7087 "sub\\t%%g0, %1, %0")
7089 (define_insn "*cmp_cc_neg"
7090 [(set (reg:CC_NOOV 100)
7091 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7094 "subcc\\t%%g0, %0, %%g0"
7095 [(set_attr "type" "compare")])
7097 (define_insn "*cmp_ccx_neg"
7098 [(set (reg:CCX_NOOV 100)
7099 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7102 "subcc\\t%%g0, %0, %%g0"
7103 [(set_attr "type" "compare")])
7105 (define_insn "*cmp_cc_set_neg"
7106 [(set (reg:CC_NOOV 100)
7107 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7109 (set (match_operand:SI 0 "register_operand" "=r")
7110 (neg:SI (match_dup 1)))]
7112 "subcc\\t%%g0, %1, %0"
7113 [(set_attr "type" "compare")])
7115 (define_insn "*cmp_ccx_set_neg"
7116 [(set (reg:CCX_NOOV 100)
7117 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7119 (set (match_operand:DI 0 "register_operand" "=r")
7120 (neg:DI (match_dup 1)))]
7122 "subcc\\t%%g0, %1, %0"
7123 [(set_attr "type" "compare")])
7125 ;; We cannot use the "not" pseudo insn because the Sun assembler
7126 ;; does not know how to make it work for constants.
7127 (define_expand "one_cmpldi2"
7128 [(set (match_operand:DI 0 "register_operand" "")
7129 (not:DI (match_operand:DI 1 "register_operand" "")))]
7133 (define_insn "*one_cmpldi2_sp32"
7134 [(set (match_operand:DI 0 "register_operand" "=r,b")
7135 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7140 [(set_attr "type" "*,fp")
7141 (set_attr "length" "2,*")
7142 (set_attr "fptype" "double")])
7145 [(set (match_operand:DI 0 "register_operand" "")
7146 (not:DI (match_operand:DI 1 "register_operand" "")))]
7149 && ((GET_CODE (operands[0]) == REG
7150 && REGNO (operands[0]) < 32)
7151 || (GET_CODE (operands[0]) == SUBREG
7152 && GET_CODE (SUBREG_REG (operands[0])) == REG
7153 && REGNO (SUBREG_REG (operands[0])) < 32))"
7154 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7155 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7156 "operands[2] = gen_highpart (SImode, operands[0]);
7157 operands[3] = gen_highpart (SImode, operands[1]);
7158 operands[4] = gen_lowpart (SImode, operands[0]);
7159 operands[5] = gen_lowpart (SImode, operands[1]);")
7161 (define_insn "*one_cmpldi2_sp64"
7162 [(set (match_operand:DI 0 "register_operand" "=r,b")
7163 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7168 [(set_attr "type" "*,fp")
7169 (set_attr "fptype" "double")])
7171 (define_insn "one_cmplsi2"
7172 [(set (match_operand:SI 0 "register_operand" "=r,d")
7173 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7178 [(set_attr "type" "*,fp")])
7180 (define_insn "*cmp_cc_not"
7182 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7185 "xnorcc\\t%%g0, %0, %%g0"
7186 [(set_attr "type" "compare")])
7188 (define_insn "*cmp_ccx_not"
7190 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7193 "xnorcc\\t%%g0, %0, %%g0"
7194 [(set_attr "type" "compare")])
7196 (define_insn "*cmp_cc_set_not"
7198 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7200 (set (match_operand:SI 0 "register_operand" "=r")
7201 (not:SI (match_dup 1)))]
7203 "xnorcc\\t%%g0, %1, %0"
7204 [(set_attr "type" "compare")])
7206 (define_insn "*cmp_ccx_set_not"
7208 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7210 (set (match_operand:DI 0 "register_operand" "=r")
7211 (not:DI (match_dup 1)))]
7213 "xnorcc\\t%%g0, %1, %0"
7214 [(set_attr "type" "compare")])
7216 ;; Floating point arithmetic instructions.
7218 (define_expand "addtf3"
7219 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7220 (plus:TF (match_operand:TF 1 "general_operand" "")
7221 (match_operand:TF 2 "general_operand" "")))]
7222 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7225 if (! TARGET_HARD_QUAD)
7227 rtx slot0, slot1, slot2;
7229 if (GET_CODE (operands[0]) != MEM)
7230 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7232 slot0 = operands[0];
7233 if (GET_CODE (operands[1]) != MEM)
7235 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7236 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7239 slot1 = operands[1];
7240 if (GET_CODE (operands[2]) != MEM)
7242 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7243 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7246 slot2 = operands[2];
7248 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7250 XEXP (slot0, 0), Pmode,
7251 XEXP (slot1, 0), Pmode,
7252 XEXP (slot2, 0), Pmode);
7254 if (GET_CODE (operands[0]) != MEM)
7255 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7260 (define_insn "*addtf3_hq"
7261 [(set (match_operand:TF 0 "register_operand" "=e")
7262 (plus:TF (match_operand:TF 1 "register_operand" "e")
7263 (match_operand:TF 2 "register_operand" "e")))]
7264 "TARGET_FPU && TARGET_HARD_QUAD"
7265 "faddq\\t%1, %2, %0"
7266 [(set_attr "type" "fp")])
7268 (define_insn "adddf3"
7269 [(set (match_operand:DF 0 "register_operand" "=e")
7270 (plus:DF (match_operand:DF 1 "register_operand" "e")
7271 (match_operand:DF 2 "register_operand" "e")))]
7273 "faddd\\t%1, %2, %0"
7274 [(set_attr "type" "fp")
7275 (set_attr "fptype" "double")])
7277 (define_insn "addsf3"
7278 [(set (match_operand:SF 0 "register_operand" "=f")
7279 (plus:SF (match_operand:SF 1 "register_operand" "f")
7280 (match_operand:SF 2 "register_operand" "f")))]
7282 "fadds\\t%1, %2, %0"
7283 [(set_attr "type" "fp")])
7285 (define_expand "subtf3"
7286 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7287 (minus:TF (match_operand:TF 1 "general_operand" "")
7288 (match_operand:TF 2 "general_operand" "")))]
7289 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7292 if (! TARGET_HARD_QUAD)
7294 rtx slot0, slot1, slot2;
7296 if (GET_CODE (operands[0]) != MEM)
7297 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7299 slot0 = operands[0];
7300 if (GET_CODE (operands[1]) != MEM)
7302 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7303 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7306 slot1 = operands[1];
7307 if (GET_CODE (operands[2]) != MEM)
7309 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7310 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7313 slot2 = operands[2];
7315 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7317 XEXP (slot0, 0), Pmode,
7318 XEXP (slot1, 0), Pmode,
7319 XEXP (slot2, 0), Pmode);
7321 if (GET_CODE (operands[0]) != MEM)
7322 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7327 (define_insn "*subtf3_hq"
7328 [(set (match_operand:TF 0 "register_operand" "=e")
7329 (minus:TF (match_operand:TF 1 "register_operand" "e")
7330 (match_operand:TF 2 "register_operand" "e")))]
7331 "TARGET_FPU && TARGET_HARD_QUAD"
7332 "fsubq\\t%1, %2, %0"
7333 [(set_attr "type" "fp")])
7335 (define_insn "subdf3"
7336 [(set (match_operand:DF 0 "register_operand" "=e")
7337 (minus:DF (match_operand:DF 1 "register_operand" "e")
7338 (match_operand:DF 2 "register_operand" "e")))]
7340 "fsubd\\t%1, %2, %0"
7341 [(set_attr "type" "fp")
7342 (set_attr "fptype" "double")])
7344 (define_insn "subsf3"
7345 [(set (match_operand:SF 0 "register_operand" "=f")
7346 (minus:SF (match_operand:SF 1 "register_operand" "f")
7347 (match_operand:SF 2 "register_operand" "f")))]
7349 "fsubs\\t%1, %2, %0"
7350 [(set_attr "type" "fp")])
7352 (define_expand "multf3"
7353 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7354 (mult:TF (match_operand:TF 1 "general_operand" "")
7355 (match_operand:TF 2 "general_operand" "")))]
7356 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7359 if (! TARGET_HARD_QUAD)
7361 rtx slot0, slot1, slot2;
7363 if (GET_CODE (operands[0]) != MEM)
7364 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7366 slot0 = operands[0];
7367 if (GET_CODE (operands[1]) != MEM)
7369 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7370 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7373 slot1 = operands[1];
7374 if (GET_CODE (operands[2]) != MEM)
7376 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7377 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7380 slot2 = operands[2];
7382 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7384 XEXP (slot0, 0), Pmode,
7385 XEXP (slot1, 0), Pmode,
7386 XEXP (slot2, 0), Pmode);
7388 if (GET_CODE (operands[0]) != MEM)
7389 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7394 (define_insn "*multf3_hq"
7395 [(set (match_operand:TF 0 "register_operand" "=e")
7396 (mult:TF (match_operand:TF 1 "register_operand" "e")
7397 (match_operand:TF 2 "register_operand" "e")))]
7398 "TARGET_FPU && TARGET_HARD_QUAD"
7399 "fmulq\\t%1, %2, %0"
7400 [(set_attr "type" "fpmul")])
7402 (define_insn "muldf3"
7403 [(set (match_operand:DF 0 "register_operand" "=e")
7404 (mult:DF (match_operand:DF 1 "register_operand" "e")
7405 (match_operand:DF 2 "register_operand" "e")))]
7407 "fmuld\\t%1, %2, %0"
7408 [(set_attr "type" "fpmul")
7409 (set_attr "fptype" "double")])
7411 (define_insn "mulsf3"
7412 [(set (match_operand:SF 0 "register_operand" "=f")
7413 (mult:SF (match_operand:SF 1 "register_operand" "f")
7414 (match_operand:SF 2 "register_operand" "f")))]
7416 "fmuls\\t%1, %2, %0"
7417 [(set_attr "type" "fpmul")])
7419 (define_insn "*muldf3_extend"
7420 [(set (match_operand:DF 0 "register_operand" "=e")
7421 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7422 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7423 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7424 "fsmuld\\t%1, %2, %0"
7425 [(set_attr "type" "fpmul")
7426 (set_attr "fptype" "double")])
7428 (define_insn "*multf3_extend"
7429 [(set (match_operand:TF 0 "register_operand" "=e")
7430 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7431 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7432 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7433 "fdmulq\\t%1, %2, %0"
7434 [(set_attr "type" "fpmul")])
7436 (define_expand "divtf3"
7437 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7438 (div:TF (match_operand:TF 1 "general_operand" "")
7439 (match_operand:TF 2 "general_operand" "")))]
7440 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7443 if (! TARGET_HARD_QUAD)
7445 rtx slot0, slot1, slot2;
7447 if (GET_CODE (operands[0]) != MEM)
7448 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7450 slot0 = operands[0];
7451 if (GET_CODE (operands[1]) != MEM)
7453 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7454 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7457 slot1 = operands[1];
7458 if (GET_CODE (operands[2]) != MEM)
7460 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7461 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7464 slot2 = operands[2];
7466 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7468 XEXP (slot0, 0), Pmode,
7469 XEXP (slot1, 0), Pmode,
7470 XEXP (slot2, 0), Pmode);
7472 if (GET_CODE (operands[0]) != MEM)
7473 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7478 ;; don't have timing for quad-prec. divide.
7479 (define_insn "*divtf3_hq"
7480 [(set (match_operand:TF 0 "register_operand" "=e")
7481 (div:TF (match_operand:TF 1 "register_operand" "e")
7482 (match_operand:TF 2 "register_operand" "e")))]
7483 "TARGET_FPU && TARGET_HARD_QUAD"
7484 "fdivq\\t%1, %2, %0"
7485 [(set_attr "type" "fpdivd")])
7487 (define_insn "divdf3"
7488 [(set (match_operand:DF 0 "register_operand" "=e")
7489 (div:DF (match_operand:DF 1 "register_operand" "e")
7490 (match_operand:DF 2 "register_operand" "e")))]
7492 "fdivd\\t%1, %2, %0"
7493 [(set_attr "type" "fpdivd")
7494 (set_attr "fptype" "double")])
7496 (define_insn "divsf3"
7497 [(set (match_operand:SF 0 "register_operand" "=f")
7498 (div:SF (match_operand:SF 1 "register_operand" "f")
7499 (match_operand:SF 2 "register_operand" "f")))]
7501 "fdivs\\t%1, %2, %0"
7502 [(set_attr "type" "fpdivs")])
7504 (define_expand "negtf2"
7505 [(set (match_operand:TF 0 "register_operand" "=e,e")
7506 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7510 (define_insn "*negtf2_notv9"
7511 [(set (match_operand:TF 0 "register_operand" "=e,e")
7512 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7513 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7519 [(set_attr "type" "fpmove,*")
7520 (set_attr "length" "*,2")])
7523 [(set (match_operand:TF 0 "register_operand" "")
7524 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7528 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7529 [(set (match_dup 2) (neg:SF (match_dup 3)))
7530 (set (match_dup 4) (match_dup 5))
7531 (set (match_dup 6) (match_dup 7))]
7532 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7533 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7534 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7535 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7536 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7537 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7539 (define_insn "*negtf2_v9"
7540 [(set (match_operand:TF 0 "register_operand" "=e,e")
7541 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7542 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7543 "TARGET_FPU && TARGET_V9"
7547 [(set_attr "type" "fpmove,*")
7548 (set_attr "length" "*,2")
7549 (set_attr "fptype" "double")])
7552 [(set (match_operand:TF 0 "register_operand" "")
7553 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7557 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7558 [(set (match_dup 2) (neg:DF (match_dup 3)))
7559 (set (match_dup 4) (match_dup 5))]
7560 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7561 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7562 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7563 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7565 (define_expand "negdf2"
7566 [(set (match_operand:DF 0 "register_operand" "")
7567 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7571 (define_insn "*negdf2_notv9"
7572 [(set (match_operand:DF 0 "register_operand" "=e,e")
7573 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7574 "TARGET_FPU && ! TARGET_V9"
7578 [(set_attr "type" "fpmove,*")
7579 (set_attr "length" "*,2")])
7582 [(set (match_operand:DF 0 "register_operand" "")
7583 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7587 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7588 [(set (match_dup 2) (neg:SF (match_dup 3)))
7589 (set (match_dup 4) (match_dup 5))]
7590 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7591 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7592 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7593 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7595 (define_insn "*negdf2_v9"
7596 [(set (match_operand:DF 0 "register_operand" "=e")
7597 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7598 "TARGET_FPU && TARGET_V9"
7600 [(set_attr "type" "fpmove")
7601 (set_attr "fptype" "double")])
7603 (define_insn "negsf2"
7604 [(set (match_operand:SF 0 "register_operand" "=f")
7605 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7608 [(set_attr "type" "fpmove")])
7610 (define_expand "abstf2"
7611 [(set (match_operand:TF 0 "register_operand" "")
7612 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7616 (define_insn "*abstf2_notv9"
7617 [(set (match_operand:TF 0 "register_operand" "=e,e")
7618 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7619 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7620 "TARGET_FPU && ! TARGET_V9"
7624 [(set_attr "type" "fpmove,*")
7625 (set_attr "length" "*,2")])
7628 [(set (match_operand:TF 0 "register_operand" "")
7629 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7633 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7634 [(set (match_dup 2) (abs:SF (match_dup 3)))
7635 (set (match_dup 4) (match_dup 5))
7636 (set (match_dup 6) (match_dup 7))]
7637 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7638 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7639 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7640 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7641 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7642 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7644 (define_insn "*abstf2_hq_v9"
7645 [(set (match_operand:TF 0 "register_operand" "=e,e")
7646 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7647 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7651 [(set_attr "type" "fpmove")
7652 (set_attr "fptype" "double,*")])
7654 (define_insn "*abstf2_v9"
7655 [(set (match_operand:TF 0 "register_operand" "=e,e")
7656 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7657 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7661 [(set_attr "type" "fpmove,*")
7662 (set_attr "length" "*,2")
7663 (set_attr "fptype" "double,*")])
7666 [(set (match_operand:TF 0 "register_operand" "")
7667 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7671 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7672 [(set (match_dup 2) (abs:DF (match_dup 3)))
7673 (set (match_dup 4) (match_dup 5))]
7674 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7675 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7676 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7677 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7679 (define_expand "absdf2"
7680 [(set (match_operand:DF 0 "register_operand" "")
7681 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7685 (define_insn "*absdf2_notv9"
7686 [(set (match_operand:DF 0 "register_operand" "=e,e")
7687 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7688 "TARGET_FPU && ! TARGET_V9"
7692 [(set_attr "type" "fpmove,*")
7693 (set_attr "length" "*,2")])
7696 [(set (match_operand:DF 0 "register_operand" "")
7697 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7701 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7702 [(set (match_dup 2) (abs:SF (match_dup 3)))
7703 (set (match_dup 4) (match_dup 5))]
7704 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7705 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7706 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7707 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7709 (define_insn "*absdf2_v9"
7710 [(set (match_operand:DF 0 "register_operand" "=e")
7711 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7712 "TARGET_FPU && TARGET_V9"
7714 [(set_attr "type" "fpmove")
7715 (set_attr "fptype" "double")])
7717 (define_insn "abssf2"
7718 [(set (match_operand:SF 0 "register_operand" "=f")
7719 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7722 [(set_attr "type" "fpmove")])
7724 (define_expand "sqrttf2"
7725 [(set (match_operand:TF 0 "register_operand" "=e")
7726 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7727 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7730 if (! TARGET_HARD_QUAD)
7734 if (GET_CODE (operands[0]) != MEM)
7735 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7737 slot0 = operands[0];
7738 if (GET_CODE (operands[1]) != MEM)
7740 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7741 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7744 slot1 = operands[1];
7746 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7748 XEXP (slot0, 0), Pmode,
7749 XEXP (slot1, 0), Pmode);
7751 if (GET_CODE (operands[0]) != MEM)
7752 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7757 (define_insn "*sqrttf2_hq"
7758 [(set (match_operand:TF 0 "register_operand" "=e")
7759 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7760 "TARGET_FPU && TARGET_HARD_QUAD"
7762 [(set_attr "type" "fpsqrtd")])
7764 (define_insn "sqrtdf2"
7765 [(set (match_operand:DF 0 "register_operand" "=e")
7766 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7769 [(set_attr "type" "fpsqrtd")
7770 (set_attr "fptype" "double")])
7772 (define_insn "sqrtsf2"
7773 [(set (match_operand:SF 0 "register_operand" "=f")
7774 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7777 [(set_attr "type" "fpsqrts")])
7779 ;;- arithmetic shift instructions
7781 (define_insn "ashlsi3"
7782 [(set (match_operand:SI 0 "register_operand" "=r")
7783 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7784 (match_operand:SI 2 "arith_operand" "rI")))]
7788 if (GET_CODE (operands[2]) == CONST_INT
7789 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7790 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7792 return \"sll\\t%1, %2, %0\";
7794 [(set_attr "type" "shift")])
7796 ;; We special case multiplication by two, as add can be done
7797 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7798 (define_insn "*ashlsi3_const1"
7799 [(set (match_operand:SI 0 "register_operand" "=r")
7800 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7805 (define_expand "ashldi3"
7806 [(set (match_operand:DI 0 "register_operand" "=r")
7807 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7808 (match_operand:SI 2 "arith_operand" "rI")))]
7809 "TARGET_ARCH64 || TARGET_V8PLUS"
7812 if (! TARGET_ARCH64)
7814 if (GET_CODE (operands[2]) == CONST_INT)
7816 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7821 ;; We special case multiplication by two, as add can be done
7822 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7823 (define_insn "*ashldi3_const1"
7824 [(set (match_operand:DI 0 "register_operand" "=r")
7825 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7830 (define_insn "*ashldi3_sp64"
7831 [(set (match_operand:DI 0 "register_operand" "=r")
7832 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7833 (match_operand:SI 2 "arith_operand" "rI")))]
7837 if (GET_CODE (operands[2]) == CONST_INT
7838 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7839 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7841 return \"sllx\\t%1, %2, %0\";
7843 [(set_attr "type" "shift")])
7846 (define_insn "ashldi3_v8plus"
7847 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7848 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7849 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7850 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7852 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7853 [(set_attr "type" "multi")
7854 (set_attr "length" "5,5,6")])
7856 ;; Optimize (1LL<<x)-1
7857 ;; XXX this also needs to be fixed to handle equal subregs
7858 ;; XXX first before we could re-enable it.
7860 ; [(set (match_operand:DI 0 "register_operand" "=h")
7861 ; (plus:DI (ashift:DI (const_int 1)
7862 ; (match_operand:SI 1 "arith_operand" "rI"))
7864 ; "0 && TARGET_V8PLUS"
7867 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7868 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7869 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7871 ; [(set_attr "type" "multi")
7872 ; (set_attr "length" "4")])
7874 (define_insn "*cmp_cc_ashift_1"
7875 [(set (reg:CC_NOOV 100)
7876 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7880 "addcc\\t%0, %0, %%g0"
7881 [(set_attr "type" "compare")])
7883 (define_insn "*cmp_cc_set_ashift_1"
7884 [(set (reg:CC_NOOV 100)
7885 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7888 (set (match_operand:SI 0 "register_operand" "=r")
7889 (ashift:SI (match_dup 1) (const_int 1)))]
7891 "addcc\\t%1, %1, %0"
7892 [(set_attr "type" "compare")])
7894 (define_insn "ashrsi3"
7895 [(set (match_operand:SI 0 "register_operand" "=r")
7896 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7897 (match_operand:SI 2 "arith_operand" "rI")))]
7901 if (GET_CODE (operands[2]) == CONST_INT
7902 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7903 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7905 return \"sra\\t%1, %2, %0\";
7907 [(set_attr "type" "shift")])
7909 (define_insn "*ashrsi3_extend"
7910 [(set (match_operand:DI 0 "register_operand" "=r")
7911 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7912 (match_operand:SI 2 "arith_operand" "r"))))]
7915 [(set_attr "type" "shift")])
7917 ;; This handles the case as above, but with constant shift instead of
7918 ;; register. Combiner "simplifies" it for us a little bit though.
7919 (define_insn "*ashrsi3_extend2"
7920 [(set (match_operand:DI 0 "register_operand" "=r")
7921 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7923 (match_operand:SI 2 "small_int_or_double" "n")))]
7925 && ((GET_CODE (operands[2]) == CONST_INT
7926 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7927 || (GET_CODE (operands[2]) == CONST_DOUBLE
7928 && !CONST_DOUBLE_HIGH (operands[2])
7929 && CONST_DOUBLE_LOW (operands[2]) >= 32
7930 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7933 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7935 return \"sra\\t%1, %2, %0\";
7937 [(set_attr "type" "shift")])
7939 (define_expand "ashrdi3"
7940 [(set (match_operand:DI 0 "register_operand" "=r")
7941 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7942 (match_operand:SI 2 "arith_operand" "rI")))]
7943 "TARGET_ARCH64 || TARGET_V8PLUS"
7946 if (! TARGET_ARCH64)
7948 if (GET_CODE (operands[2]) == CONST_INT)
7949 FAIL; /* prefer generic code in this case */
7950 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7956 [(set (match_operand:DI 0 "register_operand" "=r")
7957 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7958 (match_operand:SI 2 "arith_operand" "rI")))]
7962 if (GET_CODE (operands[2]) == CONST_INT
7963 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7964 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7966 return \"srax\\t%1, %2, %0\";
7968 [(set_attr "type" "shift")])
7971 (define_insn "ashrdi3_v8plus"
7972 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7973 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7974 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7975 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7977 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7978 [(set_attr "type" "multi")
7979 (set_attr "length" "5,5,6")])
7981 (define_insn "lshrsi3"
7982 [(set (match_operand:SI 0 "register_operand" "=r")
7983 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7984 (match_operand:SI 2 "arith_operand" "rI")))]
7988 if (GET_CODE (operands[2]) == CONST_INT
7989 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7990 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7992 return \"srl\\t%1, %2, %0\";
7994 [(set_attr "type" "shift")])
7996 ;; This handles the case where
7997 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7998 ;; but combiner "simplifies" it for us.
7999 (define_insn "*lshrsi3_extend"
8000 [(set (match_operand:DI 0 "register_operand" "=r")
8001 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8002 (match_operand:SI 2 "arith_operand" "r")) 0)
8003 (match_operand 3 "" "")))]
8005 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8006 && CONST_DOUBLE_HIGH (operands[3]) == 0
8007 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8008 || (HOST_BITS_PER_WIDE_INT >= 64
8009 && GET_CODE (operands[3]) == CONST_INT
8010 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8012 [(set_attr "type" "shift")])
8014 ;; This handles the case where
8015 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8016 ;; but combiner "simplifies" it for us.
8017 (define_insn "*lshrsi3_extend2"
8018 [(set (match_operand:DI 0 "register_operand" "=r")
8019 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8020 (match_operand 2 "small_int_or_double" "n")
8023 && ((GET_CODE (operands[2]) == CONST_INT
8024 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8025 || (GET_CODE (operands[2]) == CONST_DOUBLE
8026 && CONST_DOUBLE_HIGH (operands[2]) == 0
8027 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8030 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8032 return \"srl\\t%1, %2, %0\";
8034 [(set_attr "type" "shift")])
8036 (define_expand "lshrdi3"
8037 [(set (match_operand:DI 0 "register_operand" "=r")
8038 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8039 (match_operand:SI 2 "arith_operand" "rI")))]
8040 "TARGET_ARCH64 || TARGET_V8PLUS"
8043 if (! TARGET_ARCH64)
8045 if (GET_CODE (operands[2]) == CONST_INT)
8047 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8053 [(set (match_operand:DI 0 "register_operand" "=r")
8054 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8055 (match_operand:SI 2 "arith_operand" "rI")))]
8059 if (GET_CODE (operands[2]) == CONST_INT
8060 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8061 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8063 return \"srlx\\t%1, %2, %0\";
8065 [(set_attr "type" "shift")])
8068 (define_insn "lshrdi3_v8plus"
8069 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8070 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8071 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8072 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8074 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8075 [(set_attr "type" "multi")
8076 (set_attr "length" "5,5,6")])
8079 [(set (match_operand:SI 0 "register_operand" "=r")
8080 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8082 (match_operand:SI 2 "small_int_or_double" "n")))]
8084 && ((GET_CODE (operands[2]) == CONST_INT
8085 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8086 || (GET_CODE (operands[2]) == CONST_DOUBLE
8087 && !CONST_DOUBLE_HIGH (operands[2])
8088 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8091 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8093 return \"srax\\t%1, %2, %0\";
8095 [(set_attr "type" "shift")])
8098 [(set (match_operand:SI 0 "register_operand" "=r")
8099 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8101 (match_operand:SI 2 "small_int_or_double" "n")))]
8103 && ((GET_CODE (operands[2]) == CONST_INT
8104 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8105 || (GET_CODE (operands[2]) == CONST_DOUBLE
8106 && !CONST_DOUBLE_HIGH (operands[2])
8107 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8110 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8112 return \"srlx\\t%1, %2, %0\";
8114 [(set_attr "type" "shift")])
8117 [(set (match_operand:SI 0 "register_operand" "=r")
8118 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8119 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8120 (match_operand:SI 3 "small_int_or_double" "n")))]
8122 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8123 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8124 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8125 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8128 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8130 return \"srax\\t%1, %2, %0\";
8132 [(set_attr "type" "shift")])
8135 [(set (match_operand:SI 0 "register_operand" "=r")
8136 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8137 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8138 (match_operand:SI 3 "small_int_or_double" "n")))]
8140 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8141 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8142 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8143 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8146 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8148 return \"srlx\\t%1, %2, %0\";
8150 [(set_attr "type" "shift")])
8152 ;; Unconditional and other jump instructions
8153 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8154 ;; following insn is never executed. This saves us a nop. Dbx does not
8155 ;; handle such branches though, so we only use them when optimizing.
8157 [(set (pc) (label_ref (match_operand 0 "" "")))]
8161 /* TurboSparc is reported to have problems with
8164 i.e. an empty loop with the annul bit set. The workaround is to use
8168 if (! TARGET_V9 && flag_delayed_branch
8169 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8170 == INSN_ADDRESSES (INSN_UID (insn))))
8171 return \"b\\t%l0%#\";
8173 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8175 [(set_attr "type" "uncond_branch")])
8177 (define_expand "tablejump"
8178 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8179 (use (label_ref (match_operand 1 "" "")))])]
8183 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8186 /* In pic mode, our address differences are against the base of the
8187 table. Add that base value back in; CSE ought to be able to combine
8188 the two address loads. */
8192 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8194 if (CASE_VECTOR_MODE != Pmode)
8195 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8196 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8197 operands[0] = memory_address (Pmode, tmp);
8201 (define_insn "*tablejump_sp32"
8202 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8203 (use (label_ref (match_operand 1 "" "")))]
8206 [(set_attr "type" "uncond_branch")])
8208 (define_insn "*tablejump_sp64"
8209 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8210 (use (label_ref (match_operand 1 "" "")))]
8213 [(set_attr "type" "uncond_branch")])
8215 ;; This pattern recognizes the "instruction" that appears in
8216 ;; a function call that wants a structure value,
8217 ;; to inform the called function if compiled with Sun CC.
8218 ;(define_insn "*unimp_insn"
8219 ; [(match_operand:SI 0 "immediate_operand" "")]
8220 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8222 ; [(set_attr "type" "marker")])
8224 ;;- jump to subroutine
8225 (define_expand "call"
8226 ;; Note that this expression is not used for generating RTL.
8227 ;; All the RTL is generated explicitly below.
8228 [(call (match_operand 0 "call_operand" "")
8229 (match_operand 3 "" "i"))]
8230 ;; operands[2] is next_arg_register
8231 ;; operands[3] is struct_value_size_rtx.
8235 rtx fn_rtx, nregs_rtx;
8237 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8240 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8242 /* This is really a PIC sequence. We want to represent
8243 it as a funny jump so its delay slots can be filled.
8245 ??? But if this really *is* a CALL, will not it clobber the
8246 call-clobbered registers? We lose this if it is a JUMP_INSN.
8247 Why cannot we have delay slots filled if it were a CALL? */
8249 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8254 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8256 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8262 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8263 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8267 fn_rtx = operands[0];
8269 /* Count the number of parameter registers being used by this call.
8270 if that argument is NULL, it means we are using them all, which
8271 means 6 on the sparc. */
8274 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8276 nregs_rtx = GEN_INT (6);
8278 nregs_rtx = const0_rtx;
8281 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8285 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8287 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8292 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8293 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8297 /* If this call wants a structure value,
8298 emit an unimp insn to let the called function know about this. */
8299 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8301 rtx insn = emit_insn (operands[3]);
8302 SCHED_GROUP_P (insn) = 1;
8309 ;; We can't use the same pattern for these two insns, because then registers
8310 ;; in the address may not be properly reloaded.
8312 (define_insn "*call_address_sp32"
8313 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8314 (match_operand 1 "" ""))
8315 (clobber (reg:SI 15))]
8316 ;;- Do not use operand 1 for most machines.
8319 [(set_attr "type" "call")])
8321 (define_insn "*call_symbolic_sp32"
8322 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8323 (match_operand 1 "" ""))
8324 (clobber (reg:SI 15))]
8325 ;;- Do not use operand 1 for most machines.
8328 [(set_attr "type" "call")])
8330 (define_insn "*call_address_sp64"
8331 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8332 (match_operand 1 "" ""))
8333 (clobber (reg:DI 15))]
8334 ;;- Do not use operand 1 for most machines.
8337 [(set_attr "type" "call")])
8339 (define_insn "*call_symbolic_sp64"
8340 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8341 (match_operand 1 "" ""))
8342 (clobber (reg:DI 15))]
8343 ;;- Do not use operand 1 for most machines.
8346 [(set_attr "type" "call")])
8348 ;; This is a call that wants a structure value.
8349 ;; There is no such critter for v9 (??? we may need one anyway).
8350 (define_insn "*call_address_struct_value_sp32"
8351 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8352 (match_operand 1 "" ""))
8353 (match_operand 2 "immediate_operand" "")
8354 (clobber (reg:SI 15))]
8355 ;;- Do not use operand 1 for most machines.
8356 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8357 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8358 [(set_attr "type" "call_no_delay_slot")])
8360 ;; This is a call that wants a structure value.
8361 ;; There is no such critter for v9 (??? we may need one anyway).
8362 (define_insn "*call_symbolic_struct_value_sp32"
8363 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8364 (match_operand 1 "" ""))
8365 (match_operand 2 "immediate_operand" "")
8366 (clobber (reg:SI 15))]
8367 ;;- Do not use operand 1 for most machines.
8368 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8369 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8370 [(set_attr "type" "call_no_delay_slot")])
8372 ;; This is a call that may want a structure value. This is used for
8374 (define_insn "*call_address_untyped_struct_value_sp32"
8375 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8376 (match_operand 1 "" ""))
8377 (match_operand 2 "immediate_operand" "")
8378 (clobber (reg:SI 15))]
8379 ;;- Do not use operand 1 for most machines.
8380 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8381 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8382 [(set_attr "type" "call_no_delay_slot")])
8384 ;; This is a call that wants a structure value.
8385 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8386 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8387 (match_operand 1 "" ""))
8388 (match_operand 2 "immediate_operand" "")
8389 (clobber (reg:SI 15))]
8390 ;;- Do not use operand 1 for most machines.
8391 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8392 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8393 [(set_attr "type" "call_no_delay_slot")])
8395 (define_expand "call_value"
8396 ;; Note that this expression is not used for generating RTL.
8397 ;; All the RTL is generated explicitly below.
8398 [(set (match_operand 0 "register_operand" "=rf")
8399 (call (match_operand 1 "" "")
8400 (match_operand 4 "" "")))]
8401 ;; operand 2 is stack_size_rtx
8402 ;; operand 3 is next_arg_register
8406 rtx fn_rtx, nregs_rtx;
8409 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8412 fn_rtx = operands[1];
8416 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8418 nregs_rtx = GEN_INT (6);
8420 nregs_rtx = const0_rtx;
8424 gen_rtx_SET (VOIDmode, operands[0],
8425 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8426 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8428 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8433 (define_insn "*call_value_address_sp32"
8434 [(set (match_operand 0 "" "=rf")
8435 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8436 (match_operand 2 "" "")))
8437 (clobber (reg:SI 15))]
8438 ;;- Do not use operand 2 for most machines.
8441 [(set_attr "type" "call")])
8443 (define_insn "*call_value_symbolic_sp32"
8444 [(set (match_operand 0 "" "=rf")
8445 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8446 (match_operand 2 "" "")))
8447 (clobber (reg:SI 15))]
8448 ;;- Do not use operand 2 for most machines.
8451 [(set_attr "type" "call")])
8453 (define_insn "*call_value_address_sp64"
8454 [(set (match_operand 0 "" "")
8455 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8456 (match_operand 2 "" "")))
8457 (clobber (reg:DI 15))]
8458 ;;- Do not use operand 2 for most machines.
8461 [(set_attr "type" "call")])
8463 (define_insn "*call_value_symbolic_sp64"
8464 [(set (match_operand 0 "" "")
8465 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8466 (match_operand 2 "" "")))
8467 (clobber (reg:DI 15))]
8468 ;;- Do not use operand 2 for most machines.
8471 [(set_attr "type" "call")])
8473 (define_expand "untyped_call"
8474 [(parallel [(call (match_operand 0 "" "")
8476 (match_operand 1 "" "")
8477 (match_operand 2 "" "")])]
8483 /* Pass constm1 to indicate that it may expect a structure value, but
8484 we don't know what size it is. */
8485 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8487 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8489 rtx set = XVECEXP (operands[2], 0, i);
8490 emit_move_insn (SET_DEST (set), SET_SRC (set));
8493 /* The optimizer does not know that the call sets the function value
8494 registers we stored in the result block. We avoid problems by
8495 claiming that all hard registers are used and clobbered at this
8497 emit_insn (gen_blockage ());
8503 (define_expand "sibcall"
8504 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8509 (define_insn "*sibcall_symbolic_sp32"
8510 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8511 (match_operand 1 "" ""))
8514 "* return output_sibcall(insn, operands[0]);"
8515 [(set_attr "type" "sibcall")])
8517 (define_insn "*sibcall_symbolic_sp64"
8518 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8519 (match_operand 1 "" ""))
8522 "* return output_sibcall(insn, operands[0]);"
8523 [(set_attr "type" "sibcall")])
8525 (define_expand "sibcall_value"
8526 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8527 (call (match_operand 1 "" "") (const_int 0)))
8532 (define_insn "*sibcall_value_symbolic_sp32"
8533 [(set (match_operand 0 "" "=rf")
8534 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8535 (match_operand 2 "" "")))
8538 "* return output_sibcall(insn, operands[1]);"
8539 [(set_attr "type" "sibcall")])
8541 (define_insn "*sibcall_value_symbolic_sp64"
8542 [(set (match_operand 0 "" "")
8543 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8544 (match_operand 2 "" "")))
8547 "* return output_sibcall(insn, operands[1]);"
8548 [(set_attr "type" "sibcall")])
8550 (define_expand "sibcall_epilogue"
8555 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8556 ;; all of memory. This blocks insns from being moved across this point.
8558 (define_insn "blockage"
8559 [(unspec_volatile [(const_int 0)] 0)]
8562 [(set_attr "length" "0")])
8564 ;; Prepare to return any type including a structure value.
8566 (define_expand "untyped_return"
8567 [(match_operand:BLK 0 "memory_operand" "")
8568 (match_operand 1 "" "")]
8572 rtx valreg1 = gen_rtx_REG (DImode, 24);
8573 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8574 rtx result = operands[0];
8576 if (! TARGET_ARCH64)
8578 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8580 rtx value = gen_reg_rtx (SImode);
8582 /* Fetch the instruction where we will return to and see if it's an unimp
8583 instruction (the most significant 10 bits will be zero). If so,
8584 update the return address to skip the unimp instruction. */
8585 emit_move_insn (value,
8586 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8587 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8588 emit_insn (gen_update_return (rtnreg, value));
8591 /* Reload the function value registers. */
8592 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8593 emit_move_insn (valreg2,
8594 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8596 /* Put USE insns before the return. */
8597 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8598 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8600 /* Construct the return. */
8601 expand_null_return ();
8606 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8607 ;; and parts of the compiler don't want to believe that the add is needed.
8609 (define_insn "update_return"
8610 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8611 (match_operand:SI 1 "register_operand" "r")] 1)]
8613 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8614 [(set_attr "type" "multi")
8615 (set_attr "length" "3")])
8617 (define_insn "return"
8621 "* return output_return (operands);"
8622 [(set_attr "type" "return")])
8625 [(set (match_operand:SI 0 "register_operand" "=r")
8626 (match_operand:SI 1 "arith_operand" "rI"))
8628 (use (reg:SI 31))])]
8629 "sparc_return_peephole_ok (operands[0], operands[1])"
8630 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8637 (define_expand "indirect_jump"
8638 [(set (pc) (match_operand 0 "address_operand" "p"))]
8642 (define_insn "*branch_sp32"
8643 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8646 [(set_attr "type" "uncond_branch")])
8648 (define_insn "*branch_sp64"
8649 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8652 [(set_attr "type" "uncond_branch")])
8654 ;; ??? Doesn't work with -mflat.
8655 (define_expand "nonlocal_goto"
8656 [(match_operand:SI 0 "general_operand" "")
8657 (match_operand:SI 1 "general_operand" "")
8658 (match_operand:SI 2 "general_operand" "")
8659 (match_operand:SI 3 "" "")]
8664 rtx chain = operands[0];
8666 rtx lab = operands[1];
8667 rtx stack = operands[2];
8668 rtx fp = operands[3];
8671 /* Trap instruction to flush all the register windows. */
8672 emit_insn (gen_flush_register_windows ());
8674 /* Load the fp value for the containing fn into %fp. This is needed
8675 because STACK refers to %fp. Note that virtual register instantiation
8676 fails if the virtual %fp isn't set from a register. */
8677 if (GET_CODE (fp) != REG)
8678 fp = force_reg (Pmode, fp);
8679 emit_move_insn (virtual_stack_vars_rtx, fp);
8681 /* Find the containing function's current nonlocal goto handler,
8682 which will do any cleanups and then jump to the label. */
8683 labreg = gen_rtx_REG (Pmode, 8);
8684 emit_move_insn (labreg, lab);
8686 /* Restore %fp from stack pointer value for containing function.
8687 The restore insn that follows will move this to %sp,
8688 and reload the appropriate value into %fp. */
8689 emit_move_insn (frame_pointer_rtx, stack);
8691 /* USE of frame_pointer_rtx added for consistency; not clear if
8693 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8694 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8697 /* Return, restoring reg window and jumping to goto handler. */
8698 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8699 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8701 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8707 /* Put in the static chain register the nonlocal label address. */
8708 emit_move_insn (static_chain_rtx, chain);
8711 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8712 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8717 ;; Special trap insn to flush register windows.
8718 (define_insn "flush_register_windows"
8719 [(unspec_volatile [(const_int 0)] 1)]
8721 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8722 [(set_attr "type" "misc")])
8724 (define_insn "goto_handler_and_restore"
8725 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8726 "GET_MODE (operands[0]) == Pmode"
8727 "jmp\\t%0+0\\n\\trestore"
8728 [(set_attr "type" "multi")
8729 (set_attr "length" "2")])
8731 ;;(define_insn "goto_handler_and_restore_v9"
8732 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8733 ;; (match_operand:SI 1 "register_operand" "=r,r")
8734 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8735 ;; "TARGET_V9 && ! TARGET_ARCH64"
8737 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8738 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8739 ;; [(set_attr "type" "multi")
8740 ;; (set_attr "length" "2,3")])
8742 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8743 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8744 ;; (match_operand:DI 1 "register_operand" "=r,r")
8745 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8746 ;; "TARGET_V9 && TARGET_ARCH64"
8748 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8749 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8750 ;; [(set_attr "type" "multi")
8751 ;; (set_attr "length" "2,3")])
8753 ;; For __builtin_setjmp we need to flush register windows iff the function
8754 ;; calls alloca as well, because otherwise the register window might be
8755 ;; saved after %sp adjustement and thus setjmp would crash
8756 (define_expand "builtin_setjmp_setup"
8757 [(match_operand 0 "register_operand" "r")]
8761 emit_insn (gen_do_builtin_setjmp_setup ());
8765 ;; ??? Should set length to zero when !current_function_calls_alloca,
8766 ;; ??? but there is no easy way to get at that definition. It would
8767 ;; ??? require including function.h into sparc-protos.h and that is
8768 ;; ??? likely not a good idea. -DaveM
8769 (define_insn "do_builtin_setjmp_setup"
8770 [(unspec_volatile [(const_int 0)] 5)]
8774 if (!current_function_calls_alloca)
8780 [(set_attr "type" "misc")])
8782 ;; Pattern for use after a setjmp to store FP and the return register
8783 ;; into the stack area.
8785 (define_expand "setjmp"
8791 emit_insn (gen_setjmp_64 ());
8793 emit_insn (gen_setjmp_32 ());
8797 (define_expand "setjmp_32"
8798 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8799 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8802 { operands[0] = frame_pointer_rtx; }")
8804 (define_expand "setjmp_64"
8805 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8806 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8809 { operands[0] = frame_pointer_rtx; }")
8811 ;; Special pattern for the FLUSH instruction.
8813 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8814 ; of the define_insn otherwise missing a mode. We make "flush", aka
8815 ; gen_flush, the default one since sparc_initialize_trampoline uses
8816 ; it on SImode mem values.
8818 (define_insn "flush"
8819 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8821 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8822 [(set_attr "type" "misc")])
8824 (define_insn "flushdi"
8825 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8827 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8828 [(set_attr "type" "misc")])
8833 ;; The scan instruction searches from the most significant bit while ffs
8834 ;; searches from the least significant bit. The bit index and treatment of
8835 ;; zero also differ. It takes at least 7 instructions to get the proper
8836 ;; result. Here is an obvious 8 instruction sequence.
8839 (define_insn "ffssi2"
8840 [(set (match_operand:SI 0 "register_operand" "=&r")
8841 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8842 (clobber (match_scratch:SI 2 "=&r"))]
8843 "TARGET_SPARCLITE || TARGET_SPARCLET"
8846 return \"sub\\t%%g0, %1, %0\;and\\t%0, %1, %0\;scan\\t%0, 0, %0\;mov\\t32, %2\;sub\\t%2, %0, %0\;sra\\t%0, 31, %2\;and\\t%2, 31, %2\;add\\t%2, %0, %0\";
8848 [(set_attr "type" "multi")
8849 (set_attr "length" "8")])
8851 ;; ??? This should be a define expand, so that the extra instruction have
8852 ;; a chance of being optimized away.
8854 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8855 ;; does, but no one uses that and we don't have a switch for it.
8857 ;(define_insn "ffsdi2"
8858 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8859 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8860 ; (clobber (match_scratch:DI 2 "=&r"))]
8862 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8863 ; [(set_attr "type" "multi")
8864 ; (set_attr "length" "4")])
8868 ;; Peepholes go at the end.
8870 ;; Optimize consecutive loads or stores into ldd and std when possible.
8871 ;; The conditions in which we do this are very restricted and are
8872 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8875 [(set (match_operand:SI 0 "memory_operand" "")
8877 (set (match_operand:SI 1 "memory_operand" "")
8880 && ! MEM_VOLATILE_P (operands[0])
8881 && ! MEM_VOLATILE_P (operands[1])
8882 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8886 [(set (match_operand:SI 0 "memory_operand" "")
8888 (set (match_operand:SI 1 "memory_operand" "")
8891 && ! MEM_VOLATILE_P (operands[0])
8892 && ! MEM_VOLATILE_P (operands[1])
8893 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8897 [(set (match_operand:SI 0 "register_operand" "=rf")
8898 (match_operand:SI 1 "memory_operand" ""))
8899 (set (match_operand:SI 2 "register_operand" "=rf")
8900 (match_operand:SI 3 "memory_operand" ""))]
8901 "registers_ok_for_ldd_peep (operands[0], operands[2])
8902 && ! MEM_VOLATILE_P (operands[1])
8903 && ! MEM_VOLATILE_P (operands[3])
8904 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8908 [(set (match_operand:SI 0 "memory_operand" "")
8909 (match_operand:SI 1 "register_operand" "rf"))
8910 (set (match_operand:SI 2 "memory_operand" "")
8911 (match_operand:SI 3 "register_operand" "rf"))]
8912 "registers_ok_for_ldd_peep (operands[1], operands[3])
8913 && ! MEM_VOLATILE_P (operands[0])
8914 && ! MEM_VOLATILE_P (operands[2])
8915 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8919 [(set (match_operand:SF 0 "register_operand" "=fr")
8920 (match_operand:SF 1 "memory_operand" ""))
8921 (set (match_operand:SF 2 "register_operand" "=fr")
8922 (match_operand:SF 3 "memory_operand" ""))]
8923 "registers_ok_for_ldd_peep (operands[0], operands[2])
8924 && ! MEM_VOLATILE_P (operands[1])
8925 && ! MEM_VOLATILE_P (operands[3])
8926 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8930 [(set (match_operand:SF 0 "memory_operand" "")
8931 (match_operand:SF 1 "register_operand" "fr"))
8932 (set (match_operand:SF 2 "memory_operand" "")
8933 (match_operand:SF 3 "register_operand" "fr"))]
8934 "registers_ok_for_ldd_peep (operands[1], operands[3])
8935 && ! MEM_VOLATILE_P (operands[0])
8936 && ! MEM_VOLATILE_P (operands[2])
8937 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8941 [(set (match_operand:SI 0 "register_operand" "=rf")
8942 (match_operand:SI 1 "memory_operand" ""))
8943 (set (match_operand:SI 2 "register_operand" "=rf")
8944 (match_operand:SI 3 "memory_operand" ""))]
8945 "registers_ok_for_ldd_peep (operands[2], operands[0])
8946 && ! MEM_VOLATILE_P (operands[3])
8947 && ! MEM_VOLATILE_P (operands[1])
8948 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8952 [(set (match_operand:SI 0 "memory_operand" "")
8953 (match_operand:SI 1 "register_operand" "rf"))
8954 (set (match_operand:SI 2 "memory_operand" "")
8955 (match_operand:SI 3 "register_operand" "rf"))]
8956 "registers_ok_for_ldd_peep (operands[3], operands[1])
8957 && ! MEM_VOLATILE_P (operands[2])
8958 && ! MEM_VOLATILE_P (operands[0])
8959 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8963 [(set (match_operand:SF 0 "register_operand" "=fr")
8964 (match_operand:SF 1 "memory_operand" ""))
8965 (set (match_operand:SF 2 "register_operand" "=fr")
8966 (match_operand:SF 3 "memory_operand" ""))]
8967 "registers_ok_for_ldd_peep (operands[2], operands[0])
8968 && ! MEM_VOLATILE_P (operands[3])
8969 && ! MEM_VOLATILE_P (operands[1])
8970 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8974 [(set (match_operand:SF 0 "memory_operand" "")
8975 (match_operand:SF 1 "register_operand" "fr"))
8976 (set (match_operand:SF 2 "memory_operand" "")
8977 (match_operand:SF 3 "register_operand" "fr"))]
8978 "registers_ok_for_ldd_peep (operands[3], operands[1])
8979 && ! MEM_VOLATILE_P (operands[2])
8980 && ! MEM_VOLATILE_P (operands[0])
8981 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8984 ;; Optimize the case of following a reg-reg move with a test
8985 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8986 ;; This can result from a float to fix conversion.
8989 [(set (match_operand:SI 0 "register_operand" "=r")
8990 (match_operand:SI 1 "register_operand" "r"))
8992 (compare:CC (match_operand:SI 2 "register_operand" "r")
8994 "(rtx_equal_p (operands[2], operands[0])
8995 || rtx_equal_p (operands[2], operands[1]))
8996 && ! FP_REG_P (operands[0])
8997 && ! FP_REG_P (operands[1])"
9001 [(set (match_operand:DI 0 "register_operand" "=r")
9002 (match_operand:DI 1 "register_operand" "r"))
9004 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9007 && (rtx_equal_p (operands[2], operands[0])
9008 || rtx_equal_p (operands[2], operands[1]))
9009 && ! FP_REG_P (operands[0])
9010 && ! FP_REG_P (operands[1])"
9013 ;; Return peepholes. First the "normal" ones.
9014 ;; These are necessary to catch insns ending up in the epilogue delay list.
9016 (define_insn "*return_qi"
9017 [(set (match_operand:QI 0 "restore_operand" "")
9018 (match_operand:QI 1 "arith_operand" "rI"))
9023 if (! TARGET_ARCH64 && current_function_returns_struct)
9024 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9025 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9026 || IN_OR_GLOBAL_P (operands[1])))
9027 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9029 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9031 [(set_attr "type" "multi")
9032 (set_attr "length" "2")])
9034 (define_insn "*return_hi"
9035 [(set (match_operand:HI 0 "restore_operand" "")
9036 (match_operand:HI 1 "arith_operand" "rI"))
9041 if (! TARGET_ARCH64 && current_function_returns_struct)
9042 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9043 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9044 || IN_OR_GLOBAL_P (operands[1])))
9045 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9047 return \"ret\;restore %%g0, %1, %Y0\";
9049 [(set_attr "type" "multi")
9050 (set_attr "length" "2")])
9052 (define_insn "*return_si"
9053 [(set (match_operand:SI 0 "restore_operand" "")
9054 (match_operand:SI 1 "arith_operand" "rI"))
9059 if (! TARGET_ARCH64 && current_function_returns_struct)
9060 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9061 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9062 || IN_OR_GLOBAL_P (operands[1])))
9063 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9065 return \"ret\;restore %%g0, %1, %Y0\";
9067 [(set_attr "type" "multi")
9068 (set_attr "length" "2")])
9070 ;; The following pattern is only generated by delayed-branch scheduling,
9071 ;; when the insn winds up in the epilogue. This can happen not only when
9072 ;; ! TARGET_FPU because we move complex types around by parts using
9074 (define_insn "*return_sf_no_fpu"
9075 [(set (match_operand:SF 0 "restore_operand" "=r")
9076 (match_operand:SF 1 "register_operand" "r"))
9081 if (! TARGET_ARCH64 && current_function_returns_struct)
9082 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9083 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9084 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9086 return \"ret\;restore %%g0, %1, %Y0\";
9088 [(set_attr "type" "multi")
9089 (set_attr "length" "2")])
9091 (define_insn "*return_df_no_fpu"
9092 [(set (match_operand:DF 0 "restore_operand" "=r")
9093 (match_operand:DF 1 "register_operand" "r"))
9095 "! TARGET_EPILOGUE && TARGET_ARCH64"
9098 if (IN_OR_GLOBAL_P (operands[1]))
9099 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9101 return \"ret\;restore %%g0, %1, %Y0\";
9103 [(set_attr "type" "multi")
9104 (set_attr "length" "2")])
9106 (define_insn "*return_addsi"
9107 [(set (match_operand:SI 0 "restore_operand" "")
9108 (plus:SI (match_operand:SI 1 "register_operand" "r")
9109 (match_operand:SI 2 "arith_operand" "rI")))
9114 if (! TARGET_ARCH64 && current_function_returns_struct)
9115 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9116 /* If operands are global or in registers, can use return */
9117 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9118 && (GET_CODE (operands[2]) == CONST_INT
9119 || IN_OR_GLOBAL_P (operands[2])))
9120 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9122 return \"ret\;restore %r1, %2, %Y0\";
9124 [(set_attr "type" "multi")
9125 (set_attr "length" "2")])
9127 (define_insn "*return_losum_si"
9128 [(set (match_operand:SI 0 "restore_operand" "")
9129 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9130 (match_operand:SI 2 "immediate_operand" "in")))
9132 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9135 if (! TARGET_ARCH64 && current_function_returns_struct)
9136 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9137 /* If operands are global or in registers, can use return */
9138 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9139 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9141 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9143 [(set_attr "type" "multi")
9144 (set_attr "length" "2")])
9146 (define_insn "*return_di"
9147 [(set (match_operand:DI 0 "restore_operand" "")
9148 (match_operand:DI 1 "arith_double_operand" "rHI"))
9150 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9151 "ret\;restore %%g0, %1, %Y0"
9152 [(set_attr "type" "multi")
9153 (set_attr "length" "2")])
9155 (define_insn "*return_adddi"
9156 [(set (match_operand:DI 0 "restore_operand" "")
9157 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9158 (match_operand:DI 2 "arith_double_operand" "rHI")))
9160 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9161 "ret\;restore %r1, %2, %Y0"
9162 [(set_attr "type" "multi")
9163 (set_attr "length" "2")])
9165 (define_insn "*return_losum_di"
9166 [(set (match_operand:DI 0 "restore_operand" "")
9167 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9168 (match_operand:DI 2 "immediate_operand" "in")))
9170 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9171 "ret\;restore %r1, %%lo(%a2), %Y0"
9172 [(set_attr "type" "multi")
9173 (set_attr "length" "2")])
9175 ;; The following pattern is only generated by delayed-branch scheduling,
9176 ;; when the insn winds up in the epilogue.
9177 (define_insn "*return_sf"
9179 (match_operand:SF 0 "register_operand" "f"))
9182 "ret\;fmovs\\t%0, %%f0"
9183 [(set_attr "type" "multi")
9184 (set_attr "length" "2")])
9186 ;; Now peepholes to do a call followed by a jump.
9189 [(parallel [(set (match_operand 0 "" "")
9190 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9191 (match_operand 2 "" "")))
9192 (clobber (reg:SI 15))])
9193 (set (pc) (label_ref (match_operand 3 "" "")))]
9194 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9195 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9196 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9199 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9200 (match_operand 1 "" ""))
9201 (clobber (reg:SI 15))])
9202 (set (pc) (label_ref (match_operand 2 "" "")))]
9203 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9204 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9205 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9208 [(parallel [(set (match_operand 0 "" "")
9209 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9210 (match_operand 2 "" "")))
9211 (clobber (reg:DI 15))])
9212 (set (pc) (label_ref (match_operand 3 "" "")))]
9214 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9215 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9216 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9219 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9220 (match_operand 1 "" ""))
9221 (clobber (reg:DI 15))])
9222 (set (pc) (label_ref (match_operand 2 "" "")))]
9224 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9225 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9226 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9228 (define_expand "prologue"
9230 "flag_pic && current_function_uses_pic_offset_table"
9233 load_pic_register ();
9237 ;; We need to reload %l7 for -mflat -fpic,
9238 ;; otherwise %l7 should be preserved simply
9239 ;; by loading the function's register window
9240 (define_expand "exception_receiver"
9242 "TARGET_FLAT && flag_pic"
9245 load_pic_register ();
9250 (define_expand "builtin_setjmp_receiver"
9251 [(label_ref (match_operand 0 "" ""))]
9252 "TARGET_FLAT && flag_pic"
9255 load_pic_register ();
9260 [(trap_if (const_int 1) (const_int 5))]
9263 [(set_attr "type" "misc")])
9265 (define_expand "conditional_trap"
9266 [(trap_if (match_operator 0 "noov_compare_op"
9267 [(match_dup 2) (match_dup 3)])
9268 (match_operand:SI 1 "arith_operand" ""))]
9270 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9271 sparc_compare_op0, sparc_compare_op1);
9272 operands[3] = const0_rtx;")
9275 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9276 (match_operand:SI 1 "arith_operand" "rM"))]
9279 [(set_attr "type" "misc")])
9282 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9283 (match_operand:SI 1 "arith_operand" "rM"))]
9286 [(set_attr "type" "misc")])