1 ;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
29 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
34 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
40 ;; 11 embmedany_sethi, embmedany_brsum
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
48 ;; UNSPEC_VOLATILE: 0 blockage
49 ;; 1 flush_register_windows
50 ;; 2 goto_handler_and_restore
51 ;; 3 goto_handler_and_restore_v9*
53 ;; 5 do_builtin_setjmp_setup
56 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
57 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
58 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
59 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
60 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62 ;; Attribute for cpu type.
63 ;; These must match the values for enum processor_type in sparc.h.
64 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
65 (const (symbol_ref "sparc_cpu_attr")))
67 ;; Attribute for the instruction set.
68 ;; At present we only need to distinguish v9/!v9, but for clarity we
69 ;; test TARGET_V8 too.
70 (define_attr "isa" "v6,v8,v9,sparclet"
72 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
73 (symbol_ref "TARGET_V8") (const_string "v8")
74 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
75 (const_string "v6"))))
78 (define_attr "arch" "arch32bit,arch64bit"
80 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
81 (const_string "arch32bit"))))
86 "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,idiv,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
87 (const_string "ialu"))
89 ;; Length (in # of insns).
90 (define_attr "length" "" (const_int 1))
93 (define_attr "fptype" "single,double" (const_string "single"))
95 (define_asm_attributes
96 [(set_attr "length" "2")
97 (set_attr "type" "multi")])
99 ;; Attributes for instruction and branch scheduling
101 (define_attr "in_call_delay" "false,true"
102 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
103 (const_string "false")
104 (eq_attr "type" "load,fpload,store,fpstore")
105 (if_then_else (eq_attr "length" "1")
106 (const_string "true")
107 (const_string "false"))]
108 (if_then_else (eq_attr "length" "1")
109 (const_string "true")
110 (const_string "false"))))
112 (define_delay (eq_attr "type" "call")
113 [(eq_attr "in_call_delay" "true") (nil) (nil)])
115 (define_attr "eligible_for_sibcall_delay" "false,true"
116 (symbol_ref "eligible_for_sibcall_delay (insn)"))
118 (define_delay (eq_attr "type" "sibcall")
119 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
121 (define_attr "leaf_function" "false,true"
122 (const (symbol_ref "current_function_uses_only_leaf_regs")))
124 (define_attr "eligible_for_return_delay" "false,true"
125 (symbol_ref "eligible_for_return_delay (insn)"))
127 (define_attr "in_return_delay" "false,true"
128 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
129 (eq_attr "length" "1"))
130 (eq_attr "leaf_function" "false"))
131 (eq_attr "eligible_for_return_delay" "false"))
132 (const_string "true")
133 (const_string "false")))
135 (define_delay (and (eq_attr "type" "return")
136 (eq_attr "isa" "v9"))
137 [(eq_attr "in_return_delay" "true") (nil) (nil)])
139 ;; ??? Should implement the notion of predelay slots for floating point
140 ;; branches. This would allow us to remove the nop always inserted before
141 ;; a floating point branch.
143 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
144 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
145 ;; This is because doing so will add several pipeline stalls to the path
146 ;; that the load/store did not come from. Unfortunately, there is no way
147 ;; to prevent fill_eager_delay_slots from using load/store without completely
148 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
149 ;; because it prevents us from moving back the final store of inner loops.
151 (define_attr "in_branch_delay" "false,true"
152 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
153 (eq_attr "length" "1"))
154 (const_string "true")
155 (const_string "false")))
157 (define_attr "in_uncond_branch_delay" "false,true"
158 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
159 (eq_attr "length" "1"))
160 (const_string "true")
161 (const_string "false")))
163 (define_attr "in_annul_branch_delay" "false,true"
164 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
165 (eq_attr "length" "1"))
166 (const_string "true")
167 (const_string "false")))
169 (define_delay (eq_attr "type" "branch")
170 [(eq_attr "in_branch_delay" "true")
171 (nil) (eq_attr "in_annul_branch_delay" "true")])
173 (define_delay (eq_attr "type" "uncond_branch")
174 [(eq_attr "in_uncond_branch_delay" "true")
177 ;; Function units of the SPARC
179 ;; (define_function_unit {name} {num-units} {n-users} {test}
180 ;; {ready-delay} {issue-delay} [{conflict-list}])
183 ;; (Noted only for documentation; units that take one cycle do not need to
186 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
189 ;; ---- cypress CY7C602 scheduling:
190 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
192 (define_function_unit "memory" 1 0
193 (and (eq_attr "cpu" "cypress")
194 (eq_attr "type" "load,sload,fpload"))
197 ;; SPARC has two floating-point units: the FP ALU,
198 ;; and the FP MUL/DIV/SQRT unit.
199 ;; Instruction timings on the CY7C602 are as follows
213 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
214 ;; More insns cause the chip to stall.
216 (define_function_unit "fp_alu" 1 0
217 (and (eq_attr "cpu" "cypress")
218 (eq_attr "type" "fp,fpmove"))
221 (define_function_unit "fp_mds" 1 0
222 (and (eq_attr "cpu" "cypress")
223 (eq_attr "type" "fpmul"))
226 (define_function_unit "fp_mds" 1 0
227 (and (eq_attr "cpu" "cypress")
228 (eq_attr "type" "fpdivs,fpdivd"))
231 (define_function_unit "fp_mds" 1 0
232 (and (eq_attr "cpu" "cypress")
233 (eq_attr "type" "fpsqrts,fpsqrtd"))
236 ;; ----- The TMS390Z55 scheduling
237 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
238 ;; one ld/st, one fp.
239 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
241 (define_function_unit "memory" 1 0
242 (and (eq_attr "cpu" "supersparc")
243 (eq_attr "type" "load,sload"))
246 (define_function_unit "memory" 1 0
247 (and (eq_attr "cpu" "supersparc")
248 (eq_attr "type" "fpload"))
251 (define_function_unit "memory" 1 0
252 (and (eq_attr "cpu" "supersparc")
253 (eq_attr "type" "store,fpstore"))
256 (define_function_unit "shift" 1 0
257 (and (eq_attr "cpu" "supersparc")
258 (eq_attr "type" "shift"))
261 ;; There are only two write ports to the integer register file
262 ;; A store also uses a write port
264 (define_function_unit "iwport" 2 0
265 (and (eq_attr "cpu" "supersparc")
266 (eq_attr "type" "load,sload,store,shift,ialu"))
269 ;; Timings; throughput/latency
270 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
278 (define_function_unit "fp_alu" 1 0
279 (and (eq_attr "cpu" "supersparc")
280 (eq_attr "type" "fp,fpmove,fpcmp"))
283 (define_function_unit "fp_mds" 1 0
284 (and (eq_attr "cpu" "supersparc")
285 (eq_attr "type" "fpmul"))
288 (define_function_unit "fp_mds" 1 0
289 (and (eq_attr "cpu" "supersparc")
290 (eq_attr "type" "fpdivs"))
293 (define_function_unit "fp_mds" 1 0
294 (and (eq_attr "cpu" "supersparc")
295 (eq_attr "type" "fpdivd"))
298 (define_function_unit "fp_mds" 1 0
299 (and (eq_attr "cpu" "supersparc")
300 (eq_attr "type" "fpsqrts,fpsqrtd"))
303 (define_function_unit "fp_mds" 1 0
304 (and (eq_attr "cpu" "supersparc")
305 (eq_attr "type" "imul"))
308 ;; ----- hypersparc/sparclite86x scheduling
309 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
310 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
311 ;; II/FF case is only when loading a 32 bit hi/lo constant
312 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
313 ;; Memory delivers its result in one cycle to IU
315 (define_function_unit "memory" 1 0
316 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
317 (eq_attr "type" "load,sload,fpload"))
320 (define_function_unit "memory" 1 0
321 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
322 (eq_attr "type" "store,fpstore"))
325 (define_function_unit "sparclite86x_branch" 1 0
326 (and (eq_attr "cpu" "sparclite86x")
327 (eq_attr "type" "branch"))
330 ;; integer multiply insns
331 (define_function_unit "sparclite86x_shift" 1 0
332 (and (eq_attr "cpu" "sparclite86x")
333 (eq_attr "type" "shift"))
336 (define_function_unit "fp_alu" 1 0
337 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
338 (eq_attr "type" "fp,fpmove,fpcmp"))
341 (define_function_unit "fp_mds" 1 0
342 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
343 (eq_attr "type" "fpmul"))
346 (define_function_unit "fp_mds" 1 0
347 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
348 (eq_attr "type" "fpdivs"))
351 (define_function_unit "fp_mds" 1 0
352 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
353 (eq_attr "type" "fpdivd"))
356 (define_function_unit "fp_mds" 1 0
357 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
358 (eq_attr "type" "fpsqrts,fpsqrtd"))
361 (define_function_unit "fp_mds" 1 0
362 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
363 (eq_attr "type" "imul"))
366 ;; ----- sparclet tsc701 scheduling
367 ;; The tsc701 issues 1 insn per cycle.
368 ;; Results may be written back out of order.
370 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
372 (define_function_unit "tsc701_load" 4 1
373 (and (eq_attr "cpu" "tsc701")
374 (eq_attr "type" "load,sload"))
377 ;; Stores take 2(?) extra cycles to complete.
378 ;; It is desirable to not have any memory operation in the following 2 cycles.
379 ;; (??? or 2 memory ops in the case of std).
381 (define_function_unit "tsc701_store" 1 0
382 (and (eq_attr "cpu" "tsc701")
383 (eq_attr "type" "store"))
385 [(eq_attr "type" "load,sload,store")])
387 ;; The multiply unit has a latency of 5.
388 (define_function_unit "tsc701_mul" 1 0
389 (and (eq_attr "cpu" "tsc701")
390 (eq_attr "type" "imul"))
393 ;; ----- The UltraSPARC-1 scheduling
394 ;; UltraSPARC has two integer units. Shift instructions can only execute
395 ;; on IE0. Condition code setting instructions, call, and jmpl (including
396 ;; the ret and retl pseudo-instructions) can only execute on IE1.
397 ;; Branch on register uses IE1, but branch on condition code does not.
398 ;; Conditional moves take 2 cycles. No other instruction can issue in the
399 ;; same cycle as a conditional move.
400 ;; Multiply and divide take many cycles during which no other instructions
402 ;; Memory delivers its result in two cycles (except for signed loads,
403 ;; which take one cycle more). One memory instruction can be issued per
406 (define_function_unit "memory" 1 0
407 (and (eq_attr "cpu" "ultrasparc")
408 (eq_attr "type" "load,fpload"))
411 (define_function_unit "memory" 1 0
412 (and (eq_attr "cpu" "ultrasparc")
413 (eq_attr "type" "sload"))
416 (define_function_unit "memory" 1 0
417 (and (eq_attr "cpu" "ultrasparc")
418 (eq_attr "type" "store,fpstore"))
421 (define_function_unit "ieuN" 2 0
422 (and (eq_attr "cpu" "ultrasparc")
423 (eq_attr "type" "ialu,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
426 (define_function_unit "ieu0" 1 0
427 (and (eq_attr "cpu" "ultrasparc")
428 (eq_attr "type" "shift"))
431 (define_function_unit "ieu0" 1 0
432 (and (eq_attr "cpu" "ultrasparc")
433 (eq_attr "type" "cmove"))
436 (define_function_unit "ieu1" 1 0
437 (and (eq_attr "cpu" "ultrasparc")
438 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
441 (define_function_unit "cti" 1 0
442 (and (eq_attr "cpu" "ultrasparc")
443 (eq_attr "type" "branch"))
446 ;; Timings; throughput/latency
447 ;; FMOV 1/1 fmov, fabs, fneg
449 ;; FADD 1/3 add/sub, format conv, compar
455 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
457 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
458 ;; use the FPM multiplier for final rounding 3 cycles before the
459 ;; end of their latency and we have no real way to model that.
461 ;; ??? This is really bogus because the timings really depend upon
462 ;; who uses the result. We should record who the user is with
463 ;; more descriptive 'type' attribute names and account for these
464 ;; issues in ultrasparc_adjust_cost.
466 (define_function_unit "fadd" 1 0
467 (and (eq_attr "cpu" "ultrasparc")
468 (eq_attr "type" "fpmove"))
471 (define_function_unit "fadd" 1 0
472 (and (eq_attr "cpu" "ultrasparc")
473 (eq_attr "type" "fpcmove"))
476 (define_function_unit "fadd" 1 0
477 (and (eq_attr "cpu" "ultrasparc")
478 (eq_attr "type" "fp"))
481 (define_function_unit "fadd" 1 0
482 (and (eq_attr "cpu" "ultrasparc")
483 (eq_attr "type" "fpcmp"))
486 (define_function_unit "fmul" 1 0
487 (and (eq_attr "cpu" "ultrasparc")
488 (eq_attr "type" "fpmul"))
491 (define_function_unit "fadd" 1 0
492 (and (eq_attr "cpu" "ultrasparc")
493 (eq_attr "type" "fpcmove"))
496 (define_function_unit "fdiv" 1 0
497 (and (eq_attr "cpu" "ultrasparc")
498 (eq_attr "type" "fpdivs"))
501 (define_function_unit "fdiv" 1 0
502 (and (eq_attr "cpu" "ultrasparc")
503 (eq_attr "type" "fpdivd"))
506 (define_function_unit "fdiv" 1 0
507 (and (eq_attr "cpu" "ultrasparc")
508 (eq_attr "type" "fpsqrts"))
511 (define_function_unit "fdiv" 1 0
512 (and (eq_attr "cpu" "ultrasparc")
513 (eq_attr "type" "fpsqrtd"))
516 ;; Compare instructions.
517 ;; This controls RTL generation and register allocation.
519 ;; We generate RTL for comparisons and branches by having the cmpxx
520 ;; patterns store away the operands. Then, the scc and bcc patterns
521 ;; emit RTL for both the compare and the branch.
523 ;; We do this because we want to generate different code for an sne and
524 ;; seq insn. In those cases, if the second operand of the compare is not
525 ;; const0_rtx, we want to compute the xor of the two operands and test
528 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
529 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
530 ;; insns that actually require more than one machine instruction.
532 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
534 (define_expand "cmpsi"
536 (compare:CC (match_operand:SI 0 "register_operand" "")
537 (match_operand:SI 1 "arith_operand" "")))]
541 sparc_compare_op0 = operands[0];
542 sparc_compare_op1 = operands[1];
546 (define_expand "cmpdi"
548 (compare:CCX (match_operand:DI 0 "register_operand" "")
549 (match_operand:DI 1 "arith_double_operand" "")))]
553 sparc_compare_op0 = operands[0];
554 sparc_compare_op1 = operands[1];
558 (define_expand "cmpsf"
559 ;; The 96 here isn't ever used by anyone.
561 (compare:CCFP (match_operand:SF 0 "register_operand" "")
562 (match_operand:SF 1 "register_operand" "")))]
566 sparc_compare_op0 = operands[0];
567 sparc_compare_op1 = operands[1];
571 (define_expand "cmpdf"
572 ;; The 96 here isn't ever used by anyone.
574 (compare:CCFP (match_operand:DF 0 "register_operand" "")
575 (match_operand:DF 1 "register_operand" "")))]
579 sparc_compare_op0 = operands[0];
580 sparc_compare_op1 = operands[1];
584 (define_expand "cmptf"
585 ;; The 96 here isn't ever used by anyone.
587 (compare:CCFP (match_operand:TF 0 "register_operand" "")
588 (match_operand:TF 1 "register_operand" "")))]
592 sparc_compare_op0 = operands[0];
593 sparc_compare_op1 = operands[1];
597 ;; Now the compare DEFINE_INSNs.
599 (define_insn "*cmpsi_insn"
601 (compare:CC (match_operand:SI 0 "register_operand" "r")
602 (match_operand:SI 1 "arith_operand" "rI")))]
605 [(set_attr "type" "compare")])
607 (define_insn "*cmpdi_sp64"
609 (compare:CCX (match_operand:DI 0 "register_operand" "r")
610 (match_operand:DI 1 "arith_double_operand" "rHI")))]
613 [(set_attr "type" "compare")])
615 (define_insn "*cmpsf_fpe"
616 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
617 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
618 (match_operand:SF 2 "register_operand" "f")))]
623 return \"fcmpes\\t%0, %1, %2\";
624 return \"fcmpes\\t%1, %2\";
626 [(set_attr "type" "fpcmp")])
628 (define_insn "*cmpdf_fpe"
629 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
630 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
631 (match_operand:DF 2 "register_operand" "e")))]
636 return \"fcmped\\t%0, %1, %2\";
637 return \"fcmped\\t%1, %2\";
639 [(set_attr "type" "fpcmp")
640 (set_attr "fptype" "double")])
642 (define_insn "*cmptf_fpe"
643 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
644 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
645 (match_operand:TF 2 "register_operand" "e")))]
646 "TARGET_FPU && TARGET_HARD_QUAD"
650 return \"fcmpeq\\t%0, %1, %2\";
651 return \"fcmpeq\\t%1, %2\";
653 [(set_attr "type" "fpcmp")])
655 (define_insn "*cmpsf_fp"
656 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
657 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
658 (match_operand:SF 2 "register_operand" "f")))]
663 return \"fcmps\\t%0, %1, %2\";
664 return \"fcmps\\t%1, %2\";
666 [(set_attr "type" "fpcmp")])
668 (define_insn "*cmpdf_fp"
669 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
670 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
671 (match_operand:DF 2 "register_operand" "e")))]
676 return \"fcmpd\\t%0, %1, %2\";
677 return \"fcmpd\\t%1, %2\";
679 [(set_attr "type" "fpcmp")
680 (set_attr "fptype" "double")])
682 (define_insn "*cmptf_fp"
683 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
684 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
685 (match_operand:TF 2 "register_operand" "e")))]
686 "TARGET_FPU && TARGET_HARD_QUAD"
690 return \"fcmpq\\t%0, %1, %2\";
691 return \"fcmpq\\t%1, %2\";
693 [(set_attr "type" "fpcmp")])
695 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
696 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
697 ;; the same code as v8 (the addx/subx method has more applications). The
698 ;; exception to this is "reg != 0" which can be done in one instruction on v9
699 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
702 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
703 ;; generate addcc/subcc instructions.
705 (define_expand "seqsi_special"
707 (xor:SI (match_operand:SI 1 "register_operand" "")
708 (match_operand:SI 2 "register_operand" "")))
709 (parallel [(set (match_operand:SI 0 "register_operand" "")
710 (eq:SI (match_dup 3) (const_int 0)))
711 (clobber (reg:CC 100))])]
713 "{ operands[3] = gen_reg_rtx (SImode); }")
715 (define_expand "seqdi_special"
717 (xor:DI (match_operand:DI 1 "register_operand" "")
718 (match_operand:DI 2 "register_operand" "")))
719 (set (match_operand:DI 0 "register_operand" "")
720 (eq:DI (match_dup 3) (const_int 0)))]
722 "{ operands[3] = gen_reg_rtx (DImode); }")
724 (define_expand "snesi_special"
726 (xor:SI (match_operand:SI 1 "register_operand" "")
727 (match_operand:SI 2 "register_operand" "")))
728 (parallel [(set (match_operand:SI 0 "register_operand" "")
729 (ne:SI (match_dup 3) (const_int 0)))
730 (clobber (reg:CC 100))])]
732 "{ operands[3] = gen_reg_rtx (SImode); }")
734 (define_expand "snedi_special"
736 (xor:DI (match_operand:DI 1 "register_operand" "")
737 (match_operand:DI 2 "register_operand" "")))
738 (set (match_operand:DI 0 "register_operand" "")
739 (ne:DI (match_dup 3) (const_int 0)))]
741 "{ operands[3] = gen_reg_rtx (DImode); }")
743 (define_expand "seqdi_special_trunc"
745 (xor:DI (match_operand:DI 1 "register_operand" "")
746 (match_operand:DI 2 "register_operand" "")))
747 (set (match_operand:SI 0 "register_operand" "")
748 (eq:SI (match_dup 3) (const_int 0)))]
750 "{ operands[3] = gen_reg_rtx (DImode); }")
752 (define_expand "snedi_special_trunc"
754 (xor:DI (match_operand:DI 1 "register_operand" "")
755 (match_operand:DI 2 "register_operand" "")))
756 (set (match_operand:SI 0 "register_operand" "")
757 (ne:SI (match_dup 3) (const_int 0)))]
759 "{ operands[3] = gen_reg_rtx (DImode); }")
761 (define_expand "seqsi_special_extend"
763 (xor:SI (match_operand:SI 1 "register_operand" "")
764 (match_operand:SI 2 "register_operand" "")))
765 (parallel [(set (match_operand:DI 0 "register_operand" "")
766 (eq:DI (match_dup 3) (const_int 0)))
767 (clobber (reg:CC 100))])]
769 "{ operands[3] = gen_reg_rtx (SImode); }")
771 (define_expand "snesi_special_extend"
773 (xor:SI (match_operand:SI 1 "register_operand" "")
774 (match_operand:SI 2 "register_operand" "")))
775 (parallel [(set (match_operand:DI 0 "register_operand" "")
776 (ne:DI (match_dup 3) (const_int 0)))
777 (clobber (reg:CC 100))])]
779 "{ operands[3] = gen_reg_rtx (SImode); }")
781 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
782 ;; However, the code handles both SImode and DImode.
784 [(set (match_operand:SI 0 "intreg_operand" "")
785 (eq:SI (match_dup 1) (const_int 0)))]
789 if (GET_MODE (sparc_compare_op0) == SImode)
793 if (GET_MODE (operands[0]) == SImode)
794 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
796 else if (! TARGET_ARCH64)
799 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
804 else if (GET_MODE (sparc_compare_op0) == DImode)
810 else if (GET_MODE (operands[0]) == SImode)
811 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
814 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
819 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
821 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
822 emit_jump_insn (gen_sne (operands[0]));
827 if (gen_v9_scc (EQ, operands))
834 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
835 ;; However, the code handles both SImode and DImode.
837 [(set (match_operand:SI 0 "intreg_operand" "")
838 (ne:SI (match_dup 1) (const_int 0)))]
842 if (GET_MODE (sparc_compare_op0) == SImode)
846 if (GET_MODE (operands[0]) == SImode)
847 pat = gen_snesi_special (operands[0], sparc_compare_op0,
849 else if (! TARGET_ARCH64)
852 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
857 else if (GET_MODE (sparc_compare_op0) == DImode)
863 else if (GET_MODE (operands[0]) == SImode)
864 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
867 pat = gen_snedi_special (operands[0], sparc_compare_op0,
872 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
874 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
875 emit_jump_insn (gen_sne (operands[0]));
880 if (gen_v9_scc (NE, operands))
888 [(set (match_operand:SI 0 "intreg_operand" "")
889 (gt:SI (match_dup 1) (const_int 0)))]
893 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
895 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
896 emit_jump_insn (gen_sne (operands[0]));
901 if (gen_v9_scc (GT, operands))
909 [(set (match_operand:SI 0 "intreg_operand" "")
910 (lt:SI (match_dup 1) (const_int 0)))]
914 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
916 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
917 emit_jump_insn (gen_sne (operands[0]));
922 if (gen_v9_scc (LT, operands))
930 [(set (match_operand:SI 0 "intreg_operand" "")
931 (ge:SI (match_dup 1) (const_int 0)))]
935 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
937 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
938 emit_jump_insn (gen_sne (operands[0]));
943 if (gen_v9_scc (GE, operands))
951 [(set (match_operand:SI 0 "intreg_operand" "")
952 (le:SI (match_dup 1) (const_int 0)))]
956 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
958 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
959 emit_jump_insn (gen_sne (operands[0]));
964 if (gen_v9_scc (LE, operands))
971 (define_expand "sgtu"
972 [(set (match_operand:SI 0 "intreg_operand" "")
973 (gtu:SI (match_dup 1) (const_int 0)))]
981 /* We can do ltu easily, so if both operands are registers, swap them and
983 if ((GET_CODE (sparc_compare_op0) == REG
984 || GET_CODE (sparc_compare_op0) == SUBREG)
985 && (GET_CODE (sparc_compare_op1) == REG
986 || GET_CODE (sparc_compare_op1) == SUBREG))
988 tem = sparc_compare_op0;
989 sparc_compare_op0 = sparc_compare_op1;
990 sparc_compare_op1 = tem;
991 pat = gen_sltu (operands[0]);
1000 if (gen_v9_scc (GTU, operands))
1006 (define_expand "sltu"
1007 [(set (match_operand:SI 0 "intreg_operand" "")
1008 (ltu:SI (match_dup 1) (const_int 0)))]
1014 if (gen_v9_scc (LTU, operands))
1017 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1020 (define_expand "sgeu"
1021 [(set (match_operand:SI 0 "intreg_operand" "")
1022 (geu:SI (match_dup 1) (const_int 0)))]
1028 if (gen_v9_scc (GEU, operands))
1031 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1034 (define_expand "sleu"
1035 [(set (match_operand:SI 0 "intreg_operand" "")
1036 (leu:SI (match_dup 1) (const_int 0)))]
1044 /* We can do geu easily, so if both operands are registers, swap them and
1046 if ((GET_CODE (sparc_compare_op0) == REG
1047 || GET_CODE (sparc_compare_op0) == SUBREG)
1048 && (GET_CODE (sparc_compare_op1) == REG
1049 || GET_CODE (sparc_compare_op1) == SUBREG))
1051 tem = sparc_compare_op0;
1052 sparc_compare_op0 = sparc_compare_op1;
1053 sparc_compare_op1 = tem;
1054 pat = gen_sgeu (operands[0]);
1055 if (pat == NULL_RTX)
1063 if (gen_v9_scc (LEU, operands))
1069 ;; Now the DEFINE_INSNs for the scc cases.
1071 ;; The SEQ and SNE patterns are special because they can be done
1072 ;; without any branching and do not involve a COMPARE. We want
1073 ;; them to always use the splitz below so the results can be
1076 (define_insn "*snesi_zero"
1077 [(set (match_operand:SI 0 "register_operand" "=r")
1078 (ne:SI (match_operand:SI 1 "register_operand" "r")
1080 (clobber (reg:CC 100))]
1083 [(set_attr "length" "2")])
1086 [(set (match_operand:SI 0 "register_operand" "")
1087 (ne:SI (match_operand:SI 1 "register_operand" "")
1089 (clobber (reg:CC 100))]
1091 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1093 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1096 (define_insn "*neg_snesi_zero"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1098 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1100 (clobber (reg:CC 100))]
1103 [(set_attr "length" "2")])
1106 [(set (match_operand:SI 0 "register_operand" "")
1107 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1109 (clobber (reg:CC 100))]
1111 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1113 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1116 (define_insn "*snesi_zero_extend"
1117 [(set (match_operand:DI 0 "register_operand" "=r")
1118 (ne:DI (match_operand:SI 1 "register_operand" "r")
1120 (clobber (reg:CC 100))]
1123 [(set_attr "length" "2")])
1126 [(set (match_operand:DI 0 "register_operand" "")
1127 (ne:DI (match_operand:SI 1 "register_operand" "")
1129 (clobber (reg:CC 100))]
1131 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1133 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1135 (ltu:SI (reg:CC_NOOV 100)
1139 (define_insn "*snedi_zero"
1140 [(set (match_operand:DI 0 "register_operand" "=&r")
1141 (ne:DI (match_operand:DI 1 "register_operand" "r")
1145 [(set_attr "length" "2")])
1148 [(set (match_operand:DI 0 "register_operand" "")
1149 (ne:DI (match_operand:DI 1 "register_operand" "")
1152 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1153 [(set (match_dup 0) (const_int 0))
1154 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1160 (define_insn "*neg_snedi_zero"
1161 [(set (match_operand:DI 0 "register_operand" "=&r")
1162 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1166 [(set_attr "length" "2")])
1169 [(set (match_operand:DI 0 "register_operand" "")
1170 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1173 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1174 [(set (match_dup 0) (const_int 0))
1175 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1181 (define_insn "*snedi_zero_trunc"
1182 [(set (match_operand:SI 0 "register_operand" "=&r")
1183 (ne:SI (match_operand:DI 1 "register_operand" "r")
1187 [(set_attr "length" "2")])
1190 [(set (match_operand:SI 0 "register_operand" "")
1191 (ne:SI (match_operand:DI 1 "register_operand" "")
1194 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1195 [(set (match_dup 0) (const_int 0))
1196 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1202 (define_insn "*seqsi_zero"
1203 [(set (match_operand:SI 0 "register_operand" "=r")
1204 (eq:SI (match_operand:SI 1 "register_operand" "r")
1206 (clobber (reg:CC 100))]
1209 [(set_attr "length" "2")])
1212 [(set (match_operand:SI 0 "register_operand" "")
1213 (eq:SI (match_operand:SI 1 "register_operand" "")
1215 (clobber (reg:CC 100))]
1217 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1219 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1222 (define_insn "*neg_seqsi_zero"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1226 (clobber (reg:CC 100))]
1229 [(set_attr "length" "2")])
1232 [(set (match_operand:SI 0 "register_operand" "")
1233 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1235 (clobber (reg:CC 100))]
1237 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1239 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1242 (define_insn "*seqsi_zero_extend"
1243 [(set (match_operand:DI 0 "register_operand" "=r")
1244 (eq:DI (match_operand:SI 1 "register_operand" "r")
1246 (clobber (reg:CC 100))]
1249 [(set_attr "length" "2")])
1252 [(set (match_operand:DI 0 "register_operand" "")
1253 (eq:DI (match_operand:SI 1 "register_operand" "")
1255 (clobber (reg:CC 100))]
1257 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1259 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1261 (ltu:SI (reg:CC_NOOV 100)
1265 (define_insn "*seqdi_zero"
1266 [(set (match_operand:DI 0 "register_operand" "=&r")
1267 (eq:DI (match_operand:DI 1 "register_operand" "r")
1271 [(set_attr "length" "2")])
1274 [(set (match_operand:DI 0 "register_operand" "")
1275 (eq:DI (match_operand:DI 1 "register_operand" "")
1278 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1279 [(set (match_dup 0) (const_int 0))
1280 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1286 (define_insn "*neg_seqdi_zero"
1287 [(set (match_operand:DI 0 "register_operand" "=&r")
1288 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1292 [(set_attr "length" "2")])
1295 [(set (match_operand:DI 0 "register_operand" "")
1296 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1299 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1300 [(set (match_dup 0) (const_int 0))
1301 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1307 (define_insn "*seqdi_zero_trunc"
1308 [(set (match_operand:SI 0 "register_operand" "=&r")
1309 (eq:SI (match_operand:DI 1 "register_operand" "r")
1313 [(set_attr "length" "2")])
1316 [(set (match_operand:SI 0 "register_operand" "")
1317 (eq:SI (match_operand:DI 1 "register_operand" "")
1320 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1321 [(set (match_dup 0) (const_int 0))
1322 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1328 ;; We can also do (x + (i == 0)) and related, so put them in.
1329 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1332 (define_insn "*x_plus_i_ne_0"
1333 [(set (match_operand:SI 0 "register_operand" "=r")
1334 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1336 (match_operand:SI 2 "register_operand" "r")))
1337 (clobber (reg:CC 100))]
1340 [(set_attr "length" "2")])
1343 [(set (match_operand:SI 0 "register_operand" "")
1344 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1346 (match_operand:SI 2 "register_operand" "")))
1347 (clobber (reg:CC 100))]
1349 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1351 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1355 (define_insn "*x_minus_i_ne_0"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (minus:SI (match_operand:SI 2 "register_operand" "r")
1358 (ne:SI (match_operand:SI 1 "register_operand" "r")
1360 (clobber (reg:CC 100))]
1363 [(set_attr "length" "2")])
1366 [(set (match_operand:SI 0 "register_operand" "")
1367 (minus:SI (match_operand:SI 2 "register_operand" "")
1368 (ne:SI (match_operand:SI 1 "register_operand" "")
1370 (clobber (reg:CC 100))]
1372 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1374 (set (match_dup 0) (minus:SI (match_dup 2)
1375 (ltu:SI (reg:CC 100) (const_int 0))))]
1378 (define_insn "*x_plus_i_eq_0"
1379 [(set (match_operand:SI 0 "register_operand" "=r")
1380 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1382 (match_operand:SI 2 "register_operand" "r")))
1383 (clobber (reg:CC 100))]
1386 [(set_attr "length" "2")])
1389 [(set (match_operand:SI 0 "register_operand" "")
1390 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1392 (match_operand:SI 2 "register_operand" "")))
1393 (clobber (reg:CC 100))]
1395 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1397 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1401 (define_insn "*x_minus_i_eq_0"
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (minus:SI (match_operand:SI 2 "register_operand" "r")
1404 (eq:SI (match_operand:SI 1 "register_operand" "r")
1406 (clobber (reg:CC 100))]
1409 [(set_attr "length" "2")])
1412 [(set (match_operand:SI 0 "register_operand" "")
1413 (minus:SI (match_operand:SI 2 "register_operand" "")
1414 (eq:SI (match_operand:SI 1 "register_operand" "")
1416 (clobber (reg:CC 100))]
1418 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1420 (set (match_dup 0) (minus:SI (match_dup 2)
1421 (geu:SI (reg:CC 100) (const_int 0))))]
1424 ;; We can also do GEU and LTU directly, but these operate after a compare.
1425 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1428 (define_insn "*sltu_insn"
1429 [(set (match_operand:SI 0 "register_operand" "=r")
1430 (ltu:SI (reg:CC 100) (const_int 0)))]
1432 "addx\\t%%g0, 0, %0"
1433 [(set_attr "type" "misc")])
1435 (define_insn "*neg_sltu_insn"
1436 [(set (match_operand:SI 0 "register_operand" "=r")
1437 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1439 "subx\\t%%g0, 0, %0"
1440 [(set_attr "type" "misc")])
1442 ;; ??? Combine should canonicalize these next two to the same pattern.
1443 (define_insn "*neg_sltu_minus_x"
1444 [(set (match_operand:SI 0 "register_operand" "=r")
1445 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1446 (match_operand:SI 1 "arith_operand" "rI")))]
1448 "subx\\t%%g0, %1, %0"
1449 [(set_attr "type" "misc")])
1451 (define_insn "*neg_sltu_plus_x"
1452 [(set (match_operand:SI 0 "register_operand" "=r")
1453 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1454 (match_operand:SI 1 "arith_operand" "rI"))))]
1456 "subx\\t%%g0, %1, %0"
1457 [(set_attr "type" "misc")])
1459 (define_insn "*sgeu_insn"
1460 [(set (match_operand:SI 0 "register_operand" "=r")
1461 (geu:SI (reg:CC 100) (const_int 0)))]
1463 "subx\\t%%g0, -1, %0"
1464 [(set_attr "type" "misc")])
1466 (define_insn "*neg_sgeu_insn"
1467 [(set (match_operand:SI 0 "register_operand" "=r")
1468 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1470 "addx\\t%%g0, -1, %0"
1471 [(set_attr "type" "misc")])
1473 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1474 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1477 (define_insn "*sltu_plus_x"
1478 [(set (match_operand:SI 0 "register_operand" "=r")
1479 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1480 (match_operand:SI 1 "arith_operand" "rI")))]
1482 "addx\\t%%g0, %1, %0"
1483 [(set_attr "type" "misc")])
1485 (define_insn "*sltu_plus_x_plus_y"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1488 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1489 (match_operand:SI 2 "arith_operand" "rI"))))]
1492 [(set_attr "type" "misc")])
1494 (define_insn "*x_minus_sltu"
1495 [(set (match_operand:SI 0 "register_operand" "=r")
1496 (minus:SI (match_operand:SI 1 "register_operand" "r")
1497 (ltu:SI (reg:CC 100) (const_int 0))))]
1500 [(set_attr "type" "misc")])
1502 ;; ??? Combine should canonicalize these next two to the same pattern.
1503 (define_insn "*x_minus_y_minus_sltu"
1504 [(set (match_operand:SI 0 "register_operand" "=r")
1505 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1506 (match_operand:SI 2 "arith_operand" "rI"))
1507 (ltu:SI (reg:CC 100) (const_int 0))))]
1509 "subx\\t%r1, %2, %0"
1510 [(set_attr "type" "misc")])
1512 (define_insn "*x_minus_sltu_plus_y"
1513 [(set (match_operand:SI 0 "register_operand" "=r")
1514 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1515 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1516 (match_operand:SI 2 "arith_operand" "rI"))))]
1518 "subx\\t%r1, %2, %0"
1519 [(set_attr "type" "misc")])
1521 (define_insn "*sgeu_plus_x"
1522 [(set (match_operand:SI 0 "register_operand" "=r")
1523 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1524 (match_operand:SI 1 "register_operand" "r")))]
1527 [(set_attr "type" "misc")])
1529 (define_insn "*x_minus_sgeu"
1530 [(set (match_operand:SI 0 "register_operand" "=r")
1531 (minus:SI (match_operand:SI 1 "register_operand" "r")
1532 (geu:SI (reg:CC 100) (const_int 0))))]
1535 [(set_attr "type" "misc")])
1538 [(set (match_operand:SI 0 "register_operand" "")
1539 (match_operator:SI 2 "noov_compare_op"
1540 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1542 ;; 32 bit LTU/GEU are better implemented using addx/subx
1543 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1544 && (GET_MODE (operands[1]) == CCXmode
1545 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1546 [(set (match_dup 0) (const_int 0))
1548 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1554 ;; These control RTL generation for conditional jump insns
1556 ;; The quad-word fp compare library routines all return nonzero to indicate
1557 ;; true, which is different from the equivalent libgcc routines, so we must
1558 ;; handle them specially here.
1560 (define_expand "beq"
1562 (if_then_else (eq (match_dup 1) (const_int 0))
1563 (label_ref (match_operand 0 "" ""))
1568 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1569 && GET_CODE (sparc_compare_op0) == REG
1570 && GET_MODE (sparc_compare_op0) == DImode)
1572 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1575 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1577 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1578 emit_jump_insn (gen_bne (operands[0]));
1581 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1584 (define_expand "bne"
1586 (if_then_else (ne (match_dup 1) (const_int 0))
1587 (label_ref (match_operand 0 "" ""))
1592 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1593 && GET_CODE (sparc_compare_op0) == REG
1594 && GET_MODE (sparc_compare_op0) == DImode)
1596 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1599 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1601 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1602 emit_jump_insn (gen_bne (operands[0]));
1605 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1608 (define_expand "bgt"
1610 (if_then_else (gt (match_dup 1) (const_int 0))
1611 (label_ref (match_operand 0 "" ""))
1616 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1617 && GET_CODE (sparc_compare_op0) == REG
1618 && GET_MODE (sparc_compare_op0) == DImode)
1620 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1623 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1625 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1626 emit_jump_insn (gen_bne (operands[0]));
1629 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1632 (define_expand "bgtu"
1634 (if_then_else (gtu (match_dup 1) (const_int 0))
1635 (label_ref (match_operand 0 "" ""))
1639 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1642 (define_expand "blt"
1644 (if_then_else (lt (match_dup 1) (const_int 0))
1645 (label_ref (match_operand 0 "" ""))
1650 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1651 && GET_CODE (sparc_compare_op0) == REG
1652 && GET_MODE (sparc_compare_op0) == DImode)
1654 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1657 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1659 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1660 emit_jump_insn (gen_bne (operands[0]));
1663 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1666 (define_expand "bltu"
1668 (if_then_else (ltu (match_dup 1) (const_int 0))
1669 (label_ref (match_operand 0 "" ""))
1673 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1676 (define_expand "bge"
1678 (if_then_else (ge (match_dup 1) (const_int 0))
1679 (label_ref (match_operand 0 "" ""))
1684 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1685 && GET_CODE (sparc_compare_op0) == REG
1686 && GET_MODE (sparc_compare_op0) == DImode)
1688 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1691 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1693 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1694 emit_jump_insn (gen_bne (operands[0]));
1697 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1700 (define_expand "bgeu"
1702 (if_then_else (geu (match_dup 1) (const_int 0))
1703 (label_ref (match_operand 0 "" ""))
1707 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1710 (define_expand "ble"
1712 (if_then_else (le (match_dup 1) (const_int 0))
1713 (label_ref (match_operand 0 "" ""))
1718 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1719 && GET_CODE (sparc_compare_op0) == REG
1720 && GET_MODE (sparc_compare_op0) == DImode)
1722 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1725 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1727 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1728 emit_jump_insn (gen_bne (operands[0]));
1731 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1734 (define_expand "bleu"
1736 (if_then_else (leu (match_dup 1) (const_int 0))
1737 (label_ref (match_operand 0 "" ""))
1741 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1744 (define_expand "bunordered"
1746 (if_then_else (unordered (match_dup 1) (const_int 0))
1747 (label_ref (match_operand 0 "" ""))
1752 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1754 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1756 emit_jump_insn (gen_beq (operands[0]));
1759 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1763 (define_expand "bordered"
1765 (if_then_else (ordered (match_dup 1) (const_int 0))
1766 (label_ref (match_operand 0 "" ""))
1771 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1773 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1774 emit_jump_insn (gen_bne (operands[0]));
1777 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1781 (define_expand "bungt"
1783 (if_then_else (ungt (match_dup 1) (const_int 0))
1784 (label_ref (match_operand 0 "" ""))
1789 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1791 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1792 emit_jump_insn (gen_bgt (operands[0]));
1795 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1798 (define_expand "bunlt"
1800 (if_then_else (unlt (match_dup 1) (const_int 0))
1801 (label_ref (match_operand 0 "" ""))
1806 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1808 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1809 emit_jump_insn (gen_bne (operands[0]));
1812 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1815 (define_expand "buneq"
1817 (if_then_else (uneq (match_dup 1) (const_int 0))
1818 (label_ref (match_operand 0 "" ""))
1823 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1825 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1826 emit_jump_insn (gen_beq (operands[0]));
1829 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1832 (define_expand "bunge"
1834 (if_then_else (unge (match_dup 1) (const_int 0))
1835 (label_ref (match_operand 0 "" ""))
1840 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1842 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1843 emit_jump_insn (gen_bne (operands[0]));
1846 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1849 (define_expand "bunle"
1851 (if_then_else (unle (match_dup 1) (const_int 0))
1852 (label_ref (match_operand 0 "" ""))
1857 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1859 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1860 emit_jump_insn (gen_bne (operands[0]));
1863 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1866 (define_expand "bltgt"
1868 (if_then_else (ltgt (match_dup 1) (const_int 0))
1869 (label_ref (match_operand 0 "" ""))
1874 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1876 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1877 emit_jump_insn (gen_bne (operands[0]));
1880 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1883 ;; Now match both normal and inverted jump.
1885 ;; XXX fpcmp nop braindamage
1886 (define_insn "*normal_branch"
1888 (if_then_else (match_operator 0 "noov_compare_op"
1889 [(reg 100) (const_int 0)])
1890 (label_ref (match_operand 1 "" ""))
1895 return output_cbranch (operands[0], 1, 0,
1896 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1897 ! final_sequence, insn);
1899 [(set_attr "type" "branch")])
1901 ;; XXX fpcmp nop braindamage
1902 (define_insn "*inverted_branch"
1904 (if_then_else (match_operator 0 "noov_compare_op"
1905 [(reg 100) (const_int 0)])
1907 (label_ref (match_operand 1 "" ""))))]
1911 return output_cbranch (operands[0], 1, 1,
1912 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1913 ! final_sequence, insn);
1915 [(set_attr "type" "branch")])
1917 ;; XXX fpcmp nop braindamage
1918 (define_insn "*normal_fp_branch"
1920 (if_then_else (match_operator 1 "comparison_operator"
1921 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1923 (label_ref (match_operand 2 "" ""))
1928 return output_cbranch (operands[1], 2, 0,
1929 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1930 ! final_sequence, insn);
1932 [(set_attr "type" "branch")])
1934 ;; XXX fpcmp nop braindamage
1935 (define_insn "*inverted_fp_branch"
1937 (if_then_else (match_operator 1 "comparison_operator"
1938 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1941 (label_ref (match_operand 2 "" ""))))]
1945 return output_cbranch (operands[1], 2, 1,
1946 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1947 ! final_sequence, insn);
1949 [(set_attr "type" "branch")])
1951 ;; XXX fpcmp nop braindamage
1952 (define_insn "*normal_fpe_branch"
1954 (if_then_else (match_operator 1 "comparison_operator"
1955 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1957 (label_ref (match_operand 2 "" ""))
1962 return output_cbranch (operands[1], 2, 0,
1963 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1964 ! final_sequence, insn);
1966 [(set_attr "type" "branch")])
1968 ;; XXX fpcmp nop braindamage
1969 (define_insn "*inverted_fpe_branch"
1971 (if_then_else (match_operator 1 "comparison_operator"
1972 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1975 (label_ref (match_operand 2 "" ""))))]
1979 return output_cbranch (operands[1], 2, 1,
1980 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1981 ! final_sequence, insn);
1983 [(set_attr "type" "branch")])
1985 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1986 ;; in the architecture.
1988 ;; There are no 32 bit brreg insns.
1991 (define_insn "*normal_int_branch_sp64"
1993 (if_then_else (match_operator 0 "v9_regcmp_op"
1994 [(match_operand:DI 1 "register_operand" "r")
1996 (label_ref (match_operand 2 "" ""))
2001 return output_v9branch (operands[0], 1, 2, 0,
2002 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2003 ! final_sequence, insn);
2005 [(set_attr "type" "branch")])
2008 (define_insn "*inverted_int_branch_sp64"
2010 (if_then_else (match_operator 0 "v9_regcmp_op"
2011 [(match_operand:DI 1 "register_operand" "r")
2014 (label_ref (match_operand 2 "" ""))))]
2018 return output_v9branch (operands[0], 1, 2, 1,
2019 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2020 ! final_sequence, insn);
2022 [(set_attr "type" "branch")])
2024 ;; Load program counter insns.
2026 (define_insn "get_pc"
2027 [(clobber (reg:SI 15))
2028 (set (match_operand 0 "register_operand" "=r")
2029 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2030 "flag_pic && REGNO (operands[0]) == 23"
2031 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2032 [(set_attr "type" "multi")
2033 (set_attr "length" "3")])
2035 ;; Currently unused...
2036 ;; (define_insn "get_pc_via_rdpc"
2037 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2040 ;; [(set_attr "type" "misc")])
2043 ;; Move instructions
2045 (define_expand "movqi"
2046 [(set (match_operand:QI 0 "general_operand" "")
2047 (match_operand:QI 1 "general_operand" ""))]
2051 /* Working with CONST_INTs is easier, so convert
2052 a double if needed. */
2053 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2055 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2057 else if (GET_CODE (operands[1]) == CONST_INT)
2059 /* And further, we know for all QI cases that only the
2060 low byte is significant, which we can always process
2061 in a single insn. So mask it now. */
2062 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2065 /* Handle sets of MEM first. */
2066 if (GET_CODE (operands[0]) == MEM)
2068 if (reg_or_0_operand (operands[1], QImode))
2071 if (! reload_in_progress)
2073 operands[0] = validize_mem (operands[0]);
2074 operands[1] = force_reg (QImode, operands[1]);
2078 /* Fixup PIC cases. */
2081 if (CONSTANT_P (operands[1])
2082 && pic_address_needs_scratch (operands[1]))
2083 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2085 if (symbolic_operand (operands[1], QImode))
2087 operands[1] = legitimize_pic_address (operands[1],
2089 (reload_in_progress ?
2096 /* All QI constants require only one insn, so proceed. */
2102 (define_insn "*movqi_insn"
2103 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2104 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2105 "(register_operand (operands[0], QImode)
2106 || reg_or_0_operand (operands[1], QImode))"
2111 [(set_attr "type" "*,load,store")])
2113 (define_expand "movhi"
2114 [(set (match_operand:HI 0 "general_operand" "")
2115 (match_operand:HI 1 "general_operand" ""))]
2119 /* Working with CONST_INTs is easier, so convert
2120 a double if needed. */
2121 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2122 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2124 /* Handle sets of MEM first. */
2125 if (GET_CODE (operands[0]) == MEM)
2127 if (reg_or_0_operand (operands[1], HImode))
2130 if (! reload_in_progress)
2132 operands[0] = validize_mem (operands[0]);
2133 operands[1] = force_reg (HImode, operands[1]);
2137 /* Fixup PIC cases. */
2140 if (CONSTANT_P (operands[1])
2141 && pic_address_needs_scratch (operands[1]))
2142 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2144 if (symbolic_operand (operands[1], HImode))
2146 operands[1] = legitimize_pic_address (operands[1],
2148 (reload_in_progress ?
2155 /* This makes sure we will not get rematched due to splittage. */
2156 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2158 else if (CONSTANT_P (operands[1])
2159 && GET_CODE (operands[1]) != HIGH
2160 && GET_CODE (operands[1]) != LO_SUM)
2162 sparc_emit_set_const32 (operands[0], operands[1]);
2169 (define_insn "*movhi_const64_special"
2170 [(set (match_operand:HI 0 "register_operand" "=r")
2171 (match_operand:HI 1 "const64_high_operand" ""))]
2173 "sethi\\t%%hi(%a1), %0")
2175 (define_insn "*movhi_insn"
2176 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2177 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2178 "(register_operand (operands[0], HImode)
2179 || reg_or_0_operand (operands[1], HImode))"
2182 sethi\\t%%hi(%a1), %0
2185 [(set_attr "type" "*,*,load,store")])
2187 ;; We always work with constants here.
2188 (define_insn "*movhi_lo_sum"
2189 [(set (match_operand:HI 0 "register_operand" "=r")
2190 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2191 (match_operand:HI 2 "arith_operand" "I")))]
2195 (define_expand "movsi"
2196 [(set (match_operand:SI 0 "general_operand" "")
2197 (match_operand:SI 1 "general_operand" ""))]
2201 /* Working with CONST_INTs is easier, so convert
2202 a double if needed. */
2203 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2204 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2206 /* Handle sets of MEM first. */
2207 if (GET_CODE (operands[0]) == MEM)
2209 if (reg_or_0_operand (operands[1], SImode))
2212 if (! reload_in_progress)
2214 operands[0] = validize_mem (operands[0]);
2215 operands[1] = force_reg (SImode, operands[1]);
2219 /* Fixup PIC cases. */
2222 if (CONSTANT_P (operands[1])
2223 && pic_address_needs_scratch (operands[1]))
2224 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2226 if (GET_CODE (operands[1]) == LABEL_REF)
2229 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2233 if (symbolic_operand (operands[1], SImode))
2235 operands[1] = legitimize_pic_address (operands[1],
2237 (reload_in_progress ?
2244 /* If we are trying to toss an integer constant into the
2245 FPU registers, force it into memory. */
2246 if (GET_CODE (operands[0]) == REG
2247 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2248 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2249 && CONSTANT_P (operands[1]))
2250 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2253 /* This makes sure we will not get rematched due to splittage. */
2254 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2256 else if (CONSTANT_P (operands[1])
2257 && GET_CODE (operands[1]) != HIGH
2258 && GET_CODE (operands[1]) != LO_SUM)
2260 sparc_emit_set_const32 (operands[0], operands[1]);
2267 ;; This is needed to show CSE exactly which bits are set
2268 ;; in a 64-bit register by sethi instructions.
2269 (define_insn "*movsi_const64_special"
2270 [(set (match_operand:SI 0 "register_operand" "=r")
2271 (match_operand:SI 1 "const64_high_operand" ""))]
2273 "sethi\\t%%hi(%a1), %0")
2275 (define_insn "*movsi_insn"
2276 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2277 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2278 "(register_operand (operands[0], SImode)
2279 || reg_or_0_operand (operands[1], SImode))"
2283 sethi\\t%%hi(%a1), %0
2290 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2292 (define_insn "*movsi_lo_sum"
2293 [(set (match_operand:SI 0 "register_operand" "=r")
2294 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2295 (match_operand:SI 2 "immediate_operand" "in")))]
2297 "or\\t%1, %%lo(%a2), %0")
2299 (define_insn "*movsi_high"
2300 [(set (match_operand:SI 0 "register_operand" "=r")
2301 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2303 "sethi\\t%%hi(%a1), %0")
2305 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2306 ;; so that CSE won't optimize the address computation away.
2307 (define_insn "movsi_lo_sum_pic"
2308 [(set (match_operand:SI 0 "register_operand" "=r")
2309 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2310 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2312 "or\\t%1, %%lo(%a2), %0")
2314 (define_insn "movsi_high_pic"
2315 [(set (match_operand:SI 0 "register_operand" "=r")
2316 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2317 "flag_pic && check_pic (1)"
2318 "sethi\\t%%hi(%a1), %0")
2320 (define_expand "movsi_pic_label_ref"
2321 [(set (match_dup 3) (high:SI
2322 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2324 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2325 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2326 (set (match_operand:SI 0 "register_operand" "=r")
2327 (minus:SI (match_dup 5) (match_dup 4)))]
2331 current_function_uses_pic_offset_table = 1;
2332 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2335 operands[3] = operands[0];
2336 operands[4] = operands[0];
2340 operands[3] = gen_reg_rtx (SImode);
2341 operands[4] = gen_reg_rtx (SImode);
2343 operands[5] = pic_offset_table_rtx;
2346 (define_insn "*movsi_high_pic_label_ref"
2347 [(set (match_operand:SI 0 "register_operand" "=r")
2349 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2350 (match_operand:SI 2 "" "")] 5)))]
2352 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2354 (define_insn "*movsi_lo_sum_pic_label_ref"
2355 [(set (match_operand:SI 0 "register_operand" "=r")
2356 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2357 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2358 (match_operand:SI 3 "" "")] 5)))]
2360 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2362 (define_expand "movdi"
2363 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2364 (match_operand:DI 1 "general_operand" ""))]
2368 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2369 if (GET_CODE (operands[1]) == CONST_DOUBLE
2370 #if HOST_BITS_PER_WIDE_INT == 32
2371 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2372 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2373 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2374 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2377 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2379 /* Handle MEM cases first. */
2380 if (GET_CODE (operands[0]) == MEM)
2382 /* If it's a REG, we can always do it.
2383 The const zero case is more complex, on v9
2384 we can always perform it. */
2385 if (register_operand (operands[1], DImode)
2387 && (operands[1] == const0_rtx)))
2390 if (! reload_in_progress)
2392 operands[0] = validize_mem (operands[0]);
2393 operands[1] = force_reg (DImode, operands[1]);
2399 if (CONSTANT_P (operands[1])
2400 && pic_address_needs_scratch (operands[1]))
2401 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2403 if (GET_CODE (operands[1]) == LABEL_REF)
2405 if (! TARGET_ARCH64)
2407 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2411 if (symbolic_operand (operands[1], DImode))
2413 operands[1] = legitimize_pic_address (operands[1],
2415 (reload_in_progress ?
2422 /* If we are trying to toss an integer constant into the
2423 FPU registers, force it into memory. */
2424 if (GET_CODE (operands[0]) == REG
2425 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2426 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2427 && CONSTANT_P (operands[1]))
2428 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2431 /* This makes sure we will not get rematched due to splittage. */
2432 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2434 else if (TARGET_ARCH64
2435 && CONSTANT_P (operands[1])
2436 && GET_CODE (operands[1]) != HIGH
2437 && GET_CODE (operands[1]) != LO_SUM)
2439 sparc_emit_set_const64 (operands[0], operands[1]);
2447 ;; Be careful, fmovd does not exist when !arch64.
2448 ;; We match MEM moves directly when we have correct even
2449 ;; numbered registers, but fall into splits otherwise.
2450 ;; The constraint ordering here is really important to
2451 ;; avoid insane problems in reload, especially for patterns
2454 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2455 ;; (const_int -5016)))
2458 (define_insn "*movdi_insn_sp32"
2459 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2460 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2462 (register_operand (operands[0], DImode)
2463 || register_operand (operands[1], DImode))"
2476 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2477 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2479 ;; The following are generated by sparc_emit_set_const64
2480 (define_insn "*movdi_sp64_dbl"
2481 [(set (match_operand:DI 0 "register_operand" "=r")
2482 (match_operand:DI 1 "const64_operand" ""))]
2484 && HOST_BITS_PER_WIDE_INT != 64)"
2487 ;; This is needed to show CSE exactly which bits are set
2488 ;; in a 64-bit register by sethi instructions.
2489 (define_insn "*movdi_const64_special"
2490 [(set (match_operand:DI 0 "register_operand" "=r")
2491 (match_operand:DI 1 "const64_high_operand" ""))]
2493 "sethi\\t%%hi(%a1), %0")
2495 (define_insn "*movdi_insn_sp64_novis"
2496 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2497 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2498 "TARGET_ARCH64 && ! TARGET_VIS
2499 && (register_operand (operands[0], DImode)
2500 || reg_or_0_operand (operands[1], DImode))"
2503 sethi\\t%%hi(%a1), %0
2510 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2511 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2513 (define_insn "*movdi_insn_sp64_vis"
2514 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2515 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2516 "TARGET_ARCH64 && TARGET_VIS &&
2517 (register_operand (operands[0], DImode)
2518 || reg_or_0_operand (operands[1], DImode))"
2521 sethi\\t%%hi(%a1), %0
2529 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2530 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2532 (define_expand "movdi_pic_label_ref"
2533 [(set (match_dup 3) (high:DI
2534 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2536 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2537 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2538 (set (match_operand:DI 0 "register_operand" "=r")
2539 (minus:DI (match_dup 5) (match_dup 4)))]
2540 "TARGET_ARCH64 && flag_pic"
2543 current_function_uses_pic_offset_table = 1;
2544 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2547 operands[3] = operands[0];
2548 operands[4] = operands[0];
2552 operands[3] = gen_reg_rtx (DImode);
2553 operands[4] = gen_reg_rtx (DImode);
2555 operands[5] = pic_offset_table_rtx;
2558 (define_insn "*movdi_high_pic_label_ref"
2559 [(set (match_operand:DI 0 "register_operand" "=r")
2561 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2562 (match_operand:DI 2 "" "")] 5)))]
2563 "TARGET_ARCH64 && flag_pic"
2564 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2566 (define_insn "*movdi_lo_sum_pic_label_ref"
2567 [(set (match_operand:DI 0 "register_operand" "=r")
2568 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2569 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2570 (match_operand:DI 3 "" "")] 5)))]
2571 "TARGET_ARCH64 && flag_pic"
2572 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2574 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2575 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2577 (define_insn "movdi_lo_sum_pic"
2578 [(set (match_operand:DI 0 "register_operand" "=r")
2579 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2580 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2581 "TARGET_ARCH64 && flag_pic"
2582 "or\\t%1, %%lo(%a2), %0")
2584 (define_insn "movdi_high_pic"
2585 [(set (match_operand:DI 0 "register_operand" "=r")
2586 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2587 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2588 "sethi\\t%%hi(%a1), %0")
2590 (define_insn "*sethi_di_medlow_embmedany_pic"
2591 [(set (match_operand:DI 0 "register_operand" "=r")
2592 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2593 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2594 "sethi\\t%%hi(%a1), %0")
2596 (define_insn "*sethi_di_medlow"
2597 [(set (match_operand:DI 0 "register_operand" "=r")
2598 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2599 "TARGET_CM_MEDLOW && check_pic (1)"
2600 "sethi\\t%%hi(%a1), %0")
2602 (define_insn "*losum_di_medlow"
2603 [(set (match_operand:DI 0 "register_operand" "=r")
2604 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2605 (match_operand:DI 2 "symbolic_operand" "")))]
2607 "or\\t%1, %%lo(%a2), %0")
2609 (define_insn "seth44"
2610 [(set (match_operand:DI 0 "register_operand" "=r")
2611 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2613 "sethi\\t%%h44(%a1), %0")
2615 (define_insn "setm44"
2616 [(set (match_operand:DI 0 "register_operand" "=r")
2617 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2618 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2620 "or\\t%1, %%m44(%a2), %0")
2622 (define_insn "setl44"
2623 [(set (match_operand:DI 0 "register_operand" "=r")
2624 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2625 (match_operand:DI 2 "symbolic_operand" "")))]
2627 "or\\t%1, %%l44(%a2), %0")
2629 (define_insn "sethh"
2630 [(set (match_operand:DI 0 "register_operand" "=r")
2631 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2633 "sethi\\t%%hh(%a1), %0")
2635 (define_insn "setlm"
2636 [(set (match_operand:DI 0 "register_operand" "=r")
2637 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2639 "sethi\\t%%lm(%a1), %0")
2641 (define_insn "sethm"
2642 [(set (match_operand:DI 0 "register_operand" "=r")
2643 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2644 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2646 "or\\t%1, %%hm(%a2), %0")
2648 (define_insn "setlo"
2649 [(set (match_operand:DI 0 "register_operand" "=r")
2650 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2651 (match_operand:DI 2 "symbolic_operand" "")))]
2653 "or\\t%1, %%lo(%a2), %0")
2655 (define_insn "embmedany_sethi"
2656 [(set (match_operand:DI 0 "register_operand" "=r")
2657 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2658 "TARGET_CM_EMBMEDANY && check_pic (1)"
2659 "sethi\\t%%hi(%a1), %0")
2661 (define_insn "embmedany_losum"
2662 [(set (match_operand:DI 0 "register_operand" "=r")
2663 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2664 (match_operand:DI 2 "data_segment_operand" "")))]
2665 "TARGET_CM_EMBMEDANY"
2666 "add\\t%1, %%lo(%a2), %0")
2668 (define_insn "embmedany_brsum"
2669 [(set (match_operand:DI 0 "register_operand" "=r")
2670 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2671 "TARGET_CM_EMBMEDANY"
2674 (define_insn "embmedany_textuhi"
2675 [(set (match_operand:DI 0 "register_operand" "=r")
2676 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2677 "TARGET_CM_EMBMEDANY && check_pic (1)"
2678 "sethi\\t%%uhi(%a1), %0")
2680 (define_insn "embmedany_texthi"
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2683 "TARGET_CM_EMBMEDANY && check_pic (1)"
2684 "sethi\\t%%hi(%a1), %0")
2686 (define_insn "embmedany_textulo"
2687 [(set (match_operand:DI 0 "register_operand" "=r")
2688 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2689 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2690 "TARGET_CM_EMBMEDANY"
2691 "or\\t%1, %%ulo(%a2), %0")
2693 (define_insn "embmedany_textlo"
2694 [(set (match_operand:DI 0 "register_operand" "=r")
2695 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2696 (match_operand:DI 2 "text_segment_operand" "")))]
2697 "TARGET_CM_EMBMEDANY"
2698 "or\\t%1, %%lo(%a2), %0")
2700 ;; Now some patterns to help reload out a bit.
2701 (define_expand "reload_indi"
2702 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2703 (match_operand:DI 1 "immediate_operand" "")
2704 (match_operand:TI 2 "register_operand" "=&r")])]
2706 || TARGET_CM_EMBMEDANY)
2710 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2711 gen_rtx_REG (DImode, REGNO (operands[2])));
2715 (define_expand "reload_outdi"
2716 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2717 (match_operand:DI 1 "immediate_operand" "")
2718 (match_operand:TI 2 "register_operand" "=&r")])]
2720 || TARGET_CM_EMBMEDANY)
2724 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2725 gen_rtx_REG (DImode, REGNO (operands[2])));
2729 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2731 [(set (match_operand:DI 0 "register_operand" "")
2732 (match_operand:DI 1 "const_int_operand" ""))]
2733 "! TARGET_ARCH64 && reload_completed"
2734 [(clobber (const_int 0))]
2737 #if HOST_BITS_PER_WIDE_INT == 32
2738 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2739 (INTVAL (operands[1]) < 0) ?
2742 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2745 unsigned int low, high;
2747 low = INTVAL (operands[1]) & 0xffffffff;
2748 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2749 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2751 /* Slick... but this trick loses if this subreg constant part
2752 can be done in one insn. */
2753 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2754 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2755 gen_highpart (SImode, operands[0])));
2757 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2763 [(set (match_operand:DI 0 "register_operand" "")
2764 (match_operand:DI 1 "const_double_operand" ""))]
2765 "! TARGET_ARCH64 && reload_completed"
2766 [(clobber (const_int 0))]
2769 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2770 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2772 /* Slick... but this trick loses if this subreg constant part
2773 can be done in one insn. */
2774 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2775 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2776 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2778 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2779 gen_highpart (SImode, operands[0])));
2783 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2784 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2790 [(set (match_operand:DI 0 "register_operand" "")
2791 (match_operand:DI 1 "register_operand" ""))]
2792 "! TARGET_ARCH64 && reload_completed"
2793 [(clobber (const_int 0))]
2796 rtx set_dest = operands[0];
2797 rtx set_src = operands[1];
2801 if (GET_CODE (set_dest) == SUBREG)
2802 set_dest = alter_subreg (set_dest);
2803 if (GET_CODE (set_src) == SUBREG)
2804 set_src = alter_subreg (set_src);
2806 dest1 = gen_highpart (SImode, set_dest);
2807 dest2 = gen_lowpart (SImode, set_dest);
2808 src1 = gen_highpart (SImode, set_src);
2809 src2 = gen_lowpart (SImode, set_src);
2811 /* Now emit using the real source and destination we found, swapping
2812 the order if we detect overlap. */
2813 if (reg_overlap_mentioned_p (dest1, src2))
2815 emit_insn (gen_movsi (dest2, src2));
2816 emit_insn (gen_movsi (dest1, src1));
2820 emit_insn (gen_movsi (dest1, src1));
2821 emit_insn (gen_movsi (dest2, src2));
2826 ;; Now handle the cases of memory moves from/to non-even
2827 ;; DI mode register pairs.
2829 [(set (match_operand:DI 0 "register_operand" "")
2830 (match_operand:DI 1 "memory_operand" ""))]
2833 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2834 [(clobber (const_int 0))]
2837 rtx word0 = adjust_address (operands[1], SImode, 0);
2838 rtx word1 = adjust_address (operands[1], SImode, 4);
2839 rtx high_part = gen_highpart (SImode, operands[0]);
2840 rtx low_part = gen_lowpart (SImode, operands[0]);
2842 if (reg_overlap_mentioned_p (high_part, word1))
2844 emit_insn (gen_movsi (low_part, word1));
2845 emit_insn (gen_movsi (high_part, word0));
2849 emit_insn (gen_movsi (high_part, word0));
2850 emit_insn (gen_movsi (low_part, word1));
2856 [(set (match_operand:DI 0 "memory_operand" "")
2857 (match_operand:DI 1 "register_operand" ""))]
2860 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2861 [(clobber (const_int 0))]
2864 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2865 gen_highpart (SImode, operands[1])));
2866 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2867 gen_lowpart (SImode, operands[1])));
2872 ;; Floating point move insns
2874 (define_insn "*movsf_insn_novis"
2875 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2876 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2877 "(TARGET_FPU && ! TARGET_VIS)
2878 && (register_operand (operands[0], SFmode)
2879 || register_operand (operands[1], SFmode)
2880 || fp_zero_operand (operands[1], SFmode))"
2883 if (GET_CODE (operands[1]) == CONST_DOUBLE
2884 && (which_alternative == 2
2885 || which_alternative == 3
2886 || which_alternative == 4))
2891 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2892 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2893 operands[1] = GEN_INT (i);
2896 switch (which_alternative)
2899 return \"fmovs\\t%1, %0\";
2901 return \"clr\\t%0\";
2903 return \"sethi\\t%%hi(%a1), %0\";
2905 return \"mov\\t%1, %0\";
2910 return \"ld\\t%1, %0\";
2913 return \"st\\t%r1, %0\";
2918 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2920 (define_insn "*movsf_insn_vis"
2921 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2922 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2923 "(TARGET_FPU && TARGET_VIS)
2924 && (register_operand (operands[0], SFmode)
2925 || register_operand (operands[1], SFmode)
2926 || fp_zero_operand (operands[1], SFmode))"
2929 if (GET_CODE (operands[1]) == CONST_DOUBLE
2930 && (which_alternative == 3
2931 || which_alternative == 4
2932 || which_alternative == 5))
2937 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2938 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2939 operands[1] = GEN_INT (i);
2942 switch (which_alternative)
2945 return \"fmovs\\t%1, %0\";
2947 return \"fzeros\\t%0\";
2949 return \"clr\\t%0\";
2951 return \"sethi\\t%%hi(%a1), %0\";
2953 return \"mov\\t%1, %0\";
2958 return \"ld\\t%1, %0\";
2961 return \"st\\t%r1, %0\";
2966 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2968 ;; Exactly the same as above, except that all `f' cases are deleted.
2969 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2972 (define_insn "*movsf_no_f_insn"
2973 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2974 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2976 && (register_operand (operands[0], SFmode)
2977 || register_operand (operands[1], SFmode)
2978 || fp_zero_operand (operands[1], SFmode))"
2981 if (GET_CODE (operands[1]) == CONST_DOUBLE
2982 && (which_alternative == 1
2983 || which_alternative == 2
2984 || which_alternative == 3))
2989 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2990 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2991 operands[1] = GEN_INT (i);
2994 switch (which_alternative)
2997 return \"clr\\t%0\";
2999 return \"sethi\\t%%hi(%a1), %0\";
3001 return \"mov\\t%1, %0\";
3005 return \"ld\\t%1, %0\";
3007 return \"st\\t%r1, %0\";
3012 [(set_attr "type" "*,*,*,*,load,store")])
3014 (define_insn "*movsf_lo_sum"
3015 [(set (match_operand:SF 0 "register_operand" "=r")
3016 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3017 (match_operand:SF 2 "const_double_operand" "S")))]
3018 "fp_high_losum_p (operands[2])"
3024 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3025 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3026 operands[2] = GEN_INT (i);
3027 return \"or\\t%1, %%lo(%a2), %0\";
3030 (define_insn "*movsf_high"
3031 [(set (match_operand:SF 0 "register_operand" "=r")
3032 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3033 "fp_high_losum_p (operands[1])"
3039 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3040 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3041 operands[1] = GEN_INT (i);
3042 return \"sethi\\t%%hi(%1), %0\";
3046 [(set (match_operand:SF 0 "register_operand" "")
3047 (match_operand:SF 1 "const_double_operand" ""))]
3048 "fp_high_losum_p (operands[1])
3049 && (GET_CODE (operands[0]) == REG
3050 && REGNO (operands[0]) < 32)"
3051 [(set (match_dup 0) (high:SF (match_dup 1)))
3052 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3054 (define_expand "movsf"
3055 [(set (match_operand:SF 0 "general_operand" "")
3056 (match_operand:SF 1 "general_operand" ""))]
3060 /* Force SFmode constants into memory. */
3061 if (GET_CODE (operands[0]) == REG
3062 && CONSTANT_P (operands[1]))
3064 /* emit_group_store will send such bogosity to us when it is
3065 not storing directly into memory. So fix this up to avoid
3066 crashes in output_constant_pool. */
3067 if (operands [1] == const0_rtx)
3068 operands[1] = CONST0_RTX (SFmode);
3070 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3073 /* We are able to build any SF constant in integer registers
3074 with at most 2 instructions. */
3075 if (REGNO (operands[0]) < 32)
3078 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3082 /* Handle sets of MEM first. */
3083 if (GET_CODE (operands[0]) == MEM)
3085 if (register_operand (operands[1], SFmode)
3086 || fp_zero_operand (operands[1], SFmode))
3089 if (! reload_in_progress)
3091 operands[0] = validize_mem (operands[0]);
3092 operands[1] = force_reg (SFmode, operands[1]);
3096 /* Fixup PIC cases. */
3099 if (CONSTANT_P (operands[1])
3100 && pic_address_needs_scratch (operands[1]))
3101 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3103 if (symbolic_operand (operands[1], SFmode))
3105 operands[1] = legitimize_pic_address (operands[1],
3107 (reload_in_progress ?
3117 (define_expand "movdf"
3118 [(set (match_operand:DF 0 "general_operand" "")
3119 (match_operand:DF 1 "general_operand" ""))]
3123 /* Force DFmode constants into memory. */
3124 if (GET_CODE (operands[0]) == REG
3125 && CONSTANT_P (operands[1]))
3127 /* emit_group_store will send such bogosity to us when it is
3128 not storing directly into memory. So fix this up to avoid
3129 crashes in output_constant_pool. */
3130 if (operands [1] == const0_rtx)
3131 operands[1] = CONST0_RTX (DFmode);
3133 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3134 && fp_zero_operand (operands[1], DFmode))
3137 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3141 /* Handle MEM cases first. */
3142 if (GET_CODE (operands[0]) == MEM)
3144 if (register_operand (operands[1], DFmode)
3145 || fp_zero_operand (operands[1], DFmode))
3148 if (! reload_in_progress)
3150 operands[0] = validize_mem (operands[0]);
3151 operands[1] = force_reg (DFmode, operands[1]);
3155 /* Fixup PIC cases. */
3158 if (CONSTANT_P (operands[1])
3159 && pic_address_needs_scratch (operands[1]))
3160 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3162 if (symbolic_operand (operands[1], DFmode))
3164 operands[1] = legitimize_pic_address (operands[1],
3166 (reload_in_progress ?
3176 ;; Be careful, fmovd does not exist when !v9.
3177 (define_insn "*movdf_insn_sp32"
3178 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3179 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3182 && (register_operand (operands[0], DFmode)
3183 || register_operand (operands[1], DFmode)
3184 || fp_zero_operand (operands[1], DFmode))"
3196 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3197 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3199 (define_insn "*movdf_no_e_insn_sp32"
3200 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3201 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3205 && (register_operand (operands[0], DFmode)
3206 || register_operand (operands[1], DFmode)
3207 || fp_zero_operand (operands[1], DFmode))"
3214 [(set_attr "type" "load,store,*,*,*")
3215 (set_attr "length" "*,*,2,2,2")])
3217 (define_insn "*movdf_no_e_insn_v9_sp32"
3218 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3219 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3223 && (register_operand (operands[0], DFmode)
3224 || register_operand (operands[1], DFmode)
3225 || fp_zero_operand (operands[1], DFmode))"
3232 [(set_attr "type" "load,store,store,*,*")
3233 (set_attr "length" "*,*,*,2,2")])
3235 ;; We have available v9 double floats but not 64-bit
3236 ;; integer registers and no VIS.
3237 (define_insn "*movdf_insn_v9only_novis"
3238 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3239 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3244 && (register_operand (operands[0], DFmode)
3245 || register_operand (operands[1], DFmode)
3246 || fp_zero_operand (operands[1], DFmode))"
3257 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3258 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3259 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3261 ;; We have available v9 double floats but not 64-bit
3262 ;; integer registers but we have VIS.
3263 (define_insn "*movdf_insn_v9only_vis"
3264 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3265 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3269 && (register_operand (operands[0], DFmode)
3270 || register_operand (operands[1], DFmode)
3271 || fp_zero_operand (operands[1], DFmode))"
3283 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3284 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3285 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3287 ;; We have available both v9 double floats and 64-bit
3288 ;; integer registers. No VIS though.
3289 (define_insn "*movdf_insn_sp64_novis"
3290 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3291 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3295 && (register_operand (operands[0], DFmode)
3296 || register_operand (operands[1], DFmode)
3297 || fp_zero_operand (operands[1], DFmode))"
3306 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3307 (set_attr "length" "*,*,*,*,*,*,2")
3308 (set_attr "fptype" "double,*,*,*,*,*,*")])
3310 ;; We have available both v9 double floats and 64-bit
3311 ;; integer registers. And we have VIS.
3312 (define_insn "*movdf_insn_sp64_vis"
3313 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3314 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3318 && (register_operand (operands[0], DFmode)
3319 || register_operand (operands[1], DFmode)
3320 || fp_zero_operand (operands[1], DFmode))"
3330 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3331 (set_attr "length" "*,*,*,*,*,*,*,2")
3332 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3334 (define_insn "*movdf_no_e_insn_sp64"
3335 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3336 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3339 && (register_operand (operands[0], DFmode)
3340 || register_operand (operands[1], DFmode)
3341 || fp_zero_operand (operands[1], DFmode))"
3346 [(set_attr "type" "*,load,store")])
3349 [(set (match_operand:DF 0 "register_operand" "")
3350 (match_operand:DF 1 "const_double_operand" ""))]
3352 && (GET_CODE (operands[0]) == REG
3353 && REGNO (operands[0]) < 32)
3354 && ! fp_zero_operand(operands[1], DFmode)
3355 && reload_completed"
3356 [(clobber (const_int 0))]
3362 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3363 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3364 if (GET_CODE (operands[0]) == SUBREG)
3365 operands[0] = alter_subreg (operands[0]);
3366 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3370 #if HOST_BITS_PER_WIDE_INT == 64
3373 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3374 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3375 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3377 emit_insn (gen_movdi (operands[0],
3378 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3384 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3387 /* Slick... but this trick loses if this subreg constant part
3388 can be done in one insn. */
3390 && !(SPARC_SETHI_P (l[0])
3391 || SPARC_SIMM13_P (l[0])))
3393 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3394 gen_highpart (SImode, operands[0])));
3398 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3405 ;; Ok, now the splits to handle all the multi insn and
3406 ;; mis-aligned memory address cases.
3407 ;; In these splits please take note that we must be
3408 ;; careful when V9 but not ARCH64 because the integer
3409 ;; register DFmode cases must be handled.
3411 [(set (match_operand:DF 0 "register_operand" "")
3412 (match_operand:DF 1 "register_operand" ""))]
3415 && ((GET_CODE (operands[0]) == REG
3416 && REGNO (operands[0]) < 32)
3417 || (GET_CODE (operands[0]) == SUBREG
3418 && GET_CODE (SUBREG_REG (operands[0])) == REG
3419 && REGNO (SUBREG_REG (operands[0])) < 32))))
3420 && reload_completed"
3421 [(clobber (const_int 0))]
3424 rtx set_dest = operands[0];
3425 rtx set_src = operands[1];
3429 if (GET_CODE (set_dest) == SUBREG)
3430 set_dest = alter_subreg (set_dest);
3431 if (GET_CODE (set_src) == SUBREG)
3432 set_src = alter_subreg (set_src);
3434 dest1 = gen_highpart (SFmode, set_dest);
3435 dest2 = gen_lowpart (SFmode, set_dest);
3436 src1 = gen_highpart (SFmode, set_src);
3437 src2 = gen_lowpart (SFmode, set_src);
3439 /* Now emit using the real source and destination we found, swapping
3440 the order if we detect overlap. */
3441 if (reg_overlap_mentioned_p (dest1, src2))
3443 emit_insn (gen_movsf (dest2, src2));
3444 emit_insn (gen_movsf (dest1, src1));
3448 emit_insn (gen_movsf (dest1, src1));
3449 emit_insn (gen_movsf (dest2, src2));
3455 [(set (match_operand:DF 0 "register_operand" "")
3456 (match_operand:DF 1 "memory_operand" ""))]
3459 && (((REGNO (operands[0]) % 2) != 0)
3460 || ! mem_min_alignment (operands[1], 8))
3461 && offsettable_memref_p (operands[1])"
3462 [(clobber (const_int 0))]
3465 rtx word0 = adjust_address (operands[1], SFmode, 0);
3466 rtx word1 = adjust_address (operands[1], SFmode, 4);
3468 if (GET_CODE (operands[0]) == SUBREG)
3469 operands[0] = alter_subreg (operands[0]);
3471 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3473 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3475 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3480 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3482 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3489 [(set (match_operand:DF 0 "memory_operand" "")
3490 (match_operand:DF 1 "register_operand" ""))]
3493 && (((REGNO (operands[1]) % 2) != 0)
3494 || ! mem_min_alignment (operands[0], 8))
3495 && offsettable_memref_p (operands[0])"
3496 [(clobber (const_int 0))]
3499 rtx word0 = adjust_address (operands[0], SFmode, 0);
3500 rtx word1 = adjust_address (operands[0], SFmode, 4);
3502 if (GET_CODE (operands[1]) == SUBREG)
3503 operands[1] = alter_subreg (operands[1]);
3504 emit_insn (gen_movsf (word0,
3505 gen_highpart (SFmode, operands[1])));
3506 emit_insn (gen_movsf (word1,
3507 gen_lowpart (SFmode, operands[1])));
3512 [(set (match_operand:DF 0 "memory_operand" "")
3513 (match_operand:DF 1 "fp_zero_operand" ""))]
3517 && ! mem_min_alignment (operands[0], 8)))
3518 && offsettable_memref_p (operands[0])"
3519 [(clobber (const_int 0))]
3524 dest1 = adjust_address (operands[0], SFmode, 0);
3525 dest2 = adjust_address (operands[0], SFmode, 4);
3527 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3528 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3533 [(set (match_operand:DF 0 "register_operand" "")
3534 (match_operand:DF 1 "fp_zero_operand" ""))]
3537 && ((GET_CODE (operands[0]) == REG
3538 && REGNO (operands[0]) < 32)
3539 || (GET_CODE (operands[0]) == SUBREG
3540 && GET_CODE (SUBREG_REG (operands[0])) == REG
3541 && REGNO (SUBREG_REG (operands[0])) < 32))"
3542 [(clobber (const_int 0))]
3545 rtx set_dest = operands[0];
3548 if (GET_CODE (set_dest) == SUBREG)
3549 set_dest = alter_subreg (set_dest);
3550 dest1 = gen_highpart (SFmode, set_dest);
3551 dest2 = gen_lowpart (SFmode, set_dest);
3552 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3553 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3557 (define_expand "movtf"
3558 [(set (match_operand:TF 0 "general_operand" "")
3559 (match_operand:TF 1 "general_operand" ""))]
3563 /* Force TFmode constants into memory. */
3564 if (GET_CODE (operands[0]) == REG
3565 && CONSTANT_P (operands[1]))
3567 /* emit_group_store will send such bogosity to us when it is
3568 not storing directly into memory. So fix this up to avoid
3569 crashes in output_constant_pool. */
3570 if (operands [1] == const0_rtx)
3571 operands[1] = CONST0_RTX (TFmode);
3573 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3576 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3580 /* Handle MEM cases first, note that only v9 guarentees
3581 full 16-byte alignment for quads. */
3582 if (GET_CODE (operands[0]) == MEM)
3584 if (register_operand (operands[1], TFmode)
3585 || fp_zero_operand (operands[1], TFmode))
3588 if (! reload_in_progress)
3590 operands[0] = validize_mem (operands[0]);
3591 operands[1] = force_reg (TFmode, operands[1]);
3595 /* Fixup PIC cases. */
3598 if (CONSTANT_P (operands[1])
3599 && pic_address_needs_scratch (operands[1]))
3600 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3602 if (symbolic_operand (operands[1], TFmode))
3604 operands[1] = legitimize_pic_address (operands[1],
3606 (reload_in_progress ?
3616 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3617 ;; we must split them all. :-(
3618 (define_insn "*movtf_insn_sp32"
3619 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3620 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3624 && (register_operand (operands[0], TFmode)
3625 || register_operand (operands[1], TFmode)
3626 || fp_zero_operand (operands[1], TFmode))"
3628 [(set_attr "length" "4")])
3630 (define_insn "*movtf_insn_vis_sp32"
3631 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3632 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3636 && (register_operand (operands[0], TFmode)
3637 || register_operand (operands[1], TFmode)
3638 || fp_zero_operand (operands[1], TFmode))"
3640 [(set_attr "length" "4")])
3642 ;; Exactly the same as above, except that all `e' cases are deleted.
3643 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3646 (define_insn "*movtf_no_e_insn_sp32"
3647 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3648 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3651 && (register_operand (operands[0], TFmode)
3652 || register_operand (operands[1], TFmode)
3653 || fp_zero_operand (operands[1], TFmode))"
3655 [(set_attr "length" "4")])
3657 ;; Now handle the float reg cases directly when arch64,
3658 ;; hard_quad, and proper reg number alignment are all true.
3659 (define_insn "*movtf_insn_hq_sp64"
3660 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3661 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3666 && (register_operand (operands[0], TFmode)
3667 || register_operand (operands[1], TFmode)
3668 || fp_zero_operand (operands[1], TFmode))"
3675 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3676 (set_attr "length" "*,*,*,2,2")])
3678 (define_insn "*movtf_insn_hq_vis_sp64"
3679 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3680 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3685 && (register_operand (operands[0], TFmode)
3686 || register_operand (operands[1], TFmode)
3687 || fp_zero_operand (operands[1], TFmode))"
3695 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3696 (set_attr "length" "*,*,*,2,2,2")])
3698 ;; Now we allow the integer register cases even when
3699 ;; only arch64 is true.
3700 (define_insn "*movtf_insn_sp64"
3701 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3702 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3706 && ! TARGET_HARD_QUAD
3707 && (register_operand (operands[0], TFmode)
3708 || register_operand (operands[1], TFmode)
3709 || fp_zero_operand (operands[1], TFmode))"
3711 [(set_attr "length" "2")])
3713 (define_insn "*movtf_insn_vis_sp64"
3714 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3715 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3719 && ! TARGET_HARD_QUAD
3720 && (register_operand (operands[0], TFmode)
3721 || register_operand (operands[1], TFmode)
3722 || fp_zero_operand (operands[1], TFmode))"
3724 [(set_attr "length" "2")])
3726 (define_insn "*movtf_no_e_insn_sp64"
3727 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3728 (match_operand:TF 1 "input_operand" "orG,rG"))]
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 ;; Now all the splits to handle multi-insn TF mode moves.
3739 [(set (match_operand:TF 0 "register_operand" "")
3740 (match_operand:TF 1 "register_operand" ""))]
3744 && ! TARGET_HARD_QUAD))"
3745 [(clobber (const_int 0))]
3748 rtx set_dest = operands[0];
3749 rtx set_src = operands[1];
3753 if (GET_CODE (set_dest) == SUBREG)
3754 set_dest = alter_subreg (set_dest);
3755 if (GET_CODE (set_src) == SUBREG)
3756 set_src = alter_subreg (set_src);
3758 dest1 = gen_df_reg (set_dest, 0);
3759 dest2 = gen_df_reg (set_dest, 1);
3760 src1 = gen_df_reg (set_src, 0);
3761 src2 = gen_df_reg (set_src, 1);
3763 /* Now emit using the real source and destination we found, swapping
3764 the order if we detect overlap. */
3765 if (reg_overlap_mentioned_p (dest1, src2))
3767 emit_insn (gen_movdf (dest2, src2));
3768 emit_insn (gen_movdf (dest1, src1));
3772 emit_insn (gen_movdf (dest1, src1));
3773 emit_insn (gen_movdf (dest2, src2));
3779 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3780 (match_operand:TF 1 "fp_zero_operand" ""))]
3782 [(clobber (const_int 0))]
3785 rtx set_dest = operands[0];
3788 switch (GET_CODE (set_dest))
3791 set_dest = alter_subreg (set_dest);
3794 dest1 = gen_df_reg (set_dest, 0);
3795 dest2 = gen_df_reg (set_dest, 1);
3798 dest1 = adjust_address (set_dest, DFmode, 0);
3799 dest2 = adjust_address (set_dest, DFmode, 8);
3805 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3806 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3811 [(set (match_operand:TF 0 "register_operand" "")
3812 (match_operand:TF 1 "memory_operand" ""))]
3814 && offsettable_memref_p (operands[1]))"
3815 [(clobber (const_int 0))]
3818 rtx word0 = adjust_address (operands[1], DFmode, 0);
3819 rtx word1 = adjust_address (operands[1], DFmode, 8);
3820 rtx set_dest, dest1, dest2;
3822 set_dest = operands[0];
3823 if (GET_CODE (set_dest) == SUBREG)
3824 set_dest = alter_subreg (set_dest);
3826 dest1 = gen_df_reg (set_dest, 0);
3827 dest2 = gen_df_reg (set_dest, 1);
3829 /* Now output, ordering such that we don't clobber any registers
3830 mentioned in the address. */
3831 if (reg_overlap_mentioned_p (dest1, word1))
3834 emit_insn (gen_movdf (dest2, word1));
3835 emit_insn (gen_movdf (dest1, word0));
3839 emit_insn (gen_movdf (dest1, word0));
3840 emit_insn (gen_movdf (dest2, word1));
3846 [(set (match_operand:TF 0 "memory_operand" "")
3847 (match_operand:TF 1 "register_operand" ""))]
3849 && offsettable_memref_p (operands[0]))"
3850 [(clobber (const_int 0))]
3853 rtx set_src = operands[1];
3854 if (GET_CODE (set_src) == SUBREG)
3855 set_src = alter_subreg (set_src);
3857 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3858 gen_df_reg (set_src, 0)));
3859 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3860 gen_df_reg (set_src, 1)));
3864 ;; Sparc V9 conditional move instructions.
3866 ;; We can handle larger constants here for some flavors, but for now we keep
3867 ;; it simple and only allow those constants supported by all flavours.
3868 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3869 ;; 3 contains the constant if one is present, but we handle either for
3870 ;; generality (sparc.c puts a constant in operand 2).
3872 (define_expand "movqicc"
3873 [(set (match_operand:QI 0 "register_operand" "")
3874 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3875 (match_operand:QI 2 "arith10_operand" "")
3876 (match_operand:QI 3 "arith10_operand" "")))]
3880 enum rtx_code code = GET_CODE (operands[1]);
3882 if (GET_MODE (sparc_compare_op0) == DImode
3886 if (sparc_compare_op1 == const0_rtx
3887 && GET_CODE (sparc_compare_op0) == REG
3888 && GET_MODE (sparc_compare_op0) == DImode
3889 && v9_regcmp_p (code))
3891 operands[1] = gen_rtx_fmt_ee (code, DImode,
3892 sparc_compare_op0, sparc_compare_op1);
3896 rtx cc_reg = gen_compare_reg (code,
3897 sparc_compare_op0, sparc_compare_op1);
3898 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3902 (define_expand "movhicc"
3903 [(set (match_operand:HI 0 "register_operand" "")
3904 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3905 (match_operand:HI 2 "arith10_operand" "")
3906 (match_operand:HI 3 "arith10_operand" "")))]
3910 enum rtx_code code = GET_CODE (operands[1]);
3912 if (GET_MODE (sparc_compare_op0) == DImode
3916 if (sparc_compare_op1 == const0_rtx
3917 && GET_CODE (sparc_compare_op0) == REG
3918 && GET_MODE (sparc_compare_op0) == DImode
3919 && v9_regcmp_p (code))
3921 operands[1] = gen_rtx_fmt_ee (code, DImode,
3922 sparc_compare_op0, sparc_compare_op1);
3926 rtx cc_reg = gen_compare_reg (code,
3927 sparc_compare_op0, sparc_compare_op1);
3928 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3932 (define_expand "movsicc"
3933 [(set (match_operand:SI 0 "register_operand" "")
3934 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3935 (match_operand:SI 2 "arith10_operand" "")
3936 (match_operand:SI 3 "arith10_operand" "")))]
3940 enum rtx_code code = GET_CODE (operands[1]);
3941 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3943 if (sparc_compare_op1 == const0_rtx
3944 && GET_CODE (sparc_compare_op0) == REG
3945 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3947 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3948 sparc_compare_op0, sparc_compare_op1);
3952 rtx cc_reg = gen_compare_reg (code,
3953 sparc_compare_op0, sparc_compare_op1);
3954 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3955 cc_reg, const0_rtx);
3959 (define_expand "movdicc"
3960 [(set (match_operand:DI 0 "register_operand" "")
3961 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3962 (match_operand:DI 2 "arith10_double_operand" "")
3963 (match_operand:DI 3 "arith10_double_operand" "")))]
3967 enum rtx_code code = GET_CODE (operands[1]);
3969 if (sparc_compare_op1 == const0_rtx
3970 && GET_CODE (sparc_compare_op0) == REG
3971 && GET_MODE (sparc_compare_op0) == DImode
3972 && v9_regcmp_p (code))
3974 operands[1] = gen_rtx_fmt_ee (code, DImode,
3975 sparc_compare_op0, sparc_compare_op1);
3979 rtx cc_reg = gen_compare_reg (code,
3980 sparc_compare_op0, sparc_compare_op1);
3981 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3982 cc_reg, const0_rtx);
3986 (define_expand "movsfcc"
3987 [(set (match_operand:SF 0 "register_operand" "")
3988 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3989 (match_operand:SF 2 "register_operand" "")
3990 (match_operand:SF 3 "register_operand" "")))]
3991 "TARGET_V9 && TARGET_FPU"
3994 enum rtx_code code = GET_CODE (operands[1]);
3996 if (GET_MODE (sparc_compare_op0) == DImode
4000 if (sparc_compare_op1 == const0_rtx
4001 && GET_CODE (sparc_compare_op0) == REG
4002 && GET_MODE (sparc_compare_op0) == DImode
4003 && v9_regcmp_p (code))
4005 operands[1] = gen_rtx_fmt_ee (code, DImode,
4006 sparc_compare_op0, sparc_compare_op1);
4010 rtx cc_reg = gen_compare_reg (code,
4011 sparc_compare_op0, sparc_compare_op1);
4012 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4016 (define_expand "movdfcc"
4017 [(set (match_operand:DF 0 "register_operand" "")
4018 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4019 (match_operand:DF 2 "register_operand" "")
4020 (match_operand:DF 3 "register_operand" "")))]
4021 "TARGET_V9 && TARGET_FPU"
4024 enum rtx_code code = GET_CODE (operands[1]);
4026 if (GET_MODE (sparc_compare_op0) == DImode
4030 if (sparc_compare_op1 == const0_rtx
4031 && GET_CODE (sparc_compare_op0) == REG
4032 && GET_MODE (sparc_compare_op0) == DImode
4033 && v9_regcmp_p (code))
4035 operands[1] = gen_rtx_fmt_ee (code, DImode,
4036 sparc_compare_op0, sparc_compare_op1);
4040 rtx cc_reg = gen_compare_reg (code,
4041 sparc_compare_op0, sparc_compare_op1);
4042 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4046 (define_expand "movtfcc"
4047 [(set (match_operand:TF 0 "register_operand" "")
4048 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4049 (match_operand:TF 2 "register_operand" "")
4050 (match_operand:TF 3 "register_operand" "")))]
4051 "TARGET_V9 && TARGET_FPU"
4054 enum rtx_code code = GET_CODE (operands[1]);
4056 if (GET_MODE (sparc_compare_op0) == DImode
4060 if (sparc_compare_op1 == const0_rtx
4061 && GET_CODE (sparc_compare_op0) == REG
4062 && GET_MODE (sparc_compare_op0) == DImode
4063 && v9_regcmp_p (code))
4065 operands[1] = gen_rtx_fmt_ee (code, DImode,
4066 sparc_compare_op0, sparc_compare_op1);
4070 rtx cc_reg = gen_compare_reg (code,
4071 sparc_compare_op0, sparc_compare_op1);
4072 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4076 ;; Conditional move define_insns.
4078 (define_insn "*movqi_cc_sp64"
4079 [(set (match_operand:QI 0 "register_operand" "=r,r")
4080 (if_then_else:QI (match_operator 1 "comparison_operator"
4081 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4083 (match_operand:QI 3 "arith11_operand" "rL,0")
4084 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4087 mov%C1\\t%x2, %3, %0
4088 mov%c1\\t%x2, %4, %0"
4089 [(set_attr "type" "cmove")])
4091 (define_insn "*movhi_cc_sp64"
4092 [(set (match_operand:HI 0 "register_operand" "=r,r")
4093 (if_then_else:HI (match_operator 1 "comparison_operator"
4094 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4096 (match_operand:HI 3 "arith11_operand" "rL,0")
4097 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4100 mov%C1\\t%x2, %3, %0
4101 mov%c1\\t%x2, %4, %0"
4102 [(set_attr "type" "cmove")])
4104 (define_insn "*movsi_cc_sp64"
4105 [(set (match_operand:SI 0 "register_operand" "=r,r")
4106 (if_then_else:SI (match_operator 1 "comparison_operator"
4107 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4109 (match_operand:SI 3 "arith11_operand" "rL,0")
4110 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4113 mov%C1\\t%x2, %3, %0
4114 mov%c1\\t%x2, %4, %0"
4115 [(set_attr "type" "cmove")])
4117 ;; ??? The constraints of operands 3,4 need work.
4118 (define_insn "*movdi_cc_sp64"
4119 [(set (match_operand:DI 0 "register_operand" "=r,r")
4120 (if_then_else:DI (match_operator 1 "comparison_operator"
4121 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4123 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4124 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4127 mov%C1\\t%x2, %3, %0
4128 mov%c1\\t%x2, %4, %0"
4129 [(set_attr "type" "cmove")])
4131 (define_insn "*movdi_cc_sp64_trunc"
4132 [(set (match_operand:SI 0 "register_operand" "=r,r")
4133 (if_then_else:SI (match_operator 1 "comparison_operator"
4134 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4136 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4137 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4140 mov%C1\\t%x2, %3, %0
4141 mov%c1\\t%x2, %4, %0"
4142 [(set_attr "type" "cmove")])
4144 (define_insn "*movsf_cc_sp64"
4145 [(set (match_operand:SF 0 "register_operand" "=f,f")
4146 (if_then_else:SF (match_operator 1 "comparison_operator"
4147 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4149 (match_operand:SF 3 "register_operand" "f,0")
4150 (match_operand:SF 4 "register_operand" "0,f")))]
4151 "TARGET_V9 && TARGET_FPU"
4153 fmovs%C1\\t%x2, %3, %0
4154 fmovs%c1\\t%x2, %4, %0"
4155 [(set_attr "type" "fpcmove")])
4157 (define_insn "movdf_cc_sp64"
4158 [(set (match_operand:DF 0 "register_operand" "=e,e")
4159 (if_then_else:DF (match_operator 1 "comparison_operator"
4160 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4162 (match_operand:DF 3 "register_operand" "e,0")
4163 (match_operand:DF 4 "register_operand" "0,e")))]
4164 "TARGET_V9 && TARGET_FPU"
4166 fmovd%C1\\t%x2, %3, %0
4167 fmovd%c1\\t%x2, %4, %0"
4168 [(set_attr "type" "fpcmove")
4169 (set_attr "fptype" "double")])
4171 (define_insn "*movtf_cc_hq_sp64"
4172 [(set (match_operand:TF 0 "register_operand" "=e,e")
4173 (if_then_else:TF (match_operator 1 "comparison_operator"
4174 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4176 (match_operand:TF 3 "register_operand" "e,0")
4177 (match_operand:TF 4 "register_operand" "0,e")))]
4178 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4180 fmovq%C1\\t%x2, %3, %0
4181 fmovq%c1\\t%x2, %4, %0"
4182 [(set_attr "type" "fpcmove")])
4184 (define_insn "*movtf_cc_sp64"
4185 [(set (match_operand:TF 0 "register_operand" "=e,e")
4186 (if_then_else:TF (match_operator 1 "comparison_operator"
4187 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4189 (match_operand:TF 3 "register_operand" "e,0")
4190 (match_operand:TF 4 "register_operand" "0,e")))]
4191 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4193 [(set_attr "length" "2")])
4196 [(set (match_operand:TF 0 "register_operand" "")
4197 (if_then_else:TF (match_operator 1 "comparison_operator"
4198 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4200 (match_operand:TF 3 "register_operand" "")
4201 (match_operand:TF 4 "register_operand" "")))]
4202 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4203 [(clobber (const_int 0))]
4206 rtx set_dest = operands[0];
4207 rtx set_srca = operands[3];
4208 rtx set_srcb = operands[4];
4209 int third = rtx_equal_p (set_dest, set_srca);
4211 rtx srca1, srca2, srcb1, srcb2;
4213 if (GET_CODE (set_dest) == SUBREG)
4214 set_dest = alter_subreg (set_dest);
4215 if (GET_CODE (set_srca) == SUBREG)
4216 set_srca = alter_subreg (set_srca);
4217 if (GET_CODE (set_srcb) == SUBREG)
4218 set_srcb = alter_subreg (set_srcb);
4220 dest1 = gen_df_reg (set_dest, 0);
4221 dest2 = gen_df_reg (set_dest, 1);
4222 srca1 = gen_df_reg (set_srca, 0);
4223 srca2 = gen_df_reg (set_srca, 1);
4224 srcb1 = gen_df_reg (set_srcb, 0);
4225 srcb2 = gen_df_reg (set_srcb, 1);
4227 /* Now emit using the real source and destination we found, swapping
4228 the order if we detect overlap. */
4229 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4230 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4232 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4233 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4237 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4238 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4243 (define_insn "*movqi_cc_reg_sp64"
4244 [(set (match_operand:QI 0 "register_operand" "=r,r")
4245 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4246 [(match_operand:DI 2 "register_operand" "r,r")
4248 (match_operand:QI 3 "arith10_operand" "rM,0")
4249 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4252 movr%D1\\t%2, %r3, %0
4253 movr%d1\\t%2, %r4, %0"
4254 [(set_attr "type" "cmove")])
4256 (define_insn "*movhi_cc_reg_sp64"
4257 [(set (match_operand:HI 0 "register_operand" "=r,r")
4258 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4259 [(match_operand:DI 2 "register_operand" "r,r")
4261 (match_operand:HI 3 "arith10_operand" "rM,0")
4262 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4265 movr%D1\\t%2, %r3, %0
4266 movr%d1\\t%2, %r4, %0"
4267 [(set_attr "type" "cmove")])
4269 (define_insn "*movsi_cc_reg_sp64"
4270 [(set (match_operand:SI 0 "register_operand" "=r,r")
4271 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4272 [(match_operand:DI 2 "register_operand" "r,r")
4274 (match_operand:SI 3 "arith10_operand" "rM,0")
4275 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4278 movr%D1\\t%2, %r3, %0
4279 movr%d1\\t%2, %r4, %0"
4280 [(set_attr "type" "cmove")])
4282 ;; ??? The constraints of operands 3,4 need work.
4283 (define_insn "*movdi_cc_reg_sp64"
4284 [(set (match_operand:DI 0 "register_operand" "=r,r")
4285 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4286 [(match_operand:DI 2 "register_operand" "r,r")
4288 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4289 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4292 movr%D1\\t%2, %r3, %0
4293 movr%d1\\t%2, %r4, %0"
4294 [(set_attr "type" "cmove")])
4296 (define_insn "*movdi_cc_reg_sp64_trunc"
4297 [(set (match_operand:SI 0 "register_operand" "=r,r")
4298 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4299 [(match_operand:DI 2 "register_operand" "r,r")
4301 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4302 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4305 movr%D1\\t%2, %r3, %0
4306 movr%d1\\t%2, %r4, %0"
4307 [(set_attr "type" "cmove")])
4309 (define_insn "*movsf_cc_reg_sp64"
4310 [(set (match_operand:SF 0 "register_operand" "=f,f")
4311 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4312 [(match_operand:DI 2 "register_operand" "r,r")
4314 (match_operand:SF 3 "register_operand" "f,0")
4315 (match_operand:SF 4 "register_operand" "0,f")))]
4316 "TARGET_ARCH64 && TARGET_FPU"
4318 fmovrs%D1\\t%2, %3, %0
4319 fmovrs%d1\\t%2, %4, %0"
4320 [(set_attr "type" "fpcmove")])
4322 (define_insn "movdf_cc_reg_sp64"
4323 [(set (match_operand:DF 0 "register_operand" "=e,e")
4324 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4325 [(match_operand:DI 2 "register_operand" "r,r")
4327 (match_operand:DF 3 "register_operand" "e,0")
4328 (match_operand:DF 4 "register_operand" "0,e")))]
4329 "TARGET_ARCH64 && TARGET_FPU"
4331 fmovrd%D1\\t%2, %3, %0
4332 fmovrd%d1\\t%2, %4, %0"
4333 [(set_attr "type" "fpcmove")
4334 (set_attr "fptype" "double")])
4336 (define_insn "*movtf_cc_reg_hq_sp64"
4337 [(set (match_operand:TF 0 "register_operand" "=e,e")
4338 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4339 [(match_operand:DI 2 "register_operand" "r,r")
4341 (match_operand:TF 3 "register_operand" "e,0")
4342 (match_operand:TF 4 "register_operand" "0,e")))]
4343 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4345 fmovrq%D1\\t%2, %3, %0
4346 fmovrq%d1\\t%2, %4, %0"
4347 [(set_attr "type" "fpcmove")])
4349 (define_insn "*movtf_cc_reg_sp64"
4350 [(set (match_operand:TF 0 "register_operand" "=e,e")
4351 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4352 [(match_operand:DI 2 "register_operand" "r,r")
4354 (match_operand:TF 3 "register_operand" "e,0")
4355 (match_operand:TF 4 "register_operand" "0,e")))]
4356 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4358 [(set_attr "length" "2")])
4361 [(set (match_operand:TF 0 "register_operand" "")
4362 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4363 [(match_operand:DI 2 "register_operand" "")
4365 (match_operand:TF 3 "register_operand" "")
4366 (match_operand:TF 4 "register_operand" "")))]
4367 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4368 [(clobber (const_int 0))]
4371 rtx set_dest = operands[0];
4372 rtx set_srca = operands[3];
4373 rtx set_srcb = operands[4];
4374 int third = rtx_equal_p (set_dest, set_srca);
4376 rtx srca1, srca2, srcb1, srcb2;
4378 if (GET_CODE (set_dest) == SUBREG)
4379 set_dest = alter_subreg (set_dest);
4380 if (GET_CODE (set_srca) == SUBREG)
4381 set_srca = alter_subreg (set_srca);
4382 if (GET_CODE (set_srcb) == SUBREG)
4383 set_srcb = alter_subreg (set_srcb);
4385 dest1 = gen_df_reg (set_dest, 0);
4386 dest2 = gen_df_reg (set_dest, 1);
4387 srca1 = gen_df_reg (set_srca, 0);
4388 srca2 = gen_df_reg (set_srca, 1);
4389 srcb1 = gen_df_reg (set_srcb, 0);
4390 srcb2 = gen_df_reg (set_srcb, 1);
4392 /* Now emit using the real source and destination we found, swapping
4393 the order if we detect overlap. */
4394 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4395 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4397 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4398 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4402 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4403 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4409 ;;- zero extension instructions
4411 ;; These patterns originally accepted general_operands, however, slightly
4412 ;; better code is generated by only accepting register_operands, and then
4413 ;; letting combine generate the ldu[hb] insns.
4415 (define_expand "zero_extendhisi2"
4416 [(set (match_operand:SI 0 "register_operand" "")
4417 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4421 rtx temp = gen_reg_rtx (SImode);
4422 rtx shift_16 = GEN_INT (16);
4423 int op1_subbyte = 0;
4425 if (GET_CODE (operand1) == SUBREG)
4427 op1_subbyte = SUBREG_BYTE (operand1);
4428 op1_subbyte /= GET_MODE_SIZE (SImode);
4429 op1_subbyte *= GET_MODE_SIZE (SImode);
4430 operand1 = XEXP (operand1, 0);
4433 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4435 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4439 (define_insn "*zero_extendhisi2_insn"
4440 [(set (match_operand:SI 0 "register_operand" "=r")
4441 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4444 [(set_attr "type" "load")])
4446 (define_expand "zero_extendqihi2"
4447 [(set (match_operand:HI 0 "register_operand" "")
4448 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4452 (define_insn "*zero_extendqihi2_insn"
4453 [(set (match_operand:HI 0 "register_operand" "=r,r")
4454 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4455 "GET_CODE (operands[1]) != CONST_INT"
4459 [(set_attr "type" "*,load")])
4461 (define_expand "zero_extendqisi2"
4462 [(set (match_operand:SI 0 "register_operand" "")
4463 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4467 (define_insn "*zero_extendqisi2_insn"
4468 [(set (match_operand:SI 0 "register_operand" "=r,r")
4469 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4470 "GET_CODE (operands[1]) != CONST_INT"
4474 [(set_attr "type" "*,load")])
4476 (define_expand "zero_extendqidi2"
4477 [(set (match_operand:DI 0 "register_operand" "")
4478 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4482 (define_insn "*zero_extendqidi2_insn"
4483 [(set (match_operand:DI 0 "register_operand" "=r,r")
4484 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4485 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4489 [(set_attr "type" "*,load")])
4491 (define_expand "zero_extendhidi2"
4492 [(set (match_operand:DI 0 "register_operand" "")
4493 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4497 rtx temp = gen_reg_rtx (DImode);
4498 rtx shift_48 = GEN_INT (48);
4499 int op1_subbyte = 0;
4501 if (GET_CODE (operand1) == SUBREG)
4503 op1_subbyte = SUBREG_BYTE (operand1);
4504 op1_subbyte /= GET_MODE_SIZE (DImode);
4505 op1_subbyte *= GET_MODE_SIZE (DImode);
4506 operand1 = XEXP (operand1, 0);
4509 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4511 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4515 (define_insn "*zero_extendhidi2_insn"
4516 [(set (match_operand:DI 0 "register_operand" "=r")
4517 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4520 [(set_attr "type" "load")])
4523 ;; ??? Write truncdisi pattern using sra?
4525 (define_expand "zero_extendsidi2"
4526 [(set (match_operand:DI 0 "register_operand" "")
4527 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4531 (define_insn "*zero_extendsidi2_insn_sp64"
4532 [(set (match_operand:DI 0 "register_operand" "=r,r")
4533 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4534 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4538 [(set_attr "type" "shift,load")])
4540 (define_insn "*zero_extendsidi2_insn_sp32"
4541 [(set (match_operand:DI 0 "register_operand" "=r")
4542 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4545 [(set_attr "length" "2")])
4548 [(set (match_operand:DI 0 "register_operand" "")
4549 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4550 "! TARGET_ARCH64 && reload_completed"
4551 [(set (match_dup 2) (match_dup 3))
4552 (set (match_dup 4) (match_dup 5))]
4557 if (GET_CODE (operands[0]) == SUBREG)
4558 operands[0] = alter_subreg (operands[0]);
4560 dest1 = gen_highpart (SImode, operands[0]);
4561 dest2 = gen_lowpart (SImode, operands[0]);
4563 /* Swap the order in case of overlap. */
4564 if (REGNO (dest1) == REGNO (operands[1]))
4566 operands[2] = dest2;
4567 operands[3] = operands[1];
4568 operands[4] = dest1;
4569 operands[5] = const0_rtx;
4573 operands[2] = dest1;
4574 operands[3] = const0_rtx;
4575 operands[4] = dest2;
4576 operands[5] = operands[1];
4580 ;; Simplify comparisons of extended values.
4582 (define_insn "*cmp_zero_extendqisi2"
4584 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4587 "andcc\\t%0, 0xff, %%g0"
4588 [(set_attr "type" "compare")])
4590 (define_insn "*cmp_zero_qi"
4592 (compare:CC (match_operand:QI 0 "register_operand" "r")
4595 "andcc\\t%0, 0xff, %%g0"
4596 [(set_attr "type" "compare")])
4598 (define_insn "*cmp_zero_extendqisi2_set"
4600 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4602 (set (match_operand:SI 0 "register_operand" "=r")
4603 (zero_extend:SI (match_dup 1)))]
4605 "andcc\\t%1, 0xff, %0"
4606 [(set_attr "type" "compare")])
4608 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4610 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4613 (set (match_operand:SI 0 "register_operand" "=r")
4614 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4616 "andcc\\t%1, 0xff, %0"
4617 [(set_attr "type" "compare")])
4619 (define_insn "*cmp_zero_extendqidi2"
4621 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4624 "andcc\\t%0, 0xff, %%g0"
4625 [(set_attr "type" "compare")])
4627 (define_insn "*cmp_zero_qi_sp64"
4629 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4632 "andcc\\t%0, 0xff, %%g0"
4633 [(set_attr "type" "compare")])
4635 (define_insn "*cmp_zero_extendqidi2_set"
4637 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4639 (set (match_operand:DI 0 "register_operand" "=r")
4640 (zero_extend:DI (match_dup 1)))]
4642 "andcc\\t%1, 0xff, %0"
4643 [(set_attr "type" "compare")])
4645 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4647 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4650 (set (match_operand:DI 0 "register_operand" "=r")
4651 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4653 "andcc\\t%1, 0xff, %0"
4654 [(set_attr "type" "compare")])
4656 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4658 (define_insn "*cmp_siqi_trunc"
4660 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4663 "andcc\\t%0, 0xff, %%g0"
4664 [(set_attr "type" "compare")])
4666 (define_insn "*cmp_siqi_trunc_set"
4668 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4670 (set (match_operand:QI 0 "register_operand" "=r")
4671 (subreg:QI (match_dup 1) 3))]
4673 "andcc\\t%1, 0xff, %0"
4674 [(set_attr "type" "compare")])
4676 (define_insn "*cmp_diqi_trunc"
4678 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4681 "andcc\\t%0, 0xff, %%g0"
4682 [(set_attr "type" "compare")])
4684 (define_insn "*cmp_diqi_trunc_set"
4686 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4688 (set (match_operand:QI 0 "register_operand" "=r")
4689 (subreg:QI (match_dup 1) 7))]
4691 "andcc\\t%1, 0xff, %0"
4692 [(set_attr "type" "compare")])
4694 ;;- sign extension instructions
4696 ;; These patterns originally accepted general_operands, however, slightly
4697 ;; better code is generated by only accepting register_operands, and then
4698 ;; letting combine generate the lds[hb] insns.
4700 (define_expand "extendhisi2"
4701 [(set (match_operand:SI 0 "register_operand" "")
4702 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4706 rtx temp = gen_reg_rtx (SImode);
4707 rtx shift_16 = GEN_INT (16);
4708 int op1_subbyte = 0;
4710 if (GET_CODE (operand1) == SUBREG)
4712 op1_subbyte = SUBREG_BYTE (operand1);
4713 op1_subbyte /= GET_MODE_SIZE (SImode);
4714 op1_subbyte *= GET_MODE_SIZE (SImode);
4715 operand1 = XEXP (operand1, 0);
4718 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4720 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4724 (define_insn "*sign_extendhisi2_insn"
4725 [(set (match_operand:SI 0 "register_operand" "=r")
4726 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4729 [(set_attr "type" "sload")])
4731 (define_expand "extendqihi2"
4732 [(set (match_operand:HI 0 "register_operand" "")
4733 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4737 rtx temp = gen_reg_rtx (SImode);
4738 rtx shift_24 = GEN_INT (24);
4739 int op1_subbyte = 0;
4740 int op0_subbyte = 0;
4742 if (GET_CODE (operand1) == SUBREG)
4744 op1_subbyte = SUBREG_BYTE (operand1);
4745 op1_subbyte /= GET_MODE_SIZE (SImode);
4746 op1_subbyte *= GET_MODE_SIZE (SImode);
4747 operand1 = XEXP (operand1, 0);
4749 if (GET_CODE (operand0) == SUBREG)
4751 op0_subbyte = SUBREG_BYTE (operand0);
4752 op0_subbyte /= GET_MODE_SIZE (SImode);
4753 op0_subbyte *= GET_MODE_SIZE (SImode);
4754 operand0 = XEXP (operand0, 0);
4756 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4758 if (GET_MODE (operand0) != SImode)
4759 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4760 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4764 (define_insn "*sign_extendqihi2_insn"
4765 [(set (match_operand:HI 0 "register_operand" "=r")
4766 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4769 [(set_attr "type" "sload")])
4771 (define_expand "extendqisi2"
4772 [(set (match_operand:SI 0 "register_operand" "")
4773 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4777 rtx temp = gen_reg_rtx (SImode);
4778 rtx shift_24 = GEN_INT (24);
4779 int op1_subbyte = 0;
4781 if (GET_CODE (operand1) == SUBREG)
4783 op1_subbyte = SUBREG_BYTE (operand1);
4784 op1_subbyte /= GET_MODE_SIZE (SImode);
4785 op1_subbyte *= GET_MODE_SIZE (SImode);
4786 operand1 = XEXP (operand1, 0);
4789 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4791 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4795 (define_insn "*sign_extendqisi2_insn"
4796 [(set (match_operand:SI 0 "register_operand" "=r")
4797 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4800 [(set_attr "type" "sload")])
4802 (define_expand "extendqidi2"
4803 [(set (match_operand:DI 0 "register_operand" "")
4804 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4808 rtx temp = gen_reg_rtx (DImode);
4809 rtx shift_56 = GEN_INT (56);
4810 int op1_subbyte = 0;
4812 if (GET_CODE (operand1) == SUBREG)
4814 op1_subbyte = SUBREG_BYTE (operand1);
4815 op1_subbyte /= GET_MODE_SIZE (DImode);
4816 op1_subbyte *= GET_MODE_SIZE (DImode);
4817 operand1 = XEXP (operand1, 0);
4820 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4822 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4826 (define_insn "*sign_extendqidi2_insn"
4827 [(set (match_operand:DI 0 "register_operand" "=r")
4828 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4831 [(set_attr "type" "sload")])
4833 (define_expand "extendhidi2"
4834 [(set (match_operand:DI 0 "register_operand" "")
4835 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4839 rtx temp = gen_reg_rtx (DImode);
4840 rtx shift_48 = GEN_INT (48);
4841 int op1_subbyte = 0;
4843 if (GET_CODE (operand1) == SUBREG)
4845 op1_subbyte = SUBREG_BYTE (operand1);
4846 op1_subbyte /= GET_MODE_SIZE (DImode);
4847 op1_subbyte *= GET_MODE_SIZE (DImode);
4848 operand1 = XEXP (operand1, 0);
4851 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4853 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4857 (define_insn "*sign_extendhidi2_insn"
4858 [(set (match_operand:DI 0 "register_operand" "=r")
4859 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4862 [(set_attr "type" "sload")])
4864 (define_expand "extendsidi2"
4865 [(set (match_operand:DI 0 "register_operand" "")
4866 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4870 (define_insn "*sign_extendsidi2_insn"
4871 [(set (match_operand:DI 0 "register_operand" "=r,r")
4872 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4877 [(set_attr "type" "shift,sload")])
4879 ;; Special pattern for optimizing bit-field compares. This is needed
4880 ;; because combine uses this as a canonical form.
4882 (define_insn "*cmp_zero_extract"
4885 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4886 (match_operand:SI 1 "small_int_or_double" "n")
4887 (match_operand:SI 2 "small_int_or_double" "n"))
4889 "(GET_CODE (operands[2]) == CONST_INT
4890 && INTVAL (operands[2]) > 19)
4891 || (GET_CODE (operands[2]) == CONST_DOUBLE
4892 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4895 int len = (GET_CODE (operands[1]) == CONST_INT
4896 ? INTVAL (operands[1])
4897 : CONST_DOUBLE_LOW (operands[1]));
4899 (GET_CODE (operands[2]) == CONST_INT
4900 ? INTVAL (operands[2])
4901 : CONST_DOUBLE_LOW (operands[2])) - len;
4902 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4904 operands[1] = GEN_INT (mask);
4905 return \"andcc\\t%0, %1, %%g0\";
4907 [(set_attr "type" "compare")])
4909 (define_insn "*cmp_zero_extract_sp64"
4912 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4913 (match_operand:SI 1 "small_int_or_double" "n")
4914 (match_operand:SI 2 "small_int_or_double" "n"))
4917 && ((GET_CODE (operands[2]) == CONST_INT
4918 && INTVAL (operands[2]) > 51)
4919 || (GET_CODE (operands[2]) == CONST_DOUBLE
4920 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4923 int len = (GET_CODE (operands[1]) == CONST_INT
4924 ? INTVAL (operands[1])
4925 : CONST_DOUBLE_LOW (operands[1]));
4927 (GET_CODE (operands[2]) == CONST_INT
4928 ? INTVAL (operands[2])
4929 : CONST_DOUBLE_LOW (operands[2])) - len;
4930 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4932 operands[1] = GEN_INT (mask);
4933 return \"andcc\\t%0, %1, %%g0\";
4935 [(set_attr "type" "compare")])
4937 ;; Conversions between float, double and long double.
4939 (define_insn "extendsfdf2"
4940 [(set (match_operand:DF 0 "register_operand" "=e")
4942 (match_operand:SF 1 "register_operand" "f")))]
4945 [(set_attr "type" "fp")
4946 (set_attr "fptype" "double")])
4948 (define_expand "extendsftf2"
4949 [(set (match_operand:TF 0 "register_operand" "=e")
4951 (match_operand:SF 1 "register_operand" "f")))]
4952 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4955 if (! TARGET_HARD_QUAD)
4959 if (GET_CODE (operands[0]) != MEM)
4960 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4962 slot0 = operands[0];
4964 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4966 XEXP (slot0, 0), Pmode,
4967 operands[1], SFmode);
4969 if (GET_CODE (operands[0]) != MEM)
4970 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4975 (define_insn "*extendsftf2_hq"
4976 [(set (match_operand:TF 0 "register_operand" "=e")
4978 (match_operand:SF 1 "register_operand" "f")))]
4979 "TARGET_FPU && TARGET_HARD_QUAD"
4981 [(set_attr "type" "fp")])
4983 (define_expand "extenddftf2"
4984 [(set (match_operand:TF 0 "register_operand" "=e")
4986 (match_operand:DF 1 "register_operand" "e")))]
4987 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4990 if (! TARGET_HARD_QUAD)
4994 if (GET_CODE (operands[0]) != MEM)
4995 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4997 slot0 = operands[0];
4999 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5001 XEXP (slot0, 0), Pmode,
5002 operands[1], DFmode);
5004 if (GET_CODE (operands[0]) != MEM)
5005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5010 (define_insn "*extenddftf2_hq"
5011 [(set (match_operand:TF 0 "register_operand" "=e")
5013 (match_operand:DF 1 "register_operand" "e")))]
5014 "TARGET_FPU && TARGET_HARD_QUAD"
5016 [(set_attr "type" "fp")])
5018 (define_insn "truncdfsf2"
5019 [(set (match_operand:SF 0 "register_operand" "=f")
5021 (match_operand:DF 1 "register_operand" "e")))]
5024 [(set_attr "type" "fp")
5025 (set_attr "fptype" "double")])
5027 (define_expand "trunctfsf2"
5028 [(set (match_operand:SF 0 "register_operand" "=f")
5030 (match_operand:TF 1 "register_operand" "e")))]
5031 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5034 if (! TARGET_HARD_QUAD)
5038 if (GET_CODE (operands[1]) != MEM)
5040 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5041 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5044 slot0 = operands[1];
5046 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5047 operands[0], 0, SFmode, 1,
5048 XEXP (slot0, 0), Pmode);
5053 (define_insn "*trunctfsf2_hq"
5054 [(set (match_operand:SF 0 "register_operand" "=f")
5056 (match_operand:TF 1 "register_operand" "e")))]
5057 "TARGET_FPU && TARGET_HARD_QUAD"
5059 [(set_attr "type" "fp")])
5061 (define_expand "trunctfdf2"
5062 [(set (match_operand:DF 0 "register_operand" "=f")
5064 (match_operand:TF 1 "register_operand" "e")))]
5065 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5068 if (! TARGET_HARD_QUAD)
5072 if (GET_CODE (operands[1]) != MEM)
5074 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5075 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5078 slot0 = operands[1];
5080 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5081 operands[0], 0, DFmode, 1,
5082 XEXP (slot0, 0), Pmode);
5087 (define_insn "*trunctfdf2_hq"
5088 [(set (match_operand:DF 0 "register_operand" "=e")
5090 (match_operand:TF 1 "register_operand" "e")))]
5091 "TARGET_FPU && TARGET_HARD_QUAD"
5093 [(set_attr "type" "fp")])
5095 ;; Conversion between fixed point and floating point.
5097 (define_insn "floatsisf2"
5098 [(set (match_operand:SF 0 "register_operand" "=f")
5099 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5102 [(set_attr "type" "fp")
5103 (set_attr "fptype" "double")])
5105 (define_insn "floatsidf2"
5106 [(set (match_operand:DF 0 "register_operand" "=e")
5107 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5110 [(set_attr "type" "fp")
5111 (set_attr "fptype" "double")])
5113 (define_expand "floatsitf2"
5114 [(set (match_operand:TF 0 "register_operand" "=e")
5115 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5116 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5119 if (! TARGET_HARD_QUAD)
5123 if (GET_CODE (operands[1]) != MEM)
5124 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5126 slot0 = operands[1];
5128 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5130 XEXP (slot0, 0), Pmode,
5131 operands[1], SImode);
5133 if (GET_CODE (operands[0]) != MEM)
5134 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5139 (define_insn "*floatsitf2_hq"
5140 [(set (match_operand:TF 0 "register_operand" "=e")
5141 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5142 "TARGET_FPU && TARGET_HARD_QUAD"
5144 [(set_attr "type" "fp")])
5146 (define_expand "floatunssitf2"
5147 [(set (match_operand:TF 0 "register_operand" "=e")
5148 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5149 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5154 if (GET_CODE (operands[1]) != MEM)
5155 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5157 slot0 = operands[1];
5159 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5161 XEXP (slot0, 0), Pmode,
5162 operands[1], SImode);
5164 if (GET_CODE (operands[0]) != MEM)
5165 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5169 ;; Now the same for 64 bit sources.
5171 (define_insn "floatdisf2"
5172 [(set (match_operand:SF 0 "register_operand" "=f")
5173 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5174 "TARGET_V9 && TARGET_FPU"
5176 [(set_attr "type" "fp")
5177 (set_attr "fptype" "double")])
5179 (define_insn "floatdidf2"
5180 [(set (match_operand:DF 0 "register_operand" "=e")
5181 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5182 "TARGET_V9 && TARGET_FPU"
5184 [(set_attr "type" "fp")
5185 (set_attr "fptype" "double")])
5187 (define_expand "floatditf2"
5188 [(set (match_operand:TF 0 "register_operand" "=e")
5189 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5190 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5193 if (! TARGET_HARD_QUAD)
5197 if (GET_CODE (operands[1]) != MEM)
5198 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5200 slot0 = operands[1];
5202 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5204 XEXP (slot0, 0), Pmode,
5205 operands[1], DImode);
5207 if (GET_CODE (operands[0]) != MEM)
5208 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5213 (define_insn "*floatditf2_hq"
5214 [(set (match_operand:TF 0 "register_operand" "=e")
5215 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5216 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5218 [(set_attr "type" "fp")])
5220 (define_expand "floatunsditf2"
5221 [(set (match_operand:TF 0 "register_operand" "=e")
5222 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5223 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5228 if (GET_CODE (operands[1]) != MEM)
5229 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5231 slot0 = operands[1];
5233 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5235 XEXP (slot0, 0), Pmode,
5236 operands[1], DImode);
5238 if (GET_CODE (operands[0]) != MEM)
5239 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5243 ;; Convert a float to an actual integer.
5244 ;; Truncation is performed as part of the conversion.
5246 (define_insn "fix_truncsfsi2"
5247 [(set (match_operand:SI 0 "register_operand" "=f")
5248 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5251 [(set_attr "type" "fp")
5252 (set_attr "fptype" "double")])
5254 (define_insn "fix_truncdfsi2"
5255 [(set (match_operand:SI 0 "register_operand" "=f")
5256 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5259 [(set_attr "type" "fp")
5260 (set_attr "fptype" "double")])
5262 (define_expand "fix_trunctfsi2"
5263 [(set (match_operand:SI 0 "register_operand" "=f")
5264 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5265 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5268 if (! TARGET_HARD_QUAD)
5272 if (GET_CODE (operands[1]) != MEM)
5274 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5275 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5278 slot0 = operands[1];
5280 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5281 operands[0], 0, SImode, 1,
5282 XEXP (slot0, 0), Pmode);
5287 (define_insn "*fix_trunctfsi2_hq"
5288 [(set (match_operand:SI 0 "register_operand" "=f")
5289 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5290 "TARGET_FPU && TARGET_HARD_QUAD"
5292 [(set_attr "type" "fp")])
5294 (define_expand "fixuns_trunctfsi2"
5295 [(set (match_operand:SI 0 "register_operand" "=f")
5296 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5297 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5302 if (GET_CODE (operands[1]) != MEM)
5304 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5305 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5308 slot0 = operands[1];
5310 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5311 operands[0], 0, SImode, 1,
5312 XEXP (slot0, 0), Pmode);
5316 ;; Now the same, for V9 targets
5318 (define_insn "fix_truncsfdi2"
5319 [(set (match_operand:DI 0 "register_operand" "=e")
5320 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5321 "TARGET_V9 && TARGET_FPU"
5323 [(set_attr "type" "fp")
5324 (set_attr "fptype" "double")])
5326 (define_insn "fix_truncdfdi2"
5327 [(set (match_operand:DI 0 "register_operand" "=e")
5328 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5329 "TARGET_V9 && TARGET_FPU"
5331 [(set_attr "type" "fp")
5332 (set_attr "fptype" "double")])
5334 (define_expand "fix_trunctfdi2"
5335 [(set (match_operand:DI 0 "register_operand" "=e")
5336 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5337 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5340 if (! TARGET_HARD_QUAD)
5344 if (GET_CODE (operands[1]) != MEM)
5346 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5347 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5350 slot0 = operands[1];
5352 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5353 operands[0], 0, DImode, 1,
5354 XEXP (slot0, 0), Pmode);
5359 (define_insn "*fix_trunctfdi2_hq"
5360 [(set (match_operand:DI 0 "register_operand" "=e")
5361 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5362 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5364 [(set_attr "type" "fp")])
5366 (define_expand "fixuns_trunctfdi2"
5367 [(set (match_operand:DI 0 "register_operand" "=f")
5368 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5369 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5374 if (GET_CODE (operands[1]) != MEM)
5376 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5377 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5380 slot0 = operands[1];
5382 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5383 operands[0], 0, DImode, 1,
5384 XEXP (slot0, 0), Pmode);
5389 ;;- arithmetic instructions
5391 (define_expand "adddi3"
5392 [(set (match_operand:DI 0 "register_operand" "=r")
5393 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5394 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5400 if (! TARGET_ARCH64)
5402 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5403 gen_rtx_SET (VOIDmode, operands[0],
5404 gen_rtx_PLUS (DImode, operands[1],
5406 gen_rtx_CLOBBER (VOIDmode,
5407 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5410 if (arith_double_4096_operand(operands[2], DImode))
5412 switch (GET_CODE (operands[1]))
5414 case CONST_INT: i = INTVAL (operands[1]); break;
5415 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5417 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5418 gen_rtx_MINUS (DImode, operands[1],
5422 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5427 (define_insn "adddi3_insn_sp32"
5428 [(set (match_operand:DI 0 "register_operand" "=r")
5429 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5430 (match_operand:DI 2 "arith_double_operand" "rHI")))
5431 (clobber (reg:CC 100))]
5434 [(set_attr "length" "2")])
5437 [(set (match_operand:DI 0 "register_operand" "")
5438 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5439 (match_operand:DI 2 "arith_double_operand" "")))
5440 (clobber (reg:CC 100))]
5441 "! TARGET_ARCH64 && reload_completed"
5442 [(parallel [(set (reg:CC_NOOV 100)
5443 (compare:CC_NOOV (plus:SI (match_dup 4)
5447 (plus:SI (match_dup 4) (match_dup 5)))])
5449 (plus:SI (plus:SI (match_dup 7)
5451 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5454 operands[3] = gen_lowpart (SImode, operands[0]);
5455 operands[4] = gen_lowpart (SImode, operands[1]);
5456 operands[5] = gen_lowpart (SImode, operands[2]);
5457 operands[6] = gen_highpart (SImode, operands[0]);
5458 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5459 #if HOST_BITS_PER_WIDE_INT == 32
5460 if (GET_CODE (operands[2]) == CONST_INT)
5462 if (INTVAL (operands[2]) < 0)
5463 operands[8] = constm1_rtx;
5465 operands[8] = const0_rtx;
5469 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5473 [(set (match_operand:DI 0 "register_operand" "")
5474 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5475 (match_operand:DI 2 "arith_double_operand" "")))
5476 (clobber (reg:CC 100))]
5477 "! TARGET_ARCH64 && reload_completed"
5478 [(parallel [(set (reg:CC_NOOV 100)
5479 (compare:CC_NOOV (minus:SI (match_dup 4)
5483 (minus:SI (match_dup 4) (match_dup 5)))])
5485 (minus:SI (minus:SI (match_dup 7)
5487 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5490 operands[3] = gen_lowpart (SImode, operands[0]);
5491 operands[4] = gen_lowpart (SImode, operands[1]);
5492 operands[5] = gen_lowpart (SImode, operands[2]);
5493 operands[6] = gen_highpart (SImode, operands[0]);
5494 operands[7] = gen_highpart (SImode, operands[1]);
5495 #if HOST_BITS_PER_WIDE_INT == 32
5496 if (GET_CODE (operands[2]) == CONST_INT)
5498 if (INTVAL (operands[2]) < 0)
5499 operands[8] = constm1_rtx;
5501 operands[8] = const0_rtx;
5505 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5508 ;; LTU here means "carry set"
5510 [(set (match_operand:SI 0 "register_operand" "=r")
5511 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5512 (match_operand:SI 2 "arith_operand" "rI"))
5513 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5516 [(set_attr "type" "misc")])
5518 (define_insn "*addx_extend_sp32"
5519 [(set (match_operand:DI 0 "register_operand" "=r")
5520 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5521 (match_operand:SI 2 "arith_operand" "rI"))
5522 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5525 [(set_attr "length" "2")])
5528 [(set (match_operand:DI 0 "register_operand" "")
5529 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5530 (match_operand:SI 2 "arith_operand" ""))
5531 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5532 "! TARGET_ARCH64 && reload_completed"
5533 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5534 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5535 (set (match_dup 4) (const_int 0))]
5536 "operands[3] = gen_lowpart (SImode, operands[0]);
5537 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5539 (define_insn "*addx_extend_sp64"
5540 [(set (match_operand:DI 0 "register_operand" "=r")
5541 (zero_extend:DI (plus:SI (plus: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 "addx\\t%r1, %2, %0"
5546 [(set_attr "type" "misc")])
5549 [(set (match_operand:SI 0 "register_operand" "=r")
5550 (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))))]
5554 "subx\\t%r1, %2, %0"
5555 [(set_attr "type" "misc")])
5557 (define_insn "*subx_extend_sp64"
5558 [(set (match_operand:DI 0 "register_operand" "=r")
5559 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5560 (match_operand:SI 2 "arith_operand" "rI"))
5561 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5563 "subx\\t%r1, %2, %0"
5564 [(set_attr "type" "misc")])
5566 (define_insn "*subx_extend"
5567 [(set (match_operand:DI 0 "register_operand" "=r")
5568 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5569 (match_operand:SI 2 "arith_operand" "rI"))
5570 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5573 [(set_attr "length" "2")])
5576 [(set (match_operand:DI 0 "register_operand" "")
5577 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5578 (match_operand:SI 2 "arith_operand" ""))
5579 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5580 "! TARGET_ARCH64 && reload_completed"
5581 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5582 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5583 (set (match_dup 4) (const_int 0))]
5584 "operands[3] = gen_lowpart (SImode, operands[0]);
5585 operands[4] = gen_highpart (SImode, operands[0]);")
5588 [(set (match_operand:DI 0 "register_operand" "=r")
5589 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5590 (match_operand:DI 2 "register_operand" "r")))
5591 (clobber (reg:CC 100))]
5594 [(set_attr "length" "2")])
5597 [(set (match_operand:DI 0 "register_operand" "")
5598 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5599 (match_operand:DI 2 "register_operand" "")))
5600 (clobber (reg:CC 100))]
5601 "! TARGET_ARCH64 && reload_completed"
5602 [(parallel [(set (reg:CC_NOOV 100)
5603 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5605 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5607 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5608 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5609 "operands[3] = gen_lowpart (SImode, operands[2]);
5610 operands[4] = gen_highpart (SImode, operands[2]);
5611 operands[5] = gen_lowpart (SImode, operands[0]);
5612 operands[6] = gen_highpart (SImode, operands[0]);")
5614 (define_insn "*adddi3_sp64"
5615 [(set (match_operand:DI 0 "register_operand" "=r")
5616 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5617 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5621 (define_expand "addsi3"
5622 [(set (match_operand:SI 0 "register_operand" "=r,d")
5623 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5624 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5628 if (arith_4096_operand(operands[2], SImode))
5630 if (GET_CODE (operands[1]) == CONST_INT)
5631 emit_insn (gen_movsi (operands[0],
5632 GEN_INT (INTVAL (operands[1]) + 4096)));
5634 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5635 gen_rtx_MINUS (SImode, operands[1],
5641 (define_insn "*addsi3"
5642 [(set (match_operand:SI 0 "register_operand" "=r,d")
5643 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5644 (match_operand:SI 2 "arith_operand" "rI,d")))]
5648 fpadd32s\\t%1, %2, %0"
5649 [(set_attr "type" "*,fp")])
5651 (define_insn "*cmp_cc_plus"
5652 [(set (reg:CC_NOOV 100)
5653 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5654 (match_operand:SI 1 "arith_operand" "rI"))
5657 "addcc\\t%0, %1, %%g0"
5658 [(set_attr "type" "compare")])
5660 (define_insn "*cmp_ccx_plus"
5661 [(set (reg:CCX_NOOV 100)
5662 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5663 (match_operand:DI 1 "arith_double_operand" "rHI"))
5666 "addcc\\t%0, %1, %%g0"
5667 [(set_attr "type" "compare")])
5669 (define_insn "*cmp_cc_plus_set"
5670 [(set (reg:CC_NOOV 100)
5671 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5672 (match_operand:SI 2 "arith_operand" "rI"))
5674 (set (match_operand:SI 0 "register_operand" "=r")
5675 (plus:SI (match_dup 1) (match_dup 2)))]
5677 "addcc\\t%1, %2, %0"
5678 [(set_attr "type" "compare")])
5680 (define_insn "*cmp_ccx_plus_set"
5681 [(set (reg:CCX_NOOV 100)
5682 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5683 (match_operand:DI 2 "arith_double_operand" "rHI"))
5685 (set (match_operand:DI 0 "register_operand" "=r")
5686 (plus:DI (match_dup 1) (match_dup 2)))]
5688 "addcc\\t%1, %2, %0"
5689 [(set_attr "type" "compare")])
5691 (define_expand "subdi3"
5692 [(set (match_operand:DI 0 "register_operand" "=r")
5693 (minus:DI (match_operand:DI 1 "register_operand" "r")
5694 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5698 if (! TARGET_ARCH64)
5700 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5701 gen_rtx_SET (VOIDmode, operands[0],
5702 gen_rtx_MINUS (DImode, operands[1],
5704 gen_rtx_CLOBBER (VOIDmode,
5705 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5708 if (arith_double_4096_operand(operands[2], DImode))
5710 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5711 gen_rtx_PLUS (DImode, operands[1],
5717 (define_insn "*subdi3_sp32"
5718 [(set (match_operand:DI 0 "register_operand" "=r")
5719 (minus:DI (match_operand:DI 1 "register_operand" "r")
5720 (match_operand:DI 2 "arith_double_operand" "rHI")))
5721 (clobber (reg:CC 100))]
5724 [(set_attr "length" "2")])
5727 [(set (match_operand:DI 0 "register_operand" "")
5728 (minus:DI (match_operand:DI 1 "register_operand" "")
5729 (match_operand:DI 2 "arith_double_operand" "")))
5730 (clobber (reg:CC 100))]
5733 && (GET_CODE (operands[2]) == CONST_INT
5734 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5735 [(clobber (const_int 0))]
5740 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5741 lowp = gen_lowpart (SImode, operands[2]);
5742 if ((lowp == const0_rtx)
5743 && (operands[0] == operands[1]))
5745 emit_insn (gen_rtx_SET (VOIDmode,
5746 gen_highpart (SImode, operands[0]),
5747 gen_rtx_MINUS (SImode,
5748 gen_highpart_mode (SImode, DImode,
5754 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5755 gen_lowpart (SImode, operands[1]),
5757 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5758 gen_highpart_mode (SImode, DImode, operands[1]),
5765 [(set (match_operand:DI 0 "register_operand" "")
5766 (minus:DI (match_operand:DI 1 "register_operand" "")
5767 (match_operand:DI 2 "register_operand" "")))
5768 (clobber (reg:CC 100))]
5770 && reload_completed"
5771 [(clobber (const_int 0))]
5774 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5775 gen_lowpart (SImode, operands[1]),
5776 gen_lowpart (SImode, operands[2])));
5777 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5778 gen_highpart (SImode, operands[1]),
5779 gen_highpart (SImode, operands[2])));
5784 [(set (match_operand:DI 0 "register_operand" "=r")
5785 (minus:DI (match_operand:DI 1 "register_operand" "r")
5786 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5787 (clobber (reg:CC 100))]
5790 [(set_attr "length" "2")])
5793 [(set (match_operand:DI 0 "register_operand" "")
5794 (minus:DI (match_operand:DI 1 "register_operand" "")
5795 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5796 (clobber (reg:CC 100))]
5797 "! TARGET_ARCH64 && reload_completed"
5798 [(parallel [(set (reg:CC_NOOV 100)
5799 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5801 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5803 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5804 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5805 "operands[3] = gen_lowpart (SImode, operands[1]);
5806 operands[4] = gen_highpart (SImode, operands[1]);
5807 operands[5] = gen_lowpart (SImode, operands[0]);
5808 operands[6] = gen_highpart (SImode, operands[0]);")
5810 (define_insn "*subdi3_sp64"
5811 [(set (match_operand:DI 0 "register_operand" "=r")
5812 (minus:DI (match_operand:DI 1 "register_operand" "r")
5813 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5817 (define_expand "subsi3"
5818 [(set (match_operand:SI 0 "register_operand" "=r,d")
5819 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5820 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5824 if (arith_4096_operand(operands[2], SImode))
5826 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5827 gen_rtx_PLUS (SImode, operands[1],
5833 (define_insn "*subsi3"
5834 [(set (match_operand:SI 0 "register_operand" "=r,d")
5835 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5836 (match_operand:SI 2 "arith_operand" "rI,d")))]
5840 fpsub32s\\t%1, %2, %0"
5841 [(set_attr "type" "*,fp")])
5843 (define_insn "*cmp_minus_cc"
5844 [(set (reg:CC_NOOV 100)
5845 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5846 (match_operand:SI 1 "arith_operand" "rI"))
5849 "subcc\\t%r0, %1, %%g0"
5850 [(set_attr "type" "compare")])
5852 (define_insn "*cmp_minus_ccx"
5853 [(set (reg:CCX_NOOV 100)
5854 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5855 (match_operand:DI 1 "arith_double_operand" "rHI"))
5858 "subcc\\t%0, %1, %%g0"
5859 [(set_attr "type" "compare")])
5861 (define_insn "cmp_minus_cc_set"
5862 [(set (reg:CC_NOOV 100)
5863 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5864 (match_operand:SI 2 "arith_operand" "rI"))
5866 (set (match_operand:SI 0 "register_operand" "=r")
5867 (minus:SI (match_dup 1) (match_dup 2)))]
5869 "subcc\\t%r1, %2, %0"
5870 [(set_attr "type" "compare")])
5872 (define_insn "*cmp_minus_ccx_set"
5873 [(set (reg:CCX_NOOV 100)
5874 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5875 (match_operand:DI 2 "arith_double_operand" "rHI"))
5877 (set (match_operand:DI 0 "register_operand" "=r")
5878 (minus:DI (match_dup 1) (match_dup 2)))]
5880 "subcc\\t%1, %2, %0"
5881 [(set_attr "type" "compare")])
5883 ;; Integer Multiply/Divide.
5885 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5886 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5888 (define_insn "mulsi3"
5889 [(set (match_operand:SI 0 "register_operand" "=r")
5890 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5891 (match_operand:SI 2 "arith_operand" "rI")))]
5894 [(set_attr "type" "imul")])
5896 (define_expand "muldi3"
5897 [(set (match_operand:DI 0 "register_operand" "=r")
5898 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5899 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5900 "TARGET_ARCH64 || TARGET_V8PLUS"
5905 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5910 (define_insn "*muldi3_sp64"
5911 [(set (match_operand:DI 0 "register_operand" "=r")
5912 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5913 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5916 [(set_attr "type" "imul")])
5918 ;; V8plus wide multiply.
5920 (define_insn "muldi3_v8plus"
5921 [(set (match_operand:DI 0 "register_operand" "=r,h")
5922 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5923 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5924 (clobber (match_scratch:SI 3 "=&h,X"))
5925 (clobber (match_scratch:SI 4 "=&h,X"))]
5929 if (sparc_check_64 (operands[1], insn) <= 0)
5930 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5931 if (which_alternative == 1)
5932 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5933 if (GET_CODE (operands[2]) == CONST_INT)
5935 if (which_alternative == 1)
5936 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5938 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\";
5940 if (sparc_check_64 (operands[2], insn) <= 0)
5941 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5942 if (which_alternative == 1)
5943 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\";
5945 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\";
5947 [(set_attr "type" "multi")
5948 (set_attr "length" "9,8")])
5950 (define_insn "*cmp_mul_set"
5952 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5953 (match_operand:SI 2 "arith_operand" "rI"))
5955 (set (match_operand:SI 0 "register_operand" "=r")
5956 (mult:SI (match_dup 1) (match_dup 2)))]
5957 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5958 "smulcc\\t%1, %2, %0"
5959 [(set_attr "type" "imul")])
5961 (define_expand "mulsidi3"
5962 [(set (match_operand:DI 0 "register_operand" "")
5963 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5964 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5968 if (CONSTANT_P (operands[2]))
5971 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5974 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5980 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5985 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5986 ;; registers can hold 64 bit values in the V8plus environment.
5988 (define_insn "mulsidi3_v8plus"
5989 [(set (match_operand:DI 0 "register_operand" "=h,r")
5990 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5991 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5992 (clobber (match_scratch:SI 3 "=X,&h"))]
5995 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5996 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5997 [(set_attr "type" "multi")
5998 (set_attr "length" "2,3")])
6001 (define_insn "const_mulsidi3_v8plus"
6002 [(set (match_operand:DI 0 "register_operand" "=h,r")
6003 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6004 (match_operand:SI 2 "small_int" "I,I")))
6005 (clobber (match_scratch:SI 3 "=X,&h"))]
6008 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6009 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6010 [(set_attr "type" "multi")
6011 (set_attr "length" "2,3")])
6014 (define_insn "*mulsidi3_sp32"
6015 [(set (match_operand:DI 0 "register_operand" "=r")
6016 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6017 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6021 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6024 (if_then_else (eq_attr "isa" "sparclet")
6025 (const_string "imul") (const_string "multi")))
6026 (set (attr "length")
6027 (if_then_else (eq_attr "isa" "sparclet")
6028 (const_int 1) (const_int 2)))])
6030 (define_insn "*mulsidi3_sp64"
6031 [(set (match_operand:DI 0 "register_operand" "=r")
6032 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6033 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6034 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6036 [(set_attr "type" "imul")])
6038 ;; Extra pattern, because sign_extend of a constant isn't valid.
6041 (define_insn "const_mulsidi3_sp32"
6042 [(set (match_operand:DI 0 "register_operand" "=r")
6043 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6044 (match_operand:SI 2 "small_int" "I")))]
6048 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6051 (if_then_else (eq_attr "isa" "sparclet")
6052 (const_string "imul") (const_string "multi")))
6053 (set (attr "length")
6054 (if_then_else (eq_attr "isa" "sparclet")
6055 (const_int 1) (const_int 2)))])
6057 (define_insn "const_mulsidi3_sp64"
6058 [(set (match_operand:DI 0 "register_operand" "=r")
6059 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6060 (match_operand:SI 2 "small_int" "I")))]
6061 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6063 [(set_attr "type" "imul")])
6065 (define_expand "smulsi3_highpart"
6066 [(set (match_operand:SI 0 "register_operand" "")
6068 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6069 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6071 "TARGET_HARD_MUL && TARGET_ARCH32"
6074 if (CONSTANT_P (operands[2]))
6078 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6084 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6089 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6090 operands[2], GEN_INT (32)));
6096 (define_insn "smulsi3_highpart_v8plus"
6097 [(set (match_operand:SI 0 "register_operand" "=h,r")
6099 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6100 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6101 (match_operand:SI 3 "const_int_operand" "i,i"))))
6102 (clobber (match_scratch:SI 4 "=X,&h"))]
6105 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6106 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6107 [(set_attr "type" "multi")
6108 (set_attr "length" "2")])
6110 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6113 [(set (match_operand:SI 0 "register_operand" "=h,r")
6116 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6117 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6118 (match_operand:SI 3 "const_int_operand" "i,i"))
6120 (clobber (match_scratch:SI 4 "=X,&h"))]
6123 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6124 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6125 [(set_attr "type" "multi")
6126 (set_attr "length" "2")])
6129 (define_insn "const_smulsi3_highpart_v8plus"
6130 [(set (match_operand:SI 0 "register_operand" "=h,r")
6132 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6133 (match_operand 2 "small_int" "i,i"))
6134 (match_operand:SI 3 "const_int_operand" "i,i"))))
6135 (clobber (match_scratch:SI 4 "=X,&h"))]
6138 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6139 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6140 [(set_attr "type" "multi")
6141 (set_attr "length" "2")])
6144 (define_insn "*smulsi3_highpart_sp32"
6145 [(set (match_operand:SI 0 "register_operand" "=r")
6147 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6148 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6151 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6152 [(set_attr "type" "multi")
6153 (set_attr "length" "2")])
6156 (define_insn "const_smulsi3_highpart"
6157 [(set (match_operand:SI 0 "register_operand" "=r")
6159 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6160 (match_operand:SI 2 "register_operand" "r"))
6163 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6164 [(set_attr "type" "multi")
6165 (set_attr "length" "2")])
6167 (define_expand "umulsidi3"
6168 [(set (match_operand:DI 0 "register_operand" "")
6169 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6170 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6174 if (CONSTANT_P (operands[2]))
6177 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6180 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6186 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6192 (define_insn "umulsidi3_v8plus"
6193 [(set (match_operand:DI 0 "register_operand" "=h,r")
6194 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6195 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6196 (clobber (match_scratch:SI 3 "=X,&h"))]
6199 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6200 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6201 [(set_attr "type" "multi")
6202 (set_attr "length" "2,3")])
6205 (define_insn "*umulsidi3_sp32"
6206 [(set (match_operand:DI 0 "register_operand" "=r")
6207 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6208 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6212 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6215 (if_then_else (eq_attr "isa" "sparclet")
6216 (const_string "imul") (const_string "multi")))
6217 (set (attr "length")
6218 (if_then_else (eq_attr "isa" "sparclet")
6219 (const_int 1) (const_int 2)))])
6221 (define_insn "*umulsidi3_sp64"
6222 [(set (match_operand:DI 0 "register_operand" "=r")
6223 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6224 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6225 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6227 [(set_attr "type" "imul")])
6229 ;; Extra pattern, because sign_extend of a constant isn't valid.
6232 (define_insn "const_umulsidi3_sp32"
6233 [(set (match_operand:DI 0 "register_operand" "=r")
6234 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6235 (match_operand:SI 2 "uns_small_int" "")))]
6239 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6242 (if_then_else (eq_attr "isa" "sparclet")
6243 (const_string "imul") (const_string "multi")))
6244 (set (attr "length")
6245 (if_then_else (eq_attr "isa" "sparclet")
6246 (const_int 1) (const_int 2)))])
6248 (define_insn "const_umulsidi3_sp64"
6249 [(set (match_operand:DI 0 "register_operand" "=r")
6250 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6251 (match_operand:SI 2 "uns_small_int" "")))]
6252 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6254 [(set_attr "type" "imul")])
6257 (define_insn "const_umulsidi3_v8plus"
6258 [(set (match_operand:DI 0 "register_operand" "=h,r")
6259 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6260 (match_operand:SI 2 "uns_small_int" "")))
6261 (clobber (match_scratch:SI 3 "=X,h"))]
6264 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6265 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6266 [(set_attr "type" "multi")
6267 (set_attr "length" "2,3")])
6269 (define_expand "umulsi3_highpart"
6270 [(set (match_operand:SI 0 "register_operand" "")
6272 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6273 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6275 "TARGET_HARD_MUL && TARGET_ARCH32"
6278 if (CONSTANT_P (operands[2]))
6282 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6288 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6293 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6294 operands[2], GEN_INT (32)));
6300 (define_insn "umulsi3_highpart_v8plus"
6301 [(set (match_operand:SI 0 "register_operand" "=h,r")
6303 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6304 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6305 (match_operand:SI 3 "const_int_operand" "i,i"))))
6306 (clobber (match_scratch:SI 4 "=X,h"))]
6309 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6310 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6311 [(set_attr "type" "multi")
6312 (set_attr "length" "2")])
6315 (define_insn "const_umulsi3_highpart_v8plus"
6316 [(set (match_operand:SI 0 "register_operand" "=h,r")
6318 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6319 (match_operand:SI 2 "uns_small_int" ""))
6320 (match_operand:SI 3 "const_int_operand" "i,i"))))
6321 (clobber (match_scratch:SI 4 "=X,h"))]
6324 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6325 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6326 [(set_attr "type" "multi")
6327 (set_attr "length" "2")])
6330 (define_insn "*umulsi3_highpart_sp32"
6331 [(set (match_operand:SI 0 "register_operand" "=r")
6333 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6334 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6337 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6338 [(set_attr "type" "multi")
6339 (set_attr "length" "2")])
6342 (define_insn "const_umulsi3_highpart"
6343 [(set (match_operand:SI 0 "register_operand" "=r")
6345 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6346 (match_operand:SI 2 "uns_small_int" ""))
6349 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6350 [(set_attr "type" "multi")
6351 (set_attr "length" "2")])
6353 ;; The v8 architecture specifies that there must be 3 instructions between
6354 ;; a y register write and a use of it for correct results.
6356 (define_expand "divsi3"
6357 [(parallel [(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"
6366 operands[3] = gen_reg_rtx(SImode);
6367 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6368 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6374 (define_insn "divsi3_sp32"
6375 [(set (match_operand:SI 0 "register_operand" "=r,r")
6376 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6377 (match_operand:SI 2 "input_operand" "rI,m")))
6378 (clobber (match_scratch:SI 3 "=&r,&r"))]
6379 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6383 if (which_alternative == 0)
6385 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6387 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6390 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6392 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\";
6394 [(set_attr "type" "multi")
6395 (set (attr "length")
6396 (if_then_else (eq_attr "isa" "v9")
6397 (const_int 4) (const_int 7)))])
6399 (define_insn "divsi3_sp64"
6400 [(set (match_operand:SI 0 "register_operand" "=r")
6401 (div:SI (match_operand:SI 1 "register_operand" "r")
6402 (match_operand:SI 2 "input_operand" "rI")))
6403 (use (match_operand:SI 3 "register_operand" "r"))]
6404 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6405 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6406 [(set_attr "type" "multi")
6407 (set_attr "length" "2")])
6409 (define_insn "divdi3"
6410 [(set (match_operand:DI 0 "register_operand" "=r")
6411 (div:DI (match_operand:DI 1 "register_operand" "r")
6412 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6414 "sdivx\\t%1, %2, %0"
6415 [(set_attr "type" "idiv")])
6417 (define_insn "*cmp_sdiv_cc_set"
6419 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6420 (match_operand:SI 2 "arith_operand" "rI"))
6422 (set (match_operand:SI 0 "register_operand" "=r")
6423 (div:SI (match_dup 1) (match_dup 2)))
6424 (clobber (match_scratch:SI 3 "=&r"))]
6425 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6429 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6431 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6433 [(set_attr "type" "multi")
6434 (set (attr "length")
6435 (if_then_else (eq_attr "isa" "v9")
6436 (const_int 3) (const_int 6)))])
6439 (define_expand "udivsi3"
6440 [(set (match_operand:SI 0 "register_operand" "")
6441 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6442 (match_operand:SI 2 "input_operand" "")))]
6443 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6446 (define_insn "udivsi3_sp32"
6447 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6448 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6449 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6451 || TARGET_DEPRECATED_V8_INSNS)
6455 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6456 switch (which_alternative)
6459 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6461 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6463 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6466 [(set_attr "type" "multi")
6467 (set_attr "length" "5")])
6469 (define_insn "udivsi3_sp64"
6470 [(set (match_operand:SI 0 "register_operand" "=r")
6471 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6472 (match_operand:SI 2 "input_operand" "rI")))]
6473 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6474 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6475 [(set_attr "type" "multi")
6476 (set_attr "length" "2")])
6478 (define_insn "udivdi3"
6479 [(set (match_operand:DI 0 "register_operand" "=r")
6480 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6481 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6483 "udivx\\t%1, %2, %0"
6484 [(set_attr "type" "idiv")])
6486 (define_insn "*cmp_udiv_cc_set"
6488 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6489 (match_operand:SI 2 "arith_operand" "rI"))
6491 (set (match_operand:SI 0 "register_operand" "=r")
6492 (udiv:SI (match_dup 1) (match_dup 2)))]
6494 || TARGET_DEPRECATED_V8_INSNS"
6498 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6500 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6502 [(set_attr "type" "multi")
6503 (set (attr "length")
6504 (if_then_else (eq_attr "isa" "v9")
6505 (const_int 2) (const_int 5)))])
6507 ; sparclet multiply/accumulate insns
6509 (define_insn "*smacsi"
6510 [(set (match_operand:SI 0 "register_operand" "=r")
6511 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6512 (match_operand:SI 2 "arith_operand" "rI"))
6513 (match_operand:SI 3 "register_operand" "0")))]
6516 [(set_attr "type" "imul")])
6518 (define_insn "*smacdi"
6519 [(set (match_operand:DI 0 "register_operand" "=r")
6520 (plus:DI (mult:DI (sign_extend:DI
6521 (match_operand:SI 1 "register_operand" "%r"))
6523 (match_operand:SI 2 "register_operand" "r")))
6524 (match_operand:DI 3 "register_operand" "0")))]
6526 "smacd\\t%1, %2, %L0"
6527 [(set_attr "type" "imul")])
6529 (define_insn "*umacdi"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (plus:DI (mult:DI (zero_extend:DI
6532 (match_operand:SI 1 "register_operand" "%r"))
6534 (match_operand:SI 2 "register_operand" "r")))
6535 (match_operand:DI 3 "register_operand" "0")))]
6537 "umacd\\t%1, %2, %L0"
6538 [(set_attr "type" "imul")])
6540 ;;- Boolean instructions
6541 ;; We define DImode `and' so with DImode `not' we can get
6542 ;; DImode `andn'. Other combinations are possible.
6544 (define_expand "anddi3"
6545 [(set (match_operand:DI 0 "register_operand" "")
6546 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6547 (match_operand:DI 2 "arith_double_operand" "")))]
6551 (define_insn "*anddi3_sp32"
6552 [(set (match_operand:DI 0 "register_operand" "=r,b")
6553 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6554 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6559 [(set_attr "type" "*,fp")
6560 (set_attr "length" "2,*")
6561 (set_attr "fptype" "double")])
6563 (define_insn "*anddi3_sp64"
6564 [(set (match_operand:DI 0 "register_operand" "=r,b")
6565 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6566 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6571 [(set_attr "type" "*,fp")
6572 (set_attr "fptype" "double")])
6574 (define_insn "andsi3"
6575 [(set (match_operand:SI 0 "register_operand" "=r,d")
6576 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6577 (match_operand:SI 2 "arith_operand" "rI,d")))]
6582 [(set_attr "type" "*,fp")])
6585 [(set (match_operand:SI 0 "register_operand" "")
6586 (and:SI (match_operand:SI 1 "register_operand" "")
6587 (match_operand:SI 2 "" "")))
6588 (clobber (match_operand:SI 3 "register_operand" ""))]
6589 "GET_CODE (operands[2]) == CONST_INT
6590 && !SMALL_INT32 (operands[2])
6591 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6592 [(set (match_dup 3) (match_dup 4))
6593 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6596 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6599 ;; Split DImode logical operations requiring two instructions.
6601 [(set (match_operand:DI 0 "register_operand" "")
6602 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6603 [(match_operand:DI 2 "register_operand" "")
6604 (match_operand:DI 3 "arith_double_operand" "")]))]
6607 && ((GET_CODE (operands[0]) == REG
6608 && REGNO (operands[0]) < 32)
6609 || (GET_CODE (operands[0]) == SUBREG
6610 && GET_CODE (SUBREG_REG (operands[0])) == REG
6611 && REGNO (SUBREG_REG (operands[0])) < 32))"
6612 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6613 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6616 if (GET_CODE (operands[0]) == SUBREG)
6617 operands[0] = alter_subreg (operands[0]);
6618 operands[4] = gen_highpart (SImode, operands[0]);
6619 operands[5] = gen_lowpart (SImode, operands[0]);
6620 operands[6] = gen_highpart (SImode, operands[2]);
6621 operands[7] = gen_lowpart (SImode, operands[2]);
6622 #if HOST_BITS_PER_WIDE_INT == 32
6623 if (GET_CODE (operands[3]) == CONST_INT)
6625 if (INTVAL (operands[3]) < 0)
6626 operands[8] = constm1_rtx;
6628 operands[8] = const0_rtx;
6632 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6633 operands[9] = gen_lowpart (SImode, operands[3]);
6636 (define_insn "*and_not_di_sp32"
6637 [(set (match_operand:DI 0 "register_operand" "=r,b")
6638 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6639 (match_operand:DI 2 "register_operand" "r,b")))]
6643 fandnot1\\t%1, %2, %0"
6644 [(set_attr "type" "*,fp")
6645 (set_attr "length" "2,*")
6646 (set_attr "fptype" "double")])
6649 [(set (match_operand:DI 0 "register_operand" "")
6650 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6651 (match_operand:DI 2 "register_operand" "")))]
6654 && ((GET_CODE (operands[0]) == REG
6655 && REGNO (operands[0]) < 32)
6656 || (GET_CODE (operands[0]) == SUBREG
6657 && GET_CODE (SUBREG_REG (operands[0])) == REG
6658 && REGNO (SUBREG_REG (operands[0])) < 32))"
6659 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6660 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6661 "if (GET_CODE (operands[0]) == SUBREG)
6662 operands[0] = alter_subreg (operands[0]);
6663 operands[3] = gen_highpart (SImode, operands[0]);
6664 operands[4] = gen_highpart (SImode, operands[1]);
6665 operands[5] = gen_highpart (SImode, operands[2]);
6666 operands[6] = gen_lowpart (SImode, operands[0]);
6667 operands[7] = gen_lowpart (SImode, operands[1]);
6668 operands[8] = gen_lowpart (SImode, operands[2]);")
6670 (define_insn "*and_not_di_sp64"
6671 [(set (match_operand:DI 0 "register_operand" "=r,b")
6672 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6673 (match_operand:DI 2 "register_operand" "r,b")))]
6677 fandnot1\\t%1, %2, %0"
6678 [(set_attr "type" "*,fp")
6679 (set_attr "fptype" "double")])
6681 (define_insn "*and_not_si"
6682 [(set (match_operand:SI 0 "register_operand" "=r,d")
6683 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6684 (match_operand:SI 2 "register_operand" "r,d")))]
6688 fandnot1s\\t%1, %2, %0"
6689 [(set_attr "type" "*,fp")])
6691 (define_expand "iordi3"
6692 [(set (match_operand:DI 0 "register_operand" "")
6693 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6694 (match_operand:DI 2 "arith_double_operand" "")))]
6698 (define_insn "*iordi3_sp32"
6699 [(set (match_operand:DI 0 "register_operand" "=r,b")
6700 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6701 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6706 [(set_attr "type" "*,fp")
6707 (set_attr "length" "2,*")
6708 (set_attr "fptype" "double")])
6710 (define_insn "*iordi3_sp64"
6711 [(set (match_operand:DI 0 "register_operand" "=r,b")
6712 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6713 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6718 [(set_attr "type" "*,fp")
6719 (set_attr "fptype" "double")])
6721 (define_insn "iorsi3"
6722 [(set (match_operand:SI 0 "register_operand" "=r,d")
6723 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6724 (match_operand:SI 2 "arith_operand" "rI,d")))]
6729 [(set_attr "type" "*,fp")])
6732 [(set (match_operand:SI 0 "register_operand" "")
6733 (ior:SI (match_operand:SI 1 "register_operand" "")
6734 (match_operand:SI 2 "" "")))
6735 (clobber (match_operand:SI 3 "register_operand" ""))]
6736 "GET_CODE (operands[2]) == CONST_INT
6737 && !SMALL_INT32 (operands[2])
6738 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6739 [(set (match_dup 3) (match_dup 4))
6740 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6743 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6746 (define_insn "*or_not_di_sp32"
6747 [(set (match_operand:DI 0 "register_operand" "=r,b")
6748 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6749 (match_operand:DI 2 "register_operand" "r,b")))]
6753 fornot1\\t%1, %2, %0"
6754 [(set_attr "type" "*,fp")
6755 (set_attr "length" "2,*")
6756 (set_attr "fptype" "double")])
6759 [(set (match_operand:DI 0 "register_operand" "")
6760 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6761 (match_operand:DI 2 "register_operand" "")))]
6764 && ((GET_CODE (operands[0]) == REG
6765 && REGNO (operands[0]) < 32)
6766 || (GET_CODE (operands[0]) == SUBREG
6767 && GET_CODE (SUBREG_REG (operands[0])) == REG
6768 && REGNO (SUBREG_REG (operands[0])) < 32))"
6769 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6770 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6771 "if (GET_CODE (operands[0]) == SUBREG)
6772 operands[0] = alter_subreg (operands[0]);
6773 operands[3] = gen_highpart (SImode, operands[0]);
6774 operands[4] = gen_highpart (SImode, operands[1]);
6775 operands[5] = gen_highpart (SImode, operands[2]);
6776 operands[6] = gen_lowpart (SImode, operands[0]);
6777 operands[7] = gen_lowpart (SImode, operands[1]);
6778 operands[8] = gen_lowpart (SImode, operands[2]);")
6780 (define_insn "*or_not_di_sp64"
6781 [(set (match_operand:DI 0 "register_operand" "=r,b")
6782 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6783 (match_operand:DI 2 "register_operand" "r,b")))]
6787 fornot1\\t%1, %2, %0"
6788 [(set_attr "type" "*,fp")
6789 (set_attr "fptype" "double")])
6791 (define_insn "*or_not_si"
6792 [(set (match_operand:SI 0 "register_operand" "=r,d")
6793 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6794 (match_operand:SI 2 "register_operand" "r,d")))]
6798 fornot1s\\t%1, %2, %0"
6799 [(set_attr "type" "*,fp")])
6801 (define_expand "xordi3"
6802 [(set (match_operand:DI 0 "register_operand" "")
6803 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6804 (match_operand:DI 2 "arith_double_operand" "")))]
6808 (define_insn "*xordi3_sp32"
6809 [(set (match_operand:DI 0 "register_operand" "=r,b")
6810 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6811 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6816 [(set_attr "type" "*,fp")
6817 (set_attr "length" "2,*")
6818 (set_attr "fptype" "double")])
6820 (define_insn "*xordi3_sp64"
6821 [(set (match_operand:DI 0 "register_operand" "=r,b")
6822 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6823 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6828 [(set_attr "type" "*,fp")
6829 (set_attr "fptype" "double")])
6831 (define_insn "*xordi3_sp64_dbl"
6832 [(set (match_operand:DI 0 "register_operand" "=r")
6833 (xor:DI (match_operand:DI 1 "register_operand" "r")
6834 (match_operand:DI 2 "const64_operand" "")))]
6836 && HOST_BITS_PER_WIDE_INT != 64)"
6839 (define_insn "xorsi3"
6840 [(set (match_operand:SI 0 "register_operand" "=r,d")
6841 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6842 (match_operand:SI 2 "arith_operand" "rI,d")))]
6847 [(set_attr "type" "*,fp")])
6850 [(set (match_operand:SI 0 "register_operand" "")
6851 (xor:SI (match_operand:SI 1 "register_operand" "")
6852 (match_operand:SI 2 "" "")))
6853 (clobber (match_operand:SI 3 "register_operand" ""))]
6854 "GET_CODE (operands[2]) == CONST_INT
6855 && !SMALL_INT32 (operands[2])
6856 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6857 [(set (match_dup 3) (match_dup 4))
6858 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6861 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6865 [(set (match_operand:SI 0 "register_operand" "")
6866 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6867 (match_operand:SI 2 "" ""))))
6868 (clobber (match_operand:SI 3 "register_operand" ""))]
6869 "GET_CODE (operands[2]) == CONST_INT
6870 && !SMALL_INT32 (operands[2])
6871 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6872 [(set (match_dup 3) (match_dup 4))
6873 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6876 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6879 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6880 ;; Combine now canonicalizes to the rightmost expression.
6881 (define_insn "*xor_not_di_sp32"
6882 [(set (match_operand:DI 0 "register_operand" "=r,b")
6883 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6884 (match_operand:DI 2 "register_operand" "r,b"))))]
6889 [(set_attr "type" "*,fp")
6890 (set_attr "length" "2,*")
6891 (set_attr "fptype" "double")])
6894 [(set (match_operand:DI 0 "register_operand" "")
6895 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6896 (match_operand:DI 2 "register_operand" ""))))]
6899 && ((GET_CODE (operands[0]) == REG
6900 && REGNO (operands[0]) < 32)
6901 || (GET_CODE (operands[0]) == SUBREG
6902 && GET_CODE (SUBREG_REG (operands[0])) == REG
6903 && REGNO (SUBREG_REG (operands[0])) < 32))"
6904 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6905 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6906 "if (GET_CODE (operands[0]) == SUBREG)
6907 operands[0] = alter_subreg (operands[0]);
6908 operands[3] = gen_highpart (SImode, operands[0]);
6909 operands[4] = gen_highpart (SImode, operands[1]);
6910 operands[5] = gen_highpart (SImode, operands[2]);
6911 operands[6] = gen_lowpart (SImode, operands[0]);
6912 operands[7] = gen_lowpart (SImode, operands[1]);
6913 operands[8] = gen_lowpart (SImode, operands[2]);")
6915 (define_insn "*xor_not_di_sp64"
6916 [(set (match_operand:DI 0 "register_operand" "=r,b")
6917 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6918 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6923 [(set_attr "type" "*,fp")
6924 (set_attr "fptype" "double")])
6926 (define_insn "*xor_not_si"
6927 [(set (match_operand:SI 0 "register_operand" "=r,d")
6928 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6929 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6933 fxnors\\t%1, %2, %0"
6934 [(set_attr "type" "*,fp")])
6936 ;; These correspond to the above in the case where we also (or only)
6937 ;; want to set the condition code.
6939 (define_insn "*cmp_cc_arith_op"
6942 (match_operator:SI 2 "cc_arithop"
6943 [(match_operand:SI 0 "arith_operand" "%r")
6944 (match_operand:SI 1 "arith_operand" "rI")])
6947 "%A2cc\\t%0, %1, %%g0"
6948 [(set_attr "type" "compare")])
6950 (define_insn "*cmp_ccx_arith_op"
6953 (match_operator:DI 2 "cc_arithop"
6954 [(match_operand:DI 0 "arith_double_operand" "%r")
6955 (match_operand:DI 1 "arith_double_operand" "rHI")])
6958 "%A2cc\\t%0, %1, %%g0"
6959 [(set_attr "type" "compare")])
6961 (define_insn "*cmp_cc_arith_op_set"
6964 (match_operator:SI 3 "cc_arithop"
6965 [(match_operand:SI 1 "arith_operand" "%r")
6966 (match_operand:SI 2 "arith_operand" "rI")])
6968 (set (match_operand:SI 0 "register_operand" "=r")
6969 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6970 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6971 "%A3cc\\t%1, %2, %0"
6972 [(set_attr "type" "compare")])
6974 (define_insn "*cmp_ccx_arith_op_set"
6977 (match_operator:DI 3 "cc_arithop"
6978 [(match_operand:DI 1 "arith_double_operand" "%r")
6979 (match_operand:DI 2 "arith_double_operand" "rHI")])
6981 (set (match_operand:DI 0 "register_operand" "=r")
6982 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6983 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6984 "%A3cc\\t%1, %2, %0"
6985 [(set_attr "type" "compare")])
6987 (define_insn "*cmp_cc_xor_not"
6990 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6991 (match_operand:SI 1 "arith_operand" "rI")))
6994 "xnorcc\\t%r0, %1, %%g0"
6995 [(set_attr "type" "compare")])
6997 (define_insn "*cmp_ccx_xor_not"
7000 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7001 (match_operand:DI 1 "arith_double_operand" "rHI")))
7004 "xnorcc\\t%r0, %1, %%g0"
7005 [(set_attr "type" "compare")])
7007 (define_insn "*cmp_cc_xor_not_set"
7010 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7011 (match_operand:SI 2 "arith_operand" "rI")))
7013 (set (match_operand:SI 0 "register_operand" "=r")
7014 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7016 "xnorcc\\t%r1, %2, %0"
7017 [(set_attr "type" "compare")])
7019 (define_insn "*cmp_ccx_xor_not_set"
7022 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7023 (match_operand:DI 2 "arith_double_operand" "rHI")))
7025 (set (match_operand:DI 0 "register_operand" "=r")
7026 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7028 "xnorcc\\t%r1, %2, %0"
7029 [(set_attr "type" "compare")])
7031 (define_insn "*cmp_cc_arith_op_not"
7034 (match_operator:SI 2 "cc_arithopn"
7035 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7036 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7039 "%B2cc\\t%r1, %0, %%g0"
7040 [(set_attr "type" "compare")])
7042 (define_insn "*cmp_ccx_arith_op_not"
7045 (match_operator:DI 2 "cc_arithopn"
7046 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7047 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7050 "%B2cc\\t%r1, %0, %%g0"
7051 [(set_attr "type" "compare")])
7053 (define_insn "*cmp_cc_arith_op_not_set"
7056 (match_operator:SI 3 "cc_arithopn"
7057 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7058 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7060 (set (match_operand:SI 0 "register_operand" "=r")
7061 (match_operator:SI 4 "cc_arithopn"
7062 [(not:SI (match_dup 1)) (match_dup 2)]))]
7063 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7064 "%B3cc\\t%r2, %1, %0"
7065 [(set_attr "type" "compare")])
7067 (define_insn "*cmp_ccx_arith_op_not_set"
7070 (match_operator:DI 3 "cc_arithopn"
7071 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7072 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7074 (set (match_operand:DI 0 "register_operand" "=r")
7075 (match_operator:DI 4 "cc_arithopn"
7076 [(not:DI (match_dup 1)) (match_dup 2)]))]
7077 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7078 "%B3cc\\t%r2, %1, %0"
7079 [(set_attr "type" "compare")])
7081 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7082 ;; does not know how to make it work for constants.
7084 (define_expand "negdi2"
7085 [(set (match_operand:DI 0 "register_operand" "=r")
7086 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7090 if (! TARGET_ARCH64)
7092 emit_insn (gen_rtx_PARALLEL
7095 gen_rtx_SET (VOIDmode, operand0,
7096 gen_rtx_NEG (DImode, operand1)),
7097 gen_rtx_CLOBBER (VOIDmode,
7098 gen_rtx_REG (CCmode,
7104 (define_insn "*negdi2_sp32"
7105 [(set (match_operand:DI 0 "register_operand" "=r")
7106 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7107 (clobber (reg:CC 100))]
7110 [(set_attr "length" "2")])
7113 [(set (match_operand:DI 0 "register_operand" "")
7114 (neg:DI (match_operand:DI 1 "register_operand" "")))
7115 (clobber (reg:CC 100))]
7117 && reload_completed"
7118 [(parallel [(set (reg:CC_NOOV 100)
7119 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7121 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7122 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7123 (ltu:SI (reg:CC 100) (const_int 0))))]
7124 "operands[2] = gen_highpart (SImode, operands[0]);
7125 operands[3] = gen_highpart (SImode, operands[1]);
7126 operands[4] = gen_lowpart (SImode, operands[0]);
7127 operands[5] = gen_lowpart (SImode, operands[1]);")
7129 (define_insn "*negdi2_sp64"
7130 [(set (match_operand:DI 0 "register_operand" "=r")
7131 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7133 "sub\\t%%g0, %1, %0")
7135 (define_insn "negsi2"
7136 [(set (match_operand:SI 0 "register_operand" "=r")
7137 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7139 "sub\\t%%g0, %1, %0")
7141 (define_insn "*cmp_cc_neg"
7142 [(set (reg:CC_NOOV 100)
7143 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7146 "subcc\\t%%g0, %0, %%g0"
7147 [(set_attr "type" "compare")])
7149 (define_insn "*cmp_ccx_neg"
7150 [(set (reg:CCX_NOOV 100)
7151 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7154 "subcc\\t%%g0, %0, %%g0"
7155 [(set_attr "type" "compare")])
7157 (define_insn "*cmp_cc_set_neg"
7158 [(set (reg:CC_NOOV 100)
7159 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7161 (set (match_operand:SI 0 "register_operand" "=r")
7162 (neg:SI (match_dup 1)))]
7164 "subcc\\t%%g0, %1, %0"
7165 [(set_attr "type" "compare")])
7167 (define_insn "*cmp_ccx_set_neg"
7168 [(set (reg:CCX_NOOV 100)
7169 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7171 (set (match_operand:DI 0 "register_operand" "=r")
7172 (neg:DI (match_dup 1)))]
7174 "subcc\\t%%g0, %1, %0"
7175 [(set_attr "type" "compare")])
7177 ;; We cannot use the "not" pseudo insn because the Sun assembler
7178 ;; does not know how to make it work for constants.
7179 (define_expand "one_cmpldi2"
7180 [(set (match_operand:DI 0 "register_operand" "")
7181 (not:DI (match_operand:DI 1 "register_operand" "")))]
7185 (define_insn "*one_cmpldi2_sp32"
7186 [(set (match_operand:DI 0 "register_operand" "=r,b")
7187 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7192 [(set_attr "type" "*,fp")
7193 (set_attr "length" "2,*")
7194 (set_attr "fptype" "double")])
7197 [(set (match_operand:DI 0 "register_operand" "")
7198 (not:DI (match_operand:DI 1 "register_operand" "")))]
7201 && ((GET_CODE (operands[0]) == REG
7202 && REGNO (operands[0]) < 32)
7203 || (GET_CODE (operands[0]) == SUBREG
7204 && GET_CODE (SUBREG_REG (operands[0])) == REG
7205 && REGNO (SUBREG_REG (operands[0])) < 32))"
7206 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7207 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7208 "if (GET_CODE (operands[0]) == SUBREG)
7209 operands[0] = alter_subreg (operands[0]);
7210 operands[2] = gen_highpart (SImode, operands[0]);
7211 operands[3] = gen_highpart (SImode, operands[1]);
7212 operands[4] = gen_lowpart (SImode, operands[0]);
7213 operands[5] = gen_lowpart (SImode, operands[1]);")
7215 (define_insn "*one_cmpldi2_sp64"
7216 [(set (match_operand:DI 0 "register_operand" "=r,b")
7217 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7222 [(set_attr "type" "*,fp")
7223 (set_attr "fptype" "double")])
7225 (define_insn "one_cmplsi2"
7226 [(set (match_operand:SI 0 "register_operand" "=r,d")
7227 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7232 [(set_attr "type" "*,fp")])
7234 (define_insn "*cmp_cc_not"
7236 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7239 "xnorcc\\t%%g0, %0, %%g0"
7240 [(set_attr "type" "compare")])
7242 (define_insn "*cmp_ccx_not"
7244 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7247 "xnorcc\\t%%g0, %0, %%g0"
7248 [(set_attr "type" "compare")])
7250 (define_insn "*cmp_cc_set_not"
7252 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7254 (set (match_operand:SI 0 "register_operand" "=r")
7255 (not:SI (match_dup 1)))]
7257 "xnorcc\\t%%g0, %1, %0"
7258 [(set_attr "type" "compare")])
7260 (define_insn "*cmp_ccx_set_not"
7262 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7264 (set (match_operand:DI 0 "register_operand" "=r")
7265 (not:DI (match_dup 1)))]
7267 "xnorcc\\t%%g0, %1, %0"
7268 [(set_attr "type" "compare")])
7270 ;; Floating point arithmetic instructions.
7272 (define_expand "addtf3"
7273 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7274 (plus:TF (match_operand:TF 1 "general_operand" "")
7275 (match_operand:TF 2 "general_operand" "")))]
7276 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7279 if (! TARGET_HARD_QUAD)
7281 rtx slot0, slot1, slot2;
7283 if (GET_CODE (operands[0]) != MEM)
7284 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7286 slot0 = operands[0];
7287 if (GET_CODE (operands[1]) != MEM)
7289 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7290 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7293 slot1 = operands[1];
7294 if (GET_CODE (operands[2]) != MEM)
7296 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7297 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7300 slot2 = operands[2];
7302 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7304 XEXP (slot0, 0), Pmode,
7305 XEXP (slot1, 0), Pmode,
7306 XEXP (slot2, 0), Pmode);
7308 if (GET_CODE (operands[0]) != MEM)
7309 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7314 (define_insn "*addtf3_hq"
7315 [(set (match_operand:TF 0 "register_operand" "=e")
7316 (plus:TF (match_operand:TF 1 "register_operand" "e")
7317 (match_operand:TF 2 "register_operand" "e")))]
7318 "TARGET_FPU && TARGET_HARD_QUAD"
7319 "faddq\\t%1, %2, %0"
7320 [(set_attr "type" "fp")])
7322 (define_insn "adddf3"
7323 [(set (match_operand:DF 0 "register_operand" "=e")
7324 (plus:DF (match_operand:DF 1 "register_operand" "e")
7325 (match_operand:DF 2 "register_operand" "e")))]
7327 "faddd\\t%1, %2, %0"
7328 [(set_attr "type" "fp")
7329 (set_attr "fptype" "double")])
7331 (define_insn "addsf3"
7332 [(set (match_operand:SF 0 "register_operand" "=f")
7333 (plus:SF (match_operand:SF 1 "register_operand" "f")
7334 (match_operand:SF 2 "register_operand" "f")))]
7336 "fadds\\t%1, %2, %0"
7337 [(set_attr "type" "fp")])
7339 (define_expand "subtf3"
7340 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7341 (minus:TF (match_operand:TF 1 "general_operand" "")
7342 (match_operand:TF 2 "general_operand" "")))]
7343 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7346 if (! TARGET_HARD_QUAD)
7348 rtx slot0, slot1, slot2;
7350 if (GET_CODE (operands[0]) != MEM)
7351 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7353 slot0 = operands[0];
7354 if (GET_CODE (operands[1]) != MEM)
7356 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7357 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7360 slot1 = operands[1];
7361 if (GET_CODE (operands[2]) != MEM)
7363 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7364 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7367 slot2 = operands[2];
7369 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7371 XEXP (slot0, 0), Pmode,
7372 XEXP (slot1, 0), Pmode,
7373 XEXP (slot2, 0), Pmode);
7375 if (GET_CODE (operands[0]) != MEM)
7376 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7381 (define_insn "*subtf3_hq"
7382 [(set (match_operand:TF 0 "register_operand" "=e")
7383 (minus:TF (match_operand:TF 1 "register_operand" "e")
7384 (match_operand:TF 2 "register_operand" "e")))]
7385 "TARGET_FPU && TARGET_HARD_QUAD"
7386 "fsubq\\t%1, %2, %0"
7387 [(set_attr "type" "fp")])
7389 (define_insn "subdf3"
7390 [(set (match_operand:DF 0 "register_operand" "=e")
7391 (minus:DF (match_operand:DF 1 "register_operand" "e")
7392 (match_operand:DF 2 "register_operand" "e")))]
7394 "fsubd\\t%1, %2, %0"
7395 [(set_attr "type" "fp")
7396 (set_attr "fptype" "double")])
7398 (define_insn "subsf3"
7399 [(set (match_operand:SF 0 "register_operand" "=f")
7400 (minus:SF (match_operand:SF 1 "register_operand" "f")
7401 (match_operand:SF 2 "register_operand" "f")))]
7403 "fsubs\\t%1, %2, %0"
7404 [(set_attr "type" "fp")])
7406 (define_expand "multf3"
7407 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7408 (mult:TF (match_operand:TF 1 "general_operand" "")
7409 (match_operand:TF 2 "general_operand" "")))]
7410 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7413 if (! TARGET_HARD_QUAD)
7415 rtx slot0, slot1, slot2;
7417 if (GET_CODE (operands[0]) != MEM)
7418 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7420 slot0 = operands[0];
7421 if (GET_CODE (operands[1]) != MEM)
7423 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7424 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7427 slot1 = operands[1];
7428 if (GET_CODE (operands[2]) != MEM)
7430 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7431 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7434 slot2 = operands[2];
7436 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7438 XEXP (slot0, 0), Pmode,
7439 XEXP (slot1, 0), Pmode,
7440 XEXP (slot2, 0), Pmode);
7442 if (GET_CODE (operands[0]) != MEM)
7443 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7448 (define_insn "*multf3_hq"
7449 [(set (match_operand:TF 0 "register_operand" "=e")
7450 (mult:TF (match_operand:TF 1 "register_operand" "e")
7451 (match_operand:TF 2 "register_operand" "e")))]
7452 "TARGET_FPU && TARGET_HARD_QUAD"
7453 "fmulq\\t%1, %2, %0"
7454 [(set_attr "type" "fpmul")])
7456 (define_insn "muldf3"
7457 [(set (match_operand:DF 0 "register_operand" "=e")
7458 (mult:DF (match_operand:DF 1 "register_operand" "e")
7459 (match_operand:DF 2 "register_operand" "e")))]
7461 "fmuld\\t%1, %2, %0"
7462 [(set_attr "type" "fpmul")
7463 (set_attr "fptype" "double")])
7465 (define_insn "mulsf3"
7466 [(set (match_operand:SF 0 "register_operand" "=f")
7467 (mult:SF (match_operand:SF 1 "register_operand" "f")
7468 (match_operand:SF 2 "register_operand" "f")))]
7470 "fmuls\\t%1, %2, %0"
7471 [(set_attr "type" "fpmul")])
7473 (define_insn "*muldf3_extend"
7474 [(set (match_operand:DF 0 "register_operand" "=e")
7475 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7476 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7477 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7478 "fsmuld\\t%1, %2, %0"
7479 [(set_attr "type" "fpmul")
7480 (set_attr "fptype" "double")])
7482 (define_insn "*multf3_extend"
7483 [(set (match_operand:TF 0 "register_operand" "=e")
7484 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7485 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7486 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7487 "fdmulq\\t%1, %2, %0"
7488 [(set_attr "type" "fpmul")])
7490 (define_expand "divtf3"
7491 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7492 (div:TF (match_operand:TF 1 "general_operand" "")
7493 (match_operand:TF 2 "general_operand" "")))]
7494 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7497 if (! TARGET_HARD_QUAD)
7499 rtx slot0, slot1, slot2;
7501 if (GET_CODE (operands[0]) != MEM)
7502 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7504 slot0 = operands[0];
7505 if (GET_CODE (operands[1]) != MEM)
7507 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7508 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7511 slot1 = operands[1];
7512 if (GET_CODE (operands[2]) != MEM)
7514 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7515 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7518 slot2 = operands[2];
7520 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7522 XEXP (slot0, 0), Pmode,
7523 XEXP (slot1, 0), Pmode,
7524 XEXP (slot2, 0), Pmode);
7526 if (GET_CODE (operands[0]) != MEM)
7527 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7532 ;; don't have timing for quad-prec. divide.
7533 (define_insn "*divtf3_hq"
7534 [(set (match_operand:TF 0 "register_operand" "=e")
7535 (div:TF (match_operand:TF 1 "register_operand" "e")
7536 (match_operand:TF 2 "register_operand" "e")))]
7537 "TARGET_FPU && TARGET_HARD_QUAD"
7538 "fdivq\\t%1, %2, %0"
7539 [(set_attr "type" "fpdivd")])
7541 (define_insn "divdf3"
7542 [(set (match_operand:DF 0 "register_operand" "=e")
7543 (div:DF (match_operand:DF 1 "register_operand" "e")
7544 (match_operand:DF 2 "register_operand" "e")))]
7546 "fdivd\\t%1, %2, %0"
7547 [(set_attr "type" "fpdivd")
7548 (set_attr "fptype" "double")])
7550 (define_insn "divsf3"
7551 [(set (match_operand:SF 0 "register_operand" "=f")
7552 (div:SF (match_operand:SF 1 "register_operand" "f")
7553 (match_operand:SF 2 "register_operand" "f")))]
7555 "fdivs\\t%1, %2, %0"
7556 [(set_attr "type" "fpdivs")])
7558 (define_expand "negtf2"
7559 [(set (match_operand:TF 0 "register_operand" "=e,e")
7560 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7564 (define_insn "*negtf2_notv9"
7565 [(set (match_operand:TF 0 "register_operand" "=e,e")
7566 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7567 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7573 [(set_attr "type" "fpmove,*")
7574 (set_attr "length" "*,2")])
7577 [(set (match_operand:TF 0 "register_operand" "")
7578 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7582 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7583 [(set (match_dup 2) (neg:SF (match_dup 3)))
7584 (set (match_dup 4) (match_dup 5))
7585 (set (match_dup 6) (match_dup 7))]
7586 "if (GET_CODE (operands[0]) == SUBREG)
7587 operands[0] = alter_subreg (operands[0]);
7588 if (GET_CODE (operands[1]) == SUBREG)
7589 operands[1] = alter_subreg (operands[1]);
7590 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7591 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7592 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7593 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7594 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7595 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7597 (define_insn "*negtf2_v9"
7598 [(set (match_operand:TF 0 "register_operand" "=e,e")
7599 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7600 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7601 "TARGET_FPU && TARGET_V9"
7605 [(set_attr "type" "fpmove,*")
7606 (set_attr "length" "*,2")
7607 (set_attr "fptype" "double")])
7610 [(set (match_operand:TF 0 "register_operand" "")
7611 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7615 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7616 [(set (match_dup 2) (neg:DF (match_dup 3)))
7617 (set (match_dup 4) (match_dup 5))]
7618 "if (GET_CODE (operands[0]) == SUBREG)
7619 operands[0] = alter_subreg (operands[0]);
7620 if (GET_CODE (operands[1]) == SUBREG)
7621 operands[1] = alter_subreg (operands[1]);
7622 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7623 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7624 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7625 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7627 (define_expand "negdf2"
7628 [(set (match_operand:DF 0 "register_operand" "")
7629 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7633 (define_insn "*negdf2_notv9"
7634 [(set (match_operand:DF 0 "register_operand" "=e,e")
7635 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7636 "TARGET_FPU && ! TARGET_V9"
7640 [(set_attr "type" "fpmove,*")
7641 (set_attr "length" "*,2")])
7644 [(set (match_operand:DF 0 "register_operand" "")
7645 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7649 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7650 [(set (match_dup 2) (neg:SF (match_dup 3)))
7651 (set (match_dup 4) (match_dup 5))]
7652 "if (GET_CODE (operands[0]) == SUBREG)
7653 operands[0] = alter_subreg (operands[0]);
7654 if (GET_CODE (operands[1]) == SUBREG)
7655 operands[1] = alter_subreg (operands[1]);
7656 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7657 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7658 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7659 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7661 (define_insn "*negdf2_v9"
7662 [(set (match_operand:DF 0 "register_operand" "=e")
7663 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7664 "TARGET_FPU && TARGET_V9"
7666 [(set_attr "type" "fpmove")
7667 (set_attr "fptype" "double")])
7669 (define_insn "negsf2"
7670 [(set (match_operand:SF 0 "register_operand" "=f")
7671 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7674 [(set_attr "type" "fpmove")])
7676 (define_expand "abstf2"
7677 [(set (match_operand:TF 0 "register_operand" "")
7678 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7682 (define_insn "*abstf2_notv9"
7683 [(set (match_operand:TF 0 "register_operand" "=e,e")
7684 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7685 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7686 "TARGET_FPU && ! TARGET_V9"
7690 [(set_attr "type" "fpmove,*")
7691 (set_attr "length" "*,2")])
7694 [(set (match_operand:TF 0 "register_operand" "")
7695 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7699 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7700 [(set (match_dup 2) (abs:SF (match_dup 3)))
7701 (set (match_dup 4) (match_dup 5))
7702 (set (match_dup 6) (match_dup 7))]
7703 "if (GET_CODE (operands[0]) == SUBREG)
7704 operands[0] = alter_subreg (operands[0]);
7705 if (GET_CODE (operands[1]) == SUBREG)
7706 operands[1] = alter_subreg (operands[1]);
7707 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7708 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7709 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7710 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7711 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7712 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7714 (define_insn "*abstf2_hq_v9"
7715 [(set (match_operand:TF 0 "register_operand" "=e,e")
7716 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7717 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7721 [(set_attr "type" "fpmove")
7722 (set_attr "fptype" "double,*")])
7724 (define_insn "*abstf2_v9"
7725 [(set (match_operand:TF 0 "register_operand" "=e,e")
7726 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7727 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7731 [(set_attr "type" "fpmove,*")
7732 (set_attr "length" "*,2")
7733 (set_attr "fptype" "double,*")])
7736 [(set (match_operand:TF 0 "register_operand" "")
7737 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7741 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7742 [(set (match_dup 2) (abs:DF (match_dup 3)))
7743 (set (match_dup 4) (match_dup 5))]
7744 "if (GET_CODE (operands[0]) == SUBREG)
7745 operands[0] = alter_subreg (operands[0]);
7746 if (GET_CODE (operands[1]) == SUBREG)
7747 operands[1] = alter_subreg (operands[1]);
7748 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7749 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7750 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7751 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7753 (define_expand "absdf2"
7754 [(set (match_operand:DF 0 "register_operand" "")
7755 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7759 (define_insn "*absdf2_notv9"
7760 [(set (match_operand:DF 0 "register_operand" "=e,e")
7761 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7762 "TARGET_FPU && ! TARGET_V9"
7766 [(set_attr "type" "fpmove,*")
7767 (set_attr "length" "*,2")])
7770 [(set (match_operand:DF 0 "register_operand" "")
7771 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7775 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7776 [(set (match_dup 2) (abs:SF (match_dup 3)))
7777 (set (match_dup 4) (match_dup 5))]
7778 "if (GET_CODE (operands[0]) == SUBREG)
7779 operands[0] = alter_subreg (operands[0]);
7780 if (GET_CODE (operands[1]) == SUBREG)
7781 operands[1] = alter_subreg (operands[1]);
7782 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7783 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7784 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7785 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7787 (define_insn "*absdf2_v9"
7788 [(set (match_operand:DF 0 "register_operand" "=e")
7789 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7790 "TARGET_FPU && TARGET_V9"
7792 [(set_attr "type" "fpmove")
7793 (set_attr "fptype" "double")])
7795 (define_insn "abssf2"
7796 [(set (match_operand:SF 0 "register_operand" "=f")
7797 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7800 [(set_attr "type" "fpmove")])
7802 (define_expand "sqrttf2"
7803 [(set (match_operand:TF 0 "register_operand" "=e")
7804 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7805 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7808 if (! TARGET_HARD_QUAD)
7812 if (GET_CODE (operands[0]) != MEM)
7813 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7815 slot0 = operands[0];
7816 if (GET_CODE (operands[1]) != MEM)
7818 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7819 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7822 slot1 = operands[1];
7824 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7826 XEXP (slot0, 0), Pmode,
7827 XEXP (slot1, 0), Pmode);
7829 if (GET_CODE (operands[0]) != MEM)
7830 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7835 (define_insn "*sqrttf2_hq"
7836 [(set (match_operand:TF 0 "register_operand" "=e")
7837 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7838 "TARGET_FPU && TARGET_HARD_QUAD"
7840 [(set_attr "type" "fpsqrtd")])
7842 (define_insn "sqrtdf2"
7843 [(set (match_operand:DF 0 "register_operand" "=e")
7844 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7847 [(set_attr "type" "fpsqrtd")
7848 (set_attr "fptype" "double")])
7850 (define_insn "sqrtsf2"
7851 [(set (match_operand:SF 0 "register_operand" "=f")
7852 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7855 [(set_attr "type" "fpsqrts")])
7857 ;;- arithmetic shift instructions
7859 (define_insn "ashlsi3"
7860 [(set (match_operand:SI 0 "register_operand" "=r")
7861 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7862 (match_operand:SI 2 "arith_operand" "rI")))]
7866 if (GET_CODE (operands[2]) == CONST_INT
7867 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7868 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7870 return \"sll\\t%1, %2, %0\";
7872 [(set_attr "type" "shift")])
7874 ;; We special case multiplication by two, as add can be done
7875 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7876 (define_insn "*ashlsi3_const1"
7877 [(set (match_operand:SI 0 "register_operand" "=r")
7878 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7883 (define_expand "ashldi3"
7884 [(set (match_operand:DI 0 "register_operand" "=r")
7885 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7886 (match_operand:SI 2 "arith_operand" "rI")))]
7887 "TARGET_ARCH64 || TARGET_V8PLUS"
7890 if (! TARGET_ARCH64)
7892 if (GET_CODE (operands[2]) == CONST_INT)
7894 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7899 ;; We special case multiplication by two, as add can be done
7900 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7901 (define_insn "*ashldi3_const1"
7902 [(set (match_operand:DI 0 "register_operand" "=r")
7903 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7908 (define_insn "*ashldi3_sp64"
7909 [(set (match_operand:DI 0 "register_operand" "=r")
7910 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7911 (match_operand:SI 2 "arith_operand" "rI")))]
7915 if (GET_CODE (operands[2]) == CONST_INT
7916 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7917 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7919 return \"sllx\\t%1, %2, %0\";
7921 [(set_attr "type" "shift")])
7924 (define_insn "ashldi3_v8plus"
7925 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7926 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7927 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7928 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7930 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7931 [(set_attr "type" "multi")
7932 (set_attr "length" "5,5,6")])
7934 ;; Optimize (1LL<<x)-1
7935 ;; XXX this also needs to be fixed to handle equal subregs
7936 ;; XXX first before we could re-enable it.
7938 ; [(set (match_operand:DI 0 "register_operand" "=h")
7939 ; (plus:DI (ashift:DI (const_int 1)
7940 ; (match_operand:SI 1 "arith_operand" "rI"))
7942 ; "0 && TARGET_V8PLUS"
7945 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7946 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7947 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7949 ; [(set_attr "type" "multi")
7950 ; (set_attr "length" "4")])
7952 (define_insn "*cmp_cc_ashift_1"
7953 [(set (reg:CC_NOOV 100)
7954 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7958 "addcc\\t%0, %0, %%g0"
7959 [(set_attr "type" "compare")])
7961 (define_insn "*cmp_cc_set_ashift_1"
7962 [(set (reg:CC_NOOV 100)
7963 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7966 (set (match_operand:SI 0 "register_operand" "=r")
7967 (ashift:SI (match_dup 1) (const_int 1)))]
7969 "addcc\\t%1, %1, %0"
7970 [(set_attr "type" "compare")])
7972 (define_insn "ashrsi3"
7973 [(set (match_operand:SI 0 "register_operand" "=r")
7974 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7975 (match_operand:SI 2 "arith_operand" "rI")))]
7979 if (GET_CODE (operands[2]) == CONST_INT
7980 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7981 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7983 return \"sra\\t%1, %2, %0\";
7985 [(set_attr "type" "shift")])
7987 (define_insn "*ashrsi3_extend"
7988 [(set (match_operand:DI 0 "register_operand" "=r")
7989 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7990 (match_operand:SI 2 "arith_operand" "r"))))]
7993 [(set_attr "type" "shift")])
7995 ;; This handles the case as above, but with constant shift instead of
7996 ;; register. Combiner "simplifies" it for us a little bit though.
7997 (define_insn "*ashrsi3_extend2"
7998 [(set (match_operand:DI 0 "register_operand" "=r")
7999 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8001 (match_operand:SI 2 "small_int_or_double" "n")))]
8003 && ((GET_CODE (operands[2]) == CONST_INT
8004 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8005 || (GET_CODE (operands[2]) == CONST_DOUBLE
8006 && !CONST_DOUBLE_HIGH (operands[2])
8007 && CONST_DOUBLE_LOW (operands[2]) >= 32
8008 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8011 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8013 return \"sra\\t%1, %2, %0\";
8015 [(set_attr "type" "shift")])
8017 (define_expand "ashrdi3"
8018 [(set (match_operand:DI 0 "register_operand" "=r")
8019 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8020 (match_operand:SI 2 "arith_operand" "rI")))]
8021 "TARGET_ARCH64 || TARGET_V8PLUS"
8024 if (! TARGET_ARCH64)
8026 if (GET_CODE (operands[2]) == CONST_INT)
8027 FAIL; /* prefer generic code in this case */
8028 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8034 [(set (match_operand:DI 0 "register_operand" "=r")
8035 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8036 (match_operand:SI 2 "arith_operand" "rI")))]
8040 if (GET_CODE (operands[2]) == CONST_INT
8041 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8042 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8044 return \"srax\\t%1, %2, %0\";
8046 [(set_attr "type" "shift")])
8049 (define_insn "ashrdi3_v8plus"
8050 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8051 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8052 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8053 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8055 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8056 [(set_attr "type" "multi")
8057 (set_attr "length" "5,5,6")])
8059 (define_insn "lshrsi3"
8060 [(set (match_operand:SI 0 "register_operand" "=r")
8061 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8062 (match_operand:SI 2 "arith_operand" "rI")))]
8066 if (GET_CODE (operands[2]) == CONST_INT
8067 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8068 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8070 return \"srl\\t%1, %2, %0\";
8072 [(set_attr "type" "shift")])
8074 ;; This handles the case where
8075 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8076 ;; but combiner "simplifies" it for us.
8077 (define_insn "*lshrsi3_extend"
8078 [(set (match_operand:DI 0 "register_operand" "=r")
8079 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8080 (match_operand:SI 2 "arith_operand" "r")) 0)
8081 (match_operand 3 "" "")))]
8083 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8084 && CONST_DOUBLE_HIGH (operands[3]) == 0
8085 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8086 || (HOST_BITS_PER_WIDE_INT >= 64
8087 && GET_CODE (operands[3]) == CONST_INT
8088 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8090 [(set_attr "type" "shift")])
8092 ;; This handles the case where
8093 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8094 ;; but combiner "simplifies" it for us.
8095 (define_insn "*lshrsi3_extend2"
8096 [(set (match_operand:DI 0 "register_operand" "=r")
8097 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8098 (match_operand 2 "small_int_or_double" "n")
8101 && ((GET_CODE (operands[2]) == CONST_INT
8102 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8103 || (GET_CODE (operands[2]) == CONST_DOUBLE
8104 && CONST_DOUBLE_HIGH (operands[2]) == 0
8105 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8108 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8110 return \"srl\\t%1, %2, %0\";
8112 [(set_attr "type" "shift")])
8114 (define_expand "lshrdi3"
8115 [(set (match_operand:DI 0 "register_operand" "=r")
8116 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8117 (match_operand:SI 2 "arith_operand" "rI")))]
8118 "TARGET_ARCH64 || TARGET_V8PLUS"
8121 if (! TARGET_ARCH64)
8123 if (GET_CODE (operands[2]) == CONST_INT)
8125 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8131 [(set (match_operand:DI 0 "register_operand" "=r")
8132 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8133 (match_operand:SI 2 "arith_operand" "rI")))]
8137 if (GET_CODE (operands[2]) == CONST_INT
8138 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8139 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8141 return \"srlx\\t%1, %2, %0\";
8143 [(set_attr "type" "shift")])
8146 (define_insn "lshrdi3_v8plus"
8147 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8148 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8149 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8150 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8152 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8153 [(set_attr "type" "multi")
8154 (set_attr "length" "5,5,6")])
8157 [(set (match_operand:SI 0 "register_operand" "=r")
8158 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8160 (match_operand:SI 2 "small_int_or_double" "n")))]
8162 && ((GET_CODE (operands[2]) == CONST_INT
8163 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8164 || (GET_CODE (operands[2]) == CONST_DOUBLE
8165 && !CONST_DOUBLE_HIGH (operands[2])
8166 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8169 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8171 return \"srax\\t%1, %2, %0\";
8173 [(set_attr "type" "shift")])
8176 [(set (match_operand:SI 0 "register_operand" "=r")
8177 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8179 (match_operand:SI 2 "small_int_or_double" "n")))]
8181 && ((GET_CODE (operands[2]) == CONST_INT
8182 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8183 || (GET_CODE (operands[2]) == CONST_DOUBLE
8184 && !CONST_DOUBLE_HIGH (operands[2])
8185 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8188 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8190 return \"srlx\\t%1, %2, %0\";
8192 [(set_attr "type" "shift")])
8195 [(set (match_operand:SI 0 "register_operand" "=r")
8196 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8197 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8198 (match_operand:SI 3 "small_int_or_double" "n")))]
8200 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8201 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8202 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8203 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8206 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8208 return \"srax\\t%1, %2, %0\";
8210 [(set_attr "type" "shift")])
8213 [(set (match_operand:SI 0 "register_operand" "=r")
8214 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8215 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8216 (match_operand:SI 3 "small_int_or_double" "n")))]
8218 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8219 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8220 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8221 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8224 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8226 return \"srlx\\t%1, %2, %0\";
8228 [(set_attr "type" "shift")])
8230 ;; Unconditional and other jump instructions
8231 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8232 ;; following insn is never executed. This saves us a nop. Dbx does not
8233 ;; handle such branches though, so we only use them when optimizing.
8235 [(set (pc) (label_ref (match_operand 0 "" "")))]
8239 /* TurboSparc is reported to have problems with
8242 i.e. an empty loop with the annul bit set. The workaround is to use
8246 if (! TARGET_V9 && flag_delayed_branch
8247 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8248 == INSN_ADDRESSES (INSN_UID (insn))))
8249 return \"b\\t%l0%#\";
8251 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8253 [(set_attr "type" "uncond_branch")])
8255 (define_expand "tablejump"
8256 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8257 (use (label_ref (match_operand 1 "" "")))])]
8261 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8264 /* In pic mode, our address differences are against the base of the
8265 table. Add that base value back in; CSE ought to be able to combine
8266 the two address loads. */
8270 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8272 if (CASE_VECTOR_MODE != Pmode)
8273 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8274 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8275 operands[0] = memory_address (Pmode, tmp);
8279 (define_insn "*tablejump_sp32"
8280 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8281 (use (label_ref (match_operand 1 "" "")))]
8284 [(set_attr "type" "uncond_branch")])
8286 (define_insn "*tablejump_sp64"
8287 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8288 (use (label_ref (match_operand 1 "" "")))]
8291 [(set_attr "type" "uncond_branch")])
8293 ;; This pattern recognizes the "instruction" that appears in
8294 ;; a function call that wants a structure value,
8295 ;; to inform the called function if compiled with Sun CC.
8296 ;(define_insn "*unimp_insn"
8297 ; [(match_operand:SI 0 "immediate_operand" "")]
8298 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8300 ; [(set_attr "type" "marker")])
8302 ;;- jump to subroutine
8303 (define_expand "call"
8304 ;; Note that this expression is not used for generating RTL.
8305 ;; All the RTL is generated explicitly below.
8306 [(call (match_operand 0 "call_operand" "")
8307 (match_operand 3 "" "i"))]
8308 ;; operands[2] is next_arg_register
8309 ;; operands[3] is struct_value_size_rtx.
8313 rtx fn_rtx, nregs_rtx;
8315 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8318 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8320 /* This is really a PIC sequence. We want to represent
8321 it as a funny jump so its delay slots can be filled.
8323 ??? But if this really *is* a CALL, will not it clobber the
8324 call-clobbered registers? We lose this if it is a JUMP_INSN.
8325 Why cannot we have delay slots filled if it were a CALL? */
8327 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8332 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8334 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8340 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8341 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8345 fn_rtx = operands[0];
8347 /* Count the number of parameter registers being used by this call.
8348 if that argument is NULL, it means we are using them all, which
8349 means 6 on the sparc. */
8352 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8354 nregs_rtx = GEN_INT (6);
8356 nregs_rtx = const0_rtx;
8359 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8363 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8365 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8370 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8371 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8375 /* If this call wants a structure value,
8376 emit an unimp insn to let the called function know about this. */
8377 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8379 rtx insn = emit_insn (operands[3]);
8380 SCHED_GROUP_P (insn) = 1;
8387 ;; We can't use the same pattern for these two insns, because then registers
8388 ;; in the address may not be properly reloaded.
8390 (define_insn "*call_address_sp32"
8391 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8392 (match_operand 1 "" ""))
8393 (clobber (reg:SI 15))]
8394 ;;- Do not use operand 1 for most machines.
8397 [(set_attr "type" "call")])
8399 (define_insn "*call_symbolic_sp32"
8400 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8401 (match_operand 1 "" ""))
8402 (clobber (reg:SI 15))]
8403 ;;- Do not use operand 1 for most machines.
8406 [(set_attr "type" "call")])
8408 (define_insn "*call_address_sp64"
8409 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8410 (match_operand 1 "" ""))
8411 (clobber (reg:DI 15))]
8412 ;;- Do not use operand 1 for most machines.
8415 [(set_attr "type" "call")])
8417 (define_insn "*call_symbolic_sp64"
8418 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8419 (match_operand 1 "" ""))
8420 (clobber (reg:DI 15))]
8421 ;;- Do not use operand 1 for most machines.
8424 [(set_attr "type" "call")])
8426 ;; This is a call that wants a structure value.
8427 ;; There is no such critter for v9 (??? we may need one anyway).
8428 (define_insn "*call_address_struct_value_sp32"
8429 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8430 (match_operand 1 "" ""))
8431 (match_operand 2 "immediate_operand" "")
8432 (clobber (reg:SI 15))]
8433 ;;- Do not use operand 1 for most machines.
8434 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8435 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8436 [(set_attr "type" "call_no_delay_slot")])
8438 ;; This is a call that wants a structure value.
8439 ;; There is no such critter for v9 (??? we may need one anyway).
8440 (define_insn "*call_symbolic_struct_value_sp32"
8441 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8442 (match_operand 1 "" ""))
8443 (match_operand 2 "immediate_operand" "")
8444 (clobber (reg:SI 15))]
8445 ;;- Do not use operand 1 for most machines.
8446 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8447 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8448 [(set_attr "type" "call_no_delay_slot")])
8450 ;; This is a call that may want a structure value. This is used for
8452 (define_insn "*call_address_untyped_struct_value_sp32"
8453 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8454 (match_operand 1 "" ""))
8455 (match_operand 2 "immediate_operand" "")
8456 (clobber (reg:SI 15))]
8457 ;;- Do not use operand 1 for most machines.
8458 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8459 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8460 [(set_attr "type" "call_no_delay_slot")])
8462 ;; This is a call that wants a structure value.
8463 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8464 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8465 (match_operand 1 "" ""))
8466 (match_operand 2 "immediate_operand" "")
8467 (clobber (reg:SI 15))]
8468 ;;- Do not use operand 1 for most machines.
8469 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8470 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8471 [(set_attr "type" "call_no_delay_slot")])
8473 (define_expand "call_value"
8474 ;; Note that this expression is not used for generating RTL.
8475 ;; All the RTL is generated explicitly below.
8476 [(set (match_operand 0 "register_operand" "=rf")
8477 (call (match_operand 1 "" "")
8478 (match_operand 4 "" "")))]
8479 ;; operand 2 is stack_size_rtx
8480 ;; operand 3 is next_arg_register
8484 rtx fn_rtx, nregs_rtx;
8487 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8490 fn_rtx = operands[1];
8494 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8496 nregs_rtx = GEN_INT (6);
8498 nregs_rtx = const0_rtx;
8502 gen_rtx_SET (VOIDmode, operands[0],
8503 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8504 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8506 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8511 (define_insn "*call_value_address_sp32"
8512 [(set (match_operand 0 "" "=rf")
8513 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8514 (match_operand 2 "" "")))
8515 (clobber (reg:SI 15))]
8516 ;;- Do not use operand 2 for most machines.
8519 [(set_attr "type" "call")])
8521 (define_insn "*call_value_symbolic_sp32"
8522 [(set (match_operand 0 "" "=rf")
8523 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8524 (match_operand 2 "" "")))
8525 (clobber (reg:SI 15))]
8526 ;;- Do not use operand 2 for most machines.
8529 [(set_attr "type" "call")])
8531 (define_insn "*call_value_address_sp64"
8532 [(set (match_operand 0 "" "")
8533 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8534 (match_operand 2 "" "")))
8535 (clobber (reg:DI 15))]
8536 ;;- Do not use operand 2 for most machines.
8539 [(set_attr "type" "call")])
8541 (define_insn "*call_value_symbolic_sp64"
8542 [(set (match_operand 0 "" "")
8543 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8544 (match_operand 2 "" "")))
8545 (clobber (reg:DI 15))]
8546 ;;- Do not use operand 2 for most machines.
8549 [(set_attr "type" "call")])
8551 (define_expand "untyped_call"
8552 [(parallel [(call (match_operand 0 "" "")
8554 (match_operand 1 "" "")
8555 (match_operand 2 "" "")])]
8561 /* Pass constm1 to indicate that it may expect a structure value, but
8562 we don't know what size it is. */
8563 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8565 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8567 rtx set = XVECEXP (operands[2], 0, i);
8568 emit_move_insn (SET_DEST (set), SET_SRC (set));
8571 /* The optimizer does not know that the call sets the function value
8572 registers we stored in the result block. We avoid problems by
8573 claiming that all hard registers are used and clobbered at this
8575 emit_insn (gen_blockage ());
8581 (define_expand "sibcall"
8582 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8587 (define_insn "*sibcall_symbolic_sp32"
8588 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8589 (match_operand 1 "" ""))
8592 "* return output_sibcall(insn, operands[0]);"
8593 [(set_attr "type" "sibcall")])
8595 (define_insn "*sibcall_symbolic_sp64"
8596 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8597 (match_operand 1 "" ""))
8600 "* return output_sibcall(insn, operands[0]);"
8601 [(set_attr "type" "sibcall")])
8603 (define_expand "sibcall_value"
8604 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8605 (call (match_operand 1 "" "") (const_int 0)))
8610 (define_insn "*sibcall_value_symbolic_sp32"
8611 [(set (match_operand 0 "" "=rf")
8612 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8613 (match_operand 2 "" "")))
8616 "* return output_sibcall(insn, operands[1]);"
8617 [(set_attr "type" "sibcall")])
8619 (define_insn "*sibcall_value_symbolic_sp64"
8620 [(set (match_operand 0 "" "")
8621 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8622 (match_operand 2 "" "")))
8625 "* return output_sibcall(insn, operands[1]);"
8626 [(set_attr "type" "sibcall")])
8628 (define_expand "sibcall_epilogue"
8633 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8634 ;; all of memory. This blocks insns from being moved across this point.
8636 (define_insn "blockage"
8637 [(unspec_volatile [(const_int 0)] 0)]
8640 [(set_attr "length" "0")])
8642 ;; Prepare to return any type including a structure value.
8644 (define_expand "untyped_return"
8645 [(match_operand:BLK 0 "memory_operand" "")
8646 (match_operand 1 "" "")]
8650 rtx valreg1 = gen_rtx_REG (DImode, 24);
8651 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8652 rtx result = operands[0];
8654 if (! TARGET_ARCH64)
8656 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8658 rtx value = gen_reg_rtx (SImode);
8660 /* Fetch the instruction where we will return to and see if it's an unimp
8661 instruction (the most significant 10 bits will be zero). If so,
8662 update the return address to skip the unimp instruction. */
8663 emit_move_insn (value,
8664 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8665 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8666 emit_insn (gen_update_return (rtnreg, value));
8669 /* Reload the function value registers. */
8670 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8671 emit_move_insn (valreg2,
8672 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8674 /* Put USE insns before the return. */
8675 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8676 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8678 /* Construct the return. */
8679 expand_null_return ();
8684 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8685 ;; and parts of the compiler don't want to believe that the add is needed.
8687 (define_insn "update_return"
8688 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8689 (match_operand:SI 1 "register_operand" "r")] 1)]
8691 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8692 [(set_attr "type" "multi")
8693 (set_attr "length" "3")])
8695 (define_insn "return"
8699 "* return output_return (operands);"
8700 [(set_attr "type" "return")])
8703 [(set (match_operand:SI 0 "register_operand" "=r")
8704 (match_operand:SI 1 "arith_operand" "rI"))
8706 (use (reg:SI 31))])]
8707 "sparc_return_peephole_ok (operands[0], operands[1])"
8708 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8715 (define_expand "indirect_jump"
8716 [(set (pc) (match_operand 0 "address_operand" "p"))]
8720 (define_insn "*branch_sp32"
8721 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8724 [(set_attr "type" "uncond_branch")])
8726 (define_insn "*branch_sp64"
8727 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8730 [(set_attr "type" "uncond_branch")])
8732 ;; ??? Doesn't work with -mflat.
8733 (define_expand "nonlocal_goto"
8734 [(match_operand:SI 0 "general_operand" "")
8735 (match_operand:SI 1 "general_operand" "")
8736 (match_operand:SI 2 "general_operand" "")
8737 (match_operand:SI 3 "" "")]
8742 rtx chain = operands[0];
8744 rtx lab = operands[1];
8745 rtx stack = operands[2];
8746 rtx fp = operands[3];
8749 /* Trap instruction to flush all the register windows. */
8750 emit_insn (gen_flush_register_windows ());
8752 /* Load the fp value for the containing fn into %fp. This is needed
8753 because STACK refers to %fp. Note that virtual register instantiation
8754 fails if the virtual %fp isn't set from a register. */
8755 if (GET_CODE (fp) != REG)
8756 fp = force_reg (Pmode, fp);
8757 emit_move_insn (virtual_stack_vars_rtx, fp);
8759 /* Find the containing function's current nonlocal goto handler,
8760 which will do any cleanups and then jump to the label. */
8761 labreg = gen_rtx_REG (Pmode, 8);
8762 emit_move_insn (labreg, lab);
8764 /* Restore %fp from stack pointer value for containing function.
8765 The restore insn that follows will move this to %sp,
8766 and reload the appropriate value into %fp. */
8767 emit_move_insn (frame_pointer_rtx, stack);
8769 /* USE of frame_pointer_rtx added for consistency; not clear if
8771 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8772 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8775 /* Return, restoring reg window and jumping to goto handler. */
8776 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8777 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8779 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8785 /* Put in the static chain register the nonlocal label address. */
8786 emit_move_insn (static_chain_rtx, chain);
8789 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8790 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8795 ;; Special trap insn to flush register windows.
8796 (define_insn "flush_register_windows"
8797 [(unspec_volatile [(const_int 0)] 1)]
8799 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8800 [(set_attr "type" "misc")])
8802 (define_insn "goto_handler_and_restore"
8803 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8804 "GET_MODE (operands[0]) == Pmode"
8805 "jmp\\t%0+0\\n\\trestore"
8806 [(set_attr "type" "multi")
8807 (set_attr "length" "2")])
8809 ;;(define_insn "goto_handler_and_restore_v9"
8810 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8811 ;; (match_operand:SI 1 "register_operand" "=r,r")
8812 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8813 ;; "TARGET_V9 && ! TARGET_ARCH64"
8815 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8816 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8817 ;; [(set_attr "type" "multi")
8818 ;; (set_attr "length" "2,3")])
8820 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8821 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8822 ;; (match_operand:DI 1 "register_operand" "=r,r")
8823 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8824 ;; "TARGET_V9 && TARGET_ARCH64"
8826 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8827 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8828 ;; [(set_attr "type" "multi")
8829 ;; (set_attr "length" "2,3")])
8831 ;; For __builtin_setjmp we need to flush register windows iff the function
8832 ;; calls alloca as well, because otherwise the register window might be
8833 ;; saved after %sp adjustement and thus setjmp would crash
8834 (define_expand "builtin_setjmp_setup"
8835 [(match_operand 0 "register_operand" "r")]
8839 emit_insn (gen_do_builtin_setjmp_setup ());
8843 ;; ??? Should set length to zero when !current_function_calls_alloca,
8844 ;; ??? but there is no easy way to get at that definition. It would
8845 ;; ??? require including function.h into sparc-protos.h and that is
8846 ;; ??? likely not a good idea. -DaveM
8847 (define_insn "do_builtin_setjmp_setup"
8848 [(unspec_volatile [(const_int 0)] 5)]
8852 if (!current_function_calls_alloca)
8858 [(set_attr "type" "misc")])
8860 ;; Pattern for use after a setjmp to store FP and the return register
8861 ;; into the stack area.
8863 (define_expand "setjmp"
8869 emit_insn (gen_setjmp_64 ());
8871 emit_insn (gen_setjmp_32 ());
8875 (define_expand "setjmp_32"
8876 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8877 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8880 { operands[0] = frame_pointer_rtx; }")
8882 (define_expand "setjmp_64"
8883 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8884 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8887 { operands[0] = frame_pointer_rtx; }")
8889 ;; Special pattern for the FLUSH instruction.
8891 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8892 ; of the define_insn otherwise missing a mode. We make "flush", aka
8893 ; gen_flush, the default one since sparc_initialize_trampoline uses
8894 ; it on SImode mem values.
8896 (define_insn "flush"
8897 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8899 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8900 [(set_attr "type" "misc")])
8902 (define_insn "flushdi"
8903 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8905 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8906 [(set_attr "type" "misc")])
8911 ;; The scan instruction searches from the most significant bit while ffs
8912 ;; searches from the least significant bit. The bit index and treatment of
8913 ;; zero also differ. It takes at least 7 instructions to get the proper
8914 ;; result. Here is an obvious 8 instruction sequence.
8917 (define_insn "ffssi2"
8918 [(set (match_operand:SI 0 "register_operand" "=&r")
8919 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8920 (clobber (match_scratch:SI 2 "=&r"))]
8921 "TARGET_SPARCLITE || TARGET_SPARCLET"
8924 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\";
8926 [(set_attr "type" "multi")
8927 (set_attr "length" "8")])
8929 ;; ??? This should be a define expand, so that the extra instruction have
8930 ;; a chance of being optimized away.
8932 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8933 ;; does, but no one uses that and we don't have a switch for it.
8935 ;(define_insn "ffsdi2"
8936 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8937 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8938 ; (clobber (match_scratch:DI 2 "=&r"))]
8940 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8941 ; [(set_attr "type" "multi")
8942 ; (set_attr "length" "4")])
8946 ;; Peepholes go at the end.
8948 ;; Optimize consecutive loads or stores into ldd and std when possible.
8949 ;; The conditions in which we do this are very restricted and are
8950 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8953 [(set (match_operand:SI 0 "memory_operand" "")
8955 (set (match_operand:SI 1 "memory_operand" "")
8958 && ! MEM_VOLATILE_P (operands[0])
8959 && ! MEM_VOLATILE_P (operands[1])
8960 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8964 [(set (match_operand:SI 0 "memory_operand" "")
8966 (set (match_operand:SI 1 "memory_operand" "")
8969 && ! MEM_VOLATILE_P (operands[0])
8970 && ! MEM_VOLATILE_P (operands[1])
8971 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8975 [(set (match_operand:SI 0 "register_operand" "=rf")
8976 (match_operand:SI 1 "memory_operand" ""))
8977 (set (match_operand:SI 2 "register_operand" "=rf")
8978 (match_operand:SI 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 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8986 [(set (match_operand:SI 0 "memory_operand" "")
8987 (match_operand:SI 1 "register_operand" "rf"))
8988 (set (match_operand:SI 2 "memory_operand" "")
8989 (match_operand:SI 3 "register_operand" "rf"))]
8990 "registers_ok_for_ldd_peep (operands[1], operands[3])
8991 && ! MEM_VOLATILE_P (operands[0])
8992 && ! MEM_VOLATILE_P (operands[2])
8993 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8997 [(set (match_operand:SF 0 "register_operand" "=fr")
8998 (match_operand:SF 1 "memory_operand" ""))
8999 (set (match_operand:SF 2 "register_operand" "=fr")
9000 (match_operand:SF 3 "memory_operand" ""))]
9001 "registers_ok_for_ldd_peep (operands[0], operands[2])
9002 && ! MEM_VOLATILE_P (operands[1])
9003 && ! MEM_VOLATILE_P (operands[3])
9004 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9008 [(set (match_operand:SF 0 "memory_operand" "")
9009 (match_operand:SF 1 "register_operand" "fr"))
9010 (set (match_operand:SF 2 "memory_operand" "")
9011 (match_operand:SF 3 "register_operand" "fr"))]
9012 "registers_ok_for_ldd_peep (operands[1], operands[3])
9013 && ! MEM_VOLATILE_P (operands[0])
9014 && ! MEM_VOLATILE_P (operands[2])
9015 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9019 [(set (match_operand:SI 0 "register_operand" "=rf")
9020 (match_operand:SI 1 "memory_operand" ""))
9021 (set (match_operand:SI 2 "register_operand" "=rf")
9022 (match_operand:SI 3 "memory_operand" ""))]
9023 "registers_ok_for_ldd_peep (operands[2], operands[0])
9024 && ! MEM_VOLATILE_P (operands[3])
9025 && ! MEM_VOLATILE_P (operands[1])
9026 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9030 [(set (match_operand:SI 0 "memory_operand" "")
9031 (match_operand:SI 1 "register_operand" "rf"))
9032 (set (match_operand:SI 2 "memory_operand" "")
9033 (match_operand:SI 3 "register_operand" "rf"))]
9034 "registers_ok_for_ldd_peep (operands[3], operands[1])
9035 && ! MEM_VOLATILE_P (operands[2])
9036 && ! MEM_VOLATILE_P (operands[0])
9037 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9041 [(set (match_operand:SF 0 "register_operand" "=fr")
9042 (match_operand:SF 1 "memory_operand" ""))
9043 (set (match_operand:SF 2 "register_operand" "=fr")
9044 (match_operand:SF 3 "memory_operand" ""))]
9045 "registers_ok_for_ldd_peep (operands[2], operands[0])
9046 && ! MEM_VOLATILE_P (operands[3])
9047 && ! MEM_VOLATILE_P (operands[1])
9048 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9052 [(set (match_operand:SF 0 "memory_operand" "")
9053 (match_operand:SF 1 "register_operand" "fr"))
9054 (set (match_operand:SF 2 "memory_operand" "")
9055 (match_operand:SF 3 "register_operand" "fr"))]
9056 "registers_ok_for_ldd_peep (operands[3], operands[1])
9057 && ! MEM_VOLATILE_P (operands[2])
9058 && ! MEM_VOLATILE_P (operands[0])
9059 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9062 ;; Optimize the case of following a reg-reg move with a test
9063 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9064 ;; This can result from a float to fix conversion.
9067 [(set (match_operand:SI 0 "register_operand" "=r")
9068 (match_operand:SI 1 "register_operand" "r"))
9070 (compare:CC (match_operand:SI 2 "register_operand" "r")
9072 "(rtx_equal_p (operands[2], operands[0])
9073 || rtx_equal_p (operands[2], operands[1]))
9074 && ! FP_REG_P (operands[0])
9075 && ! FP_REG_P (operands[1])"
9079 [(set (match_operand:DI 0 "register_operand" "=r")
9080 (match_operand:DI 1 "register_operand" "r"))
9082 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9085 && (rtx_equal_p (operands[2], operands[0])
9086 || rtx_equal_p (operands[2], operands[1]))
9087 && ! FP_REG_P (operands[0])
9088 && ! FP_REG_P (operands[1])"
9091 ;; Return peepholes. First the "normal" ones.
9092 ;; These are necessary to catch insns ending up in the epilogue delay list.
9094 (define_insn "*return_qi"
9095 [(set (match_operand:QI 0 "restore_operand" "")
9096 (match_operand:QI 1 "arith_operand" "rI"))
9101 if (! TARGET_ARCH64 && current_function_returns_struct)
9102 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9103 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9104 || IN_OR_GLOBAL_P (operands[1])))
9105 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9107 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9109 [(set_attr "type" "multi")
9110 (set_attr "length" "2")])
9112 (define_insn "*return_hi"
9113 [(set (match_operand:HI 0 "restore_operand" "")
9114 (match_operand:HI 1 "arith_operand" "rI"))
9119 if (! TARGET_ARCH64 && current_function_returns_struct)
9120 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9121 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9122 || IN_OR_GLOBAL_P (operands[1])))
9123 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9125 return \"ret\;restore %%g0, %1, %Y0\";
9127 [(set_attr "type" "multi")
9128 (set_attr "length" "2")])
9130 (define_insn "*return_si"
9131 [(set (match_operand:SI 0 "restore_operand" "")
9132 (match_operand:SI 1 "arith_operand" "rI"))
9137 if (! TARGET_ARCH64 && current_function_returns_struct)
9138 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9139 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9140 || IN_OR_GLOBAL_P (operands[1])))
9141 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9143 return \"ret\;restore %%g0, %1, %Y0\";
9145 [(set_attr "type" "multi")
9146 (set_attr "length" "2")])
9148 ;; The following pattern is only generated by delayed-branch scheduling,
9149 ;; when the insn winds up in the epilogue. This can happen not only when
9150 ;; ! TARGET_FPU because we move complex types around by parts using
9152 (define_insn "*return_sf_no_fpu"
9153 [(set (match_operand:SF 0 "restore_operand" "=r")
9154 (match_operand:SF 1 "register_operand" "r"))
9159 if (! TARGET_ARCH64 && current_function_returns_struct)
9160 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9161 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9162 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9164 return \"ret\;restore %%g0, %1, %Y0\";
9166 [(set_attr "type" "multi")
9167 (set_attr "length" "2")])
9169 (define_insn "*return_df_no_fpu"
9170 [(set (match_operand:DF 0 "restore_operand" "=r")
9171 (match_operand:DF 1 "register_operand" "r"))
9173 "! TARGET_EPILOGUE && TARGET_ARCH64"
9176 if (IN_OR_GLOBAL_P (operands[1]))
9177 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9179 return \"ret\;restore %%g0, %1, %Y0\";
9181 [(set_attr "type" "multi")
9182 (set_attr "length" "2")])
9184 (define_insn "*return_addsi"
9185 [(set (match_operand:SI 0 "restore_operand" "")
9186 (plus:SI (match_operand:SI 1 "register_operand" "r")
9187 (match_operand:SI 2 "arith_operand" "rI")))
9192 if (! TARGET_ARCH64 && current_function_returns_struct)
9193 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9194 /* If operands are global or in registers, can use return */
9195 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9196 && (GET_CODE (operands[2]) == CONST_INT
9197 || IN_OR_GLOBAL_P (operands[2])))
9198 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9200 return \"ret\;restore %r1, %2, %Y0\";
9202 [(set_attr "type" "multi")
9203 (set_attr "length" "2")])
9205 (define_insn "*return_losum_si"
9206 [(set (match_operand:SI 0 "restore_operand" "")
9207 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9208 (match_operand:SI 2 "immediate_operand" "in")))
9210 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9213 if (! TARGET_ARCH64 && current_function_returns_struct)
9214 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9215 /* If operands are global or in registers, can use return */
9216 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9217 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9219 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9221 [(set_attr "type" "multi")
9222 (set_attr "length" "2")])
9224 (define_insn "*return_di"
9225 [(set (match_operand:DI 0 "restore_operand" "")
9226 (match_operand:DI 1 "arith_double_operand" "rHI"))
9228 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9229 "ret\;restore %%g0, %1, %Y0"
9230 [(set_attr "type" "multi")
9231 (set_attr "length" "2")])
9233 (define_insn "*return_adddi"
9234 [(set (match_operand:DI 0 "restore_operand" "")
9235 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9236 (match_operand:DI 2 "arith_double_operand" "rHI")))
9238 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9239 "ret\;restore %r1, %2, %Y0"
9240 [(set_attr "type" "multi")
9241 (set_attr "length" "2")])
9243 (define_insn "*return_losum_di"
9244 [(set (match_operand:DI 0 "restore_operand" "")
9245 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9246 (match_operand:DI 2 "immediate_operand" "in")))
9248 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9249 "ret\;restore %r1, %%lo(%a2), %Y0"
9250 [(set_attr "type" "multi")
9251 (set_attr "length" "2")])
9253 ;; The following pattern is only generated by delayed-branch scheduling,
9254 ;; when the insn winds up in the epilogue.
9255 (define_insn "*return_sf"
9257 (match_operand:SF 0 "register_operand" "f"))
9260 "ret\;fmovs\\t%0, %%f0"
9261 [(set_attr "type" "multi")
9262 (set_attr "length" "2")])
9264 ;; Now peepholes to do a call followed by a jump.
9267 [(parallel [(set (match_operand 0 "" "")
9268 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9269 (match_operand 2 "" "")))
9270 (clobber (reg:SI 15))])
9271 (set (pc) (label_ref (match_operand 3 "" "")))]
9272 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9273 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9274 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9277 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9278 (match_operand 1 "" ""))
9279 (clobber (reg:SI 15))])
9280 (set (pc) (label_ref (match_operand 2 "" "")))]
9281 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9282 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9283 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9286 [(parallel [(set (match_operand 0 "" "")
9287 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9288 (match_operand 2 "" "")))
9289 (clobber (reg:DI 15))])
9290 (set (pc) (label_ref (match_operand 3 "" "")))]
9292 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9293 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9294 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9297 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9298 (match_operand 1 "" ""))
9299 (clobber (reg:DI 15))])
9300 (set (pc) (label_ref (match_operand 2 "" "")))]
9302 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9303 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9304 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9306 (define_expand "prologue"
9308 "flag_pic && current_function_uses_pic_offset_table"
9311 load_pic_register ();
9315 ;; We need to reload %l7 for -mflat -fpic,
9316 ;; otherwise %l7 should be preserved simply
9317 ;; by loading the function's register window
9318 (define_expand "exception_receiver"
9320 "TARGET_FLAT && flag_pic"
9323 load_pic_register ();
9328 (define_expand "builtin_setjmp_receiver"
9329 [(label_ref (match_operand 0 "" ""))]
9330 "TARGET_FLAT && flag_pic"
9333 load_pic_register ();
9338 [(trap_if (const_int 1) (const_int 5))]
9341 [(set_attr "type" "misc")])
9343 (define_expand "conditional_trap"
9344 [(trap_if (match_operator 0 "noov_compare_op"
9345 [(match_dup 2) (match_dup 3)])
9346 (match_operand:SI 1 "arith_operand" ""))]
9348 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9349 sparc_compare_op0, sparc_compare_op1);
9350 operands[3] = const0_rtx;")
9353 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9354 (match_operand:SI 1 "arith_operand" "rM"))]
9357 [(set_attr "type" "misc")])
9360 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9361 (match_operand:SI 1 "arith_operand" "rM"))]
9364 [(set_attr "type" "misc")])