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, 2002 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"))))
85 ;; If you add any new type here, please update ultrasparc_sched_reorder too.
87 "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"
88 (const_string "ialu"))
90 ;; true if branch/call has empty delay slot and will emit a nop in it
91 (define_attr "empty_delay_slot" "false,true"
92 (symbol_ref "empty_delay_slot (insn)"))
94 (define_attr "branch_type" "none,icc,fcc,reg" (const_string "none"))
96 (define_attr "pic" "false,true"
97 (symbol_ref "flag_pic != 0"))
99 ;; Length (in # of insns).
100 (define_attr "length" ""
101 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
102 (if_then_else (eq_attr "empty_delay_slot" "true")
105 (eq_attr "branch_type" "icc")
106 (if_then_else (match_operand 0 "noov_compare64_op" "")
107 (if_then_else (lt (pc) (match_dup 1))
108 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
109 (if_then_else (eq_attr "empty_delay_slot" "true")
112 (if_then_else (eq_attr "empty_delay_slot" "true")
115 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
116 (if_then_else (eq_attr "empty_delay_slot" "true")
119 (if_then_else (eq_attr "empty_delay_slot" "true")
122 (if_then_else (eq_attr "empty_delay_slot" "true")
125 (eq_attr "branch_type" "fcc")
126 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
127 (if_then_else (eq_attr "empty_delay_slot" "true")
130 (if_then_else (lt (pc) (match_dup 2))
131 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
132 (if_then_else (eq_attr "empty_delay_slot" "true")
135 (if_then_else (eq_attr "empty_delay_slot" "true")
138 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
139 (if_then_else (eq_attr "empty_delay_slot" "true")
142 (if_then_else (eq_attr "empty_delay_slot" "true")
145 (eq_attr "branch_type" "reg")
146 (if_then_else (lt (pc) (match_dup 2))
147 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
148 (if_then_else (eq_attr "empty_delay_slot" "true")
151 (if_then_else (eq_attr "empty_delay_slot" "true")
154 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
155 (if_then_else (eq_attr "empty_delay_slot" "true")
158 (if_then_else (eq_attr "empty_delay_slot" "true")
164 (define_attr "fptype" "single,double" (const_string "single"))
166 (define_asm_attributes
167 [(set_attr "length" "2")
168 (set_attr "type" "multi")])
170 ;; Attributes for instruction and branch scheduling
172 (define_attr "in_call_delay" "false,true"
173 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
174 (const_string "false")
175 (eq_attr "type" "load,fpload,store,fpstore")
176 (if_then_else (eq_attr "length" "1")
177 (const_string "true")
178 (const_string "false"))]
179 (if_then_else (eq_attr "length" "1")
180 (const_string "true")
181 (const_string "false"))))
183 (define_delay (eq_attr "type" "call")
184 [(eq_attr "in_call_delay" "true") (nil) (nil)])
186 (define_attr "eligible_for_sibcall_delay" "false,true"
187 (symbol_ref "eligible_for_sibcall_delay (insn)"))
189 (define_delay (eq_attr "type" "sibcall")
190 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
192 (define_attr "leaf_function" "false,true"
193 (const (symbol_ref "current_function_uses_only_leaf_regs")))
195 (define_attr "eligible_for_return_delay" "false,true"
196 (symbol_ref "eligible_for_return_delay (insn)"))
198 (define_attr "in_return_delay" "false,true"
199 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
200 (eq_attr "length" "1"))
201 (eq_attr "leaf_function" "false"))
202 (eq_attr "eligible_for_return_delay" "false"))
203 (const_string "true")
204 (const_string "false")))
206 (define_delay (and (eq_attr "type" "return")
207 (eq_attr "isa" "v9"))
208 [(eq_attr "in_return_delay" "true") (nil) (nil)])
210 ;; ??? Should implement the notion of predelay slots for floating point
211 ;; branches. This would allow us to remove the nop always inserted before
212 ;; a floating point branch.
214 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
215 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
216 ;; This is because doing so will add several pipeline stalls to the path
217 ;; that the load/store did not come from. Unfortunately, there is no way
218 ;; to prevent fill_eager_delay_slots from using load/store without completely
219 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
220 ;; because it prevents us from moving back the final store of inner loops.
222 (define_attr "in_branch_delay" "false,true"
223 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
224 (eq_attr "length" "1"))
225 (const_string "true")
226 (const_string "false")))
228 (define_attr "in_uncond_branch_delay" "false,true"
229 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
230 (eq_attr "length" "1"))
231 (const_string "true")
232 (const_string "false")))
234 (define_attr "in_annul_branch_delay" "false,true"
235 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
236 (eq_attr "length" "1"))
237 (const_string "true")
238 (const_string "false")))
240 (define_delay (eq_attr "type" "branch")
241 [(eq_attr "in_branch_delay" "true")
242 (nil) (eq_attr "in_annul_branch_delay" "true")])
244 (define_delay (eq_attr "type" "uncond_branch")
245 [(eq_attr "in_uncond_branch_delay" "true")
248 ;; Function units of the SPARC
250 ;; (define_function_unit {name} {num-units} {n-users} {test}
251 ;; {ready-delay} {issue-delay} [{conflict-list}])
254 ;; (Noted only for documentation; units that take one cycle do not need to
257 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
260 ;; ---- cypress CY7C602 scheduling:
261 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
263 (define_function_unit "memory" 1 0
264 (and (eq_attr "cpu" "cypress")
265 (eq_attr "type" "load,sload,fpload"))
268 ;; SPARC has two floating-point units: the FP ALU,
269 ;; and the FP MUL/DIV/SQRT unit.
270 ;; Instruction timings on the CY7C602 are as follows
284 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
285 ;; More insns cause the chip to stall.
287 (define_function_unit "fp_alu" 1 0
288 (and (eq_attr "cpu" "cypress")
289 (eq_attr "type" "fp,fpmove"))
292 (define_function_unit "fp_mds" 1 0
293 (and (eq_attr "cpu" "cypress")
294 (eq_attr "type" "fpmul"))
297 (define_function_unit "fp_mds" 1 0
298 (and (eq_attr "cpu" "cypress")
299 (eq_attr "type" "fpdivs,fpdivd"))
302 (define_function_unit "fp_mds" 1 0
303 (and (eq_attr "cpu" "cypress")
304 (eq_attr "type" "fpsqrts,fpsqrtd"))
307 ;; ----- The TMS390Z55 scheduling
308 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
309 ;; one ld/st, one fp.
310 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
312 (define_function_unit "memory" 1 0
313 (and (eq_attr "cpu" "supersparc")
314 (eq_attr "type" "load,sload"))
317 (define_function_unit "memory" 1 0
318 (and (eq_attr "cpu" "supersparc")
319 (eq_attr "type" "fpload"))
322 (define_function_unit "memory" 1 0
323 (and (eq_attr "cpu" "supersparc")
324 (eq_attr "type" "store,fpstore"))
327 (define_function_unit "shift" 1 0
328 (and (eq_attr "cpu" "supersparc")
329 (eq_attr "type" "shift"))
332 ;; There are only two write ports to the integer register file
333 ;; A store also uses a write port
335 (define_function_unit "iwport" 2 0
336 (and (eq_attr "cpu" "supersparc")
337 (eq_attr "type" "load,sload,store,shift,ialu"))
340 ;; Timings; throughput/latency
341 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
349 (define_function_unit "fp_alu" 1 0
350 (and (eq_attr "cpu" "supersparc")
351 (eq_attr "type" "fp,fpmove,fpcmp"))
354 (define_function_unit "fp_mds" 1 0
355 (and (eq_attr "cpu" "supersparc")
356 (eq_attr "type" "fpmul"))
359 (define_function_unit "fp_mds" 1 0
360 (and (eq_attr "cpu" "supersparc")
361 (eq_attr "type" "fpdivs"))
364 (define_function_unit "fp_mds" 1 0
365 (and (eq_attr "cpu" "supersparc")
366 (eq_attr "type" "fpdivd"))
369 (define_function_unit "fp_mds" 1 0
370 (and (eq_attr "cpu" "supersparc")
371 (eq_attr "type" "fpsqrts,fpsqrtd"))
374 (define_function_unit "fp_mds" 1 0
375 (and (eq_attr "cpu" "supersparc")
376 (eq_attr "type" "imul"))
379 ;; ----- hypersparc/sparclite86x scheduling
380 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
381 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
382 ;; II/FF case is only when loading a 32 bit hi/lo constant
383 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
384 ;; Memory delivers its result in one cycle to IU
386 (define_function_unit "memory" 1 0
387 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
388 (eq_attr "type" "load,sload,fpload"))
391 (define_function_unit "memory" 1 0
392 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
393 (eq_attr "type" "store,fpstore"))
396 (define_function_unit "sparclite86x_branch" 1 0
397 (and (eq_attr "cpu" "sparclite86x")
398 (eq_attr "type" "branch"))
401 ;; integer multiply insns
402 (define_function_unit "sparclite86x_shift" 1 0
403 (and (eq_attr "cpu" "sparclite86x")
404 (eq_attr "type" "shift"))
407 (define_function_unit "fp_alu" 1 0
408 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
409 (eq_attr "type" "fp,fpmove,fpcmp"))
412 (define_function_unit "fp_mds" 1 0
413 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
414 (eq_attr "type" "fpmul"))
417 (define_function_unit "fp_mds" 1 0
418 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
419 (eq_attr "type" "fpdivs"))
422 (define_function_unit "fp_mds" 1 0
423 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
424 (eq_attr "type" "fpdivd"))
427 (define_function_unit "fp_mds" 1 0
428 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
429 (eq_attr "type" "fpsqrts,fpsqrtd"))
432 (define_function_unit "fp_mds" 1 0
433 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
434 (eq_attr "type" "imul"))
437 ;; ----- sparclet tsc701 scheduling
438 ;; The tsc701 issues 1 insn per cycle.
439 ;; Results may be written back out of order.
441 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
443 (define_function_unit "tsc701_load" 4 1
444 (and (eq_attr "cpu" "tsc701")
445 (eq_attr "type" "load,sload"))
448 ;; Stores take 2(?) extra cycles to complete.
449 ;; It is desirable to not have any memory operation in the following 2 cycles.
450 ;; (??? or 2 memory ops in the case of std).
452 (define_function_unit "tsc701_store" 1 0
453 (and (eq_attr "cpu" "tsc701")
454 (eq_attr "type" "store"))
456 [(eq_attr "type" "load,sload,store")])
458 ;; The multiply unit has a latency of 5.
459 (define_function_unit "tsc701_mul" 1 0
460 (and (eq_attr "cpu" "tsc701")
461 (eq_attr "type" "imul"))
464 ;; ----- The UltraSPARC-1 scheduling
465 ;; UltraSPARC has two integer units. Shift instructions can only execute
466 ;; on IE0. Condition code setting instructions, call, and jmpl (including
467 ;; the ret and retl pseudo-instructions) can only execute on IE1.
468 ;; Branch on register uses IE1, but branch on condition code does not.
469 ;; Conditional moves take 2 cycles. No other instruction can issue in the
470 ;; same cycle as a conditional move.
471 ;; Multiply and divide take many cycles during which no other instructions
473 ;; Memory delivers its result in two cycles (except for signed loads,
474 ;; which take one cycle more). One memory instruction can be issued per
477 (define_function_unit "memory" 1 0
478 (and (eq_attr "cpu" "ultrasparc")
479 (eq_attr "type" "load,fpload"))
482 (define_function_unit "memory" 1 0
483 (and (eq_attr "cpu" "ultrasparc")
484 (eq_attr "type" "sload"))
487 (define_function_unit "memory" 1 0
488 (and (eq_attr "cpu" "ultrasparc")
489 (eq_attr "type" "store,fpstore"))
492 (define_function_unit "ieuN" 2 0
493 (and (eq_attr "cpu" "ultrasparc")
494 (eq_attr "type" "ialu,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
497 (define_function_unit "ieu0" 1 0
498 (and (eq_attr "cpu" "ultrasparc")
499 (eq_attr "type" "shift"))
502 (define_function_unit "ieu0" 1 0
503 (and (eq_attr "cpu" "ultrasparc")
504 (eq_attr "type" "cmove"))
507 (define_function_unit "ieu1" 1 0
508 (and (eq_attr "cpu" "ultrasparc")
509 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
512 (define_function_unit "cti" 1 0
513 (and (eq_attr "cpu" "ultrasparc")
514 (eq_attr "type" "branch"))
517 ;; Timings; throughput/latency
518 ;; FMOV 1/1 fmov, fabs, fneg
520 ;; FADD 1/3 add/sub, format conv, compar
526 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
528 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
529 ;; use the FPM multiplier for final rounding 3 cycles before the
530 ;; end of their latency and we have no real way to model that.
532 ;; ??? This is really bogus because the timings really depend upon
533 ;; who uses the result. We should record who the user is with
534 ;; more descriptive 'type' attribute names and account for these
535 ;; issues in ultrasparc_adjust_cost.
537 (define_function_unit "fadd" 1 0
538 (and (eq_attr "cpu" "ultrasparc")
539 (eq_attr "type" "fpmove"))
542 (define_function_unit "fadd" 1 0
543 (and (eq_attr "cpu" "ultrasparc")
544 (eq_attr "type" "fpcmove"))
547 (define_function_unit "fadd" 1 0
548 (and (eq_attr "cpu" "ultrasparc")
549 (eq_attr "type" "fp"))
552 (define_function_unit "fadd" 1 0
553 (and (eq_attr "cpu" "ultrasparc")
554 (eq_attr "type" "fpcmp"))
557 (define_function_unit "fmul" 1 0
558 (and (eq_attr "cpu" "ultrasparc")
559 (eq_attr "type" "fpmul"))
562 (define_function_unit "fadd" 1 0
563 (and (eq_attr "cpu" "ultrasparc")
564 (eq_attr "type" "fpcmove"))
567 (define_function_unit "fdiv" 1 0
568 (and (eq_attr "cpu" "ultrasparc")
569 (eq_attr "type" "fpdivs"))
572 (define_function_unit "fdiv" 1 0
573 (and (eq_attr "cpu" "ultrasparc")
574 (eq_attr "type" "fpdivd"))
577 (define_function_unit "fdiv" 1 0
578 (and (eq_attr "cpu" "ultrasparc")
579 (eq_attr "type" "fpsqrts"))
582 (define_function_unit "fdiv" 1 0
583 (and (eq_attr "cpu" "ultrasparc")
584 (eq_attr "type" "fpsqrtd"))
587 ;; Compare instructions.
588 ;; This controls RTL generation and register allocation.
590 ;; We generate RTL for comparisons and branches by having the cmpxx
591 ;; patterns store away the operands. Then, the scc and bcc patterns
592 ;; emit RTL for both the compare and the branch.
594 ;; We do this because we want to generate different code for an sne and
595 ;; seq insn. In those cases, if the second operand of the compare is not
596 ;; const0_rtx, we want to compute the xor of the two operands and test
599 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
600 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
601 ;; insns that actually require more than one machine instruction.
603 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
605 (define_expand "cmpsi"
607 (compare:CC (match_operand:SI 0 "register_operand" "")
608 (match_operand:SI 1 "arith_operand" "")))]
612 sparc_compare_op0 = operands[0];
613 sparc_compare_op1 = operands[1];
617 (define_expand "cmpdi"
619 (compare:CCX (match_operand:DI 0 "register_operand" "")
620 (match_operand:DI 1 "arith_double_operand" "")))]
624 sparc_compare_op0 = operands[0];
625 sparc_compare_op1 = operands[1];
629 (define_expand "cmpsf"
630 ;; The 96 here isn't ever used by anyone.
632 (compare:CCFP (match_operand:SF 0 "register_operand" "")
633 (match_operand:SF 1 "register_operand" "")))]
637 sparc_compare_op0 = operands[0];
638 sparc_compare_op1 = operands[1];
642 (define_expand "cmpdf"
643 ;; The 96 here isn't ever used by anyone.
645 (compare:CCFP (match_operand:DF 0 "register_operand" "")
646 (match_operand:DF 1 "register_operand" "")))]
650 sparc_compare_op0 = operands[0];
651 sparc_compare_op1 = operands[1];
655 (define_expand "cmptf"
656 ;; The 96 here isn't ever used by anyone.
658 (compare:CCFP (match_operand:TF 0 "register_operand" "")
659 (match_operand:TF 1 "register_operand" "")))]
663 sparc_compare_op0 = operands[0];
664 sparc_compare_op1 = operands[1];
668 ;; Now the compare DEFINE_INSNs.
670 (define_insn "*cmpsi_insn"
672 (compare:CC (match_operand:SI 0 "register_operand" "r")
673 (match_operand:SI 1 "arith_operand" "rI")))]
676 [(set_attr "type" "compare")])
678 (define_insn "*cmpdi_sp64"
680 (compare:CCX (match_operand:DI 0 "register_operand" "r")
681 (match_operand:DI 1 "arith_double_operand" "rHI")))]
684 [(set_attr "type" "compare")])
686 (define_insn "*cmpsf_fpe"
687 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
688 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
689 (match_operand:SF 2 "register_operand" "f")))]
694 return \"fcmpes\\t%0, %1, %2\";
695 return \"fcmpes\\t%1, %2\";
697 [(set_attr "type" "fpcmp")])
699 (define_insn "*cmpdf_fpe"
700 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
701 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
702 (match_operand:DF 2 "register_operand" "e")))]
707 return \"fcmped\\t%0, %1, %2\";
708 return \"fcmped\\t%1, %2\";
710 [(set_attr "type" "fpcmp")
711 (set_attr "fptype" "double")])
713 (define_insn "*cmptf_fpe"
714 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
715 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
716 (match_operand:TF 2 "register_operand" "e")))]
717 "TARGET_FPU && TARGET_HARD_QUAD"
721 return \"fcmpeq\\t%0, %1, %2\";
722 return \"fcmpeq\\t%1, %2\";
724 [(set_attr "type" "fpcmp")])
726 (define_insn "*cmpsf_fp"
727 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
728 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
729 (match_operand:SF 2 "register_operand" "f")))]
734 return \"fcmps\\t%0, %1, %2\";
735 return \"fcmps\\t%1, %2\";
737 [(set_attr "type" "fpcmp")])
739 (define_insn "*cmpdf_fp"
740 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
741 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
742 (match_operand:DF 2 "register_operand" "e")))]
747 return \"fcmpd\\t%0, %1, %2\";
748 return \"fcmpd\\t%1, %2\";
750 [(set_attr "type" "fpcmp")
751 (set_attr "fptype" "double")])
753 (define_insn "*cmptf_fp"
754 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
755 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
756 (match_operand:TF 2 "register_operand" "e")))]
757 "TARGET_FPU && TARGET_HARD_QUAD"
761 return \"fcmpq\\t%0, %1, %2\";
762 return \"fcmpq\\t%1, %2\";
764 [(set_attr "type" "fpcmp")])
766 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
767 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
768 ;; the same code as v8 (the addx/subx method has more applications). The
769 ;; exception to this is "reg != 0" which can be done in one instruction on v9
770 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
773 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
774 ;; generate addcc/subcc instructions.
776 (define_expand "seqsi_special"
778 (xor:SI (match_operand:SI 1 "register_operand" "")
779 (match_operand:SI 2 "register_operand" "")))
780 (parallel [(set (match_operand:SI 0 "register_operand" "")
781 (eq:SI (match_dup 3) (const_int 0)))
782 (clobber (reg:CC 100))])]
784 "{ operands[3] = gen_reg_rtx (SImode); }")
786 (define_expand "seqdi_special"
788 (xor:DI (match_operand:DI 1 "register_operand" "")
789 (match_operand:DI 2 "register_operand" "")))
790 (set (match_operand:DI 0 "register_operand" "")
791 (eq:DI (match_dup 3) (const_int 0)))]
793 "{ operands[3] = gen_reg_rtx (DImode); }")
795 (define_expand "snesi_special"
797 (xor:SI (match_operand:SI 1 "register_operand" "")
798 (match_operand:SI 2 "register_operand" "")))
799 (parallel [(set (match_operand:SI 0 "register_operand" "")
800 (ne:SI (match_dup 3) (const_int 0)))
801 (clobber (reg:CC 100))])]
803 "{ operands[3] = gen_reg_rtx (SImode); }")
805 (define_expand "snedi_special"
807 (xor:DI (match_operand:DI 1 "register_operand" "")
808 (match_operand:DI 2 "register_operand" "")))
809 (set (match_operand:DI 0 "register_operand" "")
810 (ne:DI (match_dup 3) (const_int 0)))]
812 "{ operands[3] = gen_reg_rtx (DImode); }")
814 (define_expand "seqdi_special_trunc"
816 (xor:DI (match_operand:DI 1 "register_operand" "")
817 (match_operand:DI 2 "register_operand" "")))
818 (set (match_operand:SI 0 "register_operand" "")
819 (eq:SI (match_dup 3) (const_int 0)))]
821 "{ operands[3] = gen_reg_rtx (DImode); }")
823 (define_expand "snedi_special_trunc"
825 (xor:DI (match_operand:DI 1 "register_operand" "")
826 (match_operand:DI 2 "register_operand" "")))
827 (set (match_operand:SI 0 "register_operand" "")
828 (ne:SI (match_dup 3) (const_int 0)))]
830 "{ operands[3] = gen_reg_rtx (DImode); }")
832 (define_expand "seqsi_special_extend"
834 (xor:SI (match_operand:SI 1 "register_operand" "")
835 (match_operand:SI 2 "register_operand" "")))
836 (parallel [(set (match_operand:DI 0 "register_operand" "")
837 (eq:DI (match_dup 3) (const_int 0)))
838 (clobber (reg:CC 100))])]
840 "{ operands[3] = gen_reg_rtx (SImode); }")
842 (define_expand "snesi_special_extend"
844 (xor:SI (match_operand:SI 1 "register_operand" "")
845 (match_operand:SI 2 "register_operand" "")))
846 (parallel [(set (match_operand:DI 0 "register_operand" "")
847 (ne:DI (match_dup 3) (const_int 0)))
848 (clobber (reg:CC 100))])]
850 "{ operands[3] = gen_reg_rtx (SImode); }")
852 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
853 ;; However, the code handles both SImode and DImode.
855 [(set (match_operand:SI 0 "intreg_operand" "")
856 (eq:SI (match_dup 1) (const_int 0)))]
860 if (GET_MODE (sparc_compare_op0) == SImode)
864 if (GET_MODE (operands[0]) == SImode)
865 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
867 else if (! TARGET_ARCH64)
870 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
875 else if (GET_MODE (sparc_compare_op0) == DImode)
881 else if (GET_MODE (operands[0]) == SImode)
882 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
885 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
890 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
892 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
893 emit_jump_insn (gen_sne (operands[0]));
898 if (gen_v9_scc (EQ, operands))
905 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
906 ;; However, the code handles both SImode and DImode.
908 [(set (match_operand:SI 0 "intreg_operand" "")
909 (ne:SI (match_dup 1) (const_int 0)))]
913 if (GET_MODE (sparc_compare_op0) == SImode)
917 if (GET_MODE (operands[0]) == SImode)
918 pat = gen_snesi_special (operands[0], sparc_compare_op0,
920 else if (! TARGET_ARCH64)
923 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
928 else if (GET_MODE (sparc_compare_op0) == DImode)
934 else if (GET_MODE (operands[0]) == SImode)
935 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
938 pat = gen_snedi_special (operands[0], sparc_compare_op0,
943 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
945 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
946 emit_jump_insn (gen_sne (operands[0]));
951 if (gen_v9_scc (NE, operands))
959 [(set (match_operand:SI 0 "intreg_operand" "")
960 (gt:SI (match_dup 1) (const_int 0)))]
964 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
966 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
967 emit_jump_insn (gen_sne (operands[0]));
972 if (gen_v9_scc (GT, operands))
980 [(set (match_operand:SI 0 "intreg_operand" "")
981 (lt:SI (match_dup 1) (const_int 0)))]
985 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
987 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
988 emit_jump_insn (gen_sne (operands[0]));
993 if (gen_v9_scc (LT, operands))
1000 (define_expand "sge"
1001 [(set (match_operand:SI 0 "intreg_operand" "")
1002 (ge:SI (match_dup 1) (const_int 0)))]
1006 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1008 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1009 emit_jump_insn (gen_sne (operands[0]));
1014 if (gen_v9_scc (GE, operands))
1021 (define_expand "sle"
1022 [(set (match_operand:SI 0 "intreg_operand" "")
1023 (le:SI (match_dup 1) (const_int 0)))]
1027 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1029 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1030 emit_jump_insn (gen_sne (operands[0]));
1035 if (gen_v9_scc (LE, operands))
1042 (define_expand "sgtu"
1043 [(set (match_operand:SI 0 "intreg_operand" "")
1044 (gtu:SI (match_dup 1) (const_int 0)))]
1052 /* We can do ltu easily, so if both operands are registers, swap them and
1054 if ((GET_CODE (sparc_compare_op0) == REG
1055 || GET_CODE (sparc_compare_op0) == SUBREG)
1056 && (GET_CODE (sparc_compare_op1) == REG
1057 || GET_CODE (sparc_compare_op1) == SUBREG))
1059 tem = sparc_compare_op0;
1060 sparc_compare_op0 = sparc_compare_op1;
1061 sparc_compare_op1 = tem;
1062 pat = gen_sltu (operands[0]);
1063 if (pat == NULL_RTX)
1071 if (gen_v9_scc (GTU, operands))
1077 (define_expand "sltu"
1078 [(set (match_operand:SI 0 "intreg_operand" "")
1079 (ltu:SI (match_dup 1) (const_int 0)))]
1085 if (gen_v9_scc (LTU, operands))
1088 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1091 (define_expand "sgeu"
1092 [(set (match_operand:SI 0 "intreg_operand" "")
1093 (geu:SI (match_dup 1) (const_int 0)))]
1099 if (gen_v9_scc (GEU, operands))
1102 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1105 (define_expand "sleu"
1106 [(set (match_operand:SI 0 "intreg_operand" "")
1107 (leu:SI (match_dup 1) (const_int 0)))]
1115 /* We can do geu easily, so if both operands are registers, swap them and
1117 if ((GET_CODE (sparc_compare_op0) == REG
1118 || GET_CODE (sparc_compare_op0) == SUBREG)
1119 && (GET_CODE (sparc_compare_op1) == REG
1120 || GET_CODE (sparc_compare_op1) == SUBREG))
1122 tem = sparc_compare_op0;
1123 sparc_compare_op0 = sparc_compare_op1;
1124 sparc_compare_op1 = tem;
1125 pat = gen_sgeu (operands[0]);
1126 if (pat == NULL_RTX)
1134 if (gen_v9_scc (LEU, operands))
1140 ;; Now the DEFINE_INSNs for the scc cases.
1142 ;; The SEQ and SNE patterns are special because they can be done
1143 ;; without any branching and do not involve a COMPARE. We want
1144 ;; them to always use the splitz below so the results can be
1147 (define_insn "*snesi_zero"
1148 [(set (match_operand:SI 0 "register_operand" "=r")
1149 (ne:SI (match_operand:SI 1 "register_operand" "r")
1151 (clobber (reg:CC 100))]
1154 [(set_attr "length" "2")])
1157 [(set (match_operand:SI 0 "register_operand" "")
1158 (ne:SI (match_operand:SI 1 "register_operand" "")
1160 (clobber (reg:CC 100))]
1162 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1164 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1167 (define_insn "*neg_snesi_zero"
1168 [(set (match_operand:SI 0 "register_operand" "=r")
1169 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1171 (clobber (reg:CC 100))]
1174 [(set_attr "length" "2")])
1177 [(set (match_operand:SI 0 "register_operand" "")
1178 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1180 (clobber (reg:CC 100))]
1182 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1184 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1187 (define_insn "*snesi_zero_extend"
1188 [(set (match_operand:DI 0 "register_operand" "=r")
1189 (ne:DI (match_operand:SI 1 "register_operand" "r")
1191 (clobber (reg:CC 100))]
1194 [(set_attr "length" "2")])
1197 [(set (match_operand:DI 0 "register_operand" "")
1198 (ne:DI (match_operand:SI 1 "register_operand" "")
1200 (clobber (reg:CC 100))]
1202 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1204 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1206 (ltu:SI (reg:CC_NOOV 100)
1210 (define_insn "*snedi_zero"
1211 [(set (match_operand:DI 0 "register_operand" "=&r")
1212 (ne:DI (match_operand:DI 1 "register_operand" "r")
1216 [(set_attr "length" "2")])
1219 [(set (match_operand:DI 0 "register_operand" "")
1220 (ne:DI (match_operand:DI 1 "register_operand" "")
1223 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1224 [(set (match_dup 0) (const_int 0))
1225 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1231 (define_insn "*neg_snedi_zero"
1232 [(set (match_operand:DI 0 "register_operand" "=&r")
1233 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1237 [(set_attr "length" "2")])
1240 [(set (match_operand:DI 0 "register_operand" "")
1241 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1244 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1245 [(set (match_dup 0) (const_int 0))
1246 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1252 (define_insn "*snedi_zero_trunc"
1253 [(set (match_operand:SI 0 "register_operand" "=&r")
1254 (ne:SI (match_operand:DI 1 "register_operand" "r")
1258 [(set_attr "length" "2")])
1261 [(set (match_operand:SI 0 "register_operand" "")
1262 (ne:SI (match_operand:DI 1 "register_operand" "")
1265 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1266 [(set (match_dup 0) (const_int 0))
1267 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1273 (define_insn "*seqsi_zero"
1274 [(set (match_operand:SI 0 "register_operand" "=r")
1275 (eq:SI (match_operand:SI 1 "register_operand" "r")
1277 (clobber (reg:CC 100))]
1280 [(set_attr "length" "2")])
1283 [(set (match_operand:SI 0 "register_operand" "")
1284 (eq:SI (match_operand:SI 1 "register_operand" "")
1286 (clobber (reg:CC 100))]
1288 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1290 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1293 (define_insn "*neg_seqsi_zero"
1294 [(set (match_operand:SI 0 "register_operand" "=r")
1295 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1297 (clobber (reg:CC 100))]
1300 [(set_attr "length" "2")])
1303 [(set (match_operand:SI 0 "register_operand" "")
1304 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1306 (clobber (reg:CC 100))]
1308 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1310 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1313 (define_insn "*seqsi_zero_extend"
1314 [(set (match_operand:DI 0 "register_operand" "=r")
1315 (eq:DI (match_operand:SI 1 "register_operand" "r")
1317 (clobber (reg:CC 100))]
1320 [(set_attr "length" "2")])
1323 [(set (match_operand:DI 0 "register_operand" "")
1324 (eq:DI (match_operand:SI 1 "register_operand" "")
1326 (clobber (reg:CC 100))]
1328 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1330 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1332 (ltu:SI (reg:CC_NOOV 100)
1336 (define_insn "*seqdi_zero"
1337 [(set (match_operand:DI 0 "register_operand" "=&r")
1338 (eq:DI (match_operand:DI 1 "register_operand" "r")
1342 [(set_attr "length" "2")])
1345 [(set (match_operand:DI 0 "register_operand" "")
1346 (eq:DI (match_operand:DI 1 "register_operand" "")
1349 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1350 [(set (match_dup 0) (const_int 0))
1351 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1357 (define_insn "*neg_seqdi_zero"
1358 [(set (match_operand:DI 0 "register_operand" "=&r")
1359 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1363 [(set_attr "length" "2")])
1366 [(set (match_operand:DI 0 "register_operand" "")
1367 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1370 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1371 [(set (match_dup 0) (const_int 0))
1372 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1378 (define_insn "*seqdi_zero_trunc"
1379 [(set (match_operand:SI 0 "register_operand" "=&r")
1380 (eq:SI (match_operand:DI 1 "register_operand" "r")
1384 [(set_attr "length" "2")])
1387 [(set (match_operand:SI 0 "register_operand" "")
1388 (eq:SI (match_operand:DI 1 "register_operand" "")
1391 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1392 [(set (match_dup 0) (const_int 0))
1393 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1399 ;; We can also do (x + (i == 0)) and related, so put them in.
1400 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1403 (define_insn "*x_plus_i_ne_0"
1404 [(set (match_operand:SI 0 "register_operand" "=r")
1405 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1407 (match_operand:SI 2 "register_operand" "r")))
1408 (clobber (reg:CC 100))]
1411 [(set_attr "length" "2")])
1414 [(set (match_operand:SI 0 "register_operand" "")
1415 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1417 (match_operand:SI 2 "register_operand" "")))
1418 (clobber (reg:CC 100))]
1420 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1422 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1426 (define_insn "*x_minus_i_ne_0"
1427 [(set (match_operand:SI 0 "register_operand" "=r")
1428 (minus:SI (match_operand:SI 2 "register_operand" "r")
1429 (ne:SI (match_operand:SI 1 "register_operand" "r")
1431 (clobber (reg:CC 100))]
1434 [(set_attr "length" "2")])
1437 [(set (match_operand:SI 0 "register_operand" "")
1438 (minus:SI (match_operand:SI 2 "register_operand" "")
1439 (ne:SI (match_operand:SI 1 "register_operand" "")
1441 (clobber (reg:CC 100))]
1443 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1445 (set (match_dup 0) (minus:SI (match_dup 2)
1446 (ltu:SI (reg:CC 100) (const_int 0))))]
1449 (define_insn "*x_plus_i_eq_0"
1450 [(set (match_operand:SI 0 "register_operand" "=r")
1451 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1453 (match_operand:SI 2 "register_operand" "r")))
1454 (clobber (reg:CC 100))]
1457 [(set_attr "length" "2")])
1460 [(set (match_operand:SI 0 "register_operand" "")
1461 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1463 (match_operand:SI 2 "register_operand" "")))
1464 (clobber (reg:CC 100))]
1466 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1468 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1472 (define_insn "*x_minus_i_eq_0"
1473 [(set (match_operand:SI 0 "register_operand" "=r")
1474 (minus:SI (match_operand:SI 2 "register_operand" "r")
1475 (eq:SI (match_operand:SI 1 "register_operand" "r")
1477 (clobber (reg:CC 100))]
1480 [(set_attr "length" "2")])
1483 [(set (match_operand:SI 0 "register_operand" "")
1484 (minus:SI (match_operand:SI 2 "register_operand" "")
1485 (eq:SI (match_operand:SI 1 "register_operand" "")
1487 (clobber (reg:CC 100))]
1489 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1491 (set (match_dup 0) (minus:SI (match_dup 2)
1492 (geu:SI (reg:CC 100) (const_int 0))))]
1495 ;; We can also do GEU and LTU directly, but these operate after a compare.
1496 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1499 (define_insn "*sltu_insn"
1500 [(set (match_operand:SI 0 "register_operand" "=r")
1501 (ltu:SI (reg:CC 100) (const_int 0)))]
1503 "addx\\t%%g0, 0, %0"
1504 [(set_attr "type" "misc")])
1506 (define_insn "*neg_sltu_insn"
1507 [(set (match_operand:SI 0 "register_operand" "=r")
1508 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1510 "subx\\t%%g0, 0, %0"
1511 [(set_attr "type" "misc")])
1513 ;; ??? Combine should canonicalize these next two to the same pattern.
1514 (define_insn "*neg_sltu_minus_x"
1515 [(set (match_operand:SI 0 "register_operand" "=r")
1516 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1517 (match_operand:SI 1 "arith_operand" "rI")))]
1519 "subx\\t%%g0, %1, %0"
1520 [(set_attr "type" "misc")])
1522 (define_insn "*neg_sltu_plus_x"
1523 [(set (match_operand:SI 0 "register_operand" "=r")
1524 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1525 (match_operand:SI 1 "arith_operand" "rI"))))]
1527 "subx\\t%%g0, %1, %0"
1528 [(set_attr "type" "misc")])
1530 (define_insn "*sgeu_insn"
1531 [(set (match_operand:SI 0 "register_operand" "=r")
1532 (geu:SI (reg:CC 100) (const_int 0)))]
1534 "subx\\t%%g0, -1, %0"
1535 [(set_attr "type" "misc")])
1537 (define_insn "*neg_sgeu_insn"
1538 [(set (match_operand:SI 0 "register_operand" "=r")
1539 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1541 "addx\\t%%g0, -1, %0"
1542 [(set_attr "type" "misc")])
1544 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1545 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1548 (define_insn "*sltu_plus_x"
1549 [(set (match_operand:SI 0 "register_operand" "=r")
1550 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1551 (match_operand:SI 1 "arith_operand" "rI")))]
1553 "addx\\t%%g0, %1, %0"
1554 [(set_attr "type" "misc")])
1556 (define_insn "*sltu_plus_x_plus_y"
1557 [(set (match_operand:SI 0 "register_operand" "=r")
1558 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1559 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1560 (match_operand:SI 2 "arith_operand" "rI"))))]
1563 [(set_attr "type" "misc")])
1565 (define_insn "*x_minus_sltu"
1566 [(set (match_operand:SI 0 "register_operand" "=r")
1567 (minus:SI (match_operand:SI 1 "register_operand" "r")
1568 (ltu:SI (reg:CC 100) (const_int 0))))]
1571 [(set_attr "type" "misc")])
1573 ;; ??? Combine should canonicalize these next two to the same pattern.
1574 (define_insn "*x_minus_y_minus_sltu"
1575 [(set (match_operand:SI 0 "register_operand" "=r")
1576 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1577 (match_operand:SI 2 "arith_operand" "rI"))
1578 (ltu:SI (reg:CC 100) (const_int 0))))]
1580 "subx\\t%r1, %2, %0"
1581 [(set_attr "type" "misc")])
1583 (define_insn "*x_minus_sltu_plus_y"
1584 [(set (match_operand:SI 0 "register_operand" "=r")
1585 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1586 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1587 (match_operand:SI 2 "arith_operand" "rI"))))]
1589 "subx\\t%r1, %2, %0"
1590 [(set_attr "type" "misc")])
1592 (define_insn "*sgeu_plus_x"
1593 [(set (match_operand:SI 0 "register_operand" "=r")
1594 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1595 (match_operand:SI 1 "register_operand" "r")))]
1598 [(set_attr "type" "misc")])
1600 (define_insn "*x_minus_sgeu"
1601 [(set (match_operand:SI 0 "register_operand" "=r")
1602 (minus:SI (match_operand:SI 1 "register_operand" "r")
1603 (geu:SI (reg:CC 100) (const_int 0))))]
1606 [(set_attr "type" "misc")])
1609 [(set (match_operand:SI 0 "register_operand" "")
1610 (match_operator:SI 2 "noov_compare_op"
1611 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1613 ;; 32 bit LTU/GEU are better implemented using addx/subx
1614 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1615 && (GET_MODE (operands[1]) == CCXmode
1616 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1617 [(set (match_dup 0) (const_int 0))
1619 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1625 ;; These control RTL generation for conditional jump insns
1627 ;; The quad-word fp compare library routines all return nonzero to indicate
1628 ;; true, which is different from the equivalent libgcc routines, so we must
1629 ;; handle them specially here.
1631 (define_expand "beq"
1633 (if_then_else (eq (match_dup 1) (const_int 0))
1634 (label_ref (match_operand 0 "" ""))
1639 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1640 && GET_CODE (sparc_compare_op0) == REG
1641 && GET_MODE (sparc_compare_op0) == DImode)
1643 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1646 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1648 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1649 emit_jump_insn (gen_bne (operands[0]));
1652 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1655 (define_expand "bne"
1657 (if_then_else (ne (match_dup 1) (const_int 0))
1658 (label_ref (match_operand 0 "" ""))
1663 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1664 && GET_CODE (sparc_compare_op0) == REG
1665 && GET_MODE (sparc_compare_op0) == DImode)
1667 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1670 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1672 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1673 emit_jump_insn (gen_bne (operands[0]));
1676 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1679 (define_expand "bgt"
1681 (if_then_else (gt (match_dup 1) (const_int 0))
1682 (label_ref (match_operand 0 "" ""))
1687 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1688 && GET_CODE (sparc_compare_op0) == REG
1689 && GET_MODE (sparc_compare_op0) == DImode)
1691 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1694 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1696 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1697 emit_jump_insn (gen_bne (operands[0]));
1700 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1703 (define_expand "bgtu"
1705 (if_then_else (gtu (match_dup 1) (const_int 0))
1706 (label_ref (match_operand 0 "" ""))
1710 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1713 (define_expand "blt"
1715 (if_then_else (lt (match_dup 1) (const_int 0))
1716 (label_ref (match_operand 0 "" ""))
1721 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1722 && GET_CODE (sparc_compare_op0) == REG
1723 && GET_MODE (sparc_compare_op0) == DImode)
1725 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1728 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1730 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1731 emit_jump_insn (gen_bne (operands[0]));
1734 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1737 (define_expand "bltu"
1739 (if_then_else (ltu (match_dup 1) (const_int 0))
1740 (label_ref (match_operand 0 "" ""))
1744 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1747 (define_expand "bge"
1749 (if_then_else (ge (match_dup 1) (const_int 0))
1750 (label_ref (match_operand 0 "" ""))
1755 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1756 && GET_CODE (sparc_compare_op0) == REG
1757 && GET_MODE (sparc_compare_op0) == DImode)
1759 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1762 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1764 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1765 emit_jump_insn (gen_bne (operands[0]));
1768 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1771 (define_expand "bgeu"
1773 (if_then_else (geu (match_dup 1) (const_int 0))
1774 (label_ref (match_operand 0 "" ""))
1778 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1781 (define_expand "ble"
1783 (if_then_else (le (match_dup 1) (const_int 0))
1784 (label_ref (match_operand 0 "" ""))
1789 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1790 && GET_CODE (sparc_compare_op0) == REG
1791 && GET_MODE (sparc_compare_op0) == DImode)
1793 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1796 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1798 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1799 emit_jump_insn (gen_bne (operands[0]));
1802 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1805 (define_expand "bleu"
1807 (if_then_else (leu (match_dup 1) (const_int 0))
1808 (label_ref (match_operand 0 "" ""))
1812 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1815 (define_expand "bunordered"
1817 (if_then_else (unordered (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,
1827 emit_jump_insn (gen_beq (operands[0]));
1830 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1834 (define_expand "bordered"
1836 (if_then_else (ordered (match_dup 1) (const_int 0))
1837 (label_ref (match_operand 0 "" ""))
1842 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1844 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1845 emit_jump_insn (gen_bne (operands[0]));
1848 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1852 (define_expand "bungt"
1854 (if_then_else (ungt (match_dup 1) (const_int 0))
1855 (label_ref (match_operand 0 "" ""))
1860 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1862 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1863 emit_jump_insn (gen_bgt (operands[0]));
1866 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1869 (define_expand "bunlt"
1871 (if_then_else (unlt (match_dup 1) (const_int 0))
1872 (label_ref (match_operand 0 "" ""))
1877 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1879 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1880 emit_jump_insn (gen_bne (operands[0]));
1883 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1886 (define_expand "buneq"
1888 (if_then_else (uneq (match_dup 1) (const_int 0))
1889 (label_ref (match_operand 0 "" ""))
1894 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1896 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1897 emit_jump_insn (gen_beq (operands[0]));
1900 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1903 (define_expand "bunge"
1905 (if_then_else (unge (match_dup 1) (const_int 0))
1906 (label_ref (match_operand 0 "" ""))
1911 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1913 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1914 emit_jump_insn (gen_bne (operands[0]));
1917 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1920 (define_expand "bunle"
1922 (if_then_else (unle (match_dup 1) (const_int 0))
1923 (label_ref (match_operand 0 "" ""))
1928 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1930 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1931 emit_jump_insn (gen_bne (operands[0]));
1934 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1937 (define_expand "bltgt"
1939 (if_then_else (ltgt (match_dup 1) (const_int 0))
1940 (label_ref (match_operand 0 "" ""))
1945 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1947 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1948 emit_jump_insn (gen_bne (operands[0]));
1951 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1954 ;; Now match both normal and inverted jump.
1956 ;; XXX fpcmp nop braindamage
1957 (define_insn "*normal_branch"
1959 (if_then_else (match_operator 0 "noov_compare_op"
1960 [(reg 100) (const_int 0)])
1961 (label_ref (match_operand 1 "" ""))
1966 return output_cbranch (operands[0], operands[1], 1, 0,
1967 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1968 ! final_sequence, insn);
1970 [(set_attr "type" "branch")
1971 (set_attr "branch_type" "icc")])
1973 ;; XXX fpcmp nop braindamage
1974 (define_insn "*inverted_branch"
1976 (if_then_else (match_operator 0 "noov_compare_op"
1977 [(reg 100) (const_int 0)])
1979 (label_ref (match_operand 1 "" ""))))]
1983 return output_cbranch (operands[0], operands[1], 1, 1,
1984 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1985 ! final_sequence, insn);
1987 [(set_attr "type" "branch")
1988 (set_attr "branch_type" "icc")])
1990 ;; XXX fpcmp nop braindamage
1991 (define_insn "*normal_fp_branch"
1993 (if_then_else (match_operator 1 "comparison_operator"
1994 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1996 (label_ref (match_operand 2 "" ""))
2001 return output_cbranch (operands[1], operands[2], 2, 0,
2002 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2003 ! final_sequence, insn);
2005 [(set_attr "type" "branch")
2006 (set_attr "branch_type" "fcc")])
2008 ;; XXX fpcmp nop braindamage
2009 (define_insn "*inverted_fp_branch"
2011 (if_then_else (match_operator 1 "comparison_operator"
2012 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2015 (label_ref (match_operand 2 "" ""))))]
2019 return output_cbranch (operands[1], operands[2], 2, 1,
2020 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2021 ! final_sequence, insn);
2023 [(set_attr "type" "branch")
2024 (set_attr "branch_type" "fcc")])
2026 ;; XXX fpcmp nop braindamage
2027 (define_insn "*normal_fpe_branch"
2029 (if_then_else (match_operator 1 "comparison_operator"
2030 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2032 (label_ref (match_operand 2 "" ""))
2037 return output_cbranch (operands[1], operands[2], 2, 0,
2038 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2039 ! final_sequence, insn);
2041 [(set_attr "type" "branch")
2042 (set_attr "branch_type" "fcc")])
2044 ;; XXX fpcmp nop braindamage
2045 (define_insn "*inverted_fpe_branch"
2047 (if_then_else (match_operator 1 "comparison_operator"
2048 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2051 (label_ref (match_operand 2 "" ""))))]
2055 return output_cbranch (operands[1], operands[2], 2, 1,
2056 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2057 ! final_sequence, insn);
2059 [(set_attr "type" "branch")
2060 (set_attr "branch_type" "fcc")])
2062 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2063 ;; in the architecture.
2065 ;; There are no 32 bit brreg insns.
2068 (define_insn "*normal_int_branch_sp64"
2070 (if_then_else (match_operator 0 "v9_regcmp_op"
2071 [(match_operand:DI 1 "register_operand" "r")
2073 (label_ref (match_operand 2 "" ""))
2078 return output_v9branch (operands[0], operands[2], 1, 2, 0,
2079 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2080 ! final_sequence, insn);
2082 [(set_attr "type" "branch")
2083 (set_attr "branch_type" "reg")])
2086 (define_insn "*inverted_int_branch_sp64"
2088 (if_then_else (match_operator 0 "v9_regcmp_op"
2089 [(match_operand:DI 1 "register_operand" "r")
2092 (label_ref (match_operand 2 "" ""))))]
2096 return output_v9branch (operands[0], operands[2], 1, 2, 1,
2097 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2098 ! final_sequence, insn);
2100 [(set_attr "type" "branch")
2101 (set_attr "branch_type" "reg")])
2103 ;; Load program counter insns.
2105 (define_insn "get_pc"
2106 [(clobber (reg:SI 15))
2107 (set (match_operand 0 "register_operand" "=r")
2108 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2109 "flag_pic && REGNO (operands[0]) == 23"
2110 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2111 [(set_attr "type" "multi")
2112 (set_attr "length" "3")])
2114 ;; Currently unused...
2115 ;; (define_insn "get_pc_via_rdpc"
2116 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2119 ;; [(set_attr "type" "misc")])
2122 ;; Move instructions
2124 (define_expand "movqi"
2125 [(set (match_operand:QI 0 "general_operand" "")
2126 (match_operand:QI 1 "general_operand" ""))]
2130 /* Working with CONST_INTs is easier, so convert
2131 a double if needed. */
2132 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2134 operands[1] = GEN_INT (trunc_int_for_mode
2135 (CONST_DOUBLE_LOW (operands[1]), QImode));
2138 /* Handle sets of MEM first. */
2139 if (GET_CODE (operands[0]) == MEM)
2141 if (reg_or_0_operand (operands[1], QImode))
2144 if (! reload_in_progress)
2146 operands[0] = validize_mem (operands[0]);
2147 operands[1] = force_reg (QImode, operands[1]);
2151 /* Fixup PIC cases. */
2154 if (CONSTANT_P (operands[1])
2155 && pic_address_needs_scratch (operands[1]))
2156 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2158 if (symbolic_operand (operands[1], QImode))
2160 operands[1] = legitimize_pic_address (operands[1],
2162 (reload_in_progress ?
2169 /* All QI constants require only one insn, so proceed. */
2175 (define_insn "*movqi_insn"
2176 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2177 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2178 "(register_operand (operands[0], QImode)
2179 || reg_or_0_operand (operands[1], QImode))"
2184 [(set_attr "type" "*,load,store")])
2186 (define_expand "movhi"
2187 [(set (match_operand:HI 0 "general_operand" "")
2188 (match_operand:HI 1 "general_operand" ""))]
2192 /* Working with CONST_INTs is easier, so convert
2193 a double if needed. */
2194 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2195 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2197 /* Handle sets of MEM first. */
2198 if (GET_CODE (operands[0]) == MEM)
2200 if (reg_or_0_operand (operands[1], HImode))
2203 if (! reload_in_progress)
2205 operands[0] = validize_mem (operands[0]);
2206 operands[1] = force_reg (HImode, operands[1]);
2210 /* Fixup PIC cases. */
2213 if (CONSTANT_P (operands[1])
2214 && pic_address_needs_scratch (operands[1]))
2215 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2217 if (symbolic_operand (operands[1], HImode))
2219 operands[1] = legitimize_pic_address (operands[1],
2221 (reload_in_progress ?
2228 /* This makes sure we will not get rematched due to splittage. */
2229 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2231 else if (CONSTANT_P (operands[1])
2232 && GET_CODE (operands[1]) != HIGH
2233 && GET_CODE (operands[1]) != LO_SUM)
2235 sparc_emit_set_const32 (operands[0], operands[1]);
2242 (define_insn "*movhi_const64_special"
2243 [(set (match_operand:HI 0 "register_operand" "=r")
2244 (match_operand:HI 1 "const64_high_operand" ""))]
2246 "sethi\\t%%hi(%a1), %0")
2248 (define_insn "*movhi_insn"
2249 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2250 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2251 "(register_operand (operands[0], HImode)
2252 || reg_or_0_operand (operands[1], HImode))"
2255 sethi\\t%%hi(%a1), %0
2258 [(set_attr "type" "*,*,load,store")])
2260 ;; We always work with constants here.
2261 (define_insn "*movhi_lo_sum"
2262 [(set (match_operand:HI 0 "register_operand" "=r")
2263 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2264 (match_operand:HI 2 "arith_operand" "I")))]
2268 (define_expand "movsi"
2269 [(set (match_operand:SI 0 "general_operand" "")
2270 (match_operand:SI 1 "general_operand" ""))]
2274 /* Working with CONST_INTs is easier, so convert
2275 a double if needed. */
2276 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2277 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2279 /* Handle sets of MEM first. */
2280 if (GET_CODE (operands[0]) == MEM)
2282 if (reg_or_0_operand (operands[1], SImode))
2285 if (! reload_in_progress)
2287 operands[0] = validize_mem (operands[0]);
2288 operands[1] = force_reg (SImode, operands[1]);
2292 /* Fixup PIC cases. */
2295 if (CONSTANT_P (operands[1])
2296 && pic_address_needs_scratch (operands[1]))
2297 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2299 if (GET_CODE (operands[1]) == LABEL_REF)
2302 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2306 if (symbolic_operand (operands[1], SImode))
2308 operands[1] = legitimize_pic_address (operands[1],
2310 (reload_in_progress ?
2317 /* If we are trying to toss an integer constant into the
2318 FPU registers, force it into memory. */
2319 if (GET_CODE (operands[0]) == REG
2320 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2321 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2322 && CONSTANT_P (operands[1]))
2323 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2326 /* This makes sure we will not get rematched due to splittage. */
2327 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2329 else if (CONSTANT_P (operands[1])
2330 && GET_CODE (operands[1]) != HIGH
2331 && GET_CODE (operands[1]) != LO_SUM)
2333 sparc_emit_set_const32 (operands[0], operands[1]);
2340 ;; This is needed to show CSE exactly which bits are set
2341 ;; in a 64-bit register by sethi instructions.
2342 (define_insn "*movsi_const64_special"
2343 [(set (match_operand:SI 0 "register_operand" "=r")
2344 (match_operand:SI 1 "const64_high_operand" ""))]
2346 "sethi\\t%%hi(%a1), %0")
2348 (define_insn "*movsi_insn"
2349 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2350 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2351 "(register_operand (operands[0], SImode)
2352 || reg_or_0_operand (operands[1], SImode))"
2356 sethi\\t%%hi(%a1), %0
2363 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2365 (define_insn "*movsi_lo_sum"
2366 [(set (match_operand:SI 0 "register_operand" "=r")
2367 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2368 (match_operand:SI 2 "immediate_operand" "in")))]
2370 "or\\t%1, %%lo(%a2), %0")
2372 (define_insn "*movsi_high"
2373 [(set (match_operand:SI 0 "register_operand" "=r")
2374 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2376 "sethi\\t%%hi(%a1), %0")
2378 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2379 ;; so that CSE won't optimize the address computation away.
2380 (define_insn "movsi_lo_sum_pic"
2381 [(set (match_operand:SI 0 "register_operand" "=r")
2382 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2383 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2385 "or\\t%1, %%lo(%a2), %0")
2387 (define_insn "movsi_high_pic"
2388 [(set (match_operand:SI 0 "register_operand" "=r")
2389 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2390 "flag_pic && check_pic (1)"
2391 "sethi\\t%%hi(%a1), %0")
2393 (define_expand "movsi_pic_label_ref"
2394 [(set (match_dup 3) (high:SI
2395 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2397 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2398 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2399 (set (match_operand:SI 0 "register_operand" "=r")
2400 (minus:SI (match_dup 5) (match_dup 4)))]
2404 current_function_uses_pic_offset_table = 1;
2405 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2408 operands[3] = operands[0];
2409 operands[4] = operands[0];
2413 operands[3] = gen_reg_rtx (SImode);
2414 operands[4] = gen_reg_rtx (SImode);
2416 operands[5] = pic_offset_table_rtx;
2419 (define_insn "*movsi_high_pic_label_ref"
2420 [(set (match_operand:SI 0 "register_operand" "=r")
2422 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2423 (match_operand:SI 2 "" "")] 5)))]
2425 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2427 (define_insn "*movsi_lo_sum_pic_label_ref"
2428 [(set (match_operand:SI 0 "register_operand" "=r")
2429 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2430 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2431 (match_operand:SI 3 "" "")] 5)))]
2433 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2435 (define_expand "movdi"
2436 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2437 (match_operand:DI 1 "general_operand" ""))]
2441 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2442 if (GET_CODE (operands[1]) == CONST_DOUBLE
2443 #if HOST_BITS_PER_WIDE_INT == 32
2444 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2445 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2446 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2447 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2450 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2452 /* Handle MEM cases first. */
2453 if (GET_CODE (operands[0]) == MEM)
2455 /* If it's a REG, we can always do it.
2456 The const zero case is more complex, on v9
2457 we can always perform it. */
2458 if (register_operand (operands[1], DImode)
2460 && (operands[1] == const0_rtx)))
2463 if (! reload_in_progress)
2465 operands[0] = validize_mem (operands[0]);
2466 operands[1] = force_reg (DImode, operands[1]);
2472 if (CONSTANT_P (operands[1])
2473 && pic_address_needs_scratch (operands[1]))
2474 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2476 if (GET_CODE (operands[1]) == LABEL_REF)
2478 if (! TARGET_ARCH64)
2480 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2484 if (symbolic_operand (operands[1], DImode))
2486 operands[1] = legitimize_pic_address (operands[1],
2488 (reload_in_progress ?
2495 /* If we are trying to toss an integer constant into the
2496 FPU registers, force it into memory. */
2497 if (GET_CODE (operands[0]) == REG
2498 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2499 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2500 && CONSTANT_P (operands[1]))
2501 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2504 /* This makes sure we will not get rematched due to splittage. */
2505 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2507 else if (TARGET_ARCH64
2508 && CONSTANT_P (operands[1])
2509 && GET_CODE (operands[1]) != HIGH
2510 && GET_CODE (operands[1]) != LO_SUM)
2512 sparc_emit_set_const64 (operands[0], operands[1]);
2520 ;; Be careful, fmovd does not exist when !arch64.
2521 ;; We match MEM moves directly when we have correct even
2522 ;; numbered registers, but fall into splits otherwise.
2523 ;; The constraint ordering here is really important to
2524 ;; avoid insane problems in reload, especially for patterns
2527 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2528 ;; (const_int -5016)))
2532 (define_insn "*movdi_insn_sp32_v9"
2533 [(set (match_operand:DI 0 "nonimmediate_operand"
2534 "=m,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2535 (match_operand:DI 1 "input_operand"
2536 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2537 "! TARGET_ARCH64 && TARGET_V9
2538 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2552 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2553 (set_attr "length" "*,*,*,2,2,2,2,*,*,2,2,2")])
2555 (define_insn "*movdi_insn_sp32"
2556 [(set (match_operand:DI 0 "nonimmediate_operand"
2557 "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2558 (match_operand:DI 1 "input_operand"
2559 " U,T,r,o,i,r, f, T, o, f, f"))]
2561 && (register_operand (operands[0], DImode)
2562 || register_operand (operands[1], DImode))"
2575 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2576 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2578 ;; The following are generated by sparc_emit_set_const64
2579 (define_insn "*movdi_sp64_dbl"
2580 [(set (match_operand:DI 0 "register_operand" "=r")
2581 (match_operand:DI 1 "const64_operand" ""))]
2583 && HOST_BITS_PER_WIDE_INT != 64)"
2586 ;; This is needed to show CSE exactly which bits are set
2587 ;; in a 64-bit register by sethi instructions.
2588 (define_insn "*movdi_const64_special"
2589 [(set (match_operand:DI 0 "register_operand" "=r")
2590 (match_operand:DI 1 "const64_high_operand" ""))]
2592 "sethi\\t%%hi(%a1), %0")
2594 (define_insn "*movdi_insn_sp64_novis"
2595 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2596 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2597 "TARGET_ARCH64 && ! TARGET_VIS
2598 && (register_operand (operands[0], DImode)
2599 || reg_or_0_operand (operands[1], DImode))"
2602 sethi\\t%%hi(%a1), %0
2609 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2610 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2612 (define_insn "*movdi_insn_sp64_vis"
2613 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2614 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2615 "TARGET_ARCH64 && TARGET_VIS &&
2616 (register_operand (operands[0], DImode)
2617 || reg_or_0_operand (operands[1], DImode))"
2620 sethi\\t%%hi(%a1), %0
2628 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2629 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2631 (define_expand "movdi_pic_label_ref"
2632 [(set (match_dup 3) (high:DI
2633 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2635 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2636 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2637 (set (match_operand:DI 0 "register_operand" "=r")
2638 (minus:DI (match_dup 5) (match_dup 4)))]
2639 "TARGET_ARCH64 && flag_pic"
2642 current_function_uses_pic_offset_table = 1;
2643 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2646 operands[3] = operands[0];
2647 operands[4] = operands[0];
2651 operands[3] = gen_reg_rtx (DImode);
2652 operands[4] = gen_reg_rtx (DImode);
2654 operands[5] = pic_offset_table_rtx;
2657 (define_insn "*movdi_high_pic_label_ref"
2658 [(set (match_operand:DI 0 "register_operand" "=r")
2660 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2661 (match_operand:DI 2 "" "")] 5)))]
2662 "TARGET_ARCH64 && flag_pic"
2663 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2665 (define_insn "*movdi_lo_sum_pic_label_ref"
2666 [(set (match_operand:DI 0 "register_operand" "=r")
2667 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2668 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2669 (match_operand:DI 3 "" "")] 5)))]
2670 "TARGET_ARCH64 && flag_pic"
2671 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2673 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2674 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2676 (define_insn "movdi_lo_sum_pic"
2677 [(set (match_operand:DI 0 "register_operand" "=r")
2678 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2679 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2680 "TARGET_ARCH64 && flag_pic"
2681 "or\\t%1, %%lo(%a2), %0")
2683 (define_insn "movdi_high_pic"
2684 [(set (match_operand:DI 0 "register_operand" "=r")
2685 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2686 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2687 "sethi\\t%%hi(%a1), %0")
2689 (define_insn "*sethi_di_medlow_embmedany_pic"
2690 [(set (match_operand:DI 0 "register_operand" "=r")
2691 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2692 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2693 "sethi\\t%%hi(%a1), %0")
2695 (define_insn "*sethi_di_medlow"
2696 [(set (match_operand:DI 0 "register_operand" "=r")
2697 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2698 "TARGET_CM_MEDLOW && check_pic (1)"
2699 "sethi\\t%%hi(%a1), %0")
2701 (define_insn "*losum_di_medlow"
2702 [(set (match_operand:DI 0 "register_operand" "=r")
2703 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2704 (match_operand:DI 2 "symbolic_operand" "")))]
2706 "or\\t%1, %%lo(%a2), %0")
2708 (define_insn "seth44"
2709 [(set (match_operand:DI 0 "register_operand" "=r")
2710 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2712 "sethi\\t%%h44(%a1), %0")
2714 (define_insn "setm44"
2715 [(set (match_operand:DI 0 "register_operand" "=r")
2716 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2717 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2719 "or\\t%1, %%m44(%a2), %0")
2721 (define_insn "setl44"
2722 [(set (match_operand:DI 0 "register_operand" "=r")
2723 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2724 (match_operand:DI 2 "symbolic_operand" "")))]
2726 "or\\t%1, %%l44(%a2), %0")
2728 (define_insn "sethh"
2729 [(set (match_operand:DI 0 "register_operand" "=r")
2730 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2732 "sethi\\t%%hh(%a1), %0")
2734 (define_insn "setlm"
2735 [(set (match_operand:DI 0 "register_operand" "=r")
2736 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2738 "sethi\\t%%lm(%a1), %0")
2740 (define_insn "sethm"
2741 [(set (match_operand:DI 0 "register_operand" "=r")
2742 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2743 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2745 "or\\t%1, %%hm(%a2), %0")
2747 (define_insn "setlo"
2748 [(set (match_operand:DI 0 "register_operand" "=r")
2749 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2750 (match_operand:DI 2 "symbolic_operand" "")))]
2752 "or\\t%1, %%lo(%a2), %0")
2754 (define_insn "embmedany_sethi"
2755 [(set (match_operand:DI 0 "register_operand" "=r")
2756 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2757 "TARGET_CM_EMBMEDANY && check_pic (1)"
2758 "sethi\\t%%hi(%a1), %0")
2760 (define_insn "embmedany_losum"
2761 [(set (match_operand:DI 0 "register_operand" "=r")
2762 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2763 (match_operand:DI 2 "data_segment_operand" "")))]
2764 "TARGET_CM_EMBMEDANY"
2765 "add\\t%1, %%lo(%a2), %0")
2767 (define_insn "embmedany_brsum"
2768 [(set (match_operand:DI 0 "register_operand" "=r")
2769 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2770 "TARGET_CM_EMBMEDANY"
2773 (define_insn "embmedany_textuhi"
2774 [(set (match_operand:DI 0 "register_operand" "=r")
2775 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2776 "TARGET_CM_EMBMEDANY && check_pic (1)"
2777 "sethi\\t%%uhi(%a1), %0")
2779 (define_insn "embmedany_texthi"
2780 [(set (match_operand:DI 0 "register_operand" "=r")
2781 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2782 "TARGET_CM_EMBMEDANY && check_pic (1)"
2783 "sethi\\t%%hi(%a1), %0")
2785 (define_insn "embmedany_textulo"
2786 [(set (match_operand:DI 0 "register_operand" "=r")
2787 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2788 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2789 "TARGET_CM_EMBMEDANY"
2790 "or\\t%1, %%ulo(%a2), %0")
2792 (define_insn "embmedany_textlo"
2793 [(set (match_operand:DI 0 "register_operand" "=r")
2794 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2795 (match_operand:DI 2 "text_segment_operand" "")))]
2796 "TARGET_CM_EMBMEDANY"
2797 "or\\t%1, %%lo(%a2), %0")
2799 ;; Now some patterns to help reload out a bit.
2800 (define_expand "reload_indi"
2801 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2802 (match_operand:DI 1 "immediate_operand" "")
2803 (match_operand:TI 2 "register_operand" "=&r")])]
2805 || TARGET_CM_EMBMEDANY)
2809 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2813 (define_expand "reload_outdi"
2814 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2815 (match_operand:DI 1 "immediate_operand" "")
2816 (match_operand:TI 2 "register_operand" "=&r")])]
2818 || TARGET_CM_EMBMEDANY)
2822 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2826 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2828 [(set (match_operand:DI 0 "register_operand" "")
2829 (match_operand:DI 1 "const_int_operand" ""))]
2830 "! TARGET_ARCH64 && reload_completed"
2831 [(clobber (const_int 0))]
2834 #if HOST_BITS_PER_WIDE_INT == 32
2835 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2836 (INTVAL (operands[1]) < 0) ?
2839 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2842 unsigned int low, high;
2844 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2845 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2846 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2848 /* Slick... but this trick loses if this subreg constant part
2849 can be done in one insn. */
2850 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2851 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2852 gen_highpart (SImode, operands[0])));
2854 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2860 [(set (match_operand:DI 0 "register_operand" "")
2861 (match_operand:DI 1 "const_double_operand" ""))]
2862 "! TARGET_ARCH64 && reload_completed"
2863 [(clobber (const_int 0))]
2866 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2867 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2869 /* Slick... but this trick loses if this subreg constant part
2870 can be done in one insn. */
2871 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2872 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2873 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2875 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2876 gen_highpart (SImode, operands[0])));
2880 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2881 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2887 [(set (match_operand:DI 0 "register_operand" "")
2888 (match_operand:DI 1 "register_operand" ""))]
2889 "! TARGET_ARCH64 && reload_completed"
2890 [(clobber (const_int 0))]
2893 rtx set_dest = operands[0];
2894 rtx set_src = operands[1];
2898 dest1 = gen_highpart (SImode, set_dest);
2899 dest2 = gen_lowpart (SImode, set_dest);
2900 src1 = gen_highpart (SImode, set_src);
2901 src2 = gen_lowpart (SImode, set_src);
2903 /* Now emit using the real source and destination we found, swapping
2904 the order if we detect overlap. */
2905 if (reg_overlap_mentioned_p (dest1, src2))
2907 emit_insn (gen_movsi (dest2, src2));
2908 emit_insn (gen_movsi (dest1, src1));
2912 emit_insn (gen_movsi (dest1, src1));
2913 emit_insn (gen_movsi (dest2, src2));
2918 ;; Now handle the cases of memory moves from/to non-even
2919 ;; DI mode register pairs.
2921 [(set (match_operand:DI 0 "register_operand" "")
2922 (match_operand:DI 1 "memory_operand" ""))]
2925 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2926 [(clobber (const_int 0))]
2929 rtx word0 = adjust_address (operands[1], SImode, 0);
2930 rtx word1 = adjust_address (operands[1], SImode, 4);
2931 rtx high_part = gen_highpart (SImode, operands[0]);
2932 rtx low_part = gen_lowpart (SImode, operands[0]);
2934 if (reg_overlap_mentioned_p (high_part, word1))
2936 emit_insn (gen_movsi (low_part, word1));
2937 emit_insn (gen_movsi (high_part, word0));
2941 emit_insn (gen_movsi (high_part, word0));
2942 emit_insn (gen_movsi (low_part, word1));
2948 [(set (match_operand:DI 0 "memory_operand" "")
2949 (match_operand:DI 1 "register_operand" ""))]
2952 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2953 [(clobber (const_int 0))]
2956 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2957 gen_highpart (SImode, operands[1])));
2958 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2959 gen_lowpart (SImode, operands[1])));
2964 ;; Floating point move insns
2966 (define_insn "*movsf_insn_novis"
2967 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2968 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2969 "(TARGET_FPU && ! TARGET_VIS)
2970 && (register_operand (operands[0], SFmode)
2971 || register_operand (operands[1], SFmode)
2972 || fp_zero_operand (operands[1], SFmode))"
2975 if (GET_CODE (operands[1]) == CONST_DOUBLE
2976 && (which_alternative == 2
2977 || which_alternative == 3
2978 || which_alternative == 4))
2983 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2984 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2985 operands[1] = GEN_INT (i);
2988 switch (which_alternative)
2991 return \"fmovs\\t%1, %0\";
2993 return \"clr\\t%0\";
2995 return \"sethi\\t%%hi(%a1), %0\";
2997 return \"mov\\t%1, %0\";
3002 return \"ld\\t%1, %0\";
3005 return \"st\\t%r1, %0\";
3010 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3012 (define_insn "*movsf_insn_vis"
3013 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3014 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3015 "(TARGET_FPU && TARGET_VIS)
3016 && (register_operand (operands[0], SFmode)
3017 || register_operand (operands[1], SFmode)
3018 || fp_zero_operand (operands[1], SFmode))"
3021 if (GET_CODE (operands[1]) == CONST_DOUBLE
3022 && (which_alternative == 3
3023 || which_alternative == 4
3024 || which_alternative == 5))
3029 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3030 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3031 operands[1] = GEN_INT (i);
3034 switch (which_alternative)
3037 return \"fmovs\\t%1, %0\";
3039 return \"fzeros\\t%0\";
3041 return \"clr\\t%0\";
3043 return \"sethi\\t%%hi(%a1), %0\";
3045 return \"mov\\t%1, %0\";
3050 return \"ld\\t%1, %0\";
3053 return \"st\\t%r1, %0\";
3058 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3060 ;; Exactly the same as above, except that all `f' cases are deleted.
3061 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3064 (define_insn "*movsf_no_f_insn"
3065 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3066 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3068 && (register_operand (operands[0], SFmode)
3069 || register_operand (operands[1], SFmode)
3070 || fp_zero_operand (operands[1], SFmode))"
3073 if (GET_CODE (operands[1]) == CONST_DOUBLE
3074 && (which_alternative == 1
3075 || which_alternative == 2
3076 || which_alternative == 3))
3081 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3082 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3083 operands[1] = GEN_INT (i);
3086 switch (which_alternative)
3089 return \"clr\\t%0\";
3091 return \"sethi\\t%%hi(%a1), %0\";
3093 return \"mov\\t%1, %0\";
3097 return \"ld\\t%1, %0\";
3099 return \"st\\t%r1, %0\";
3104 [(set_attr "type" "*,*,*,*,load,store")])
3106 (define_insn "*movsf_lo_sum"
3107 [(set (match_operand:SF 0 "register_operand" "=r")
3108 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3109 (match_operand:SF 2 "const_double_operand" "S")))]
3110 "fp_high_losum_p (operands[2])"
3116 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3117 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3118 operands[2] = GEN_INT (i);
3119 return \"or\\t%1, %%lo(%a2), %0\";
3122 (define_insn "*movsf_high"
3123 [(set (match_operand:SF 0 "register_operand" "=r")
3124 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3125 "fp_high_losum_p (operands[1])"
3131 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3132 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3133 operands[1] = GEN_INT (i);
3134 return \"sethi\\t%%hi(%1), %0\";
3138 [(set (match_operand:SF 0 "register_operand" "")
3139 (match_operand:SF 1 "const_double_operand" ""))]
3140 "fp_high_losum_p (operands[1])
3141 && (GET_CODE (operands[0]) == REG
3142 && REGNO (operands[0]) < 32)"
3143 [(set (match_dup 0) (high:SF (match_dup 1)))
3144 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3146 (define_expand "movsf"
3147 [(set (match_operand:SF 0 "general_operand" "")
3148 (match_operand:SF 1 "general_operand" ""))]
3152 /* Force SFmode constants into memory. */
3153 if (GET_CODE (operands[0]) == REG
3154 && CONSTANT_P (operands[1]))
3156 /* emit_group_store will send such bogosity to us when it is
3157 not storing directly into memory. So fix this up to avoid
3158 crashes in output_constant_pool. */
3159 if (operands [1] == const0_rtx)
3160 operands[1] = CONST0_RTX (SFmode);
3162 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3165 /* We are able to build any SF constant in integer registers
3166 with at most 2 instructions. */
3167 if (REGNO (operands[0]) < 32)
3170 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3174 /* Handle sets of MEM first. */
3175 if (GET_CODE (operands[0]) == MEM)
3177 if (register_operand (operands[1], SFmode)
3178 || fp_zero_operand (operands[1], SFmode))
3181 if (! reload_in_progress)
3183 operands[0] = validize_mem (operands[0]);
3184 operands[1] = force_reg (SFmode, operands[1]);
3188 /* Fixup PIC cases. */
3191 if (CONSTANT_P (operands[1])
3192 && pic_address_needs_scratch (operands[1]))
3193 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3195 if (symbolic_operand (operands[1], SFmode))
3197 operands[1] = legitimize_pic_address (operands[1],
3199 (reload_in_progress ?
3209 (define_expand "movdf"
3210 [(set (match_operand:DF 0 "general_operand" "")
3211 (match_operand:DF 1 "general_operand" ""))]
3215 /* Force DFmode constants into memory. */
3216 if (GET_CODE (operands[0]) == REG
3217 && CONSTANT_P (operands[1]))
3219 /* emit_group_store will send such bogosity to us when it is
3220 not storing directly into memory. So fix this up to avoid
3221 crashes in output_constant_pool. */
3222 if (operands [1] == const0_rtx)
3223 operands[1] = CONST0_RTX (DFmode);
3225 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3226 && fp_zero_operand (operands[1], DFmode))
3229 /* We are able to build any DF constant in integer registers. */
3230 if (REGNO (operands[0]) < 32
3231 && (reload_completed || reload_in_progress))
3234 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3238 /* Handle MEM cases first. */
3239 if (GET_CODE (operands[0]) == MEM)
3241 if (register_operand (operands[1], DFmode)
3242 || fp_zero_operand (operands[1], DFmode))
3245 if (! reload_in_progress)
3247 operands[0] = validize_mem (operands[0]);
3248 operands[1] = force_reg (DFmode, operands[1]);
3252 /* Fixup PIC cases. */
3255 if (CONSTANT_P (operands[1])
3256 && pic_address_needs_scratch (operands[1]))
3257 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3259 if (symbolic_operand (operands[1], DFmode))
3261 operands[1] = legitimize_pic_address (operands[1],
3263 (reload_in_progress ?
3273 ;; Be careful, fmovd does not exist when !v9.
3274 (define_insn "*movdf_insn_sp32"
3275 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
3276 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3279 && (register_operand (operands[0], DFmode)
3280 || register_operand (operands[1], DFmode)
3281 || fp_zero_operand (operands[1], DFmode))"
3293 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3294 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3296 (define_insn "*movdf_no_e_insn_sp32"
3297 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3298 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3302 && (register_operand (operands[0], DFmode)
3303 || register_operand (operands[1], DFmode)
3304 || fp_zero_operand (operands[1], DFmode))"
3311 [(set_attr "type" "load,store,*,*,*")
3312 (set_attr "length" "*,*,2,2,2")])
3314 (define_insn "*movdf_no_e_insn_v9_sp32"
3315 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3316 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3320 && (register_operand (operands[0], DFmode)
3321 || register_operand (operands[1], DFmode)
3322 || fp_zero_operand (operands[1], DFmode))"
3329 [(set_attr "type" "load,store,store,*,*")
3330 (set_attr "length" "*,*,*,2,2")])
3332 ;; We have available v9 double floats but not 64-bit
3333 ;; integer registers and no VIS.
3334 (define_insn "*movdf_insn_v9only_novis"
3335 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,e,*r,o")
3336 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGe"))]
3341 && (register_operand (operands[0], DFmode)
3342 || register_operand (operands[1], DFmode)
3343 || fp_zero_operand (operands[1], DFmode))"
3354 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3355 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3356 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3358 ;; We have available v9 double floats but not 64-bit
3359 ;; integer registers but we have VIS.
3360 (define_insn "*movdf_insn_v9only_vis"
3361 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,e,*r,o")
3362 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGe"))]
3366 && (register_operand (operands[0], DFmode)
3367 || register_operand (operands[1], DFmode)
3368 || fp_zero_operand (operands[1], DFmode))"
3380 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3381 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3382 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3384 ;; We have available both v9 double floats and 64-bit
3385 ;; integer registers. No VIS though.
3386 (define_insn "*movdf_insn_sp64_novis"
3387 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3388 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3392 && (register_operand (operands[0], DFmode)
3393 || register_operand (operands[1], DFmode)
3394 || fp_zero_operand (operands[1], DFmode))"
3403 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3404 (set_attr "length" "*,*,*,*,*,*,2")
3405 (set_attr "fptype" "double,*,*,*,*,*,*")])
3407 ;; We have available both v9 double floats and 64-bit
3408 ;; integer registers. And we have VIS.
3409 (define_insn "*movdf_insn_sp64_vis"
3410 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3411 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3415 && (register_operand (operands[0], DFmode)
3416 || register_operand (operands[1], DFmode)
3417 || fp_zero_operand (operands[1], DFmode))"
3427 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3428 (set_attr "length" "*,*,*,*,*,*,*,2")
3429 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3431 (define_insn "*movdf_no_e_insn_sp64"
3432 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3433 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3436 && (register_operand (operands[0], DFmode)
3437 || register_operand (operands[1], DFmode)
3438 || fp_zero_operand (operands[1], DFmode))"
3443 [(set_attr "type" "*,load,store")])
3446 [(set (match_operand:DF 0 "register_operand" "")
3447 (match_operand:DF 1 "const_double_operand" ""))]
3449 && (GET_CODE (operands[0]) == REG
3450 && REGNO (operands[0]) < 32)
3451 && ! fp_zero_operand(operands[1], DFmode)
3452 && reload_completed"
3453 [(clobber (const_int 0))]
3459 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3460 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3461 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3465 #if HOST_BITS_PER_WIDE_INT == 64
3468 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3469 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3470 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3472 emit_insn (gen_movdi (operands[0],
3473 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3478 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3481 /* Slick... but this trick loses if this subreg constant part
3482 can be done in one insn. */
3484 && !(SPARC_SETHI32_P (l[0])
3485 || SPARC_SIMM13_P (l[0])))
3487 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3488 gen_highpart (SImode, operands[0])));
3492 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3499 ;; Ok, now the splits to handle all the multi insn and
3500 ;; mis-aligned memory address cases.
3501 ;; In these splits please take note that we must be
3502 ;; careful when V9 but not ARCH64 because the integer
3503 ;; register DFmode cases must be handled.
3505 [(set (match_operand:DF 0 "register_operand" "")
3506 (match_operand:DF 1 "register_operand" ""))]
3509 && ((GET_CODE (operands[0]) == REG
3510 && REGNO (operands[0]) < 32)
3511 || (GET_CODE (operands[0]) == SUBREG
3512 && GET_CODE (SUBREG_REG (operands[0])) == REG
3513 && REGNO (SUBREG_REG (operands[0])) < 32))))
3514 && reload_completed"
3515 [(clobber (const_int 0))]
3518 rtx set_dest = operands[0];
3519 rtx set_src = operands[1];
3523 dest1 = gen_highpart (SFmode, set_dest);
3524 dest2 = gen_lowpart (SFmode, set_dest);
3525 src1 = gen_highpart (SFmode, set_src);
3526 src2 = gen_lowpart (SFmode, set_src);
3528 /* Now emit using the real source and destination we found, swapping
3529 the order if we detect overlap. */
3530 if (reg_overlap_mentioned_p (dest1, src2))
3532 emit_insn (gen_movsf (dest2, src2));
3533 emit_insn (gen_movsf (dest1, src1));
3537 emit_insn (gen_movsf (dest1, src1));
3538 emit_insn (gen_movsf (dest2, src2));
3544 [(set (match_operand:DF 0 "register_operand" "")
3545 (match_operand:DF 1 "memory_operand" ""))]
3548 && (((REGNO (operands[0]) % 2) != 0)
3549 || ! mem_min_alignment (operands[1], 8))
3550 && offsettable_memref_p (operands[1])"
3551 [(clobber (const_int 0))]
3554 rtx word0 = adjust_address (operands[1], SFmode, 0);
3555 rtx word1 = adjust_address (operands[1], SFmode, 4);
3557 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3559 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3561 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3566 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3568 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3575 [(set (match_operand:DF 0 "memory_operand" "")
3576 (match_operand:DF 1 "register_operand" ""))]
3579 && (((REGNO (operands[1]) % 2) != 0)
3580 || ! mem_min_alignment (operands[0], 8))
3581 && offsettable_memref_p (operands[0])"
3582 [(clobber (const_int 0))]
3585 rtx word0 = adjust_address (operands[0], SFmode, 0);
3586 rtx word1 = adjust_address (operands[0], SFmode, 4);
3588 emit_insn (gen_movsf (word0,
3589 gen_highpart (SFmode, operands[1])));
3590 emit_insn (gen_movsf (word1,
3591 gen_lowpart (SFmode, operands[1])));
3596 [(set (match_operand:DF 0 "memory_operand" "")
3597 (match_operand:DF 1 "fp_zero_operand" ""))]
3601 && ! mem_min_alignment (operands[0], 8)))
3602 && offsettable_memref_p (operands[0])"
3603 [(clobber (const_int 0))]
3608 dest1 = adjust_address (operands[0], SFmode, 0);
3609 dest2 = adjust_address (operands[0], SFmode, 4);
3611 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3612 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3617 [(set (match_operand:DF 0 "register_operand" "")
3618 (match_operand:DF 1 "fp_zero_operand" ""))]
3621 && ((GET_CODE (operands[0]) == REG
3622 && REGNO (operands[0]) < 32)
3623 || (GET_CODE (operands[0]) == SUBREG
3624 && GET_CODE (SUBREG_REG (operands[0])) == REG
3625 && REGNO (SUBREG_REG (operands[0])) < 32))"
3626 [(clobber (const_int 0))]
3629 rtx set_dest = operands[0];
3632 dest1 = gen_highpart (SFmode, set_dest);
3633 dest2 = gen_lowpart (SFmode, set_dest);
3634 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3635 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3639 (define_expand "movtf"
3640 [(set (match_operand:TF 0 "general_operand" "")
3641 (match_operand:TF 1 "general_operand" ""))]
3645 /* Force TFmode constants into memory. */
3646 if (GET_CODE (operands[0]) == REG
3647 && CONSTANT_P (operands[1]))
3649 /* emit_group_store will send such bogosity to us when it is
3650 not storing directly into memory. So fix this up to avoid
3651 crashes in output_constant_pool. */
3652 if (operands [1] == const0_rtx)
3653 operands[1] = CONST0_RTX (TFmode);
3655 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3658 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3662 /* Handle MEM cases first, note that only v9 guarentees
3663 full 16-byte alignment for quads. */
3664 if (GET_CODE (operands[0]) == MEM)
3666 if (register_operand (operands[1], TFmode)
3667 || fp_zero_operand (operands[1], TFmode))
3670 if (! reload_in_progress)
3672 operands[0] = validize_mem (operands[0]);
3673 operands[1] = force_reg (TFmode, operands[1]);
3677 /* Fixup PIC cases. */
3680 if (CONSTANT_P (operands[1])
3681 && pic_address_needs_scratch (operands[1]))
3682 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3684 if (symbolic_operand (operands[1], TFmode))
3686 operands[1] = legitimize_pic_address (operands[1],
3688 (reload_in_progress ?
3698 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3699 ;; we must split them all. :-(
3700 (define_insn "*movtf_insn_sp32"
3701 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3702 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3706 && (register_operand (operands[0], TFmode)
3707 || register_operand (operands[1], TFmode)
3708 || fp_zero_operand (operands[1], TFmode))"
3710 [(set_attr "length" "4")])
3712 (define_insn "*movtf_insn_vis_sp32"
3713 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3714 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3718 && (register_operand (operands[0], TFmode)
3719 || register_operand (operands[1], TFmode)
3720 || fp_zero_operand (operands[1], TFmode))"
3722 [(set_attr "length" "4")])
3724 ;; Exactly the same as above, except that all `e' cases are deleted.
3725 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3728 (define_insn "*movtf_no_e_insn_sp32"
3729 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3730 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3733 && (register_operand (operands[0], TFmode)
3734 || register_operand (operands[1], TFmode)
3735 || fp_zero_operand (operands[1], TFmode))"
3737 [(set_attr "length" "4")])
3739 ;; Now handle the float reg cases directly when arch64,
3740 ;; hard_quad, and proper reg number alignment are all true.
3741 (define_insn "*movtf_insn_hq_sp64"
3742 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3743 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3748 && (register_operand (operands[0], TFmode)
3749 || register_operand (operands[1], TFmode)
3750 || fp_zero_operand (operands[1], TFmode))"
3757 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3758 (set_attr "length" "*,*,*,2,2")])
3760 (define_insn "*movtf_insn_hq_vis_sp64"
3761 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3762 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3767 && (register_operand (operands[0], TFmode)
3768 || register_operand (operands[1], TFmode)
3769 || fp_zero_operand (operands[1], TFmode))"
3777 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3778 (set_attr "length" "*,*,*,2,2,2")])
3780 ;; Now we allow the integer register cases even when
3781 ;; only arch64 is true.
3782 (define_insn "*movtf_insn_sp64"
3783 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3784 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3788 && ! TARGET_HARD_QUAD
3789 && (register_operand (operands[0], TFmode)
3790 || register_operand (operands[1], TFmode)
3791 || fp_zero_operand (operands[1], TFmode))"
3793 [(set_attr "length" "2")])
3795 (define_insn "*movtf_insn_vis_sp64"
3796 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3797 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3801 && ! TARGET_HARD_QUAD
3802 && (register_operand (operands[0], TFmode)
3803 || register_operand (operands[1], TFmode)
3804 || fp_zero_operand (operands[1], TFmode))"
3806 [(set_attr "length" "2")])
3808 (define_insn "*movtf_no_e_insn_sp64"
3809 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3810 (match_operand:TF 1 "input_operand" "orG,rG"))]
3813 && (register_operand (operands[0], TFmode)
3814 || register_operand (operands[1], TFmode)
3815 || fp_zero_operand (operands[1], TFmode))"
3817 [(set_attr "length" "2")])
3819 ;; Now all the splits to handle multi-insn TF mode moves.
3821 [(set (match_operand:TF 0 "register_operand" "")
3822 (match_operand:TF 1 "register_operand" ""))]
3826 && ! TARGET_HARD_QUAD))"
3827 [(clobber (const_int 0))]
3830 rtx set_dest = operands[0];
3831 rtx set_src = operands[1];
3835 dest1 = gen_df_reg (set_dest, 0);
3836 dest2 = gen_df_reg (set_dest, 1);
3837 src1 = gen_df_reg (set_src, 0);
3838 src2 = gen_df_reg (set_src, 1);
3840 /* Now emit using the real source and destination we found, swapping
3841 the order if we detect overlap. */
3842 if (reg_overlap_mentioned_p (dest1, src2))
3844 emit_insn (gen_movdf (dest2, src2));
3845 emit_insn (gen_movdf (dest1, src1));
3849 emit_insn (gen_movdf (dest1, src1));
3850 emit_insn (gen_movdf (dest2, src2));
3856 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3857 (match_operand:TF 1 "fp_zero_operand" ""))]
3859 [(clobber (const_int 0))]
3862 rtx set_dest = operands[0];
3865 switch (GET_CODE (set_dest))
3868 dest1 = gen_df_reg (set_dest, 0);
3869 dest2 = gen_df_reg (set_dest, 1);
3872 dest1 = adjust_address (set_dest, DFmode, 0);
3873 dest2 = adjust_address (set_dest, DFmode, 8);
3879 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3880 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3885 [(set (match_operand:TF 0 "register_operand" "")
3886 (match_operand:TF 1 "memory_operand" ""))]
3888 && offsettable_memref_p (operands[1]))"
3889 [(clobber (const_int 0))]
3892 rtx word0 = adjust_address (operands[1], DFmode, 0);
3893 rtx word1 = adjust_address (operands[1], DFmode, 8);
3894 rtx set_dest, dest1, dest2;
3896 set_dest = operands[0];
3898 dest1 = gen_df_reg (set_dest, 0);
3899 dest2 = gen_df_reg (set_dest, 1);
3901 /* Now output, ordering such that we don't clobber any registers
3902 mentioned in the address. */
3903 if (reg_overlap_mentioned_p (dest1, word1))
3906 emit_insn (gen_movdf (dest2, word1));
3907 emit_insn (gen_movdf (dest1, word0));
3911 emit_insn (gen_movdf (dest1, word0));
3912 emit_insn (gen_movdf (dest2, word1));
3918 [(set (match_operand:TF 0 "memory_operand" "")
3919 (match_operand:TF 1 "register_operand" ""))]
3921 && offsettable_memref_p (operands[0]))"
3922 [(clobber (const_int 0))]
3925 rtx set_src = operands[1];
3927 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3928 gen_df_reg (set_src, 0)));
3929 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3930 gen_df_reg (set_src, 1)));
3934 ;; Sparc V9 conditional move instructions.
3936 ;; We can handle larger constants here for some flavors, but for now we keep
3937 ;; it simple and only allow those constants supported by all flavours.
3938 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3939 ;; 3 contains the constant if one is present, but we handle either for
3940 ;; generality (sparc.c puts a constant in operand 2).
3942 (define_expand "movqicc"
3943 [(set (match_operand:QI 0 "register_operand" "")
3944 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3945 (match_operand:QI 2 "arith10_operand" "")
3946 (match_operand:QI 3 "arith10_operand" "")))]
3950 enum rtx_code code = GET_CODE (operands[1]);
3952 if (GET_MODE (sparc_compare_op0) == DImode
3956 if (sparc_compare_op1 == const0_rtx
3957 && GET_CODE (sparc_compare_op0) == REG
3958 && GET_MODE (sparc_compare_op0) == DImode
3959 && v9_regcmp_p (code))
3961 operands[1] = gen_rtx_fmt_ee (code, DImode,
3962 sparc_compare_op0, sparc_compare_op1);
3966 rtx cc_reg = gen_compare_reg (code,
3967 sparc_compare_op0, sparc_compare_op1);
3968 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3972 (define_expand "movhicc"
3973 [(set (match_operand:HI 0 "register_operand" "")
3974 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3975 (match_operand:HI 2 "arith10_operand" "")
3976 (match_operand:HI 3 "arith10_operand" "")))]
3980 enum rtx_code code = GET_CODE (operands[1]);
3982 if (GET_MODE (sparc_compare_op0) == DImode
3986 if (sparc_compare_op1 == const0_rtx
3987 && GET_CODE (sparc_compare_op0) == REG
3988 && GET_MODE (sparc_compare_op0) == DImode
3989 && v9_regcmp_p (code))
3991 operands[1] = gen_rtx_fmt_ee (code, DImode,
3992 sparc_compare_op0, sparc_compare_op1);
3996 rtx cc_reg = gen_compare_reg (code,
3997 sparc_compare_op0, sparc_compare_op1);
3998 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4002 (define_expand "movsicc"
4003 [(set (match_operand:SI 0 "register_operand" "")
4004 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4005 (match_operand:SI 2 "arith10_operand" "")
4006 (match_operand:SI 3 "arith10_operand" "")))]
4010 enum rtx_code code = GET_CODE (operands[1]);
4011 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4013 if (sparc_compare_op1 == const0_rtx
4014 && GET_CODE (sparc_compare_op0) == REG
4015 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4017 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4018 sparc_compare_op0, sparc_compare_op1);
4022 rtx cc_reg = gen_compare_reg (code,
4023 sparc_compare_op0, sparc_compare_op1);
4024 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4025 cc_reg, const0_rtx);
4029 (define_expand "movdicc"
4030 [(set (match_operand:DI 0 "register_operand" "")
4031 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4032 (match_operand:DI 2 "arith10_double_operand" "")
4033 (match_operand:DI 3 "arith10_double_operand" "")))]
4037 enum rtx_code code = GET_CODE (operands[1]);
4039 if (sparc_compare_op1 == const0_rtx
4040 && GET_CODE (sparc_compare_op0) == REG
4041 && GET_MODE (sparc_compare_op0) == DImode
4042 && v9_regcmp_p (code))
4044 operands[1] = gen_rtx_fmt_ee (code, DImode,
4045 sparc_compare_op0, sparc_compare_op1);
4049 rtx cc_reg = gen_compare_reg (code,
4050 sparc_compare_op0, sparc_compare_op1);
4051 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4052 cc_reg, const0_rtx);
4056 (define_expand "movsfcc"
4057 [(set (match_operand:SF 0 "register_operand" "")
4058 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4059 (match_operand:SF 2 "register_operand" "")
4060 (match_operand:SF 3 "register_operand" "")))]
4061 "TARGET_V9 && TARGET_FPU"
4064 enum rtx_code code = GET_CODE (operands[1]);
4066 if (GET_MODE (sparc_compare_op0) == DImode
4070 if (sparc_compare_op1 == const0_rtx
4071 && GET_CODE (sparc_compare_op0) == REG
4072 && GET_MODE (sparc_compare_op0) == DImode
4073 && v9_regcmp_p (code))
4075 operands[1] = gen_rtx_fmt_ee (code, DImode,
4076 sparc_compare_op0, sparc_compare_op1);
4080 rtx cc_reg = gen_compare_reg (code,
4081 sparc_compare_op0, sparc_compare_op1);
4082 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4086 (define_expand "movdfcc"
4087 [(set (match_operand:DF 0 "register_operand" "")
4088 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4089 (match_operand:DF 2 "register_operand" "")
4090 (match_operand:DF 3 "register_operand" "")))]
4091 "TARGET_V9 && TARGET_FPU"
4094 enum rtx_code code = GET_CODE (operands[1]);
4096 if (GET_MODE (sparc_compare_op0) == DImode
4100 if (sparc_compare_op1 == const0_rtx
4101 && GET_CODE (sparc_compare_op0) == REG
4102 && GET_MODE (sparc_compare_op0) == DImode
4103 && v9_regcmp_p (code))
4105 operands[1] = gen_rtx_fmt_ee (code, DImode,
4106 sparc_compare_op0, sparc_compare_op1);
4110 rtx cc_reg = gen_compare_reg (code,
4111 sparc_compare_op0, sparc_compare_op1);
4112 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4116 (define_expand "movtfcc"
4117 [(set (match_operand:TF 0 "register_operand" "")
4118 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4119 (match_operand:TF 2 "register_operand" "")
4120 (match_operand:TF 3 "register_operand" "")))]
4121 "TARGET_V9 && TARGET_FPU"
4124 enum rtx_code code = GET_CODE (operands[1]);
4126 if (GET_MODE (sparc_compare_op0) == DImode
4130 if (sparc_compare_op1 == const0_rtx
4131 && GET_CODE (sparc_compare_op0) == REG
4132 && GET_MODE (sparc_compare_op0) == DImode
4133 && v9_regcmp_p (code))
4135 operands[1] = gen_rtx_fmt_ee (code, DImode,
4136 sparc_compare_op0, sparc_compare_op1);
4140 rtx cc_reg = gen_compare_reg (code,
4141 sparc_compare_op0, sparc_compare_op1);
4142 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4146 ;; Conditional move define_insns.
4148 (define_insn "*movqi_cc_sp64"
4149 [(set (match_operand:QI 0 "register_operand" "=r,r")
4150 (if_then_else:QI (match_operator 1 "comparison_operator"
4151 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4153 (match_operand:QI 3 "arith11_operand" "rL,0")
4154 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4157 mov%C1\\t%x2, %3, %0
4158 mov%c1\\t%x2, %4, %0"
4159 [(set_attr "type" "cmove")])
4161 (define_insn "*movhi_cc_sp64"
4162 [(set (match_operand:HI 0 "register_operand" "=r,r")
4163 (if_then_else:HI (match_operator 1 "comparison_operator"
4164 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4166 (match_operand:HI 3 "arith11_operand" "rL,0")
4167 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4170 mov%C1\\t%x2, %3, %0
4171 mov%c1\\t%x2, %4, %0"
4172 [(set_attr "type" "cmove")])
4174 (define_insn "*movsi_cc_sp64"
4175 [(set (match_operand:SI 0 "register_operand" "=r,r")
4176 (if_then_else:SI (match_operator 1 "comparison_operator"
4177 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4179 (match_operand:SI 3 "arith11_operand" "rL,0")
4180 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4183 mov%C1\\t%x2, %3, %0
4184 mov%c1\\t%x2, %4, %0"
4185 [(set_attr "type" "cmove")])
4187 ;; ??? The constraints of operands 3,4 need work.
4188 (define_insn "*movdi_cc_sp64"
4189 [(set (match_operand:DI 0 "register_operand" "=r,r")
4190 (if_then_else:DI (match_operator 1 "comparison_operator"
4191 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4193 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4194 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4197 mov%C1\\t%x2, %3, %0
4198 mov%c1\\t%x2, %4, %0"
4199 [(set_attr "type" "cmove")])
4201 (define_insn "*movdi_cc_sp64_trunc"
4202 [(set (match_operand:SI 0 "register_operand" "=r,r")
4203 (if_then_else:SI (match_operator 1 "comparison_operator"
4204 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4206 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4207 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4210 mov%C1\\t%x2, %3, %0
4211 mov%c1\\t%x2, %4, %0"
4212 [(set_attr "type" "cmove")])
4214 (define_insn "*movsf_cc_sp64"
4215 [(set (match_operand:SF 0 "register_operand" "=f,f")
4216 (if_then_else:SF (match_operator 1 "comparison_operator"
4217 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4219 (match_operand:SF 3 "register_operand" "f,0")
4220 (match_operand:SF 4 "register_operand" "0,f")))]
4221 "TARGET_V9 && TARGET_FPU"
4223 fmovs%C1\\t%x2, %3, %0
4224 fmovs%c1\\t%x2, %4, %0"
4225 [(set_attr "type" "fpcmove")])
4227 (define_insn "movdf_cc_sp64"
4228 [(set (match_operand:DF 0 "register_operand" "=e,e")
4229 (if_then_else:DF (match_operator 1 "comparison_operator"
4230 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4232 (match_operand:DF 3 "register_operand" "e,0")
4233 (match_operand:DF 4 "register_operand" "0,e")))]
4234 "TARGET_V9 && TARGET_FPU"
4236 fmovd%C1\\t%x2, %3, %0
4237 fmovd%c1\\t%x2, %4, %0"
4238 [(set_attr "type" "fpcmove")
4239 (set_attr "fptype" "double")])
4241 (define_insn "*movtf_cc_hq_sp64"
4242 [(set (match_operand:TF 0 "register_operand" "=e,e")
4243 (if_then_else:TF (match_operator 1 "comparison_operator"
4244 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4246 (match_operand:TF 3 "register_operand" "e,0")
4247 (match_operand:TF 4 "register_operand" "0,e")))]
4248 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4250 fmovq%C1\\t%x2, %3, %0
4251 fmovq%c1\\t%x2, %4, %0"
4252 [(set_attr "type" "fpcmove")])
4254 (define_insn "*movtf_cc_sp64"
4255 [(set (match_operand:TF 0 "register_operand" "=e,e")
4256 (if_then_else:TF (match_operator 1 "comparison_operator"
4257 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4259 (match_operand:TF 3 "register_operand" "e,0")
4260 (match_operand:TF 4 "register_operand" "0,e")))]
4261 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4263 [(set_attr "length" "2")])
4266 [(set (match_operand:TF 0 "register_operand" "")
4267 (if_then_else:TF (match_operator 1 "comparison_operator"
4268 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4270 (match_operand:TF 3 "register_operand" "")
4271 (match_operand:TF 4 "register_operand" "")))]
4272 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4273 [(clobber (const_int 0))]
4276 rtx set_dest = operands[0];
4277 rtx set_srca = operands[3];
4278 rtx set_srcb = operands[4];
4279 int third = rtx_equal_p (set_dest, set_srca);
4281 rtx srca1, srca2, srcb1, srcb2;
4283 dest1 = gen_df_reg (set_dest, 0);
4284 dest2 = gen_df_reg (set_dest, 1);
4285 srca1 = gen_df_reg (set_srca, 0);
4286 srca2 = gen_df_reg (set_srca, 1);
4287 srcb1 = gen_df_reg (set_srcb, 0);
4288 srcb2 = gen_df_reg (set_srcb, 1);
4290 /* Now emit using the real source and destination we found, swapping
4291 the order if we detect overlap. */
4292 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4293 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4295 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4296 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4300 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4301 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4306 (define_insn "*movqi_cc_reg_sp64"
4307 [(set (match_operand:QI 0 "register_operand" "=r,r")
4308 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4309 [(match_operand:DI 2 "register_operand" "r,r")
4311 (match_operand:QI 3 "arith10_operand" "rM,0")
4312 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4315 movr%D1\\t%2, %r3, %0
4316 movr%d1\\t%2, %r4, %0"
4317 [(set_attr "type" "cmove")])
4319 (define_insn "*movhi_cc_reg_sp64"
4320 [(set (match_operand:HI 0 "register_operand" "=r,r")
4321 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4322 [(match_operand:DI 2 "register_operand" "r,r")
4324 (match_operand:HI 3 "arith10_operand" "rM,0")
4325 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4328 movr%D1\\t%2, %r3, %0
4329 movr%d1\\t%2, %r4, %0"
4330 [(set_attr "type" "cmove")])
4332 (define_insn "*movsi_cc_reg_sp64"
4333 [(set (match_operand:SI 0 "register_operand" "=r,r")
4334 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4335 [(match_operand:DI 2 "register_operand" "r,r")
4337 (match_operand:SI 3 "arith10_operand" "rM,0")
4338 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4341 movr%D1\\t%2, %r3, %0
4342 movr%d1\\t%2, %r4, %0"
4343 [(set_attr "type" "cmove")])
4345 ;; ??? The constraints of operands 3,4 need work.
4346 (define_insn "*movdi_cc_reg_sp64"
4347 [(set (match_operand:DI 0 "register_operand" "=r,r")
4348 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4349 [(match_operand:DI 2 "register_operand" "r,r")
4351 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4352 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4355 movr%D1\\t%2, %r3, %0
4356 movr%d1\\t%2, %r4, %0"
4357 [(set_attr "type" "cmove")])
4359 (define_insn "*movdi_cc_reg_sp64_trunc"
4360 [(set (match_operand:SI 0 "register_operand" "=r,r")
4361 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4362 [(match_operand:DI 2 "register_operand" "r,r")
4364 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4365 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4368 movr%D1\\t%2, %r3, %0
4369 movr%d1\\t%2, %r4, %0"
4370 [(set_attr "type" "cmove")])
4372 (define_insn "*movsf_cc_reg_sp64"
4373 [(set (match_operand:SF 0 "register_operand" "=f,f")
4374 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4375 [(match_operand:DI 2 "register_operand" "r,r")
4377 (match_operand:SF 3 "register_operand" "f,0")
4378 (match_operand:SF 4 "register_operand" "0,f")))]
4379 "TARGET_ARCH64 && TARGET_FPU"
4381 fmovrs%D1\\t%2, %3, %0
4382 fmovrs%d1\\t%2, %4, %0"
4383 [(set_attr "type" "fpcmove")])
4385 (define_insn "movdf_cc_reg_sp64"
4386 [(set (match_operand:DF 0 "register_operand" "=e,e")
4387 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4388 [(match_operand:DI 2 "register_operand" "r,r")
4390 (match_operand:DF 3 "register_operand" "e,0")
4391 (match_operand:DF 4 "register_operand" "0,e")))]
4392 "TARGET_ARCH64 && TARGET_FPU"
4394 fmovrd%D1\\t%2, %3, %0
4395 fmovrd%d1\\t%2, %4, %0"
4396 [(set_attr "type" "fpcmove")
4397 (set_attr "fptype" "double")])
4399 (define_insn "*movtf_cc_reg_hq_sp64"
4400 [(set (match_operand:TF 0 "register_operand" "=e,e")
4401 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4402 [(match_operand:DI 2 "register_operand" "r,r")
4404 (match_operand:TF 3 "register_operand" "e,0")
4405 (match_operand:TF 4 "register_operand" "0,e")))]
4406 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4408 fmovrq%D1\\t%2, %3, %0
4409 fmovrq%d1\\t%2, %4, %0"
4410 [(set_attr "type" "fpcmove")])
4412 (define_insn "*movtf_cc_reg_sp64"
4413 [(set (match_operand:TF 0 "register_operand" "=e,e")
4414 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4415 [(match_operand:DI 2 "register_operand" "r,r")
4417 (match_operand:TF 3 "register_operand" "e,0")
4418 (match_operand:TF 4 "register_operand" "0,e")))]
4419 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4421 [(set_attr "length" "2")])
4424 [(set (match_operand:TF 0 "register_operand" "")
4425 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4426 [(match_operand:DI 2 "register_operand" "")
4428 (match_operand:TF 3 "register_operand" "")
4429 (match_operand:TF 4 "register_operand" "")))]
4430 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4431 [(clobber (const_int 0))]
4434 rtx set_dest = operands[0];
4435 rtx set_srca = operands[3];
4436 rtx set_srcb = operands[4];
4437 int third = rtx_equal_p (set_dest, set_srca);
4439 rtx srca1, srca2, srcb1, srcb2;
4441 dest1 = gen_df_reg (set_dest, 0);
4442 dest2 = gen_df_reg (set_dest, 1);
4443 srca1 = gen_df_reg (set_srca, 0);
4444 srca2 = gen_df_reg (set_srca, 1);
4445 srcb1 = gen_df_reg (set_srcb, 0);
4446 srcb2 = gen_df_reg (set_srcb, 1);
4448 /* Now emit using the real source and destination we found, swapping
4449 the order if we detect overlap. */
4450 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4451 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4453 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4454 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4458 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4459 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4465 ;;- zero extension instructions
4467 ;; These patterns originally accepted general_operands, however, slightly
4468 ;; better code is generated by only accepting register_operands, and then
4469 ;; letting combine generate the ldu[hb] insns.
4471 (define_expand "zero_extendhisi2"
4472 [(set (match_operand:SI 0 "register_operand" "")
4473 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4477 rtx temp = gen_reg_rtx (SImode);
4478 rtx shift_16 = GEN_INT (16);
4479 int op1_subbyte = 0;
4481 if (GET_CODE (operand1) == SUBREG)
4483 op1_subbyte = SUBREG_BYTE (operand1);
4484 op1_subbyte /= GET_MODE_SIZE (SImode);
4485 op1_subbyte *= GET_MODE_SIZE (SImode);
4486 operand1 = XEXP (operand1, 0);
4489 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4491 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4495 (define_insn "*zero_extendhisi2_insn"
4496 [(set (match_operand:SI 0 "register_operand" "=r")
4497 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4500 [(set_attr "type" "load")])
4502 (define_expand "zero_extendqihi2"
4503 [(set (match_operand:HI 0 "register_operand" "")
4504 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4508 (define_insn "*zero_extendqihi2_insn"
4509 [(set (match_operand:HI 0 "register_operand" "=r,r")
4510 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4511 "GET_CODE (operands[1]) != CONST_INT"
4515 [(set_attr "type" "*,load")])
4517 (define_expand "zero_extendqisi2"
4518 [(set (match_operand:SI 0 "register_operand" "")
4519 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4523 (define_insn "*zero_extendqisi2_insn"
4524 [(set (match_operand:SI 0 "register_operand" "=r,r")
4525 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4526 "GET_CODE (operands[1]) != CONST_INT"
4530 [(set_attr "type" "*,load")])
4532 (define_expand "zero_extendqidi2"
4533 [(set (match_operand:DI 0 "register_operand" "")
4534 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4538 (define_insn "*zero_extendqidi2_insn"
4539 [(set (match_operand:DI 0 "register_operand" "=r,r")
4540 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4541 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4545 [(set_attr "type" "*,load")])
4547 (define_expand "zero_extendhidi2"
4548 [(set (match_operand:DI 0 "register_operand" "")
4549 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4553 rtx temp = gen_reg_rtx (DImode);
4554 rtx shift_48 = GEN_INT (48);
4555 int op1_subbyte = 0;
4557 if (GET_CODE (operand1) == SUBREG)
4559 op1_subbyte = SUBREG_BYTE (operand1);
4560 op1_subbyte /= GET_MODE_SIZE (DImode);
4561 op1_subbyte *= GET_MODE_SIZE (DImode);
4562 operand1 = XEXP (operand1, 0);
4565 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4567 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4571 (define_insn "*zero_extendhidi2_insn"
4572 [(set (match_operand:DI 0 "register_operand" "=r")
4573 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4576 [(set_attr "type" "load")])
4579 ;; ??? Write truncdisi pattern using sra?
4581 (define_expand "zero_extendsidi2"
4582 [(set (match_operand:DI 0 "register_operand" "")
4583 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4587 (define_insn "*zero_extendsidi2_insn_sp64"
4588 [(set (match_operand:DI 0 "register_operand" "=r,r")
4589 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4590 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4594 [(set_attr "type" "shift,load")])
4596 (define_insn "*zero_extendsidi2_insn_sp32"
4597 [(set (match_operand:DI 0 "register_operand" "=r")
4598 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4601 [(set_attr "length" "2")])
4604 [(set (match_operand:DI 0 "register_operand" "")
4605 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4606 "! TARGET_ARCH64 && reload_completed"
4607 [(set (match_dup 2) (match_dup 3))
4608 (set (match_dup 4) (match_dup 5))]
4613 dest1 = gen_highpart (SImode, operands[0]);
4614 dest2 = gen_lowpart (SImode, operands[0]);
4616 /* Swap the order in case of overlap. */
4617 if (REGNO (dest1) == REGNO (operands[1]))
4619 operands[2] = dest2;
4620 operands[3] = operands[1];
4621 operands[4] = dest1;
4622 operands[5] = const0_rtx;
4626 operands[2] = dest1;
4627 operands[3] = const0_rtx;
4628 operands[4] = dest2;
4629 operands[5] = operands[1];
4633 ;; Simplify comparisons of extended values.
4635 (define_insn "*cmp_zero_extendqisi2"
4637 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4640 "andcc\\t%0, 0xff, %%g0"
4641 [(set_attr "type" "compare")])
4643 (define_insn "*cmp_zero_qi"
4645 (compare:CC (match_operand:QI 0 "register_operand" "r")
4648 "andcc\\t%0, 0xff, %%g0"
4649 [(set_attr "type" "compare")])
4651 (define_insn "*cmp_zero_extendqisi2_set"
4653 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4655 (set (match_operand:SI 0 "register_operand" "=r")
4656 (zero_extend:SI (match_dup 1)))]
4658 "andcc\\t%1, 0xff, %0"
4659 [(set_attr "type" "compare")])
4661 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4663 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4666 (set (match_operand:SI 0 "register_operand" "=r")
4667 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4669 "andcc\\t%1, 0xff, %0"
4670 [(set_attr "type" "compare")])
4672 (define_insn "*cmp_zero_extendqidi2"
4674 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4677 "andcc\\t%0, 0xff, %%g0"
4678 [(set_attr "type" "compare")])
4680 (define_insn "*cmp_zero_qi_sp64"
4682 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4685 "andcc\\t%0, 0xff, %%g0"
4686 [(set_attr "type" "compare")])
4688 (define_insn "*cmp_zero_extendqidi2_set"
4690 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4692 (set (match_operand:DI 0 "register_operand" "=r")
4693 (zero_extend:DI (match_dup 1)))]
4695 "andcc\\t%1, 0xff, %0"
4696 [(set_attr "type" "compare")])
4698 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4700 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4703 (set (match_operand:DI 0 "register_operand" "=r")
4704 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4706 "andcc\\t%1, 0xff, %0"
4707 [(set_attr "type" "compare")])
4709 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4711 (define_insn "*cmp_siqi_trunc"
4713 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4716 "andcc\\t%0, 0xff, %%g0"
4717 [(set_attr "type" "compare")])
4719 (define_insn "*cmp_siqi_trunc_set"
4721 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4723 (set (match_operand:QI 0 "register_operand" "=r")
4724 (subreg:QI (match_dup 1) 3))]
4726 "andcc\\t%1, 0xff, %0"
4727 [(set_attr "type" "compare")])
4729 (define_insn "*cmp_diqi_trunc"
4731 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4734 "andcc\\t%0, 0xff, %%g0"
4735 [(set_attr "type" "compare")])
4737 (define_insn "*cmp_diqi_trunc_set"
4739 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4741 (set (match_operand:QI 0 "register_operand" "=r")
4742 (subreg:QI (match_dup 1) 7))]
4744 "andcc\\t%1, 0xff, %0"
4745 [(set_attr "type" "compare")])
4747 ;;- sign extension instructions
4749 ;; These patterns originally accepted general_operands, however, slightly
4750 ;; better code is generated by only accepting register_operands, and then
4751 ;; letting combine generate the lds[hb] insns.
4753 (define_expand "extendhisi2"
4754 [(set (match_operand:SI 0 "register_operand" "")
4755 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4759 rtx temp = gen_reg_rtx (SImode);
4760 rtx shift_16 = GEN_INT (16);
4761 int op1_subbyte = 0;
4763 if (GET_CODE (operand1) == SUBREG)
4765 op1_subbyte = SUBREG_BYTE (operand1);
4766 op1_subbyte /= GET_MODE_SIZE (SImode);
4767 op1_subbyte *= GET_MODE_SIZE (SImode);
4768 operand1 = XEXP (operand1, 0);
4771 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4773 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4777 (define_insn "*sign_extendhisi2_insn"
4778 [(set (match_operand:SI 0 "register_operand" "=r")
4779 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4782 [(set_attr "type" "sload")])
4784 (define_expand "extendqihi2"
4785 [(set (match_operand:HI 0 "register_operand" "")
4786 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4790 rtx temp = gen_reg_rtx (SImode);
4791 rtx shift_24 = GEN_INT (24);
4792 int op1_subbyte = 0;
4793 int op0_subbyte = 0;
4795 if (GET_CODE (operand1) == SUBREG)
4797 op1_subbyte = SUBREG_BYTE (operand1);
4798 op1_subbyte /= GET_MODE_SIZE (SImode);
4799 op1_subbyte *= GET_MODE_SIZE (SImode);
4800 operand1 = XEXP (operand1, 0);
4802 if (GET_CODE (operand0) == SUBREG)
4804 op0_subbyte = SUBREG_BYTE (operand0);
4805 op0_subbyte /= GET_MODE_SIZE (SImode);
4806 op0_subbyte *= GET_MODE_SIZE (SImode);
4807 operand0 = XEXP (operand0, 0);
4809 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4811 if (GET_MODE (operand0) != SImode)
4812 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4813 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4817 (define_insn "*sign_extendqihi2_insn"
4818 [(set (match_operand:HI 0 "register_operand" "=r")
4819 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4822 [(set_attr "type" "sload")])
4824 (define_expand "extendqisi2"
4825 [(set (match_operand:SI 0 "register_operand" "")
4826 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4830 rtx temp = gen_reg_rtx (SImode);
4831 rtx shift_24 = GEN_INT (24);
4832 int op1_subbyte = 0;
4834 if (GET_CODE (operand1) == SUBREG)
4836 op1_subbyte = SUBREG_BYTE (operand1);
4837 op1_subbyte /= GET_MODE_SIZE (SImode);
4838 op1_subbyte *= GET_MODE_SIZE (SImode);
4839 operand1 = XEXP (operand1, 0);
4842 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4844 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4848 (define_insn "*sign_extendqisi2_insn"
4849 [(set (match_operand:SI 0 "register_operand" "=r")
4850 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4853 [(set_attr "type" "sload")])
4855 (define_expand "extendqidi2"
4856 [(set (match_operand:DI 0 "register_operand" "")
4857 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4861 rtx temp = gen_reg_rtx (DImode);
4862 rtx shift_56 = GEN_INT (56);
4863 int op1_subbyte = 0;
4865 if (GET_CODE (operand1) == SUBREG)
4867 op1_subbyte = SUBREG_BYTE (operand1);
4868 op1_subbyte /= GET_MODE_SIZE (DImode);
4869 op1_subbyte *= GET_MODE_SIZE (DImode);
4870 operand1 = XEXP (operand1, 0);
4873 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4875 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4879 (define_insn "*sign_extendqidi2_insn"
4880 [(set (match_operand:DI 0 "register_operand" "=r")
4881 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4884 [(set_attr "type" "sload")])
4886 (define_expand "extendhidi2"
4887 [(set (match_operand:DI 0 "register_operand" "")
4888 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4892 rtx temp = gen_reg_rtx (DImode);
4893 rtx shift_48 = GEN_INT (48);
4894 int op1_subbyte = 0;
4896 if (GET_CODE (operand1) == SUBREG)
4898 op1_subbyte = SUBREG_BYTE (operand1);
4899 op1_subbyte /= GET_MODE_SIZE (DImode);
4900 op1_subbyte *= GET_MODE_SIZE (DImode);
4901 operand1 = XEXP (operand1, 0);
4904 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4906 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4910 (define_insn "*sign_extendhidi2_insn"
4911 [(set (match_operand:DI 0 "register_operand" "=r")
4912 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4915 [(set_attr "type" "sload")])
4917 (define_expand "extendsidi2"
4918 [(set (match_operand:DI 0 "register_operand" "")
4919 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4923 (define_insn "*sign_extendsidi2_insn"
4924 [(set (match_operand:DI 0 "register_operand" "=r,r")
4925 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4930 [(set_attr "type" "shift,sload")])
4932 ;; Special pattern for optimizing bit-field compares. This is needed
4933 ;; because combine uses this as a canonical form.
4935 (define_insn "*cmp_zero_extract"
4938 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4939 (match_operand:SI 1 "small_int_or_double" "n")
4940 (match_operand:SI 2 "small_int_or_double" "n"))
4942 "(GET_CODE (operands[2]) == CONST_INT
4943 && INTVAL (operands[2]) > 19)
4944 || (GET_CODE (operands[2]) == CONST_DOUBLE
4945 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4948 int len = (GET_CODE (operands[1]) == CONST_INT
4949 ? INTVAL (operands[1])
4950 : CONST_DOUBLE_LOW (operands[1]));
4952 (GET_CODE (operands[2]) == CONST_INT
4953 ? INTVAL (operands[2])
4954 : CONST_DOUBLE_LOW (operands[2])) - len;
4955 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4957 operands[1] = GEN_INT (mask);
4958 return \"andcc\\t%0, %1, %%g0\";
4960 [(set_attr "type" "compare")])
4962 (define_insn "*cmp_zero_extract_sp64"
4965 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4966 (match_operand:SI 1 "small_int_or_double" "n")
4967 (match_operand:SI 2 "small_int_or_double" "n"))
4970 && ((GET_CODE (operands[2]) == CONST_INT
4971 && INTVAL (operands[2]) > 51)
4972 || (GET_CODE (operands[2]) == CONST_DOUBLE
4973 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4976 int len = (GET_CODE (operands[1]) == CONST_INT
4977 ? INTVAL (operands[1])
4978 : CONST_DOUBLE_LOW (operands[1]));
4980 (GET_CODE (operands[2]) == CONST_INT
4981 ? INTVAL (operands[2])
4982 : CONST_DOUBLE_LOW (operands[2])) - len;
4983 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4985 operands[1] = GEN_INT (mask);
4986 return \"andcc\\t%0, %1, %%g0\";
4988 [(set_attr "type" "compare")])
4990 ;; Conversions between float, double and long double.
4992 (define_insn "extendsfdf2"
4993 [(set (match_operand:DF 0 "register_operand" "=e")
4995 (match_operand:SF 1 "register_operand" "f")))]
4998 [(set_attr "type" "fp")
4999 (set_attr "fptype" "double")])
5001 (define_expand "extendsftf2"
5002 [(set (match_operand:TF 0 "register_operand" "=e")
5004 (match_operand:SF 1 "register_operand" "f")))]
5005 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5008 if (! TARGET_HARD_QUAD)
5012 if (GET_CODE (operands[0]) != MEM)
5013 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5015 slot0 = operands[0];
5017 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5019 XEXP (slot0, 0), Pmode,
5020 operands[1], SFmode);
5022 if (GET_CODE (operands[0]) != MEM)
5023 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5028 (define_insn "*extendsftf2_hq"
5029 [(set (match_operand:TF 0 "register_operand" "=e")
5031 (match_operand:SF 1 "register_operand" "f")))]
5032 "TARGET_FPU && TARGET_HARD_QUAD"
5034 [(set_attr "type" "fp")])
5036 (define_expand "extenddftf2"
5037 [(set (match_operand:TF 0 "register_operand" "=e")
5039 (match_operand:DF 1 "register_operand" "e")))]
5040 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5043 if (! TARGET_HARD_QUAD)
5047 if (GET_CODE (operands[0]) != MEM)
5048 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5050 slot0 = operands[0];
5052 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5054 XEXP (slot0, 0), Pmode,
5055 operands[1], DFmode);
5057 if (GET_CODE (operands[0]) != MEM)
5058 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5063 (define_insn "*extenddftf2_hq"
5064 [(set (match_operand:TF 0 "register_operand" "=e")
5066 (match_operand:DF 1 "register_operand" "e")))]
5067 "TARGET_FPU && TARGET_HARD_QUAD"
5069 [(set_attr "type" "fp")])
5071 (define_insn "truncdfsf2"
5072 [(set (match_operand:SF 0 "register_operand" "=f")
5074 (match_operand:DF 1 "register_operand" "e")))]
5077 [(set_attr "type" "fp")
5078 (set_attr "fptype" "double")])
5080 (define_expand "trunctfsf2"
5081 [(set (match_operand:SF 0 "register_operand" "=f")
5083 (match_operand:TF 1 "register_operand" "e")))]
5084 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5087 if (! TARGET_HARD_QUAD)
5091 if (GET_CODE (operands[1]) != MEM)
5093 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5094 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5097 slot0 = operands[1];
5099 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5100 operands[0], 0, SFmode, 1,
5101 XEXP (slot0, 0), Pmode);
5106 (define_insn "*trunctfsf2_hq"
5107 [(set (match_operand:SF 0 "register_operand" "=f")
5109 (match_operand:TF 1 "register_operand" "e")))]
5110 "TARGET_FPU && TARGET_HARD_QUAD"
5112 [(set_attr "type" "fp")])
5114 (define_expand "trunctfdf2"
5115 [(set (match_operand:DF 0 "register_operand" "=f")
5117 (match_operand:TF 1 "register_operand" "e")))]
5118 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5121 if (! TARGET_HARD_QUAD)
5125 if (GET_CODE (operands[1]) != MEM)
5127 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5128 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5131 slot0 = operands[1];
5133 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5134 operands[0], 0, DFmode, 1,
5135 XEXP (slot0, 0), Pmode);
5140 (define_insn "*trunctfdf2_hq"
5141 [(set (match_operand:DF 0 "register_operand" "=e")
5143 (match_operand:TF 1 "register_operand" "e")))]
5144 "TARGET_FPU && TARGET_HARD_QUAD"
5146 [(set_attr "type" "fp")])
5148 ;; Conversion between fixed point and floating point.
5150 (define_insn "floatsisf2"
5151 [(set (match_operand:SF 0 "register_operand" "=f")
5152 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5155 [(set_attr "type" "fp")
5156 (set_attr "fptype" "double")])
5158 (define_insn "floatsidf2"
5159 [(set (match_operand:DF 0 "register_operand" "=e")
5160 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5163 [(set_attr "type" "fp")
5164 (set_attr "fptype" "double")])
5166 (define_expand "floatsitf2"
5167 [(set (match_operand:TF 0 "register_operand" "=e")
5168 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5169 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5172 if (! TARGET_HARD_QUAD)
5176 if (GET_CODE (operands[1]) != MEM)
5177 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5179 slot0 = operands[1];
5181 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5183 XEXP (slot0, 0), Pmode,
5184 operands[1], SImode);
5186 if (GET_CODE (operands[0]) != MEM)
5187 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5192 (define_insn "*floatsitf2_hq"
5193 [(set (match_operand:TF 0 "register_operand" "=e")
5194 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5195 "TARGET_FPU && TARGET_HARD_QUAD"
5197 [(set_attr "type" "fp")])
5199 (define_expand "floatunssitf2"
5200 [(set (match_operand:TF 0 "register_operand" "=e")
5201 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5202 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5207 if (GET_CODE (operands[1]) != MEM)
5208 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5210 slot0 = operands[1];
5212 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5214 XEXP (slot0, 0), Pmode,
5215 operands[1], SImode);
5217 if (GET_CODE (operands[0]) != MEM)
5218 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5222 ;; Now the same for 64 bit sources.
5224 (define_insn "floatdisf2"
5225 [(set (match_operand:SF 0 "register_operand" "=f")
5226 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5227 "TARGET_V9 && TARGET_FPU"
5229 [(set_attr "type" "fp")
5230 (set_attr "fptype" "double")])
5232 (define_expand "floatunsdisf2"
5233 [(use (match_operand:SF 0 "register_operand" ""))
5234 (use (match_operand:DI 1 "register_operand" ""))]
5235 "TARGET_ARCH64 && TARGET_FPU"
5236 "sparc_emit_floatunsdi (operands); DONE;")
5238 (define_insn "floatdidf2"
5239 [(set (match_operand:DF 0 "register_operand" "=e")
5240 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5241 "TARGET_V9 && TARGET_FPU"
5243 [(set_attr "type" "fp")
5244 (set_attr "fptype" "double")])
5246 (define_expand "floatunsdidf2"
5247 [(use (match_operand:DF 0 "register_operand" ""))
5248 (use (match_operand:DI 1 "register_operand" ""))]
5249 "TARGET_ARCH64 && TARGET_FPU"
5250 "sparc_emit_floatunsdi (operands); DONE;")
5252 (define_expand "floatditf2"
5253 [(set (match_operand:TF 0 "register_operand" "=e")
5254 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5255 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5258 if (! TARGET_HARD_QUAD)
5262 if (GET_CODE (operands[1]) != MEM)
5263 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5265 slot0 = operands[1];
5267 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5269 XEXP (slot0, 0), Pmode,
5270 operands[1], DImode);
5272 if (GET_CODE (operands[0]) != MEM)
5273 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5278 (define_insn "*floatditf2_hq"
5279 [(set (match_operand:TF 0 "register_operand" "=e")
5280 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5281 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5283 [(set_attr "type" "fp")])
5285 (define_expand "floatunsditf2"
5286 [(set (match_operand:TF 0 "register_operand" "=e")
5287 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5288 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5293 if (GET_CODE (operands[1]) != MEM)
5294 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5296 slot0 = operands[1];
5298 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5300 XEXP (slot0, 0), Pmode,
5301 operands[1], DImode);
5303 if (GET_CODE (operands[0]) != MEM)
5304 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5308 ;; Convert a float to an actual integer.
5309 ;; Truncation is performed as part of the conversion.
5311 (define_insn "fix_truncsfsi2"
5312 [(set (match_operand:SI 0 "register_operand" "=f")
5313 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5316 [(set_attr "type" "fp")
5317 (set_attr "fptype" "double")])
5319 (define_insn "fix_truncdfsi2"
5320 [(set (match_operand:SI 0 "register_operand" "=f")
5321 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5324 [(set_attr "type" "fp")
5325 (set_attr "fptype" "double")])
5327 (define_expand "fix_trunctfsi2"
5328 [(set (match_operand:SI 0 "register_operand" "=f")
5329 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5330 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5333 if (! TARGET_HARD_QUAD)
5337 if (GET_CODE (operands[1]) != MEM)
5339 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5340 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5343 slot0 = operands[1];
5345 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5346 operands[0], 0, SImode, 1,
5347 XEXP (slot0, 0), Pmode);
5352 (define_insn "*fix_trunctfsi2_hq"
5353 [(set (match_operand:SI 0 "register_operand" "=f")
5354 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5355 "TARGET_FPU && TARGET_HARD_QUAD"
5357 [(set_attr "type" "fp")])
5359 (define_expand "fixuns_trunctfsi2"
5360 [(set (match_operand:SI 0 "register_operand" "=f")
5361 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5362 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5367 if (GET_CODE (operands[1]) != MEM)
5369 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5370 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5373 slot0 = operands[1];
5375 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5376 operands[0], 0, SImode, 1,
5377 XEXP (slot0, 0), Pmode);
5381 ;; Now the same, for V9 targets
5383 (define_insn "fix_truncsfdi2"
5384 [(set (match_operand:DI 0 "register_operand" "=e")
5385 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5386 "TARGET_V9 && TARGET_FPU"
5388 [(set_attr "type" "fp")
5389 (set_attr "fptype" "double")])
5391 (define_insn "fix_truncdfdi2"
5392 [(set (match_operand:DI 0 "register_operand" "=e")
5393 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5394 "TARGET_V9 && TARGET_FPU"
5396 [(set_attr "type" "fp")
5397 (set_attr "fptype" "double")])
5399 (define_expand "fix_trunctfdi2"
5400 [(set (match_operand:DI 0 "register_operand" "=e")
5401 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5402 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5405 if (! TARGET_HARD_QUAD)
5409 if (GET_CODE (operands[1]) != MEM)
5411 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5412 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5415 slot0 = operands[1];
5417 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5418 operands[0], 0, DImode, 1,
5419 XEXP (slot0, 0), Pmode);
5424 (define_insn "*fix_trunctfdi2_hq"
5425 [(set (match_operand:DI 0 "register_operand" "=e")
5426 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5427 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5429 [(set_attr "type" "fp")])
5431 (define_expand "fixuns_trunctfdi2"
5432 [(set (match_operand:DI 0 "register_operand" "=f")
5433 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5434 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5439 if (GET_CODE (operands[1]) != MEM)
5441 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5442 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5445 slot0 = operands[1];
5447 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5448 operands[0], 0, DImode, 1,
5449 XEXP (slot0, 0), Pmode);
5454 ;;- arithmetic instructions
5456 (define_expand "adddi3"
5457 [(set (match_operand:DI 0 "register_operand" "=r")
5458 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5459 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5465 if (! TARGET_ARCH64)
5467 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5468 gen_rtx_SET (VOIDmode, operands[0],
5469 gen_rtx_PLUS (DImode, operands[1],
5471 gen_rtx_CLOBBER (VOIDmode,
5472 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5475 if (arith_double_4096_operand(operands[2], DImode))
5477 switch (GET_CODE (operands[1]))
5479 case CONST_INT: i = INTVAL (operands[1]); break;
5480 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5482 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5483 gen_rtx_MINUS (DImode, operands[1],
5487 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5492 (define_insn "adddi3_insn_sp32"
5493 [(set (match_operand:DI 0 "register_operand" "=r")
5494 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5495 (match_operand:DI 2 "arith_double_operand" "rHI")))
5496 (clobber (reg:CC 100))]
5499 [(set_attr "length" "2")])
5502 [(set (match_operand:DI 0 "register_operand" "")
5503 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5504 (match_operand:DI 2 "arith_double_operand" "")))
5505 (clobber (reg:CC 100))]
5506 "! TARGET_ARCH64 && reload_completed"
5507 [(parallel [(set (reg:CC_NOOV 100)
5508 (compare:CC_NOOV (plus:SI (match_dup 4)
5512 (plus:SI (match_dup 4) (match_dup 5)))])
5514 (plus:SI (plus:SI (match_dup 7)
5516 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5519 operands[3] = gen_lowpart (SImode, operands[0]);
5520 operands[4] = gen_lowpart (SImode, operands[1]);
5521 operands[5] = gen_lowpart (SImode, operands[2]);
5522 operands[6] = gen_highpart (SImode, operands[0]);
5523 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5524 #if HOST_BITS_PER_WIDE_INT == 32
5525 if (GET_CODE (operands[2]) == CONST_INT)
5527 if (INTVAL (operands[2]) < 0)
5528 operands[8] = constm1_rtx;
5530 operands[8] = const0_rtx;
5534 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5538 [(set (match_operand:DI 0 "register_operand" "")
5539 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5540 (match_operand:DI 2 "arith_double_operand" "")))
5541 (clobber (reg:CC 100))]
5542 "! TARGET_ARCH64 && reload_completed"
5543 [(parallel [(set (reg:CC_NOOV 100)
5544 (compare:CC_NOOV (minus:SI (match_dup 4)
5548 (minus:SI (match_dup 4) (match_dup 5)))])
5550 (minus:SI (minus:SI (match_dup 7)
5552 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5555 operands[3] = gen_lowpart (SImode, operands[0]);
5556 operands[4] = gen_lowpart (SImode, operands[1]);
5557 operands[5] = gen_lowpart (SImode, operands[2]);
5558 operands[6] = gen_highpart (SImode, operands[0]);
5559 operands[7] = gen_highpart (SImode, operands[1]);
5560 #if HOST_BITS_PER_WIDE_INT == 32
5561 if (GET_CODE (operands[2]) == CONST_INT)
5563 if (INTVAL (operands[2]) < 0)
5564 operands[8] = constm1_rtx;
5566 operands[8] = const0_rtx;
5570 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5573 ;; LTU here means "carry set"
5575 [(set (match_operand:SI 0 "register_operand" "=r")
5576 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5577 (match_operand:SI 2 "arith_operand" "rI"))
5578 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5581 [(set_attr "type" "misc")])
5583 (define_insn "*addx_extend_sp32"
5584 [(set (match_operand:DI 0 "register_operand" "=r")
5585 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5586 (match_operand:SI 2 "arith_operand" "rI"))
5587 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5590 [(set_attr "length" "2")])
5593 [(set (match_operand:DI 0 "register_operand" "")
5594 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5595 (match_operand:SI 2 "arith_operand" ""))
5596 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5597 "! TARGET_ARCH64 && reload_completed"
5598 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5599 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5600 (set (match_dup 4) (const_int 0))]
5601 "operands[3] = gen_lowpart (SImode, operands[0]);
5602 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5604 (define_insn "*addx_extend_sp64"
5605 [(set (match_operand:DI 0 "register_operand" "=r")
5606 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5607 (match_operand:SI 2 "arith_operand" "rI"))
5608 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5610 "addx\\t%r1, %2, %0"
5611 [(set_attr "type" "misc")])
5614 [(set (match_operand:SI 0 "register_operand" "=r")
5615 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5616 (match_operand:SI 2 "arith_operand" "rI"))
5617 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5619 "subx\\t%r1, %2, %0"
5620 [(set_attr "type" "misc")])
5622 (define_insn "*subx_extend_sp64"
5623 [(set (match_operand:DI 0 "register_operand" "=r")
5624 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5625 (match_operand:SI 2 "arith_operand" "rI"))
5626 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5628 "subx\\t%r1, %2, %0"
5629 [(set_attr "type" "misc")])
5631 (define_insn "*subx_extend"
5632 [(set (match_operand:DI 0 "register_operand" "=r")
5633 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5634 (match_operand:SI 2 "arith_operand" "rI"))
5635 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5638 [(set_attr "length" "2")])
5641 [(set (match_operand:DI 0 "register_operand" "")
5642 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5643 (match_operand:SI 2 "arith_operand" ""))
5644 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5645 "! TARGET_ARCH64 && reload_completed"
5646 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5647 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5648 (set (match_dup 4) (const_int 0))]
5649 "operands[3] = gen_lowpart (SImode, operands[0]);
5650 operands[4] = gen_highpart (SImode, operands[0]);")
5653 [(set (match_operand:DI 0 "register_operand" "=r")
5654 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5655 (match_operand:DI 2 "register_operand" "r")))
5656 (clobber (reg:CC 100))]
5659 [(set_attr "length" "2")])
5662 [(set (match_operand:DI 0 "register_operand" "")
5663 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5664 (match_operand:DI 2 "register_operand" "")))
5665 (clobber (reg:CC 100))]
5666 "! TARGET_ARCH64 && reload_completed"
5667 [(parallel [(set (reg:CC_NOOV 100)
5668 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5670 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5672 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5673 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5674 "operands[3] = gen_lowpart (SImode, operands[2]);
5675 operands[4] = gen_highpart (SImode, operands[2]);
5676 operands[5] = gen_lowpart (SImode, operands[0]);
5677 operands[6] = gen_highpart (SImode, operands[0]);")
5679 (define_insn "*adddi3_sp64"
5680 [(set (match_operand:DI 0 "register_operand" "=r")
5681 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5682 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5686 (define_expand "addsi3"
5687 [(set (match_operand:SI 0 "register_operand" "=r,d")
5688 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5689 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5693 if (arith_4096_operand(operands[2], SImode))
5695 if (GET_CODE (operands[1]) == CONST_INT)
5696 emit_insn (gen_movsi (operands[0],
5697 GEN_INT (INTVAL (operands[1]) + 4096)));
5699 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5700 gen_rtx_MINUS (SImode, operands[1],
5706 (define_insn "*addsi3"
5707 [(set (match_operand:SI 0 "register_operand" "=r,d")
5708 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5709 (match_operand:SI 2 "arith_operand" "rI,d")))]
5713 fpadd32s\\t%1, %2, %0"
5714 [(set_attr "type" "*,fp")])
5716 (define_insn "*cmp_cc_plus"
5717 [(set (reg:CC_NOOV 100)
5718 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5719 (match_operand:SI 1 "arith_operand" "rI"))
5722 "addcc\\t%0, %1, %%g0"
5723 [(set_attr "type" "compare")])
5725 (define_insn "*cmp_ccx_plus"
5726 [(set (reg:CCX_NOOV 100)
5727 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5728 (match_operand:DI 1 "arith_double_operand" "rHI"))
5731 "addcc\\t%0, %1, %%g0"
5732 [(set_attr "type" "compare")])
5734 (define_insn "*cmp_cc_plus_set"
5735 [(set (reg:CC_NOOV 100)
5736 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5737 (match_operand:SI 2 "arith_operand" "rI"))
5739 (set (match_operand:SI 0 "register_operand" "=r")
5740 (plus:SI (match_dup 1) (match_dup 2)))]
5742 "addcc\\t%1, %2, %0"
5743 [(set_attr "type" "compare")])
5745 (define_insn "*cmp_ccx_plus_set"
5746 [(set (reg:CCX_NOOV 100)
5747 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5748 (match_operand:DI 2 "arith_double_operand" "rHI"))
5750 (set (match_operand:DI 0 "register_operand" "=r")
5751 (plus:DI (match_dup 1) (match_dup 2)))]
5753 "addcc\\t%1, %2, %0"
5754 [(set_attr "type" "compare")])
5756 (define_expand "subdi3"
5757 [(set (match_operand:DI 0 "register_operand" "=r")
5758 (minus:DI (match_operand:DI 1 "register_operand" "r")
5759 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5763 if (! TARGET_ARCH64)
5765 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5766 gen_rtx_SET (VOIDmode, operands[0],
5767 gen_rtx_MINUS (DImode, operands[1],
5769 gen_rtx_CLOBBER (VOIDmode,
5770 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5773 if (arith_double_4096_operand(operands[2], DImode))
5775 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5776 gen_rtx_PLUS (DImode, operands[1],
5782 (define_insn "*subdi3_sp32"
5783 [(set (match_operand:DI 0 "register_operand" "=r")
5784 (minus:DI (match_operand:DI 1 "register_operand" "r")
5785 (match_operand:DI 2 "arith_double_operand" "rHI")))
5786 (clobber (reg:CC 100))]
5789 [(set_attr "length" "2")])
5792 [(set (match_operand:DI 0 "register_operand" "")
5793 (minus:DI (match_operand:DI 1 "register_operand" "")
5794 (match_operand:DI 2 "arith_double_operand" "")))
5795 (clobber (reg:CC 100))]
5798 && (GET_CODE (operands[2]) == CONST_INT
5799 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5800 [(clobber (const_int 0))]
5805 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5806 lowp = gen_lowpart (SImode, operands[2]);
5807 if ((lowp == const0_rtx)
5808 && (operands[0] == operands[1]))
5810 emit_insn (gen_rtx_SET (VOIDmode,
5811 gen_highpart (SImode, operands[0]),
5812 gen_rtx_MINUS (SImode,
5813 gen_highpart_mode (SImode, DImode,
5819 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5820 gen_lowpart (SImode, operands[1]),
5822 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5823 gen_highpart_mode (SImode, DImode, operands[1]),
5830 [(set (match_operand:DI 0 "register_operand" "")
5831 (minus:DI (match_operand:DI 1 "register_operand" "")
5832 (match_operand:DI 2 "register_operand" "")))
5833 (clobber (reg:CC 100))]
5835 && reload_completed"
5836 [(clobber (const_int 0))]
5839 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5840 gen_lowpart (SImode, operands[1]),
5841 gen_lowpart (SImode, operands[2])));
5842 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5843 gen_highpart (SImode, operands[1]),
5844 gen_highpart (SImode, operands[2])));
5849 [(set (match_operand:DI 0 "register_operand" "=r")
5850 (minus:DI (match_operand:DI 1 "register_operand" "r")
5851 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5852 (clobber (reg:CC 100))]
5855 [(set_attr "length" "2")])
5858 [(set (match_operand:DI 0 "register_operand" "")
5859 (minus:DI (match_operand:DI 1 "register_operand" "")
5860 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5861 (clobber (reg:CC 100))]
5862 "! TARGET_ARCH64 && reload_completed"
5863 [(parallel [(set (reg:CC_NOOV 100)
5864 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5866 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5868 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5869 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5870 "operands[3] = gen_lowpart (SImode, operands[1]);
5871 operands[4] = gen_highpart (SImode, operands[1]);
5872 operands[5] = gen_lowpart (SImode, operands[0]);
5873 operands[6] = gen_highpart (SImode, operands[0]);")
5875 (define_insn "*subdi3_sp64"
5876 [(set (match_operand:DI 0 "register_operand" "=r")
5877 (minus:DI (match_operand:DI 1 "register_operand" "r")
5878 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5882 (define_expand "subsi3"
5883 [(set (match_operand:SI 0 "register_operand" "=r,d")
5884 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5885 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5889 if (arith_4096_operand(operands[2], SImode))
5891 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5892 gen_rtx_PLUS (SImode, operands[1],
5898 (define_insn "*subsi3"
5899 [(set (match_operand:SI 0 "register_operand" "=r,d")
5900 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5901 (match_operand:SI 2 "arith_operand" "rI,d")))]
5905 fpsub32s\\t%1, %2, %0"
5906 [(set_attr "type" "*,fp")])
5908 (define_insn "*cmp_minus_cc"
5909 [(set (reg:CC_NOOV 100)
5910 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5911 (match_operand:SI 1 "arith_operand" "rI"))
5914 "subcc\\t%r0, %1, %%g0"
5915 [(set_attr "type" "compare")])
5917 (define_insn "*cmp_minus_ccx"
5918 [(set (reg:CCX_NOOV 100)
5919 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5920 (match_operand:DI 1 "arith_double_operand" "rHI"))
5923 "subcc\\t%0, %1, %%g0"
5924 [(set_attr "type" "compare")])
5926 (define_insn "cmp_minus_cc_set"
5927 [(set (reg:CC_NOOV 100)
5928 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5929 (match_operand:SI 2 "arith_operand" "rI"))
5931 (set (match_operand:SI 0 "register_operand" "=r")
5932 (minus:SI (match_dup 1) (match_dup 2)))]
5934 "subcc\\t%r1, %2, %0"
5935 [(set_attr "type" "compare")])
5937 (define_insn "*cmp_minus_ccx_set"
5938 [(set (reg:CCX_NOOV 100)
5939 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5940 (match_operand:DI 2 "arith_double_operand" "rHI"))
5942 (set (match_operand:DI 0 "register_operand" "=r")
5943 (minus:DI (match_dup 1) (match_dup 2)))]
5945 "subcc\\t%1, %2, %0"
5946 [(set_attr "type" "compare")])
5948 ;; Integer Multiply/Divide.
5950 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5951 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5953 (define_insn "mulsi3"
5954 [(set (match_operand:SI 0 "register_operand" "=r")
5955 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5956 (match_operand:SI 2 "arith_operand" "rI")))]
5959 [(set_attr "type" "imul")])
5961 (define_expand "muldi3"
5962 [(set (match_operand:DI 0 "register_operand" "=r")
5963 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5964 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5965 "TARGET_ARCH64 || TARGET_V8PLUS"
5970 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5975 (define_insn "*muldi3_sp64"
5976 [(set (match_operand:DI 0 "register_operand" "=r")
5977 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5978 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5981 [(set_attr "type" "imul")])
5983 ;; V8plus wide multiply.
5985 (define_insn "muldi3_v8plus"
5986 [(set (match_operand:DI 0 "register_operand" "=r,h")
5987 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5988 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5989 (clobber (match_scratch:SI 3 "=&h,X"))
5990 (clobber (match_scratch:SI 4 "=&h,X"))]
5994 if (sparc_check_64 (operands[1], insn) <= 0)
5995 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5996 if (which_alternative == 1)
5997 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5998 if (GET_CODE (operands[2]) == CONST_INT)
6000 if (which_alternative == 1)
6001 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6003 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\";
6005 if (sparc_check_64 (operands[2], insn) <= 0)
6006 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6007 if (which_alternative == 1)
6008 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\";
6010 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\";
6012 [(set_attr "type" "multi")
6013 (set_attr "length" "9,8")])
6015 (define_insn "*cmp_mul_set"
6017 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6018 (match_operand:SI 2 "arith_operand" "rI"))
6020 (set (match_operand:SI 0 "register_operand" "=r")
6021 (mult:SI (match_dup 1) (match_dup 2)))]
6022 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6023 "smulcc\\t%1, %2, %0"
6024 [(set_attr "type" "imul")])
6026 (define_expand "mulsidi3"
6027 [(set (match_operand:DI 0 "register_operand" "")
6028 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6029 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6033 if (CONSTANT_P (operands[2]))
6036 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6039 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6045 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6050 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6051 ;; registers can hold 64 bit values in the V8plus environment.
6053 (define_insn "mulsidi3_v8plus"
6054 [(set (match_operand:DI 0 "register_operand" "=h,r")
6055 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6056 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6057 (clobber (match_scratch:SI 3 "=X,&h"))]
6060 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6061 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6062 [(set_attr "type" "multi")
6063 (set_attr "length" "2,3")])
6066 (define_insn "const_mulsidi3_v8plus"
6067 [(set (match_operand:DI 0 "register_operand" "=h,r")
6068 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6069 (match_operand:SI 2 "small_int" "I,I")))
6070 (clobber (match_scratch:SI 3 "=X,&h"))]
6073 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6074 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6075 [(set_attr "type" "multi")
6076 (set_attr "length" "2,3")])
6079 (define_insn "*mulsidi3_sp32"
6080 [(set (match_operand:DI 0 "register_operand" "=r")
6081 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6082 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6086 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6089 (if_then_else (eq_attr "isa" "sparclet")
6090 (const_string "imul") (const_string "multi")))
6091 (set (attr "length")
6092 (if_then_else (eq_attr "isa" "sparclet")
6093 (const_int 1) (const_int 2)))])
6095 (define_insn "*mulsidi3_sp64"
6096 [(set (match_operand:DI 0 "register_operand" "=r")
6097 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6098 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6099 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6101 [(set_attr "type" "imul")])
6103 ;; Extra pattern, because sign_extend of a constant isn't valid.
6106 (define_insn "const_mulsidi3_sp32"
6107 [(set (match_operand:DI 0 "register_operand" "=r")
6108 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6109 (match_operand:SI 2 "small_int" "I")))]
6113 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6116 (if_then_else (eq_attr "isa" "sparclet")
6117 (const_string "imul") (const_string "multi")))
6118 (set (attr "length")
6119 (if_then_else (eq_attr "isa" "sparclet")
6120 (const_int 1) (const_int 2)))])
6122 (define_insn "const_mulsidi3_sp64"
6123 [(set (match_operand:DI 0 "register_operand" "=r")
6124 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6125 (match_operand:SI 2 "small_int" "I")))]
6126 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6128 [(set_attr "type" "imul")])
6130 (define_expand "smulsi3_highpart"
6131 [(set (match_operand:SI 0 "register_operand" "")
6133 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6134 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6136 "TARGET_HARD_MUL && TARGET_ARCH32"
6139 if (CONSTANT_P (operands[2]))
6143 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6149 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6154 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6155 operands[2], GEN_INT (32)));
6161 (define_insn "smulsi3_highpart_v8plus"
6162 [(set (match_operand:SI 0 "register_operand" "=h,r")
6164 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6165 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6166 (match_operand:SI 3 "const_int_operand" "i,i"))))
6167 (clobber (match_scratch:SI 4 "=X,&h"))]
6170 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6171 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6172 [(set_attr "type" "multi")
6173 (set_attr "length" "2")])
6175 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6178 [(set (match_operand:SI 0 "register_operand" "=h,r")
6181 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6182 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6183 (match_operand:SI 3 "const_int_operand" "i,i"))
6185 (clobber (match_scratch:SI 4 "=X,&h"))]
6188 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6189 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6190 [(set_attr "type" "multi")
6191 (set_attr "length" "2")])
6194 (define_insn "const_smulsi3_highpart_v8plus"
6195 [(set (match_operand:SI 0 "register_operand" "=h,r")
6197 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6198 (match_operand 2 "small_int" "i,i"))
6199 (match_operand:SI 3 "const_int_operand" "i,i"))))
6200 (clobber (match_scratch:SI 4 "=X,&h"))]
6203 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6204 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6205 [(set_attr "type" "multi")
6206 (set_attr "length" "2")])
6209 (define_insn "*smulsi3_highpart_sp32"
6210 [(set (match_operand:SI 0 "register_operand" "=r")
6212 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6213 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6216 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6217 [(set_attr "type" "multi")
6218 (set_attr "length" "2")])
6221 (define_insn "const_smulsi3_highpart"
6222 [(set (match_operand:SI 0 "register_operand" "=r")
6224 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6225 (match_operand:SI 2 "register_operand" "r"))
6228 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6229 [(set_attr "type" "multi")
6230 (set_attr "length" "2")])
6232 (define_expand "umulsidi3"
6233 [(set (match_operand:DI 0 "register_operand" "")
6234 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6235 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6239 if (CONSTANT_P (operands[2]))
6242 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6245 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6251 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6257 (define_insn "umulsidi3_v8plus"
6258 [(set (match_operand:DI 0 "register_operand" "=h,r")
6259 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6260 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6261 (clobber (match_scratch:SI 3 "=X,&h"))]
6264 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6265 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6266 [(set_attr "type" "multi")
6267 (set_attr "length" "2,3")])
6270 (define_insn "*umulsidi3_sp32"
6271 [(set (match_operand:DI 0 "register_operand" "=r")
6272 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6273 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6277 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6280 (if_then_else (eq_attr "isa" "sparclet")
6281 (const_string "imul") (const_string "multi")))
6282 (set (attr "length")
6283 (if_then_else (eq_attr "isa" "sparclet")
6284 (const_int 1) (const_int 2)))])
6286 (define_insn "*umulsidi3_sp64"
6287 [(set (match_operand:DI 0 "register_operand" "=r")
6288 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6289 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6290 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6292 [(set_attr "type" "imul")])
6294 ;; Extra pattern, because sign_extend of a constant isn't valid.
6297 (define_insn "const_umulsidi3_sp32"
6298 [(set (match_operand:DI 0 "register_operand" "=r")
6299 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6300 (match_operand:SI 2 "uns_small_int" "")))]
6304 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6307 (if_then_else (eq_attr "isa" "sparclet")
6308 (const_string "imul") (const_string "multi")))
6309 (set (attr "length")
6310 (if_then_else (eq_attr "isa" "sparclet")
6311 (const_int 1) (const_int 2)))])
6313 (define_insn "const_umulsidi3_sp64"
6314 [(set (match_operand:DI 0 "register_operand" "=r")
6315 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6316 (match_operand:SI 2 "uns_small_int" "")))]
6317 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6319 [(set_attr "type" "imul")])
6322 (define_insn "const_umulsidi3_v8plus"
6323 [(set (match_operand:DI 0 "register_operand" "=h,r")
6324 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6325 (match_operand:SI 2 "uns_small_int" "")))
6326 (clobber (match_scratch:SI 3 "=X,h"))]
6329 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6330 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6331 [(set_attr "type" "multi")
6332 (set_attr "length" "2,3")])
6334 (define_expand "umulsi3_highpart"
6335 [(set (match_operand:SI 0 "register_operand" "")
6337 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6338 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6340 "TARGET_HARD_MUL && TARGET_ARCH32"
6343 if (CONSTANT_P (operands[2]))
6347 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6353 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6358 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6359 operands[2], GEN_INT (32)));
6365 (define_insn "umulsi3_highpart_v8plus"
6366 [(set (match_operand:SI 0 "register_operand" "=h,r")
6368 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6369 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6370 (match_operand:SI 3 "const_int_operand" "i,i"))))
6371 (clobber (match_scratch:SI 4 "=X,h"))]
6374 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6375 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6376 [(set_attr "type" "multi")
6377 (set_attr "length" "2")])
6380 (define_insn "const_umulsi3_highpart_v8plus"
6381 [(set (match_operand:SI 0 "register_operand" "=h,r")
6383 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6384 (match_operand:SI 2 "uns_small_int" ""))
6385 (match_operand:SI 3 "const_int_operand" "i,i"))))
6386 (clobber (match_scratch:SI 4 "=X,h"))]
6389 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6390 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6391 [(set_attr "type" "multi")
6392 (set_attr "length" "2")])
6395 (define_insn "*umulsi3_highpart_sp32"
6396 [(set (match_operand:SI 0 "register_operand" "=r")
6398 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6399 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6402 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6403 [(set_attr "type" "multi")
6404 (set_attr "length" "2")])
6407 (define_insn "const_umulsi3_highpart"
6408 [(set (match_operand:SI 0 "register_operand" "=r")
6410 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6411 (match_operand:SI 2 "uns_small_int" ""))
6414 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6415 [(set_attr "type" "multi")
6416 (set_attr "length" "2")])
6418 ;; The v8 architecture specifies that there must be 3 instructions between
6419 ;; a y register write and a use of it for correct results.
6421 (define_expand "divsi3"
6422 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6423 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6424 (match_operand:SI 2 "input_operand" "rI,m")))
6425 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6426 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6431 operands[3] = gen_reg_rtx(SImode);
6432 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6433 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6439 (define_insn "divsi3_sp32"
6440 [(set (match_operand:SI 0 "register_operand" "=r,r")
6441 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6442 (match_operand:SI 2 "input_operand" "rI,m")))
6443 (clobber (match_scratch:SI 3 "=&r,&r"))]
6444 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6448 if (which_alternative == 0)
6450 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6452 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6455 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6457 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\";
6459 [(set_attr "type" "multi")
6460 (set (attr "length")
6461 (if_then_else (eq_attr "isa" "v9")
6462 (const_int 4) (const_int 6)))])
6464 (define_insn "divsi3_sp64"
6465 [(set (match_operand:SI 0 "register_operand" "=r")
6466 (div:SI (match_operand:SI 1 "register_operand" "r")
6467 (match_operand:SI 2 "input_operand" "rI")))
6468 (use (match_operand:SI 3 "register_operand" "r"))]
6469 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6470 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6471 [(set_attr "type" "multi")
6472 (set_attr "length" "2")])
6474 (define_insn "divdi3"
6475 [(set (match_operand:DI 0 "register_operand" "=r")
6476 (div:DI (match_operand:DI 1 "register_operand" "r")
6477 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6479 "sdivx\\t%1, %2, %0"
6480 [(set_attr "type" "idiv")])
6482 (define_insn "*cmp_sdiv_cc_set"
6484 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6485 (match_operand:SI 2 "arith_operand" "rI"))
6487 (set (match_operand:SI 0 "register_operand" "=r")
6488 (div:SI (match_dup 1) (match_dup 2)))
6489 (clobber (match_scratch:SI 3 "=&r"))]
6490 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6494 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6496 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6498 [(set_attr "type" "multi")
6499 (set (attr "length")
6500 (if_then_else (eq_attr "isa" "v9")
6501 (const_int 3) (const_int 6)))])
6504 (define_expand "udivsi3"
6505 [(set (match_operand:SI 0 "register_operand" "")
6506 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6507 (match_operand:SI 2 "input_operand" "")))]
6508 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6511 (define_insn "udivsi3_sp32"
6512 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6513 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6514 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6516 || TARGET_DEPRECATED_V8_INSNS)
6520 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6521 switch (which_alternative)
6524 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6526 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6528 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6531 [(set_attr "type" "multi")
6532 (set_attr "length" "5")])
6534 (define_insn "udivsi3_sp64"
6535 [(set (match_operand:SI 0 "register_operand" "=r")
6536 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6537 (match_operand:SI 2 "input_operand" "rI")))]
6538 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6539 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6540 [(set_attr "type" "multi")
6541 (set_attr "length" "2")])
6543 (define_insn "udivdi3"
6544 [(set (match_operand:DI 0 "register_operand" "=r")
6545 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6546 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6548 "udivx\\t%1, %2, %0"
6549 [(set_attr "type" "idiv")])
6551 (define_insn "*cmp_udiv_cc_set"
6553 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6554 (match_operand:SI 2 "arith_operand" "rI"))
6556 (set (match_operand:SI 0 "register_operand" "=r")
6557 (udiv:SI (match_dup 1) (match_dup 2)))]
6559 || TARGET_DEPRECATED_V8_INSNS"
6563 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6565 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6567 [(set_attr "type" "multi")
6568 (set (attr "length")
6569 (if_then_else (eq_attr "isa" "v9")
6570 (const_int 2) (const_int 5)))])
6572 ; sparclet multiply/accumulate insns
6574 (define_insn "*smacsi"
6575 [(set (match_operand:SI 0 "register_operand" "=r")
6576 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6577 (match_operand:SI 2 "arith_operand" "rI"))
6578 (match_operand:SI 3 "register_operand" "0")))]
6581 [(set_attr "type" "imul")])
6583 (define_insn "*smacdi"
6584 [(set (match_operand:DI 0 "register_operand" "=r")
6585 (plus:DI (mult:DI (sign_extend:DI
6586 (match_operand:SI 1 "register_operand" "%r"))
6588 (match_operand:SI 2 "register_operand" "r")))
6589 (match_operand:DI 3 "register_operand" "0")))]
6591 "smacd\\t%1, %2, %L0"
6592 [(set_attr "type" "imul")])
6594 (define_insn "*umacdi"
6595 [(set (match_operand:DI 0 "register_operand" "=r")
6596 (plus:DI (mult:DI (zero_extend:DI
6597 (match_operand:SI 1 "register_operand" "%r"))
6599 (match_operand:SI 2 "register_operand" "r")))
6600 (match_operand:DI 3 "register_operand" "0")))]
6602 "umacd\\t%1, %2, %L0"
6603 [(set_attr "type" "imul")])
6605 ;;- Boolean instructions
6606 ;; We define DImode `and' so with DImode `not' we can get
6607 ;; DImode `andn'. Other combinations are possible.
6609 (define_expand "anddi3"
6610 [(set (match_operand:DI 0 "register_operand" "")
6611 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6612 (match_operand:DI 2 "arith_double_operand" "")))]
6616 (define_insn "*anddi3_sp32"
6617 [(set (match_operand:DI 0 "register_operand" "=r,b")
6618 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6619 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6624 [(set_attr "type" "*,fp")
6625 (set_attr "length" "2,*")
6626 (set_attr "fptype" "double")])
6628 (define_insn "*anddi3_sp64"
6629 [(set (match_operand:DI 0 "register_operand" "=r,b")
6630 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6631 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6636 [(set_attr "type" "*,fp")
6637 (set_attr "fptype" "double")])
6639 (define_insn "andsi3"
6640 [(set (match_operand:SI 0 "register_operand" "=r,d")
6641 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6642 (match_operand:SI 2 "arith_operand" "rI,d")))]
6647 [(set_attr "type" "*,fp")])
6650 [(set (match_operand:SI 0 "register_operand" "")
6651 (and:SI (match_operand:SI 1 "register_operand" "")
6652 (match_operand:SI 2 "" "")))
6653 (clobber (match_operand:SI 3 "register_operand" ""))]
6654 "GET_CODE (operands[2]) == CONST_INT
6655 && !SMALL_INT32 (operands[2])
6656 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6657 [(set (match_dup 3) (match_dup 4))
6658 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6661 operands[4] = GEN_INT (~INTVAL (operands[2]));
6664 ;; Split DImode logical operations requiring two instructions.
6666 [(set (match_operand:DI 0 "register_operand" "")
6667 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6668 [(match_operand:DI 2 "register_operand" "")
6669 (match_operand:DI 3 "arith_double_operand" "")]))]
6672 && ((GET_CODE (operands[0]) == REG
6673 && REGNO (operands[0]) < 32)
6674 || (GET_CODE (operands[0]) == SUBREG
6675 && GET_CODE (SUBREG_REG (operands[0])) == REG
6676 && REGNO (SUBREG_REG (operands[0])) < 32))"
6677 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6678 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6681 operands[4] = gen_highpart (SImode, operands[0]);
6682 operands[5] = gen_lowpart (SImode, operands[0]);
6683 operands[6] = gen_highpart (SImode, operands[2]);
6684 operands[7] = gen_lowpart (SImode, operands[2]);
6685 #if HOST_BITS_PER_WIDE_INT == 32
6686 if (GET_CODE (operands[3]) == CONST_INT)
6688 if (INTVAL (operands[3]) < 0)
6689 operands[8] = constm1_rtx;
6691 operands[8] = const0_rtx;
6695 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6696 operands[9] = gen_lowpart (SImode, operands[3]);
6699 (define_insn "*and_not_di_sp32"
6700 [(set (match_operand:DI 0 "register_operand" "=r,b")
6701 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6702 (match_operand:DI 2 "register_operand" "r,b")))]
6706 fandnot1\\t%1, %2, %0"
6707 [(set_attr "type" "*,fp")
6708 (set_attr "length" "2,*")
6709 (set_attr "fptype" "double")])
6712 [(set (match_operand:DI 0 "register_operand" "")
6713 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6714 (match_operand:DI 2 "register_operand" "")))]
6717 && ((GET_CODE (operands[0]) == REG
6718 && REGNO (operands[0]) < 32)
6719 || (GET_CODE (operands[0]) == SUBREG
6720 && GET_CODE (SUBREG_REG (operands[0])) == REG
6721 && REGNO (SUBREG_REG (operands[0])) < 32))"
6722 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6723 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6724 "operands[3] = gen_highpart (SImode, operands[0]);
6725 operands[4] = gen_highpart (SImode, operands[1]);
6726 operands[5] = gen_highpart (SImode, operands[2]);
6727 operands[6] = gen_lowpart (SImode, operands[0]);
6728 operands[7] = gen_lowpart (SImode, operands[1]);
6729 operands[8] = gen_lowpart (SImode, operands[2]);")
6731 (define_insn "*and_not_di_sp64"
6732 [(set (match_operand:DI 0 "register_operand" "=r,b")
6733 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6734 (match_operand:DI 2 "register_operand" "r,b")))]
6738 fandnot1\\t%1, %2, %0"
6739 [(set_attr "type" "*,fp")
6740 (set_attr "fptype" "double")])
6742 (define_insn "*and_not_si"
6743 [(set (match_operand:SI 0 "register_operand" "=r,d")
6744 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6745 (match_operand:SI 2 "register_operand" "r,d")))]
6749 fandnot1s\\t%1, %2, %0"
6750 [(set_attr "type" "*,fp")])
6752 (define_expand "iordi3"
6753 [(set (match_operand:DI 0 "register_operand" "")
6754 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6755 (match_operand:DI 2 "arith_double_operand" "")))]
6759 (define_insn "*iordi3_sp32"
6760 [(set (match_operand:DI 0 "register_operand" "=r,b")
6761 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6762 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6767 [(set_attr "type" "*,fp")
6768 (set_attr "length" "2,*")
6769 (set_attr "fptype" "double")])
6771 (define_insn "*iordi3_sp64"
6772 [(set (match_operand:DI 0 "register_operand" "=r,b")
6773 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6774 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6779 [(set_attr "type" "*,fp")
6780 (set_attr "fptype" "double")])
6782 (define_insn "iorsi3"
6783 [(set (match_operand:SI 0 "register_operand" "=r,d")
6784 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6785 (match_operand:SI 2 "arith_operand" "rI,d")))]
6790 [(set_attr "type" "*,fp")])
6793 [(set (match_operand:SI 0 "register_operand" "")
6794 (ior:SI (match_operand:SI 1 "register_operand" "")
6795 (match_operand:SI 2 "" "")))
6796 (clobber (match_operand:SI 3 "register_operand" ""))]
6797 "GET_CODE (operands[2]) == CONST_INT
6798 && !SMALL_INT32 (operands[2])
6799 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6800 [(set (match_dup 3) (match_dup 4))
6801 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6804 operands[4] = GEN_INT (~INTVAL (operands[2]));
6807 (define_insn "*or_not_di_sp32"
6808 [(set (match_operand:DI 0 "register_operand" "=r,b")
6809 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6810 (match_operand:DI 2 "register_operand" "r,b")))]
6814 fornot1\\t%1, %2, %0"
6815 [(set_attr "type" "*,fp")
6816 (set_attr "length" "2,*")
6817 (set_attr "fptype" "double")])
6820 [(set (match_operand:DI 0 "register_operand" "")
6821 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6822 (match_operand:DI 2 "register_operand" "")))]
6825 && ((GET_CODE (operands[0]) == REG
6826 && REGNO (operands[0]) < 32)
6827 || (GET_CODE (operands[0]) == SUBREG
6828 && GET_CODE (SUBREG_REG (operands[0])) == REG
6829 && REGNO (SUBREG_REG (operands[0])) < 32))"
6830 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6831 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6832 "operands[3] = gen_highpart (SImode, operands[0]);
6833 operands[4] = gen_highpart (SImode, operands[1]);
6834 operands[5] = gen_highpart (SImode, operands[2]);
6835 operands[6] = gen_lowpart (SImode, operands[0]);
6836 operands[7] = gen_lowpart (SImode, operands[1]);
6837 operands[8] = gen_lowpart (SImode, operands[2]);")
6839 (define_insn "*or_not_di_sp64"
6840 [(set (match_operand:DI 0 "register_operand" "=r,b")
6841 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6842 (match_operand:DI 2 "register_operand" "r,b")))]
6846 fornot1\\t%1, %2, %0"
6847 [(set_attr "type" "*,fp")
6848 (set_attr "fptype" "double")])
6850 (define_insn "*or_not_si"
6851 [(set (match_operand:SI 0 "register_operand" "=r,d")
6852 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6853 (match_operand:SI 2 "register_operand" "r,d")))]
6857 fornot1s\\t%1, %2, %0"
6858 [(set_attr "type" "*,fp")])
6860 (define_expand "xordi3"
6861 [(set (match_operand:DI 0 "register_operand" "")
6862 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6863 (match_operand:DI 2 "arith_double_operand" "")))]
6867 (define_insn "*xordi3_sp32"
6868 [(set (match_operand:DI 0 "register_operand" "=r,b")
6869 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6870 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6875 [(set_attr "type" "*,fp")
6876 (set_attr "length" "2,*")
6877 (set_attr "fptype" "double")])
6879 (define_insn "*xordi3_sp64"
6880 [(set (match_operand:DI 0 "register_operand" "=r,b")
6881 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6882 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6887 [(set_attr "type" "*,fp")
6888 (set_attr "fptype" "double")])
6890 (define_insn "*xordi3_sp64_dbl"
6891 [(set (match_operand:DI 0 "register_operand" "=r")
6892 (xor:DI (match_operand:DI 1 "register_operand" "r")
6893 (match_operand:DI 2 "const64_operand" "")))]
6895 && HOST_BITS_PER_WIDE_INT != 64)"
6898 (define_insn "xorsi3"
6899 [(set (match_operand:SI 0 "register_operand" "=r,d")
6900 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6901 (match_operand:SI 2 "arith_operand" "rI,d")))]
6906 [(set_attr "type" "*,fp")])
6909 [(set (match_operand:SI 0 "register_operand" "")
6910 (xor:SI (match_operand:SI 1 "register_operand" "")
6911 (match_operand:SI 2 "" "")))
6912 (clobber (match_operand:SI 3 "register_operand" ""))]
6913 "GET_CODE (operands[2]) == CONST_INT
6914 && !SMALL_INT32 (operands[2])
6915 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6916 [(set (match_dup 3) (match_dup 4))
6917 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6920 operands[4] = GEN_INT (~INTVAL (operands[2]));
6924 [(set (match_operand:SI 0 "register_operand" "")
6925 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6926 (match_operand:SI 2 "" ""))))
6927 (clobber (match_operand:SI 3 "register_operand" ""))]
6928 "GET_CODE (operands[2]) == CONST_INT
6929 && !SMALL_INT32 (operands[2])
6930 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6931 [(set (match_dup 3) (match_dup 4))
6932 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6935 operands[4] = GEN_INT (~INTVAL (operands[2]));
6938 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6939 ;; Combine now canonicalizes to the rightmost expression.
6940 (define_insn "*xor_not_di_sp32"
6941 [(set (match_operand:DI 0 "register_operand" "=r,b")
6942 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6943 (match_operand:DI 2 "register_operand" "r,b"))))]
6948 [(set_attr "type" "*,fp")
6949 (set_attr "length" "2,*")
6950 (set_attr "fptype" "double")])
6953 [(set (match_operand:DI 0 "register_operand" "")
6954 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6955 (match_operand:DI 2 "register_operand" ""))))]
6958 && ((GET_CODE (operands[0]) == REG
6959 && REGNO (operands[0]) < 32)
6960 || (GET_CODE (operands[0]) == SUBREG
6961 && GET_CODE (SUBREG_REG (operands[0])) == REG
6962 && REGNO (SUBREG_REG (operands[0])) < 32))"
6963 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6964 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6965 "operands[3] = gen_highpart (SImode, operands[0]);
6966 operands[4] = gen_highpart (SImode, operands[1]);
6967 operands[5] = gen_highpart (SImode, operands[2]);
6968 operands[6] = gen_lowpart (SImode, operands[0]);
6969 operands[7] = gen_lowpart (SImode, operands[1]);
6970 operands[8] = gen_lowpart (SImode, operands[2]);")
6972 (define_insn "*xor_not_di_sp64"
6973 [(set (match_operand:DI 0 "register_operand" "=r,b")
6974 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6975 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6980 [(set_attr "type" "*,fp")
6981 (set_attr "fptype" "double")])
6983 (define_insn "*xor_not_si"
6984 [(set (match_operand:SI 0 "register_operand" "=r,d")
6985 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6986 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6990 fxnors\\t%1, %2, %0"
6991 [(set_attr "type" "*,fp")])
6993 ;; These correspond to the above in the case where we also (or only)
6994 ;; want to set the condition code.
6996 (define_insn "*cmp_cc_arith_op"
6999 (match_operator:SI 2 "cc_arithop"
7000 [(match_operand:SI 0 "arith_operand" "%r")
7001 (match_operand:SI 1 "arith_operand" "rI")])
7004 "%A2cc\\t%0, %1, %%g0"
7005 [(set_attr "type" "compare")])
7007 (define_insn "*cmp_ccx_arith_op"
7010 (match_operator:DI 2 "cc_arithop"
7011 [(match_operand:DI 0 "arith_double_operand" "%r")
7012 (match_operand:DI 1 "arith_double_operand" "rHI")])
7015 "%A2cc\\t%0, %1, %%g0"
7016 [(set_attr "type" "compare")])
7018 (define_insn "*cmp_cc_arith_op_set"
7021 (match_operator:SI 3 "cc_arithop"
7022 [(match_operand:SI 1 "arith_operand" "%r")
7023 (match_operand:SI 2 "arith_operand" "rI")])
7025 (set (match_operand:SI 0 "register_operand" "=r")
7026 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7027 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7028 "%A3cc\\t%1, %2, %0"
7029 [(set_attr "type" "compare")])
7031 (define_insn "*cmp_ccx_arith_op_set"
7034 (match_operator:DI 3 "cc_arithop"
7035 [(match_operand:DI 1 "arith_double_operand" "%r")
7036 (match_operand:DI 2 "arith_double_operand" "rHI")])
7038 (set (match_operand:DI 0 "register_operand" "=r")
7039 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7040 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7041 "%A3cc\\t%1, %2, %0"
7042 [(set_attr "type" "compare")])
7044 (define_insn "*cmp_cc_xor_not"
7047 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7048 (match_operand:SI 1 "arith_operand" "rI")))
7051 "xnorcc\\t%r0, %1, %%g0"
7052 [(set_attr "type" "compare")])
7054 (define_insn "*cmp_ccx_xor_not"
7057 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7058 (match_operand:DI 1 "arith_double_operand" "rHI")))
7061 "xnorcc\\t%r0, %1, %%g0"
7062 [(set_attr "type" "compare")])
7064 (define_insn "*cmp_cc_xor_not_set"
7067 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7068 (match_operand:SI 2 "arith_operand" "rI")))
7070 (set (match_operand:SI 0 "register_operand" "=r")
7071 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7073 "xnorcc\\t%r1, %2, %0"
7074 [(set_attr "type" "compare")])
7076 (define_insn "*cmp_ccx_xor_not_set"
7079 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7080 (match_operand:DI 2 "arith_double_operand" "rHI")))
7082 (set (match_operand:DI 0 "register_operand" "=r")
7083 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7085 "xnorcc\\t%r1, %2, %0"
7086 [(set_attr "type" "compare")])
7088 (define_insn "*cmp_cc_arith_op_not"
7091 (match_operator:SI 2 "cc_arithopn"
7092 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7093 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7096 "%B2cc\\t%r1, %0, %%g0"
7097 [(set_attr "type" "compare")])
7099 (define_insn "*cmp_ccx_arith_op_not"
7102 (match_operator:DI 2 "cc_arithopn"
7103 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7104 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7107 "%B2cc\\t%r1, %0, %%g0"
7108 [(set_attr "type" "compare")])
7110 (define_insn "*cmp_cc_arith_op_not_set"
7113 (match_operator:SI 3 "cc_arithopn"
7114 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7115 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7117 (set (match_operand:SI 0 "register_operand" "=r")
7118 (match_operator:SI 4 "cc_arithopn"
7119 [(not:SI (match_dup 1)) (match_dup 2)]))]
7120 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7121 "%B3cc\\t%r2, %1, %0"
7122 [(set_attr "type" "compare")])
7124 (define_insn "*cmp_ccx_arith_op_not_set"
7127 (match_operator:DI 3 "cc_arithopn"
7128 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7129 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7131 (set (match_operand:DI 0 "register_operand" "=r")
7132 (match_operator:DI 4 "cc_arithopn"
7133 [(not:DI (match_dup 1)) (match_dup 2)]))]
7134 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7135 "%B3cc\\t%r2, %1, %0"
7136 [(set_attr "type" "compare")])
7138 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7139 ;; does not know how to make it work for constants.
7141 (define_expand "negdi2"
7142 [(set (match_operand:DI 0 "register_operand" "=r")
7143 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7147 if (! TARGET_ARCH64)
7149 emit_insn (gen_rtx_PARALLEL
7152 gen_rtx_SET (VOIDmode, operand0,
7153 gen_rtx_NEG (DImode, operand1)),
7154 gen_rtx_CLOBBER (VOIDmode,
7155 gen_rtx_REG (CCmode,
7161 (define_insn "*negdi2_sp32"
7162 [(set (match_operand:DI 0 "register_operand" "=r")
7163 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7164 (clobber (reg:CC 100))]
7167 [(set_attr "length" "2")])
7170 [(set (match_operand:DI 0 "register_operand" "")
7171 (neg:DI (match_operand:DI 1 "register_operand" "")))
7172 (clobber (reg:CC 100))]
7174 && reload_completed"
7175 [(parallel [(set (reg:CC_NOOV 100)
7176 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7178 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7179 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7180 (ltu:SI (reg:CC 100) (const_int 0))))]
7181 "operands[2] = gen_highpart (SImode, operands[0]);
7182 operands[3] = gen_highpart (SImode, operands[1]);
7183 operands[4] = gen_lowpart (SImode, operands[0]);
7184 operands[5] = gen_lowpart (SImode, operands[1]);")
7186 (define_insn "*negdi2_sp64"
7187 [(set (match_operand:DI 0 "register_operand" "=r")
7188 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7190 "sub\\t%%g0, %1, %0")
7192 (define_insn "negsi2"
7193 [(set (match_operand:SI 0 "register_operand" "=r")
7194 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7196 "sub\\t%%g0, %1, %0")
7198 (define_insn "*cmp_cc_neg"
7199 [(set (reg:CC_NOOV 100)
7200 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7203 "subcc\\t%%g0, %0, %%g0"
7204 [(set_attr "type" "compare")])
7206 (define_insn "*cmp_ccx_neg"
7207 [(set (reg:CCX_NOOV 100)
7208 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7211 "subcc\\t%%g0, %0, %%g0"
7212 [(set_attr "type" "compare")])
7214 (define_insn "*cmp_cc_set_neg"
7215 [(set (reg:CC_NOOV 100)
7216 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7218 (set (match_operand:SI 0 "register_operand" "=r")
7219 (neg:SI (match_dup 1)))]
7221 "subcc\\t%%g0, %1, %0"
7222 [(set_attr "type" "compare")])
7224 (define_insn "*cmp_ccx_set_neg"
7225 [(set (reg:CCX_NOOV 100)
7226 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7228 (set (match_operand:DI 0 "register_operand" "=r")
7229 (neg:DI (match_dup 1)))]
7231 "subcc\\t%%g0, %1, %0"
7232 [(set_attr "type" "compare")])
7234 ;; We cannot use the "not" pseudo insn because the Sun assembler
7235 ;; does not know how to make it work for constants.
7236 (define_expand "one_cmpldi2"
7237 [(set (match_operand:DI 0 "register_operand" "")
7238 (not:DI (match_operand:DI 1 "register_operand" "")))]
7242 (define_insn "*one_cmpldi2_sp32"
7243 [(set (match_operand:DI 0 "register_operand" "=r,b")
7244 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7249 [(set_attr "type" "*,fp")
7250 (set_attr "length" "2,*")
7251 (set_attr "fptype" "double")])
7254 [(set (match_operand:DI 0 "register_operand" "")
7255 (not:DI (match_operand:DI 1 "register_operand" "")))]
7258 && ((GET_CODE (operands[0]) == REG
7259 && REGNO (operands[0]) < 32)
7260 || (GET_CODE (operands[0]) == SUBREG
7261 && GET_CODE (SUBREG_REG (operands[0])) == REG
7262 && REGNO (SUBREG_REG (operands[0])) < 32))"
7263 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7264 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7265 "operands[2] = gen_highpart (SImode, operands[0]);
7266 operands[3] = gen_highpart (SImode, operands[1]);
7267 operands[4] = gen_lowpart (SImode, operands[0]);
7268 operands[5] = gen_lowpart (SImode, operands[1]);")
7270 (define_insn "*one_cmpldi2_sp64"
7271 [(set (match_operand:DI 0 "register_operand" "=r,b")
7272 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7277 [(set_attr "type" "*,fp")
7278 (set_attr "fptype" "double")])
7280 (define_insn "one_cmplsi2"
7281 [(set (match_operand:SI 0 "register_operand" "=r,d")
7282 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7287 [(set_attr "type" "*,fp")])
7289 (define_insn "*cmp_cc_not"
7291 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7294 "xnorcc\\t%%g0, %0, %%g0"
7295 [(set_attr "type" "compare")])
7297 (define_insn "*cmp_ccx_not"
7299 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7302 "xnorcc\\t%%g0, %0, %%g0"
7303 [(set_attr "type" "compare")])
7305 (define_insn "*cmp_cc_set_not"
7307 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7309 (set (match_operand:SI 0 "register_operand" "=r")
7310 (not:SI (match_dup 1)))]
7312 "xnorcc\\t%%g0, %1, %0"
7313 [(set_attr "type" "compare")])
7315 (define_insn "*cmp_ccx_set_not"
7317 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7319 (set (match_operand:DI 0 "register_operand" "=r")
7320 (not:DI (match_dup 1)))]
7322 "xnorcc\\t%%g0, %1, %0"
7323 [(set_attr "type" "compare")])
7325 (define_insn "*cmp_cc_set"
7326 [(set (match_operand:SI 0 "register_operand" "=r")
7327 (match_operand:SI 1 "register_operand" "r"))
7329 (compare:CC (match_dup 1)
7333 [(set_attr "type" "compare")])
7335 (define_insn "*cmp_ccx_set64"
7336 [(set (match_operand:DI 0 "register_operand" "=r")
7337 (match_operand:DI 1 "register_operand" "r"))
7339 (compare:CCX (match_dup 1)
7343 [(set_attr "type" "compare")])
7345 ;; Floating point arithmetic instructions.
7347 (define_expand "addtf3"
7348 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7349 (plus:TF (match_operand:TF 1 "general_operand" "")
7350 (match_operand:TF 2 "general_operand" "")))]
7351 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7354 if (! TARGET_HARD_QUAD)
7356 rtx slot0, slot1, slot2;
7358 if (GET_CODE (operands[0]) != MEM)
7359 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7361 slot0 = operands[0];
7362 if (GET_CODE (operands[1]) != MEM)
7364 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7365 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7368 slot1 = operands[1];
7369 if (GET_CODE (operands[2]) != MEM)
7371 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7372 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7375 slot2 = operands[2];
7377 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7379 XEXP (slot0, 0), Pmode,
7380 XEXP (slot1, 0), Pmode,
7381 XEXP (slot2, 0), Pmode);
7383 if (GET_CODE (operands[0]) != MEM)
7384 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7389 (define_insn "*addtf3_hq"
7390 [(set (match_operand:TF 0 "register_operand" "=e")
7391 (plus:TF (match_operand:TF 1 "register_operand" "e")
7392 (match_operand:TF 2 "register_operand" "e")))]
7393 "TARGET_FPU && TARGET_HARD_QUAD"
7394 "faddq\\t%1, %2, %0"
7395 [(set_attr "type" "fp")])
7397 (define_insn "adddf3"
7398 [(set (match_operand:DF 0 "register_operand" "=e")
7399 (plus:DF (match_operand:DF 1 "register_operand" "e")
7400 (match_operand:DF 2 "register_operand" "e")))]
7402 "faddd\\t%1, %2, %0"
7403 [(set_attr "type" "fp")
7404 (set_attr "fptype" "double")])
7406 (define_insn "addsf3"
7407 [(set (match_operand:SF 0 "register_operand" "=f")
7408 (plus:SF (match_operand:SF 1 "register_operand" "f")
7409 (match_operand:SF 2 "register_operand" "f")))]
7411 "fadds\\t%1, %2, %0"
7412 [(set_attr "type" "fp")])
7414 (define_expand "subtf3"
7415 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7416 (minus:TF (match_operand:TF 1 "general_operand" "")
7417 (match_operand:TF 2 "general_operand" "")))]
7418 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7421 if (! TARGET_HARD_QUAD)
7423 rtx slot0, slot1, slot2;
7425 if (GET_CODE (operands[0]) != MEM)
7426 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7428 slot0 = operands[0];
7429 if (GET_CODE (operands[1]) != MEM)
7431 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7432 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7435 slot1 = operands[1];
7436 if (GET_CODE (operands[2]) != MEM)
7438 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7439 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7442 slot2 = operands[2];
7444 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7446 XEXP (slot0, 0), Pmode,
7447 XEXP (slot1, 0), Pmode,
7448 XEXP (slot2, 0), Pmode);
7450 if (GET_CODE (operands[0]) != MEM)
7451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7456 (define_insn "*subtf3_hq"
7457 [(set (match_operand:TF 0 "register_operand" "=e")
7458 (minus:TF (match_operand:TF 1 "register_operand" "e")
7459 (match_operand:TF 2 "register_operand" "e")))]
7460 "TARGET_FPU && TARGET_HARD_QUAD"
7461 "fsubq\\t%1, %2, %0"
7462 [(set_attr "type" "fp")])
7464 (define_insn "subdf3"
7465 [(set (match_operand:DF 0 "register_operand" "=e")
7466 (minus:DF (match_operand:DF 1 "register_operand" "e")
7467 (match_operand:DF 2 "register_operand" "e")))]
7469 "fsubd\\t%1, %2, %0"
7470 [(set_attr "type" "fp")
7471 (set_attr "fptype" "double")])
7473 (define_insn "subsf3"
7474 [(set (match_operand:SF 0 "register_operand" "=f")
7475 (minus:SF (match_operand:SF 1 "register_operand" "f")
7476 (match_operand:SF 2 "register_operand" "f")))]
7478 "fsubs\\t%1, %2, %0"
7479 [(set_attr "type" "fp")])
7481 (define_expand "multf3"
7482 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7483 (mult:TF (match_operand:TF 1 "general_operand" "")
7484 (match_operand:TF 2 "general_operand" "")))]
7485 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7488 if (! TARGET_HARD_QUAD)
7490 rtx slot0, slot1, slot2;
7492 if (GET_CODE (operands[0]) != MEM)
7493 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7495 slot0 = operands[0];
7496 if (GET_CODE (operands[1]) != MEM)
7498 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7499 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7502 slot1 = operands[1];
7503 if (GET_CODE (operands[2]) != MEM)
7505 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7506 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7509 slot2 = operands[2];
7511 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7513 XEXP (slot0, 0), Pmode,
7514 XEXP (slot1, 0), Pmode,
7515 XEXP (slot2, 0), Pmode);
7517 if (GET_CODE (operands[0]) != MEM)
7518 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7523 (define_insn "*multf3_hq"
7524 [(set (match_operand:TF 0 "register_operand" "=e")
7525 (mult:TF (match_operand:TF 1 "register_operand" "e")
7526 (match_operand:TF 2 "register_operand" "e")))]
7527 "TARGET_FPU && TARGET_HARD_QUAD"
7528 "fmulq\\t%1, %2, %0"
7529 [(set_attr "type" "fpmul")])
7531 (define_insn "muldf3"
7532 [(set (match_operand:DF 0 "register_operand" "=e")
7533 (mult:DF (match_operand:DF 1 "register_operand" "e")
7534 (match_operand:DF 2 "register_operand" "e")))]
7536 "fmuld\\t%1, %2, %0"
7537 [(set_attr "type" "fpmul")
7538 (set_attr "fptype" "double")])
7540 (define_insn "mulsf3"
7541 [(set (match_operand:SF 0 "register_operand" "=f")
7542 (mult:SF (match_operand:SF 1 "register_operand" "f")
7543 (match_operand:SF 2 "register_operand" "f")))]
7545 "fmuls\\t%1, %2, %0"
7546 [(set_attr "type" "fpmul")])
7548 (define_insn "*muldf3_extend"
7549 [(set (match_operand:DF 0 "register_operand" "=e")
7550 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7551 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7552 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7553 "fsmuld\\t%1, %2, %0"
7554 [(set_attr "type" "fpmul")
7555 (set_attr "fptype" "double")])
7557 (define_insn "*multf3_extend"
7558 [(set (match_operand:TF 0 "register_operand" "=e")
7559 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7560 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7561 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7562 "fdmulq\\t%1, %2, %0"
7563 [(set_attr "type" "fpmul")])
7565 (define_expand "divtf3"
7566 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7567 (div:TF (match_operand:TF 1 "general_operand" "")
7568 (match_operand:TF 2 "general_operand" "")))]
7569 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7572 if (! TARGET_HARD_QUAD)
7574 rtx slot0, slot1, slot2;
7576 if (GET_CODE (operands[0]) != MEM)
7577 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7579 slot0 = operands[0];
7580 if (GET_CODE (operands[1]) != MEM)
7582 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7583 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7586 slot1 = operands[1];
7587 if (GET_CODE (operands[2]) != MEM)
7589 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7590 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7593 slot2 = operands[2];
7595 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7597 XEXP (slot0, 0), Pmode,
7598 XEXP (slot1, 0), Pmode,
7599 XEXP (slot2, 0), Pmode);
7601 if (GET_CODE (operands[0]) != MEM)
7602 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7607 ;; don't have timing for quad-prec. divide.
7608 (define_insn "*divtf3_hq"
7609 [(set (match_operand:TF 0 "register_operand" "=e")
7610 (div:TF (match_operand:TF 1 "register_operand" "e")
7611 (match_operand:TF 2 "register_operand" "e")))]
7612 "TARGET_FPU && TARGET_HARD_QUAD"
7613 "fdivq\\t%1, %2, %0"
7614 [(set_attr "type" "fpdivd")])
7616 (define_insn "divdf3"
7617 [(set (match_operand:DF 0 "register_operand" "=e")
7618 (div:DF (match_operand:DF 1 "register_operand" "e")
7619 (match_operand:DF 2 "register_operand" "e")))]
7621 "fdivd\\t%1, %2, %0"
7622 [(set_attr "type" "fpdivd")
7623 (set_attr "fptype" "double")])
7625 (define_insn "divsf3"
7626 [(set (match_operand:SF 0 "register_operand" "=f")
7627 (div:SF (match_operand:SF 1 "register_operand" "f")
7628 (match_operand:SF 2 "register_operand" "f")))]
7630 "fdivs\\t%1, %2, %0"
7631 [(set_attr "type" "fpdivs")])
7633 (define_expand "negtf2"
7634 [(set (match_operand:TF 0 "register_operand" "=e,e")
7635 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7639 (define_insn "*negtf2_notv9"
7640 [(set (match_operand:TF 0 "register_operand" "=e,e")
7641 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7642 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7648 [(set_attr "type" "fpmove,*")
7649 (set_attr "length" "*,2")])
7652 [(set (match_operand:TF 0 "register_operand" "")
7653 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7657 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7658 [(set (match_dup 2) (neg:SF (match_dup 3)))
7659 (set (match_dup 4) (match_dup 5))
7660 (set (match_dup 6) (match_dup 7))]
7661 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7662 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7663 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7664 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7665 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7666 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7668 (define_insn "*negtf2_v9"
7669 [(set (match_operand:TF 0 "register_operand" "=e,e")
7670 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7671 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7672 "TARGET_FPU && TARGET_V9"
7676 [(set_attr "type" "fpmove,*")
7677 (set_attr "length" "*,2")
7678 (set_attr "fptype" "double")])
7681 [(set (match_operand:TF 0 "register_operand" "")
7682 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7686 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7687 [(set (match_dup 2) (neg:DF (match_dup 3)))
7688 (set (match_dup 4) (match_dup 5))]
7689 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7690 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7691 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7692 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7694 (define_expand "negdf2"
7695 [(set (match_operand:DF 0 "register_operand" "")
7696 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7700 (define_insn "*negdf2_notv9"
7701 [(set (match_operand:DF 0 "register_operand" "=e,e")
7702 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7703 "TARGET_FPU && ! TARGET_V9"
7707 [(set_attr "type" "fpmove,*")
7708 (set_attr "length" "*,2")])
7711 [(set (match_operand:DF 0 "register_operand" "")
7712 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7716 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7717 [(set (match_dup 2) (neg:SF (match_dup 3)))
7718 (set (match_dup 4) (match_dup 5))]
7719 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7720 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7721 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7722 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7724 (define_insn "*negdf2_v9"
7725 [(set (match_operand:DF 0 "register_operand" "=e")
7726 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7727 "TARGET_FPU && TARGET_V9"
7729 [(set_attr "type" "fpmove")
7730 (set_attr "fptype" "double")])
7732 (define_insn "negsf2"
7733 [(set (match_operand:SF 0 "register_operand" "=f")
7734 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7737 [(set_attr "type" "fpmove")])
7739 (define_expand "abstf2"
7740 [(set (match_operand:TF 0 "register_operand" "")
7741 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7745 (define_insn "*abstf2_notv9"
7746 [(set (match_operand:TF 0 "register_operand" "=e,e")
7747 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7748 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7749 "TARGET_FPU && ! TARGET_V9"
7753 [(set_attr "type" "fpmove,*")
7754 (set_attr "length" "*,2")])
7757 [(set (match_operand:TF 0 "register_operand" "")
7758 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7762 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7763 [(set (match_dup 2) (abs:SF (match_dup 3)))
7764 (set (match_dup 4) (match_dup 5))
7765 (set (match_dup 6) (match_dup 7))]
7766 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7767 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7768 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7769 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7770 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7771 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7773 (define_insn "*abstf2_hq_v9"
7774 [(set (match_operand:TF 0 "register_operand" "=e,e")
7775 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7776 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7780 [(set_attr "type" "fpmove")
7781 (set_attr "fptype" "double,*")])
7783 (define_insn "*abstf2_v9"
7784 [(set (match_operand:TF 0 "register_operand" "=e,e")
7785 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7786 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7790 [(set_attr "type" "fpmove,*")
7791 (set_attr "length" "*,2")
7792 (set_attr "fptype" "double,*")])
7795 [(set (match_operand:TF 0 "register_operand" "")
7796 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7800 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7801 [(set (match_dup 2) (abs:DF (match_dup 3)))
7802 (set (match_dup 4) (match_dup 5))]
7803 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7804 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7805 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7806 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7808 (define_expand "absdf2"
7809 [(set (match_operand:DF 0 "register_operand" "")
7810 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7814 (define_insn "*absdf2_notv9"
7815 [(set (match_operand:DF 0 "register_operand" "=e,e")
7816 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7817 "TARGET_FPU && ! TARGET_V9"
7821 [(set_attr "type" "fpmove,*")
7822 (set_attr "length" "*,2")])
7825 [(set (match_operand:DF 0 "register_operand" "")
7826 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7830 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7831 [(set (match_dup 2) (abs:SF (match_dup 3)))
7832 (set (match_dup 4) (match_dup 5))]
7833 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7834 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7835 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7836 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7838 (define_insn "*absdf2_v9"
7839 [(set (match_operand:DF 0 "register_operand" "=e")
7840 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7841 "TARGET_FPU && TARGET_V9"
7843 [(set_attr "type" "fpmove")
7844 (set_attr "fptype" "double")])
7846 (define_insn "abssf2"
7847 [(set (match_operand:SF 0 "register_operand" "=f")
7848 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7851 [(set_attr "type" "fpmove")])
7853 (define_expand "sqrttf2"
7854 [(set (match_operand:TF 0 "register_operand" "=e")
7855 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7856 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7859 if (! TARGET_HARD_QUAD)
7863 if (GET_CODE (operands[0]) != MEM)
7864 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7866 slot0 = operands[0];
7867 if (GET_CODE (operands[1]) != MEM)
7869 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7870 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7873 slot1 = operands[1];
7875 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7877 XEXP (slot0, 0), Pmode,
7878 XEXP (slot1, 0), Pmode);
7880 if (GET_CODE (operands[0]) != MEM)
7881 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7886 (define_insn "*sqrttf2_hq"
7887 [(set (match_operand:TF 0 "register_operand" "=e")
7888 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7889 "TARGET_FPU && TARGET_HARD_QUAD"
7891 [(set_attr "type" "fpsqrtd")])
7893 (define_insn "sqrtdf2"
7894 [(set (match_operand:DF 0 "register_operand" "=e")
7895 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7898 [(set_attr "type" "fpsqrtd")
7899 (set_attr "fptype" "double")])
7901 (define_insn "sqrtsf2"
7902 [(set (match_operand:SF 0 "register_operand" "=f")
7903 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7906 [(set_attr "type" "fpsqrts")])
7908 ;;- arithmetic shift instructions
7910 (define_insn "ashlsi3"
7911 [(set (match_operand:SI 0 "register_operand" "=r")
7912 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7913 (match_operand:SI 2 "arith_operand" "rI")))]
7917 if (GET_CODE (operands[2]) == CONST_INT
7918 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7919 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7921 return \"sll\\t%1, %2, %0\";
7923 [(set_attr "type" "shift")])
7925 ;; We special case multiplication by two, as add can be done
7926 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7927 (define_insn "*ashlsi3_const1"
7928 [(set (match_operand:SI 0 "register_operand" "=r")
7929 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7934 (define_expand "ashldi3"
7935 [(set (match_operand:DI 0 "register_operand" "=r")
7936 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7937 (match_operand:SI 2 "arith_operand" "rI")))]
7938 "TARGET_ARCH64 || TARGET_V8PLUS"
7941 if (! TARGET_ARCH64)
7943 if (GET_CODE (operands[2]) == CONST_INT)
7945 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7950 ;; We special case multiplication by two, as add can be done
7951 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7952 (define_insn "*ashldi3_const1"
7953 [(set (match_operand:DI 0 "register_operand" "=r")
7954 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7959 (define_insn "*ashldi3_sp64"
7960 [(set (match_operand:DI 0 "register_operand" "=r")
7961 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7962 (match_operand:SI 2 "arith_operand" "rI")))]
7966 if (GET_CODE (operands[2]) == CONST_INT
7967 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7968 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7970 return \"sllx\\t%1, %2, %0\";
7972 [(set_attr "type" "shift")])
7975 (define_insn "ashldi3_v8plus"
7976 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7977 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7978 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7979 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7981 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7982 [(set_attr "type" "multi")
7983 (set_attr "length" "5,5,6")])
7985 ;; Optimize (1LL<<x)-1
7986 ;; XXX this also needs to be fixed to handle equal subregs
7987 ;; XXX first before we could re-enable it.
7989 ; [(set (match_operand:DI 0 "register_operand" "=h")
7990 ; (plus:DI (ashift:DI (const_int 1)
7991 ; (match_operand:SI 1 "arith_operand" "rI"))
7993 ; "0 && TARGET_V8PLUS"
7996 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7997 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7998 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8000 ; [(set_attr "type" "multi")
8001 ; (set_attr "length" "4")])
8003 (define_insn "*cmp_cc_ashift_1"
8004 [(set (reg:CC_NOOV 100)
8005 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8009 "addcc\\t%0, %0, %%g0"
8010 [(set_attr "type" "compare")])
8012 (define_insn "*cmp_cc_set_ashift_1"
8013 [(set (reg:CC_NOOV 100)
8014 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8017 (set (match_operand:SI 0 "register_operand" "=r")
8018 (ashift:SI (match_dup 1) (const_int 1)))]
8020 "addcc\\t%1, %1, %0"
8021 [(set_attr "type" "compare")])
8023 (define_insn "ashrsi3"
8024 [(set (match_operand:SI 0 "register_operand" "=r")
8025 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8026 (match_operand:SI 2 "arith_operand" "rI")))]
8030 if (GET_CODE (operands[2]) == CONST_INT
8031 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8032 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8034 return \"sra\\t%1, %2, %0\";
8036 [(set_attr "type" "shift")])
8038 (define_insn "*ashrsi3_extend"
8039 [(set (match_operand:DI 0 "register_operand" "=r")
8040 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8041 (match_operand:SI 2 "arith_operand" "r"))))]
8044 [(set_attr "type" "shift")])
8046 ;; This handles the case as above, but with constant shift instead of
8047 ;; register. Combiner "simplifies" it for us a little bit though.
8048 (define_insn "*ashrsi3_extend2"
8049 [(set (match_operand:DI 0 "register_operand" "=r")
8050 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8052 (match_operand:SI 2 "small_int_or_double" "n")))]
8054 && ((GET_CODE (operands[2]) == CONST_INT
8055 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8056 || (GET_CODE (operands[2]) == CONST_DOUBLE
8057 && !CONST_DOUBLE_HIGH (operands[2])
8058 && CONST_DOUBLE_LOW (operands[2]) >= 32
8059 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8062 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8064 return \"sra\\t%1, %2, %0\";
8066 [(set_attr "type" "shift")])
8068 (define_expand "ashrdi3"
8069 [(set (match_operand:DI 0 "register_operand" "=r")
8070 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8071 (match_operand:SI 2 "arith_operand" "rI")))]
8072 "TARGET_ARCH64 || TARGET_V8PLUS"
8075 if (! TARGET_ARCH64)
8077 if (GET_CODE (operands[2]) == CONST_INT)
8078 FAIL; /* prefer generic code in this case */
8079 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8085 [(set (match_operand:DI 0 "register_operand" "=r")
8086 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8087 (match_operand:SI 2 "arith_operand" "rI")))]
8091 if (GET_CODE (operands[2]) == CONST_INT
8092 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8093 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8095 return \"srax\\t%1, %2, %0\";
8097 [(set_attr "type" "shift")])
8100 (define_insn "ashrdi3_v8plus"
8101 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8102 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8103 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8104 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8106 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8107 [(set_attr "type" "multi")
8108 (set_attr "length" "5,5,6")])
8110 (define_insn "lshrsi3"
8111 [(set (match_operand:SI 0 "register_operand" "=r")
8112 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8113 (match_operand:SI 2 "arith_operand" "rI")))]
8117 if (GET_CODE (operands[2]) == CONST_INT
8118 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8119 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8121 return \"srl\\t%1, %2, %0\";
8123 [(set_attr "type" "shift")])
8125 ;; This handles the case where
8126 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8127 ;; but combiner "simplifies" it for us.
8128 (define_insn "*lshrsi3_extend"
8129 [(set (match_operand:DI 0 "register_operand" "=r")
8130 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8131 (match_operand:SI 2 "arith_operand" "r")) 0)
8132 (match_operand 3 "" "")))]
8134 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8135 && CONST_DOUBLE_HIGH (operands[3]) == 0
8136 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8137 || (HOST_BITS_PER_WIDE_INT >= 64
8138 && GET_CODE (operands[3]) == CONST_INT
8139 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8141 [(set_attr "type" "shift")])
8143 ;; This handles the case where
8144 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8145 ;; but combiner "simplifies" it for us.
8146 (define_insn "*lshrsi3_extend2"
8147 [(set (match_operand:DI 0 "register_operand" "=r")
8148 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8149 (match_operand 2 "small_int_or_double" "n")
8152 && ((GET_CODE (operands[2]) == CONST_INT
8153 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8154 || (GET_CODE (operands[2]) == CONST_DOUBLE
8155 && CONST_DOUBLE_HIGH (operands[2]) == 0
8156 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8159 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8161 return \"srl\\t%1, %2, %0\";
8163 [(set_attr "type" "shift")])
8165 (define_expand "lshrdi3"
8166 [(set (match_operand:DI 0 "register_operand" "=r")
8167 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8168 (match_operand:SI 2 "arith_operand" "rI")))]
8169 "TARGET_ARCH64 || TARGET_V8PLUS"
8172 if (! TARGET_ARCH64)
8174 if (GET_CODE (operands[2]) == CONST_INT)
8176 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8182 [(set (match_operand:DI 0 "register_operand" "=r")
8183 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8184 (match_operand:SI 2 "arith_operand" "rI")))]
8188 if (GET_CODE (operands[2]) == CONST_INT
8189 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8190 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8192 return \"srlx\\t%1, %2, %0\";
8194 [(set_attr "type" "shift")])
8197 (define_insn "lshrdi3_v8plus"
8198 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8199 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8200 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8201 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8203 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8204 [(set_attr "type" "multi")
8205 (set_attr "length" "5,5,6")])
8208 [(set (match_operand:SI 0 "register_operand" "=r")
8209 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8211 (match_operand:SI 2 "small_int_or_double" "n")))]
8213 && ((GET_CODE (operands[2]) == CONST_INT
8214 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8215 || (GET_CODE (operands[2]) == CONST_DOUBLE
8216 && !CONST_DOUBLE_HIGH (operands[2])
8217 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8220 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8222 return \"srax\\t%1, %2, %0\";
8224 [(set_attr "type" "shift")])
8227 [(set (match_operand:SI 0 "register_operand" "=r")
8228 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8230 (match_operand:SI 2 "small_int_or_double" "n")))]
8232 && ((GET_CODE (operands[2]) == CONST_INT
8233 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8234 || (GET_CODE (operands[2]) == CONST_DOUBLE
8235 && !CONST_DOUBLE_HIGH (operands[2])
8236 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8239 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8241 return \"srlx\\t%1, %2, %0\";
8243 [(set_attr "type" "shift")])
8246 [(set (match_operand:SI 0 "register_operand" "=r")
8247 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8248 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8249 (match_operand:SI 3 "small_int_or_double" "n")))]
8251 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8252 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8253 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8254 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8257 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8259 return \"srax\\t%1, %2, %0\";
8261 [(set_attr "type" "shift")])
8264 [(set (match_operand:SI 0 "register_operand" "=r")
8265 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8266 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8267 (match_operand:SI 3 "small_int_or_double" "n")))]
8269 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8270 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8271 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8272 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8275 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8277 return \"srlx\\t%1, %2, %0\";
8279 [(set_attr "type" "shift")])
8281 ;; Unconditional and other jump instructions
8282 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8283 ;; following insn is never executed. This saves us a nop. Dbx does not
8284 ;; handle such branches though, so we only use them when optimizing.
8286 [(set (pc) (label_ref (match_operand 0 "" "")))]
8290 /* TurboSparc is reported to have problems with
8293 i.e. an empty loop with the annul bit set. The workaround is to use
8297 if (! TARGET_V9 && flag_delayed_branch
8298 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8299 == INSN_ADDRESSES (INSN_UID (insn))))
8300 return \"b\\t%l0%#\";
8302 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8304 [(set_attr "type" "uncond_branch")])
8306 (define_expand "tablejump"
8307 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8308 (use (label_ref (match_operand 1 "" "")))])]
8312 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8315 /* In pic mode, our address differences are against the base of the
8316 table. Add that base value back in; CSE ought to be able to combine
8317 the two address loads. */
8321 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8323 if (CASE_VECTOR_MODE != Pmode)
8324 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8325 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8326 operands[0] = memory_address (Pmode, tmp);
8330 (define_insn "*tablejump_sp32"
8331 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8332 (use (label_ref (match_operand 1 "" "")))]
8335 [(set_attr "type" "uncond_branch")])
8337 (define_insn "*tablejump_sp64"
8338 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8339 (use (label_ref (match_operand 1 "" "")))]
8342 [(set_attr "type" "uncond_branch")])
8344 ;; This pattern recognizes the "instruction" that appears in
8345 ;; a function call that wants a structure value,
8346 ;; to inform the called function if compiled with Sun CC.
8347 ;(define_insn "*unimp_insn"
8348 ; [(match_operand:SI 0 "immediate_operand" "")]
8349 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8351 ; [(set_attr "type" "marker")])
8353 ;;- jump to subroutine
8354 (define_expand "call"
8355 ;; Note that this expression is not used for generating RTL.
8356 ;; All the RTL is generated explicitly below.
8357 [(call (match_operand 0 "call_operand" "")
8358 (match_operand 3 "" "i"))]
8359 ;; operands[2] is next_arg_register
8360 ;; operands[3] is struct_value_size_rtx.
8364 rtx fn_rtx, nregs_rtx;
8366 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8369 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8371 /* This is really a PIC sequence. We want to represent
8372 it as a funny jump so its delay slots can be filled.
8374 ??? But if this really *is* a CALL, will not it clobber the
8375 call-clobbered registers? We lose this if it is a JUMP_INSN.
8376 Why cannot we have delay slots filled if it were a CALL? */
8378 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8383 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8385 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8391 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8392 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8396 fn_rtx = operands[0];
8398 /* Count the number of parameter registers being used by this call.
8399 if that argument is NULL, it means we are using them all, which
8400 means 6 on the sparc. */
8403 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8405 nregs_rtx = GEN_INT (6);
8407 nregs_rtx = const0_rtx;
8410 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8414 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8416 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8421 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8422 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8426 /* If this call wants a structure value,
8427 emit an unimp insn to let the called function know about this. */
8428 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8430 rtx insn = emit_insn (operands[3]);
8431 SCHED_GROUP_P (insn) = 1;
8438 ;; We can't use the same pattern for these two insns, because then registers
8439 ;; in the address may not be properly reloaded.
8441 (define_insn "*call_address_sp32"
8442 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8443 (match_operand 1 "" ""))
8444 (clobber (reg:SI 15))]
8445 ;;- Do not use operand 1 for most machines.
8448 [(set_attr "type" "call")])
8450 (define_insn "*call_symbolic_sp32"
8451 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8452 (match_operand 1 "" ""))
8453 (clobber (reg:SI 15))]
8454 ;;- Do not use operand 1 for most machines.
8457 [(set_attr "type" "call")])
8459 (define_insn "*call_address_sp64"
8460 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8461 (match_operand 1 "" ""))
8462 (clobber (reg:DI 15))]
8463 ;;- Do not use operand 1 for most machines.
8466 [(set_attr "type" "call")])
8468 (define_insn "*call_symbolic_sp64"
8469 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8470 (match_operand 1 "" ""))
8471 (clobber (reg:DI 15))]
8472 ;;- Do not use operand 1 for most machines.
8475 [(set_attr "type" "call")])
8477 ;; This is a call that wants a structure value.
8478 ;; There is no such critter for v9 (??? we may need one anyway).
8479 (define_insn "*call_address_struct_value_sp32"
8480 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8481 (match_operand 1 "" ""))
8482 (match_operand 2 "immediate_operand" "")
8483 (clobber (reg:SI 15))]
8484 ;;- Do not use operand 1 for most machines.
8485 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8486 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8487 [(set_attr "type" "call_no_delay_slot")
8488 (set_attr "length" "3")])
8490 ;; This is a call that wants a structure value.
8491 ;; There is no such critter for v9 (??? we may need one anyway).
8492 (define_insn "*call_symbolic_struct_value_sp32"
8493 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8494 (match_operand 1 "" ""))
8495 (match_operand 2 "immediate_operand" "")
8496 (clobber (reg:SI 15))]
8497 ;;- Do not use operand 1 for most machines.
8498 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8499 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8500 [(set_attr "type" "call_no_delay_slot")
8501 (set_attr "length" "3")])
8503 ;; This is a call that may want a structure value. This is used for
8505 (define_insn "*call_address_untyped_struct_value_sp32"
8506 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8507 (match_operand 1 "" ""))
8508 (match_operand 2 "immediate_operand" "")
8509 (clobber (reg:SI 15))]
8510 ;;- Do not use operand 1 for most machines.
8511 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8512 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8513 [(set_attr "type" "call_no_delay_slot")
8514 (set_attr "length" "3")])
8516 ;; This is a call that wants a structure value.
8517 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8518 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8519 (match_operand 1 "" ""))
8520 (match_operand 2 "immediate_operand" "")
8521 (clobber (reg:SI 15))]
8522 ;;- Do not use operand 1 for most machines.
8523 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8524 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8525 [(set_attr "type" "call_no_delay_slot")
8526 (set_attr "length" "3")])
8528 (define_expand "call_value"
8529 ;; Note that this expression is not used for generating RTL.
8530 ;; All the RTL is generated explicitly below.
8531 [(set (match_operand 0 "register_operand" "=rf")
8532 (call (match_operand 1 "" "")
8533 (match_operand 4 "" "")))]
8534 ;; operand 2 is stack_size_rtx
8535 ;; operand 3 is next_arg_register
8539 rtx fn_rtx, nregs_rtx;
8542 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8545 fn_rtx = operands[1];
8549 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8551 nregs_rtx = GEN_INT (6);
8553 nregs_rtx = const0_rtx;
8557 gen_rtx_SET (VOIDmode, operands[0],
8558 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8559 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8561 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8566 (define_insn "*call_value_address_sp32"
8567 [(set (match_operand 0 "" "=rf")
8568 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8569 (match_operand 2 "" "")))
8570 (clobber (reg:SI 15))]
8571 ;;- Do not use operand 2 for most machines.
8574 [(set_attr "type" "call")])
8576 (define_insn "*call_value_symbolic_sp32"
8577 [(set (match_operand 0 "" "=rf")
8578 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8579 (match_operand 2 "" "")))
8580 (clobber (reg:SI 15))]
8581 ;;- Do not use operand 2 for most machines.
8584 [(set_attr "type" "call")])
8586 (define_insn "*call_value_address_sp64"
8587 [(set (match_operand 0 "" "")
8588 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8589 (match_operand 2 "" "")))
8590 (clobber (reg:DI 15))]
8591 ;;- Do not use operand 2 for most machines.
8594 [(set_attr "type" "call")])
8596 (define_insn "*call_value_symbolic_sp64"
8597 [(set (match_operand 0 "" "")
8598 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8599 (match_operand 2 "" "")))
8600 (clobber (reg:DI 15))]
8601 ;;- Do not use operand 2 for most machines.
8604 [(set_attr "type" "call")])
8606 (define_expand "untyped_call"
8607 [(parallel [(call (match_operand 0 "" "")
8609 (match_operand 1 "" "")
8610 (match_operand 2 "" "")])]
8616 /* Pass constm1 to indicate that it may expect a structure value, but
8617 we don't know what size it is. */
8618 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8620 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8622 rtx set = XVECEXP (operands[2], 0, i);
8623 emit_move_insn (SET_DEST (set), SET_SRC (set));
8626 /* The optimizer does not know that the call sets the function value
8627 registers we stored in the result block. We avoid problems by
8628 claiming that all hard registers are used and clobbered at this
8630 emit_insn (gen_blockage ());
8636 (define_expand "sibcall"
8637 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8642 (define_insn "*sibcall_symbolic_sp32"
8643 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8644 (match_operand 1 "" ""))
8647 "* return output_sibcall(insn, operands[0]);"
8648 [(set_attr "type" "sibcall")])
8650 (define_insn "*sibcall_symbolic_sp64"
8651 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8652 (match_operand 1 "" ""))
8655 "* return output_sibcall(insn, operands[0]);"
8656 [(set_attr "type" "sibcall")])
8658 (define_expand "sibcall_value"
8659 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8660 (call (match_operand 1 "" "") (const_int 0)))
8665 (define_insn "*sibcall_value_symbolic_sp32"
8666 [(set (match_operand 0 "" "=rf")
8667 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8668 (match_operand 2 "" "")))
8671 "* return output_sibcall(insn, operands[1]);"
8672 [(set_attr "type" "sibcall")])
8674 (define_insn "*sibcall_value_symbolic_sp64"
8675 [(set (match_operand 0 "" "")
8676 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8677 (match_operand 2 "" "")))
8680 "* return output_sibcall(insn, operands[1]);"
8681 [(set_attr "type" "sibcall")])
8683 (define_expand "sibcall_epilogue"
8688 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8689 ;; all of memory. This blocks insns from being moved across this point.
8691 (define_insn "blockage"
8692 [(unspec_volatile [(const_int 0)] 0)]
8695 [(set_attr "length" "0")])
8697 ;; Prepare to return any type including a structure value.
8699 (define_expand "untyped_return"
8700 [(match_operand:BLK 0 "memory_operand" "")
8701 (match_operand 1 "" "")]
8705 rtx valreg1 = gen_rtx_REG (DImode, 24);
8706 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8707 rtx result = operands[0];
8709 if (! TARGET_ARCH64)
8711 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8713 rtx value = gen_reg_rtx (SImode);
8715 /* Fetch the instruction where we will return to and see if it's an unimp
8716 instruction (the most significant 10 bits will be zero). If so,
8717 update the return address to skip the unimp instruction. */
8718 emit_move_insn (value,
8719 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8720 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8721 emit_insn (gen_update_return (rtnreg, value));
8724 /* Reload the function value registers. */
8725 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8726 emit_move_insn (valreg2,
8727 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8729 /* Put USE insns before the return. */
8730 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8731 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8733 /* Construct the return. */
8734 expand_null_return ();
8739 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8740 ;; and parts of the compiler don't want to believe that the add is needed.
8742 (define_insn "update_return"
8743 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8744 (match_operand:SI 1 "register_operand" "r")] 1)]
8746 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8747 [(set_attr "type" "multi")
8748 (set_attr "length" "3")])
8755 (define_expand "indirect_jump"
8756 [(set (pc) (match_operand 0 "address_operand" "p"))]
8760 (define_insn "*branch_sp32"
8761 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8764 [(set_attr "type" "uncond_branch")])
8766 (define_insn "*branch_sp64"
8767 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8770 [(set_attr "type" "uncond_branch")])
8772 ;; ??? Doesn't work with -mflat.
8773 (define_expand "nonlocal_goto"
8774 [(match_operand:SI 0 "general_operand" "")
8775 (match_operand:SI 1 "general_operand" "")
8776 (match_operand:SI 2 "general_operand" "")
8777 (match_operand:SI 3 "" "")]
8782 rtx chain = operands[0];
8784 rtx lab = operands[1];
8785 rtx stack = operands[2];
8786 rtx fp = operands[3];
8789 /* Trap instruction to flush all the register windows. */
8790 emit_insn (gen_flush_register_windows ());
8792 /* Load the fp value for the containing fn into %fp. This is needed
8793 because STACK refers to %fp. Note that virtual register instantiation
8794 fails if the virtual %fp isn't set from a register. */
8795 if (GET_CODE (fp) != REG)
8796 fp = force_reg (Pmode, fp);
8797 emit_move_insn (virtual_stack_vars_rtx, fp);
8799 /* Find the containing function's current nonlocal goto handler,
8800 which will do any cleanups and then jump to the label. */
8801 labreg = gen_rtx_REG (Pmode, 8);
8802 emit_move_insn (labreg, lab);
8804 /* Restore %fp from stack pointer value for containing function.
8805 The restore insn that follows will move this to %sp,
8806 and reload the appropriate value into %fp. */
8807 emit_move_insn (hard_frame_pointer_rtx, stack);
8809 /* USE of frame_pointer_rtx added for consistency; not clear if
8811 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8812 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8815 /* Return, restoring reg window and jumping to goto handler. */
8816 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8817 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8819 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8825 /* Put in the static chain register the nonlocal label address. */
8826 emit_move_insn (static_chain_rtx, chain);
8829 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8830 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8835 ;; Special trap insn to flush register windows.
8836 (define_insn "flush_register_windows"
8837 [(unspec_volatile [(const_int 0)] 1)]
8839 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8840 [(set_attr "type" "misc")])
8842 (define_insn "goto_handler_and_restore"
8843 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8844 "GET_MODE (operands[0]) == Pmode"
8845 "jmp\\t%0+0\\n\\trestore"
8846 [(set_attr "type" "multi")
8847 (set_attr "length" "2")])
8849 ;;(define_insn "goto_handler_and_restore_v9"
8850 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8851 ;; (match_operand:SI 1 "register_operand" "=r,r")
8852 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8853 ;; "TARGET_V9 && ! TARGET_ARCH64"
8855 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8856 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8857 ;; [(set_attr "type" "multi")
8858 ;; (set_attr "length" "2,3")])
8860 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8861 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8862 ;; (match_operand:DI 1 "register_operand" "=r,r")
8863 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8864 ;; "TARGET_V9 && TARGET_ARCH64"
8866 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8867 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8868 ;; [(set_attr "type" "multi")
8869 ;; (set_attr "length" "2,3")])
8871 ;; For __builtin_setjmp we need to flush register windows iff the function
8872 ;; calls alloca as well, because otherwise the register window might be
8873 ;; saved after %sp adjustement and thus setjmp would crash
8874 (define_expand "builtin_setjmp_setup"
8875 [(match_operand 0 "register_operand" "r")]
8879 emit_insn (gen_do_builtin_setjmp_setup ());
8883 (define_insn "do_builtin_setjmp_setup"
8884 [(unspec_volatile [(const_int 0)] 5)]
8888 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
8890 fputs (\"\tflushw\n\", asm_out_file);
8892 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8893 TARGET_ARCH64 ? 'x' : 'w',
8894 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8895 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8896 TARGET_ARCH64 ? 'x' : 'w',
8897 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8898 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8899 TARGET_ARCH64 ? 'x' : 'w',
8900 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8903 [(set_attr "type" "misc")
8904 (set (attr "length") (if_then_else (eq_attr "pic" "true")
8909 [(unspec_volatile [(const_int 0)] 5)]
8910 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
8914 if (current_function_calls_alloca)
8915 emit_insn (gen_flush_register_windows ());
8919 ;; Pattern for use after a setjmp to store FP and the return register
8920 ;; into the stack area.
8922 (define_expand "setjmp"
8928 emit_insn (gen_setjmp_64 ());
8930 emit_insn (gen_setjmp_32 ());
8934 (define_expand "setjmp_32"
8935 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8936 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8939 { operands[0] = frame_pointer_rtx; }")
8941 (define_expand "setjmp_64"
8942 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8943 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8946 { operands[0] = frame_pointer_rtx; }")
8948 ;; Special pattern for the FLUSH instruction.
8950 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8951 ; of the define_insn otherwise missing a mode. We make "flush", aka
8952 ; gen_flush, the default one since sparc_initialize_trampoline uses
8953 ; it on SImode mem values.
8955 (define_insn "flush"
8956 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8958 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8959 [(set_attr "type" "misc")])
8961 (define_insn "flushdi"
8962 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8964 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8965 [(set_attr "type" "misc")])
8970 ;; The scan instruction searches from the most significant bit while ffs
8971 ;; searches from the least significant bit. The bit index and treatment of
8972 ;; zero also differ. It takes at least 7 instructions to get the proper
8973 ;; result. Here is an obvious 8 instruction sequence.
8976 (define_insn "ffssi2"
8977 [(set (match_operand:SI 0 "register_operand" "=&r")
8978 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8979 (clobber (match_scratch:SI 2 "=&r"))]
8980 "TARGET_SPARCLITE || TARGET_SPARCLET"
8983 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\";
8985 [(set_attr "type" "multi")
8986 (set_attr "length" "8")])
8988 ;; ??? This should be a define expand, so that the extra instruction have
8989 ;; a chance of being optimized away.
8991 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8992 ;; does, but no one uses that and we don't have a switch for it.
8994 ;(define_insn "ffsdi2"
8995 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8996 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8997 ; (clobber (match_scratch:DI 2 "=&r"))]
8999 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9000 ; [(set_attr "type" "multi")
9001 ; (set_attr "length" "4")])
9005 ;; Peepholes go at the end.
9007 ;; Optimize consecutive loads or stores into ldd and std when possible.
9008 ;; The conditions in which we do this are very restricted and are
9009 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9012 [(set (match_operand:SI 0 "memory_operand" "")
9014 (set (match_operand:SI 1 "memory_operand" "")
9017 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
9020 "operands[0] = change_address (operands[0], DImode, NULL);")
9023 [(set (match_operand:SI 0 "memory_operand" "")
9025 (set (match_operand:SI 1 "memory_operand" "")
9028 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9031 "operands[1] = change_address (operands[1], DImode, NULL);")
9034 [(set (match_operand:SI 0 "register_operand" "")
9035 (match_operand:SI 1 "memory_operand" ""))
9036 (set (match_operand:SI 2 "register_operand" "")
9037 (match_operand:SI 3 "memory_operand" ""))]
9038 "registers_ok_for_ldd_peep (operands[0], operands[2])
9039 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9042 "operands[1] = change_address (operands[1], DImode, NULL);
9043 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9046 [(set (match_operand:SI 0 "memory_operand" "")
9047 (match_operand:SI 1 "register_operand" ""))
9048 (set (match_operand:SI 2 "memory_operand" "")
9049 (match_operand:SI 3 "register_operand" ""))]
9050 "registers_ok_for_ldd_peep (operands[1], operands[3])
9051 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9054 "operands[0] = change_address (operands[0], DImode, NULL);
9055 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9058 [(set (match_operand:SF 0 "register_operand" "")
9059 (match_operand:SF 1 "memory_operand" ""))
9060 (set (match_operand:SF 2 "register_operand" "")
9061 (match_operand:SF 3 "memory_operand" ""))]
9062 "registers_ok_for_ldd_peep (operands[0], operands[2])
9063 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9066 "operands[1] = change_address (operands[1], DFmode, NULL);
9067 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9070 [(set (match_operand:SF 0 "memory_operand" "")
9071 (match_operand:SF 1 "register_operand" ""))
9072 (set (match_operand:SF 2 "memory_operand" "")
9073 (match_operand:SF 3 "register_operand" ""))]
9074 "registers_ok_for_ldd_peep (operands[1], operands[3])
9075 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9078 "operands[0] = change_address (operands[0], DFmode, NULL);
9079 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9082 [(set (match_operand:SI 0 "register_operand" "")
9083 (match_operand:SI 1 "memory_operand" ""))
9084 (set (match_operand:SI 2 "register_operand" "")
9085 (match_operand:SI 3 "memory_operand" ""))]
9086 "registers_ok_for_ldd_peep (operands[2], operands[0])
9087 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9090 "operands[3] = change_address (operands[3], DImode, NULL);
9091 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9094 [(set (match_operand:SI 0 "memory_operand" "")
9095 (match_operand:SI 1 "register_operand" ""))
9096 (set (match_operand:SI 2 "memory_operand" "")
9097 (match_operand:SI 3 "register_operand" ""))]
9098 "registers_ok_for_ldd_peep (operands[3], operands[1])
9099 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9102 "operands[2] = change_address (operands[2], DImode, NULL);
9103 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9107 [(set (match_operand:SF 0 "register_operand" "")
9108 (match_operand:SF 1 "memory_operand" ""))
9109 (set (match_operand:SF 2 "register_operand" "")
9110 (match_operand:SF 3 "memory_operand" ""))]
9111 "registers_ok_for_ldd_peep (operands[2], operands[0])
9112 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9115 "operands[3] = change_address (operands[3], DFmode, NULL);
9116 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9119 [(set (match_operand:SF 0 "memory_operand" "")
9120 (match_operand:SF 1 "register_operand" ""))
9121 (set (match_operand:SF 2 "memory_operand" "")
9122 (match_operand:SF 3 "register_operand" ""))]
9123 "registers_ok_for_ldd_peep (operands[3], operands[1])
9124 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9127 "operands[2] = change_address (operands[2], DFmode, NULL);
9128 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9130 ;; Optimize the case of following a reg-reg move with a test
9131 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9132 ;; This can result from a float to fix conversion.
9135 [(set (match_operand:SI 0 "register_operand" "")
9136 (match_operand:SI 1 "register_operand" ""))
9138 (compare:CC (match_operand:SI 2 "register_operand" "")
9140 "(rtx_equal_p (operands[2], operands[0])
9141 || rtx_equal_p (operands[2], operands[1]))
9142 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9143 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9144 [(parallel [(set (match_dup 0) (match_dup 1))
9146 (compare:CC (match_dup 1) (const_int 0)))])]
9150 [(set (match_operand:DI 0 "register_operand" "")
9151 (match_operand:DI 1 "register_operand" ""))
9153 (compare:CCX (match_operand:DI 2 "register_operand" "")
9156 && (rtx_equal_p (operands[2], operands[0])
9157 || rtx_equal_p (operands[2], operands[1]))
9158 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9159 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9160 [(parallel [(set (match_dup 0) (match_dup 1))
9162 (compare:CC (match_dup 1) (const_int 0)))])]
9165 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
9166 ;; who then immediately calls final_scan_insn.
9168 (define_insn "*return_qi"
9169 [(set (match_operand:QI 0 "restore_operand" "")
9170 (match_operand:QI 1 "arith_operand" "rI"))
9172 "sparc_emitting_epilogue"
9175 if (! TARGET_ARCH64 && current_function_returns_struct)
9176 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9177 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9178 || IN_OR_GLOBAL_P (operands[1])))
9179 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9181 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9183 [(set_attr "type" "multi")
9184 (set_attr "length" "2")])
9186 (define_insn "*return_hi"
9187 [(set (match_operand:HI 0 "restore_operand" "")
9188 (match_operand:HI 1 "arith_operand" "rI"))
9190 "sparc_emitting_epilogue"
9193 if (! TARGET_ARCH64 && current_function_returns_struct)
9194 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9195 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9196 || IN_OR_GLOBAL_P (operands[1])))
9197 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9199 return \"ret\;restore %%g0, %1, %Y0\";
9201 [(set_attr "type" "multi")
9202 (set_attr "length" "2")])
9204 (define_insn "*return_si"
9205 [(set (match_operand:SI 0 "restore_operand" "")
9206 (match_operand:SI 1 "arith_operand" "rI"))
9208 "sparc_emitting_epilogue"
9211 if (! TARGET_ARCH64 && current_function_returns_struct)
9212 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9213 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9214 || IN_OR_GLOBAL_P (operands[1])))
9215 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9217 return \"ret\;restore %%g0, %1, %Y0\";
9219 [(set_attr "type" "multi")
9220 (set_attr "length" "2")])
9222 (define_insn "*return_sf_no_fpu"
9223 [(set (match_operand:SF 0 "restore_operand" "=r")
9224 (match_operand:SF 1 "register_operand" "r"))
9226 "sparc_emitting_epilogue"
9229 if (! TARGET_ARCH64 && current_function_returns_struct)
9230 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9231 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9232 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9234 return \"ret\;restore %%g0, %1, %Y0\";
9236 [(set_attr "type" "multi")
9237 (set_attr "length" "2")])
9239 (define_insn "*return_df_no_fpu"
9240 [(set (match_operand:DF 0 "restore_operand" "=r")
9241 (match_operand:DF 1 "register_operand" "r"))
9243 "sparc_emitting_epilogue && TARGET_ARCH64"
9246 if (IN_OR_GLOBAL_P (operands[1]))
9247 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9249 return \"ret\;restore %%g0, %1, %Y0\";
9251 [(set_attr "type" "multi")
9252 (set_attr "length" "2")])
9254 (define_insn "*return_addsi"
9255 [(set (match_operand:SI 0 "restore_operand" "")
9256 (plus:SI (match_operand:SI 1 "register_operand" "r")
9257 (match_operand:SI 2 "arith_operand" "rI")))
9259 "sparc_emitting_epilogue"
9262 if (! TARGET_ARCH64 && current_function_returns_struct)
9263 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9264 /* If operands are global or in registers, can use return */
9265 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9266 && (GET_CODE (operands[2]) == CONST_INT
9267 || IN_OR_GLOBAL_P (operands[2])))
9268 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9270 return \"ret\;restore %r1, %2, %Y0\";
9272 [(set_attr "type" "multi")
9273 (set_attr "length" "2")])
9275 (define_insn "*return_losum_si"
9276 [(set (match_operand:SI 0 "restore_operand" "")
9277 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9278 (match_operand:SI 2 "immediate_operand" "in")))
9280 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
9283 if (! TARGET_ARCH64 && current_function_returns_struct)
9284 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9285 /* If operands are global or in registers, can use return */
9286 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9287 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9289 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9291 [(set_attr "type" "multi")
9292 (set_attr "length" "2")])
9294 (define_insn "*return_di"
9295 [(set (match_operand:DI 0 "restore_operand" "")
9296 (match_operand:DI 1 "arith_double_operand" "rHI"))
9298 "sparc_emitting_epilogue && TARGET_ARCH64"
9299 "ret\;restore %%g0, %1, %Y0"
9300 [(set_attr "type" "multi")
9301 (set_attr "length" "2")])
9303 (define_insn "*return_adddi"
9304 [(set (match_operand:DI 0 "restore_operand" "")
9305 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9306 (match_operand:DI 2 "arith_double_operand" "rHI")))
9308 "sparc_emitting_epilogue && TARGET_ARCH64"
9309 "ret\;restore %r1, %2, %Y0"
9310 [(set_attr "type" "multi")
9311 (set_attr "length" "2")])
9313 (define_insn "*return_losum_di"
9314 [(set (match_operand:DI 0 "restore_operand" "")
9315 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9316 (match_operand:DI 2 "immediate_operand" "in")))
9318 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
9319 "ret\;restore %r1, %%lo(%a2), %Y0"
9320 [(set_attr "type" "multi")
9321 (set_attr "length" "2")])
9323 (define_insn "*return_sf"
9325 (match_operand:SF 0 "register_operand" "f"))
9327 "sparc_emitting_epilogue"
9328 "ret\;fmovs\\t%0, %%f0"
9329 [(set_attr "type" "multi")
9330 (set_attr "length" "2")])
9332 ;; Now peepholes to do a call followed by a jump.
9335 [(parallel [(set (match_operand 0 "" "")
9336 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9337 (match_operand 2 "" "")))
9338 (clobber (reg:SI 15))])
9339 (set (pc) (label_ref (match_operand 3 "" "")))]
9340 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9341 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9342 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9345 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9346 (match_operand 1 "" ""))
9347 (clobber (reg:SI 15))])
9348 (set (pc) (label_ref (match_operand 2 "" "")))]
9349 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9350 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9351 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9354 [(parallel [(set (match_operand 0 "" "")
9355 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9356 (match_operand 2 "" "")))
9357 (clobber (reg:DI 15))])
9358 (set (pc) (label_ref (match_operand 3 "" "")))]
9360 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9361 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9362 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9365 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9366 (match_operand 1 "" ""))
9367 (clobber (reg:DI 15))])
9368 (set (pc) (label_ref (match_operand 2 "" "")))]
9370 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9371 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9372 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9374 (define_insn "prefetch"
9375 [(prefetch (match_operand:DI 0 "address_operand" "p")
9376 (match_operand:DI 1 "const_int_operand" "n")
9377 (match_operand:DI 2 "const_int_operand" "n"))]
9380 static const char * const prefetch_instr[2][4] = {
9382 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9383 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9384 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9385 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9388 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9389 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9390 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9391 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9394 int read_or_write = INTVAL (operands[1]);
9395 int locality = INTVAL (operands[2]);
9397 if (read_or_write != 0 && read_or_write != 1)
9399 if (locality < 0 || locality > 3)
9401 return prefetch_instr [read_or_write][locality];
9403 [(set_attr "type" "load")])
9405 (define_expand "prologue"
9407 "flag_pic && current_function_uses_pic_offset_table"
9410 load_pic_register ();
9414 ;; We need to reload %l7 for -mflat -fpic,
9415 ;; otherwise %l7 should be preserved simply
9416 ;; by loading the function's register window
9417 (define_expand "exception_receiver"
9419 "TARGET_FLAT && flag_pic"
9422 load_pic_register ();
9427 (define_expand "builtin_setjmp_receiver"
9428 [(label_ref (match_operand 0 "" ""))]
9429 "TARGET_FLAT && flag_pic"
9432 load_pic_register ();
9437 [(trap_if (const_int 1) (const_int 5))]
9440 [(set_attr "type" "misc")])
9442 (define_expand "conditional_trap"
9443 [(trap_if (match_operator 0 "noov_compare_op"
9444 [(match_dup 2) (match_dup 3)])
9445 (match_operand:SI 1 "arith_operand" ""))]
9447 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9448 sparc_compare_op0, sparc_compare_op1);
9449 operands[3] = const0_rtx;")
9452 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9453 (match_operand:SI 1 "arith_operand" "rM"))]
9456 [(set_attr "type" "misc")])
9459 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9460 (match_operand:SI 1 "arith_operand" "rM"))]
9463 [(set_attr "type" "misc")])