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)))
2459 (define_insn "*movdi_insn_sp32_v9"
2460 [(set (match_operand:DI 0 "nonimmediate_operand"
2461 "=m,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2462 (match_operand:DI 1 "input_operand"
2463 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2464 "! TARGET_ARCH64 && TARGET_V9
2465 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2479 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2480 (set_attr "length" "*,*,*,2,2,2,2,*,*,2,2,2")])
2482 (define_insn "*movdi_insn_sp32"
2483 [(set (match_operand:DI 0 "nonimmediate_operand"
2484 "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2485 (match_operand:DI 1 "input_operand"
2486 " U,T,r,o,i,r, f, T, o, f, f"))]
2488 && (register_operand (operands[0], DImode)
2489 || register_operand (operands[1], DImode))"
2502 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2503 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2505 ;; The following are generated by sparc_emit_set_const64
2506 (define_insn "*movdi_sp64_dbl"
2507 [(set (match_operand:DI 0 "register_operand" "=r")
2508 (match_operand:DI 1 "const64_operand" ""))]
2510 && HOST_BITS_PER_WIDE_INT != 64)"
2513 ;; This is needed to show CSE exactly which bits are set
2514 ;; in a 64-bit register by sethi instructions.
2515 (define_insn "*movdi_const64_special"
2516 [(set (match_operand:DI 0 "register_operand" "=r")
2517 (match_operand:DI 1 "const64_high_operand" ""))]
2519 "sethi\\t%%hi(%a1), %0")
2521 (define_insn "*movdi_insn_sp64_novis"
2522 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2523 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2524 "TARGET_ARCH64 && ! TARGET_VIS
2525 && (register_operand (operands[0], DImode)
2526 || reg_or_0_operand (operands[1], DImode))"
2529 sethi\\t%%hi(%a1), %0
2536 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2537 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2539 (define_insn "*movdi_insn_sp64_vis"
2540 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2541 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2542 "TARGET_ARCH64 && TARGET_VIS &&
2543 (register_operand (operands[0], DImode)
2544 || reg_or_0_operand (operands[1], DImode))"
2547 sethi\\t%%hi(%a1), %0
2555 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2556 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2558 (define_expand "movdi_pic_label_ref"
2559 [(set (match_dup 3) (high:DI
2560 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2562 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2563 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2564 (set (match_operand:DI 0 "register_operand" "=r")
2565 (minus:DI (match_dup 5) (match_dup 4)))]
2566 "TARGET_ARCH64 && flag_pic"
2569 current_function_uses_pic_offset_table = 1;
2570 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2573 operands[3] = operands[0];
2574 operands[4] = operands[0];
2578 operands[3] = gen_reg_rtx (DImode);
2579 operands[4] = gen_reg_rtx (DImode);
2581 operands[5] = pic_offset_table_rtx;
2584 (define_insn "*movdi_high_pic_label_ref"
2585 [(set (match_operand:DI 0 "register_operand" "=r")
2587 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2588 (match_operand:DI 2 "" "")] 5)))]
2589 "TARGET_ARCH64 && flag_pic"
2590 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2592 (define_insn "*movdi_lo_sum_pic_label_ref"
2593 [(set (match_operand:DI 0 "register_operand" "=r")
2594 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2595 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2596 (match_operand:DI 3 "" "")] 5)))]
2597 "TARGET_ARCH64 && flag_pic"
2598 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2600 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2601 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2603 (define_insn "movdi_lo_sum_pic"
2604 [(set (match_operand:DI 0 "register_operand" "=r")
2605 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2606 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2607 "TARGET_ARCH64 && flag_pic"
2608 "or\\t%1, %%lo(%a2), %0")
2610 (define_insn "movdi_high_pic"
2611 [(set (match_operand:DI 0 "register_operand" "=r")
2612 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2613 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2614 "sethi\\t%%hi(%a1), %0")
2616 (define_insn "*sethi_di_medlow_embmedany_pic"
2617 [(set (match_operand:DI 0 "register_operand" "=r")
2618 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2619 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2620 "sethi\\t%%hi(%a1), %0")
2622 (define_insn "*sethi_di_medlow"
2623 [(set (match_operand:DI 0 "register_operand" "=r")
2624 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2625 "TARGET_CM_MEDLOW && check_pic (1)"
2626 "sethi\\t%%hi(%a1), %0")
2628 (define_insn "*losum_di_medlow"
2629 [(set (match_operand:DI 0 "register_operand" "=r")
2630 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2631 (match_operand:DI 2 "symbolic_operand" "")))]
2633 "or\\t%1, %%lo(%a2), %0")
2635 (define_insn "seth44"
2636 [(set (match_operand:DI 0 "register_operand" "=r")
2637 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2639 "sethi\\t%%h44(%a1), %0")
2641 (define_insn "setm44"
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" "")] 7)))]
2646 "or\\t%1, %%m44(%a2), %0")
2648 (define_insn "setl44"
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, %%l44(%a2), %0")
2655 (define_insn "sethh"
2656 [(set (match_operand:DI 0 "register_operand" "=r")
2657 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2659 "sethi\\t%%hh(%a1), %0")
2661 (define_insn "setlm"
2662 [(set (match_operand:DI 0 "register_operand" "=r")
2663 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2665 "sethi\\t%%lm(%a1), %0")
2667 (define_insn "sethm"
2668 [(set (match_operand:DI 0 "register_operand" "=r")
2669 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2670 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2672 "or\\t%1, %%hm(%a2), %0")
2674 (define_insn "setlo"
2675 [(set (match_operand:DI 0 "register_operand" "=r")
2676 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2677 (match_operand:DI 2 "symbolic_operand" "")))]
2679 "or\\t%1, %%lo(%a2), %0")
2681 (define_insn "embmedany_sethi"
2682 [(set (match_operand:DI 0 "register_operand" "=r")
2683 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2684 "TARGET_CM_EMBMEDANY && check_pic (1)"
2685 "sethi\\t%%hi(%a1), %0")
2687 (define_insn "embmedany_losum"
2688 [(set (match_operand:DI 0 "register_operand" "=r")
2689 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2690 (match_operand:DI 2 "data_segment_operand" "")))]
2691 "TARGET_CM_EMBMEDANY"
2692 "add\\t%1, %%lo(%a2), %0")
2694 (define_insn "embmedany_brsum"
2695 [(set (match_operand:DI 0 "register_operand" "=r")
2696 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2697 "TARGET_CM_EMBMEDANY"
2700 (define_insn "embmedany_textuhi"
2701 [(set (match_operand:DI 0 "register_operand" "=r")
2702 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2703 "TARGET_CM_EMBMEDANY && check_pic (1)"
2704 "sethi\\t%%uhi(%a1), %0")
2706 (define_insn "embmedany_texthi"
2707 [(set (match_operand:DI 0 "register_operand" "=r")
2708 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2709 "TARGET_CM_EMBMEDANY && check_pic (1)"
2710 "sethi\\t%%hi(%a1), %0")
2712 (define_insn "embmedany_textulo"
2713 [(set (match_operand:DI 0 "register_operand" "=r")
2714 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2715 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2716 "TARGET_CM_EMBMEDANY"
2717 "or\\t%1, %%ulo(%a2), %0")
2719 (define_insn "embmedany_textlo"
2720 [(set (match_operand:DI 0 "register_operand" "=r")
2721 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2722 (match_operand:DI 2 "text_segment_operand" "")))]
2723 "TARGET_CM_EMBMEDANY"
2724 "or\\t%1, %%lo(%a2), %0")
2726 ;; Now some patterns to help reload out a bit.
2727 (define_expand "reload_indi"
2728 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2729 (match_operand:DI 1 "immediate_operand" "")
2730 (match_operand:TI 2 "register_operand" "=&r")])]
2732 || TARGET_CM_EMBMEDANY)
2736 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2737 gen_rtx_REG (DImode, REGNO (operands[2])));
2741 (define_expand "reload_outdi"
2742 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2743 (match_operand:DI 1 "immediate_operand" "")
2744 (match_operand:TI 2 "register_operand" "=&r")])]
2746 || TARGET_CM_EMBMEDANY)
2750 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2751 gen_rtx_REG (DImode, REGNO (operands[2])));
2755 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2757 [(set (match_operand:DI 0 "register_operand" "")
2758 (match_operand:DI 1 "const_int_operand" ""))]
2759 "! TARGET_ARCH64 && reload_completed"
2760 [(clobber (const_int 0))]
2763 #if HOST_BITS_PER_WIDE_INT == 32
2764 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2765 (INTVAL (operands[1]) < 0) ?
2768 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2771 unsigned int low, high;
2773 low = INTVAL (operands[1]) & 0xffffffff;
2774 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2775 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2777 /* Slick... but this trick loses if this subreg constant part
2778 can be done in one insn. */
2779 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2780 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2781 gen_highpart (SImode, operands[0])));
2783 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2789 [(set (match_operand:DI 0 "register_operand" "")
2790 (match_operand:DI 1 "const_double_operand" ""))]
2791 "! TARGET_ARCH64 && reload_completed"
2792 [(clobber (const_int 0))]
2795 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2796 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2798 /* Slick... but this trick loses if this subreg constant part
2799 can be done in one insn. */
2800 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2801 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2802 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2804 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2805 gen_highpart (SImode, operands[0])));
2809 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2810 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2816 [(set (match_operand:DI 0 "register_operand" "")
2817 (match_operand:DI 1 "register_operand" ""))]
2818 "! TARGET_ARCH64 && reload_completed"
2819 [(clobber (const_int 0))]
2822 rtx set_dest = operands[0];
2823 rtx set_src = operands[1];
2827 dest1 = gen_highpart (SImode, set_dest);
2828 dest2 = gen_lowpart (SImode, set_dest);
2829 src1 = gen_highpart (SImode, set_src);
2830 src2 = gen_lowpart (SImode, set_src);
2832 /* Now emit using the real source and destination we found, swapping
2833 the order if we detect overlap. */
2834 if (reg_overlap_mentioned_p (dest1, src2))
2836 emit_insn (gen_movsi (dest2, src2));
2837 emit_insn (gen_movsi (dest1, src1));
2841 emit_insn (gen_movsi (dest1, src1));
2842 emit_insn (gen_movsi (dest2, src2));
2847 ;; Now handle the cases of memory moves from/to non-even
2848 ;; DI mode register pairs.
2850 [(set (match_operand:DI 0 "register_operand" "")
2851 (match_operand:DI 1 "memory_operand" ""))]
2854 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2855 [(clobber (const_int 0))]
2858 rtx word0 = adjust_address (operands[1], SImode, 0);
2859 rtx word1 = adjust_address (operands[1], SImode, 4);
2860 rtx high_part = gen_highpart (SImode, operands[0]);
2861 rtx low_part = gen_lowpart (SImode, operands[0]);
2863 if (reg_overlap_mentioned_p (high_part, word1))
2865 emit_insn (gen_movsi (low_part, word1));
2866 emit_insn (gen_movsi (high_part, word0));
2870 emit_insn (gen_movsi (high_part, word0));
2871 emit_insn (gen_movsi (low_part, word1));
2877 [(set (match_operand:DI 0 "memory_operand" "")
2878 (match_operand:DI 1 "register_operand" ""))]
2881 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2882 [(clobber (const_int 0))]
2885 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2886 gen_highpart (SImode, operands[1])));
2887 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2888 gen_lowpart (SImode, operands[1])));
2893 ;; Floating point move insns
2895 (define_insn "*movsf_insn_novis"
2896 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2897 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2898 "(TARGET_FPU && ! TARGET_VIS)
2899 && (register_operand (operands[0], SFmode)
2900 || register_operand (operands[1], SFmode)
2901 || fp_zero_operand (operands[1], SFmode))"
2904 if (GET_CODE (operands[1]) == CONST_DOUBLE
2905 && (which_alternative == 2
2906 || which_alternative == 3
2907 || which_alternative == 4))
2912 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2913 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2914 operands[1] = GEN_INT (i);
2917 switch (which_alternative)
2920 return \"fmovs\\t%1, %0\";
2922 return \"clr\\t%0\";
2924 return \"sethi\\t%%hi(%a1), %0\";
2926 return \"mov\\t%1, %0\";
2931 return \"ld\\t%1, %0\";
2934 return \"st\\t%r1, %0\";
2939 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2941 (define_insn "*movsf_insn_vis"
2942 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2943 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2944 "(TARGET_FPU && TARGET_VIS)
2945 && (register_operand (operands[0], SFmode)
2946 || register_operand (operands[1], SFmode)
2947 || fp_zero_operand (operands[1], SFmode))"
2950 if (GET_CODE (operands[1]) == CONST_DOUBLE
2951 && (which_alternative == 3
2952 || which_alternative == 4
2953 || which_alternative == 5))
2958 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2959 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2960 operands[1] = GEN_INT (i);
2963 switch (which_alternative)
2966 return \"fmovs\\t%1, %0\";
2968 return \"fzeros\\t%0\";
2970 return \"clr\\t%0\";
2972 return \"sethi\\t%%hi(%a1), %0\";
2974 return \"mov\\t%1, %0\";
2979 return \"ld\\t%1, %0\";
2982 return \"st\\t%r1, %0\";
2987 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2989 ;; Exactly the same as above, except that all `f' cases are deleted.
2990 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2993 (define_insn "*movsf_no_f_insn"
2994 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2995 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2997 && (register_operand (operands[0], SFmode)
2998 || register_operand (operands[1], SFmode)
2999 || fp_zero_operand (operands[1], SFmode))"
3002 if (GET_CODE (operands[1]) == CONST_DOUBLE
3003 && (which_alternative == 1
3004 || which_alternative == 2
3005 || which_alternative == 3))
3010 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3011 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3012 operands[1] = GEN_INT (i);
3015 switch (which_alternative)
3018 return \"clr\\t%0\";
3020 return \"sethi\\t%%hi(%a1), %0\";
3022 return \"mov\\t%1, %0\";
3026 return \"ld\\t%1, %0\";
3028 return \"st\\t%r1, %0\";
3033 [(set_attr "type" "*,*,*,*,load,store")])
3035 (define_insn "*movsf_lo_sum"
3036 [(set (match_operand:SF 0 "register_operand" "=r")
3037 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3038 (match_operand:SF 2 "const_double_operand" "S")))]
3039 "fp_high_losum_p (operands[2])"
3045 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3046 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3047 operands[2] = GEN_INT (i);
3048 return \"or\\t%1, %%lo(%a2), %0\";
3051 (define_insn "*movsf_high"
3052 [(set (match_operand:SF 0 "register_operand" "=r")
3053 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3054 "fp_high_losum_p (operands[1])"
3060 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3061 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3062 operands[1] = GEN_INT (i);
3063 return \"sethi\\t%%hi(%1), %0\";
3067 [(set (match_operand:SF 0 "register_operand" "")
3068 (match_operand:SF 1 "const_double_operand" ""))]
3069 "fp_high_losum_p (operands[1])
3070 && (GET_CODE (operands[0]) == REG
3071 && REGNO (operands[0]) < 32)"
3072 [(set (match_dup 0) (high:SF (match_dup 1)))
3073 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3075 (define_expand "movsf"
3076 [(set (match_operand:SF 0 "general_operand" "")
3077 (match_operand:SF 1 "general_operand" ""))]
3081 /* Force SFmode constants into memory. */
3082 if (GET_CODE (operands[0]) == REG
3083 && CONSTANT_P (operands[1]))
3085 /* emit_group_store will send such bogosity to us when it is
3086 not storing directly into memory. So fix this up to avoid
3087 crashes in output_constant_pool. */
3088 if (operands [1] == const0_rtx)
3089 operands[1] = CONST0_RTX (SFmode);
3091 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3094 /* We are able to build any SF constant in integer registers
3095 with at most 2 instructions. */
3096 if (REGNO (operands[0]) < 32)
3099 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3103 /* Handle sets of MEM first. */
3104 if (GET_CODE (operands[0]) == MEM)
3106 if (register_operand (operands[1], SFmode)
3107 || fp_zero_operand (operands[1], SFmode))
3110 if (! reload_in_progress)
3112 operands[0] = validize_mem (operands[0]);
3113 operands[1] = force_reg (SFmode, operands[1]);
3117 /* Fixup PIC cases. */
3120 if (CONSTANT_P (operands[1])
3121 && pic_address_needs_scratch (operands[1]))
3122 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3124 if (symbolic_operand (operands[1], SFmode))
3126 operands[1] = legitimize_pic_address (operands[1],
3128 (reload_in_progress ?
3138 (define_expand "movdf"
3139 [(set (match_operand:DF 0 "general_operand" "")
3140 (match_operand:DF 1 "general_operand" ""))]
3144 /* Force DFmode constants into memory. */
3145 if (GET_CODE (operands[0]) == REG
3146 && CONSTANT_P (operands[1]))
3148 /* emit_group_store will send such bogosity to us when it is
3149 not storing directly into memory. So fix this up to avoid
3150 crashes in output_constant_pool. */
3151 if (operands [1] == const0_rtx)
3152 operands[1] = CONST0_RTX (DFmode);
3154 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3155 && fp_zero_operand (operands[1], DFmode))
3158 /* We are able to build any DF constant in integer registers. */
3159 if (REGNO (operands[0]) < 32
3160 && (reload_completed || reload_in_progress))
3163 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3167 /* Handle MEM cases first. */
3168 if (GET_CODE (operands[0]) == MEM)
3170 if (register_operand (operands[1], DFmode)
3171 || fp_zero_operand (operands[1], DFmode))
3174 if (! reload_in_progress)
3176 operands[0] = validize_mem (operands[0]);
3177 operands[1] = force_reg (DFmode, operands[1]);
3181 /* Fixup PIC cases. */
3184 if (CONSTANT_P (operands[1])
3185 && pic_address_needs_scratch (operands[1]))
3186 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3188 if (symbolic_operand (operands[1], DFmode))
3190 operands[1] = legitimize_pic_address (operands[1],
3192 (reload_in_progress ?
3202 ;; Be careful, fmovd does not exist when !v9.
3203 (define_insn "*movdf_insn_sp32"
3204 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3205 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3208 && (register_operand (operands[0], DFmode)
3209 || register_operand (operands[1], DFmode)
3210 || fp_zero_operand (operands[1], DFmode))"
3222 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3223 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3225 (define_insn "*movdf_no_e_insn_sp32"
3226 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3227 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3231 && (register_operand (operands[0], DFmode)
3232 || register_operand (operands[1], DFmode)
3233 || fp_zero_operand (operands[1], DFmode))"
3240 [(set_attr "type" "load,store,*,*,*")
3241 (set_attr "length" "*,*,2,2,2")])
3243 (define_insn "*movdf_no_e_insn_v9_sp32"
3244 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3245 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3249 && (register_operand (operands[0], DFmode)
3250 || register_operand (operands[1], DFmode)
3251 || fp_zero_operand (operands[1], DFmode))"
3258 [(set_attr "type" "load,store,store,*,*")
3259 (set_attr "length" "*,*,*,2,2")])
3261 ;; We have available v9 double floats but not 64-bit
3262 ;; integer registers and no VIS.
3263 (define_insn "*movdf_insn_v9only_novis"
3264 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3265 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3270 && (register_operand (operands[0], DFmode)
3271 || register_operand (operands[1], DFmode)
3272 || fp_zero_operand (operands[1], DFmode))"
3283 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3284 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3285 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3287 ;; We have available v9 double floats but not 64-bit
3288 ;; integer registers but we have VIS.
3289 (define_insn "*movdf_insn_v9only_vis"
3290 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3291 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3295 && (register_operand (operands[0], DFmode)
3296 || register_operand (operands[1], DFmode)
3297 || fp_zero_operand (operands[1], DFmode))"
3309 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3310 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3311 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3313 ;; We have available both v9 double floats and 64-bit
3314 ;; integer registers. No VIS though.
3315 (define_insn "*movdf_insn_sp64_novis"
3316 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3317 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3321 && (register_operand (operands[0], DFmode)
3322 || register_operand (operands[1], DFmode)
3323 || fp_zero_operand (operands[1], DFmode))"
3332 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3333 (set_attr "length" "*,*,*,*,*,*,2")
3334 (set_attr "fptype" "double,*,*,*,*,*,*")])
3336 ;; We have available both v9 double floats and 64-bit
3337 ;; integer registers. And we have VIS.
3338 (define_insn "*movdf_insn_sp64_vis"
3339 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3340 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3344 && (register_operand (operands[0], DFmode)
3345 || register_operand (operands[1], DFmode)
3346 || fp_zero_operand (operands[1], DFmode))"
3356 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3357 (set_attr "length" "*,*,*,*,*,*,*,2")
3358 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3360 (define_insn "*movdf_no_e_insn_sp64"
3361 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3362 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3365 && (register_operand (operands[0], DFmode)
3366 || register_operand (operands[1], DFmode)
3367 || fp_zero_operand (operands[1], DFmode))"
3372 [(set_attr "type" "*,load,store")])
3375 [(set (match_operand:DF 0 "register_operand" "")
3376 (match_operand:DF 1 "const_double_operand" ""))]
3378 && (GET_CODE (operands[0]) == REG
3379 && REGNO (operands[0]) < 32)
3380 && ! fp_zero_operand(operands[1], DFmode)
3381 && reload_completed"
3382 [(clobber (const_int 0))]
3388 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3389 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3390 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3394 #if HOST_BITS_PER_WIDE_INT == 64
3397 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3398 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3399 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3401 emit_insn (gen_movdi (operands[0],
3402 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3407 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3410 /* Slick... but this trick loses if this subreg constant part
3411 can be done in one insn. */
3413 && !(SPARC_SETHI_P (l[0])
3414 || SPARC_SIMM13_P (l[0])))
3416 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3417 gen_highpart (SImode, operands[0])));
3421 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3428 ;; Ok, now the splits to handle all the multi insn and
3429 ;; mis-aligned memory address cases.
3430 ;; In these splits please take note that we must be
3431 ;; careful when V9 but not ARCH64 because the integer
3432 ;; register DFmode cases must be handled.
3434 [(set (match_operand:DF 0 "register_operand" "")
3435 (match_operand:DF 1 "register_operand" ""))]
3438 && ((GET_CODE (operands[0]) == REG
3439 && REGNO (operands[0]) < 32)
3440 || (GET_CODE (operands[0]) == SUBREG
3441 && GET_CODE (SUBREG_REG (operands[0])) == REG
3442 && REGNO (SUBREG_REG (operands[0])) < 32))))
3443 && reload_completed"
3444 [(clobber (const_int 0))]
3447 rtx set_dest = operands[0];
3448 rtx set_src = operands[1];
3452 dest1 = gen_highpart (SFmode, set_dest);
3453 dest2 = gen_lowpart (SFmode, set_dest);
3454 src1 = gen_highpart (SFmode, set_src);
3455 src2 = gen_lowpart (SFmode, set_src);
3457 /* Now emit using the real source and destination we found, swapping
3458 the order if we detect overlap. */
3459 if (reg_overlap_mentioned_p (dest1, src2))
3461 emit_insn (gen_movsf (dest2, src2));
3462 emit_insn (gen_movsf (dest1, src1));
3466 emit_insn (gen_movsf (dest1, src1));
3467 emit_insn (gen_movsf (dest2, src2));
3473 [(set (match_operand:DF 0 "register_operand" "")
3474 (match_operand:DF 1 "memory_operand" ""))]
3477 && (((REGNO (operands[0]) % 2) != 0)
3478 || ! mem_min_alignment (operands[1], 8))
3479 && offsettable_memref_p (operands[1])"
3480 [(clobber (const_int 0))]
3483 rtx word0 = adjust_address (operands[1], SFmode, 0);
3484 rtx word1 = adjust_address (operands[1], SFmode, 4);
3486 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3488 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3490 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3495 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3497 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3504 [(set (match_operand:DF 0 "memory_operand" "")
3505 (match_operand:DF 1 "register_operand" ""))]
3508 && (((REGNO (operands[1]) % 2) != 0)
3509 || ! mem_min_alignment (operands[0], 8))
3510 && offsettable_memref_p (operands[0])"
3511 [(clobber (const_int 0))]
3514 rtx word0 = adjust_address (operands[0], SFmode, 0);
3515 rtx word1 = adjust_address (operands[0], SFmode, 4);
3517 emit_insn (gen_movsf (word0,
3518 gen_highpart (SFmode, operands[1])));
3519 emit_insn (gen_movsf (word1,
3520 gen_lowpart (SFmode, operands[1])));
3525 [(set (match_operand:DF 0 "memory_operand" "")
3526 (match_operand:DF 1 "fp_zero_operand" ""))]
3530 && ! mem_min_alignment (operands[0], 8)))
3531 && offsettable_memref_p (operands[0])"
3532 [(clobber (const_int 0))]
3537 dest1 = adjust_address (operands[0], SFmode, 0);
3538 dest2 = adjust_address (operands[0], SFmode, 4);
3540 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3541 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3546 [(set (match_operand:DF 0 "register_operand" "")
3547 (match_operand:DF 1 "fp_zero_operand" ""))]
3550 && ((GET_CODE (operands[0]) == REG
3551 && REGNO (operands[0]) < 32)
3552 || (GET_CODE (operands[0]) == SUBREG
3553 && GET_CODE (SUBREG_REG (operands[0])) == REG
3554 && REGNO (SUBREG_REG (operands[0])) < 32))"
3555 [(clobber (const_int 0))]
3558 rtx set_dest = operands[0];
3561 dest1 = gen_highpart (SFmode, set_dest);
3562 dest2 = gen_lowpart (SFmode, set_dest);
3563 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3564 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3568 (define_expand "movtf"
3569 [(set (match_operand:TF 0 "general_operand" "")
3570 (match_operand:TF 1 "general_operand" ""))]
3574 /* Force TFmode constants into memory. */
3575 if (GET_CODE (operands[0]) == REG
3576 && CONSTANT_P (operands[1]))
3578 /* emit_group_store will send such bogosity to us when it is
3579 not storing directly into memory. So fix this up to avoid
3580 crashes in output_constant_pool. */
3581 if (operands [1] == const0_rtx)
3582 operands[1] = CONST0_RTX (TFmode);
3584 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3587 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3591 /* Handle MEM cases first, note that only v9 guarentees
3592 full 16-byte alignment for quads. */
3593 if (GET_CODE (operands[0]) == MEM)
3595 if (register_operand (operands[1], TFmode)
3596 || fp_zero_operand (operands[1], TFmode))
3599 if (! reload_in_progress)
3601 operands[0] = validize_mem (operands[0]);
3602 operands[1] = force_reg (TFmode, operands[1]);
3606 /* Fixup PIC cases. */
3609 if (CONSTANT_P (operands[1])
3610 && pic_address_needs_scratch (operands[1]))
3611 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3613 if (symbolic_operand (operands[1], TFmode))
3615 operands[1] = legitimize_pic_address (operands[1],
3617 (reload_in_progress ?
3627 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3628 ;; we must split them all. :-(
3629 (define_insn "*movtf_insn_sp32"
3630 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3631 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3635 && (register_operand (operands[0], TFmode)
3636 || register_operand (operands[1], TFmode)
3637 || fp_zero_operand (operands[1], TFmode))"
3639 [(set_attr "length" "4")])
3641 (define_insn "*movtf_insn_vis_sp32"
3642 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3643 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3647 && (register_operand (operands[0], TFmode)
3648 || register_operand (operands[1], TFmode)
3649 || fp_zero_operand (operands[1], TFmode))"
3651 [(set_attr "length" "4")])
3653 ;; Exactly the same as above, except that all `e' cases are deleted.
3654 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3657 (define_insn "*movtf_no_e_insn_sp32"
3658 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3659 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3662 && (register_operand (operands[0], TFmode)
3663 || register_operand (operands[1], TFmode)
3664 || fp_zero_operand (operands[1], TFmode))"
3666 [(set_attr "length" "4")])
3668 ;; Now handle the float reg cases directly when arch64,
3669 ;; hard_quad, and proper reg number alignment are all true.
3670 (define_insn "*movtf_insn_hq_sp64"
3671 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3672 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3677 && (register_operand (operands[0], TFmode)
3678 || register_operand (operands[1], TFmode)
3679 || fp_zero_operand (operands[1], TFmode))"
3686 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3687 (set_attr "length" "*,*,*,2,2")])
3689 (define_insn "*movtf_insn_hq_vis_sp64"
3690 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3691 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3696 && (register_operand (operands[0], TFmode)
3697 || register_operand (operands[1], TFmode)
3698 || fp_zero_operand (operands[1], TFmode))"
3706 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3707 (set_attr "length" "*,*,*,2,2,2")])
3709 ;; Now we allow the integer register cases even when
3710 ;; only arch64 is true.
3711 (define_insn "*movtf_insn_sp64"
3712 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3713 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3717 && ! TARGET_HARD_QUAD
3718 && (register_operand (operands[0], TFmode)
3719 || register_operand (operands[1], TFmode)
3720 || fp_zero_operand (operands[1], TFmode))"
3722 [(set_attr "length" "2")])
3724 (define_insn "*movtf_insn_vis_sp64"
3725 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3726 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3730 && ! TARGET_HARD_QUAD
3731 && (register_operand (operands[0], TFmode)
3732 || register_operand (operands[1], TFmode)
3733 || fp_zero_operand (operands[1], TFmode))"
3735 [(set_attr "length" "2")])
3737 (define_insn "*movtf_no_e_insn_sp64"
3738 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3739 (match_operand:TF 1 "input_operand" "orG,rG"))]
3742 && (register_operand (operands[0], TFmode)
3743 || register_operand (operands[1], TFmode)
3744 || fp_zero_operand (operands[1], TFmode))"
3746 [(set_attr "length" "2")])
3748 ;; Now all the splits to handle multi-insn TF mode moves.
3750 [(set (match_operand:TF 0 "register_operand" "")
3751 (match_operand:TF 1 "register_operand" ""))]
3755 && ! TARGET_HARD_QUAD))"
3756 [(clobber (const_int 0))]
3759 rtx set_dest = operands[0];
3760 rtx set_src = operands[1];
3764 dest1 = gen_df_reg (set_dest, 0);
3765 dest2 = gen_df_reg (set_dest, 1);
3766 src1 = gen_df_reg (set_src, 0);
3767 src2 = gen_df_reg (set_src, 1);
3769 /* Now emit using the real source and destination we found, swapping
3770 the order if we detect overlap. */
3771 if (reg_overlap_mentioned_p (dest1, src2))
3773 emit_insn (gen_movdf (dest2, src2));
3774 emit_insn (gen_movdf (dest1, src1));
3778 emit_insn (gen_movdf (dest1, src1));
3779 emit_insn (gen_movdf (dest2, src2));
3785 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3786 (match_operand:TF 1 "fp_zero_operand" ""))]
3788 [(clobber (const_int 0))]
3791 rtx set_dest = operands[0];
3794 switch (GET_CODE (set_dest))
3797 dest1 = gen_df_reg (set_dest, 0);
3798 dest2 = gen_df_reg (set_dest, 1);
3801 dest1 = adjust_address (set_dest, DFmode, 0);
3802 dest2 = adjust_address (set_dest, DFmode, 8);
3808 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3809 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3814 [(set (match_operand:TF 0 "register_operand" "")
3815 (match_operand:TF 1 "memory_operand" ""))]
3817 && offsettable_memref_p (operands[1]))"
3818 [(clobber (const_int 0))]
3821 rtx word0 = adjust_address (operands[1], DFmode, 0);
3822 rtx word1 = adjust_address (operands[1], DFmode, 8);
3823 rtx set_dest, dest1, dest2;
3825 set_dest = operands[0];
3827 dest1 = gen_df_reg (set_dest, 0);
3828 dest2 = gen_df_reg (set_dest, 1);
3830 /* Now output, ordering such that we don't clobber any registers
3831 mentioned in the address. */
3832 if (reg_overlap_mentioned_p (dest1, word1))
3835 emit_insn (gen_movdf (dest2, word1));
3836 emit_insn (gen_movdf (dest1, word0));
3840 emit_insn (gen_movdf (dest1, word0));
3841 emit_insn (gen_movdf (dest2, word1));
3847 [(set (match_operand:TF 0 "memory_operand" "")
3848 (match_operand:TF 1 "register_operand" ""))]
3850 && offsettable_memref_p (operands[0]))"
3851 [(clobber (const_int 0))]
3854 rtx set_src = operands[1];
3856 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3857 gen_df_reg (set_src, 0)));
3858 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3859 gen_df_reg (set_src, 1)));
3863 ;; Sparc V9 conditional move instructions.
3865 ;; We can handle larger constants here for some flavors, but for now we keep
3866 ;; it simple and only allow those constants supported by all flavours.
3867 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3868 ;; 3 contains the constant if one is present, but we handle either for
3869 ;; generality (sparc.c puts a constant in operand 2).
3871 (define_expand "movqicc"
3872 [(set (match_operand:QI 0 "register_operand" "")
3873 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3874 (match_operand:QI 2 "arith10_operand" "")
3875 (match_operand:QI 3 "arith10_operand" "")))]
3879 enum rtx_code code = GET_CODE (operands[1]);
3881 if (GET_MODE (sparc_compare_op0) == DImode
3885 if (sparc_compare_op1 == const0_rtx
3886 && GET_CODE (sparc_compare_op0) == REG
3887 && GET_MODE (sparc_compare_op0) == DImode
3888 && v9_regcmp_p (code))
3890 operands[1] = gen_rtx_fmt_ee (code, DImode,
3891 sparc_compare_op0, sparc_compare_op1);
3895 rtx cc_reg = gen_compare_reg (code,
3896 sparc_compare_op0, sparc_compare_op1);
3897 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3901 (define_expand "movhicc"
3902 [(set (match_operand:HI 0 "register_operand" "")
3903 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3904 (match_operand:HI 2 "arith10_operand" "")
3905 (match_operand:HI 3 "arith10_operand" "")))]
3909 enum rtx_code code = GET_CODE (operands[1]);
3911 if (GET_MODE (sparc_compare_op0) == DImode
3915 if (sparc_compare_op1 == const0_rtx
3916 && GET_CODE (sparc_compare_op0) == REG
3917 && GET_MODE (sparc_compare_op0) == DImode
3918 && v9_regcmp_p (code))
3920 operands[1] = gen_rtx_fmt_ee (code, DImode,
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), cc_reg, const0_rtx);
3931 (define_expand "movsicc"
3932 [(set (match_operand:SI 0 "register_operand" "")
3933 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3934 (match_operand:SI 2 "arith10_operand" "")
3935 (match_operand:SI 3 "arith10_operand" "")))]
3939 enum rtx_code code = GET_CODE (operands[1]);
3940 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3942 if (sparc_compare_op1 == const0_rtx
3943 && GET_CODE (sparc_compare_op0) == REG
3944 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3946 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3947 sparc_compare_op0, sparc_compare_op1);
3951 rtx cc_reg = gen_compare_reg (code,
3952 sparc_compare_op0, sparc_compare_op1);
3953 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3954 cc_reg, const0_rtx);
3958 (define_expand "movdicc"
3959 [(set (match_operand:DI 0 "register_operand" "")
3960 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3961 (match_operand:DI 2 "arith10_double_operand" "")
3962 (match_operand:DI 3 "arith10_double_operand" "")))]
3966 enum rtx_code code = GET_CODE (operands[1]);
3968 if (sparc_compare_op1 == const0_rtx
3969 && GET_CODE (sparc_compare_op0) == REG
3970 && GET_MODE (sparc_compare_op0) == DImode
3971 && v9_regcmp_p (code))
3973 operands[1] = gen_rtx_fmt_ee (code, DImode,
3974 sparc_compare_op0, sparc_compare_op1);
3978 rtx cc_reg = gen_compare_reg (code,
3979 sparc_compare_op0, sparc_compare_op1);
3980 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3981 cc_reg, const0_rtx);
3985 (define_expand "movsfcc"
3986 [(set (match_operand:SF 0 "register_operand" "")
3987 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3988 (match_operand:SF 2 "register_operand" "")
3989 (match_operand:SF 3 "register_operand" "")))]
3990 "TARGET_V9 && TARGET_FPU"
3993 enum rtx_code code = GET_CODE (operands[1]);
3995 if (GET_MODE (sparc_compare_op0) == DImode
3999 if (sparc_compare_op1 == const0_rtx
4000 && GET_CODE (sparc_compare_op0) == REG
4001 && GET_MODE (sparc_compare_op0) == DImode
4002 && v9_regcmp_p (code))
4004 operands[1] = gen_rtx_fmt_ee (code, DImode,
4005 sparc_compare_op0, sparc_compare_op1);
4009 rtx cc_reg = gen_compare_reg (code,
4010 sparc_compare_op0, sparc_compare_op1);
4011 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4015 (define_expand "movdfcc"
4016 [(set (match_operand:DF 0 "register_operand" "")
4017 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4018 (match_operand:DF 2 "register_operand" "")
4019 (match_operand:DF 3 "register_operand" "")))]
4020 "TARGET_V9 && TARGET_FPU"
4023 enum rtx_code code = GET_CODE (operands[1]);
4025 if (GET_MODE (sparc_compare_op0) == DImode
4029 if (sparc_compare_op1 == const0_rtx
4030 && GET_CODE (sparc_compare_op0) == REG
4031 && GET_MODE (sparc_compare_op0) == DImode
4032 && v9_regcmp_p (code))
4034 operands[1] = gen_rtx_fmt_ee (code, DImode,
4035 sparc_compare_op0, sparc_compare_op1);
4039 rtx cc_reg = gen_compare_reg (code,
4040 sparc_compare_op0, sparc_compare_op1);
4041 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4045 (define_expand "movtfcc"
4046 [(set (match_operand:TF 0 "register_operand" "")
4047 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4048 (match_operand:TF 2 "register_operand" "")
4049 (match_operand:TF 3 "register_operand" "")))]
4050 "TARGET_V9 && TARGET_FPU"
4053 enum rtx_code code = GET_CODE (operands[1]);
4055 if (GET_MODE (sparc_compare_op0) == DImode
4059 if (sparc_compare_op1 == const0_rtx
4060 && GET_CODE (sparc_compare_op0) == REG
4061 && GET_MODE (sparc_compare_op0) == DImode
4062 && v9_regcmp_p (code))
4064 operands[1] = gen_rtx_fmt_ee (code, DImode,
4065 sparc_compare_op0, sparc_compare_op1);
4069 rtx cc_reg = gen_compare_reg (code,
4070 sparc_compare_op0, sparc_compare_op1);
4071 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4075 ;; Conditional move define_insns.
4077 (define_insn "*movqi_cc_sp64"
4078 [(set (match_operand:QI 0 "register_operand" "=r,r")
4079 (if_then_else:QI (match_operator 1 "comparison_operator"
4080 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4082 (match_operand:QI 3 "arith11_operand" "rL,0")
4083 (match_operand:QI 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 (define_insn "*movhi_cc_sp64"
4091 [(set (match_operand:HI 0 "register_operand" "=r,r")
4092 (if_then_else:HI (match_operator 1 "comparison_operator"
4093 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4095 (match_operand:HI 3 "arith11_operand" "rL,0")
4096 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4099 mov%C1\\t%x2, %3, %0
4100 mov%c1\\t%x2, %4, %0"
4101 [(set_attr "type" "cmove")])
4103 (define_insn "*movsi_cc_sp64"
4104 [(set (match_operand:SI 0 "register_operand" "=r,r")
4105 (if_then_else:SI (match_operator 1 "comparison_operator"
4106 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4108 (match_operand:SI 3 "arith11_operand" "rL,0")
4109 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4112 mov%C1\\t%x2, %3, %0
4113 mov%c1\\t%x2, %4, %0"
4114 [(set_attr "type" "cmove")])
4116 ;; ??? The constraints of operands 3,4 need work.
4117 (define_insn "*movdi_cc_sp64"
4118 [(set (match_operand:DI 0 "register_operand" "=r,r")
4119 (if_then_else:DI (match_operator 1 "comparison_operator"
4120 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4122 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4123 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4126 mov%C1\\t%x2, %3, %0
4127 mov%c1\\t%x2, %4, %0"
4128 [(set_attr "type" "cmove")])
4130 (define_insn "*movdi_cc_sp64_trunc"
4131 [(set (match_operand:SI 0 "register_operand" "=r,r")
4132 (if_then_else:SI (match_operator 1 "comparison_operator"
4133 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4135 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4136 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4139 mov%C1\\t%x2, %3, %0
4140 mov%c1\\t%x2, %4, %0"
4141 [(set_attr "type" "cmove")])
4143 (define_insn "*movsf_cc_sp64"
4144 [(set (match_operand:SF 0 "register_operand" "=f,f")
4145 (if_then_else:SF (match_operator 1 "comparison_operator"
4146 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4148 (match_operand:SF 3 "register_operand" "f,0")
4149 (match_operand:SF 4 "register_operand" "0,f")))]
4150 "TARGET_V9 && TARGET_FPU"
4152 fmovs%C1\\t%x2, %3, %0
4153 fmovs%c1\\t%x2, %4, %0"
4154 [(set_attr "type" "fpcmove")])
4156 (define_insn "movdf_cc_sp64"
4157 [(set (match_operand:DF 0 "register_operand" "=e,e")
4158 (if_then_else:DF (match_operator 1 "comparison_operator"
4159 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4161 (match_operand:DF 3 "register_operand" "e,0")
4162 (match_operand:DF 4 "register_operand" "0,e")))]
4163 "TARGET_V9 && TARGET_FPU"
4165 fmovd%C1\\t%x2, %3, %0
4166 fmovd%c1\\t%x2, %4, %0"
4167 [(set_attr "type" "fpcmove")
4168 (set_attr "fptype" "double")])
4170 (define_insn "*movtf_cc_hq_sp64"
4171 [(set (match_operand:TF 0 "register_operand" "=e,e")
4172 (if_then_else:TF (match_operator 1 "comparison_operator"
4173 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4175 (match_operand:TF 3 "register_operand" "e,0")
4176 (match_operand:TF 4 "register_operand" "0,e")))]
4177 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4179 fmovq%C1\\t%x2, %3, %0
4180 fmovq%c1\\t%x2, %4, %0"
4181 [(set_attr "type" "fpcmove")])
4183 (define_insn "*movtf_cc_sp64"
4184 [(set (match_operand:TF 0 "register_operand" "=e,e")
4185 (if_then_else:TF (match_operator 1 "comparison_operator"
4186 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4188 (match_operand:TF 3 "register_operand" "e,0")
4189 (match_operand:TF 4 "register_operand" "0,e")))]
4190 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4192 [(set_attr "length" "2")])
4195 [(set (match_operand:TF 0 "register_operand" "")
4196 (if_then_else:TF (match_operator 1 "comparison_operator"
4197 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4199 (match_operand:TF 3 "register_operand" "")
4200 (match_operand:TF 4 "register_operand" "")))]
4201 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4202 [(clobber (const_int 0))]
4205 rtx set_dest = operands[0];
4206 rtx set_srca = operands[3];
4207 rtx set_srcb = operands[4];
4208 int third = rtx_equal_p (set_dest, set_srca);
4210 rtx srca1, srca2, srcb1, srcb2;
4212 dest1 = gen_df_reg (set_dest, 0);
4213 dest2 = gen_df_reg (set_dest, 1);
4214 srca1 = gen_df_reg (set_srca, 0);
4215 srca2 = gen_df_reg (set_srca, 1);
4216 srcb1 = gen_df_reg (set_srcb, 0);
4217 srcb2 = gen_df_reg (set_srcb, 1);
4219 /* Now emit using the real source and destination we found, swapping
4220 the order if we detect overlap. */
4221 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4222 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4224 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4225 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4229 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4230 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4235 (define_insn "*movqi_cc_reg_sp64"
4236 [(set (match_operand:QI 0 "register_operand" "=r,r")
4237 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4238 [(match_operand:DI 2 "register_operand" "r,r")
4240 (match_operand:QI 3 "arith10_operand" "rM,0")
4241 (match_operand:QI 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 (define_insn "*movhi_cc_reg_sp64"
4249 [(set (match_operand:HI 0 "register_operand" "=r,r")
4250 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4251 [(match_operand:DI 2 "register_operand" "r,r")
4253 (match_operand:HI 3 "arith10_operand" "rM,0")
4254 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4257 movr%D1\\t%2, %r3, %0
4258 movr%d1\\t%2, %r4, %0"
4259 [(set_attr "type" "cmove")])
4261 (define_insn "*movsi_cc_reg_sp64"
4262 [(set (match_operand:SI 0 "register_operand" "=r,r")
4263 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4264 [(match_operand:DI 2 "register_operand" "r,r")
4266 (match_operand:SI 3 "arith10_operand" "rM,0")
4267 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4270 movr%D1\\t%2, %r3, %0
4271 movr%d1\\t%2, %r4, %0"
4272 [(set_attr "type" "cmove")])
4274 ;; ??? The constraints of operands 3,4 need work.
4275 (define_insn "*movdi_cc_reg_sp64"
4276 [(set (match_operand:DI 0 "register_operand" "=r,r")
4277 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4278 [(match_operand:DI 2 "register_operand" "r,r")
4280 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4281 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4284 movr%D1\\t%2, %r3, %0
4285 movr%d1\\t%2, %r4, %0"
4286 [(set_attr "type" "cmove")])
4288 (define_insn "*movdi_cc_reg_sp64_trunc"
4289 [(set (match_operand:SI 0 "register_operand" "=r,r")
4290 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4291 [(match_operand:DI 2 "register_operand" "r,r")
4293 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4294 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4297 movr%D1\\t%2, %r3, %0
4298 movr%d1\\t%2, %r4, %0"
4299 [(set_attr "type" "cmove")])
4301 (define_insn "*movsf_cc_reg_sp64"
4302 [(set (match_operand:SF 0 "register_operand" "=f,f")
4303 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4304 [(match_operand:DI 2 "register_operand" "r,r")
4306 (match_operand:SF 3 "register_operand" "f,0")
4307 (match_operand:SF 4 "register_operand" "0,f")))]
4308 "TARGET_ARCH64 && TARGET_FPU"
4310 fmovrs%D1\\t%2, %3, %0
4311 fmovrs%d1\\t%2, %4, %0"
4312 [(set_attr "type" "fpcmove")])
4314 (define_insn "movdf_cc_reg_sp64"
4315 [(set (match_operand:DF 0 "register_operand" "=e,e")
4316 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4317 [(match_operand:DI 2 "register_operand" "r,r")
4319 (match_operand:DF 3 "register_operand" "e,0")
4320 (match_operand:DF 4 "register_operand" "0,e")))]
4321 "TARGET_ARCH64 && TARGET_FPU"
4323 fmovrd%D1\\t%2, %3, %0
4324 fmovrd%d1\\t%2, %4, %0"
4325 [(set_attr "type" "fpcmove")
4326 (set_attr "fptype" "double")])
4328 (define_insn "*movtf_cc_reg_hq_sp64"
4329 [(set (match_operand:TF 0 "register_operand" "=e,e")
4330 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4331 [(match_operand:DI 2 "register_operand" "r,r")
4333 (match_operand:TF 3 "register_operand" "e,0")
4334 (match_operand:TF 4 "register_operand" "0,e")))]
4335 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4337 fmovrq%D1\\t%2, %3, %0
4338 fmovrq%d1\\t%2, %4, %0"
4339 [(set_attr "type" "fpcmove")])
4341 (define_insn "*movtf_cc_reg_sp64"
4342 [(set (match_operand:TF 0 "register_operand" "=e,e")
4343 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4344 [(match_operand:DI 2 "register_operand" "r,r")
4346 (match_operand:TF 3 "register_operand" "e,0")
4347 (match_operand:TF 4 "register_operand" "0,e")))]
4348 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4350 [(set_attr "length" "2")])
4353 [(set (match_operand:TF 0 "register_operand" "")
4354 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4355 [(match_operand:DI 2 "register_operand" "")
4357 (match_operand:TF 3 "register_operand" "")
4358 (match_operand:TF 4 "register_operand" "")))]
4359 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4360 [(clobber (const_int 0))]
4363 rtx set_dest = operands[0];
4364 rtx set_srca = operands[3];
4365 rtx set_srcb = operands[4];
4366 int third = rtx_equal_p (set_dest, set_srca);
4368 rtx srca1, srca2, srcb1, srcb2;
4370 dest1 = gen_df_reg (set_dest, 0);
4371 dest2 = gen_df_reg (set_dest, 1);
4372 srca1 = gen_df_reg (set_srca, 0);
4373 srca2 = gen_df_reg (set_srca, 1);
4374 srcb1 = gen_df_reg (set_srcb, 0);
4375 srcb2 = gen_df_reg (set_srcb, 1);
4377 /* Now emit using the real source and destination we found, swapping
4378 the order if we detect overlap. */
4379 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4380 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4382 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4383 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4387 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4388 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4394 ;;- zero extension instructions
4396 ;; These patterns originally accepted general_operands, however, slightly
4397 ;; better code is generated by only accepting register_operands, and then
4398 ;; letting combine generate the ldu[hb] insns.
4400 (define_expand "zero_extendhisi2"
4401 [(set (match_operand:SI 0 "register_operand" "")
4402 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4406 rtx temp = gen_reg_rtx (SImode);
4407 rtx shift_16 = GEN_INT (16);
4408 int op1_subbyte = 0;
4410 if (GET_CODE (operand1) == SUBREG)
4412 op1_subbyte = SUBREG_BYTE (operand1);
4413 op1_subbyte /= GET_MODE_SIZE (SImode);
4414 op1_subbyte *= GET_MODE_SIZE (SImode);
4415 operand1 = XEXP (operand1, 0);
4418 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4420 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4424 (define_insn "*zero_extendhisi2_insn"
4425 [(set (match_operand:SI 0 "register_operand" "=r")
4426 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4429 [(set_attr "type" "load")])
4431 (define_expand "zero_extendqihi2"
4432 [(set (match_operand:HI 0 "register_operand" "")
4433 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4437 (define_insn "*zero_extendqihi2_insn"
4438 [(set (match_operand:HI 0 "register_operand" "=r,r")
4439 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4440 "GET_CODE (operands[1]) != CONST_INT"
4444 [(set_attr "type" "*,load")])
4446 (define_expand "zero_extendqisi2"
4447 [(set (match_operand:SI 0 "register_operand" "")
4448 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4452 (define_insn "*zero_extendqisi2_insn"
4453 [(set (match_operand:SI 0 "register_operand" "=r,r")
4454 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4455 "GET_CODE (operands[1]) != CONST_INT"
4459 [(set_attr "type" "*,load")])
4461 (define_expand "zero_extendqidi2"
4462 [(set (match_operand:DI 0 "register_operand" "")
4463 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4467 (define_insn "*zero_extendqidi2_insn"
4468 [(set (match_operand:DI 0 "register_operand" "=r,r")
4469 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4470 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4474 [(set_attr "type" "*,load")])
4476 (define_expand "zero_extendhidi2"
4477 [(set (match_operand:DI 0 "register_operand" "")
4478 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4482 rtx temp = gen_reg_rtx (DImode);
4483 rtx shift_48 = GEN_INT (48);
4484 int op1_subbyte = 0;
4486 if (GET_CODE (operand1) == SUBREG)
4488 op1_subbyte = SUBREG_BYTE (operand1);
4489 op1_subbyte /= GET_MODE_SIZE (DImode);
4490 op1_subbyte *= GET_MODE_SIZE (DImode);
4491 operand1 = XEXP (operand1, 0);
4494 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4496 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4500 (define_insn "*zero_extendhidi2_insn"
4501 [(set (match_operand:DI 0 "register_operand" "=r")
4502 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4505 [(set_attr "type" "load")])
4508 ;; ??? Write truncdisi pattern using sra?
4510 (define_expand "zero_extendsidi2"
4511 [(set (match_operand:DI 0 "register_operand" "")
4512 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4516 (define_insn "*zero_extendsidi2_insn_sp64"
4517 [(set (match_operand:DI 0 "register_operand" "=r,r")
4518 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4519 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4523 [(set_attr "type" "shift,load")])
4525 (define_insn "*zero_extendsidi2_insn_sp32"
4526 [(set (match_operand:DI 0 "register_operand" "=r")
4527 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4530 [(set_attr "length" "2")])
4533 [(set (match_operand:DI 0 "register_operand" "")
4534 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4535 "! TARGET_ARCH64 && reload_completed"
4536 [(set (match_dup 2) (match_dup 3))
4537 (set (match_dup 4) (match_dup 5))]
4542 dest1 = gen_highpart (SImode, operands[0]);
4543 dest2 = gen_lowpart (SImode, operands[0]);
4545 /* Swap the order in case of overlap. */
4546 if (REGNO (dest1) == REGNO (operands[1]))
4548 operands[2] = dest2;
4549 operands[3] = operands[1];
4550 operands[4] = dest1;
4551 operands[5] = const0_rtx;
4555 operands[2] = dest1;
4556 operands[3] = const0_rtx;
4557 operands[4] = dest2;
4558 operands[5] = operands[1];
4562 ;; Simplify comparisons of extended values.
4564 (define_insn "*cmp_zero_extendqisi2"
4566 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4569 "andcc\\t%0, 0xff, %%g0"
4570 [(set_attr "type" "compare")])
4572 (define_insn "*cmp_zero_qi"
4574 (compare:CC (match_operand:QI 0 "register_operand" "r")
4577 "andcc\\t%0, 0xff, %%g0"
4578 [(set_attr "type" "compare")])
4580 (define_insn "*cmp_zero_extendqisi2_set"
4582 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4584 (set (match_operand:SI 0 "register_operand" "=r")
4585 (zero_extend:SI (match_dup 1)))]
4587 "andcc\\t%1, 0xff, %0"
4588 [(set_attr "type" "compare")])
4590 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4592 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4595 (set (match_operand:SI 0 "register_operand" "=r")
4596 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4598 "andcc\\t%1, 0xff, %0"
4599 [(set_attr "type" "compare")])
4601 (define_insn "*cmp_zero_extendqidi2"
4603 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4606 "andcc\\t%0, 0xff, %%g0"
4607 [(set_attr "type" "compare")])
4609 (define_insn "*cmp_zero_qi_sp64"
4611 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4614 "andcc\\t%0, 0xff, %%g0"
4615 [(set_attr "type" "compare")])
4617 (define_insn "*cmp_zero_extendqidi2_set"
4619 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4621 (set (match_operand:DI 0 "register_operand" "=r")
4622 (zero_extend:DI (match_dup 1)))]
4624 "andcc\\t%1, 0xff, %0"
4625 [(set_attr "type" "compare")])
4627 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4629 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4632 (set (match_operand:DI 0 "register_operand" "=r")
4633 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4635 "andcc\\t%1, 0xff, %0"
4636 [(set_attr "type" "compare")])
4638 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4640 (define_insn "*cmp_siqi_trunc"
4642 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4645 "andcc\\t%0, 0xff, %%g0"
4646 [(set_attr "type" "compare")])
4648 (define_insn "*cmp_siqi_trunc_set"
4650 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4652 (set (match_operand:QI 0 "register_operand" "=r")
4653 (subreg:QI (match_dup 1) 3))]
4655 "andcc\\t%1, 0xff, %0"
4656 [(set_attr "type" "compare")])
4658 (define_insn "*cmp_diqi_trunc"
4660 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4663 "andcc\\t%0, 0xff, %%g0"
4664 [(set_attr "type" "compare")])
4666 (define_insn "*cmp_diqi_trunc_set"
4668 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4670 (set (match_operand:QI 0 "register_operand" "=r")
4671 (subreg:QI (match_dup 1) 7))]
4673 "andcc\\t%1, 0xff, %0"
4674 [(set_attr "type" "compare")])
4676 ;;- sign extension instructions
4678 ;; These patterns originally accepted general_operands, however, slightly
4679 ;; better code is generated by only accepting register_operands, and then
4680 ;; letting combine generate the lds[hb] insns.
4682 (define_expand "extendhisi2"
4683 [(set (match_operand:SI 0 "register_operand" "")
4684 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4688 rtx temp = gen_reg_rtx (SImode);
4689 rtx shift_16 = GEN_INT (16);
4690 int op1_subbyte = 0;
4692 if (GET_CODE (operand1) == SUBREG)
4694 op1_subbyte = SUBREG_BYTE (operand1);
4695 op1_subbyte /= GET_MODE_SIZE (SImode);
4696 op1_subbyte *= GET_MODE_SIZE (SImode);
4697 operand1 = XEXP (operand1, 0);
4700 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4702 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4706 (define_insn "*sign_extendhisi2_insn"
4707 [(set (match_operand:SI 0 "register_operand" "=r")
4708 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4711 [(set_attr "type" "sload")])
4713 (define_expand "extendqihi2"
4714 [(set (match_operand:HI 0 "register_operand" "")
4715 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4719 rtx temp = gen_reg_rtx (SImode);
4720 rtx shift_24 = GEN_INT (24);
4721 int op1_subbyte = 0;
4722 int op0_subbyte = 0;
4724 if (GET_CODE (operand1) == SUBREG)
4726 op1_subbyte = SUBREG_BYTE (operand1);
4727 op1_subbyte /= GET_MODE_SIZE (SImode);
4728 op1_subbyte *= GET_MODE_SIZE (SImode);
4729 operand1 = XEXP (operand1, 0);
4731 if (GET_CODE (operand0) == SUBREG)
4733 op0_subbyte = SUBREG_BYTE (operand0);
4734 op0_subbyte /= GET_MODE_SIZE (SImode);
4735 op0_subbyte *= GET_MODE_SIZE (SImode);
4736 operand0 = XEXP (operand0, 0);
4738 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4740 if (GET_MODE (operand0) != SImode)
4741 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4742 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4746 (define_insn "*sign_extendqihi2_insn"
4747 [(set (match_operand:HI 0 "register_operand" "=r")
4748 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4751 [(set_attr "type" "sload")])
4753 (define_expand "extendqisi2"
4754 [(set (match_operand:SI 0 "register_operand" "")
4755 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4759 rtx temp = gen_reg_rtx (SImode);
4760 rtx shift_24 = GEN_INT (24);
4761 int op1_subbyte = 0;
4763 if (GET_CODE (operand1) == SUBREG)
4765 op1_subbyte = SUBREG_BYTE (operand1);
4766 op1_subbyte /= GET_MODE_SIZE (SImode);
4767 op1_subbyte *= GET_MODE_SIZE (SImode);
4768 operand1 = XEXP (operand1, 0);
4771 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4773 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4777 (define_insn "*sign_extendqisi2_insn"
4778 [(set (match_operand:SI 0 "register_operand" "=r")
4779 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4782 [(set_attr "type" "sload")])
4784 (define_expand "extendqidi2"
4785 [(set (match_operand:DI 0 "register_operand" "")
4786 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4790 rtx temp = gen_reg_rtx (DImode);
4791 rtx shift_56 = GEN_INT (56);
4792 int op1_subbyte = 0;
4794 if (GET_CODE (operand1) == SUBREG)
4796 op1_subbyte = SUBREG_BYTE (operand1);
4797 op1_subbyte /= GET_MODE_SIZE (DImode);
4798 op1_subbyte *= GET_MODE_SIZE (DImode);
4799 operand1 = XEXP (operand1, 0);
4802 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4804 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4808 (define_insn "*sign_extendqidi2_insn"
4809 [(set (match_operand:DI 0 "register_operand" "=r")
4810 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4813 [(set_attr "type" "sload")])
4815 (define_expand "extendhidi2"
4816 [(set (match_operand:DI 0 "register_operand" "")
4817 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4821 rtx temp = gen_reg_rtx (DImode);
4822 rtx shift_48 = GEN_INT (48);
4823 int op1_subbyte = 0;
4825 if (GET_CODE (operand1) == SUBREG)
4827 op1_subbyte = SUBREG_BYTE (operand1);
4828 op1_subbyte /= GET_MODE_SIZE (DImode);
4829 op1_subbyte *= GET_MODE_SIZE (DImode);
4830 operand1 = XEXP (operand1, 0);
4833 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4835 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4839 (define_insn "*sign_extendhidi2_insn"
4840 [(set (match_operand:DI 0 "register_operand" "=r")
4841 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4844 [(set_attr "type" "sload")])
4846 (define_expand "extendsidi2"
4847 [(set (match_operand:DI 0 "register_operand" "")
4848 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4852 (define_insn "*sign_extendsidi2_insn"
4853 [(set (match_operand:DI 0 "register_operand" "=r,r")
4854 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4859 [(set_attr "type" "shift,sload")])
4861 ;; Special pattern for optimizing bit-field compares. This is needed
4862 ;; because combine uses this as a canonical form.
4864 (define_insn "*cmp_zero_extract"
4867 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4868 (match_operand:SI 1 "small_int_or_double" "n")
4869 (match_operand:SI 2 "small_int_or_double" "n"))
4871 "(GET_CODE (operands[2]) == CONST_INT
4872 && INTVAL (operands[2]) > 19)
4873 || (GET_CODE (operands[2]) == CONST_DOUBLE
4874 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4877 int len = (GET_CODE (operands[1]) == CONST_INT
4878 ? INTVAL (operands[1])
4879 : CONST_DOUBLE_LOW (operands[1]));
4881 (GET_CODE (operands[2]) == CONST_INT
4882 ? INTVAL (operands[2])
4883 : CONST_DOUBLE_LOW (operands[2])) - len;
4884 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4886 operands[1] = GEN_INT (mask);
4887 return \"andcc\\t%0, %1, %%g0\";
4889 [(set_attr "type" "compare")])
4891 (define_insn "*cmp_zero_extract_sp64"
4894 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4895 (match_operand:SI 1 "small_int_or_double" "n")
4896 (match_operand:SI 2 "small_int_or_double" "n"))
4899 && ((GET_CODE (operands[2]) == CONST_INT
4900 && INTVAL (operands[2]) > 51)
4901 || (GET_CODE (operands[2]) == CONST_DOUBLE
4902 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4905 int len = (GET_CODE (operands[1]) == CONST_INT
4906 ? INTVAL (operands[1])
4907 : CONST_DOUBLE_LOW (operands[1]));
4909 (GET_CODE (operands[2]) == CONST_INT
4910 ? INTVAL (operands[2])
4911 : CONST_DOUBLE_LOW (operands[2])) - len;
4912 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4914 operands[1] = GEN_INT (mask);
4915 return \"andcc\\t%0, %1, %%g0\";
4917 [(set_attr "type" "compare")])
4919 ;; Conversions between float, double and long double.
4921 (define_insn "extendsfdf2"
4922 [(set (match_operand:DF 0 "register_operand" "=e")
4924 (match_operand:SF 1 "register_operand" "f")))]
4927 [(set_attr "type" "fp")
4928 (set_attr "fptype" "double")])
4930 (define_expand "extendsftf2"
4931 [(set (match_operand:TF 0 "register_operand" "=e")
4933 (match_operand:SF 1 "register_operand" "f")))]
4934 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4937 if (! TARGET_HARD_QUAD)
4941 if (GET_CODE (operands[0]) != MEM)
4942 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4944 slot0 = operands[0];
4946 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4948 XEXP (slot0, 0), Pmode,
4949 operands[1], SFmode);
4951 if (GET_CODE (operands[0]) != MEM)
4952 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4957 (define_insn "*extendsftf2_hq"
4958 [(set (match_operand:TF 0 "register_operand" "=e")
4960 (match_operand:SF 1 "register_operand" "f")))]
4961 "TARGET_FPU && TARGET_HARD_QUAD"
4963 [(set_attr "type" "fp")])
4965 (define_expand "extenddftf2"
4966 [(set (match_operand:TF 0 "register_operand" "=e")
4968 (match_operand:DF 1 "register_operand" "e")))]
4969 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4972 if (! TARGET_HARD_QUAD)
4976 if (GET_CODE (operands[0]) != MEM)
4977 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4979 slot0 = operands[0];
4981 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
4983 XEXP (slot0, 0), Pmode,
4984 operands[1], DFmode);
4986 if (GET_CODE (operands[0]) != MEM)
4987 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4992 (define_insn "*extenddftf2_hq"
4993 [(set (match_operand:TF 0 "register_operand" "=e")
4995 (match_operand:DF 1 "register_operand" "e")))]
4996 "TARGET_FPU && TARGET_HARD_QUAD"
4998 [(set_attr "type" "fp")])
5000 (define_insn "truncdfsf2"
5001 [(set (match_operand:SF 0 "register_operand" "=f")
5003 (match_operand:DF 1 "register_operand" "e")))]
5006 [(set_attr "type" "fp")
5007 (set_attr "fptype" "double")])
5009 (define_expand "trunctfsf2"
5010 [(set (match_operand:SF 0 "register_operand" "=f")
5012 (match_operand:TF 1 "register_operand" "e")))]
5013 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5016 if (! TARGET_HARD_QUAD)
5020 if (GET_CODE (operands[1]) != MEM)
5022 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5023 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5026 slot0 = operands[1];
5028 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5029 operands[0], 0, SFmode, 1,
5030 XEXP (slot0, 0), Pmode);
5035 (define_insn "*trunctfsf2_hq"
5036 [(set (match_operand:SF 0 "register_operand" "=f")
5038 (match_operand:TF 1 "register_operand" "e")))]
5039 "TARGET_FPU && TARGET_HARD_QUAD"
5041 [(set_attr "type" "fp")])
5043 (define_expand "trunctfdf2"
5044 [(set (match_operand:DF 0 "register_operand" "=f")
5046 (match_operand:TF 1 "register_operand" "e")))]
5047 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5050 if (! TARGET_HARD_QUAD)
5054 if (GET_CODE (operands[1]) != MEM)
5056 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5057 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5060 slot0 = operands[1];
5062 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5063 operands[0], 0, DFmode, 1,
5064 XEXP (slot0, 0), Pmode);
5069 (define_insn "*trunctfdf2_hq"
5070 [(set (match_operand:DF 0 "register_operand" "=e")
5072 (match_operand:TF 1 "register_operand" "e")))]
5073 "TARGET_FPU && TARGET_HARD_QUAD"
5075 [(set_attr "type" "fp")])
5077 ;; Conversion between fixed point and floating point.
5079 (define_insn "floatsisf2"
5080 [(set (match_operand:SF 0 "register_operand" "=f")
5081 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5084 [(set_attr "type" "fp")
5085 (set_attr "fptype" "double")])
5087 (define_insn "floatsidf2"
5088 [(set (match_operand:DF 0 "register_operand" "=e")
5089 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5092 [(set_attr "type" "fp")
5093 (set_attr "fptype" "double")])
5095 (define_expand "floatsitf2"
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 || TARGET_ARCH64)"
5101 if (! TARGET_HARD_QUAD)
5105 if (GET_CODE (operands[1]) != MEM)
5106 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5108 slot0 = operands[1];
5110 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5112 XEXP (slot0, 0), Pmode,
5113 operands[1], SImode);
5115 if (GET_CODE (operands[0]) != MEM)
5116 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5121 (define_insn "*floatsitf2_hq"
5122 [(set (match_operand:TF 0 "register_operand" "=e")
5123 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5124 "TARGET_FPU && TARGET_HARD_QUAD"
5126 [(set_attr "type" "fp")])
5128 (define_expand "floatunssitf2"
5129 [(set (match_operand:TF 0 "register_operand" "=e")
5130 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5131 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5136 if (GET_CODE (operands[1]) != MEM)
5137 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5139 slot0 = operands[1];
5141 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5143 XEXP (slot0, 0), Pmode,
5144 operands[1], SImode);
5146 if (GET_CODE (operands[0]) != MEM)
5147 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5151 ;; Now the same for 64 bit sources.
5153 (define_insn "floatdisf2"
5154 [(set (match_operand:SF 0 "register_operand" "=f")
5155 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5156 "TARGET_V9 && TARGET_FPU"
5158 [(set_attr "type" "fp")
5159 (set_attr "fptype" "double")])
5161 (define_insn "floatdidf2"
5162 [(set (match_operand:DF 0 "register_operand" "=e")
5163 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5164 "TARGET_V9 && TARGET_FPU"
5166 [(set_attr "type" "fp")
5167 (set_attr "fptype" "double")])
5169 (define_expand "floatditf2"
5170 [(set (match_operand:TF 0 "register_operand" "=e")
5171 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5172 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5175 if (! TARGET_HARD_QUAD)
5179 if (GET_CODE (operands[1]) != MEM)
5180 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5182 slot0 = operands[1];
5184 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5186 XEXP (slot0, 0), Pmode,
5187 operands[1], DImode);
5189 if (GET_CODE (operands[0]) != MEM)
5190 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5195 (define_insn "*floatditf2_hq"
5196 [(set (match_operand:TF 0 "register_operand" "=e")
5197 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5198 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5200 [(set_attr "type" "fp")])
5202 (define_expand "floatunsditf2"
5203 [(set (match_operand:TF 0 "register_operand" "=e")
5204 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5205 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5210 if (GET_CODE (operands[1]) != MEM)
5211 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5213 slot0 = operands[1];
5215 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5217 XEXP (slot0, 0), Pmode,
5218 operands[1], DImode);
5220 if (GET_CODE (operands[0]) != MEM)
5221 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5225 ;; Convert a float to an actual integer.
5226 ;; Truncation is performed as part of the conversion.
5228 (define_insn "fix_truncsfsi2"
5229 [(set (match_operand:SI 0 "register_operand" "=f")
5230 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5233 [(set_attr "type" "fp")
5234 (set_attr "fptype" "double")])
5236 (define_insn "fix_truncdfsi2"
5237 [(set (match_operand:SI 0 "register_operand" "=f")
5238 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5241 [(set_attr "type" "fp")
5242 (set_attr "fptype" "double")])
5244 (define_expand "fix_trunctfsi2"
5245 [(set (match_operand:SI 0 "register_operand" "=f")
5246 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5247 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5250 if (! TARGET_HARD_QUAD)
5254 if (GET_CODE (operands[1]) != MEM)
5256 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5257 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5260 slot0 = operands[1];
5262 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5263 operands[0], 0, SImode, 1,
5264 XEXP (slot0, 0), Pmode);
5269 (define_insn "*fix_trunctfsi2_hq"
5270 [(set (match_operand:SI 0 "register_operand" "=f")
5271 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5272 "TARGET_FPU && TARGET_HARD_QUAD"
5274 [(set_attr "type" "fp")])
5276 (define_expand "fixuns_trunctfsi2"
5277 [(set (match_operand:SI 0 "register_operand" "=f")
5278 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5279 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5284 if (GET_CODE (operands[1]) != MEM)
5286 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5287 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5290 slot0 = operands[1];
5292 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5293 operands[0], 0, SImode, 1,
5294 XEXP (slot0, 0), Pmode);
5298 ;; Now the same, for V9 targets
5300 (define_insn "fix_truncsfdi2"
5301 [(set (match_operand:DI 0 "register_operand" "=e")
5302 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5303 "TARGET_V9 && TARGET_FPU"
5305 [(set_attr "type" "fp")
5306 (set_attr "fptype" "double")])
5308 (define_insn "fix_truncdfdi2"
5309 [(set (match_operand:DI 0 "register_operand" "=e")
5310 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5311 "TARGET_V9 && TARGET_FPU"
5313 [(set_attr "type" "fp")
5314 (set_attr "fptype" "double")])
5316 (define_expand "fix_trunctfdi2"
5317 [(set (match_operand:DI 0 "register_operand" "=e")
5318 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5319 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5322 if (! TARGET_HARD_QUAD)
5326 if (GET_CODE (operands[1]) != MEM)
5328 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5329 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5332 slot0 = operands[1];
5334 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5335 operands[0], 0, DImode, 1,
5336 XEXP (slot0, 0), Pmode);
5341 (define_insn "*fix_trunctfdi2_hq"
5342 [(set (match_operand:DI 0 "register_operand" "=e")
5343 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5344 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5346 [(set_attr "type" "fp")])
5348 (define_expand "fixuns_trunctfdi2"
5349 [(set (match_operand:DI 0 "register_operand" "=f")
5350 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5351 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5356 if (GET_CODE (operands[1]) != MEM)
5358 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5359 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5362 slot0 = operands[1];
5364 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5365 operands[0], 0, DImode, 1,
5366 XEXP (slot0, 0), Pmode);
5371 ;;- arithmetic instructions
5373 (define_expand "adddi3"
5374 [(set (match_operand:DI 0 "register_operand" "=r")
5375 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5376 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5382 if (! TARGET_ARCH64)
5384 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5385 gen_rtx_SET (VOIDmode, operands[0],
5386 gen_rtx_PLUS (DImode, operands[1],
5388 gen_rtx_CLOBBER (VOIDmode,
5389 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5392 if (arith_double_4096_operand(operands[2], DImode))
5394 switch (GET_CODE (operands[1]))
5396 case CONST_INT: i = INTVAL (operands[1]); break;
5397 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5399 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5400 gen_rtx_MINUS (DImode, operands[1],
5404 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5409 (define_insn "adddi3_insn_sp32"
5410 [(set (match_operand:DI 0 "register_operand" "=r")
5411 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5412 (match_operand:DI 2 "arith_double_operand" "rHI")))
5413 (clobber (reg:CC 100))]
5416 [(set_attr "length" "2")])
5419 [(set (match_operand:DI 0 "register_operand" "")
5420 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5421 (match_operand:DI 2 "arith_double_operand" "")))
5422 (clobber (reg:CC 100))]
5423 "! TARGET_ARCH64 && reload_completed"
5424 [(parallel [(set (reg:CC_NOOV 100)
5425 (compare:CC_NOOV (plus:SI (match_dup 4)
5429 (plus:SI (match_dup 4) (match_dup 5)))])
5431 (plus:SI (plus:SI (match_dup 7)
5433 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5436 operands[3] = gen_lowpart (SImode, operands[0]);
5437 operands[4] = gen_lowpart (SImode, operands[1]);
5438 operands[5] = gen_lowpart (SImode, operands[2]);
5439 operands[6] = gen_highpart (SImode, operands[0]);
5440 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5441 #if HOST_BITS_PER_WIDE_INT == 32
5442 if (GET_CODE (operands[2]) == CONST_INT)
5444 if (INTVAL (operands[2]) < 0)
5445 operands[8] = constm1_rtx;
5447 operands[8] = const0_rtx;
5451 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5455 [(set (match_operand:DI 0 "register_operand" "")
5456 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5457 (match_operand:DI 2 "arith_double_operand" "")))
5458 (clobber (reg:CC 100))]
5459 "! TARGET_ARCH64 && reload_completed"
5460 [(parallel [(set (reg:CC_NOOV 100)
5461 (compare:CC_NOOV (minus:SI (match_dup 4)
5465 (minus:SI (match_dup 4) (match_dup 5)))])
5467 (minus:SI (minus:SI (match_dup 7)
5469 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5472 operands[3] = gen_lowpart (SImode, operands[0]);
5473 operands[4] = gen_lowpart (SImode, operands[1]);
5474 operands[5] = gen_lowpart (SImode, operands[2]);
5475 operands[6] = gen_highpart (SImode, operands[0]);
5476 operands[7] = gen_highpart (SImode, operands[1]);
5477 #if HOST_BITS_PER_WIDE_INT == 32
5478 if (GET_CODE (operands[2]) == CONST_INT)
5480 if (INTVAL (operands[2]) < 0)
5481 operands[8] = constm1_rtx;
5483 operands[8] = const0_rtx;
5487 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5490 ;; LTU here means "carry set"
5492 [(set (match_operand:SI 0 "register_operand" "=r")
5493 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5494 (match_operand:SI 2 "arith_operand" "rI"))
5495 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5498 [(set_attr "type" "misc")])
5500 (define_insn "*addx_extend_sp32"
5501 [(set (match_operand:DI 0 "register_operand" "=r")
5502 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5503 (match_operand:SI 2 "arith_operand" "rI"))
5504 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5507 [(set_attr "length" "2")])
5510 [(set (match_operand:DI 0 "register_operand" "")
5511 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5512 (match_operand:SI 2 "arith_operand" ""))
5513 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5514 "! TARGET_ARCH64 && reload_completed"
5515 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5516 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5517 (set (match_dup 4) (const_int 0))]
5518 "operands[3] = gen_lowpart (SImode, operands[0]);
5519 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5521 (define_insn "*addx_extend_sp64"
5522 [(set (match_operand:DI 0 "register_operand" "=r")
5523 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5524 (match_operand:SI 2 "arith_operand" "rI"))
5525 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5527 "addx\\t%r1, %2, %0"
5528 [(set_attr "type" "misc")])
5531 [(set (match_operand:SI 0 "register_operand" "=r")
5532 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5533 (match_operand:SI 2 "arith_operand" "rI"))
5534 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5536 "subx\\t%r1, %2, %0"
5537 [(set_attr "type" "misc")])
5539 (define_insn "*subx_extend_sp64"
5540 [(set (match_operand:DI 0 "register_operand" "=r")
5541 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5542 (match_operand:SI 2 "arith_operand" "rI"))
5543 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5545 "subx\\t%r1, %2, %0"
5546 [(set_attr "type" "misc")])
5548 (define_insn "*subx_extend"
5549 [(set (match_operand:DI 0 "register_operand" "=r")
5550 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5551 (match_operand:SI 2 "arith_operand" "rI"))
5552 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5555 [(set_attr "length" "2")])
5558 [(set (match_operand:DI 0 "register_operand" "")
5559 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5560 (match_operand:SI 2 "arith_operand" ""))
5561 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5562 "! TARGET_ARCH64 && reload_completed"
5563 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5564 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5565 (set (match_dup 4) (const_int 0))]
5566 "operands[3] = gen_lowpart (SImode, operands[0]);
5567 operands[4] = gen_highpart (SImode, operands[0]);")
5570 [(set (match_operand:DI 0 "register_operand" "=r")
5571 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5572 (match_operand:DI 2 "register_operand" "r")))
5573 (clobber (reg:CC 100))]
5576 [(set_attr "length" "2")])
5579 [(set (match_operand:DI 0 "register_operand" "")
5580 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5581 (match_operand:DI 2 "register_operand" "")))
5582 (clobber (reg:CC 100))]
5583 "! TARGET_ARCH64 && reload_completed"
5584 [(parallel [(set (reg:CC_NOOV 100)
5585 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5587 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5589 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5590 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5591 "operands[3] = gen_lowpart (SImode, operands[2]);
5592 operands[4] = gen_highpart (SImode, operands[2]);
5593 operands[5] = gen_lowpart (SImode, operands[0]);
5594 operands[6] = gen_highpart (SImode, operands[0]);")
5596 (define_insn "*adddi3_sp64"
5597 [(set (match_operand:DI 0 "register_operand" "=r")
5598 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5599 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5603 (define_expand "addsi3"
5604 [(set (match_operand:SI 0 "register_operand" "=r,d")
5605 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5606 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5610 if (arith_4096_operand(operands[2], SImode))
5612 if (GET_CODE (operands[1]) == CONST_INT)
5613 emit_insn (gen_movsi (operands[0],
5614 GEN_INT (INTVAL (operands[1]) + 4096)));
5616 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5617 gen_rtx_MINUS (SImode, operands[1],
5623 (define_insn "*addsi3"
5624 [(set (match_operand:SI 0 "register_operand" "=r,d")
5625 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5626 (match_operand:SI 2 "arith_operand" "rI,d")))]
5630 fpadd32s\\t%1, %2, %0"
5631 [(set_attr "type" "*,fp")])
5633 (define_insn "*cmp_cc_plus"
5634 [(set (reg:CC_NOOV 100)
5635 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5636 (match_operand:SI 1 "arith_operand" "rI"))
5639 "addcc\\t%0, %1, %%g0"
5640 [(set_attr "type" "compare")])
5642 (define_insn "*cmp_ccx_plus"
5643 [(set (reg:CCX_NOOV 100)
5644 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5645 (match_operand:DI 1 "arith_double_operand" "rHI"))
5648 "addcc\\t%0, %1, %%g0"
5649 [(set_attr "type" "compare")])
5651 (define_insn "*cmp_cc_plus_set"
5652 [(set (reg:CC_NOOV 100)
5653 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5654 (match_operand:SI 2 "arith_operand" "rI"))
5656 (set (match_operand:SI 0 "register_operand" "=r")
5657 (plus:SI (match_dup 1) (match_dup 2)))]
5659 "addcc\\t%1, %2, %0"
5660 [(set_attr "type" "compare")])
5662 (define_insn "*cmp_ccx_plus_set"
5663 [(set (reg:CCX_NOOV 100)
5664 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5665 (match_operand:DI 2 "arith_double_operand" "rHI"))
5667 (set (match_operand:DI 0 "register_operand" "=r")
5668 (plus:DI (match_dup 1) (match_dup 2)))]
5670 "addcc\\t%1, %2, %0"
5671 [(set_attr "type" "compare")])
5673 (define_expand "subdi3"
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_add_operand" "rHI")))]
5680 if (! TARGET_ARCH64)
5682 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5683 gen_rtx_SET (VOIDmode, operands[0],
5684 gen_rtx_MINUS (DImode, operands[1],
5686 gen_rtx_CLOBBER (VOIDmode,
5687 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5690 if (arith_double_4096_operand(operands[2], DImode))
5692 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5693 gen_rtx_PLUS (DImode, operands[1],
5699 (define_insn "*subdi3_sp32"
5700 [(set (match_operand:DI 0 "register_operand" "=r")
5701 (minus:DI (match_operand:DI 1 "register_operand" "r")
5702 (match_operand:DI 2 "arith_double_operand" "rHI")))
5703 (clobber (reg:CC 100))]
5706 [(set_attr "length" "2")])
5709 [(set (match_operand:DI 0 "register_operand" "")
5710 (minus:DI (match_operand:DI 1 "register_operand" "")
5711 (match_operand:DI 2 "arith_double_operand" "")))
5712 (clobber (reg:CC 100))]
5715 && (GET_CODE (operands[2]) == CONST_INT
5716 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5717 [(clobber (const_int 0))]
5722 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5723 lowp = gen_lowpart (SImode, operands[2]);
5724 if ((lowp == const0_rtx)
5725 && (operands[0] == operands[1]))
5727 emit_insn (gen_rtx_SET (VOIDmode,
5728 gen_highpart (SImode, operands[0]),
5729 gen_rtx_MINUS (SImode,
5730 gen_highpart_mode (SImode, DImode,
5736 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5737 gen_lowpart (SImode, operands[1]),
5739 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5740 gen_highpart_mode (SImode, DImode, operands[1]),
5747 [(set (match_operand:DI 0 "register_operand" "")
5748 (minus:DI (match_operand:DI 1 "register_operand" "")
5749 (match_operand:DI 2 "register_operand" "")))
5750 (clobber (reg:CC 100))]
5752 && reload_completed"
5753 [(clobber (const_int 0))]
5756 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5757 gen_lowpart (SImode, operands[1]),
5758 gen_lowpart (SImode, operands[2])));
5759 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5760 gen_highpart (SImode, operands[1]),
5761 gen_highpart (SImode, operands[2])));
5766 [(set (match_operand:DI 0 "register_operand" "=r")
5767 (minus:DI (match_operand:DI 1 "register_operand" "r")
5768 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5769 (clobber (reg:CC 100))]
5772 [(set_attr "length" "2")])
5775 [(set (match_operand:DI 0 "register_operand" "")
5776 (minus:DI (match_operand:DI 1 "register_operand" "")
5777 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5778 (clobber (reg:CC 100))]
5779 "! TARGET_ARCH64 && reload_completed"
5780 [(parallel [(set (reg:CC_NOOV 100)
5781 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5783 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5785 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5786 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5787 "operands[3] = gen_lowpart (SImode, operands[1]);
5788 operands[4] = gen_highpart (SImode, operands[1]);
5789 operands[5] = gen_lowpart (SImode, operands[0]);
5790 operands[6] = gen_highpart (SImode, operands[0]);")
5792 (define_insn "*subdi3_sp64"
5793 [(set (match_operand:DI 0 "register_operand" "=r")
5794 (minus:DI (match_operand:DI 1 "register_operand" "r")
5795 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5799 (define_expand "subsi3"
5800 [(set (match_operand:SI 0 "register_operand" "=r,d")
5801 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5802 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5806 if (arith_4096_operand(operands[2], SImode))
5808 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5809 gen_rtx_PLUS (SImode, operands[1],
5815 (define_insn "*subsi3"
5816 [(set (match_operand:SI 0 "register_operand" "=r,d")
5817 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5818 (match_operand:SI 2 "arith_operand" "rI,d")))]
5822 fpsub32s\\t%1, %2, %0"
5823 [(set_attr "type" "*,fp")])
5825 (define_insn "*cmp_minus_cc"
5826 [(set (reg:CC_NOOV 100)
5827 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5828 (match_operand:SI 1 "arith_operand" "rI"))
5831 "subcc\\t%r0, %1, %%g0"
5832 [(set_attr "type" "compare")])
5834 (define_insn "*cmp_minus_ccx"
5835 [(set (reg:CCX_NOOV 100)
5836 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5837 (match_operand:DI 1 "arith_double_operand" "rHI"))
5840 "subcc\\t%0, %1, %%g0"
5841 [(set_attr "type" "compare")])
5843 (define_insn "cmp_minus_cc_set"
5844 [(set (reg:CC_NOOV 100)
5845 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5846 (match_operand:SI 2 "arith_operand" "rI"))
5848 (set (match_operand:SI 0 "register_operand" "=r")
5849 (minus:SI (match_dup 1) (match_dup 2)))]
5851 "subcc\\t%r1, %2, %0"
5852 [(set_attr "type" "compare")])
5854 (define_insn "*cmp_minus_ccx_set"
5855 [(set (reg:CCX_NOOV 100)
5856 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5857 (match_operand:DI 2 "arith_double_operand" "rHI"))
5859 (set (match_operand:DI 0 "register_operand" "=r")
5860 (minus:DI (match_dup 1) (match_dup 2)))]
5862 "subcc\\t%1, %2, %0"
5863 [(set_attr "type" "compare")])
5865 ;; Integer Multiply/Divide.
5867 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5868 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5870 (define_insn "mulsi3"
5871 [(set (match_operand:SI 0 "register_operand" "=r")
5872 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5873 (match_operand:SI 2 "arith_operand" "rI")))]
5876 [(set_attr "type" "imul")])
5878 (define_expand "muldi3"
5879 [(set (match_operand:DI 0 "register_operand" "=r")
5880 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5881 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5882 "TARGET_ARCH64 || TARGET_V8PLUS"
5887 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5892 (define_insn "*muldi3_sp64"
5893 [(set (match_operand:DI 0 "register_operand" "=r")
5894 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5895 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5898 [(set_attr "type" "imul")])
5900 ;; V8plus wide multiply.
5902 (define_insn "muldi3_v8plus"
5903 [(set (match_operand:DI 0 "register_operand" "=r,h")
5904 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5905 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5906 (clobber (match_scratch:SI 3 "=&h,X"))
5907 (clobber (match_scratch:SI 4 "=&h,X"))]
5911 if (sparc_check_64 (operands[1], insn) <= 0)
5912 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5913 if (which_alternative == 1)
5914 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5915 if (GET_CODE (operands[2]) == CONST_INT)
5917 if (which_alternative == 1)
5918 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5920 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\";
5922 if (sparc_check_64 (operands[2], insn) <= 0)
5923 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5924 if (which_alternative == 1)
5925 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\";
5927 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\";
5929 [(set_attr "type" "multi")
5930 (set_attr "length" "9,8")])
5932 (define_insn "*cmp_mul_set"
5934 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5935 (match_operand:SI 2 "arith_operand" "rI"))
5937 (set (match_operand:SI 0 "register_operand" "=r")
5938 (mult:SI (match_dup 1) (match_dup 2)))]
5939 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5940 "smulcc\\t%1, %2, %0"
5941 [(set_attr "type" "imul")])
5943 (define_expand "mulsidi3"
5944 [(set (match_operand:DI 0 "register_operand" "")
5945 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5946 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5950 if (CONSTANT_P (operands[2]))
5953 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5956 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5962 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5967 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5968 ;; registers can hold 64 bit values in the V8plus environment.
5970 (define_insn "mulsidi3_v8plus"
5971 [(set (match_operand:DI 0 "register_operand" "=h,r")
5972 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5973 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5974 (clobber (match_scratch:SI 3 "=X,&h"))]
5977 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5978 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5979 [(set_attr "type" "multi")
5980 (set_attr "length" "2,3")])
5983 (define_insn "const_mulsidi3_v8plus"
5984 [(set (match_operand:DI 0 "register_operand" "=h,r")
5985 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5986 (match_operand:SI 2 "small_int" "I,I")))
5987 (clobber (match_scratch:SI 3 "=X,&h"))]
5990 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5991 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5992 [(set_attr "type" "multi")
5993 (set_attr "length" "2,3")])
5996 (define_insn "*mulsidi3_sp32"
5997 [(set (match_operand:DI 0 "register_operand" "=r")
5998 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5999 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6003 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6006 (if_then_else (eq_attr "isa" "sparclet")
6007 (const_string "imul") (const_string "multi")))
6008 (set (attr "length")
6009 (if_then_else (eq_attr "isa" "sparclet")
6010 (const_int 1) (const_int 2)))])
6012 (define_insn "*mulsidi3_sp64"
6013 [(set (match_operand:DI 0 "register_operand" "=r")
6014 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6015 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6016 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6018 [(set_attr "type" "imul")])
6020 ;; Extra pattern, because sign_extend of a constant isn't valid.
6023 (define_insn "const_mulsidi3_sp32"
6024 [(set (match_operand:DI 0 "register_operand" "=r")
6025 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6026 (match_operand:SI 2 "small_int" "I")))]
6030 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6033 (if_then_else (eq_attr "isa" "sparclet")
6034 (const_string "imul") (const_string "multi")))
6035 (set (attr "length")
6036 (if_then_else (eq_attr "isa" "sparclet")
6037 (const_int 1) (const_int 2)))])
6039 (define_insn "const_mulsidi3_sp64"
6040 [(set (match_operand:DI 0 "register_operand" "=r")
6041 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6042 (match_operand:SI 2 "small_int" "I")))]
6043 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6045 [(set_attr "type" "imul")])
6047 (define_expand "smulsi3_highpart"
6048 [(set (match_operand:SI 0 "register_operand" "")
6050 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6051 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6053 "TARGET_HARD_MUL && TARGET_ARCH32"
6056 if (CONSTANT_P (operands[2]))
6060 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6066 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6071 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6072 operands[2], GEN_INT (32)));
6078 (define_insn "smulsi3_highpart_v8plus"
6079 [(set (match_operand:SI 0 "register_operand" "=h,r")
6081 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6082 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6083 (match_operand:SI 3 "const_int_operand" "i,i"))))
6084 (clobber (match_scratch:SI 4 "=X,&h"))]
6087 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6088 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6089 [(set_attr "type" "multi")
6090 (set_attr "length" "2")])
6092 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6095 [(set (match_operand:SI 0 "register_operand" "=h,r")
6098 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6099 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6100 (match_operand:SI 3 "const_int_operand" "i,i"))
6102 (clobber (match_scratch:SI 4 "=X,&h"))]
6105 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6106 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6107 [(set_attr "type" "multi")
6108 (set_attr "length" "2")])
6111 (define_insn "const_smulsi3_highpart_v8plus"
6112 [(set (match_operand:SI 0 "register_operand" "=h,r")
6114 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6115 (match_operand 2 "small_int" "i,i"))
6116 (match_operand:SI 3 "const_int_operand" "i,i"))))
6117 (clobber (match_scratch:SI 4 "=X,&h"))]
6120 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6121 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6122 [(set_attr "type" "multi")
6123 (set_attr "length" "2")])
6126 (define_insn "*smulsi3_highpart_sp32"
6127 [(set (match_operand:SI 0 "register_operand" "=r")
6129 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6130 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6133 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6134 [(set_attr "type" "multi")
6135 (set_attr "length" "2")])
6138 (define_insn "const_smulsi3_highpart"
6139 [(set (match_operand:SI 0 "register_operand" "=r")
6141 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6142 (match_operand:SI 2 "register_operand" "r"))
6145 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6146 [(set_attr "type" "multi")
6147 (set_attr "length" "2")])
6149 (define_expand "umulsidi3"
6150 [(set (match_operand:DI 0 "register_operand" "")
6151 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6152 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6156 if (CONSTANT_P (operands[2]))
6159 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6162 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6168 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6174 (define_insn "umulsidi3_v8plus"
6175 [(set (match_operand:DI 0 "register_operand" "=h,r")
6176 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6177 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6178 (clobber (match_scratch:SI 3 "=X,&h"))]
6181 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6182 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6183 [(set_attr "type" "multi")
6184 (set_attr "length" "2,3")])
6187 (define_insn "*umulsidi3_sp32"
6188 [(set (match_operand:DI 0 "register_operand" "=r")
6189 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6190 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6194 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6197 (if_then_else (eq_attr "isa" "sparclet")
6198 (const_string "imul") (const_string "multi")))
6199 (set (attr "length")
6200 (if_then_else (eq_attr "isa" "sparclet")
6201 (const_int 1) (const_int 2)))])
6203 (define_insn "*umulsidi3_sp64"
6204 [(set (match_operand:DI 0 "register_operand" "=r")
6205 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6206 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6207 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6209 [(set_attr "type" "imul")])
6211 ;; Extra pattern, because sign_extend of a constant isn't valid.
6214 (define_insn "const_umulsidi3_sp32"
6215 [(set (match_operand:DI 0 "register_operand" "=r")
6216 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6217 (match_operand:SI 2 "uns_small_int" "")))]
6221 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6224 (if_then_else (eq_attr "isa" "sparclet")
6225 (const_string "imul") (const_string "multi")))
6226 (set (attr "length")
6227 (if_then_else (eq_attr "isa" "sparclet")
6228 (const_int 1) (const_int 2)))])
6230 (define_insn "const_umulsidi3_sp64"
6231 [(set (match_operand:DI 0 "register_operand" "=r")
6232 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6233 (match_operand:SI 2 "uns_small_int" "")))]
6234 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6236 [(set_attr "type" "imul")])
6239 (define_insn "const_umulsidi3_v8plus"
6240 [(set (match_operand:DI 0 "register_operand" "=h,r")
6241 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6242 (match_operand:SI 2 "uns_small_int" "")))
6243 (clobber (match_scratch:SI 3 "=X,h"))]
6246 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6247 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6248 [(set_attr "type" "multi")
6249 (set_attr "length" "2,3")])
6251 (define_expand "umulsi3_highpart"
6252 [(set (match_operand:SI 0 "register_operand" "")
6254 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6255 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6257 "TARGET_HARD_MUL && TARGET_ARCH32"
6260 if (CONSTANT_P (operands[2]))
6264 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6270 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6275 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6276 operands[2], GEN_INT (32)));
6282 (define_insn "umulsi3_highpart_v8plus"
6283 [(set (match_operand:SI 0 "register_operand" "=h,r")
6285 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6286 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6287 (match_operand:SI 3 "const_int_operand" "i,i"))))
6288 (clobber (match_scratch:SI 4 "=X,h"))]
6291 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6292 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6293 [(set_attr "type" "multi")
6294 (set_attr "length" "2")])
6297 (define_insn "const_umulsi3_highpart_v8plus"
6298 [(set (match_operand:SI 0 "register_operand" "=h,r")
6300 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6301 (match_operand:SI 2 "uns_small_int" ""))
6302 (match_operand:SI 3 "const_int_operand" "i,i"))))
6303 (clobber (match_scratch:SI 4 "=X,h"))]
6306 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6307 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6308 [(set_attr "type" "multi")
6309 (set_attr "length" "2")])
6312 (define_insn "*umulsi3_highpart_sp32"
6313 [(set (match_operand:SI 0 "register_operand" "=r")
6315 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6316 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6319 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6320 [(set_attr "type" "multi")
6321 (set_attr "length" "2")])
6324 (define_insn "const_umulsi3_highpart"
6325 [(set (match_operand:SI 0 "register_operand" "=r")
6327 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6328 (match_operand:SI 2 "uns_small_int" ""))
6331 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6332 [(set_attr "type" "multi")
6333 (set_attr "length" "2")])
6335 ;; The v8 architecture specifies that there must be 3 instructions between
6336 ;; a y register write and a use of it for correct results.
6338 (define_expand "divsi3"
6339 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6340 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6341 (match_operand:SI 2 "input_operand" "rI,m")))
6342 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6343 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6348 operands[3] = gen_reg_rtx(SImode);
6349 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6350 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6356 (define_insn "divsi3_sp32"
6357 [(set (match_operand:SI 0 "register_operand" "=r,r")
6358 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6359 (match_operand:SI 2 "input_operand" "rI,m")))
6360 (clobber (match_scratch:SI 3 "=&r,&r"))]
6361 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6365 if (which_alternative == 0)
6367 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6369 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6372 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6374 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\";
6376 [(set_attr "type" "multi")
6377 (set (attr "length")
6378 (if_then_else (eq_attr "isa" "v9")
6379 (const_int 4) (const_int 7)))])
6381 (define_insn "divsi3_sp64"
6382 [(set (match_operand:SI 0 "register_operand" "=r")
6383 (div:SI (match_operand:SI 1 "register_operand" "r")
6384 (match_operand:SI 2 "input_operand" "rI")))
6385 (use (match_operand:SI 3 "register_operand" "r"))]
6386 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6387 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6388 [(set_attr "type" "multi")
6389 (set_attr "length" "2")])
6391 (define_insn "divdi3"
6392 [(set (match_operand:DI 0 "register_operand" "=r")
6393 (div:DI (match_operand:DI 1 "register_operand" "r")
6394 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6396 "sdivx\\t%1, %2, %0"
6397 [(set_attr "type" "idiv")])
6399 (define_insn "*cmp_sdiv_cc_set"
6401 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6402 (match_operand:SI 2 "arith_operand" "rI"))
6404 (set (match_operand:SI 0 "register_operand" "=r")
6405 (div:SI (match_dup 1) (match_dup 2)))
6406 (clobber (match_scratch:SI 3 "=&r"))]
6407 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6411 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6413 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6415 [(set_attr "type" "multi")
6416 (set (attr "length")
6417 (if_then_else (eq_attr "isa" "v9")
6418 (const_int 3) (const_int 6)))])
6421 (define_expand "udivsi3"
6422 [(set (match_operand:SI 0 "register_operand" "")
6423 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6424 (match_operand:SI 2 "input_operand" "")))]
6425 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6428 (define_insn "udivsi3_sp32"
6429 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6430 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6431 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6433 || TARGET_DEPRECATED_V8_INSNS)
6437 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6438 switch (which_alternative)
6441 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6443 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6445 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6448 [(set_attr "type" "multi")
6449 (set_attr "length" "5")])
6451 (define_insn "udivsi3_sp64"
6452 [(set (match_operand:SI 0 "register_operand" "=r")
6453 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6454 (match_operand:SI 2 "input_operand" "rI")))]
6455 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6456 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6457 [(set_attr "type" "multi")
6458 (set_attr "length" "2")])
6460 (define_insn "udivdi3"
6461 [(set (match_operand:DI 0 "register_operand" "=r")
6462 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6463 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6465 "udivx\\t%1, %2, %0"
6466 [(set_attr "type" "idiv")])
6468 (define_insn "*cmp_udiv_cc_set"
6470 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6471 (match_operand:SI 2 "arith_operand" "rI"))
6473 (set (match_operand:SI 0 "register_operand" "=r")
6474 (udiv:SI (match_dup 1) (match_dup 2)))]
6476 || TARGET_DEPRECATED_V8_INSNS"
6480 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6482 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6484 [(set_attr "type" "multi")
6485 (set (attr "length")
6486 (if_then_else (eq_attr "isa" "v9")
6487 (const_int 2) (const_int 5)))])
6489 ; sparclet multiply/accumulate insns
6491 (define_insn "*smacsi"
6492 [(set (match_operand:SI 0 "register_operand" "=r")
6493 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6494 (match_operand:SI 2 "arith_operand" "rI"))
6495 (match_operand:SI 3 "register_operand" "0")))]
6498 [(set_attr "type" "imul")])
6500 (define_insn "*smacdi"
6501 [(set (match_operand:DI 0 "register_operand" "=r")
6502 (plus:DI (mult:DI (sign_extend:DI
6503 (match_operand:SI 1 "register_operand" "%r"))
6505 (match_operand:SI 2 "register_operand" "r")))
6506 (match_operand:DI 3 "register_operand" "0")))]
6508 "smacd\\t%1, %2, %L0"
6509 [(set_attr "type" "imul")])
6511 (define_insn "*umacdi"
6512 [(set (match_operand:DI 0 "register_operand" "=r")
6513 (plus:DI (mult:DI (zero_extend:DI
6514 (match_operand:SI 1 "register_operand" "%r"))
6516 (match_operand:SI 2 "register_operand" "r")))
6517 (match_operand:DI 3 "register_operand" "0")))]
6519 "umacd\\t%1, %2, %L0"
6520 [(set_attr "type" "imul")])
6522 ;;- Boolean instructions
6523 ;; We define DImode `and' so with DImode `not' we can get
6524 ;; DImode `andn'. Other combinations are possible.
6526 (define_expand "anddi3"
6527 [(set (match_operand:DI 0 "register_operand" "")
6528 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6529 (match_operand:DI 2 "arith_double_operand" "")))]
6533 (define_insn "*anddi3_sp32"
6534 [(set (match_operand:DI 0 "register_operand" "=r,b")
6535 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6536 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6541 [(set_attr "type" "*,fp")
6542 (set_attr "length" "2,*")
6543 (set_attr "fptype" "double")])
6545 (define_insn "*anddi3_sp64"
6546 [(set (match_operand:DI 0 "register_operand" "=r,b")
6547 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6548 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6553 [(set_attr "type" "*,fp")
6554 (set_attr "fptype" "double")])
6556 (define_insn "andsi3"
6557 [(set (match_operand:SI 0 "register_operand" "=r,d")
6558 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6559 (match_operand:SI 2 "arith_operand" "rI,d")))]
6564 [(set_attr "type" "*,fp")])
6567 [(set (match_operand:SI 0 "register_operand" "")
6568 (and:SI (match_operand:SI 1 "register_operand" "")
6569 (match_operand:SI 2 "" "")))
6570 (clobber (match_operand:SI 3 "register_operand" ""))]
6571 "GET_CODE (operands[2]) == CONST_INT
6572 && !SMALL_INT32 (operands[2])
6573 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6574 [(set (match_dup 3) (match_dup 4))
6575 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6578 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6581 ;; Split DImode logical operations requiring two instructions.
6583 [(set (match_operand:DI 0 "register_operand" "")
6584 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6585 [(match_operand:DI 2 "register_operand" "")
6586 (match_operand:DI 3 "arith_double_operand" "")]))]
6589 && ((GET_CODE (operands[0]) == REG
6590 && REGNO (operands[0]) < 32)
6591 || (GET_CODE (operands[0]) == SUBREG
6592 && GET_CODE (SUBREG_REG (operands[0])) == REG
6593 && REGNO (SUBREG_REG (operands[0])) < 32))"
6594 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6595 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6598 operands[4] = gen_highpart (SImode, operands[0]);
6599 operands[5] = gen_lowpart (SImode, operands[0]);
6600 operands[6] = gen_highpart (SImode, operands[2]);
6601 operands[7] = gen_lowpart (SImode, operands[2]);
6602 #if HOST_BITS_PER_WIDE_INT == 32
6603 if (GET_CODE (operands[3]) == CONST_INT)
6605 if (INTVAL (operands[3]) < 0)
6606 operands[8] = constm1_rtx;
6608 operands[8] = const0_rtx;
6612 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6613 operands[9] = gen_lowpart (SImode, operands[3]);
6616 (define_insn "*and_not_di_sp32"
6617 [(set (match_operand:DI 0 "register_operand" "=r,b")
6618 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6619 (match_operand:DI 2 "register_operand" "r,b")))]
6623 fandnot1\\t%1, %2, %0"
6624 [(set_attr "type" "*,fp")
6625 (set_attr "length" "2,*")
6626 (set_attr "fptype" "double")])
6629 [(set (match_operand:DI 0 "register_operand" "")
6630 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6631 (match_operand:DI 2 "register_operand" "")))]
6634 && ((GET_CODE (operands[0]) == REG
6635 && REGNO (operands[0]) < 32)
6636 || (GET_CODE (operands[0]) == SUBREG
6637 && GET_CODE (SUBREG_REG (operands[0])) == REG
6638 && REGNO (SUBREG_REG (operands[0])) < 32))"
6639 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6640 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6641 "operands[3] = gen_highpart (SImode, operands[0]);
6642 operands[4] = gen_highpart (SImode, operands[1]);
6643 operands[5] = gen_highpart (SImode, operands[2]);
6644 operands[6] = gen_lowpart (SImode, operands[0]);
6645 operands[7] = gen_lowpart (SImode, operands[1]);
6646 operands[8] = gen_lowpart (SImode, operands[2]);")
6648 (define_insn "*and_not_di_sp64"
6649 [(set (match_operand:DI 0 "register_operand" "=r,b")
6650 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6651 (match_operand:DI 2 "register_operand" "r,b")))]
6655 fandnot1\\t%1, %2, %0"
6656 [(set_attr "type" "*,fp")
6657 (set_attr "fptype" "double")])
6659 (define_insn "*and_not_si"
6660 [(set (match_operand:SI 0 "register_operand" "=r,d")
6661 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6662 (match_operand:SI 2 "register_operand" "r,d")))]
6666 fandnot1s\\t%1, %2, %0"
6667 [(set_attr "type" "*,fp")])
6669 (define_expand "iordi3"
6670 [(set (match_operand:DI 0 "register_operand" "")
6671 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6672 (match_operand:DI 2 "arith_double_operand" "")))]
6676 (define_insn "*iordi3_sp32"
6677 [(set (match_operand:DI 0 "register_operand" "=r,b")
6678 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6679 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6684 [(set_attr "type" "*,fp")
6685 (set_attr "length" "2,*")
6686 (set_attr "fptype" "double")])
6688 (define_insn "*iordi3_sp64"
6689 [(set (match_operand:DI 0 "register_operand" "=r,b")
6690 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6691 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6696 [(set_attr "type" "*,fp")
6697 (set_attr "fptype" "double")])
6699 (define_insn "iorsi3"
6700 [(set (match_operand:SI 0 "register_operand" "=r,d")
6701 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6702 (match_operand:SI 2 "arith_operand" "rI,d")))]
6707 [(set_attr "type" "*,fp")])
6710 [(set (match_operand:SI 0 "register_operand" "")
6711 (ior:SI (match_operand:SI 1 "register_operand" "")
6712 (match_operand:SI 2 "" "")))
6713 (clobber (match_operand:SI 3 "register_operand" ""))]
6714 "GET_CODE (operands[2]) == CONST_INT
6715 && !SMALL_INT32 (operands[2])
6716 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6717 [(set (match_dup 3) (match_dup 4))
6718 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6721 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6724 (define_insn "*or_not_di_sp32"
6725 [(set (match_operand:DI 0 "register_operand" "=r,b")
6726 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6727 (match_operand:DI 2 "register_operand" "r,b")))]
6731 fornot1\\t%1, %2, %0"
6732 [(set_attr "type" "*,fp")
6733 (set_attr "length" "2,*")
6734 (set_attr "fptype" "double")])
6737 [(set (match_operand:DI 0 "register_operand" "")
6738 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6739 (match_operand:DI 2 "register_operand" "")))]
6742 && ((GET_CODE (operands[0]) == REG
6743 && REGNO (operands[0]) < 32)
6744 || (GET_CODE (operands[0]) == SUBREG
6745 && GET_CODE (SUBREG_REG (operands[0])) == REG
6746 && REGNO (SUBREG_REG (operands[0])) < 32))"
6747 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6748 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6749 "operands[3] = gen_highpart (SImode, operands[0]);
6750 operands[4] = gen_highpart (SImode, operands[1]);
6751 operands[5] = gen_highpart (SImode, operands[2]);
6752 operands[6] = gen_lowpart (SImode, operands[0]);
6753 operands[7] = gen_lowpart (SImode, operands[1]);
6754 operands[8] = gen_lowpart (SImode, operands[2]);")
6756 (define_insn "*or_not_di_sp64"
6757 [(set (match_operand:DI 0 "register_operand" "=r,b")
6758 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6759 (match_operand:DI 2 "register_operand" "r,b")))]
6763 fornot1\\t%1, %2, %0"
6764 [(set_attr "type" "*,fp")
6765 (set_attr "fptype" "double")])
6767 (define_insn "*or_not_si"
6768 [(set (match_operand:SI 0 "register_operand" "=r,d")
6769 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6770 (match_operand:SI 2 "register_operand" "r,d")))]
6774 fornot1s\\t%1, %2, %0"
6775 [(set_attr "type" "*,fp")])
6777 (define_expand "xordi3"
6778 [(set (match_operand:DI 0 "register_operand" "")
6779 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6780 (match_operand:DI 2 "arith_double_operand" "")))]
6784 (define_insn "*xordi3_sp32"
6785 [(set (match_operand:DI 0 "register_operand" "=r,b")
6786 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6787 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6792 [(set_attr "type" "*,fp")
6793 (set_attr "length" "2,*")
6794 (set_attr "fptype" "double")])
6796 (define_insn "*xordi3_sp64"
6797 [(set (match_operand:DI 0 "register_operand" "=r,b")
6798 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6799 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6804 [(set_attr "type" "*,fp")
6805 (set_attr "fptype" "double")])
6807 (define_insn "*xordi3_sp64_dbl"
6808 [(set (match_operand:DI 0 "register_operand" "=r")
6809 (xor:DI (match_operand:DI 1 "register_operand" "r")
6810 (match_operand:DI 2 "const64_operand" "")))]
6812 && HOST_BITS_PER_WIDE_INT != 64)"
6815 (define_insn "xorsi3"
6816 [(set (match_operand:SI 0 "register_operand" "=r,d")
6817 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6818 (match_operand:SI 2 "arith_operand" "rI,d")))]
6823 [(set_attr "type" "*,fp")])
6826 [(set (match_operand:SI 0 "register_operand" "")
6827 (xor:SI (match_operand:SI 1 "register_operand" "")
6828 (match_operand:SI 2 "" "")))
6829 (clobber (match_operand:SI 3 "register_operand" ""))]
6830 "GET_CODE (operands[2]) == CONST_INT
6831 && !SMALL_INT32 (operands[2])
6832 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6833 [(set (match_dup 3) (match_dup 4))
6834 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6837 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6841 [(set (match_operand:SI 0 "register_operand" "")
6842 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6843 (match_operand:SI 2 "" ""))))
6844 (clobber (match_operand:SI 3 "register_operand" ""))]
6845 "GET_CODE (operands[2]) == CONST_INT
6846 && !SMALL_INT32 (operands[2])
6847 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6848 [(set (match_dup 3) (match_dup 4))
6849 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6852 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6855 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6856 ;; Combine now canonicalizes to the rightmost expression.
6857 (define_insn "*xor_not_di_sp32"
6858 [(set (match_operand:DI 0 "register_operand" "=r,b")
6859 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6860 (match_operand:DI 2 "register_operand" "r,b"))))]
6865 [(set_attr "type" "*,fp")
6866 (set_attr "length" "2,*")
6867 (set_attr "fptype" "double")])
6870 [(set (match_operand:DI 0 "register_operand" "")
6871 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6872 (match_operand:DI 2 "register_operand" ""))))]
6875 && ((GET_CODE (operands[0]) == REG
6876 && REGNO (operands[0]) < 32)
6877 || (GET_CODE (operands[0]) == SUBREG
6878 && GET_CODE (SUBREG_REG (operands[0])) == REG
6879 && REGNO (SUBREG_REG (operands[0])) < 32))"
6880 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6881 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6882 "operands[3] = gen_highpart (SImode, operands[0]);
6883 operands[4] = gen_highpart (SImode, operands[1]);
6884 operands[5] = gen_highpart (SImode, operands[2]);
6885 operands[6] = gen_lowpart (SImode, operands[0]);
6886 operands[7] = gen_lowpart (SImode, operands[1]);
6887 operands[8] = gen_lowpart (SImode, operands[2]);")
6889 (define_insn "*xor_not_di_sp64"
6890 [(set (match_operand:DI 0 "register_operand" "=r,b")
6891 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6892 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6897 [(set_attr "type" "*,fp")
6898 (set_attr "fptype" "double")])
6900 (define_insn "*xor_not_si"
6901 [(set (match_operand:SI 0 "register_operand" "=r,d")
6902 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6903 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6907 fxnors\\t%1, %2, %0"
6908 [(set_attr "type" "*,fp")])
6910 ;; These correspond to the above in the case where we also (or only)
6911 ;; want to set the condition code.
6913 (define_insn "*cmp_cc_arith_op"
6916 (match_operator:SI 2 "cc_arithop"
6917 [(match_operand:SI 0 "arith_operand" "%r")
6918 (match_operand:SI 1 "arith_operand" "rI")])
6921 "%A2cc\\t%0, %1, %%g0"
6922 [(set_attr "type" "compare")])
6924 (define_insn "*cmp_ccx_arith_op"
6927 (match_operator:DI 2 "cc_arithop"
6928 [(match_operand:DI 0 "arith_double_operand" "%r")
6929 (match_operand:DI 1 "arith_double_operand" "rHI")])
6932 "%A2cc\\t%0, %1, %%g0"
6933 [(set_attr "type" "compare")])
6935 (define_insn "*cmp_cc_arith_op_set"
6938 (match_operator:SI 3 "cc_arithop"
6939 [(match_operand:SI 1 "arith_operand" "%r")
6940 (match_operand:SI 2 "arith_operand" "rI")])
6942 (set (match_operand:SI 0 "register_operand" "=r")
6943 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6944 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6945 "%A3cc\\t%1, %2, %0"
6946 [(set_attr "type" "compare")])
6948 (define_insn "*cmp_ccx_arith_op_set"
6951 (match_operator:DI 3 "cc_arithop"
6952 [(match_operand:DI 1 "arith_double_operand" "%r")
6953 (match_operand:DI 2 "arith_double_operand" "rHI")])
6955 (set (match_operand:DI 0 "register_operand" "=r")
6956 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6957 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6958 "%A3cc\\t%1, %2, %0"
6959 [(set_attr "type" "compare")])
6961 (define_insn "*cmp_cc_xor_not"
6964 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6965 (match_operand:SI 1 "arith_operand" "rI")))
6968 "xnorcc\\t%r0, %1, %%g0"
6969 [(set_attr "type" "compare")])
6971 (define_insn "*cmp_ccx_xor_not"
6974 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6975 (match_operand:DI 1 "arith_double_operand" "rHI")))
6978 "xnorcc\\t%r0, %1, %%g0"
6979 [(set_attr "type" "compare")])
6981 (define_insn "*cmp_cc_xor_not_set"
6984 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6985 (match_operand:SI 2 "arith_operand" "rI")))
6987 (set (match_operand:SI 0 "register_operand" "=r")
6988 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6990 "xnorcc\\t%r1, %2, %0"
6991 [(set_attr "type" "compare")])
6993 (define_insn "*cmp_ccx_xor_not_set"
6996 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6997 (match_operand:DI 2 "arith_double_operand" "rHI")))
6999 (set (match_operand:DI 0 "register_operand" "=r")
7000 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7002 "xnorcc\\t%r1, %2, %0"
7003 [(set_attr "type" "compare")])
7005 (define_insn "*cmp_cc_arith_op_not"
7008 (match_operator:SI 2 "cc_arithopn"
7009 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7010 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7013 "%B2cc\\t%r1, %0, %%g0"
7014 [(set_attr "type" "compare")])
7016 (define_insn "*cmp_ccx_arith_op_not"
7019 (match_operator:DI 2 "cc_arithopn"
7020 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7021 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7024 "%B2cc\\t%r1, %0, %%g0"
7025 [(set_attr "type" "compare")])
7027 (define_insn "*cmp_cc_arith_op_not_set"
7030 (match_operator:SI 3 "cc_arithopn"
7031 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7032 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7034 (set (match_operand:SI 0 "register_operand" "=r")
7035 (match_operator:SI 4 "cc_arithopn"
7036 [(not:SI (match_dup 1)) (match_dup 2)]))]
7037 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7038 "%B3cc\\t%r2, %1, %0"
7039 [(set_attr "type" "compare")])
7041 (define_insn "*cmp_ccx_arith_op_not_set"
7044 (match_operator:DI 3 "cc_arithopn"
7045 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7046 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7048 (set (match_operand:DI 0 "register_operand" "=r")
7049 (match_operator:DI 4 "cc_arithopn"
7050 [(not:DI (match_dup 1)) (match_dup 2)]))]
7051 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7052 "%B3cc\\t%r2, %1, %0"
7053 [(set_attr "type" "compare")])
7055 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7056 ;; does not know how to make it work for constants.
7058 (define_expand "negdi2"
7059 [(set (match_operand:DI 0 "register_operand" "=r")
7060 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7064 if (! TARGET_ARCH64)
7066 emit_insn (gen_rtx_PARALLEL
7069 gen_rtx_SET (VOIDmode, operand0,
7070 gen_rtx_NEG (DImode, operand1)),
7071 gen_rtx_CLOBBER (VOIDmode,
7072 gen_rtx_REG (CCmode,
7078 (define_insn "*negdi2_sp32"
7079 [(set (match_operand:DI 0 "register_operand" "=r")
7080 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7081 (clobber (reg:CC 100))]
7084 [(set_attr "length" "2")])
7087 [(set (match_operand:DI 0 "register_operand" "")
7088 (neg:DI (match_operand:DI 1 "register_operand" "")))
7089 (clobber (reg:CC 100))]
7091 && reload_completed"
7092 [(parallel [(set (reg:CC_NOOV 100)
7093 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7095 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7096 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7097 (ltu:SI (reg:CC 100) (const_int 0))))]
7098 "operands[2] = gen_highpart (SImode, operands[0]);
7099 operands[3] = gen_highpart (SImode, operands[1]);
7100 operands[4] = gen_lowpart (SImode, operands[0]);
7101 operands[5] = gen_lowpart (SImode, operands[1]);")
7103 (define_insn "*negdi2_sp64"
7104 [(set (match_operand:DI 0 "register_operand" "=r")
7105 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7107 "sub\\t%%g0, %1, %0")
7109 (define_insn "negsi2"
7110 [(set (match_operand:SI 0 "register_operand" "=r")
7111 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7113 "sub\\t%%g0, %1, %0")
7115 (define_insn "*cmp_cc_neg"
7116 [(set (reg:CC_NOOV 100)
7117 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7120 "subcc\\t%%g0, %0, %%g0"
7121 [(set_attr "type" "compare")])
7123 (define_insn "*cmp_ccx_neg"
7124 [(set (reg:CCX_NOOV 100)
7125 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7128 "subcc\\t%%g0, %0, %%g0"
7129 [(set_attr "type" "compare")])
7131 (define_insn "*cmp_cc_set_neg"
7132 [(set (reg:CC_NOOV 100)
7133 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7135 (set (match_operand:SI 0 "register_operand" "=r")
7136 (neg:SI (match_dup 1)))]
7138 "subcc\\t%%g0, %1, %0"
7139 [(set_attr "type" "compare")])
7141 (define_insn "*cmp_ccx_set_neg"
7142 [(set (reg:CCX_NOOV 100)
7143 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7145 (set (match_operand:DI 0 "register_operand" "=r")
7146 (neg:DI (match_dup 1)))]
7148 "subcc\\t%%g0, %1, %0"
7149 [(set_attr "type" "compare")])
7151 ;; We cannot use the "not" pseudo insn because the Sun assembler
7152 ;; does not know how to make it work for constants.
7153 (define_expand "one_cmpldi2"
7154 [(set (match_operand:DI 0 "register_operand" "")
7155 (not:DI (match_operand:DI 1 "register_operand" "")))]
7159 (define_insn "*one_cmpldi2_sp32"
7160 [(set (match_operand:DI 0 "register_operand" "=r,b")
7161 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7166 [(set_attr "type" "*,fp")
7167 (set_attr "length" "2,*")
7168 (set_attr "fptype" "double")])
7171 [(set (match_operand:DI 0 "register_operand" "")
7172 (not:DI (match_operand:DI 1 "register_operand" "")))]
7175 && ((GET_CODE (operands[0]) == REG
7176 && REGNO (operands[0]) < 32)
7177 || (GET_CODE (operands[0]) == SUBREG
7178 && GET_CODE (SUBREG_REG (operands[0])) == REG
7179 && REGNO (SUBREG_REG (operands[0])) < 32))"
7180 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7181 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7182 "operands[2] = gen_highpart (SImode, operands[0]);
7183 operands[3] = gen_highpart (SImode, operands[1]);
7184 operands[4] = gen_lowpart (SImode, operands[0]);
7185 operands[5] = gen_lowpart (SImode, operands[1]);")
7187 (define_insn "*one_cmpldi2_sp64"
7188 [(set (match_operand:DI 0 "register_operand" "=r,b")
7189 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7194 [(set_attr "type" "*,fp")
7195 (set_attr "fptype" "double")])
7197 (define_insn "one_cmplsi2"
7198 [(set (match_operand:SI 0 "register_operand" "=r,d")
7199 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7204 [(set_attr "type" "*,fp")])
7206 (define_insn "*cmp_cc_not"
7208 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7211 "xnorcc\\t%%g0, %0, %%g0"
7212 [(set_attr "type" "compare")])
7214 (define_insn "*cmp_ccx_not"
7216 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7219 "xnorcc\\t%%g0, %0, %%g0"
7220 [(set_attr "type" "compare")])
7222 (define_insn "*cmp_cc_set_not"
7224 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7226 (set (match_operand:SI 0 "register_operand" "=r")
7227 (not:SI (match_dup 1)))]
7229 "xnorcc\\t%%g0, %1, %0"
7230 [(set_attr "type" "compare")])
7232 (define_insn "*cmp_ccx_set_not"
7234 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7236 (set (match_operand:DI 0 "register_operand" "=r")
7237 (not:DI (match_dup 1)))]
7239 "xnorcc\\t%%g0, %1, %0"
7240 [(set_attr "type" "compare")])
7242 (define_insn "*cmp_cc_set"
7243 [(set (match_operand:SI 0 "register_operand" "=r")
7244 (match_operand:SI 1 "register_operand" "r"))
7246 (compare:CC (match_dup 1)
7250 [(set_attr "type" "compare")])
7252 (define_insn "*cmp_ccx_set64"
7253 [(set (match_operand:DI 0 "register_operand" "=r")
7254 (match_operand:DI 1 "register_operand" "r"))
7256 (compare:CCX (match_dup 1)
7260 [(set_attr "type" "compare")])
7262 ;; Floating point arithmetic instructions.
7264 (define_expand "addtf3"
7265 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7266 (plus:TF (match_operand:TF 1 "general_operand" "")
7267 (match_operand:TF 2 "general_operand" "")))]
7268 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7271 if (! TARGET_HARD_QUAD)
7273 rtx slot0, slot1, slot2;
7275 if (GET_CODE (operands[0]) != MEM)
7276 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7278 slot0 = operands[0];
7279 if (GET_CODE (operands[1]) != MEM)
7281 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7282 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7285 slot1 = operands[1];
7286 if (GET_CODE (operands[2]) != MEM)
7288 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7289 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7292 slot2 = operands[2];
7294 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7296 XEXP (slot0, 0), Pmode,
7297 XEXP (slot1, 0), Pmode,
7298 XEXP (slot2, 0), Pmode);
7300 if (GET_CODE (operands[0]) != MEM)
7301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7306 (define_insn "*addtf3_hq"
7307 [(set (match_operand:TF 0 "register_operand" "=e")
7308 (plus:TF (match_operand:TF 1 "register_operand" "e")
7309 (match_operand:TF 2 "register_operand" "e")))]
7310 "TARGET_FPU && TARGET_HARD_QUAD"
7311 "faddq\\t%1, %2, %0"
7312 [(set_attr "type" "fp")])
7314 (define_insn "adddf3"
7315 [(set (match_operand:DF 0 "register_operand" "=e")
7316 (plus:DF (match_operand:DF 1 "register_operand" "e")
7317 (match_operand:DF 2 "register_operand" "e")))]
7319 "faddd\\t%1, %2, %0"
7320 [(set_attr "type" "fp")
7321 (set_attr "fptype" "double")])
7323 (define_insn "addsf3"
7324 [(set (match_operand:SF 0 "register_operand" "=f")
7325 (plus:SF (match_operand:SF 1 "register_operand" "f")
7326 (match_operand:SF 2 "register_operand" "f")))]
7328 "fadds\\t%1, %2, %0"
7329 [(set_attr "type" "fp")])
7331 (define_expand "subtf3"
7332 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7333 (minus:TF (match_operand:TF 1 "general_operand" "")
7334 (match_operand:TF 2 "general_operand" "")))]
7335 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7338 if (! TARGET_HARD_QUAD)
7340 rtx slot0, slot1, slot2;
7342 if (GET_CODE (operands[0]) != MEM)
7343 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7345 slot0 = operands[0];
7346 if (GET_CODE (operands[1]) != MEM)
7348 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7349 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7352 slot1 = operands[1];
7353 if (GET_CODE (operands[2]) != MEM)
7355 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7356 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7359 slot2 = operands[2];
7361 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7363 XEXP (slot0, 0), Pmode,
7364 XEXP (slot1, 0), Pmode,
7365 XEXP (slot2, 0), Pmode);
7367 if (GET_CODE (operands[0]) != MEM)
7368 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7373 (define_insn "*subtf3_hq"
7374 [(set (match_operand:TF 0 "register_operand" "=e")
7375 (minus:TF (match_operand:TF 1 "register_operand" "e")
7376 (match_operand:TF 2 "register_operand" "e")))]
7377 "TARGET_FPU && TARGET_HARD_QUAD"
7378 "fsubq\\t%1, %2, %0"
7379 [(set_attr "type" "fp")])
7381 (define_insn "subdf3"
7382 [(set (match_operand:DF 0 "register_operand" "=e")
7383 (minus:DF (match_operand:DF 1 "register_operand" "e")
7384 (match_operand:DF 2 "register_operand" "e")))]
7386 "fsubd\\t%1, %2, %0"
7387 [(set_attr "type" "fp")
7388 (set_attr "fptype" "double")])
7390 (define_insn "subsf3"
7391 [(set (match_operand:SF 0 "register_operand" "=f")
7392 (minus:SF (match_operand:SF 1 "register_operand" "f")
7393 (match_operand:SF 2 "register_operand" "f")))]
7395 "fsubs\\t%1, %2, %0"
7396 [(set_attr "type" "fp")])
7398 (define_expand "multf3"
7399 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7400 (mult:TF (match_operand:TF 1 "general_operand" "")
7401 (match_operand:TF 2 "general_operand" "")))]
7402 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7405 if (! TARGET_HARD_QUAD)
7407 rtx slot0, slot1, slot2;
7409 if (GET_CODE (operands[0]) != MEM)
7410 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7412 slot0 = operands[0];
7413 if (GET_CODE (operands[1]) != MEM)
7415 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7416 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7419 slot1 = operands[1];
7420 if (GET_CODE (operands[2]) != MEM)
7422 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7423 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7426 slot2 = operands[2];
7428 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7430 XEXP (slot0, 0), Pmode,
7431 XEXP (slot1, 0), Pmode,
7432 XEXP (slot2, 0), Pmode);
7434 if (GET_CODE (operands[0]) != MEM)
7435 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7440 (define_insn "*multf3_hq"
7441 [(set (match_operand:TF 0 "register_operand" "=e")
7442 (mult:TF (match_operand:TF 1 "register_operand" "e")
7443 (match_operand:TF 2 "register_operand" "e")))]
7444 "TARGET_FPU && TARGET_HARD_QUAD"
7445 "fmulq\\t%1, %2, %0"
7446 [(set_attr "type" "fpmul")])
7448 (define_insn "muldf3"
7449 [(set (match_operand:DF 0 "register_operand" "=e")
7450 (mult:DF (match_operand:DF 1 "register_operand" "e")
7451 (match_operand:DF 2 "register_operand" "e")))]
7453 "fmuld\\t%1, %2, %0"
7454 [(set_attr "type" "fpmul")
7455 (set_attr "fptype" "double")])
7457 (define_insn "mulsf3"
7458 [(set (match_operand:SF 0 "register_operand" "=f")
7459 (mult:SF (match_operand:SF 1 "register_operand" "f")
7460 (match_operand:SF 2 "register_operand" "f")))]
7462 "fmuls\\t%1, %2, %0"
7463 [(set_attr "type" "fpmul")])
7465 (define_insn "*muldf3_extend"
7466 [(set (match_operand:DF 0 "register_operand" "=e")
7467 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7468 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7469 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7470 "fsmuld\\t%1, %2, %0"
7471 [(set_attr "type" "fpmul")
7472 (set_attr "fptype" "double")])
7474 (define_insn "*multf3_extend"
7475 [(set (match_operand:TF 0 "register_operand" "=e")
7476 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7477 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7478 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7479 "fdmulq\\t%1, %2, %0"
7480 [(set_attr "type" "fpmul")])
7482 (define_expand "divtf3"
7483 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7484 (div:TF (match_operand:TF 1 "general_operand" "")
7485 (match_operand:TF 2 "general_operand" "")))]
7486 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7489 if (! TARGET_HARD_QUAD)
7491 rtx slot0, slot1, slot2;
7493 if (GET_CODE (operands[0]) != MEM)
7494 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7496 slot0 = operands[0];
7497 if (GET_CODE (operands[1]) != MEM)
7499 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7500 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7503 slot1 = operands[1];
7504 if (GET_CODE (operands[2]) != MEM)
7506 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7507 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7510 slot2 = operands[2];
7512 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7514 XEXP (slot0, 0), Pmode,
7515 XEXP (slot1, 0), Pmode,
7516 XEXP (slot2, 0), Pmode);
7518 if (GET_CODE (operands[0]) != MEM)
7519 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7524 ;; don't have timing for quad-prec. divide.
7525 (define_insn "*divtf3_hq"
7526 [(set (match_operand:TF 0 "register_operand" "=e")
7527 (div:TF (match_operand:TF 1 "register_operand" "e")
7528 (match_operand:TF 2 "register_operand" "e")))]
7529 "TARGET_FPU && TARGET_HARD_QUAD"
7530 "fdivq\\t%1, %2, %0"
7531 [(set_attr "type" "fpdivd")])
7533 (define_insn "divdf3"
7534 [(set (match_operand:DF 0 "register_operand" "=e")
7535 (div:DF (match_operand:DF 1 "register_operand" "e")
7536 (match_operand:DF 2 "register_operand" "e")))]
7538 "fdivd\\t%1, %2, %0"
7539 [(set_attr "type" "fpdivd")
7540 (set_attr "fptype" "double")])
7542 (define_insn "divsf3"
7543 [(set (match_operand:SF 0 "register_operand" "=f")
7544 (div:SF (match_operand:SF 1 "register_operand" "f")
7545 (match_operand:SF 2 "register_operand" "f")))]
7547 "fdivs\\t%1, %2, %0"
7548 [(set_attr "type" "fpdivs")])
7550 (define_expand "negtf2"
7551 [(set (match_operand:TF 0 "register_operand" "=e,e")
7552 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7556 (define_insn "*negtf2_notv9"
7557 [(set (match_operand:TF 0 "register_operand" "=e,e")
7558 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7559 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7565 [(set_attr "type" "fpmove,*")
7566 (set_attr "length" "*,2")])
7569 [(set (match_operand:TF 0 "register_operand" "")
7570 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7574 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7575 [(set (match_dup 2) (neg:SF (match_dup 3)))
7576 (set (match_dup 4) (match_dup 5))
7577 (set (match_dup 6) (match_dup 7))]
7578 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7579 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7580 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7581 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7582 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7583 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7585 (define_insn "*negtf2_v9"
7586 [(set (match_operand:TF 0 "register_operand" "=e,e")
7587 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7588 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7589 "TARGET_FPU && TARGET_V9"
7593 [(set_attr "type" "fpmove,*")
7594 (set_attr "length" "*,2")
7595 (set_attr "fptype" "double")])
7598 [(set (match_operand:TF 0 "register_operand" "")
7599 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7603 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7604 [(set (match_dup 2) (neg:DF (match_dup 3)))
7605 (set (match_dup 4) (match_dup 5))]
7606 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7607 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7608 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7609 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7611 (define_expand "negdf2"
7612 [(set (match_operand:DF 0 "register_operand" "")
7613 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7617 (define_insn "*negdf2_notv9"
7618 [(set (match_operand:DF 0 "register_operand" "=e,e")
7619 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7620 "TARGET_FPU && ! TARGET_V9"
7624 [(set_attr "type" "fpmove,*")
7625 (set_attr "length" "*,2")])
7628 [(set (match_operand:DF 0 "register_operand" "")
7629 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7633 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7634 [(set (match_dup 2) (neg:SF (match_dup 3)))
7635 (set (match_dup 4) (match_dup 5))]
7636 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7637 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7638 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7639 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7641 (define_insn "*negdf2_v9"
7642 [(set (match_operand:DF 0 "register_operand" "=e")
7643 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7644 "TARGET_FPU && TARGET_V9"
7646 [(set_attr "type" "fpmove")
7647 (set_attr "fptype" "double")])
7649 (define_insn "negsf2"
7650 [(set (match_operand:SF 0 "register_operand" "=f")
7651 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7654 [(set_attr "type" "fpmove")])
7656 (define_expand "abstf2"
7657 [(set (match_operand:TF 0 "register_operand" "")
7658 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7662 (define_insn "*abstf2_notv9"
7663 [(set (match_operand:TF 0 "register_operand" "=e,e")
7664 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7665 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7666 "TARGET_FPU && ! TARGET_V9"
7670 [(set_attr "type" "fpmove,*")
7671 (set_attr "length" "*,2")])
7674 [(set (match_operand:TF 0 "register_operand" "")
7675 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7679 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7680 [(set (match_dup 2) (abs:SF (match_dup 3)))
7681 (set (match_dup 4) (match_dup 5))
7682 (set (match_dup 6) (match_dup 7))]
7683 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7684 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7685 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7686 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7687 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7688 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7690 (define_insn "*abstf2_hq_v9"
7691 [(set (match_operand:TF 0 "register_operand" "=e,e")
7692 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7693 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7697 [(set_attr "type" "fpmove")
7698 (set_attr "fptype" "double,*")])
7700 (define_insn "*abstf2_v9"
7701 [(set (match_operand:TF 0 "register_operand" "=e,e")
7702 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7703 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7707 [(set_attr "type" "fpmove,*")
7708 (set_attr "length" "*,2")
7709 (set_attr "fptype" "double,*")])
7712 [(set (match_operand:TF 0 "register_operand" "")
7713 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7717 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7718 [(set (match_dup 2) (abs:DF (match_dup 3)))
7719 (set (match_dup 4) (match_dup 5))]
7720 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7721 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7722 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7723 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7725 (define_expand "absdf2"
7726 [(set (match_operand:DF 0 "register_operand" "")
7727 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7731 (define_insn "*absdf2_notv9"
7732 [(set (match_operand:DF 0 "register_operand" "=e,e")
7733 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7734 "TARGET_FPU && ! TARGET_V9"
7738 [(set_attr "type" "fpmove,*")
7739 (set_attr "length" "*,2")])
7742 [(set (match_operand:DF 0 "register_operand" "")
7743 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7747 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7748 [(set (match_dup 2) (abs:SF (match_dup 3)))
7749 (set (match_dup 4) (match_dup 5))]
7750 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7751 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7752 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7753 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7755 (define_insn "*absdf2_v9"
7756 [(set (match_operand:DF 0 "register_operand" "=e")
7757 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7758 "TARGET_FPU && TARGET_V9"
7760 [(set_attr "type" "fpmove")
7761 (set_attr "fptype" "double")])
7763 (define_insn "abssf2"
7764 [(set (match_operand:SF 0 "register_operand" "=f")
7765 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7768 [(set_attr "type" "fpmove")])
7770 (define_expand "sqrttf2"
7771 [(set (match_operand:TF 0 "register_operand" "=e")
7772 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7773 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7776 if (! TARGET_HARD_QUAD)
7780 if (GET_CODE (operands[0]) != MEM)
7781 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7783 slot0 = operands[0];
7784 if (GET_CODE (operands[1]) != MEM)
7786 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7787 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7790 slot1 = operands[1];
7792 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7794 XEXP (slot0, 0), Pmode,
7795 XEXP (slot1, 0), Pmode);
7797 if (GET_CODE (operands[0]) != MEM)
7798 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7803 (define_insn "*sqrttf2_hq"
7804 [(set (match_operand:TF 0 "register_operand" "=e")
7805 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7806 "TARGET_FPU && TARGET_HARD_QUAD"
7808 [(set_attr "type" "fpsqrtd")])
7810 (define_insn "sqrtdf2"
7811 [(set (match_operand:DF 0 "register_operand" "=e")
7812 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7815 [(set_attr "type" "fpsqrtd")
7816 (set_attr "fptype" "double")])
7818 (define_insn "sqrtsf2"
7819 [(set (match_operand:SF 0 "register_operand" "=f")
7820 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7823 [(set_attr "type" "fpsqrts")])
7825 ;;- arithmetic shift instructions
7827 (define_insn "ashlsi3"
7828 [(set (match_operand:SI 0 "register_operand" "=r")
7829 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7830 (match_operand:SI 2 "arith_operand" "rI")))]
7834 if (GET_CODE (operands[2]) == CONST_INT
7835 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7836 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7838 return \"sll\\t%1, %2, %0\";
7840 [(set_attr "type" "shift")])
7842 ;; We special case multiplication by two, as add can be done
7843 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7844 (define_insn "*ashlsi3_const1"
7845 [(set (match_operand:SI 0 "register_operand" "=r")
7846 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7851 (define_expand "ashldi3"
7852 [(set (match_operand:DI 0 "register_operand" "=r")
7853 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7854 (match_operand:SI 2 "arith_operand" "rI")))]
7855 "TARGET_ARCH64 || TARGET_V8PLUS"
7858 if (! TARGET_ARCH64)
7860 if (GET_CODE (operands[2]) == CONST_INT)
7862 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7867 ;; We special case multiplication by two, as add can be done
7868 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7869 (define_insn "*ashldi3_const1"
7870 [(set (match_operand:DI 0 "register_operand" "=r")
7871 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7876 (define_insn "*ashldi3_sp64"
7877 [(set (match_operand:DI 0 "register_operand" "=r")
7878 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7879 (match_operand:SI 2 "arith_operand" "rI")))]
7883 if (GET_CODE (operands[2]) == CONST_INT
7884 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7885 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7887 return \"sllx\\t%1, %2, %0\";
7889 [(set_attr "type" "shift")])
7892 (define_insn "ashldi3_v8plus"
7893 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7894 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7895 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7896 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7898 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7899 [(set_attr "type" "multi")
7900 (set_attr "length" "5,5,6")])
7902 ;; Optimize (1LL<<x)-1
7903 ;; XXX this also needs to be fixed to handle equal subregs
7904 ;; XXX first before we could re-enable it.
7906 ; [(set (match_operand:DI 0 "register_operand" "=h")
7907 ; (plus:DI (ashift:DI (const_int 1)
7908 ; (match_operand:SI 1 "arith_operand" "rI"))
7910 ; "0 && TARGET_V8PLUS"
7913 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7914 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7915 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7917 ; [(set_attr "type" "multi")
7918 ; (set_attr "length" "4")])
7920 (define_insn "*cmp_cc_ashift_1"
7921 [(set (reg:CC_NOOV 100)
7922 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7926 "addcc\\t%0, %0, %%g0"
7927 [(set_attr "type" "compare")])
7929 (define_insn "*cmp_cc_set_ashift_1"
7930 [(set (reg:CC_NOOV 100)
7931 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7934 (set (match_operand:SI 0 "register_operand" "=r")
7935 (ashift:SI (match_dup 1) (const_int 1)))]
7937 "addcc\\t%1, %1, %0"
7938 [(set_attr "type" "compare")])
7940 (define_insn "ashrsi3"
7941 [(set (match_operand:SI 0 "register_operand" "=r")
7942 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7943 (match_operand:SI 2 "arith_operand" "rI")))]
7947 if (GET_CODE (operands[2]) == CONST_INT
7948 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7949 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7951 return \"sra\\t%1, %2, %0\";
7953 [(set_attr "type" "shift")])
7955 (define_insn "*ashrsi3_extend"
7956 [(set (match_operand:DI 0 "register_operand" "=r")
7957 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7958 (match_operand:SI 2 "arith_operand" "r"))))]
7961 [(set_attr "type" "shift")])
7963 ;; This handles the case as above, but with constant shift instead of
7964 ;; register. Combiner "simplifies" it for us a little bit though.
7965 (define_insn "*ashrsi3_extend2"
7966 [(set (match_operand:DI 0 "register_operand" "=r")
7967 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7969 (match_operand:SI 2 "small_int_or_double" "n")))]
7971 && ((GET_CODE (operands[2]) == CONST_INT
7972 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7973 || (GET_CODE (operands[2]) == CONST_DOUBLE
7974 && !CONST_DOUBLE_HIGH (operands[2])
7975 && CONST_DOUBLE_LOW (operands[2]) >= 32
7976 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7979 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7981 return \"sra\\t%1, %2, %0\";
7983 [(set_attr "type" "shift")])
7985 (define_expand "ashrdi3"
7986 [(set (match_operand:DI 0 "register_operand" "=r")
7987 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7988 (match_operand:SI 2 "arith_operand" "rI")))]
7989 "TARGET_ARCH64 || TARGET_V8PLUS"
7992 if (! TARGET_ARCH64)
7994 if (GET_CODE (operands[2]) == CONST_INT)
7995 FAIL; /* prefer generic code in this case */
7996 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8002 [(set (match_operand:DI 0 "register_operand" "=r")
8003 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8004 (match_operand:SI 2 "arith_operand" "rI")))]
8008 if (GET_CODE (operands[2]) == CONST_INT
8009 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8010 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8012 return \"srax\\t%1, %2, %0\";
8014 [(set_attr "type" "shift")])
8017 (define_insn "ashrdi3_v8plus"
8018 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8019 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8020 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8021 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8023 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8024 [(set_attr "type" "multi")
8025 (set_attr "length" "5,5,6")])
8027 (define_insn "lshrsi3"
8028 [(set (match_operand:SI 0 "register_operand" "=r")
8029 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8030 (match_operand:SI 2 "arith_operand" "rI")))]
8034 if (GET_CODE (operands[2]) == CONST_INT
8035 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8036 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8038 return \"srl\\t%1, %2, %0\";
8040 [(set_attr "type" "shift")])
8042 ;; This handles the case where
8043 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8044 ;; but combiner "simplifies" it for us.
8045 (define_insn "*lshrsi3_extend"
8046 [(set (match_operand:DI 0 "register_operand" "=r")
8047 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8048 (match_operand:SI 2 "arith_operand" "r")) 0)
8049 (match_operand 3 "" "")))]
8051 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8052 && CONST_DOUBLE_HIGH (operands[3]) == 0
8053 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8054 || (HOST_BITS_PER_WIDE_INT >= 64
8055 && GET_CODE (operands[3]) == CONST_INT
8056 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8058 [(set_attr "type" "shift")])
8060 ;; This handles the case where
8061 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8062 ;; but combiner "simplifies" it for us.
8063 (define_insn "*lshrsi3_extend2"
8064 [(set (match_operand:DI 0 "register_operand" "=r")
8065 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8066 (match_operand 2 "small_int_or_double" "n")
8069 && ((GET_CODE (operands[2]) == CONST_INT
8070 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8071 || (GET_CODE (operands[2]) == CONST_DOUBLE
8072 && CONST_DOUBLE_HIGH (operands[2]) == 0
8073 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8076 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8078 return \"srl\\t%1, %2, %0\";
8080 [(set_attr "type" "shift")])
8082 (define_expand "lshrdi3"
8083 [(set (match_operand:DI 0 "register_operand" "=r")
8084 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8085 (match_operand:SI 2 "arith_operand" "rI")))]
8086 "TARGET_ARCH64 || TARGET_V8PLUS"
8089 if (! TARGET_ARCH64)
8091 if (GET_CODE (operands[2]) == CONST_INT)
8093 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8099 [(set (match_operand:DI 0 "register_operand" "=r")
8100 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8101 (match_operand:SI 2 "arith_operand" "rI")))]
8105 if (GET_CODE (operands[2]) == CONST_INT
8106 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8107 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8109 return \"srlx\\t%1, %2, %0\";
8111 [(set_attr "type" "shift")])
8114 (define_insn "lshrdi3_v8plus"
8115 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8116 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8117 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8118 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8120 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8121 [(set_attr "type" "multi")
8122 (set_attr "length" "5,5,6")])
8125 [(set (match_operand:SI 0 "register_operand" "=r")
8126 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8128 (match_operand:SI 2 "small_int_or_double" "n")))]
8130 && ((GET_CODE (operands[2]) == CONST_INT
8131 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8132 || (GET_CODE (operands[2]) == CONST_DOUBLE
8133 && !CONST_DOUBLE_HIGH (operands[2])
8134 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8137 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8139 return \"srax\\t%1, %2, %0\";
8141 [(set_attr "type" "shift")])
8144 [(set (match_operand:SI 0 "register_operand" "=r")
8145 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8147 (match_operand:SI 2 "small_int_or_double" "n")))]
8149 && ((GET_CODE (operands[2]) == CONST_INT
8150 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8151 || (GET_CODE (operands[2]) == CONST_DOUBLE
8152 && !CONST_DOUBLE_HIGH (operands[2])
8153 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8156 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8158 return \"srlx\\t%1, %2, %0\";
8160 [(set_attr "type" "shift")])
8163 [(set (match_operand:SI 0 "register_operand" "=r")
8164 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8165 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8166 (match_operand:SI 3 "small_int_or_double" "n")))]
8168 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8169 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8170 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8171 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8174 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8176 return \"srax\\t%1, %2, %0\";
8178 [(set_attr "type" "shift")])
8181 [(set (match_operand:SI 0 "register_operand" "=r")
8182 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8183 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8184 (match_operand:SI 3 "small_int_or_double" "n")))]
8186 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8187 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8188 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8189 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8192 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8194 return \"srlx\\t%1, %2, %0\";
8196 [(set_attr "type" "shift")])
8198 ;; Unconditional and other jump instructions
8199 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8200 ;; following insn is never executed. This saves us a nop. Dbx does not
8201 ;; handle such branches though, so we only use them when optimizing.
8203 [(set (pc) (label_ref (match_operand 0 "" "")))]
8207 /* TurboSparc is reported to have problems with
8210 i.e. an empty loop with the annul bit set. The workaround is to use
8214 if (! TARGET_V9 && flag_delayed_branch
8215 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8216 == INSN_ADDRESSES (INSN_UID (insn))))
8217 return \"b\\t%l0%#\";
8219 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8221 [(set_attr "type" "uncond_branch")])
8223 (define_expand "tablejump"
8224 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8225 (use (label_ref (match_operand 1 "" "")))])]
8229 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8232 /* In pic mode, our address differences are against the base of the
8233 table. Add that base value back in; CSE ought to be able to combine
8234 the two address loads. */
8238 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8240 if (CASE_VECTOR_MODE != Pmode)
8241 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8242 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8243 operands[0] = memory_address (Pmode, tmp);
8247 (define_insn "*tablejump_sp32"
8248 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8249 (use (label_ref (match_operand 1 "" "")))]
8252 [(set_attr "type" "uncond_branch")])
8254 (define_insn "*tablejump_sp64"
8255 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8256 (use (label_ref (match_operand 1 "" "")))]
8259 [(set_attr "type" "uncond_branch")])
8261 ;; This pattern recognizes the "instruction" that appears in
8262 ;; a function call that wants a structure value,
8263 ;; to inform the called function if compiled with Sun CC.
8264 ;(define_insn "*unimp_insn"
8265 ; [(match_operand:SI 0 "immediate_operand" "")]
8266 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8268 ; [(set_attr "type" "marker")])
8270 ;;- jump to subroutine
8271 (define_expand "call"
8272 ;; Note that this expression is not used for generating RTL.
8273 ;; All the RTL is generated explicitly below.
8274 [(call (match_operand 0 "call_operand" "")
8275 (match_operand 3 "" "i"))]
8276 ;; operands[2] is next_arg_register
8277 ;; operands[3] is struct_value_size_rtx.
8281 rtx fn_rtx, nregs_rtx;
8283 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8286 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8288 /* This is really a PIC sequence. We want to represent
8289 it as a funny jump so its delay slots can be filled.
8291 ??? But if this really *is* a CALL, will not it clobber the
8292 call-clobbered registers? We lose this if it is a JUMP_INSN.
8293 Why cannot we have delay slots filled if it were a CALL? */
8295 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8300 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8302 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8308 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8309 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8313 fn_rtx = operands[0];
8315 /* Count the number of parameter registers being used by this call.
8316 if that argument is NULL, it means we are using them all, which
8317 means 6 on the sparc. */
8320 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8322 nregs_rtx = GEN_INT (6);
8324 nregs_rtx = const0_rtx;
8327 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8331 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8333 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8338 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8339 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8343 /* If this call wants a structure value,
8344 emit an unimp insn to let the called function know about this. */
8345 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8347 rtx insn = emit_insn (operands[3]);
8348 SCHED_GROUP_P (insn) = 1;
8355 ;; We can't use the same pattern for these two insns, because then registers
8356 ;; in the address may not be properly reloaded.
8358 (define_insn "*call_address_sp32"
8359 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8360 (match_operand 1 "" ""))
8361 (clobber (reg:SI 15))]
8362 ;;- Do not use operand 1 for most machines.
8365 [(set_attr "type" "call")])
8367 (define_insn "*call_symbolic_sp32"
8368 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8369 (match_operand 1 "" ""))
8370 (clobber (reg:SI 15))]
8371 ;;- Do not use operand 1 for most machines.
8374 [(set_attr "type" "call")])
8376 (define_insn "*call_address_sp64"
8377 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8378 (match_operand 1 "" ""))
8379 (clobber (reg:DI 15))]
8380 ;;- Do not use operand 1 for most machines.
8383 [(set_attr "type" "call")])
8385 (define_insn "*call_symbolic_sp64"
8386 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8387 (match_operand 1 "" ""))
8388 (clobber (reg:DI 15))]
8389 ;;- Do not use operand 1 for most machines.
8392 [(set_attr "type" "call")])
8394 ;; This is a call that wants a structure value.
8395 ;; There is no such critter for v9 (??? we may need one anyway).
8396 (define_insn "*call_address_struct_value_sp32"
8397 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8398 (match_operand 1 "" ""))
8399 (match_operand 2 "immediate_operand" "")
8400 (clobber (reg:SI 15))]
8401 ;;- Do not use operand 1 for most machines.
8402 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8403 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8404 [(set_attr "type" "call_no_delay_slot")])
8406 ;; This is a call that wants a structure value.
8407 ;; There is no such critter for v9 (??? we may need one anyway).
8408 (define_insn "*call_symbolic_struct_value_sp32"
8409 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8410 (match_operand 1 "" ""))
8411 (match_operand 2 "immediate_operand" "")
8412 (clobber (reg:SI 15))]
8413 ;;- Do not use operand 1 for most machines.
8414 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8415 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8416 [(set_attr "type" "call_no_delay_slot")])
8418 ;; This is a call that may want a structure value. This is used for
8420 (define_insn "*call_address_untyped_struct_value_sp32"
8421 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8422 (match_operand 1 "" ""))
8423 (match_operand 2 "immediate_operand" "")
8424 (clobber (reg:SI 15))]
8425 ;;- Do not use operand 1 for most machines.
8426 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8427 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8428 [(set_attr "type" "call_no_delay_slot")])
8430 ;; This is a call that wants a structure value.
8431 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8432 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8433 (match_operand 1 "" ""))
8434 (match_operand 2 "immediate_operand" "")
8435 (clobber (reg:SI 15))]
8436 ;;- Do not use operand 1 for most machines.
8437 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8438 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8439 [(set_attr "type" "call_no_delay_slot")])
8441 (define_expand "call_value"
8442 ;; Note that this expression is not used for generating RTL.
8443 ;; All the RTL is generated explicitly below.
8444 [(set (match_operand 0 "register_operand" "=rf")
8445 (call (match_operand 1 "" "")
8446 (match_operand 4 "" "")))]
8447 ;; operand 2 is stack_size_rtx
8448 ;; operand 3 is next_arg_register
8452 rtx fn_rtx, nregs_rtx;
8455 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8458 fn_rtx = operands[1];
8462 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8464 nregs_rtx = GEN_INT (6);
8466 nregs_rtx = const0_rtx;
8470 gen_rtx_SET (VOIDmode, operands[0],
8471 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8472 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8474 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8479 (define_insn "*call_value_address_sp32"
8480 [(set (match_operand 0 "" "=rf")
8481 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8482 (match_operand 2 "" "")))
8483 (clobber (reg:SI 15))]
8484 ;;- Do not use operand 2 for most machines.
8487 [(set_attr "type" "call")])
8489 (define_insn "*call_value_symbolic_sp32"
8490 [(set (match_operand 0 "" "=rf")
8491 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8492 (match_operand 2 "" "")))
8493 (clobber (reg:SI 15))]
8494 ;;- Do not use operand 2 for most machines.
8497 [(set_attr "type" "call")])
8499 (define_insn "*call_value_address_sp64"
8500 [(set (match_operand 0 "" "")
8501 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8502 (match_operand 2 "" "")))
8503 (clobber (reg:DI 15))]
8504 ;;- Do not use operand 2 for most machines.
8507 [(set_attr "type" "call")])
8509 (define_insn "*call_value_symbolic_sp64"
8510 [(set (match_operand 0 "" "")
8511 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8512 (match_operand 2 "" "")))
8513 (clobber (reg:DI 15))]
8514 ;;- Do not use operand 2 for most machines.
8517 [(set_attr "type" "call")])
8519 (define_expand "untyped_call"
8520 [(parallel [(call (match_operand 0 "" "")
8522 (match_operand 1 "" "")
8523 (match_operand 2 "" "")])]
8529 /* Pass constm1 to indicate that it may expect a structure value, but
8530 we don't know what size it is. */
8531 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8533 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8535 rtx set = XVECEXP (operands[2], 0, i);
8536 emit_move_insn (SET_DEST (set), SET_SRC (set));
8539 /* The optimizer does not know that the call sets the function value
8540 registers we stored in the result block. We avoid problems by
8541 claiming that all hard registers are used and clobbered at this
8543 emit_insn (gen_blockage ());
8549 (define_expand "sibcall"
8550 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8555 (define_insn "*sibcall_symbolic_sp32"
8556 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8557 (match_operand 1 "" ""))
8560 "* return output_sibcall(insn, operands[0]);"
8561 [(set_attr "type" "sibcall")])
8563 (define_insn "*sibcall_symbolic_sp64"
8564 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8565 (match_operand 1 "" ""))
8568 "* return output_sibcall(insn, operands[0]);"
8569 [(set_attr "type" "sibcall")])
8571 (define_expand "sibcall_value"
8572 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8573 (call (match_operand 1 "" "") (const_int 0)))
8578 (define_insn "*sibcall_value_symbolic_sp32"
8579 [(set (match_operand 0 "" "=rf")
8580 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8581 (match_operand 2 "" "")))
8584 "* return output_sibcall(insn, operands[1]);"
8585 [(set_attr "type" "sibcall")])
8587 (define_insn "*sibcall_value_symbolic_sp64"
8588 [(set (match_operand 0 "" "")
8589 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8590 (match_operand 2 "" "")))
8593 "* return output_sibcall(insn, operands[1]);"
8594 [(set_attr "type" "sibcall")])
8596 (define_expand "sibcall_epilogue"
8601 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8602 ;; all of memory. This blocks insns from being moved across this point.
8604 (define_insn "blockage"
8605 [(unspec_volatile [(const_int 0)] 0)]
8608 [(set_attr "length" "0")])
8610 ;; Prepare to return any type including a structure value.
8612 (define_expand "untyped_return"
8613 [(match_operand:BLK 0 "memory_operand" "")
8614 (match_operand 1 "" "")]
8618 rtx valreg1 = gen_rtx_REG (DImode, 24);
8619 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8620 rtx result = operands[0];
8622 if (! TARGET_ARCH64)
8624 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8626 rtx value = gen_reg_rtx (SImode);
8628 /* Fetch the instruction where we will return to and see if it's an unimp
8629 instruction (the most significant 10 bits will be zero). If so,
8630 update the return address to skip the unimp instruction. */
8631 emit_move_insn (value,
8632 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8633 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8634 emit_insn (gen_update_return (rtnreg, value));
8637 /* Reload the function value registers. */
8638 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8639 emit_move_insn (valreg2,
8640 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8642 /* Put USE insns before the return. */
8643 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8644 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8646 /* Construct the return. */
8647 expand_null_return ();
8652 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8653 ;; and parts of the compiler don't want to believe that the add is needed.
8655 (define_insn "update_return"
8656 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8657 (match_operand:SI 1 "register_operand" "r")] 1)]
8659 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8660 [(set_attr "type" "multi")
8661 (set_attr "length" "3")])
8663 (define_insn "return"
8667 "* return output_return (operands);"
8668 [(set_attr "type" "return")])
8671 [(set (match_operand:SI 0 "register_operand" "=r")
8672 (match_operand:SI 1 "arith_operand" "rI"))
8674 (use (reg:SI 31))])]
8675 "sparc_return_peephole_ok (operands[0], operands[1])"
8676 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8683 (define_expand "indirect_jump"
8684 [(set (pc) (match_operand 0 "address_operand" "p"))]
8688 (define_insn "*branch_sp32"
8689 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8692 [(set_attr "type" "uncond_branch")])
8694 (define_insn "*branch_sp64"
8695 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8698 [(set_attr "type" "uncond_branch")])
8700 ;; ??? Doesn't work with -mflat.
8701 (define_expand "nonlocal_goto"
8702 [(match_operand:SI 0 "general_operand" "")
8703 (match_operand:SI 1 "general_operand" "")
8704 (match_operand:SI 2 "general_operand" "")
8705 (match_operand:SI 3 "" "")]
8710 rtx chain = operands[0];
8712 rtx lab = operands[1];
8713 rtx stack = operands[2];
8714 rtx fp = operands[3];
8717 /* Trap instruction to flush all the register windows. */
8718 emit_insn (gen_flush_register_windows ());
8720 /* Load the fp value for the containing fn into %fp. This is needed
8721 because STACK refers to %fp. Note that virtual register instantiation
8722 fails if the virtual %fp isn't set from a register. */
8723 if (GET_CODE (fp) != REG)
8724 fp = force_reg (Pmode, fp);
8725 emit_move_insn (virtual_stack_vars_rtx, fp);
8727 /* Find the containing function's current nonlocal goto handler,
8728 which will do any cleanups and then jump to the label. */
8729 labreg = gen_rtx_REG (Pmode, 8);
8730 emit_move_insn (labreg, lab);
8732 /* Restore %fp from stack pointer value for containing function.
8733 The restore insn that follows will move this to %sp,
8734 and reload the appropriate value into %fp. */
8735 emit_move_insn (frame_pointer_rtx, stack);
8737 /* USE of frame_pointer_rtx added for consistency; not clear if
8739 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8740 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8743 /* Return, restoring reg window and jumping to goto handler. */
8744 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8745 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8747 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8753 /* Put in the static chain register the nonlocal label address. */
8754 emit_move_insn (static_chain_rtx, chain);
8757 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8758 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8763 ;; Special trap insn to flush register windows.
8764 (define_insn "flush_register_windows"
8765 [(unspec_volatile [(const_int 0)] 1)]
8767 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8768 [(set_attr "type" "misc")])
8770 (define_insn "goto_handler_and_restore"
8771 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8772 "GET_MODE (operands[0]) == Pmode"
8773 "jmp\\t%0+0\\n\\trestore"
8774 [(set_attr "type" "multi")
8775 (set_attr "length" "2")])
8777 ;;(define_insn "goto_handler_and_restore_v9"
8778 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8779 ;; (match_operand:SI 1 "register_operand" "=r,r")
8780 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8781 ;; "TARGET_V9 && ! TARGET_ARCH64"
8783 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8784 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8785 ;; [(set_attr "type" "multi")
8786 ;; (set_attr "length" "2,3")])
8788 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8789 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8790 ;; (match_operand:DI 1 "register_operand" "=r,r")
8791 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8792 ;; "TARGET_V9 && TARGET_ARCH64"
8794 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8795 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8796 ;; [(set_attr "type" "multi")
8797 ;; (set_attr "length" "2,3")])
8799 ;; For __builtin_setjmp we need to flush register windows iff the function
8800 ;; calls alloca as well, because otherwise the register window might be
8801 ;; saved after %sp adjustement and thus setjmp would crash
8802 (define_expand "builtin_setjmp_setup"
8803 [(match_operand 0 "register_operand" "r")]
8807 emit_insn (gen_do_builtin_setjmp_setup ());
8811 ;; ??? Should set length to zero when !current_function_calls_alloca,
8812 ;; ??? but there is no easy way to get at that definition. It would
8813 ;; ??? require including function.h into sparc-protos.h and that is
8814 ;; ??? likely not a good idea. -DaveM
8815 (define_insn "do_builtin_setjmp_setup"
8816 [(unspec_volatile [(const_int 0)] 5)]
8820 if (!current_function_calls_alloca)
8826 [(set_attr "type" "misc")])
8828 ;; Pattern for use after a setjmp to store FP and the return register
8829 ;; into the stack area.
8831 (define_expand "setjmp"
8837 emit_insn (gen_setjmp_64 ());
8839 emit_insn (gen_setjmp_32 ());
8843 (define_expand "setjmp_32"
8844 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8845 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8848 { operands[0] = frame_pointer_rtx; }")
8850 (define_expand "setjmp_64"
8851 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8852 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8855 { operands[0] = frame_pointer_rtx; }")
8857 ;; Special pattern for the FLUSH instruction.
8859 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8860 ; of the define_insn otherwise missing a mode. We make "flush", aka
8861 ; gen_flush, the default one since sparc_initialize_trampoline uses
8862 ; it on SImode mem values.
8864 (define_insn "flush"
8865 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8867 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8868 [(set_attr "type" "misc")])
8870 (define_insn "flushdi"
8871 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8873 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8874 [(set_attr "type" "misc")])
8879 ;; The scan instruction searches from the most significant bit while ffs
8880 ;; searches from the least significant bit. The bit index and treatment of
8881 ;; zero also differ. It takes at least 7 instructions to get the proper
8882 ;; result. Here is an obvious 8 instruction sequence.
8885 (define_insn "ffssi2"
8886 [(set (match_operand:SI 0 "register_operand" "=&r")
8887 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8888 (clobber (match_scratch:SI 2 "=&r"))]
8889 "TARGET_SPARCLITE || TARGET_SPARCLET"
8892 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\";
8894 [(set_attr "type" "multi")
8895 (set_attr "length" "8")])
8897 ;; ??? This should be a define expand, so that the extra instruction have
8898 ;; a chance of being optimized away.
8900 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8901 ;; does, but no one uses that and we don't have a switch for it.
8903 ;(define_insn "ffsdi2"
8904 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8905 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8906 ; (clobber (match_scratch:DI 2 "=&r"))]
8908 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8909 ; [(set_attr "type" "multi")
8910 ; (set_attr "length" "4")])
8914 ;; Peepholes go at the end.
8916 ;; Optimize consecutive loads or stores into ldd and std when possible.
8917 ;; The conditions in which we do this are very restricted and are
8918 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8921 [(set (match_operand:SI 0 "memory_operand" "")
8923 (set (match_operand:SI 1 "memory_operand" "")
8926 && ! MEM_VOLATILE_P (operands[0])
8927 && ! MEM_VOLATILE_P (operands[1])
8928 && mems_ok_for_ldd_peep (operands[0], operands[1])"
8931 "operands[0] = change_address (operands[0], DImode, NULL);")
8934 [(set (match_operand:SI 0 "memory_operand" "")
8936 (set (match_operand:SI 1 "memory_operand" "")
8939 && ! MEM_VOLATILE_P (operands[0])
8940 && ! MEM_VOLATILE_P (operands[1])
8941 && mems_ok_for_ldd_peep (operands[1], operands[0])"
8944 "operands[1] = change_address (operands[1], DImode, NULL);")
8947 [(set (match_operand:SI 0 "register_operand" "")
8948 (match_operand:SI 1 "memory_operand" ""))
8949 (set (match_operand:SI 2 "register_operand" "")
8950 (match_operand:SI 3 "memory_operand" ""))]
8951 "registers_ok_for_ldd_peep (operands[0], operands[2])
8952 && ! MEM_VOLATILE_P (operands[1])
8953 && ! MEM_VOLATILE_P (operands[3])
8954 && mems_ok_for_ldd_peep (operands[1], operands[3])"
8957 "operands[1] = change_address (operands[1], DImode, NULL);
8958 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8961 [(set (match_operand:SI 0 "memory_operand" "")
8962 (match_operand:SI 1 "register_operand" ""))
8963 (set (match_operand:SI 2 "memory_operand" "")
8964 (match_operand:SI 3 "register_operand" ""))]
8965 "registers_ok_for_ldd_peep (operands[1], operands[3])
8966 && ! MEM_VOLATILE_P (operands[0])
8967 && ! MEM_VOLATILE_P (operands[2])
8968 && mems_ok_for_ldd_peep (operands[0], operands[2])"
8971 "operands[0] = change_address (operands[0], DImode, NULL);
8972 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8975 [(set (match_operand:SF 0 "register_operand" "")
8976 (match_operand:SF 1 "memory_operand" ""))
8977 (set (match_operand:SF 2 "register_operand" "")
8978 (match_operand:SF 3 "memory_operand" ""))]
8979 "registers_ok_for_ldd_peep (operands[0], operands[2])
8980 && ! MEM_VOLATILE_P (operands[1])
8981 && ! MEM_VOLATILE_P (operands[3])
8982 && mems_ok_for_ldd_peep (operands[1], operands[3])"
8985 "operands[1] = change_address (operands[1], DFmode, NULL);
8986 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8989 [(set (match_operand:SF 0 "memory_operand" "")
8990 (match_operand:SF 1 "register_operand" ""))
8991 (set (match_operand:SF 2 "memory_operand" "")
8992 (match_operand:SF 3 "register_operand" ""))]
8993 "registers_ok_for_ldd_peep (operands[1], operands[3])
8994 && ! MEM_VOLATILE_P (operands[0])
8995 && ! MEM_VOLATILE_P (operands[2])
8996 && mems_ok_for_ldd_peep (operands[0], operands[2])"
8999 "operands[0] = change_address (operands[0], DFmode, NULL);
9000 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9003 [(set (match_operand:SI 0 "register_operand" "")
9004 (match_operand:SI 1 "memory_operand" ""))
9005 (set (match_operand:SI 2 "register_operand" "")
9006 (match_operand:SI 3 "memory_operand" ""))]
9007 "registers_ok_for_ldd_peep (operands[2], operands[0])
9008 && ! MEM_VOLATILE_P (operands[3])
9009 && ! MEM_VOLATILE_P (operands[1])
9010 && mems_ok_for_ldd_peep (operands[3], operands[1])"
9013 "operands[3] = change_address (operands[3], DImode, NULL);
9014 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9017 [(set (match_operand:SI 0 "memory_operand" "")
9018 (match_operand:SI 1 "register_operand" ""))
9019 (set (match_operand:SI 2 "memory_operand" "")
9020 (match_operand:SI 3 "register_operand" ""))]
9021 "registers_ok_for_ldd_peep (operands[3], operands[1])
9022 && ! MEM_VOLATILE_P (operands[2])
9023 && ! MEM_VOLATILE_P (operands[0])
9024 && mems_ok_for_ldd_peep (operands[2], operands[0])"
9027 "operands[2] = change_address (operands[2], DImode, NULL);
9028 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9032 [(set (match_operand:SF 0 "register_operand" "")
9033 (match_operand:SF 1 "memory_operand" ""))
9034 (set (match_operand:SF 2 "register_operand" "")
9035 (match_operand:SF 3 "memory_operand" ""))]
9036 "registers_ok_for_ldd_peep (operands[2], operands[0])
9037 && ! MEM_VOLATILE_P (operands[3])
9038 && ! MEM_VOLATILE_P (operands[1])
9039 && mems_ok_for_ldd_peep (operands[3], operands[1])"
9042 "operands[3] = change_address (operands[3], DFmode, NULL);
9043 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9046 [(set (match_operand:SF 0 "memory_operand" "")
9047 (match_operand:SF 1 "register_operand" ""))
9048 (set (match_operand:SF 2 "memory_operand" "")
9049 (match_operand:SF 3 "register_operand" ""))]
9050 "registers_ok_for_ldd_peep (operands[3], operands[1])
9051 && ! MEM_VOLATILE_P (operands[2])
9052 && ! MEM_VOLATILE_P (operands[0])
9053 && mems_ok_for_ldd_peep (operands[2], operands[0])"
9056 "operands[2] = change_address (operands[2], DFmode, NULL);
9057 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9059 ;; Optimize the case of following a reg-reg move with a test
9060 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9061 ;; This can result from a float to fix conversion.
9064 [(set (match_operand:SI 0 "register_operand" "")
9065 (match_operand:SI 1 "register_operand" ""))
9067 (compare:CC (match_operand:SI 2 "register_operand" "")
9069 "(rtx_equal_p (operands[2], operands[0])
9070 || rtx_equal_p (operands[2], operands[1]))
9071 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9072 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9073 [(parallel [(set (match_dup 0) (match_dup 1))
9075 (compare:CC (match_dup 1) (const_int 0)))])]
9079 [(set (match_operand:DI 0 "register_operand" "")
9080 (match_operand:DI 1 "register_operand" ""))
9082 (compare:CCX (match_operand:DI 2 "register_operand" "")
9085 && (rtx_equal_p (operands[2], operands[0])
9086 || rtx_equal_p (operands[2], operands[1]))
9087 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9088 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9089 [(parallel [(set (match_dup 0) (match_dup 1))
9091 (compare:CC (match_dup 1) (const_int 0)))])]
9094 ;; Return peepholes. First the "normal" ones.
9095 ;; These are necessary to catch insns ending up in the epilogue delay list.
9097 (define_insn "*return_qi"
9098 [(set (match_operand:QI 0 "restore_operand" "")
9099 (match_operand:QI 1 "arith_operand" "rI"))
9104 if (! TARGET_ARCH64 && current_function_returns_struct)
9105 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9106 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9107 || IN_OR_GLOBAL_P (operands[1])))
9108 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9110 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9112 [(set_attr "type" "multi")
9113 (set_attr "length" "2")])
9115 (define_insn "*return_hi"
9116 [(set (match_operand:HI 0 "restore_operand" "")
9117 (match_operand:HI 1 "arith_operand" "rI"))
9122 if (! TARGET_ARCH64 && current_function_returns_struct)
9123 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9124 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9125 || IN_OR_GLOBAL_P (operands[1])))
9126 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9128 return \"ret\;restore %%g0, %1, %Y0\";
9130 [(set_attr "type" "multi")
9131 (set_attr "length" "2")])
9133 (define_insn "*return_si"
9134 [(set (match_operand:SI 0 "restore_operand" "")
9135 (match_operand:SI 1 "arith_operand" "rI"))
9140 if (! TARGET_ARCH64 && current_function_returns_struct)
9141 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9142 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9143 || IN_OR_GLOBAL_P (operands[1])))
9144 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9146 return \"ret\;restore %%g0, %1, %Y0\";
9148 [(set_attr "type" "multi")
9149 (set_attr "length" "2")])
9151 ;; The following pattern is only generated by delayed-branch scheduling,
9152 ;; when the insn winds up in the epilogue. This can happen not only when
9153 ;; ! TARGET_FPU because we move complex types around by parts using
9155 (define_insn "*return_sf_no_fpu"
9156 [(set (match_operand:SF 0 "restore_operand" "=r")
9157 (match_operand:SF 1 "register_operand" "r"))
9162 if (! TARGET_ARCH64 && current_function_returns_struct)
9163 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9164 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9165 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9167 return \"ret\;restore %%g0, %1, %Y0\";
9169 [(set_attr "type" "multi")
9170 (set_attr "length" "2")])
9172 (define_insn "*return_df_no_fpu"
9173 [(set (match_operand:DF 0 "restore_operand" "=r")
9174 (match_operand:DF 1 "register_operand" "r"))
9176 "! TARGET_EPILOGUE && TARGET_ARCH64"
9179 if (IN_OR_GLOBAL_P (operands[1]))
9180 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9182 return \"ret\;restore %%g0, %1, %Y0\";
9184 [(set_attr "type" "multi")
9185 (set_attr "length" "2")])
9187 (define_insn "*return_addsi"
9188 [(set (match_operand:SI 0 "restore_operand" "")
9189 (plus:SI (match_operand:SI 1 "register_operand" "r")
9190 (match_operand:SI 2 "arith_operand" "rI")))
9195 if (! TARGET_ARCH64 && current_function_returns_struct)
9196 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9197 /* If operands are global or in registers, can use return */
9198 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9199 && (GET_CODE (operands[2]) == CONST_INT
9200 || IN_OR_GLOBAL_P (operands[2])))
9201 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9203 return \"ret\;restore %r1, %2, %Y0\";
9205 [(set_attr "type" "multi")
9206 (set_attr "length" "2")])
9208 (define_insn "*return_losum_si"
9209 [(set (match_operand:SI 0 "restore_operand" "")
9210 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9211 (match_operand:SI 2 "immediate_operand" "in")))
9213 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9216 if (! TARGET_ARCH64 && current_function_returns_struct)
9217 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9218 /* If operands are global or in registers, can use return */
9219 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9220 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9222 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9224 [(set_attr "type" "multi")
9225 (set_attr "length" "2")])
9227 (define_insn "*return_di"
9228 [(set (match_operand:DI 0 "restore_operand" "")
9229 (match_operand:DI 1 "arith_double_operand" "rHI"))
9231 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9232 "ret\;restore %%g0, %1, %Y0"
9233 [(set_attr "type" "multi")
9234 (set_attr "length" "2")])
9236 (define_insn "*return_adddi"
9237 [(set (match_operand:DI 0 "restore_operand" "")
9238 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9239 (match_operand:DI 2 "arith_double_operand" "rHI")))
9241 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9242 "ret\;restore %r1, %2, %Y0"
9243 [(set_attr "type" "multi")
9244 (set_attr "length" "2")])
9246 (define_insn "*return_losum_di"
9247 [(set (match_operand:DI 0 "restore_operand" "")
9248 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9249 (match_operand:DI 2 "immediate_operand" "in")))
9251 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9252 "ret\;restore %r1, %%lo(%a2), %Y0"
9253 [(set_attr "type" "multi")
9254 (set_attr "length" "2")])
9256 ;; The following pattern is only generated by delayed-branch scheduling,
9257 ;; when the insn winds up in the epilogue.
9258 (define_insn "*return_sf"
9260 (match_operand:SF 0 "register_operand" "f"))
9263 "ret\;fmovs\\t%0, %%f0"
9264 [(set_attr "type" "multi")
9265 (set_attr "length" "2")])
9267 ;; Now peepholes to do a call followed by a jump.
9270 [(parallel [(set (match_operand 0 "" "")
9271 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9272 (match_operand 2 "" "")))
9273 (clobber (reg:SI 15))])
9274 (set (pc) (label_ref (match_operand 3 "" "")))]
9275 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9276 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9277 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9280 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9281 (match_operand 1 "" ""))
9282 (clobber (reg:SI 15))])
9283 (set (pc) (label_ref (match_operand 2 "" "")))]
9284 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9285 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9286 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9289 [(parallel [(set (match_operand 0 "" "")
9290 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9291 (match_operand 2 "" "")))
9292 (clobber (reg:DI 15))])
9293 (set (pc) (label_ref (match_operand 3 "" "")))]
9295 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9296 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9297 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9300 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9301 (match_operand 1 "" ""))
9302 (clobber (reg:DI 15))])
9303 (set (pc) (label_ref (match_operand 2 "" "")))]
9305 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9306 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9307 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9309 (define_insn "prefetch"
9310 [(prefetch (match_operand:DI 0 "address_operand" "p")
9311 (match_operand:DI 1 "const_int_operand" "n")
9312 (match_operand:DI 2 "const_int_operand" "n"))]
9315 static const char * const prefetch_instr[2][4] = {
9317 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9318 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9319 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9320 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9323 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9324 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9325 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9326 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9329 int read_or_write = INTVAL (operands[1]);
9330 int locality = INTVAL (operands[2]);
9332 if (read_or_write != 0 && read_or_write != 1)
9334 if (locality < 0 || locality > 3)
9336 return prefetch_instr [read_or_write][locality];
9338 [(set_attr "type" "load")])
9340 (define_expand "prologue"
9342 "flag_pic && current_function_uses_pic_offset_table"
9345 load_pic_register ();
9349 ;; We need to reload %l7 for -mflat -fpic,
9350 ;; otherwise %l7 should be preserved simply
9351 ;; by loading the function's register window
9352 (define_expand "exception_receiver"
9354 "TARGET_FLAT && flag_pic"
9357 load_pic_register ();
9362 (define_expand "builtin_setjmp_receiver"
9363 [(label_ref (match_operand 0 "" ""))]
9364 "TARGET_FLAT && flag_pic"
9367 load_pic_register ();
9372 [(trap_if (const_int 1) (const_int 5))]
9375 [(set_attr "type" "misc")])
9377 (define_expand "conditional_trap"
9378 [(trap_if (match_operator 0 "noov_compare_op"
9379 [(match_dup 2) (match_dup 3)])
9380 (match_operand:SI 1 "arith_operand" ""))]
9382 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9383 sparc_compare_op0, sparc_compare_op1);
9384 operands[3] = const0_rtx;")
9387 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9388 (match_operand:SI 1 "arith_operand" "rM"))]
9391 [(set_attr "type" "misc")])
9394 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9395 (match_operand:SI 1 "arith_operand" "rM"))]
9398 [(set_attr "type" "misc")])