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 /* We are able to build any DF constant in integer registers. */
3138 if (REGNO (operands[0]) < 32
3139 && (reload_completed || reload_in_progress))
3142 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3146 /* Handle MEM cases first. */
3147 if (GET_CODE (operands[0]) == MEM)
3149 if (register_operand (operands[1], DFmode)
3150 || fp_zero_operand (operands[1], DFmode))
3153 if (! reload_in_progress)
3155 operands[0] = validize_mem (operands[0]);
3156 operands[1] = force_reg (DFmode, operands[1]);
3160 /* Fixup PIC cases. */
3163 if (CONSTANT_P (operands[1])
3164 && pic_address_needs_scratch (operands[1]))
3165 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3167 if (symbolic_operand (operands[1], DFmode))
3169 operands[1] = legitimize_pic_address (operands[1],
3171 (reload_in_progress ?
3181 ;; Be careful, fmovd does not exist when !v9.
3182 (define_insn "*movdf_insn_sp32"
3183 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3184 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3187 && (register_operand (operands[0], DFmode)
3188 || register_operand (operands[1], DFmode)
3189 || fp_zero_operand (operands[1], DFmode))"
3201 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3202 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3204 (define_insn "*movdf_no_e_insn_sp32"
3205 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3206 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3210 && (register_operand (operands[0], DFmode)
3211 || register_operand (operands[1], DFmode)
3212 || fp_zero_operand (operands[1], DFmode))"
3219 [(set_attr "type" "load,store,*,*,*")
3220 (set_attr "length" "*,*,2,2,2")])
3222 (define_insn "*movdf_no_e_insn_v9_sp32"
3223 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3224 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3228 && (register_operand (operands[0], DFmode)
3229 || register_operand (operands[1], DFmode)
3230 || fp_zero_operand (operands[1], DFmode))"
3237 [(set_attr "type" "load,store,store,*,*")
3238 (set_attr "length" "*,*,*,2,2")])
3240 ;; We have available v9 double floats but not 64-bit
3241 ;; integer registers and no VIS.
3242 (define_insn "*movdf_insn_v9only_novis"
3243 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3244 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3249 && (register_operand (operands[0], DFmode)
3250 || register_operand (operands[1], DFmode)
3251 || fp_zero_operand (operands[1], DFmode))"
3262 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3263 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3264 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3266 ;; We have available v9 double floats but not 64-bit
3267 ;; integer registers but we have VIS.
3268 (define_insn "*movdf_insn_v9only_vis"
3269 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3270 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3274 && (register_operand (operands[0], DFmode)
3275 || register_operand (operands[1], DFmode)
3276 || fp_zero_operand (operands[1], DFmode))"
3288 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3289 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3290 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3292 ;; We have available both v9 double floats and 64-bit
3293 ;; integer registers. No VIS though.
3294 (define_insn "*movdf_insn_sp64_novis"
3295 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3296 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3300 && (register_operand (operands[0], DFmode)
3301 || register_operand (operands[1], DFmode)
3302 || fp_zero_operand (operands[1], DFmode))"
3311 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3312 (set_attr "length" "*,*,*,*,*,*,2")
3313 (set_attr "fptype" "double,*,*,*,*,*,*")])
3315 ;; We have available both v9 double floats and 64-bit
3316 ;; integer registers. And we have VIS.
3317 (define_insn "*movdf_insn_sp64_vis"
3318 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3319 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3323 && (register_operand (operands[0], DFmode)
3324 || register_operand (operands[1], DFmode)
3325 || fp_zero_operand (operands[1], DFmode))"
3335 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3336 (set_attr "length" "*,*,*,*,*,*,*,2")
3337 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3339 (define_insn "*movdf_no_e_insn_sp64"
3340 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3341 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3344 && (register_operand (operands[0], DFmode)
3345 || register_operand (operands[1], DFmode)
3346 || fp_zero_operand (operands[1], DFmode))"
3351 [(set_attr "type" "*,load,store")])
3354 [(set (match_operand:DF 0 "register_operand" "")
3355 (match_operand:DF 1 "const_double_operand" ""))]
3357 && (GET_CODE (operands[0]) == REG
3358 && REGNO (operands[0]) < 32)
3359 && ! fp_zero_operand(operands[1], DFmode)
3360 && reload_completed"
3361 [(clobber (const_int 0))]
3367 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3368 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3369 if (GET_CODE (operands[0]) == SUBREG)
3370 operands[0] = alter_subreg (operands[0]);
3371 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3375 #if HOST_BITS_PER_WIDE_INT == 64
3378 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3379 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3380 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3382 emit_insn (gen_movdi (operands[0],
3383 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3388 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3391 /* Slick... but this trick loses if this subreg constant part
3392 can be done in one insn. */
3394 && !(SPARC_SETHI_P (l[0])
3395 || SPARC_SIMM13_P (l[0])))
3397 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3398 gen_highpart (SImode, operands[0])));
3402 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3409 ;; Ok, now the splits to handle all the multi insn and
3410 ;; mis-aligned memory address cases.
3411 ;; In these splits please take note that we must be
3412 ;; careful when V9 but not ARCH64 because the integer
3413 ;; register DFmode cases must be handled.
3415 [(set (match_operand:DF 0 "register_operand" "")
3416 (match_operand:DF 1 "register_operand" ""))]
3419 && ((GET_CODE (operands[0]) == REG
3420 && REGNO (operands[0]) < 32)
3421 || (GET_CODE (operands[0]) == SUBREG
3422 && GET_CODE (SUBREG_REG (operands[0])) == REG
3423 && REGNO (SUBREG_REG (operands[0])) < 32))))
3424 && reload_completed"
3425 [(clobber (const_int 0))]
3428 rtx set_dest = operands[0];
3429 rtx set_src = operands[1];
3433 if (GET_CODE (set_dest) == SUBREG)
3434 set_dest = alter_subreg (set_dest);
3435 if (GET_CODE (set_src) == SUBREG)
3436 set_src = alter_subreg (set_src);
3438 dest1 = gen_highpart (SFmode, set_dest);
3439 dest2 = gen_lowpart (SFmode, set_dest);
3440 src1 = gen_highpart (SFmode, set_src);
3441 src2 = gen_lowpart (SFmode, set_src);
3443 /* Now emit using the real source and destination we found, swapping
3444 the order if we detect overlap. */
3445 if (reg_overlap_mentioned_p (dest1, src2))
3447 emit_insn (gen_movsf (dest2, src2));
3448 emit_insn (gen_movsf (dest1, src1));
3452 emit_insn (gen_movsf (dest1, src1));
3453 emit_insn (gen_movsf (dest2, src2));
3459 [(set (match_operand:DF 0 "register_operand" "")
3460 (match_operand:DF 1 "memory_operand" ""))]
3463 && (((REGNO (operands[0]) % 2) != 0)
3464 || ! mem_min_alignment (operands[1], 8))
3465 && offsettable_memref_p (operands[1])"
3466 [(clobber (const_int 0))]
3469 rtx word0 = adjust_address (operands[1], SFmode, 0);
3470 rtx word1 = adjust_address (operands[1], SFmode, 4);
3472 if (GET_CODE (operands[0]) == SUBREG)
3473 operands[0] = alter_subreg (operands[0]);
3475 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3477 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3479 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3484 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3486 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3493 [(set (match_operand:DF 0 "memory_operand" "")
3494 (match_operand:DF 1 "register_operand" ""))]
3497 && (((REGNO (operands[1]) % 2) != 0)
3498 || ! mem_min_alignment (operands[0], 8))
3499 && offsettable_memref_p (operands[0])"
3500 [(clobber (const_int 0))]
3503 rtx word0 = adjust_address (operands[0], SFmode, 0);
3504 rtx word1 = adjust_address (operands[0], SFmode, 4);
3506 if (GET_CODE (operands[1]) == SUBREG)
3507 operands[1] = alter_subreg (operands[1]);
3508 emit_insn (gen_movsf (word0,
3509 gen_highpart (SFmode, operands[1])));
3510 emit_insn (gen_movsf (word1,
3511 gen_lowpart (SFmode, operands[1])));
3516 [(set (match_operand:DF 0 "memory_operand" "")
3517 (match_operand:DF 1 "fp_zero_operand" ""))]
3521 && ! mem_min_alignment (operands[0], 8)))
3522 && offsettable_memref_p (operands[0])"
3523 [(clobber (const_int 0))]
3528 dest1 = adjust_address (operands[0], SFmode, 0);
3529 dest2 = adjust_address (operands[0], SFmode, 4);
3531 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3532 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3537 [(set (match_operand:DF 0 "register_operand" "")
3538 (match_operand:DF 1 "fp_zero_operand" ""))]
3541 && ((GET_CODE (operands[0]) == REG
3542 && REGNO (operands[0]) < 32)
3543 || (GET_CODE (operands[0]) == SUBREG
3544 && GET_CODE (SUBREG_REG (operands[0])) == REG
3545 && REGNO (SUBREG_REG (operands[0])) < 32))"
3546 [(clobber (const_int 0))]
3549 rtx set_dest = operands[0];
3552 if (GET_CODE (set_dest) == SUBREG)
3553 set_dest = alter_subreg (set_dest);
3554 dest1 = gen_highpart (SFmode, set_dest);
3555 dest2 = gen_lowpart (SFmode, set_dest);
3556 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3557 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3561 (define_expand "movtf"
3562 [(set (match_operand:TF 0 "general_operand" "")
3563 (match_operand:TF 1 "general_operand" ""))]
3567 /* Force TFmode constants into memory. */
3568 if (GET_CODE (operands[0]) == REG
3569 && CONSTANT_P (operands[1]))
3571 /* emit_group_store will send such bogosity to us when it is
3572 not storing directly into memory. So fix this up to avoid
3573 crashes in output_constant_pool. */
3574 if (operands [1] == const0_rtx)
3575 operands[1] = CONST0_RTX (TFmode);
3577 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3580 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3584 /* Handle MEM cases first, note that only v9 guarentees
3585 full 16-byte alignment for quads. */
3586 if (GET_CODE (operands[0]) == MEM)
3588 if (register_operand (operands[1], TFmode)
3589 || fp_zero_operand (operands[1], TFmode))
3592 if (! reload_in_progress)
3594 operands[0] = validize_mem (operands[0]);
3595 operands[1] = force_reg (TFmode, operands[1]);
3599 /* Fixup PIC cases. */
3602 if (CONSTANT_P (operands[1])
3603 && pic_address_needs_scratch (operands[1]))
3604 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3606 if (symbolic_operand (operands[1], TFmode))
3608 operands[1] = legitimize_pic_address (operands[1],
3610 (reload_in_progress ?
3620 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3621 ;; we must split them all. :-(
3622 (define_insn "*movtf_insn_sp32"
3623 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3624 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3628 && (register_operand (operands[0], TFmode)
3629 || register_operand (operands[1], TFmode)
3630 || fp_zero_operand (operands[1], TFmode))"
3632 [(set_attr "length" "4")])
3634 (define_insn "*movtf_insn_vis_sp32"
3635 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3636 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3640 && (register_operand (operands[0], TFmode)
3641 || register_operand (operands[1], TFmode)
3642 || fp_zero_operand (operands[1], TFmode))"
3644 [(set_attr "length" "4")])
3646 ;; Exactly the same as above, except that all `e' cases are deleted.
3647 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3650 (define_insn "*movtf_no_e_insn_sp32"
3651 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3652 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3655 && (register_operand (operands[0], TFmode)
3656 || register_operand (operands[1], TFmode)
3657 || fp_zero_operand (operands[1], TFmode))"
3659 [(set_attr "length" "4")])
3661 ;; Now handle the float reg cases directly when arch64,
3662 ;; hard_quad, and proper reg number alignment are all true.
3663 (define_insn "*movtf_insn_hq_sp64"
3664 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3665 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3670 && (register_operand (operands[0], TFmode)
3671 || register_operand (operands[1], TFmode)
3672 || fp_zero_operand (operands[1], TFmode))"
3679 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3680 (set_attr "length" "*,*,*,2,2")])
3682 (define_insn "*movtf_insn_hq_vis_sp64"
3683 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3684 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3689 && (register_operand (operands[0], TFmode)
3690 || register_operand (operands[1], TFmode)
3691 || fp_zero_operand (operands[1], TFmode))"
3699 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3700 (set_attr "length" "*,*,*,2,2,2")])
3702 ;; Now we allow the integer register cases even when
3703 ;; only arch64 is true.
3704 (define_insn "*movtf_insn_sp64"
3705 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3706 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3710 && ! TARGET_HARD_QUAD
3711 && (register_operand (operands[0], TFmode)
3712 || register_operand (operands[1], TFmode)
3713 || fp_zero_operand (operands[1], TFmode))"
3715 [(set_attr "length" "2")])
3717 (define_insn "*movtf_insn_vis_sp64"
3718 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3719 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3723 && ! TARGET_HARD_QUAD
3724 && (register_operand (operands[0], TFmode)
3725 || register_operand (operands[1], TFmode)
3726 || fp_zero_operand (operands[1], TFmode))"
3728 [(set_attr "length" "2")])
3730 (define_insn "*movtf_no_e_insn_sp64"
3731 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3732 (match_operand:TF 1 "input_operand" "orG,rG"))]
3735 && (register_operand (operands[0], TFmode)
3736 || register_operand (operands[1], TFmode)
3737 || fp_zero_operand (operands[1], TFmode))"
3739 [(set_attr "length" "2")])
3741 ;; Now all the splits to handle multi-insn TF mode moves.
3743 [(set (match_operand:TF 0 "register_operand" "")
3744 (match_operand:TF 1 "register_operand" ""))]
3748 && ! TARGET_HARD_QUAD))"
3749 [(clobber (const_int 0))]
3752 rtx set_dest = operands[0];
3753 rtx set_src = operands[1];
3757 if (GET_CODE (set_dest) == SUBREG)
3758 set_dest = alter_subreg (set_dest);
3759 if (GET_CODE (set_src) == SUBREG)
3760 set_src = alter_subreg (set_src);
3762 dest1 = gen_df_reg (set_dest, 0);
3763 dest2 = gen_df_reg (set_dest, 1);
3764 src1 = gen_df_reg (set_src, 0);
3765 src2 = gen_df_reg (set_src, 1);
3767 /* Now emit using the real source and destination we found, swapping
3768 the order if we detect overlap. */
3769 if (reg_overlap_mentioned_p (dest1, src2))
3771 emit_insn (gen_movdf (dest2, src2));
3772 emit_insn (gen_movdf (dest1, src1));
3776 emit_insn (gen_movdf (dest1, src1));
3777 emit_insn (gen_movdf (dest2, src2));
3783 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3784 (match_operand:TF 1 "fp_zero_operand" ""))]
3786 [(clobber (const_int 0))]
3789 rtx set_dest = operands[0];
3792 switch (GET_CODE (set_dest))
3795 set_dest = alter_subreg (set_dest);
3798 dest1 = gen_df_reg (set_dest, 0);
3799 dest2 = gen_df_reg (set_dest, 1);
3802 dest1 = adjust_address (set_dest, DFmode, 0);
3803 dest2 = adjust_address (set_dest, DFmode, 8);
3809 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3810 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3815 [(set (match_operand:TF 0 "register_operand" "")
3816 (match_operand:TF 1 "memory_operand" ""))]
3818 && offsettable_memref_p (operands[1]))"
3819 [(clobber (const_int 0))]
3822 rtx word0 = adjust_address (operands[1], DFmode, 0);
3823 rtx word1 = adjust_address (operands[1], DFmode, 8);
3824 rtx set_dest, dest1, dest2;
3826 set_dest = operands[0];
3827 if (GET_CODE (set_dest) == SUBREG)
3828 set_dest = alter_subreg (set_dest);
3830 dest1 = gen_df_reg (set_dest, 0);
3831 dest2 = gen_df_reg (set_dest, 1);
3833 /* Now output, ordering such that we don't clobber any registers
3834 mentioned in the address. */
3835 if (reg_overlap_mentioned_p (dest1, word1))
3838 emit_insn (gen_movdf (dest2, word1));
3839 emit_insn (gen_movdf (dest1, word0));
3843 emit_insn (gen_movdf (dest1, word0));
3844 emit_insn (gen_movdf (dest2, word1));
3850 [(set (match_operand:TF 0 "memory_operand" "")
3851 (match_operand:TF 1 "register_operand" ""))]
3853 && offsettable_memref_p (operands[0]))"
3854 [(clobber (const_int 0))]
3857 rtx set_src = operands[1];
3858 if (GET_CODE (set_src) == SUBREG)
3859 set_src = alter_subreg (set_src);
3861 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3862 gen_df_reg (set_src, 0)));
3863 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3864 gen_df_reg (set_src, 1)));
3868 ;; Sparc V9 conditional move instructions.
3870 ;; We can handle larger constants here for some flavors, but for now we keep
3871 ;; it simple and only allow those constants supported by all flavours.
3872 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3873 ;; 3 contains the constant if one is present, but we handle either for
3874 ;; generality (sparc.c puts a constant in operand 2).
3876 (define_expand "movqicc"
3877 [(set (match_operand:QI 0 "register_operand" "")
3878 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3879 (match_operand:QI 2 "arith10_operand" "")
3880 (match_operand:QI 3 "arith10_operand" "")))]
3884 enum rtx_code code = GET_CODE (operands[1]);
3886 if (GET_MODE (sparc_compare_op0) == DImode
3890 if (sparc_compare_op1 == const0_rtx
3891 && GET_CODE (sparc_compare_op0) == REG
3892 && GET_MODE (sparc_compare_op0) == DImode
3893 && v9_regcmp_p (code))
3895 operands[1] = gen_rtx_fmt_ee (code, DImode,
3896 sparc_compare_op0, sparc_compare_op1);
3900 rtx cc_reg = gen_compare_reg (code,
3901 sparc_compare_op0, sparc_compare_op1);
3902 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3906 (define_expand "movhicc"
3907 [(set (match_operand:HI 0 "register_operand" "")
3908 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3909 (match_operand:HI 2 "arith10_operand" "")
3910 (match_operand:HI 3 "arith10_operand" "")))]
3914 enum rtx_code code = GET_CODE (operands[1]);
3916 if (GET_MODE (sparc_compare_op0) == DImode
3920 if (sparc_compare_op1 == const0_rtx
3921 && GET_CODE (sparc_compare_op0) == REG
3922 && GET_MODE (sparc_compare_op0) == DImode
3923 && v9_regcmp_p (code))
3925 operands[1] = gen_rtx_fmt_ee (code, DImode,
3926 sparc_compare_op0, sparc_compare_op1);
3930 rtx cc_reg = gen_compare_reg (code,
3931 sparc_compare_op0, sparc_compare_op1);
3932 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3936 (define_expand "movsicc"
3937 [(set (match_operand:SI 0 "register_operand" "")
3938 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3939 (match_operand:SI 2 "arith10_operand" "")
3940 (match_operand:SI 3 "arith10_operand" "")))]
3944 enum rtx_code code = GET_CODE (operands[1]);
3945 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3947 if (sparc_compare_op1 == const0_rtx
3948 && GET_CODE (sparc_compare_op0) == REG
3949 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3951 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3952 sparc_compare_op0, sparc_compare_op1);
3956 rtx cc_reg = gen_compare_reg (code,
3957 sparc_compare_op0, sparc_compare_op1);
3958 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3959 cc_reg, const0_rtx);
3963 (define_expand "movdicc"
3964 [(set (match_operand:DI 0 "register_operand" "")
3965 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3966 (match_operand:DI 2 "arith10_double_operand" "")
3967 (match_operand:DI 3 "arith10_double_operand" "")))]
3971 enum rtx_code code = GET_CODE (operands[1]);
3973 if (sparc_compare_op1 == const0_rtx
3974 && GET_CODE (sparc_compare_op0) == REG
3975 && GET_MODE (sparc_compare_op0) == DImode
3976 && v9_regcmp_p (code))
3978 operands[1] = gen_rtx_fmt_ee (code, DImode,
3979 sparc_compare_op0, sparc_compare_op1);
3983 rtx cc_reg = gen_compare_reg (code,
3984 sparc_compare_op0, sparc_compare_op1);
3985 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3986 cc_reg, const0_rtx);
3990 (define_expand "movsfcc"
3991 [(set (match_operand:SF 0 "register_operand" "")
3992 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3993 (match_operand:SF 2 "register_operand" "")
3994 (match_operand:SF 3 "register_operand" "")))]
3995 "TARGET_V9 && TARGET_FPU"
3998 enum rtx_code code = GET_CODE (operands[1]);
4000 if (GET_MODE (sparc_compare_op0) == DImode
4004 if (sparc_compare_op1 == const0_rtx
4005 && GET_CODE (sparc_compare_op0) == REG
4006 && GET_MODE (sparc_compare_op0) == DImode
4007 && v9_regcmp_p (code))
4009 operands[1] = gen_rtx_fmt_ee (code, DImode,
4010 sparc_compare_op0, sparc_compare_op1);
4014 rtx cc_reg = gen_compare_reg (code,
4015 sparc_compare_op0, sparc_compare_op1);
4016 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4020 (define_expand "movdfcc"
4021 [(set (match_operand:DF 0 "register_operand" "")
4022 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4023 (match_operand:DF 2 "register_operand" "")
4024 (match_operand:DF 3 "register_operand" "")))]
4025 "TARGET_V9 && TARGET_FPU"
4028 enum rtx_code code = GET_CODE (operands[1]);
4030 if (GET_MODE (sparc_compare_op0) == DImode
4034 if (sparc_compare_op1 == const0_rtx
4035 && GET_CODE (sparc_compare_op0) == REG
4036 && GET_MODE (sparc_compare_op0) == DImode
4037 && v9_regcmp_p (code))
4039 operands[1] = gen_rtx_fmt_ee (code, DImode,
4040 sparc_compare_op0, sparc_compare_op1);
4044 rtx cc_reg = gen_compare_reg (code,
4045 sparc_compare_op0, sparc_compare_op1);
4046 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4050 (define_expand "movtfcc"
4051 [(set (match_operand:TF 0 "register_operand" "")
4052 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4053 (match_operand:TF 2 "register_operand" "")
4054 (match_operand:TF 3 "register_operand" "")))]
4055 "TARGET_V9 && TARGET_FPU"
4058 enum rtx_code code = GET_CODE (operands[1]);
4060 if (GET_MODE (sparc_compare_op0) == DImode
4064 if (sparc_compare_op1 == const0_rtx
4065 && GET_CODE (sparc_compare_op0) == REG
4066 && GET_MODE (sparc_compare_op0) == DImode
4067 && v9_regcmp_p (code))
4069 operands[1] = gen_rtx_fmt_ee (code, DImode,
4070 sparc_compare_op0, sparc_compare_op1);
4074 rtx cc_reg = gen_compare_reg (code,
4075 sparc_compare_op0, sparc_compare_op1);
4076 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4080 ;; Conditional move define_insns.
4082 (define_insn "*movqi_cc_sp64"
4083 [(set (match_operand:QI 0 "register_operand" "=r,r")
4084 (if_then_else:QI (match_operator 1 "comparison_operator"
4085 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4087 (match_operand:QI 3 "arith11_operand" "rL,0")
4088 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4091 mov%C1\\t%x2, %3, %0
4092 mov%c1\\t%x2, %4, %0"
4093 [(set_attr "type" "cmove")])
4095 (define_insn "*movhi_cc_sp64"
4096 [(set (match_operand:HI 0 "register_operand" "=r,r")
4097 (if_then_else:HI (match_operator 1 "comparison_operator"
4098 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4100 (match_operand:HI 3 "arith11_operand" "rL,0")
4101 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4104 mov%C1\\t%x2, %3, %0
4105 mov%c1\\t%x2, %4, %0"
4106 [(set_attr "type" "cmove")])
4108 (define_insn "*movsi_cc_sp64"
4109 [(set (match_operand:SI 0 "register_operand" "=r,r")
4110 (if_then_else:SI (match_operator 1 "comparison_operator"
4111 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4113 (match_operand:SI 3 "arith11_operand" "rL,0")
4114 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4117 mov%C1\\t%x2, %3, %0
4118 mov%c1\\t%x2, %4, %0"
4119 [(set_attr "type" "cmove")])
4121 ;; ??? The constraints of operands 3,4 need work.
4122 (define_insn "*movdi_cc_sp64"
4123 [(set (match_operand:DI 0 "register_operand" "=r,r")
4124 (if_then_else:DI (match_operator 1 "comparison_operator"
4125 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4127 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4128 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4131 mov%C1\\t%x2, %3, %0
4132 mov%c1\\t%x2, %4, %0"
4133 [(set_attr "type" "cmove")])
4135 (define_insn "*movdi_cc_sp64_trunc"
4136 [(set (match_operand:SI 0 "register_operand" "=r,r")
4137 (if_then_else:SI (match_operator 1 "comparison_operator"
4138 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4140 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4141 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4144 mov%C1\\t%x2, %3, %0
4145 mov%c1\\t%x2, %4, %0"
4146 [(set_attr "type" "cmove")])
4148 (define_insn "*movsf_cc_sp64"
4149 [(set (match_operand:SF 0 "register_operand" "=f,f")
4150 (if_then_else:SF (match_operator 1 "comparison_operator"
4151 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4153 (match_operand:SF 3 "register_operand" "f,0")
4154 (match_operand:SF 4 "register_operand" "0,f")))]
4155 "TARGET_V9 && TARGET_FPU"
4157 fmovs%C1\\t%x2, %3, %0
4158 fmovs%c1\\t%x2, %4, %0"
4159 [(set_attr "type" "fpcmove")])
4161 (define_insn "movdf_cc_sp64"
4162 [(set (match_operand:DF 0 "register_operand" "=e,e")
4163 (if_then_else:DF (match_operator 1 "comparison_operator"
4164 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4166 (match_operand:DF 3 "register_operand" "e,0")
4167 (match_operand:DF 4 "register_operand" "0,e")))]
4168 "TARGET_V9 && TARGET_FPU"
4170 fmovd%C1\\t%x2, %3, %0
4171 fmovd%c1\\t%x2, %4, %0"
4172 [(set_attr "type" "fpcmove")
4173 (set_attr "fptype" "double")])
4175 (define_insn "*movtf_cc_hq_sp64"
4176 [(set (match_operand:TF 0 "register_operand" "=e,e")
4177 (if_then_else:TF (match_operator 1 "comparison_operator"
4178 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4180 (match_operand:TF 3 "register_operand" "e,0")
4181 (match_operand:TF 4 "register_operand" "0,e")))]
4182 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4184 fmovq%C1\\t%x2, %3, %0
4185 fmovq%c1\\t%x2, %4, %0"
4186 [(set_attr "type" "fpcmove")])
4188 (define_insn "*movtf_cc_sp64"
4189 [(set (match_operand:TF 0 "register_operand" "=e,e")
4190 (if_then_else:TF (match_operator 1 "comparison_operator"
4191 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4193 (match_operand:TF 3 "register_operand" "e,0")
4194 (match_operand:TF 4 "register_operand" "0,e")))]
4195 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4197 [(set_attr "length" "2")])
4200 [(set (match_operand:TF 0 "register_operand" "")
4201 (if_then_else:TF (match_operator 1 "comparison_operator"
4202 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4204 (match_operand:TF 3 "register_operand" "")
4205 (match_operand:TF 4 "register_operand" "")))]
4206 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4207 [(clobber (const_int 0))]
4210 rtx set_dest = operands[0];
4211 rtx set_srca = operands[3];
4212 rtx set_srcb = operands[4];
4213 int third = rtx_equal_p (set_dest, set_srca);
4215 rtx srca1, srca2, srcb1, srcb2;
4217 if (GET_CODE (set_dest) == SUBREG)
4218 set_dest = alter_subreg (set_dest);
4219 if (GET_CODE (set_srca) == SUBREG)
4220 set_srca = alter_subreg (set_srca);
4221 if (GET_CODE (set_srcb) == SUBREG)
4222 set_srcb = alter_subreg (set_srcb);
4224 dest1 = gen_df_reg (set_dest, 0);
4225 dest2 = gen_df_reg (set_dest, 1);
4226 srca1 = gen_df_reg (set_srca, 0);
4227 srca2 = gen_df_reg (set_srca, 1);
4228 srcb1 = gen_df_reg (set_srcb, 0);
4229 srcb2 = gen_df_reg (set_srcb, 1);
4231 /* Now emit using the real source and destination we found, swapping
4232 the order if we detect overlap. */
4233 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4234 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4236 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4237 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4241 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4242 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4247 (define_insn "*movqi_cc_reg_sp64"
4248 [(set (match_operand:QI 0 "register_operand" "=r,r")
4249 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4250 [(match_operand:DI 2 "register_operand" "r,r")
4252 (match_operand:QI 3 "arith10_operand" "rM,0")
4253 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4256 movr%D1\\t%2, %r3, %0
4257 movr%d1\\t%2, %r4, %0"
4258 [(set_attr "type" "cmove")])
4260 (define_insn "*movhi_cc_reg_sp64"
4261 [(set (match_operand:HI 0 "register_operand" "=r,r")
4262 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4263 [(match_operand:DI 2 "register_operand" "r,r")
4265 (match_operand:HI 3 "arith10_operand" "rM,0")
4266 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4269 movr%D1\\t%2, %r3, %0
4270 movr%d1\\t%2, %r4, %0"
4271 [(set_attr "type" "cmove")])
4273 (define_insn "*movsi_cc_reg_sp64"
4274 [(set (match_operand:SI 0 "register_operand" "=r,r")
4275 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4276 [(match_operand:DI 2 "register_operand" "r,r")
4278 (match_operand:SI 3 "arith10_operand" "rM,0")
4279 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4282 movr%D1\\t%2, %r3, %0
4283 movr%d1\\t%2, %r4, %0"
4284 [(set_attr "type" "cmove")])
4286 ;; ??? The constraints of operands 3,4 need work.
4287 (define_insn "*movdi_cc_reg_sp64"
4288 [(set (match_operand:DI 0 "register_operand" "=r,r")
4289 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4290 [(match_operand:DI 2 "register_operand" "r,r")
4292 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4293 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4296 movr%D1\\t%2, %r3, %0
4297 movr%d1\\t%2, %r4, %0"
4298 [(set_attr "type" "cmove")])
4300 (define_insn "*movdi_cc_reg_sp64_trunc"
4301 [(set (match_operand:SI 0 "register_operand" "=r,r")
4302 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4303 [(match_operand:DI 2 "register_operand" "r,r")
4305 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4306 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4309 movr%D1\\t%2, %r3, %0
4310 movr%d1\\t%2, %r4, %0"
4311 [(set_attr "type" "cmove")])
4313 (define_insn "*movsf_cc_reg_sp64"
4314 [(set (match_operand:SF 0 "register_operand" "=f,f")
4315 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4316 [(match_operand:DI 2 "register_operand" "r,r")
4318 (match_operand:SF 3 "register_operand" "f,0")
4319 (match_operand:SF 4 "register_operand" "0,f")))]
4320 "TARGET_ARCH64 && TARGET_FPU"
4322 fmovrs%D1\\t%2, %3, %0
4323 fmovrs%d1\\t%2, %4, %0"
4324 [(set_attr "type" "fpcmove")])
4326 (define_insn "movdf_cc_reg_sp64"
4327 [(set (match_operand:DF 0 "register_operand" "=e,e")
4328 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4329 [(match_operand:DI 2 "register_operand" "r,r")
4331 (match_operand:DF 3 "register_operand" "e,0")
4332 (match_operand:DF 4 "register_operand" "0,e")))]
4333 "TARGET_ARCH64 && TARGET_FPU"
4335 fmovrd%D1\\t%2, %3, %0
4336 fmovrd%d1\\t%2, %4, %0"
4337 [(set_attr "type" "fpcmove")
4338 (set_attr "fptype" "double")])
4340 (define_insn "*movtf_cc_reg_hq_sp64"
4341 [(set (match_operand:TF 0 "register_operand" "=e,e")
4342 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4343 [(match_operand:DI 2 "register_operand" "r,r")
4345 (match_operand:TF 3 "register_operand" "e,0")
4346 (match_operand:TF 4 "register_operand" "0,e")))]
4347 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4349 fmovrq%D1\\t%2, %3, %0
4350 fmovrq%d1\\t%2, %4, %0"
4351 [(set_attr "type" "fpcmove")])
4353 (define_insn "*movtf_cc_reg_sp64"
4354 [(set (match_operand:TF 0 "register_operand" "=e,e")
4355 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4356 [(match_operand:DI 2 "register_operand" "r,r")
4358 (match_operand:TF 3 "register_operand" "e,0")
4359 (match_operand:TF 4 "register_operand" "0,e")))]
4360 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4362 [(set_attr "length" "2")])
4365 [(set (match_operand:TF 0 "register_operand" "")
4366 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4367 [(match_operand:DI 2 "register_operand" "")
4369 (match_operand:TF 3 "register_operand" "")
4370 (match_operand:TF 4 "register_operand" "")))]
4371 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4372 [(clobber (const_int 0))]
4375 rtx set_dest = operands[0];
4376 rtx set_srca = operands[3];
4377 rtx set_srcb = operands[4];
4378 int third = rtx_equal_p (set_dest, set_srca);
4380 rtx srca1, srca2, srcb1, srcb2;
4382 if (GET_CODE (set_dest) == SUBREG)
4383 set_dest = alter_subreg (set_dest);
4384 if (GET_CODE (set_srca) == SUBREG)
4385 set_srca = alter_subreg (set_srca);
4386 if (GET_CODE (set_srcb) == SUBREG)
4387 set_srcb = alter_subreg (set_srcb);
4389 dest1 = gen_df_reg (set_dest, 0);
4390 dest2 = gen_df_reg (set_dest, 1);
4391 srca1 = gen_df_reg (set_srca, 0);
4392 srca2 = gen_df_reg (set_srca, 1);
4393 srcb1 = gen_df_reg (set_srcb, 0);
4394 srcb2 = gen_df_reg (set_srcb, 1);
4396 /* Now emit using the real source and destination we found, swapping
4397 the order if we detect overlap. */
4398 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4399 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4401 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4402 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4406 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4407 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4413 ;;- zero extension instructions
4415 ;; These patterns originally accepted general_operands, however, slightly
4416 ;; better code is generated by only accepting register_operands, and then
4417 ;; letting combine generate the ldu[hb] insns.
4419 (define_expand "zero_extendhisi2"
4420 [(set (match_operand:SI 0 "register_operand" "")
4421 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4425 rtx temp = gen_reg_rtx (SImode);
4426 rtx shift_16 = GEN_INT (16);
4427 int op1_subbyte = 0;
4429 if (GET_CODE (operand1) == SUBREG)
4431 op1_subbyte = SUBREG_BYTE (operand1);
4432 op1_subbyte /= GET_MODE_SIZE (SImode);
4433 op1_subbyte *= GET_MODE_SIZE (SImode);
4434 operand1 = XEXP (operand1, 0);
4437 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4439 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4443 (define_insn "*zero_extendhisi2_insn"
4444 [(set (match_operand:SI 0 "register_operand" "=r")
4445 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4448 [(set_attr "type" "load")])
4450 (define_expand "zero_extendqihi2"
4451 [(set (match_operand:HI 0 "register_operand" "")
4452 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4456 (define_insn "*zero_extendqihi2_insn"
4457 [(set (match_operand:HI 0 "register_operand" "=r,r")
4458 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4459 "GET_CODE (operands[1]) != CONST_INT"
4463 [(set_attr "type" "*,load")])
4465 (define_expand "zero_extendqisi2"
4466 [(set (match_operand:SI 0 "register_operand" "")
4467 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4471 (define_insn "*zero_extendqisi2_insn"
4472 [(set (match_operand:SI 0 "register_operand" "=r,r")
4473 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4474 "GET_CODE (operands[1]) != CONST_INT"
4478 [(set_attr "type" "*,load")])
4480 (define_expand "zero_extendqidi2"
4481 [(set (match_operand:DI 0 "register_operand" "")
4482 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4486 (define_insn "*zero_extendqidi2_insn"
4487 [(set (match_operand:DI 0 "register_operand" "=r,r")
4488 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4489 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4493 [(set_attr "type" "*,load")])
4495 (define_expand "zero_extendhidi2"
4496 [(set (match_operand:DI 0 "register_operand" "")
4497 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4501 rtx temp = gen_reg_rtx (DImode);
4502 rtx shift_48 = GEN_INT (48);
4503 int op1_subbyte = 0;
4505 if (GET_CODE (operand1) == SUBREG)
4507 op1_subbyte = SUBREG_BYTE (operand1);
4508 op1_subbyte /= GET_MODE_SIZE (DImode);
4509 op1_subbyte *= GET_MODE_SIZE (DImode);
4510 operand1 = XEXP (operand1, 0);
4513 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4515 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4519 (define_insn "*zero_extendhidi2_insn"
4520 [(set (match_operand:DI 0 "register_operand" "=r")
4521 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4524 [(set_attr "type" "load")])
4527 ;; ??? Write truncdisi pattern using sra?
4529 (define_expand "zero_extendsidi2"
4530 [(set (match_operand:DI 0 "register_operand" "")
4531 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4535 (define_insn "*zero_extendsidi2_insn_sp64"
4536 [(set (match_operand:DI 0 "register_operand" "=r,r")
4537 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4538 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4542 [(set_attr "type" "shift,load")])
4544 (define_insn "*zero_extendsidi2_insn_sp32"
4545 [(set (match_operand:DI 0 "register_operand" "=r")
4546 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4549 [(set_attr "length" "2")])
4552 [(set (match_operand:DI 0 "register_operand" "")
4553 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4554 "! TARGET_ARCH64 && reload_completed"
4555 [(set (match_dup 2) (match_dup 3))
4556 (set (match_dup 4) (match_dup 5))]
4561 if (GET_CODE (operands[0]) == SUBREG)
4562 operands[0] = alter_subreg (operands[0]);
4564 dest1 = gen_highpart (SImode, operands[0]);
4565 dest2 = gen_lowpart (SImode, operands[0]);
4567 /* Swap the order in case of overlap. */
4568 if (REGNO (dest1) == REGNO (operands[1]))
4570 operands[2] = dest2;
4571 operands[3] = operands[1];
4572 operands[4] = dest1;
4573 operands[5] = const0_rtx;
4577 operands[2] = dest1;
4578 operands[3] = const0_rtx;
4579 operands[4] = dest2;
4580 operands[5] = operands[1];
4584 ;; Simplify comparisons of extended values.
4586 (define_insn "*cmp_zero_extendqisi2"
4588 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4591 "andcc\\t%0, 0xff, %%g0"
4592 [(set_attr "type" "compare")])
4594 (define_insn "*cmp_zero_qi"
4596 (compare:CC (match_operand:QI 0 "register_operand" "r")
4599 "andcc\\t%0, 0xff, %%g0"
4600 [(set_attr "type" "compare")])
4602 (define_insn "*cmp_zero_extendqisi2_set"
4604 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4606 (set (match_operand:SI 0 "register_operand" "=r")
4607 (zero_extend:SI (match_dup 1)))]
4609 "andcc\\t%1, 0xff, %0"
4610 [(set_attr "type" "compare")])
4612 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4614 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4617 (set (match_operand:SI 0 "register_operand" "=r")
4618 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4620 "andcc\\t%1, 0xff, %0"
4621 [(set_attr "type" "compare")])
4623 (define_insn "*cmp_zero_extendqidi2"
4625 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4628 "andcc\\t%0, 0xff, %%g0"
4629 [(set_attr "type" "compare")])
4631 (define_insn "*cmp_zero_qi_sp64"
4633 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4636 "andcc\\t%0, 0xff, %%g0"
4637 [(set_attr "type" "compare")])
4639 (define_insn "*cmp_zero_extendqidi2_set"
4641 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4643 (set (match_operand:DI 0 "register_operand" "=r")
4644 (zero_extend:DI (match_dup 1)))]
4646 "andcc\\t%1, 0xff, %0"
4647 [(set_attr "type" "compare")])
4649 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4651 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4654 (set (match_operand:DI 0 "register_operand" "=r")
4655 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4657 "andcc\\t%1, 0xff, %0"
4658 [(set_attr "type" "compare")])
4660 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4662 (define_insn "*cmp_siqi_trunc"
4664 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4667 "andcc\\t%0, 0xff, %%g0"
4668 [(set_attr "type" "compare")])
4670 (define_insn "*cmp_siqi_trunc_set"
4672 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4674 (set (match_operand:QI 0 "register_operand" "=r")
4675 (subreg:QI (match_dup 1) 3))]
4677 "andcc\\t%1, 0xff, %0"
4678 [(set_attr "type" "compare")])
4680 (define_insn "*cmp_diqi_trunc"
4682 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4685 "andcc\\t%0, 0xff, %%g0"
4686 [(set_attr "type" "compare")])
4688 (define_insn "*cmp_diqi_trunc_set"
4690 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4692 (set (match_operand:QI 0 "register_operand" "=r")
4693 (subreg:QI (match_dup 1) 7))]
4695 "andcc\\t%1, 0xff, %0"
4696 [(set_attr "type" "compare")])
4698 ;;- sign extension instructions
4700 ;; These patterns originally accepted general_operands, however, slightly
4701 ;; better code is generated by only accepting register_operands, and then
4702 ;; letting combine generate the lds[hb] insns.
4704 (define_expand "extendhisi2"
4705 [(set (match_operand:SI 0 "register_operand" "")
4706 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4710 rtx temp = gen_reg_rtx (SImode);
4711 rtx shift_16 = GEN_INT (16);
4712 int op1_subbyte = 0;
4714 if (GET_CODE (operand1) == SUBREG)
4716 op1_subbyte = SUBREG_BYTE (operand1);
4717 op1_subbyte /= GET_MODE_SIZE (SImode);
4718 op1_subbyte *= GET_MODE_SIZE (SImode);
4719 operand1 = XEXP (operand1, 0);
4722 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4724 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4728 (define_insn "*sign_extendhisi2_insn"
4729 [(set (match_operand:SI 0 "register_operand" "=r")
4730 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4733 [(set_attr "type" "sload")])
4735 (define_expand "extendqihi2"
4736 [(set (match_operand:HI 0 "register_operand" "")
4737 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4741 rtx temp = gen_reg_rtx (SImode);
4742 rtx shift_24 = GEN_INT (24);
4743 int op1_subbyte = 0;
4744 int op0_subbyte = 0;
4746 if (GET_CODE (operand1) == SUBREG)
4748 op1_subbyte = SUBREG_BYTE (operand1);
4749 op1_subbyte /= GET_MODE_SIZE (SImode);
4750 op1_subbyte *= GET_MODE_SIZE (SImode);
4751 operand1 = XEXP (operand1, 0);
4753 if (GET_CODE (operand0) == SUBREG)
4755 op0_subbyte = SUBREG_BYTE (operand0);
4756 op0_subbyte /= GET_MODE_SIZE (SImode);
4757 op0_subbyte *= GET_MODE_SIZE (SImode);
4758 operand0 = XEXP (operand0, 0);
4760 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4762 if (GET_MODE (operand0) != SImode)
4763 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4764 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4768 (define_insn "*sign_extendqihi2_insn"
4769 [(set (match_operand:HI 0 "register_operand" "=r")
4770 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4773 [(set_attr "type" "sload")])
4775 (define_expand "extendqisi2"
4776 [(set (match_operand:SI 0 "register_operand" "")
4777 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4781 rtx temp = gen_reg_rtx (SImode);
4782 rtx shift_24 = GEN_INT (24);
4783 int op1_subbyte = 0;
4785 if (GET_CODE (operand1) == SUBREG)
4787 op1_subbyte = SUBREG_BYTE (operand1);
4788 op1_subbyte /= GET_MODE_SIZE (SImode);
4789 op1_subbyte *= GET_MODE_SIZE (SImode);
4790 operand1 = XEXP (operand1, 0);
4793 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4795 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4799 (define_insn "*sign_extendqisi2_insn"
4800 [(set (match_operand:SI 0 "register_operand" "=r")
4801 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4804 [(set_attr "type" "sload")])
4806 (define_expand "extendqidi2"
4807 [(set (match_operand:DI 0 "register_operand" "")
4808 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4812 rtx temp = gen_reg_rtx (DImode);
4813 rtx shift_56 = GEN_INT (56);
4814 int op1_subbyte = 0;
4816 if (GET_CODE (operand1) == SUBREG)
4818 op1_subbyte = SUBREG_BYTE (operand1);
4819 op1_subbyte /= GET_MODE_SIZE (DImode);
4820 op1_subbyte *= GET_MODE_SIZE (DImode);
4821 operand1 = XEXP (operand1, 0);
4824 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4826 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4830 (define_insn "*sign_extendqidi2_insn"
4831 [(set (match_operand:DI 0 "register_operand" "=r")
4832 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4835 [(set_attr "type" "sload")])
4837 (define_expand "extendhidi2"
4838 [(set (match_operand:DI 0 "register_operand" "")
4839 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4843 rtx temp = gen_reg_rtx (DImode);
4844 rtx shift_48 = GEN_INT (48);
4845 int op1_subbyte = 0;
4847 if (GET_CODE (operand1) == SUBREG)
4849 op1_subbyte = SUBREG_BYTE (operand1);
4850 op1_subbyte /= GET_MODE_SIZE (DImode);
4851 op1_subbyte *= GET_MODE_SIZE (DImode);
4852 operand1 = XEXP (operand1, 0);
4855 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4857 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4861 (define_insn "*sign_extendhidi2_insn"
4862 [(set (match_operand:DI 0 "register_operand" "=r")
4863 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4866 [(set_attr "type" "sload")])
4868 (define_expand "extendsidi2"
4869 [(set (match_operand:DI 0 "register_operand" "")
4870 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4874 (define_insn "*sign_extendsidi2_insn"
4875 [(set (match_operand:DI 0 "register_operand" "=r,r")
4876 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4881 [(set_attr "type" "shift,sload")])
4883 ;; Special pattern for optimizing bit-field compares. This is needed
4884 ;; because combine uses this as a canonical form.
4886 (define_insn "*cmp_zero_extract"
4889 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4890 (match_operand:SI 1 "small_int_or_double" "n")
4891 (match_operand:SI 2 "small_int_or_double" "n"))
4893 "(GET_CODE (operands[2]) == CONST_INT
4894 && INTVAL (operands[2]) > 19)
4895 || (GET_CODE (operands[2]) == CONST_DOUBLE
4896 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4899 int len = (GET_CODE (operands[1]) == CONST_INT
4900 ? INTVAL (operands[1])
4901 : CONST_DOUBLE_LOW (operands[1]));
4903 (GET_CODE (operands[2]) == CONST_INT
4904 ? INTVAL (operands[2])
4905 : CONST_DOUBLE_LOW (operands[2])) - len;
4906 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4908 operands[1] = GEN_INT (mask);
4909 return \"andcc\\t%0, %1, %%g0\";
4911 [(set_attr "type" "compare")])
4913 (define_insn "*cmp_zero_extract_sp64"
4916 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4917 (match_operand:SI 1 "small_int_or_double" "n")
4918 (match_operand:SI 2 "small_int_or_double" "n"))
4921 && ((GET_CODE (operands[2]) == CONST_INT
4922 && INTVAL (operands[2]) > 51)
4923 || (GET_CODE (operands[2]) == CONST_DOUBLE
4924 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4927 int len = (GET_CODE (operands[1]) == CONST_INT
4928 ? INTVAL (operands[1])
4929 : CONST_DOUBLE_LOW (operands[1]));
4931 (GET_CODE (operands[2]) == CONST_INT
4932 ? INTVAL (operands[2])
4933 : CONST_DOUBLE_LOW (operands[2])) - len;
4934 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4936 operands[1] = GEN_INT (mask);
4937 return \"andcc\\t%0, %1, %%g0\";
4939 [(set_attr "type" "compare")])
4941 ;; Conversions between float, double and long double.
4943 (define_insn "extendsfdf2"
4944 [(set (match_operand:DF 0 "register_operand" "=e")
4946 (match_operand:SF 1 "register_operand" "f")))]
4949 [(set_attr "type" "fp")
4950 (set_attr "fptype" "double")])
4952 (define_expand "extendsftf2"
4953 [(set (match_operand:TF 0 "register_operand" "=e")
4955 (match_operand:SF 1 "register_operand" "f")))]
4956 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4959 if (! TARGET_HARD_QUAD)
4963 if (GET_CODE (operands[0]) != MEM)
4964 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4966 slot0 = operands[0];
4968 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4970 XEXP (slot0, 0), Pmode,
4971 operands[1], SFmode);
4973 if (GET_CODE (operands[0]) != MEM)
4974 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4979 (define_insn "*extendsftf2_hq"
4980 [(set (match_operand:TF 0 "register_operand" "=e")
4982 (match_operand:SF 1 "register_operand" "f")))]
4983 "TARGET_FPU && TARGET_HARD_QUAD"
4985 [(set_attr "type" "fp")])
4987 (define_expand "extenddftf2"
4988 [(set (match_operand:TF 0 "register_operand" "=e")
4990 (match_operand:DF 1 "register_operand" "e")))]
4991 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4994 if (! TARGET_HARD_QUAD)
4998 if (GET_CODE (operands[0]) != MEM)
4999 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5001 slot0 = operands[0];
5003 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5005 XEXP (slot0, 0), Pmode,
5006 operands[1], DFmode);
5008 if (GET_CODE (operands[0]) != MEM)
5009 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5014 (define_insn "*extenddftf2_hq"
5015 [(set (match_operand:TF 0 "register_operand" "=e")
5017 (match_operand:DF 1 "register_operand" "e")))]
5018 "TARGET_FPU && TARGET_HARD_QUAD"
5020 [(set_attr "type" "fp")])
5022 (define_insn "truncdfsf2"
5023 [(set (match_operand:SF 0 "register_operand" "=f")
5025 (match_operand:DF 1 "register_operand" "e")))]
5028 [(set_attr "type" "fp")
5029 (set_attr "fptype" "double")])
5031 (define_expand "trunctfsf2"
5032 [(set (match_operand:SF 0 "register_operand" "=f")
5034 (match_operand:TF 1 "register_operand" "e")))]
5035 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5038 if (! TARGET_HARD_QUAD)
5042 if (GET_CODE (operands[1]) != MEM)
5044 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5045 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5048 slot0 = operands[1];
5050 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5051 operands[0], 0, SFmode, 1,
5052 XEXP (slot0, 0), Pmode);
5057 (define_insn "*trunctfsf2_hq"
5058 [(set (match_operand:SF 0 "register_operand" "=f")
5060 (match_operand:TF 1 "register_operand" "e")))]
5061 "TARGET_FPU && TARGET_HARD_QUAD"
5063 [(set_attr "type" "fp")])
5065 (define_expand "trunctfdf2"
5066 [(set (match_operand:DF 0 "register_operand" "=f")
5068 (match_operand:TF 1 "register_operand" "e")))]
5069 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5072 if (! TARGET_HARD_QUAD)
5076 if (GET_CODE (operands[1]) != MEM)
5078 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5079 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5082 slot0 = operands[1];
5084 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5085 operands[0], 0, DFmode, 1,
5086 XEXP (slot0, 0), Pmode);
5091 (define_insn "*trunctfdf2_hq"
5092 [(set (match_operand:DF 0 "register_operand" "=e")
5094 (match_operand:TF 1 "register_operand" "e")))]
5095 "TARGET_FPU && TARGET_HARD_QUAD"
5097 [(set_attr "type" "fp")])
5099 ;; Conversion between fixed point and floating point.
5101 (define_insn "floatsisf2"
5102 [(set (match_operand:SF 0 "register_operand" "=f")
5103 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5106 [(set_attr "type" "fp")
5107 (set_attr "fptype" "double")])
5109 (define_insn "floatsidf2"
5110 [(set (match_operand:DF 0 "register_operand" "=e")
5111 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5114 [(set_attr "type" "fp")
5115 (set_attr "fptype" "double")])
5117 (define_expand "floatsitf2"
5118 [(set (match_operand:TF 0 "register_operand" "=e")
5119 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5120 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5123 if (! TARGET_HARD_QUAD)
5127 if (GET_CODE (operands[1]) != MEM)
5128 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5130 slot0 = operands[1];
5132 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5134 XEXP (slot0, 0), Pmode,
5135 operands[1], SImode);
5137 if (GET_CODE (operands[0]) != MEM)
5138 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5143 (define_insn "*floatsitf2_hq"
5144 [(set (match_operand:TF 0 "register_operand" "=e")
5145 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5146 "TARGET_FPU && TARGET_HARD_QUAD"
5148 [(set_attr "type" "fp")])
5150 (define_expand "floatunssitf2"
5151 [(set (match_operand:TF 0 "register_operand" "=e")
5152 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5153 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5158 if (GET_CODE (operands[1]) != MEM)
5159 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5161 slot0 = operands[1];
5163 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5165 XEXP (slot0, 0), Pmode,
5166 operands[1], SImode);
5168 if (GET_CODE (operands[0]) != MEM)
5169 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5173 ;; Now the same for 64 bit sources.
5175 (define_insn "floatdisf2"
5176 [(set (match_operand:SF 0 "register_operand" "=f")
5177 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5178 "TARGET_V9 && TARGET_FPU"
5180 [(set_attr "type" "fp")
5181 (set_attr "fptype" "double")])
5183 (define_insn "floatdidf2"
5184 [(set (match_operand:DF 0 "register_operand" "=e")
5185 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5186 "TARGET_V9 && TARGET_FPU"
5188 [(set_attr "type" "fp")
5189 (set_attr "fptype" "double")])
5191 (define_expand "floatditf2"
5192 [(set (match_operand:TF 0 "register_operand" "=e")
5193 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5194 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5197 if (! TARGET_HARD_QUAD)
5201 if (GET_CODE (operands[1]) != MEM)
5202 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5204 slot0 = operands[1];
5206 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5208 XEXP (slot0, 0), Pmode,
5209 operands[1], DImode);
5211 if (GET_CODE (operands[0]) != MEM)
5212 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5217 (define_insn "*floatditf2_hq"
5218 [(set (match_operand:TF 0 "register_operand" "=e")
5219 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5220 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5222 [(set_attr "type" "fp")])
5224 (define_expand "floatunsditf2"
5225 [(set (match_operand:TF 0 "register_operand" "=e")
5226 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5227 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5232 if (GET_CODE (operands[1]) != MEM)
5233 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5235 slot0 = operands[1];
5237 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5239 XEXP (slot0, 0), Pmode,
5240 operands[1], DImode);
5242 if (GET_CODE (operands[0]) != MEM)
5243 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5247 ;; Convert a float to an actual integer.
5248 ;; Truncation is performed as part of the conversion.
5250 (define_insn "fix_truncsfsi2"
5251 [(set (match_operand:SI 0 "register_operand" "=f")
5252 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5255 [(set_attr "type" "fp")
5256 (set_attr "fptype" "double")])
5258 (define_insn "fix_truncdfsi2"
5259 [(set (match_operand:SI 0 "register_operand" "=f")
5260 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5263 [(set_attr "type" "fp")
5264 (set_attr "fptype" "double")])
5266 (define_expand "fix_trunctfsi2"
5267 [(set (match_operand:SI 0 "register_operand" "=f")
5268 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5269 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5272 if (! TARGET_HARD_QUAD)
5276 if (GET_CODE (operands[1]) != MEM)
5278 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5279 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5282 slot0 = operands[1];
5284 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5285 operands[0], 0, SImode, 1,
5286 XEXP (slot0, 0), Pmode);
5291 (define_insn "*fix_trunctfsi2_hq"
5292 [(set (match_operand:SI 0 "register_operand" "=f")
5293 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5294 "TARGET_FPU && TARGET_HARD_QUAD"
5296 [(set_attr "type" "fp")])
5298 (define_expand "fixuns_trunctfsi2"
5299 [(set (match_operand:SI 0 "register_operand" "=f")
5300 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5301 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5306 if (GET_CODE (operands[1]) != MEM)
5308 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5309 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5312 slot0 = operands[1];
5314 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5315 operands[0], 0, SImode, 1,
5316 XEXP (slot0, 0), Pmode);
5320 ;; Now the same, for V9 targets
5322 (define_insn "fix_truncsfdi2"
5323 [(set (match_operand:DI 0 "register_operand" "=e")
5324 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5325 "TARGET_V9 && TARGET_FPU"
5327 [(set_attr "type" "fp")
5328 (set_attr "fptype" "double")])
5330 (define_insn "fix_truncdfdi2"
5331 [(set (match_operand:DI 0 "register_operand" "=e")
5332 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5333 "TARGET_V9 && TARGET_FPU"
5335 [(set_attr "type" "fp")
5336 (set_attr "fptype" "double")])
5338 (define_expand "fix_trunctfdi2"
5339 [(set (match_operand:DI 0 "register_operand" "=e")
5340 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5341 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5344 if (! TARGET_HARD_QUAD)
5348 if (GET_CODE (operands[1]) != MEM)
5350 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5351 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5354 slot0 = operands[1];
5356 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5357 operands[0], 0, DImode, 1,
5358 XEXP (slot0, 0), Pmode);
5363 (define_insn "*fix_trunctfdi2_hq"
5364 [(set (match_operand:DI 0 "register_operand" "=e")
5365 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5366 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5368 [(set_attr "type" "fp")])
5370 (define_expand "fixuns_trunctfdi2"
5371 [(set (match_operand:DI 0 "register_operand" "=f")
5372 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5373 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5378 if (GET_CODE (operands[1]) != MEM)
5380 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5381 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5384 slot0 = operands[1];
5386 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5387 operands[0], 0, DImode, 1,
5388 XEXP (slot0, 0), Pmode);
5393 ;;- arithmetic instructions
5395 (define_expand "adddi3"
5396 [(set (match_operand:DI 0 "register_operand" "=r")
5397 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5398 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5404 if (! TARGET_ARCH64)
5406 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5407 gen_rtx_SET (VOIDmode, operands[0],
5408 gen_rtx_PLUS (DImode, operands[1],
5410 gen_rtx_CLOBBER (VOIDmode,
5411 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5414 if (arith_double_4096_operand(operands[2], DImode))
5416 switch (GET_CODE (operands[1]))
5418 case CONST_INT: i = INTVAL (operands[1]); break;
5419 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5421 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5422 gen_rtx_MINUS (DImode, operands[1],
5426 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5431 (define_insn "adddi3_insn_sp32"
5432 [(set (match_operand:DI 0 "register_operand" "=r")
5433 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5434 (match_operand:DI 2 "arith_double_operand" "rHI")))
5435 (clobber (reg:CC 100))]
5438 [(set_attr "length" "2")])
5441 [(set (match_operand:DI 0 "register_operand" "")
5442 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5443 (match_operand:DI 2 "arith_double_operand" "")))
5444 (clobber (reg:CC 100))]
5445 "! TARGET_ARCH64 && reload_completed"
5446 [(parallel [(set (reg:CC_NOOV 100)
5447 (compare:CC_NOOV (plus:SI (match_dup 4)
5451 (plus:SI (match_dup 4) (match_dup 5)))])
5453 (plus:SI (plus:SI (match_dup 7)
5455 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5458 operands[3] = gen_lowpart (SImode, operands[0]);
5459 operands[4] = gen_lowpart (SImode, operands[1]);
5460 operands[5] = gen_lowpart (SImode, operands[2]);
5461 operands[6] = gen_highpart (SImode, operands[0]);
5462 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5463 #if HOST_BITS_PER_WIDE_INT == 32
5464 if (GET_CODE (operands[2]) == CONST_INT)
5466 if (INTVAL (operands[2]) < 0)
5467 operands[8] = constm1_rtx;
5469 operands[8] = const0_rtx;
5473 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5477 [(set (match_operand:DI 0 "register_operand" "")
5478 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5479 (match_operand:DI 2 "arith_double_operand" "")))
5480 (clobber (reg:CC 100))]
5481 "! TARGET_ARCH64 && reload_completed"
5482 [(parallel [(set (reg:CC_NOOV 100)
5483 (compare:CC_NOOV (minus:SI (match_dup 4)
5487 (minus:SI (match_dup 4) (match_dup 5)))])
5489 (minus:SI (minus:SI (match_dup 7)
5491 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5494 operands[3] = gen_lowpart (SImode, operands[0]);
5495 operands[4] = gen_lowpart (SImode, operands[1]);
5496 operands[5] = gen_lowpart (SImode, operands[2]);
5497 operands[6] = gen_highpart (SImode, operands[0]);
5498 operands[7] = gen_highpart (SImode, operands[1]);
5499 #if HOST_BITS_PER_WIDE_INT == 32
5500 if (GET_CODE (operands[2]) == CONST_INT)
5502 if (INTVAL (operands[2]) < 0)
5503 operands[8] = constm1_rtx;
5505 operands[8] = const0_rtx;
5509 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5512 ;; LTU here means "carry set"
5514 [(set (match_operand:SI 0 "register_operand" "=r")
5515 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5516 (match_operand:SI 2 "arith_operand" "rI"))
5517 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5520 [(set_attr "type" "misc")])
5522 (define_insn "*addx_extend_sp32"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5524 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5525 (match_operand:SI 2 "arith_operand" "rI"))
5526 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5529 [(set_attr "length" "2")])
5532 [(set (match_operand:DI 0 "register_operand" "")
5533 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5534 (match_operand:SI 2 "arith_operand" ""))
5535 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5536 "! TARGET_ARCH64 && reload_completed"
5537 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5538 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5539 (set (match_dup 4) (const_int 0))]
5540 "operands[3] = gen_lowpart (SImode, operands[0]);
5541 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5543 (define_insn "*addx_extend_sp64"
5544 [(set (match_operand:DI 0 "register_operand" "=r")
5545 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5546 (match_operand:SI 2 "arith_operand" "rI"))
5547 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5549 "addx\\t%r1, %2, %0"
5550 [(set_attr "type" "misc")])
5553 [(set (match_operand:SI 0 "register_operand" "=r")
5554 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5555 (match_operand:SI 2 "arith_operand" "rI"))
5556 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5558 "subx\\t%r1, %2, %0"
5559 [(set_attr "type" "misc")])
5561 (define_insn "*subx_extend_sp64"
5562 [(set (match_operand:DI 0 "register_operand" "=r")
5563 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5564 (match_operand:SI 2 "arith_operand" "rI"))
5565 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5567 "subx\\t%r1, %2, %0"
5568 [(set_attr "type" "misc")])
5570 (define_insn "*subx_extend"
5571 [(set (match_operand:DI 0 "register_operand" "=r")
5572 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5573 (match_operand:SI 2 "arith_operand" "rI"))
5574 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5577 [(set_attr "length" "2")])
5580 [(set (match_operand:DI 0 "register_operand" "")
5581 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5582 (match_operand:SI 2 "arith_operand" ""))
5583 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5584 "! TARGET_ARCH64 && reload_completed"
5585 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5586 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5587 (set (match_dup 4) (const_int 0))]
5588 "operands[3] = gen_lowpart (SImode, operands[0]);
5589 operands[4] = gen_highpart (SImode, operands[0]);")
5592 [(set (match_operand:DI 0 "register_operand" "=r")
5593 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5594 (match_operand:DI 2 "register_operand" "r")))
5595 (clobber (reg:CC 100))]
5598 [(set_attr "length" "2")])
5601 [(set (match_operand:DI 0 "register_operand" "")
5602 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5603 (match_operand:DI 2 "register_operand" "")))
5604 (clobber (reg:CC 100))]
5605 "! TARGET_ARCH64 && reload_completed"
5606 [(parallel [(set (reg:CC_NOOV 100)
5607 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5609 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5611 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5612 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5613 "operands[3] = gen_lowpart (SImode, operands[2]);
5614 operands[4] = gen_highpart (SImode, operands[2]);
5615 operands[5] = gen_lowpart (SImode, operands[0]);
5616 operands[6] = gen_highpart (SImode, operands[0]);")
5618 (define_insn "*adddi3_sp64"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5620 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5621 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5625 (define_expand "addsi3"
5626 [(set (match_operand:SI 0 "register_operand" "=r,d")
5627 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5628 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5632 if (arith_4096_operand(operands[2], SImode))
5634 if (GET_CODE (operands[1]) == CONST_INT)
5635 emit_insn (gen_movsi (operands[0],
5636 GEN_INT (INTVAL (operands[1]) + 4096)));
5638 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5639 gen_rtx_MINUS (SImode, operands[1],
5645 (define_insn "*addsi3"
5646 [(set (match_operand:SI 0 "register_operand" "=r,d")
5647 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5648 (match_operand:SI 2 "arith_operand" "rI,d")))]
5652 fpadd32s\\t%1, %2, %0"
5653 [(set_attr "type" "*,fp")])
5655 (define_insn "*cmp_cc_plus"
5656 [(set (reg:CC_NOOV 100)
5657 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5658 (match_operand:SI 1 "arith_operand" "rI"))
5661 "addcc\\t%0, %1, %%g0"
5662 [(set_attr "type" "compare")])
5664 (define_insn "*cmp_ccx_plus"
5665 [(set (reg:CCX_NOOV 100)
5666 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5667 (match_operand:DI 1 "arith_double_operand" "rHI"))
5670 "addcc\\t%0, %1, %%g0"
5671 [(set_attr "type" "compare")])
5673 (define_insn "*cmp_cc_plus_set"
5674 [(set (reg:CC_NOOV 100)
5675 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5676 (match_operand:SI 2 "arith_operand" "rI"))
5678 (set (match_operand:SI 0 "register_operand" "=r")
5679 (plus:SI (match_dup 1) (match_dup 2)))]
5681 "addcc\\t%1, %2, %0"
5682 [(set_attr "type" "compare")])
5684 (define_insn "*cmp_ccx_plus_set"
5685 [(set (reg:CCX_NOOV 100)
5686 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5687 (match_operand:DI 2 "arith_double_operand" "rHI"))
5689 (set (match_operand:DI 0 "register_operand" "=r")
5690 (plus:DI (match_dup 1) (match_dup 2)))]
5692 "addcc\\t%1, %2, %0"
5693 [(set_attr "type" "compare")])
5695 (define_expand "subdi3"
5696 [(set (match_operand:DI 0 "register_operand" "=r")
5697 (minus:DI (match_operand:DI 1 "register_operand" "r")
5698 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5702 if (! TARGET_ARCH64)
5704 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5705 gen_rtx_SET (VOIDmode, operands[0],
5706 gen_rtx_MINUS (DImode, operands[1],
5708 gen_rtx_CLOBBER (VOIDmode,
5709 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5712 if (arith_double_4096_operand(operands[2], DImode))
5714 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5715 gen_rtx_PLUS (DImode, operands[1],
5721 (define_insn "*subdi3_sp32"
5722 [(set (match_operand:DI 0 "register_operand" "=r")
5723 (minus:DI (match_operand:DI 1 "register_operand" "r")
5724 (match_operand:DI 2 "arith_double_operand" "rHI")))
5725 (clobber (reg:CC 100))]
5728 [(set_attr "length" "2")])
5731 [(set (match_operand:DI 0 "register_operand" "")
5732 (minus:DI (match_operand:DI 1 "register_operand" "")
5733 (match_operand:DI 2 "arith_double_operand" "")))
5734 (clobber (reg:CC 100))]
5737 && (GET_CODE (operands[2]) == CONST_INT
5738 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5739 [(clobber (const_int 0))]
5744 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5745 lowp = gen_lowpart (SImode, operands[2]);
5746 if ((lowp == const0_rtx)
5747 && (operands[0] == operands[1]))
5749 emit_insn (gen_rtx_SET (VOIDmode,
5750 gen_highpart (SImode, operands[0]),
5751 gen_rtx_MINUS (SImode,
5752 gen_highpart_mode (SImode, DImode,
5758 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5759 gen_lowpart (SImode, operands[1]),
5761 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5762 gen_highpart_mode (SImode, DImode, operands[1]),
5769 [(set (match_operand:DI 0 "register_operand" "")
5770 (minus:DI (match_operand:DI 1 "register_operand" "")
5771 (match_operand:DI 2 "register_operand" "")))
5772 (clobber (reg:CC 100))]
5774 && reload_completed"
5775 [(clobber (const_int 0))]
5778 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5779 gen_lowpart (SImode, operands[1]),
5780 gen_lowpart (SImode, operands[2])));
5781 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5782 gen_highpart (SImode, operands[1]),
5783 gen_highpart (SImode, operands[2])));
5788 [(set (match_operand:DI 0 "register_operand" "=r")
5789 (minus:DI (match_operand:DI 1 "register_operand" "r")
5790 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5791 (clobber (reg:CC 100))]
5794 [(set_attr "length" "2")])
5797 [(set (match_operand:DI 0 "register_operand" "")
5798 (minus:DI (match_operand:DI 1 "register_operand" "")
5799 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5800 (clobber (reg:CC 100))]
5801 "! TARGET_ARCH64 && reload_completed"
5802 [(parallel [(set (reg:CC_NOOV 100)
5803 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5805 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5807 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5808 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5809 "operands[3] = gen_lowpart (SImode, operands[1]);
5810 operands[4] = gen_highpart (SImode, operands[1]);
5811 operands[5] = gen_lowpart (SImode, operands[0]);
5812 operands[6] = gen_highpart (SImode, operands[0]);")
5814 (define_insn "*subdi3_sp64"
5815 [(set (match_operand:DI 0 "register_operand" "=r")
5816 (minus:DI (match_operand:DI 1 "register_operand" "r")
5817 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5821 (define_expand "subsi3"
5822 [(set (match_operand:SI 0 "register_operand" "=r,d")
5823 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5824 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5828 if (arith_4096_operand(operands[2], SImode))
5830 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5831 gen_rtx_PLUS (SImode, operands[1],
5837 (define_insn "*subsi3"
5838 [(set (match_operand:SI 0 "register_operand" "=r,d")
5839 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5840 (match_operand:SI 2 "arith_operand" "rI,d")))]
5844 fpsub32s\\t%1, %2, %0"
5845 [(set_attr "type" "*,fp")])
5847 (define_insn "*cmp_minus_cc"
5848 [(set (reg:CC_NOOV 100)
5849 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5850 (match_operand:SI 1 "arith_operand" "rI"))
5853 "subcc\\t%r0, %1, %%g0"
5854 [(set_attr "type" "compare")])
5856 (define_insn "*cmp_minus_ccx"
5857 [(set (reg:CCX_NOOV 100)
5858 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5859 (match_operand:DI 1 "arith_double_operand" "rHI"))
5862 "subcc\\t%0, %1, %%g0"
5863 [(set_attr "type" "compare")])
5865 (define_insn "cmp_minus_cc_set"
5866 [(set (reg:CC_NOOV 100)
5867 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5868 (match_operand:SI 2 "arith_operand" "rI"))
5870 (set (match_operand:SI 0 "register_operand" "=r")
5871 (minus:SI (match_dup 1) (match_dup 2)))]
5873 "subcc\\t%r1, %2, %0"
5874 [(set_attr "type" "compare")])
5876 (define_insn "*cmp_minus_ccx_set"
5877 [(set (reg:CCX_NOOV 100)
5878 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5879 (match_operand:DI 2 "arith_double_operand" "rHI"))
5881 (set (match_operand:DI 0 "register_operand" "=r")
5882 (minus:DI (match_dup 1) (match_dup 2)))]
5884 "subcc\\t%1, %2, %0"
5885 [(set_attr "type" "compare")])
5887 ;; Integer Multiply/Divide.
5889 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5890 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5892 (define_insn "mulsi3"
5893 [(set (match_operand:SI 0 "register_operand" "=r")
5894 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5895 (match_operand:SI 2 "arith_operand" "rI")))]
5898 [(set_attr "type" "imul")])
5900 (define_expand "muldi3"
5901 [(set (match_operand:DI 0 "register_operand" "=r")
5902 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5903 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5904 "TARGET_ARCH64 || TARGET_V8PLUS"
5909 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5914 (define_insn "*muldi3_sp64"
5915 [(set (match_operand:DI 0 "register_operand" "=r")
5916 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5917 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5920 [(set_attr "type" "imul")])
5922 ;; V8plus wide multiply.
5924 (define_insn "muldi3_v8plus"
5925 [(set (match_operand:DI 0 "register_operand" "=r,h")
5926 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5927 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5928 (clobber (match_scratch:SI 3 "=&h,X"))
5929 (clobber (match_scratch:SI 4 "=&h,X"))]
5933 if (sparc_check_64 (operands[1], insn) <= 0)
5934 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5935 if (which_alternative == 1)
5936 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5937 if (GET_CODE (operands[2]) == CONST_INT)
5939 if (which_alternative == 1)
5940 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5942 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\";
5944 if (sparc_check_64 (operands[2], insn) <= 0)
5945 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5946 if (which_alternative == 1)
5947 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\";
5949 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\";
5951 [(set_attr "type" "multi")
5952 (set_attr "length" "9,8")])
5954 (define_insn "*cmp_mul_set"
5956 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5957 (match_operand:SI 2 "arith_operand" "rI"))
5959 (set (match_operand:SI 0 "register_operand" "=r")
5960 (mult:SI (match_dup 1) (match_dup 2)))]
5961 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5962 "smulcc\\t%1, %2, %0"
5963 [(set_attr "type" "imul")])
5965 (define_expand "mulsidi3"
5966 [(set (match_operand:DI 0 "register_operand" "")
5967 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5968 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5972 if (CONSTANT_P (operands[2]))
5975 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5978 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5984 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5989 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5990 ;; registers can hold 64 bit values in the V8plus environment.
5992 (define_insn "mulsidi3_v8plus"
5993 [(set (match_operand:DI 0 "register_operand" "=h,r")
5994 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5995 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5996 (clobber (match_scratch:SI 3 "=X,&h"))]
5999 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6000 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6001 [(set_attr "type" "multi")
6002 (set_attr "length" "2,3")])
6005 (define_insn "const_mulsidi3_v8plus"
6006 [(set (match_operand:DI 0 "register_operand" "=h,r")
6007 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6008 (match_operand:SI 2 "small_int" "I,I")))
6009 (clobber (match_scratch:SI 3 "=X,&h"))]
6012 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6013 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6014 [(set_attr "type" "multi")
6015 (set_attr "length" "2,3")])
6018 (define_insn "*mulsidi3_sp32"
6019 [(set (match_operand:DI 0 "register_operand" "=r")
6020 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6021 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6025 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6028 (if_then_else (eq_attr "isa" "sparclet")
6029 (const_string "imul") (const_string "multi")))
6030 (set (attr "length")
6031 (if_then_else (eq_attr "isa" "sparclet")
6032 (const_int 1) (const_int 2)))])
6034 (define_insn "*mulsidi3_sp64"
6035 [(set (match_operand:DI 0 "register_operand" "=r")
6036 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6037 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6038 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6040 [(set_attr "type" "imul")])
6042 ;; Extra pattern, because sign_extend of a constant isn't valid.
6045 (define_insn "const_mulsidi3_sp32"
6046 [(set (match_operand:DI 0 "register_operand" "=r")
6047 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6048 (match_operand:SI 2 "small_int" "I")))]
6052 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6055 (if_then_else (eq_attr "isa" "sparclet")
6056 (const_string "imul") (const_string "multi")))
6057 (set (attr "length")
6058 (if_then_else (eq_attr "isa" "sparclet")
6059 (const_int 1) (const_int 2)))])
6061 (define_insn "const_mulsidi3_sp64"
6062 [(set (match_operand:DI 0 "register_operand" "=r")
6063 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6064 (match_operand:SI 2 "small_int" "I")))]
6065 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6067 [(set_attr "type" "imul")])
6069 (define_expand "smulsi3_highpart"
6070 [(set (match_operand:SI 0 "register_operand" "")
6072 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6073 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6075 "TARGET_HARD_MUL && TARGET_ARCH32"
6078 if (CONSTANT_P (operands[2]))
6082 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6088 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6093 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6094 operands[2], GEN_INT (32)));
6100 (define_insn "smulsi3_highpart_v8plus"
6101 [(set (match_operand:SI 0 "register_operand" "=h,r")
6103 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6104 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6105 (match_operand:SI 3 "const_int_operand" "i,i"))))
6106 (clobber (match_scratch:SI 4 "=X,&h"))]
6109 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6110 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6111 [(set_attr "type" "multi")
6112 (set_attr "length" "2")])
6114 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6117 [(set (match_operand:SI 0 "register_operand" "=h,r")
6120 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6121 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6122 (match_operand:SI 3 "const_int_operand" "i,i"))
6124 (clobber (match_scratch:SI 4 "=X,&h"))]
6127 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6128 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6129 [(set_attr "type" "multi")
6130 (set_attr "length" "2")])
6133 (define_insn "const_smulsi3_highpart_v8plus"
6134 [(set (match_operand:SI 0 "register_operand" "=h,r")
6136 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6137 (match_operand 2 "small_int" "i,i"))
6138 (match_operand:SI 3 "const_int_operand" "i,i"))))
6139 (clobber (match_scratch:SI 4 "=X,&h"))]
6142 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6143 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6144 [(set_attr "type" "multi")
6145 (set_attr "length" "2")])
6148 (define_insn "*smulsi3_highpart_sp32"
6149 [(set (match_operand:SI 0 "register_operand" "=r")
6151 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6152 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6155 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6156 [(set_attr "type" "multi")
6157 (set_attr "length" "2")])
6160 (define_insn "const_smulsi3_highpart"
6161 [(set (match_operand:SI 0 "register_operand" "=r")
6163 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6164 (match_operand:SI 2 "register_operand" "r"))
6167 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6168 [(set_attr "type" "multi")
6169 (set_attr "length" "2")])
6171 (define_expand "umulsidi3"
6172 [(set (match_operand:DI 0 "register_operand" "")
6173 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6174 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6178 if (CONSTANT_P (operands[2]))
6181 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6184 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6190 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6196 (define_insn "umulsidi3_v8plus"
6197 [(set (match_operand:DI 0 "register_operand" "=h,r")
6198 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6199 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6200 (clobber (match_scratch:SI 3 "=X,&h"))]
6203 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6204 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6205 [(set_attr "type" "multi")
6206 (set_attr "length" "2,3")])
6209 (define_insn "*umulsidi3_sp32"
6210 [(set (match_operand:DI 0 "register_operand" "=r")
6211 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6212 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6216 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6219 (if_then_else (eq_attr "isa" "sparclet")
6220 (const_string "imul") (const_string "multi")))
6221 (set (attr "length")
6222 (if_then_else (eq_attr "isa" "sparclet")
6223 (const_int 1) (const_int 2)))])
6225 (define_insn "*umulsidi3_sp64"
6226 [(set (match_operand:DI 0 "register_operand" "=r")
6227 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6228 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6229 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6231 [(set_attr "type" "imul")])
6233 ;; Extra pattern, because sign_extend of a constant isn't valid.
6236 (define_insn "const_umulsidi3_sp32"
6237 [(set (match_operand:DI 0 "register_operand" "=r")
6238 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6239 (match_operand:SI 2 "uns_small_int" "")))]
6243 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6246 (if_then_else (eq_attr "isa" "sparclet")
6247 (const_string "imul") (const_string "multi")))
6248 (set (attr "length")
6249 (if_then_else (eq_attr "isa" "sparclet")
6250 (const_int 1) (const_int 2)))])
6252 (define_insn "const_umulsidi3_sp64"
6253 [(set (match_operand:DI 0 "register_operand" "=r")
6254 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6255 (match_operand:SI 2 "uns_small_int" "")))]
6256 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6258 [(set_attr "type" "imul")])
6261 (define_insn "const_umulsidi3_v8plus"
6262 [(set (match_operand:DI 0 "register_operand" "=h,r")
6263 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6264 (match_operand:SI 2 "uns_small_int" "")))
6265 (clobber (match_scratch:SI 3 "=X,h"))]
6268 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6269 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6270 [(set_attr "type" "multi")
6271 (set_attr "length" "2,3")])
6273 (define_expand "umulsi3_highpart"
6274 [(set (match_operand:SI 0 "register_operand" "")
6276 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6277 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6279 "TARGET_HARD_MUL && TARGET_ARCH32"
6282 if (CONSTANT_P (operands[2]))
6286 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6292 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6297 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6298 operands[2], GEN_INT (32)));
6304 (define_insn "umulsi3_highpart_v8plus"
6305 [(set (match_operand:SI 0 "register_operand" "=h,r")
6307 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6308 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6309 (match_operand:SI 3 "const_int_operand" "i,i"))))
6310 (clobber (match_scratch:SI 4 "=X,h"))]
6313 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6314 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6315 [(set_attr "type" "multi")
6316 (set_attr "length" "2")])
6319 (define_insn "const_umulsi3_highpart_v8plus"
6320 [(set (match_operand:SI 0 "register_operand" "=h,r")
6322 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6323 (match_operand:SI 2 "uns_small_int" ""))
6324 (match_operand:SI 3 "const_int_operand" "i,i"))))
6325 (clobber (match_scratch:SI 4 "=X,h"))]
6328 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6329 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6330 [(set_attr "type" "multi")
6331 (set_attr "length" "2")])
6334 (define_insn "*umulsi3_highpart_sp32"
6335 [(set (match_operand:SI 0 "register_operand" "=r")
6337 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6338 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6341 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6342 [(set_attr "type" "multi")
6343 (set_attr "length" "2")])
6346 (define_insn "const_umulsi3_highpart"
6347 [(set (match_operand:SI 0 "register_operand" "=r")
6349 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6350 (match_operand:SI 2 "uns_small_int" ""))
6353 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6354 [(set_attr "type" "multi")
6355 (set_attr "length" "2")])
6357 ;; The v8 architecture specifies that there must be 3 instructions between
6358 ;; a y register write and a use of it for correct results.
6360 (define_expand "divsi3"
6361 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6362 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6363 (match_operand:SI 2 "input_operand" "rI,m")))
6364 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6365 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6370 operands[3] = gen_reg_rtx(SImode);
6371 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6372 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6378 (define_insn "divsi3_sp32"
6379 [(set (match_operand:SI 0 "register_operand" "=r,r")
6380 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6381 (match_operand:SI 2 "input_operand" "rI,m")))
6382 (clobber (match_scratch:SI 3 "=&r,&r"))]
6383 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6387 if (which_alternative == 0)
6389 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6391 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6394 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6396 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\";
6398 [(set_attr "type" "multi")
6399 (set (attr "length")
6400 (if_then_else (eq_attr "isa" "v9")
6401 (const_int 4) (const_int 7)))])
6403 (define_insn "divsi3_sp64"
6404 [(set (match_operand:SI 0 "register_operand" "=r")
6405 (div:SI (match_operand:SI 1 "register_operand" "r")
6406 (match_operand:SI 2 "input_operand" "rI")))
6407 (use (match_operand:SI 3 "register_operand" "r"))]
6408 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6409 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6410 [(set_attr "type" "multi")
6411 (set_attr "length" "2")])
6413 (define_insn "divdi3"
6414 [(set (match_operand:DI 0 "register_operand" "=r")
6415 (div:DI (match_operand:DI 1 "register_operand" "r")
6416 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6418 "sdivx\\t%1, %2, %0"
6419 [(set_attr "type" "idiv")])
6421 (define_insn "*cmp_sdiv_cc_set"
6423 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6424 (match_operand:SI 2 "arith_operand" "rI"))
6426 (set (match_operand:SI 0 "register_operand" "=r")
6427 (div:SI (match_dup 1) (match_dup 2)))
6428 (clobber (match_scratch:SI 3 "=&r"))]
6429 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6433 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6435 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6437 [(set_attr "type" "multi")
6438 (set (attr "length")
6439 (if_then_else (eq_attr "isa" "v9")
6440 (const_int 3) (const_int 6)))])
6443 (define_expand "udivsi3"
6444 [(set (match_operand:SI 0 "register_operand" "")
6445 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6446 (match_operand:SI 2 "input_operand" "")))]
6447 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6450 (define_insn "udivsi3_sp32"
6451 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6452 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6453 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6455 || TARGET_DEPRECATED_V8_INSNS)
6459 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6460 switch (which_alternative)
6463 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6465 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6467 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6470 [(set_attr "type" "multi")
6471 (set_attr "length" "5")])
6473 (define_insn "udivsi3_sp64"
6474 [(set (match_operand:SI 0 "register_operand" "=r")
6475 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6476 (match_operand:SI 2 "input_operand" "rI")))]
6477 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6478 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6479 [(set_attr "type" "multi")
6480 (set_attr "length" "2")])
6482 (define_insn "udivdi3"
6483 [(set (match_operand:DI 0 "register_operand" "=r")
6484 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6485 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6487 "udivx\\t%1, %2, %0"
6488 [(set_attr "type" "idiv")])
6490 (define_insn "*cmp_udiv_cc_set"
6492 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6493 (match_operand:SI 2 "arith_operand" "rI"))
6495 (set (match_operand:SI 0 "register_operand" "=r")
6496 (udiv:SI (match_dup 1) (match_dup 2)))]
6498 || TARGET_DEPRECATED_V8_INSNS"
6502 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6504 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6506 [(set_attr "type" "multi")
6507 (set (attr "length")
6508 (if_then_else (eq_attr "isa" "v9")
6509 (const_int 2) (const_int 5)))])
6511 ; sparclet multiply/accumulate insns
6513 (define_insn "*smacsi"
6514 [(set (match_operand:SI 0 "register_operand" "=r")
6515 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6516 (match_operand:SI 2 "arith_operand" "rI"))
6517 (match_operand:SI 3 "register_operand" "0")))]
6520 [(set_attr "type" "imul")])
6522 (define_insn "*smacdi"
6523 [(set (match_operand:DI 0 "register_operand" "=r")
6524 (plus:DI (mult:DI (sign_extend:DI
6525 (match_operand:SI 1 "register_operand" "%r"))
6527 (match_operand:SI 2 "register_operand" "r")))
6528 (match_operand:DI 3 "register_operand" "0")))]
6530 "smacd\\t%1, %2, %L0"
6531 [(set_attr "type" "imul")])
6533 (define_insn "*umacdi"
6534 [(set (match_operand:DI 0 "register_operand" "=r")
6535 (plus:DI (mult:DI (zero_extend:DI
6536 (match_operand:SI 1 "register_operand" "%r"))
6538 (match_operand:SI 2 "register_operand" "r")))
6539 (match_operand:DI 3 "register_operand" "0")))]
6541 "umacd\\t%1, %2, %L0"
6542 [(set_attr "type" "imul")])
6544 ;;- Boolean instructions
6545 ;; We define DImode `and' so with DImode `not' we can get
6546 ;; DImode `andn'. Other combinations are possible.
6548 (define_expand "anddi3"
6549 [(set (match_operand:DI 0 "register_operand" "")
6550 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6551 (match_operand:DI 2 "arith_double_operand" "")))]
6555 (define_insn "*anddi3_sp32"
6556 [(set (match_operand:DI 0 "register_operand" "=r,b")
6557 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6558 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6563 [(set_attr "type" "*,fp")
6564 (set_attr "length" "2,*")
6565 (set_attr "fptype" "double")])
6567 (define_insn "*anddi3_sp64"
6568 [(set (match_operand:DI 0 "register_operand" "=r,b")
6569 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6570 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6575 [(set_attr "type" "*,fp")
6576 (set_attr "fptype" "double")])
6578 (define_insn "andsi3"
6579 [(set (match_operand:SI 0 "register_operand" "=r,d")
6580 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6581 (match_operand:SI 2 "arith_operand" "rI,d")))]
6586 [(set_attr "type" "*,fp")])
6589 [(set (match_operand:SI 0 "register_operand" "")
6590 (and:SI (match_operand:SI 1 "register_operand" "")
6591 (match_operand:SI 2 "" "")))
6592 (clobber (match_operand:SI 3 "register_operand" ""))]
6593 "GET_CODE (operands[2]) == CONST_INT
6594 && !SMALL_INT32 (operands[2])
6595 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6596 [(set (match_dup 3) (match_dup 4))
6597 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6600 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6603 ;; Split DImode logical operations requiring two instructions.
6605 [(set (match_operand:DI 0 "register_operand" "")
6606 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6607 [(match_operand:DI 2 "register_operand" "")
6608 (match_operand:DI 3 "arith_double_operand" "")]))]
6611 && ((GET_CODE (operands[0]) == REG
6612 && REGNO (operands[0]) < 32)
6613 || (GET_CODE (operands[0]) == SUBREG
6614 && GET_CODE (SUBREG_REG (operands[0])) == REG
6615 && REGNO (SUBREG_REG (operands[0])) < 32))"
6616 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6617 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6620 if (GET_CODE (operands[0]) == SUBREG)
6621 operands[0] = alter_subreg (operands[0]);
6622 operands[4] = gen_highpart (SImode, operands[0]);
6623 operands[5] = gen_lowpart (SImode, operands[0]);
6624 operands[6] = gen_highpart (SImode, operands[2]);
6625 operands[7] = gen_lowpart (SImode, operands[2]);
6626 #if HOST_BITS_PER_WIDE_INT == 32
6627 if (GET_CODE (operands[3]) == CONST_INT)
6629 if (INTVAL (operands[3]) < 0)
6630 operands[8] = constm1_rtx;
6632 operands[8] = const0_rtx;
6636 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6637 operands[9] = gen_lowpart (SImode, operands[3]);
6640 (define_insn "*and_not_di_sp32"
6641 [(set (match_operand:DI 0 "register_operand" "=r,b")
6642 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6643 (match_operand:DI 2 "register_operand" "r,b")))]
6647 fandnot1\\t%1, %2, %0"
6648 [(set_attr "type" "*,fp")
6649 (set_attr "length" "2,*")
6650 (set_attr "fptype" "double")])
6653 [(set (match_operand:DI 0 "register_operand" "")
6654 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6655 (match_operand:DI 2 "register_operand" "")))]
6658 && ((GET_CODE (operands[0]) == REG
6659 && REGNO (operands[0]) < 32)
6660 || (GET_CODE (operands[0]) == SUBREG
6661 && GET_CODE (SUBREG_REG (operands[0])) == REG
6662 && REGNO (SUBREG_REG (operands[0])) < 32))"
6663 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6664 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6665 "if (GET_CODE (operands[0]) == SUBREG)
6666 operands[0] = alter_subreg (operands[0]);
6667 operands[3] = gen_highpart (SImode, operands[0]);
6668 operands[4] = gen_highpart (SImode, operands[1]);
6669 operands[5] = gen_highpart (SImode, operands[2]);
6670 operands[6] = gen_lowpart (SImode, operands[0]);
6671 operands[7] = gen_lowpart (SImode, operands[1]);
6672 operands[8] = gen_lowpart (SImode, operands[2]);")
6674 (define_insn "*and_not_di_sp64"
6675 [(set (match_operand:DI 0 "register_operand" "=r,b")
6676 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6677 (match_operand:DI 2 "register_operand" "r,b")))]
6681 fandnot1\\t%1, %2, %0"
6682 [(set_attr "type" "*,fp")
6683 (set_attr "fptype" "double")])
6685 (define_insn "*and_not_si"
6686 [(set (match_operand:SI 0 "register_operand" "=r,d")
6687 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6688 (match_operand:SI 2 "register_operand" "r,d")))]
6692 fandnot1s\\t%1, %2, %0"
6693 [(set_attr "type" "*,fp")])
6695 (define_expand "iordi3"
6696 [(set (match_operand:DI 0 "register_operand" "")
6697 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6698 (match_operand:DI 2 "arith_double_operand" "")))]
6702 (define_insn "*iordi3_sp32"
6703 [(set (match_operand:DI 0 "register_operand" "=r,b")
6704 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6705 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6710 [(set_attr "type" "*,fp")
6711 (set_attr "length" "2,*")
6712 (set_attr "fptype" "double")])
6714 (define_insn "*iordi3_sp64"
6715 [(set (match_operand:DI 0 "register_operand" "=r,b")
6716 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6717 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6722 [(set_attr "type" "*,fp")
6723 (set_attr "fptype" "double")])
6725 (define_insn "iorsi3"
6726 [(set (match_operand:SI 0 "register_operand" "=r,d")
6727 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6728 (match_operand:SI 2 "arith_operand" "rI,d")))]
6733 [(set_attr "type" "*,fp")])
6736 [(set (match_operand:SI 0 "register_operand" "")
6737 (ior:SI (match_operand:SI 1 "register_operand" "")
6738 (match_operand:SI 2 "" "")))
6739 (clobber (match_operand:SI 3 "register_operand" ""))]
6740 "GET_CODE (operands[2]) == CONST_INT
6741 && !SMALL_INT32 (operands[2])
6742 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6743 [(set (match_dup 3) (match_dup 4))
6744 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6747 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6750 (define_insn "*or_not_di_sp32"
6751 [(set (match_operand:DI 0 "register_operand" "=r,b")
6752 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6753 (match_operand:DI 2 "register_operand" "r,b")))]
6757 fornot1\\t%1, %2, %0"
6758 [(set_attr "type" "*,fp")
6759 (set_attr "length" "2,*")
6760 (set_attr "fptype" "double")])
6763 [(set (match_operand:DI 0 "register_operand" "")
6764 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6765 (match_operand:DI 2 "register_operand" "")))]
6768 && ((GET_CODE (operands[0]) == REG
6769 && REGNO (operands[0]) < 32)
6770 || (GET_CODE (operands[0]) == SUBREG
6771 && GET_CODE (SUBREG_REG (operands[0])) == REG
6772 && REGNO (SUBREG_REG (operands[0])) < 32))"
6773 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6774 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6775 "if (GET_CODE (operands[0]) == SUBREG)
6776 operands[0] = alter_subreg (operands[0]);
6777 operands[3] = gen_highpart (SImode, operands[0]);
6778 operands[4] = gen_highpart (SImode, operands[1]);
6779 operands[5] = gen_highpart (SImode, operands[2]);
6780 operands[6] = gen_lowpart (SImode, operands[0]);
6781 operands[7] = gen_lowpart (SImode, operands[1]);
6782 operands[8] = gen_lowpart (SImode, operands[2]);")
6784 (define_insn "*or_not_di_sp64"
6785 [(set (match_operand:DI 0 "register_operand" "=r,b")
6786 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6787 (match_operand:DI 2 "register_operand" "r,b")))]
6791 fornot1\\t%1, %2, %0"
6792 [(set_attr "type" "*,fp")
6793 (set_attr "fptype" "double")])
6795 (define_insn "*or_not_si"
6796 [(set (match_operand:SI 0 "register_operand" "=r,d")
6797 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6798 (match_operand:SI 2 "register_operand" "r,d")))]
6802 fornot1s\\t%1, %2, %0"
6803 [(set_attr "type" "*,fp")])
6805 (define_expand "xordi3"
6806 [(set (match_operand:DI 0 "register_operand" "")
6807 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6808 (match_operand:DI 2 "arith_double_operand" "")))]
6812 (define_insn "*xordi3_sp32"
6813 [(set (match_operand:DI 0 "register_operand" "=r,b")
6814 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6815 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6820 [(set_attr "type" "*,fp")
6821 (set_attr "length" "2,*")
6822 (set_attr "fptype" "double")])
6824 (define_insn "*xordi3_sp64"
6825 [(set (match_operand:DI 0 "register_operand" "=r,b")
6826 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6827 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6832 [(set_attr "type" "*,fp")
6833 (set_attr "fptype" "double")])
6835 (define_insn "*xordi3_sp64_dbl"
6836 [(set (match_operand:DI 0 "register_operand" "=r")
6837 (xor:DI (match_operand:DI 1 "register_operand" "r")
6838 (match_operand:DI 2 "const64_operand" "")))]
6840 && HOST_BITS_PER_WIDE_INT != 64)"
6843 (define_insn "xorsi3"
6844 [(set (match_operand:SI 0 "register_operand" "=r,d")
6845 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6846 (match_operand:SI 2 "arith_operand" "rI,d")))]
6851 [(set_attr "type" "*,fp")])
6854 [(set (match_operand:SI 0 "register_operand" "")
6855 (xor:SI (match_operand:SI 1 "register_operand" "")
6856 (match_operand:SI 2 "" "")))
6857 (clobber (match_operand:SI 3 "register_operand" ""))]
6858 "GET_CODE (operands[2]) == CONST_INT
6859 && !SMALL_INT32 (operands[2])
6860 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6861 [(set (match_dup 3) (match_dup 4))
6862 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6865 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6869 [(set (match_operand:SI 0 "register_operand" "")
6870 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6871 (match_operand:SI 2 "" ""))))
6872 (clobber (match_operand:SI 3 "register_operand" ""))]
6873 "GET_CODE (operands[2]) == CONST_INT
6874 && !SMALL_INT32 (operands[2])
6875 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6876 [(set (match_dup 3) (match_dup 4))
6877 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6880 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6883 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6884 ;; Combine now canonicalizes to the rightmost expression.
6885 (define_insn "*xor_not_di_sp32"
6886 [(set (match_operand:DI 0 "register_operand" "=r,b")
6887 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6888 (match_operand:DI 2 "register_operand" "r,b"))))]
6893 [(set_attr "type" "*,fp")
6894 (set_attr "length" "2,*")
6895 (set_attr "fptype" "double")])
6898 [(set (match_operand:DI 0 "register_operand" "")
6899 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6900 (match_operand:DI 2 "register_operand" ""))))]
6903 && ((GET_CODE (operands[0]) == REG
6904 && REGNO (operands[0]) < 32)
6905 || (GET_CODE (operands[0]) == SUBREG
6906 && GET_CODE (SUBREG_REG (operands[0])) == REG
6907 && REGNO (SUBREG_REG (operands[0])) < 32))"
6908 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6909 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6910 "if (GET_CODE (operands[0]) == SUBREG)
6911 operands[0] = alter_subreg (operands[0]);
6912 operands[3] = gen_highpart (SImode, operands[0]);
6913 operands[4] = gen_highpart (SImode, operands[1]);
6914 operands[5] = gen_highpart (SImode, operands[2]);
6915 operands[6] = gen_lowpart (SImode, operands[0]);
6916 operands[7] = gen_lowpart (SImode, operands[1]);
6917 operands[8] = gen_lowpart (SImode, operands[2]);")
6919 (define_insn "*xor_not_di_sp64"
6920 [(set (match_operand:DI 0 "register_operand" "=r,b")
6921 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6922 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6927 [(set_attr "type" "*,fp")
6928 (set_attr "fptype" "double")])
6930 (define_insn "*xor_not_si"
6931 [(set (match_operand:SI 0 "register_operand" "=r,d")
6932 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6933 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6937 fxnors\\t%1, %2, %0"
6938 [(set_attr "type" "*,fp")])
6940 ;; These correspond to the above in the case where we also (or only)
6941 ;; want to set the condition code.
6943 (define_insn "*cmp_cc_arith_op"
6946 (match_operator:SI 2 "cc_arithop"
6947 [(match_operand:SI 0 "arith_operand" "%r")
6948 (match_operand:SI 1 "arith_operand" "rI")])
6951 "%A2cc\\t%0, %1, %%g0"
6952 [(set_attr "type" "compare")])
6954 (define_insn "*cmp_ccx_arith_op"
6957 (match_operator:DI 2 "cc_arithop"
6958 [(match_operand:DI 0 "arith_double_operand" "%r")
6959 (match_operand:DI 1 "arith_double_operand" "rHI")])
6962 "%A2cc\\t%0, %1, %%g0"
6963 [(set_attr "type" "compare")])
6965 (define_insn "*cmp_cc_arith_op_set"
6968 (match_operator:SI 3 "cc_arithop"
6969 [(match_operand:SI 1 "arith_operand" "%r")
6970 (match_operand:SI 2 "arith_operand" "rI")])
6972 (set (match_operand:SI 0 "register_operand" "=r")
6973 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6974 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6975 "%A3cc\\t%1, %2, %0"
6976 [(set_attr "type" "compare")])
6978 (define_insn "*cmp_ccx_arith_op_set"
6981 (match_operator:DI 3 "cc_arithop"
6982 [(match_operand:DI 1 "arith_double_operand" "%r")
6983 (match_operand:DI 2 "arith_double_operand" "rHI")])
6985 (set (match_operand:DI 0 "register_operand" "=r")
6986 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6987 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6988 "%A3cc\\t%1, %2, %0"
6989 [(set_attr "type" "compare")])
6991 (define_insn "*cmp_cc_xor_not"
6994 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6995 (match_operand:SI 1 "arith_operand" "rI")))
6998 "xnorcc\\t%r0, %1, %%g0"
6999 [(set_attr "type" "compare")])
7001 (define_insn "*cmp_ccx_xor_not"
7004 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7005 (match_operand:DI 1 "arith_double_operand" "rHI")))
7008 "xnorcc\\t%r0, %1, %%g0"
7009 [(set_attr "type" "compare")])
7011 (define_insn "*cmp_cc_xor_not_set"
7014 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7015 (match_operand:SI 2 "arith_operand" "rI")))
7017 (set (match_operand:SI 0 "register_operand" "=r")
7018 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7020 "xnorcc\\t%r1, %2, %0"
7021 [(set_attr "type" "compare")])
7023 (define_insn "*cmp_ccx_xor_not_set"
7026 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7027 (match_operand:DI 2 "arith_double_operand" "rHI")))
7029 (set (match_operand:DI 0 "register_operand" "=r")
7030 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7032 "xnorcc\\t%r1, %2, %0"
7033 [(set_attr "type" "compare")])
7035 (define_insn "*cmp_cc_arith_op_not"
7038 (match_operator:SI 2 "cc_arithopn"
7039 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7040 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7043 "%B2cc\\t%r1, %0, %%g0"
7044 [(set_attr "type" "compare")])
7046 (define_insn "*cmp_ccx_arith_op_not"
7049 (match_operator:DI 2 "cc_arithopn"
7050 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7051 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7054 "%B2cc\\t%r1, %0, %%g0"
7055 [(set_attr "type" "compare")])
7057 (define_insn "*cmp_cc_arith_op_not_set"
7060 (match_operator:SI 3 "cc_arithopn"
7061 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7062 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7064 (set (match_operand:SI 0 "register_operand" "=r")
7065 (match_operator:SI 4 "cc_arithopn"
7066 [(not:SI (match_dup 1)) (match_dup 2)]))]
7067 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7068 "%B3cc\\t%r2, %1, %0"
7069 [(set_attr "type" "compare")])
7071 (define_insn "*cmp_ccx_arith_op_not_set"
7074 (match_operator:DI 3 "cc_arithopn"
7075 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7076 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7078 (set (match_operand:DI 0 "register_operand" "=r")
7079 (match_operator:DI 4 "cc_arithopn"
7080 [(not:DI (match_dup 1)) (match_dup 2)]))]
7081 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7082 "%B3cc\\t%r2, %1, %0"
7083 [(set_attr "type" "compare")])
7085 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7086 ;; does not know how to make it work for constants.
7088 (define_expand "negdi2"
7089 [(set (match_operand:DI 0 "register_operand" "=r")
7090 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7094 if (! TARGET_ARCH64)
7096 emit_insn (gen_rtx_PARALLEL
7099 gen_rtx_SET (VOIDmode, operand0,
7100 gen_rtx_NEG (DImode, operand1)),
7101 gen_rtx_CLOBBER (VOIDmode,
7102 gen_rtx_REG (CCmode,
7108 (define_insn "*negdi2_sp32"
7109 [(set (match_operand:DI 0 "register_operand" "=r")
7110 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7111 (clobber (reg:CC 100))]
7114 [(set_attr "length" "2")])
7117 [(set (match_operand:DI 0 "register_operand" "")
7118 (neg:DI (match_operand:DI 1 "register_operand" "")))
7119 (clobber (reg:CC 100))]
7121 && reload_completed"
7122 [(parallel [(set (reg:CC_NOOV 100)
7123 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7125 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7126 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7127 (ltu:SI (reg:CC 100) (const_int 0))))]
7128 "operands[2] = gen_highpart (SImode, operands[0]);
7129 operands[3] = gen_highpart (SImode, operands[1]);
7130 operands[4] = gen_lowpart (SImode, operands[0]);
7131 operands[5] = gen_lowpart (SImode, operands[1]);")
7133 (define_insn "*negdi2_sp64"
7134 [(set (match_operand:DI 0 "register_operand" "=r")
7135 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7137 "sub\\t%%g0, %1, %0")
7139 (define_insn "negsi2"
7140 [(set (match_operand:SI 0 "register_operand" "=r")
7141 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7143 "sub\\t%%g0, %1, %0")
7145 (define_insn "*cmp_cc_neg"
7146 [(set (reg:CC_NOOV 100)
7147 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7150 "subcc\\t%%g0, %0, %%g0"
7151 [(set_attr "type" "compare")])
7153 (define_insn "*cmp_ccx_neg"
7154 [(set (reg:CCX_NOOV 100)
7155 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7158 "subcc\\t%%g0, %0, %%g0"
7159 [(set_attr "type" "compare")])
7161 (define_insn "*cmp_cc_set_neg"
7162 [(set (reg:CC_NOOV 100)
7163 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7165 (set (match_operand:SI 0 "register_operand" "=r")
7166 (neg:SI (match_dup 1)))]
7168 "subcc\\t%%g0, %1, %0"
7169 [(set_attr "type" "compare")])
7171 (define_insn "*cmp_ccx_set_neg"
7172 [(set (reg:CCX_NOOV 100)
7173 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7175 (set (match_operand:DI 0 "register_operand" "=r")
7176 (neg:DI (match_dup 1)))]
7178 "subcc\\t%%g0, %1, %0"
7179 [(set_attr "type" "compare")])
7181 ;; We cannot use the "not" pseudo insn because the Sun assembler
7182 ;; does not know how to make it work for constants.
7183 (define_expand "one_cmpldi2"
7184 [(set (match_operand:DI 0 "register_operand" "")
7185 (not:DI (match_operand:DI 1 "register_operand" "")))]
7189 (define_insn "*one_cmpldi2_sp32"
7190 [(set (match_operand:DI 0 "register_operand" "=r,b")
7191 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7196 [(set_attr "type" "*,fp")
7197 (set_attr "length" "2,*")
7198 (set_attr "fptype" "double")])
7201 [(set (match_operand:DI 0 "register_operand" "")
7202 (not:DI (match_operand:DI 1 "register_operand" "")))]
7205 && ((GET_CODE (operands[0]) == REG
7206 && REGNO (operands[0]) < 32)
7207 || (GET_CODE (operands[0]) == SUBREG
7208 && GET_CODE (SUBREG_REG (operands[0])) == REG
7209 && REGNO (SUBREG_REG (operands[0])) < 32))"
7210 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7211 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7212 "if (GET_CODE (operands[0]) == SUBREG)
7213 operands[0] = alter_subreg (operands[0]);
7214 operands[2] = gen_highpart (SImode, operands[0]);
7215 operands[3] = gen_highpart (SImode, operands[1]);
7216 operands[4] = gen_lowpart (SImode, operands[0]);
7217 operands[5] = gen_lowpart (SImode, operands[1]);")
7219 (define_insn "*one_cmpldi2_sp64"
7220 [(set (match_operand:DI 0 "register_operand" "=r,b")
7221 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7226 [(set_attr "type" "*,fp")
7227 (set_attr "fptype" "double")])
7229 (define_insn "one_cmplsi2"
7230 [(set (match_operand:SI 0 "register_operand" "=r,d")
7231 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7236 [(set_attr "type" "*,fp")])
7238 (define_insn "*cmp_cc_not"
7240 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7243 "xnorcc\\t%%g0, %0, %%g0"
7244 [(set_attr "type" "compare")])
7246 (define_insn "*cmp_ccx_not"
7248 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7251 "xnorcc\\t%%g0, %0, %%g0"
7252 [(set_attr "type" "compare")])
7254 (define_insn "*cmp_cc_set_not"
7256 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7258 (set (match_operand:SI 0 "register_operand" "=r")
7259 (not:SI (match_dup 1)))]
7261 "xnorcc\\t%%g0, %1, %0"
7262 [(set_attr "type" "compare")])
7264 (define_insn "*cmp_ccx_set_not"
7266 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7268 (set (match_operand:DI 0 "register_operand" "=r")
7269 (not:DI (match_dup 1)))]
7271 "xnorcc\\t%%g0, %1, %0"
7272 [(set_attr "type" "compare")])
7274 ;; Floating point arithmetic instructions.
7276 (define_expand "addtf3"
7277 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7278 (plus:TF (match_operand:TF 1 "general_operand" "")
7279 (match_operand:TF 2 "general_operand" "")))]
7280 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7283 if (! TARGET_HARD_QUAD)
7285 rtx slot0, slot1, slot2;
7287 if (GET_CODE (operands[0]) != MEM)
7288 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7290 slot0 = operands[0];
7291 if (GET_CODE (operands[1]) != MEM)
7293 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7294 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7297 slot1 = operands[1];
7298 if (GET_CODE (operands[2]) != MEM)
7300 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7301 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7304 slot2 = operands[2];
7306 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7308 XEXP (slot0, 0), Pmode,
7309 XEXP (slot1, 0), Pmode,
7310 XEXP (slot2, 0), Pmode);
7312 if (GET_CODE (operands[0]) != MEM)
7313 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7318 (define_insn "*addtf3_hq"
7319 [(set (match_operand:TF 0 "register_operand" "=e")
7320 (plus:TF (match_operand:TF 1 "register_operand" "e")
7321 (match_operand:TF 2 "register_operand" "e")))]
7322 "TARGET_FPU && TARGET_HARD_QUAD"
7323 "faddq\\t%1, %2, %0"
7324 [(set_attr "type" "fp")])
7326 (define_insn "adddf3"
7327 [(set (match_operand:DF 0 "register_operand" "=e")
7328 (plus:DF (match_operand:DF 1 "register_operand" "e")
7329 (match_operand:DF 2 "register_operand" "e")))]
7331 "faddd\\t%1, %2, %0"
7332 [(set_attr "type" "fp")
7333 (set_attr "fptype" "double")])
7335 (define_insn "addsf3"
7336 [(set (match_operand:SF 0 "register_operand" "=f")
7337 (plus:SF (match_operand:SF 1 "register_operand" "f")
7338 (match_operand:SF 2 "register_operand" "f")))]
7340 "fadds\\t%1, %2, %0"
7341 [(set_attr "type" "fp")])
7343 (define_expand "subtf3"
7344 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7345 (minus:TF (match_operand:TF 1 "general_operand" "")
7346 (match_operand:TF 2 "general_operand" "")))]
7347 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7350 if (! TARGET_HARD_QUAD)
7352 rtx slot0, slot1, slot2;
7354 if (GET_CODE (operands[0]) != MEM)
7355 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7357 slot0 = operands[0];
7358 if (GET_CODE (operands[1]) != MEM)
7360 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7361 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7364 slot1 = operands[1];
7365 if (GET_CODE (operands[2]) != MEM)
7367 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7368 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7371 slot2 = operands[2];
7373 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7375 XEXP (slot0, 0), Pmode,
7376 XEXP (slot1, 0), Pmode,
7377 XEXP (slot2, 0), Pmode);
7379 if (GET_CODE (operands[0]) != MEM)
7380 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7385 (define_insn "*subtf3_hq"
7386 [(set (match_operand:TF 0 "register_operand" "=e")
7387 (minus:TF (match_operand:TF 1 "register_operand" "e")
7388 (match_operand:TF 2 "register_operand" "e")))]
7389 "TARGET_FPU && TARGET_HARD_QUAD"
7390 "fsubq\\t%1, %2, %0"
7391 [(set_attr "type" "fp")])
7393 (define_insn "subdf3"
7394 [(set (match_operand:DF 0 "register_operand" "=e")
7395 (minus:DF (match_operand:DF 1 "register_operand" "e")
7396 (match_operand:DF 2 "register_operand" "e")))]
7398 "fsubd\\t%1, %2, %0"
7399 [(set_attr "type" "fp")
7400 (set_attr "fptype" "double")])
7402 (define_insn "subsf3"
7403 [(set (match_operand:SF 0 "register_operand" "=f")
7404 (minus:SF (match_operand:SF 1 "register_operand" "f")
7405 (match_operand:SF 2 "register_operand" "f")))]
7407 "fsubs\\t%1, %2, %0"
7408 [(set_attr "type" "fp")])
7410 (define_expand "multf3"
7411 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7412 (mult:TF (match_operand:TF 1 "general_operand" "")
7413 (match_operand:TF 2 "general_operand" "")))]
7414 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7417 if (! TARGET_HARD_QUAD)
7419 rtx slot0, slot1, slot2;
7421 if (GET_CODE (operands[0]) != MEM)
7422 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7424 slot0 = operands[0];
7425 if (GET_CODE (operands[1]) != MEM)
7427 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7428 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7431 slot1 = operands[1];
7432 if (GET_CODE (operands[2]) != MEM)
7434 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7435 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7438 slot2 = operands[2];
7440 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7442 XEXP (slot0, 0), Pmode,
7443 XEXP (slot1, 0), Pmode,
7444 XEXP (slot2, 0), Pmode);
7446 if (GET_CODE (operands[0]) != MEM)
7447 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7452 (define_insn "*multf3_hq"
7453 [(set (match_operand:TF 0 "register_operand" "=e")
7454 (mult:TF (match_operand:TF 1 "register_operand" "e")
7455 (match_operand:TF 2 "register_operand" "e")))]
7456 "TARGET_FPU && TARGET_HARD_QUAD"
7457 "fmulq\\t%1, %2, %0"
7458 [(set_attr "type" "fpmul")])
7460 (define_insn "muldf3"
7461 [(set (match_operand:DF 0 "register_operand" "=e")
7462 (mult:DF (match_operand:DF 1 "register_operand" "e")
7463 (match_operand:DF 2 "register_operand" "e")))]
7465 "fmuld\\t%1, %2, %0"
7466 [(set_attr "type" "fpmul")
7467 (set_attr "fptype" "double")])
7469 (define_insn "mulsf3"
7470 [(set (match_operand:SF 0 "register_operand" "=f")
7471 (mult:SF (match_operand:SF 1 "register_operand" "f")
7472 (match_operand:SF 2 "register_operand" "f")))]
7474 "fmuls\\t%1, %2, %0"
7475 [(set_attr "type" "fpmul")])
7477 (define_insn "*muldf3_extend"
7478 [(set (match_operand:DF 0 "register_operand" "=e")
7479 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7480 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7481 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7482 "fsmuld\\t%1, %2, %0"
7483 [(set_attr "type" "fpmul")
7484 (set_attr "fptype" "double")])
7486 (define_insn "*multf3_extend"
7487 [(set (match_operand:TF 0 "register_operand" "=e")
7488 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7489 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7490 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7491 "fdmulq\\t%1, %2, %0"
7492 [(set_attr "type" "fpmul")])
7494 (define_expand "divtf3"
7495 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7496 (div:TF (match_operand:TF 1 "general_operand" "")
7497 (match_operand:TF 2 "general_operand" "")))]
7498 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7501 if (! TARGET_HARD_QUAD)
7503 rtx slot0, slot1, slot2;
7505 if (GET_CODE (operands[0]) != MEM)
7506 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7508 slot0 = operands[0];
7509 if (GET_CODE (operands[1]) != MEM)
7511 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7512 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7515 slot1 = operands[1];
7516 if (GET_CODE (operands[2]) != MEM)
7518 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7519 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7522 slot2 = operands[2];
7524 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7526 XEXP (slot0, 0), Pmode,
7527 XEXP (slot1, 0), Pmode,
7528 XEXP (slot2, 0), Pmode);
7530 if (GET_CODE (operands[0]) != MEM)
7531 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7536 ;; don't have timing for quad-prec. divide.
7537 (define_insn "*divtf3_hq"
7538 [(set (match_operand:TF 0 "register_operand" "=e")
7539 (div:TF (match_operand:TF 1 "register_operand" "e")
7540 (match_operand:TF 2 "register_operand" "e")))]
7541 "TARGET_FPU && TARGET_HARD_QUAD"
7542 "fdivq\\t%1, %2, %0"
7543 [(set_attr "type" "fpdivd")])
7545 (define_insn "divdf3"
7546 [(set (match_operand:DF 0 "register_operand" "=e")
7547 (div:DF (match_operand:DF 1 "register_operand" "e")
7548 (match_operand:DF 2 "register_operand" "e")))]
7550 "fdivd\\t%1, %2, %0"
7551 [(set_attr "type" "fpdivd")
7552 (set_attr "fptype" "double")])
7554 (define_insn "divsf3"
7555 [(set (match_operand:SF 0 "register_operand" "=f")
7556 (div:SF (match_operand:SF 1 "register_operand" "f")
7557 (match_operand:SF 2 "register_operand" "f")))]
7559 "fdivs\\t%1, %2, %0"
7560 [(set_attr "type" "fpdivs")])
7562 (define_expand "negtf2"
7563 [(set (match_operand:TF 0 "register_operand" "=e,e")
7564 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7568 (define_insn "*negtf2_notv9"
7569 [(set (match_operand:TF 0 "register_operand" "=e,e")
7570 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7571 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7577 [(set_attr "type" "fpmove,*")
7578 (set_attr "length" "*,2")])
7581 [(set (match_operand:TF 0 "register_operand" "")
7582 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7586 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7587 [(set (match_dup 2) (neg:SF (match_dup 3)))
7588 (set (match_dup 4) (match_dup 5))
7589 (set (match_dup 6) (match_dup 7))]
7590 "if (GET_CODE (operands[0]) == SUBREG)
7591 operands[0] = alter_subreg (operands[0]);
7592 if (GET_CODE (operands[1]) == SUBREG)
7593 operands[1] = alter_subreg (operands[1]);
7594 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7595 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7596 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7597 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7598 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7599 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7601 (define_insn "*negtf2_v9"
7602 [(set (match_operand:TF 0 "register_operand" "=e,e")
7603 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7604 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7605 "TARGET_FPU && TARGET_V9"
7609 [(set_attr "type" "fpmove,*")
7610 (set_attr "length" "*,2")
7611 (set_attr "fptype" "double")])
7614 [(set (match_operand:TF 0 "register_operand" "")
7615 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7619 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7620 [(set (match_dup 2) (neg:DF (match_dup 3)))
7621 (set (match_dup 4) (match_dup 5))]
7622 "if (GET_CODE (operands[0]) == SUBREG)
7623 operands[0] = alter_subreg (operands[0]);
7624 if (GET_CODE (operands[1]) == SUBREG)
7625 operands[1] = alter_subreg (operands[1]);
7626 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7627 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7628 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7629 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7631 (define_expand "negdf2"
7632 [(set (match_operand:DF 0 "register_operand" "")
7633 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7637 (define_insn "*negdf2_notv9"
7638 [(set (match_operand:DF 0 "register_operand" "=e,e")
7639 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7640 "TARGET_FPU && ! TARGET_V9"
7644 [(set_attr "type" "fpmove,*")
7645 (set_attr "length" "*,2")])
7648 [(set (match_operand:DF 0 "register_operand" "")
7649 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7653 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7654 [(set (match_dup 2) (neg:SF (match_dup 3)))
7655 (set (match_dup 4) (match_dup 5))]
7656 "if (GET_CODE (operands[0]) == SUBREG)
7657 operands[0] = alter_subreg (operands[0]);
7658 if (GET_CODE (operands[1]) == SUBREG)
7659 operands[1] = alter_subreg (operands[1]);
7660 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7661 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7662 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7663 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7665 (define_insn "*negdf2_v9"
7666 [(set (match_operand:DF 0 "register_operand" "=e")
7667 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7668 "TARGET_FPU && TARGET_V9"
7670 [(set_attr "type" "fpmove")
7671 (set_attr "fptype" "double")])
7673 (define_insn "negsf2"
7674 [(set (match_operand:SF 0 "register_operand" "=f")
7675 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7678 [(set_attr "type" "fpmove")])
7680 (define_expand "abstf2"
7681 [(set (match_operand:TF 0 "register_operand" "")
7682 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7686 (define_insn "*abstf2_notv9"
7687 [(set (match_operand:TF 0 "register_operand" "=e,e")
7688 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7689 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7690 "TARGET_FPU && ! TARGET_V9"
7694 [(set_attr "type" "fpmove,*")
7695 (set_attr "length" "*,2")])
7698 [(set (match_operand:TF 0 "register_operand" "")
7699 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7703 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7704 [(set (match_dup 2) (abs:SF (match_dup 3)))
7705 (set (match_dup 4) (match_dup 5))
7706 (set (match_dup 6) (match_dup 7))]
7707 "if (GET_CODE (operands[0]) == SUBREG)
7708 operands[0] = alter_subreg (operands[0]);
7709 if (GET_CODE (operands[1]) == SUBREG)
7710 operands[1] = alter_subreg (operands[1]);
7711 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7712 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7713 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7714 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7715 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7716 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7718 (define_insn "*abstf2_hq_v9"
7719 [(set (match_operand:TF 0 "register_operand" "=e,e")
7720 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7721 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7725 [(set_attr "type" "fpmove")
7726 (set_attr "fptype" "double,*")])
7728 (define_insn "*abstf2_v9"
7729 [(set (match_operand:TF 0 "register_operand" "=e,e")
7730 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7731 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7735 [(set_attr "type" "fpmove,*")
7736 (set_attr "length" "*,2")
7737 (set_attr "fptype" "double,*")])
7740 [(set (match_operand:TF 0 "register_operand" "")
7741 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7745 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7746 [(set (match_dup 2) (abs:DF (match_dup 3)))
7747 (set (match_dup 4) (match_dup 5))]
7748 "if (GET_CODE (operands[0]) == SUBREG)
7749 operands[0] = alter_subreg (operands[0]);
7750 if (GET_CODE (operands[1]) == SUBREG)
7751 operands[1] = alter_subreg (operands[1]);
7752 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7753 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7754 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7755 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7757 (define_expand "absdf2"
7758 [(set (match_operand:DF 0 "register_operand" "")
7759 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7763 (define_insn "*absdf2_notv9"
7764 [(set (match_operand:DF 0 "register_operand" "=e,e")
7765 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7766 "TARGET_FPU && ! TARGET_V9"
7770 [(set_attr "type" "fpmove,*")
7771 (set_attr "length" "*,2")])
7774 [(set (match_operand:DF 0 "register_operand" "")
7775 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7779 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7780 [(set (match_dup 2) (abs:SF (match_dup 3)))
7781 (set (match_dup 4) (match_dup 5))]
7782 "if (GET_CODE (operands[0]) == SUBREG)
7783 operands[0] = alter_subreg (operands[0]);
7784 if (GET_CODE (operands[1]) == SUBREG)
7785 operands[1] = alter_subreg (operands[1]);
7786 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7787 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7788 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7789 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7791 (define_insn "*absdf2_v9"
7792 [(set (match_operand:DF 0 "register_operand" "=e")
7793 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7794 "TARGET_FPU && TARGET_V9"
7796 [(set_attr "type" "fpmove")
7797 (set_attr "fptype" "double")])
7799 (define_insn "abssf2"
7800 [(set (match_operand:SF 0 "register_operand" "=f")
7801 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7804 [(set_attr "type" "fpmove")])
7806 (define_expand "sqrttf2"
7807 [(set (match_operand:TF 0 "register_operand" "=e")
7808 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7809 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7812 if (! TARGET_HARD_QUAD)
7816 if (GET_CODE (operands[0]) != MEM)
7817 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7819 slot0 = operands[0];
7820 if (GET_CODE (operands[1]) != MEM)
7822 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7823 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7826 slot1 = operands[1];
7828 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7830 XEXP (slot0, 0), Pmode,
7831 XEXP (slot1, 0), Pmode);
7833 if (GET_CODE (operands[0]) != MEM)
7834 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7839 (define_insn "*sqrttf2_hq"
7840 [(set (match_operand:TF 0 "register_operand" "=e")
7841 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7842 "TARGET_FPU && TARGET_HARD_QUAD"
7844 [(set_attr "type" "fpsqrtd")])
7846 (define_insn "sqrtdf2"
7847 [(set (match_operand:DF 0 "register_operand" "=e")
7848 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7851 [(set_attr "type" "fpsqrtd")
7852 (set_attr "fptype" "double")])
7854 (define_insn "sqrtsf2"
7855 [(set (match_operand:SF 0 "register_operand" "=f")
7856 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7859 [(set_attr "type" "fpsqrts")])
7861 ;;- arithmetic shift instructions
7863 (define_insn "ashlsi3"
7864 [(set (match_operand:SI 0 "register_operand" "=r")
7865 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7866 (match_operand:SI 2 "arith_operand" "rI")))]
7870 if (GET_CODE (operands[2]) == CONST_INT
7871 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7872 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7874 return \"sll\\t%1, %2, %0\";
7876 [(set_attr "type" "shift")])
7878 ;; We special case multiplication by two, as add can be done
7879 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7880 (define_insn "*ashlsi3_const1"
7881 [(set (match_operand:SI 0 "register_operand" "=r")
7882 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7887 (define_expand "ashldi3"
7888 [(set (match_operand:DI 0 "register_operand" "=r")
7889 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7890 (match_operand:SI 2 "arith_operand" "rI")))]
7891 "TARGET_ARCH64 || TARGET_V8PLUS"
7894 if (! TARGET_ARCH64)
7896 if (GET_CODE (operands[2]) == CONST_INT)
7898 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7903 ;; We special case multiplication by two, as add can be done
7904 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7905 (define_insn "*ashldi3_const1"
7906 [(set (match_operand:DI 0 "register_operand" "=r")
7907 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7912 (define_insn "*ashldi3_sp64"
7913 [(set (match_operand:DI 0 "register_operand" "=r")
7914 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7915 (match_operand:SI 2 "arith_operand" "rI")))]
7919 if (GET_CODE (operands[2]) == CONST_INT
7920 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7921 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7923 return \"sllx\\t%1, %2, %0\";
7925 [(set_attr "type" "shift")])
7928 (define_insn "ashldi3_v8plus"
7929 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7930 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7931 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7932 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7934 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7935 [(set_attr "type" "multi")
7936 (set_attr "length" "5,5,6")])
7938 ;; Optimize (1LL<<x)-1
7939 ;; XXX this also needs to be fixed to handle equal subregs
7940 ;; XXX first before we could re-enable it.
7942 ; [(set (match_operand:DI 0 "register_operand" "=h")
7943 ; (plus:DI (ashift:DI (const_int 1)
7944 ; (match_operand:SI 1 "arith_operand" "rI"))
7946 ; "0 && TARGET_V8PLUS"
7949 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7950 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7951 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7953 ; [(set_attr "type" "multi")
7954 ; (set_attr "length" "4")])
7956 (define_insn "*cmp_cc_ashift_1"
7957 [(set (reg:CC_NOOV 100)
7958 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7962 "addcc\\t%0, %0, %%g0"
7963 [(set_attr "type" "compare")])
7965 (define_insn "*cmp_cc_set_ashift_1"
7966 [(set (reg:CC_NOOV 100)
7967 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7970 (set (match_operand:SI 0 "register_operand" "=r")
7971 (ashift:SI (match_dup 1) (const_int 1)))]
7973 "addcc\\t%1, %1, %0"
7974 [(set_attr "type" "compare")])
7976 (define_insn "ashrsi3"
7977 [(set (match_operand:SI 0 "register_operand" "=r")
7978 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7979 (match_operand:SI 2 "arith_operand" "rI")))]
7983 if (GET_CODE (operands[2]) == CONST_INT
7984 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7985 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7987 return \"sra\\t%1, %2, %0\";
7989 [(set_attr "type" "shift")])
7991 (define_insn "*ashrsi3_extend"
7992 [(set (match_operand:DI 0 "register_operand" "=r")
7993 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7994 (match_operand:SI 2 "arith_operand" "r"))))]
7997 [(set_attr "type" "shift")])
7999 ;; This handles the case as above, but with constant shift instead of
8000 ;; register. Combiner "simplifies" it for us a little bit though.
8001 (define_insn "*ashrsi3_extend2"
8002 [(set (match_operand:DI 0 "register_operand" "=r")
8003 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8005 (match_operand:SI 2 "small_int_or_double" "n")))]
8007 && ((GET_CODE (operands[2]) == CONST_INT
8008 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8009 || (GET_CODE (operands[2]) == CONST_DOUBLE
8010 && !CONST_DOUBLE_HIGH (operands[2])
8011 && CONST_DOUBLE_LOW (operands[2]) >= 32
8012 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8015 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8017 return \"sra\\t%1, %2, %0\";
8019 [(set_attr "type" "shift")])
8021 (define_expand "ashrdi3"
8022 [(set (match_operand:DI 0 "register_operand" "=r")
8023 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8024 (match_operand:SI 2 "arith_operand" "rI")))]
8025 "TARGET_ARCH64 || TARGET_V8PLUS"
8028 if (! TARGET_ARCH64)
8030 if (GET_CODE (operands[2]) == CONST_INT)
8031 FAIL; /* prefer generic code in this case */
8032 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8038 [(set (match_operand:DI 0 "register_operand" "=r")
8039 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8040 (match_operand:SI 2 "arith_operand" "rI")))]
8044 if (GET_CODE (operands[2]) == CONST_INT
8045 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8046 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8048 return \"srax\\t%1, %2, %0\";
8050 [(set_attr "type" "shift")])
8053 (define_insn "ashrdi3_v8plus"
8054 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8055 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8056 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8057 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8059 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8060 [(set_attr "type" "multi")
8061 (set_attr "length" "5,5,6")])
8063 (define_insn "lshrsi3"
8064 [(set (match_operand:SI 0 "register_operand" "=r")
8065 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8066 (match_operand:SI 2 "arith_operand" "rI")))]
8070 if (GET_CODE (operands[2]) == CONST_INT
8071 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8072 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8074 return \"srl\\t%1, %2, %0\";
8076 [(set_attr "type" "shift")])
8078 ;; This handles the case where
8079 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8080 ;; but combiner "simplifies" it for us.
8081 (define_insn "*lshrsi3_extend"
8082 [(set (match_operand:DI 0 "register_operand" "=r")
8083 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8084 (match_operand:SI 2 "arith_operand" "r")) 0)
8085 (match_operand 3 "" "")))]
8087 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8088 && CONST_DOUBLE_HIGH (operands[3]) == 0
8089 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8090 || (HOST_BITS_PER_WIDE_INT >= 64
8091 && GET_CODE (operands[3]) == CONST_INT
8092 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8094 [(set_attr "type" "shift")])
8096 ;; This handles the case where
8097 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8098 ;; but combiner "simplifies" it for us.
8099 (define_insn "*lshrsi3_extend2"
8100 [(set (match_operand:DI 0 "register_operand" "=r")
8101 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8102 (match_operand 2 "small_int_or_double" "n")
8105 && ((GET_CODE (operands[2]) == CONST_INT
8106 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8107 || (GET_CODE (operands[2]) == CONST_DOUBLE
8108 && CONST_DOUBLE_HIGH (operands[2]) == 0
8109 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8112 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8114 return \"srl\\t%1, %2, %0\";
8116 [(set_attr "type" "shift")])
8118 (define_expand "lshrdi3"
8119 [(set (match_operand:DI 0 "register_operand" "=r")
8120 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8121 (match_operand:SI 2 "arith_operand" "rI")))]
8122 "TARGET_ARCH64 || TARGET_V8PLUS"
8125 if (! TARGET_ARCH64)
8127 if (GET_CODE (operands[2]) == CONST_INT)
8129 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8135 [(set (match_operand:DI 0 "register_operand" "=r")
8136 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8137 (match_operand:SI 2 "arith_operand" "rI")))]
8141 if (GET_CODE (operands[2]) == CONST_INT
8142 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8143 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8145 return \"srlx\\t%1, %2, %0\";
8147 [(set_attr "type" "shift")])
8150 (define_insn "lshrdi3_v8plus"
8151 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8152 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8153 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8154 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8156 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8157 [(set_attr "type" "multi")
8158 (set_attr "length" "5,5,6")])
8161 [(set (match_operand:SI 0 "register_operand" "=r")
8162 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8164 (match_operand:SI 2 "small_int_or_double" "n")))]
8166 && ((GET_CODE (operands[2]) == CONST_INT
8167 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8168 || (GET_CODE (operands[2]) == CONST_DOUBLE
8169 && !CONST_DOUBLE_HIGH (operands[2])
8170 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8173 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8175 return \"srax\\t%1, %2, %0\";
8177 [(set_attr "type" "shift")])
8180 [(set (match_operand:SI 0 "register_operand" "=r")
8181 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8183 (match_operand:SI 2 "small_int_or_double" "n")))]
8185 && ((GET_CODE (operands[2]) == CONST_INT
8186 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8187 || (GET_CODE (operands[2]) == CONST_DOUBLE
8188 && !CONST_DOUBLE_HIGH (operands[2])
8189 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8192 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8194 return \"srlx\\t%1, %2, %0\";
8196 [(set_attr "type" "shift")])
8199 [(set (match_operand:SI 0 "register_operand" "=r")
8200 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8201 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8202 (match_operand:SI 3 "small_int_or_double" "n")))]
8204 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8205 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8206 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8207 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8210 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8212 return \"srax\\t%1, %2, %0\";
8214 [(set_attr "type" "shift")])
8217 [(set (match_operand:SI 0 "register_operand" "=r")
8218 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8219 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8220 (match_operand:SI 3 "small_int_or_double" "n")))]
8222 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8223 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8224 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8225 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8228 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8230 return \"srlx\\t%1, %2, %0\";
8232 [(set_attr "type" "shift")])
8234 ;; Unconditional and other jump instructions
8235 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8236 ;; following insn is never executed. This saves us a nop. Dbx does not
8237 ;; handle such branches though, so we only use them when optimizing.
8239 [(set (pc) (label_ref (match_operand 0 "" "")))]
8243 /* TurboSparc is reported to have problems with
8246 i.e. an empty loop with the annul bit set. The workaround is to use
8250 if (! TARGET_V9 && flag_delayed_branch
8251 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8252 == INSN_ADDRESSES (INSN_UID (insn))))
8253 return \"b\\t%l0%#\";
8255 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8257 [(set_attr "type" "uncond_branch")])
8259 (define_expand "tablejump"
8260 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8261 (use (label_ref (match_operand 1 "" "")))])]
8265 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8268 /* In pic mode, our address differences are against the base of the
8269 table. Add that base value back in; CSE ought to be able to combine
8270 the two address loads. */
8274 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8276 if (CASE_VECTOR_MODE != Pmode)
8277 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8278 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8279 operands[0] = memory_address (Pmode, tmp);
8283 (define_insn "*tablejump_sp32"
8284 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8285 (use (label_ref (match_operand 1 "" "")))]
8288 [(set_attr "type" "uncond_branch")])
8290 (define_insn "*tablejump_sp64"
8291 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8292 (use (label_ref (match_operand 1 "" "")))]
8295 [(set_attr "type" "uncond_branch")])
8297 ;; This pattern recognizes the "instruction" that appears in
8298 ;; a function call that wants a structure value,
8299 ;; to inform the called function if compiled with Sun CC.
8300 ;(define_insn "*unimp_insn"
8301 ; [(match_operand:SI 0 "immediate_operand" "")]
8302 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8304 ; [(set_attr "type" "marker")])
8306 ;;- jump to subroutine
8307 (define_expand "call"
8308 ;; Note that this expression is not used for generating RTL.
8309 ;; All the RTL is generated explicitly below.
8310 [(call (match_operand 0 "call_operand" "")
8311 (match_operand 3 "" "i"))]
8312 ;; operands[2] is next_arg_register
8313 ;; operands[3] is struct_value_size_rtx.
8317 rtx fn_rtx, nregs_rtx;
8319 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8322 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8324 /* This is really a PIC sequence. We want to represent
8325 it as a funny jump so its delay slots can be filled.
8327 ??? But if this really *is* a CALL, will not it clobber the
8328 call-clobbered registers? We lose this if it is a JUMP_INSN.
8329 Why cannot we have delay slots filled if it were a CALL? */
8331 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8336 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8338 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8344 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8345 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8349 fn_rtx = operands[0];
8351 /* Count the number of parameter registers being used by this call.
8352 if that argument is NULL, it means we are using them all, which
8353 means 6 on the sparc. */
8356 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8358 nregs_rtx = GEN_INT (6);
8360 nregs_rtx = const0_rtx;
8363 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8367 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8369 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8374 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8375 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8379 /* If this call wants a structure value,
8380 emit an unimp insn to let the called function know about this. */
8381 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8383 rtx insn = emit_insn (operands[3]);
8384 SCHED_GROUP_P (insn) = 1;
8391 ;; We can't use the same pattern for these two insns, because then registers
8392 ;; in the address may not be properly reloaded.
8394 (define_insn "*call_address_sp32"
8395 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8396 (match_operand 1 "" ""))
8397 (clobber (reg:SI 15))]
8398 ;;- Do not use operand 1 for most machines.
8401 [(set_attr "type" "call")])
8403 (define_insn "*call_symbolic_sp32"
8404 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8405 (match_operand 1 "" ""))
8406 (clobber (reg:SI 15))]
8407 ;;- Do not use operand 1 for most machines.
8410 [(set_attr "type" "call")])
8412 (define_insn "*call_address_sp64"
8413 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8414 (match_operand 1 "" ""))
8415 (clobber (reg:DI 15))]
8416 ;;- Do not use operand 1 for most machines.
8419 [(set_attr "type" "call")])
8421 (define_insn "*call_symbolic_sp64"
8422 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8423 (match_operand 1 "" ""))
8424 (clobber (reg:DI 15))]
8425 ;;- Do not use operand 1 for most machines.
8428 [(set_attr "type" "call")])
8430 ;; This is a call that wants a structure value.
8431 ;; There is no such critter for v9 (??? we may need one anyway).
8432 (define_insn "*call_address_struct_value_sp32"
8433 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8434 (match_operand 1 "" ""))
8435 (match_operand 2 "immediate_operand" "")
8436 (clobber (reg:SI 15))]
8437 ;;- Do not use operand 1 for most machines.
8438 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8439 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8440 [(set_attr "type" "call_no_delay_slot")])
8442 ;; This is a call that wants a structure value.
8443 ;; There is no such critter for v9 (??? we may need one anyway).
8444 (define_insn "*call_symbolic_struct_value_sp32"
8445 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8446 (match_operand 1 "" ""))
8447 (match_operand 2 "immediate_operand" "")
8448 (clobber (reg:SI 15))]
8449 ;;- Do not use operand 1 for most machines.
8450 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8451 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8452 [(set_attr "type" "call_no_delay_slot")])
8454 ;; This is a call that may want a structure value. This is used for
8456 (define_insn "*call_address_untyped_struct_value_sp32"
8457 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8458 (match_operand 1 "" ""))
8459 (match_operand 2 "immediate_operand" "")
8460 (clobber (reg:SI 15))]
8461 ;;- Do not use operand 1 for most machines.
8462 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8463 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8464 [(set_attr "type" "call_no_delay_slot")])
8466 ;; This is a call that wants a structure value.
8467 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8468 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8469 (match_operand 1 "" ""))
8470 (match_operand 2 "immediate_operand" "")
8471 (clobber (reg:SI 15))]
8472 ;;- Do not use operand 1 for most machines.
8473 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8474 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8475 [(set_attr "type" "call_no_delay_slot")])
8477 (define_expand "call_value"
8478 ;; Note that this expression is not used for generating RTL.
8479 ;; All the RTL is generated explicitly below.
8480 [(set (match_operand 0 "register_operand" "=rf")
8481 (call (match_operand 1 "" "")
8482 (match_operand 4 "" "")))]
8483 ;; operand 2 is stack_size_rtx
8484 ;; operand 3 is next_arg_register
8488 rtx fn_rtx, nregs_rtx;
8491 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8494 fn_rtx = operands[1];
8498 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8500 nregs_rtx = GEN_INT (6);
8502 nregs_rtx = const0_rtx;
8506 gen_rtx_SET (VOIDmode, operands[0],
8507 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8508 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8510 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8515 (define_insn "*call_value_address_sp32"
8516 [(set (match_operand 0 "" "=rf")
8517 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8518 (match_operand 2 "" "")))
8519 (clobber (reg:SI 15))]
8520 ;;- Do not use operand 2 for most machines.
8523 [(set_attr "type" "call")])
8525 (define_insn "*call_value_symbolic_sp32"
8526 [(set (match_operand 0 "" "=rf")
8527 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8528 (match_operand 2 "" "")))
8529 (clobber (reg:SI 15))]
8530 ;;- Do not use operand 2 for most machines.
8533 [(set_attr "type" "call")])
8535 (define_insn "*call_value_address_sp64"
8536 [(set (match_operand 0 "" "")
8537 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8538 (match_operand 2 "" "")))
8539 (clobber (reg:DI 15))]
8540 ;;- Do not use operand 2 for most machines.
8543 [(set_attr "type" "call")])
8545 (define_insn "*call_value_symbolic_sp64"
8546 [(set (match_operand 0 "" "")
8547 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8548 (match_operand 2 "" "")))
8549 (clobber (reg:DI 15))]
8550 ;;- Do not use operand 2 for most machines.
8553 [(set_attr "type" "call")])
8555 (define_expand "untyped_call"
8556 [(parallel [(call (match_operand 0 "" "")
8558 (match_operand 1 "" "")
8559 (match_operand 2 "" "")])]
8565 /* Pass constm1 to indicate that it may expect a structure value, but
8566 we don't know what size it is. */
8567 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8569 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8571 rtx set = XVECEXP (operands[2], 0, i);
8572 emit_move_insn (SET_DEST (set), SET_SRC (set));
8575 /* The optimizer does not know that the call sets the function value
8576 registers we stored in the result block. We avoid problems by
8577 claiming that all hard registers are used and clobbered at this
8579 emit_insn (gen_blockage ());
8585 (define_expand "sibcall"
8586 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8591 (define_insn "*sibcall_symbolic_sp32"
8592 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8593 (match_operand 1 "" ""))
8596 "* return output_sibcall(insn, operands[0]);"
8597 [(set_attr "type" "sibcall")])
8599 (define_insn "*sibcall_symbolic_sp64"
8600 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8601 (match_operand 1 "" ""))
8604 "* return output_sibcall(insn, operands[0]);"
8605 [(set_attr "type" "sibcall")])
8607 (define_expand "sibcall_value"
8608 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8609 (call (match_operand 1 "" "") (const_int 0)))
8614 (define_insn "*sibcall_value_symbolic_sp32"
8615 [(set (match_operand 0 "" "=rf")
8616 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8617 (match_operand 2 "" "")))
8620 "* return output_sibcall(insn, operands[1]);"
8621 [(set_attr "type" "sibcall")])
8623 (define_insn "*sibcall_value_symbolic_sp64"
8624 [(set (match_operand 0 "" "")
8625 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8626 (match_operand 2 "" "")))
8629 "* return output_sibcall(insn, operands[1]);"
8630 [(set_attr "type" "sibcall")])
8632 (define_expand "sibcall_epilogue"
8637 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8638 ;; all of memory. This blocks insns from being moved across this point.
8640 (define_insn "blockage"
8641 [(unspec_volatile [(const_int 0)] 0)]
8644 [(set_attr "length" "0")])
8646 ;; Prepare to return any type including a structure value.
8648 (define_expand "untyped_return"
8649 [(match_operand:BLK 0 "memory_operand" "")
8650 (match_operand 1 "" "")]
8654 rtx valreg1 = gen_rtx_REG (DImode, 24);
8655 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8656 rtx result = operands[0];
8658 if (! TARGET_ARCH64)
8660 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8662 rtx value = gen_reg_rtx (SImode);
8664 /* Fetch the instruction where we will return to and see if it's an unimp
8665 instruction (the most significant 10 bits will be zero). If so,
8666 update the return address to skip the unimp instruction. */
8667 emit_move_insn (value,
8668 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8669 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8670 emit_insn (gen_update_return (rtnreg, value));
8673 /* Reload the function value registers. */
8674 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8675 emit_move_insn (valreg2,
8676 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8678 /* Put USE insns before the return. */
8679 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8680 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8682 /* Construct the return. */
8683 expand_null_return ();
8688 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8689 ;; and parts of the compiler don't want to believe that the add is needed.
8691 (define_insn "update_return"
8692 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8693 (match_operand:SI 1 "register_operand" "r")] 1)]
8695 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8696 [(set_attr "type" "multi")
8697 (set_attr "length" "3")])
8699 (define_insn "return"
8703 "* return output_return (operands);"
8704 [(set_attr "type" "return")])
8707 [(set (match_operand:SI 0 "register_operand" "=r")
8708 (match_operand:SI 1 "arith_operand" "rI"))
8710 (use (reg:SI 31))])]
8711 "sparc_return_peephole_ok (operands[0], operands[1])"
8712 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8719 (define_expand "indirect_jump"
8720 [(set (pc) (match_operand 0 "address_operand" "p"))]
8724 (define_insn "*branch_sp32"
8725 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8728 [(set_attr "type" "uncond_branch")])
8730 (define_insn "*branch_sp64"
8731 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8734 [(set_attr "type" "uncond_branch")])
8736 ;; ??? Doesn't work with -mflat.
8737 (define_expand "nonlocal_goto"
8738 [(match_operand:SI 0 "general_operand" "")
8739 (match_operand:SI 1 "general_operand" "")
8740 (match_operand:SI 2 "general_operand" "")
8741 (match_operand:SI 3 "" "")]
8746 rtx chain = operands[0];
8748 rtx lab = operands[1];
8749 rtx stack = operands[2];
8750 rtx fp = operands[3];
8753 /* Trap instruction to flush all the register windows. */
8754 emit_insn (gen_flush_register_windows ());
8756 /* Load the fp value for the containing fn into %fp. This is needed
8757 because STACK refers to %fp. Note that virtual register instantiation
8758 fails if the virtual %fp isn't set from a register. */
8759 if (GET_CODE (fp) != REG)
8760 fp = force_reg (Pmode, fp);
8761 emit_move_insn (virtual_stack_vars_rtx, fp);
8763 /* Find the containing function's current nonlocal goto handler,
8764 which will do any cleanups and then jump to the label. */
8765 labreg = gen_rtx_REG (Pmode, 8);
8766 emit_move_insn (labreg, lab);
8768 /* Restore %fp from stack pointer value for containing function.
8769 The restore insn that follows will move this to %sp,
8770 and reload the appropriate value into %fp. */
8771 emit_move_insn (frame_pointer_rtx, stack);
8773 /* USE of frame_pointer_rtx added for consistency; not clear if
8775 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8776 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8779 /* Return, restoring reg window and jumping to goto handler. */
8780 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8781 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8783 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8789 /* Put in the static chain register the nonlocal label address. */
8790 emit_move_insn (static_chain_rtx, chain);
8793 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8794 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8799 ;; Special trap insn to flush register windows.
8800 (define_insn "flush_register_windows"
8801 [(unspec_volatile [(const_int 0)] 1)]
8803 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8804 [(set_attr "type" "misc")])
8806 (define_insn "goto_handler_and_restore"
8807 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8808 "GET_MODE (operands[0]) == Pmode"
8809 "jmp\\t%0+0\\n\\trestore"
8810 [(set_attr "type" "multi")
8811 (set_attr "length" "2")])
8813 ;;(define_insn "goto_handler_and_restore_v9"
8814 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8815 ;; (match_operand:SI 1 "register_operand" "=r,r")
8816 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8817 ;; "TARGET_V9 && ! TARGET_ARCH64"
8819 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8820 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8821 ;; [(set_attr "type" "multi")
8822 ;; (set_attr "length" "2,3")])
8824 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8825 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8826 ;; (match_operand:DI 1 "register_operand" "=r,r")
8827 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8828 ;; "TARGET_V9 && TARGET_ARCH64"
8830 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8831 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8832 ;; [(set_attr "type" "multi")
8833 ;; (set_attr "length" "2,3")])
8835 ;; For __builtin_setjmp we need to flush register windows iff the function
8836 ;; calls alloca as well, because otherwise the register window might be
8837 ;; saved after %sp adjustement and thus setjmp would crash
8838 (define_expand "builtin_setjmp_setup"
8839 [(match_operand 0 "register_operand" "r")]
8843 emit_insn (gen_do_builtin_setjmp_setup ());
8847 ;; ??? Should set length to zero when !current_function_calls_alloca,
8848 ;; ??? but there is no easy way to get at that definition. It would
8849 ;; ??? require including function.h into sparc-protos.h and that is
8850 ;; ??? likely not a good idea. -DaveM
8851 (define_insn "do_builtin_setjmp_setup"
8852 [(unspec_volatile [(const_int 0)] 5)]
8856 if (!current_function_calls_alloca)
8862 [(set_attr "type" "misc")])
8864 ;; Pattern for use after a setjmp to store FP and the return register
8865 ;; into the stack area.
8867 (define_expand "setjmp"
8873 emit_insn (gen_setjmp_64 ());
8875 emit_insn (gen_setjmp_32 ());
8879 (define_expand "setjmp_32"
8880 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8881 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8884 { operands[0] = frame_pointer_rtx; }")
8886 (define_expand "setjmp_64"
8887 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8888 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8891 { operands[0] = frame_pointer_rtx; }")
8893 ;; Special pattern for the FLUSH instruction.
8895 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8896 ; of the define_insn otherwise missing a mode. We make "flush", aka
8897 ; gen_flush, the default one since sparc_initialize_trampoline uses
8898 ; it on SImode mem values.
8900 (define_insn "flush"
8901 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8903 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8904 [(set_attr "type" "misc")])
8906 (define_insn "flushdi"
8907 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8909 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8910 [(set_attr "type" "misc")])
8915 ;; The scan instruction searches from the most significant bit while ffs
8916 ;; searches from the least significant bit. The bit index and treatment of
8917 ;; zero also differ. It takes at least 7 instructions to get the proper
8918 ;; result. Here is an obvious 8 instruction sequence.
8921 (define_insn "ffssi2"
8922 [(set (match_operand:SI 0 "register_operand" "=&r")
8923 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8924 (clobber (match_scratch:SI 2 "=&r"))]
8925 "TARGET_SPARCLITE || TARGET_SPARCLET"
8928 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\";
8930 [(set_attr "type" "multi")
8931 (set_attr "length" "8")])
8933 ;; ??? This should be a define expand, so that the extra instruction have
8934 ;; a chance of being optimized away.
8936 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8937 ;; does, but no one uses that and we don't have a switch for it.
8939 ;(define_insn "ffsdi2"
8940 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8941 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8942 ; (clobber (match_scratch:DI 2 "=&r"))]
8944 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8945 ; [(set_attr "type" "multi")
8946 ; (set_attr "length" "4")])
8950 ;; Peepholes go at the end.
8952 ;; Optimize consecutive loads or stores into ldd and std when possible.
8953 ;; The conditions in which we do this are very restricted and are
8954 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8957 [(set (match_operand:SI 0 "memory_operand" "")
8959 (set (match_operand:SI 1 "memory_operand" "")
8962 && ! MEM_VOLATILE_P (operands[0])
8963 && ! MEM_VOLATILE_P (operands[1])
8964 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8968 [(set (match_operand:SI 0 "memory_operand" "")
8970 (set (match_operand:SI 1 "memory_operand" "")
8973 && ! MEM_VOLATILE_P (operands[0])
8974 && ! MEM_VOLATILE_P (operands[1])
8975 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8979 [(set (match_operand:SI 0 "register_operand" "=rf")
8980 (match_operand:SI 1 "memory_operand" ""))
8981 (set (match_operand:SI 2 "register_operand" "=rf")
8982 (match_operand:SI 3 "memory_operand" ""))]
8983 "registers_ok_for_ldd_peep (operands[0], operands[2])
8984 && ! MEM_VOLATILE_P (operands[1])
8985 && ! MEM_VOLATILE_P (operands[3])
8986 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8990 [(set (match_operand:SI 0 "memory_operand" "")
8991 (match_operand:SI 1 "register_operand" "rf"))
8992 (set (match_operand:SI 2 "memory_operand" "")
8993 (match_operand:SI 3 "register_operand" "rf"))]
8994 "registers_ok_for_ldd_peep (operands[1], operands[3])
8995 && ! MEM_VOLATILE_P (operands[0])
8996 && ! MEM_VOLATILE_P (operands[2])
8997 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9001 [(set (match_operand:SF 0 "register_operand" "=fr")
9002 (match_operand:SF 1 "memory_operand" ""))
9003 (set (match_operand:SF 2 "register_operand" "=fr")
9004 (match_operand:SF 3 "memory_operand" ""))]
9005 "registers_ok_for_ldd_peep (operands[0], operands[2])
9006 && ! MEM_VOLATILE_P (operands[1])
9007 && ! MEM_VOLATILE_P (operands[3])
9008 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9012 [(set (match_operand:SF 0 "memory_operand" "")
9013 (match_operand:SF 1 "register_operand" "fr"))
9014 (set (match_operand:SF 2 "memory_operand" "")
9015 (match_operand:SF 3 "register_operand" "fr"))]
9016 "registers_ok_for_ldd_peep (operands[1], operands[3])
9017 && ! MEM_VOLATILE_P (operands[0])
9018 && ! MEM_VOLATILE_P (operands[2])
9019 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9023 [(set (match_operand:SI 0 "register_operand" "=rf")
9024 (match_operand:SI 1 "memory_operand" ""))
9025 (set (match_operand:SI 2 "register_operand" "=rf")
9026 (match_operand:SI 3 "memory_operand" ""))]
9027 "registers_ok_for_ldd_peep (operands[2], operands[0])
9028 && ! MEM_VOLATILE_P (operands[3])
9029 && ! MEM_VOLATILE_P (operands[1])
9030 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9034 [(set (match_operand:SI 0 "memory_operand" "")
9035 (match_operand:SI 1 "register_operand" "rf"))
9036 (set (match_operand:SI 2 "memory_operand" "")
9037 (match_operand:SI 3 "register_operand" "rf"))]
9038 "registers_ok_for_ldd_peep (operands[3], operands[1])
9039 && ! MEM_VOLATILE_P (operands[2])
9040 && ! MEM_VOLATILE_P (operands[0])
9041 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9045 [(set (match_operand:SF 0 "register_operand" "=fr")
9046 (match_operand:SF 1 "memory_operand" ""))
9047 (set (match_operand:SF 2 "register_operand" "=fr")
9048 (match_operand:SF 3 "memory_operand" ""))]
9049 "registers_ok_for_ldd_peep (operands[2], operands[0])
9050 && ! MEM_VOLATILE_P (operands[3])
9051 && ! MEM_VOLATILE_P (operands[1])
9052 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9056 [(set (match_operand:SF 0 "memory_operand" "")
9057 (match_operand:SF 1 "register_operand" "fr"))
9058 (set (match_operand:SF 2 "memory_operand" "")
9059 (match_operand:SF 3 "register_operand" "fr"))]
9060 "registers_ok_for_ldd_peep (operands[3], operands[1])
9061 && ! MEM_VOLATILE_P (operands[2])
9062 && ! MEM_VOLATILE_P (operands[0])
9063 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9066 ;; Optimize the case of following a reg-reg move with a test
9067 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9068 ;; This can result from a float to fix conversion.
9071 [(set (match_operand:SI 0 "register_operand" "=r")
9072 (match_operand:SI 1 "register_operand" "r"))
9074 (compare:CC (match_operand:SI 2 "register_operand" "r")
9076 "(rtx_equal_p (operands[2], operands[0])
9077 || rtx_equal_p (operands[2], operands[1]))
9078 && ! FP_REG_P (operands[0])
9079 && ! FP_REG_P (operands[1])"
9083 [(set (match_operand:DI 0 "register_operand" "=r")
9084 (match_operand:DI 1 "register_operand" "r"))
9086 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9089 && (rtx_equal_p (operands[2], operands[0])
9090 || rtx_equal_p (operands[2], operands[1]))
9091 && ! FP_REG_P (operands[0])
9092 && ! FP_REG_P (operands[1])"
9095 ;; Return peepholes. First the "normal" ones.
9096 ;; These are necessary to catch insns ending up in the epilogue delay list.
9098 (define_insn "*return_qi"
9099 [(set (match_operand:QI 0 "restore_operand" "")
9100 (match_operand:QI 1 "arith_operand" "rI"))
9105 if (! TARGET_ARCH64 && current_function_returns_struct)
9106 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9107 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9108 || IN_OR_GLOBAL_P (operands[1])))
9109 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9111 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9113 [(set_attr "type" "multi")
9114 (set_attr "length" "2")])
9116 (define_insn "*return_hi"
9117 [(set (match_operand:HI 0 "restore_operand" "")
9118 (match_operand:HI 1 "arith_operand" "rI"))
9123 if (! TARGET_ARCH64 && current_function_returns_struct)
9124 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9125 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9126 || IN_OR_GLOBAL_P (operands[1])))
9127 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9129 return \"ret\;restore %%g0, %1, %Y0\";
9131 [(set_attr "type" "multi")
9132 (set_attr "length" "2")])
9134 (define_insn "*return_si"
9135 [(set (match_operand:SI 0 "restore_operand" "")
9136 (match_operand:SI 1 "arith_operand" "rI"))
9141 if (! TARGET_ARCH64 && current_function_returns_struct)
9142 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9143 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9144 || IN_OR_GLOBAL_P (operands[1])))
9145 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9147 return \"ret\;restore %%g0, %1, %Y0\";
9149 [(set_attr "type" "multi")
9150 (set_attr "length" "2")])
9152 ;; The following pattern is only generated by delayed-branch scheduling,
9153 ;; when the insn winds up in the epilogue. This can happen not only when
9154 ;; ! TARGET_FPU because we move complex types around by parts using
9156 (define_insn "*return_sf_no_fpu"
9157 [(set (match_operand:SF 0 "restore_operand" "=r")
9158 (match_operand:SF 1 "register_operand" "r"))
9163 if (! TARGET_ARCH64 && current_function_returns_struct)
9164 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9165 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9166 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9168 return \"ret\;restore %%g0, %1, %Y0\";
9170 [(set_attr "type" "multi")
9171 (set_attr "length" "2")])
9173 (define_insn "*return_df_no_fpu"
9174 [(set (match_operand:DF 0 "restore_operand" "=r")
9175 (match_operand:DF 1 "register_operand" "r"))
9177 "! TARGET_EPILOGUE && TARGET_ARCH64"
9180 if (IN_OR_GLOBAL_P (operands[1]))
9181 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9183 return \"ret\;restore %%g0, %1, %Y0\";
9185 [(set_attr "type" "multi")
9186 (set_attr "length" "2")])
9188 (define_insn "*return_addsi"
9189 [(set (match_operand:SI 0 "restore_operand" "")
9190 (plus:SI (match_operand:SI 1 "register_operand" "r")
9191 (match_operand:SI 2 "arith_operand" "rI")))
9196 if (! TARGET_ARCH64 && current_function_returns_struct)
9197 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9198 /* If operands are global or in registers, can use return */
9199 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9200 && (GET_CODE (operands[2]) == CONST_INT
9201 || IN_OR_GLOBAL_P (operands[2])))
9202 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9204 return \"ret\;restore %r1, %2, %Y0\";
9206 [(set_attr "type" "multi")
9207 (set_attr "length" "2")])
9209 (define_insn "*return_losum_si"
9210 [(set (match_operand:SI 0 "restore_operand" "")
9211 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9212 (match_operand:SI 2 "immediate_operand" "in")))
9214 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9217 if (! TARGET_ARCH64 && current_function_returns_struct)
9218 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9219 /* If operands are global or in registers, can use return */
9220 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9221 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9223 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9225 [(set_attr "type" "multi")
9226 (set_attr "length" "2")])
9228 (define_insn "*return_di"
9229 [(set (match_operand:DI 0 "restore_operand" "")
9230 (match_operand:DI 1 "arith_double_operand" "rHI"))
9232 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9233 "ret\;restore %%g0, %1, %Y0"
9234 [(set_attr "type" "multi")
9235 (set_attr "length" "2")])
9237 (define_insn "*return_adddi"
9238 [(set (match_operand:DI 0 "restore_operand" "")
9239 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9240 (match_operand:DI 2 "arith_double_operand" "rHI")))
9242 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9243 "ret\;restore %r1, %2, %Y0"
9244 [(set_attr "type" "multi")
9245 (set_attr "length" "2")])
9247 (define_insn "*return_losum_di"
9248 [(set (match_operand:DI 0 "restore_operand" "")
9249 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9250 (match_operand:DI 2 "immediate_operand" "in")))
9252 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9253 "ret\;restore %r1, %%lo(%a2), %Y0"
9254 [(set_attr "type" "multi")
9255 (set_attr "length" "2")])
9257 ;; The following pattern is only generated by delayed-branch scheduling,
9258 ;; when the insn winds up in the epilogue.
9259 (define_insn "*return_sf"
9261 (match_operand:SF 0 "register_operand" "f"))
9264 "ret\;fmovs\\t%0, %%f0"
9265 [(set_attr "type" "multi")
9266 (set_attr "length" "2")])
9268 ;; Now peepholes to do a call followed by a jump.
9271 [(parallel [(set (match_operand 0 "" "")
9272 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9273 (match_operand 2 "" "")))
9274 (clobber (reg:SI 15))])
9275 (set (pc) (label_ref (match_operand 3 "" "")))]
9276 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9277 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9278 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9281 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9282 (match_operand 1 "" ""))
9283 (clobber (reg:SI 15))])
9284 (set (pc) (label_ref (match_operand 2 "" "")))]
9285 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9286 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9287 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9290 [(parallel [(set (match_operand 0 "" "")
9291 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9292 (match_operand 2 "" "")))
9293 (clobber (reg:DI 15))])
9294 (set (pc) (label_ref (match_operand 3 "" "")))]
9296 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9297 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9298 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9301 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9302 (match_operand 1 "" ""))
9303 (clobber (reg:DI 15))])
9304 (set (pc) (label_ref (match_operand 2 "" "")))]
9306 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9307 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9308 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9310 (define_expand "prologue"
9312 "flag_pic && current_function_uses_pic_offset_table"
9315 load_pic_register ();
9319 ;; We need to reload %l7 for -mflat -fpic,
9320 ;; otherwise %l7 should be preserved simply
9321 ;; by loading the function's register window
9322 (define_expand "exception_receiver"
9324 "TARGET_FLAT && flag_pic"
9327 load_pic_register ();
9332 (define_expand "builtin_setjmp_receiver"
9333 [(label_ref (match_operand 0 "" ""))]
9334 "TARGET_FLAT && flag_pic"
9337 load_pic_register ();
9342 [(trap_if (const_int 1) (const_int 5))]
9345 [(set_attr "type" "misc")])
9347 (define_expand "conditional_trap"
9348 [(trap_if (match_operator 0 "noov_compare_op"
9349 [(match_dup 2) (match_dup 3)])
9350 (match_operand:SI 1 "arith_operand" ""))]
9352 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9353 sparc_compare_op0, sparc_compare_op1);
9354 operands[3] = const0_rtx;")
9357 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9358 (match_operand:SI 1 "arith_operand" "rM"))]
9361 [(set_attr "type" "misc")])
9364 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9365 (match_operand:SI 1 "arith_operand" "rM"))]
9368 [(set_attr "type" "misc")])