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 "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2535 (match_operand:DI 1 "input_operand"
2536 " J,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)"
2553 [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2554 (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
2556 (define_insn "*movdi_insn_sp32"
2557 [(set (match_operand:DI 0 "nonimmediate_operand"
2558 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2559 (match_operand:DI 1 "input_operand"
2560 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2562 && (register_operand (operands[0], DImode)
2563 || register_operand (operands[1], DImode))"
2577 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2578 (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2580 ;; The following are generated by sparc_emit_set_const64
2581 (define_insn "*movdi_sp64_dbl"
2582 [(set (match_operand:DI 0 "register_operand" "=r")
2583 (match_operand:DI 1 "const64_operand" ""))]
2585 && HOST_BITS_PER_WIDE_INT != 64)"
2588 ;; This is needed to show CSE exactly which bits are set
2589 ;; in a 64-bit register by sethi instructions.
2590 (define_insn "*movdi_const64_special"
2591 [(set (match_operand:DI 0 "register_operand" "=r")
2592 (match_operand:DI 1 "const64_high_operand" ""))]
2594 "sethi\\t%%hi(%a1), %0")
2596 (define_insn "*movdi_insn_sp64_novis"
2597 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2598 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e"))]
2599 "TARGET_ARCH64 && ! TARGET_VIS
2600 && (register_operand (operands[0], DImode)
2601 || reg_or_0_operand (operands[1], DImode))"
2604 sethi\\t%%hi(%a1), %0
2611 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2612 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2614 (define_insn "*movdi_insn_sp64_vis"
2615 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2616 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,W,e,J"))]
2617 "TARGET_ARCH64 && TARGET_VIS &&
2618 (register_operand (operands[0], DImode)
2619 || reg_or_0_operand (operands[1], DImode))"
2622 sethi\\t%%hi(%a1), %0
2630 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2631 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2633 (define_expand "movdi_pic_label_ref"
2634 [(set (match_dup 3) (high:DI
2635 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2637 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2638 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2639 (set (match_operand:DI 0 "register_operand" "=r")
2640 (minus:DI (match_dup 5) (match_dup 4)))]
2641 "TARGET_ARCH64 && flag_pic"
2644 current_function_uses_pic_offset_table = 1;
2645 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2648 operands[3] = operands[0];
2649 operands[4] = operands[0];
2653 operands[3] = gen_reg_rtx (DImode);
2654 operands[4] = gen_reg_rtx (DImode);
2656 operands[5] = pic_offset_table_rtx;
2659 (define_insn "*movdi_high_pic_label_ref"
2660 [(set (match_operand:DI 0 "register_operand" "=r")
2662 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2663 (match_operand:DI 2 "" "")] 5)))]
2664 "TARGET_ARCH64 && flag_pic"
2665 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2667 (define_insn "*movdi_lo_sum_pic_label_ref"
2668 [(set (match_operand:DI 0 "register_operand" "=r")
2669 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2670 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2671 (match_operand:DI 3 "" "")] 5)))]
2672 "TARGET_ARCH64 && flag_pic"
2673 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2675 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2676 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2678 (define_insn "movdi_lo_sum_pic"
2679 [(set (match_operand:DI 0 "register_operand" "=r")
2680 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2681 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2682 "TARGET_ARCH64 && flag_pic"
2683 "or\\t%1, %%lo(%a2), %0")
2685 (define_insn "movdi_high_pic"
2686 [(set (match_operand:DI 0 "register_operand" "=r")
2687 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2688 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2689 "sethi\\t%%hi(%a1), %0")
2691 (define_insn "*sethi_di_medlow_embmedany_pic"
2692 [(set (match_operand:DI 0 "register_operand" "=r")
2693 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2694 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2695 "sethi\\t%%hi(%a1), %0")
2697 (define_insn "*sethi_di_medlow"
2698 [(set (match_operand:DI 0 "register_operand" "=r")
2699 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2700 "TARGET_CM_MEDLOW && check_pic (1)"
2701 "sethi\\t%%hi(%a1), %0")
2703 (define_insn "*losum_di_medlow"
2704 [(set (match_operand:DI 0 "register_operand" "=r")
2705 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2706 (match_operand:DI 2 "symbolic_operand" "")))]
2708 "or\\t%1, %%lo(%a2), %0")
2710 (define_insn "seth44"
2711 [(set (match_operand:DI 0 "register_operand" "=r")
2712 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2714 "sethi\\t%%h44(%a1), %0")
2716 (define_insn "setm44"
2717 [(set (match_operand:DI 0 "register_operand" "=r")
2718 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2719 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2721 "or\\t%1, %%m44(%a2), %0")
2723 (define_insn "setl44"
2724 [(set (match_operand:DI 0 "register_operand" "=r")
2725 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2726 (match_operand:DI 2 "symbolic_operand" "")))]
2728 "or\\t%1, %%l44(%a2), %0")
2730 (define_insn "sethh"
2731 [(set (match_operand:DI 0 "register_operand" "=r")
2732 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2734 "sethi\\t%%hh(%a1), %0")
2736 (define_insn "setlm"
2737 [(set (match_operand:DI 0 "register_operand" "=r")
2738 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2740 "sethi\\t%%lm(%a1), %0")
2742 (define_insn "sethm"
2743 [(set (match_operand:DI 0 "register_operand" "=r")
2744 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2745 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2747 "or\\t%1, %%hm(%a2), %0")
2749 (define_insn "setlo"
2750 [(set (match_operand:DI 0 "register_operand" "=r")
2751 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2752 (match_operand:DI 2 "symbolic_operand" "")))]
2754 "or\\t%1, %%lo(%a2), %0")
2756 (define_insn "embmedany_sethi"
2757 [(set (match_operand:DI 0 "register_operand" "=r")
2758 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2759 "TARGET_CM_EMBMEDANY && check_pic (1)"
2760 "sethi\\t%%hi(%a1), %0")
2762 (define_insn "embmedany_losum"
2763 [(set (match_operand:DI 0 "register_operand" "=r")
2764 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2765 (match_operand:DI 2 "data_segment_operand" "")))]
2766 "TARGET_CM_EMBMEDANY"
2767 "add\\t%1, %%lo(%a2), %0")
2769 (define_insn "embmedany_brsum"
2770 [(set (match_operand:DI 0 "register_operand" "=r")
2771 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2772 "TARGET_CM_EMBMEDANY"
2775 (define_insn "embmedany_textuhi"
2776 [(set (match_operand:DI 0 "register_operand" "=r")
2777 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2778 "TARGET_CM_EMBMEDANY && check_pic (1)"
2779 "sethi\\t%%uhi(%a1), %0")
2781 (define_insn "embmedany_texthi"
2782 [(set (match_operand:DI 0 "register_operand" "=r")
2783 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2784 "TARGET_CM_EMBMEDANY && check_pic (1)"
2785 "sethi\\t%%hi(%a1), %0")
2787 (define_insn "embmedany_textulo"
2788 [(set (match_operand:DI 0 "register_operand" "=r")
2789 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2790 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2791 "TARGET_CM_EMBMEDANY"
2792 "or\\t%1, %%ulo(%a2), %0")
2794 (define_insn "embmedany_textlo"
2795 [(set (match_operand:DI 0 "register_operand" "=r")
2796 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2797 (match_operand:DI 2 "text_segment_operand" "")))]
2798 "TARGET_CM_EMBMEDANY"
2799 "or\\t%1, %%lo(%a2), %0")
2801 ;; Now some patterns to help reload out a bit.
2802 (define_expand "reload_indi"
2803 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2804 (match_operand:DI 1 "immediate_operand" "")
2805 (match_operand:TI 2 "register_operand" "=&r")])]
2807 || TARGET_CM_EMBMEDANY)
2811 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2815 (define_expand "reload_outdi"
2816 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2817 (match_operand:DI 1 "immediate_operand" "")
2818 (match_operand:TI 2 "register_operand" "=&r")])]
2820 || TARGET_CM_EMBMEDANY)
2824 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2828 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2830 [(set (match_operand:DI 0 "register_operand" "")
2831 (match_operand:DI 1 "const_int_operand" ""))]
2832 "! TARGET_ARCH64 && reload_completed"
2833 [(clobber (const_int 0))]
2836 #if HOST_BITS_PER_WIDE_INT == 32
2837 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2838 (INTVAL (operands[1]) < 0) ?
2841 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2844 unsigned int low, high;
2846 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2847 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2848 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2850 /* Slick... but this trick loses if this subreg constant part
2851 can be done in one insn. */
2852 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2853 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2854 gen_highpart (SImode, operands[0])));
2856 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2862 [(set (match_operand:DI 0 "register_operand" "")
2863 (match_operand:DI 1 "const_double_operand" ""))]
2864 "! TARGET_ARCH64 && reload_completed"
2865 [(clobber (const_int 0))]
2868 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2869 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2871 /* Slick... but this trick loses if this subreg constant part
2872 can be done in one insn. */
2873 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2874 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2875 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2877 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2878 gen_highpart (SImode, operands[0])));
2882 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2883 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2889 [(set (match_operand:DI 0 "register_operand" "")
2890 (match_operand:DI 1 "register_operand" ""))]
2891 "! TARGET_ARCH64 && reload_completed"
2892 [(clobber (const_int 0))]
2895 rtx set_dest = operands[0];
2896 rtx set_src = operands[1];
2900 dest1 = gen_highpart (SImode, set_dest);
2901 dest2 = gen_lowpart (SImode, set_dest);
2902 src1 = gen_highpart (SImode, set_src);
2903 src2 = gen_lowpart (SImode, set_src);
2905 /* Now emit using the real source and destination we found, swapping
2906 the order if we detect overlap. */
2907 if (reg_overlap_mentioned_p (dest1, src2))
2909 emit_insn (gen_movsi (dest2, src2));
2910 emit_insn (gen_movsi (dest1, src1));
2914 emit_insn (gen_movsi (dest1, src1));
2915 emit_insn (gen_movsi (dest2, src2));
2920 ;; Now handle the cases of memory moves from/to non-even
2921 ;; DI mode register pairs.
2923 [(set (match_operand:DI 0 "register_operand" "")
2924 (match_operand:DI 1 "memory_operand" ""))]
2927 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2928 [(clobber (const_int 0))]
2931 rtx word0 = adjust_address (operands[1], SImode, 0);
2932 rtx word1 = adjust_address (operands[1], SImode, 4);
2933 rtx high_part = gen_highpart (SImode, operands[0]);
2934 rtx low_part = gen_lowpart (SImode, operands[0]);
2936 if (reg_overlap_mentioned_p (high_part, word1))
2938 emit_insn (gen_movsi (low_part, word1));
2939 emit_insn (gen_movsi (high_part, word0));
2943 emit_insn (gen_movsi (high_part, word0));
2944 emit_insn (gen_movsi (low_part, word1));
2950 [(set (match_operand:DI 0 "memory_operand" "")
2951 (match_operand:DI 1 "register_operand" ""))]
2954 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2955 [(clobber (const_int 0))]
2958 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2959 gen_highpart (SImode, operands[1])));
2960 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2961 gen_lowpart (SImode, operands[1])));
2966 [(set (match_operand:DI 0 "memory_operand" "")
2971 && ! mem_min_alignment (operands[0], 8)))
2972 && offsettable_memref_p (operands[0])"
2973 [(clobber (const_int 0))]
2976 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2977 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2981 ;; Floating point move insns
2983 (define_insn "*movsf_insn_novis"
2984 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2985 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2986 "(TARGET_FPU && ! TARGET_VIS)
2987 && (register_operand (operands[0], SFmode)
2988 || register_operand (operands[1], SFmode)
2989 || fp_zero_operand (operands[1], SFmode))"
2992 if (GET_CODE (operands[1]) == CONST_DOUBLE
2993 && (which_alternative == 2
2994 || which_alternative == 3
2995 || which_alternative == 4))
3000 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3001 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3002 operands[1] = GEN_INT (i);
3005 switch (which_alternative)
3008 return \"fmovs\\t%1, %0\";
3010 return \"clr\\t%0\";
3012 return \"sethi\\t%%hi(%a1), %0\";
3014 return \"mov\\t%1, %0\";
3019 return \"ld\\t%1, %0\";
3022 return \"st\\t%r1, %0\";
3027 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3029 (define_insn "*movsf_insn_vis"
3030 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3031 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3032 "(TARGET_FPU && TARGET_VIS)
3033 && (register_operand (operands[0], SFmode)
3034 || register_operand (operands[1], SFmode)
3035 || fp_zero_operand (operands[1], SFmode))"
3038 if (GET_CODE (operands[1]) == CONST_DOUBLE
3039 && (which_alternative == 3
3040 || which_alternative == 4
3041 || which_alternative == 5))
3046 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3047 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3048 operands[1] = GEN_INT (i);
3051 switch (which_alternative)
3054 return \"fmovs\\t%1, %0\";
3056 return \"fzeros\\t%0\";
3058 return \"clr\\t%0\";
3060 return \"sethi\\t%%hi(%a1), %0\";
3062 return \"mov\\t%1, %0\";
3067 return \"ld\\t%1, %0\";
3070 return \"st\\t%r1, %0\";
3075 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3077 ;; Exactly the same as above, except that all `f' cases are deleted.
3078 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3081 (define_insn "*movsf_no_f_insn"
3082 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3083 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3085 && (register_operand (operands[0], SFmode)
3086 || register_operand (operands[1], SFmode)
3087 || fp_zero_operand (operands[1], SFmode))"
3090 if (GET_CODE (operands[1]) == CONST_DOUBLE
3091 && (which_alternative == 1
3092 || which_alternative == 2
3093 || which_alternative == 3))
3098 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3099 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3100 operands[1] = GEN_INT (i);
3103 switch (which_alternative)
3106 return \"clr\\t%0\";
3108 return \"sethi\\t%%hi(%a1), %0\";
3110 return \"mov\\t%1, %0\";
3114 return \"ld\\t%1, %0\";
3116 return \"st\\t%r1, %0\";
3121 [(set_attr "type" "*,*,*,*,load,store")])
3123 (define_insn "*movsf_lo_sum"
3124 [(set (match_operand:SF 0 "register_operand" "=r")
3125 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3126 (match_operand:SF 2 "const_double_operand" "S")))]
3127 "fp_high_losum_p (operands[2])"
3133 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3134 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3135 operands[2] = GEN_INT (i);
3136 return \"or\\t%1, %%lo(%a2), %0\";
3139 (define_insn "*movsf_high"
3140 [(set (match_operand:SF 0 "register_operand" "=r")
3141 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3142 "fp_high_losum_p (operands[1])"
3148 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3149 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3150 operands[1] = GEN_INT (i);
3151 return \"sethi\\t%%hi(%1), %0\";
3155 [(set (match_operand:SF 0 "register_operand" "")
3156 (match_operand:SF 1 "const_double_operand" ""))]
3157 "fp_high_losum_p (operands[1])
3158 && (GET_CODE (operands[0]) == REG
3159 && REGNO (operands[0]) < 32)"
3160 [(set (match_dup 0) (high:SF (match_dup 1)))
3161 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3163 (define_expand "movsf"
3164 [(set (match_operand:SF 0 "general_operand" "")
3165 (match_operand:SF 1 "general_operand" ""))]
3169 /* Force SFmode constants into memory. */
3170 if (GET_CODE (operands[0]) == REG
3171 && CONSTANT_P (operands[1]))
3173 /* emit_group_store will send such bogosity to us when it is
3174 not storing directly into memory. So fix this up to avoid
3175 crashes in output_constant_pool. */
3176 if (operands [1] == const0_rtx)
3177 operands[1] = CONST0_RTX (SFmode);
3179 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3182 /* We are able to build any SF constant in integer registers
3183 with at most 2 instructions. */
3184 if (REGNO (operands[0]) < 32)
3187 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3191 /* Handle sets of MEM first. */
3192 if (GET_CODE (operands[0]) == MEM)
3194 if (register_operand (operands[1], SFmode)
3195 || fp_zero_operand (operands[1], SFmode))
3198 if (! reload_in_progress)
3200 operands[0] = validize_mem (operands[0]);
3201 operands[1] = force_reg (SFmode, operands[1]);
3205 /* Fixup PIC cases. */
3208 if (CONSTANT_P (operands[1])
3209 && pic_address_needs_scratch (operands[1]))
3210 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3212 if (symbolic_operand (operands[1], SFmode))
3214 operands[1] = legitimize_pic_address (operands[1],
3216 (reload_in_progress ?
3226 (define_expand "movdf"
3227 [(set (match_operand:DF 0 "general_operand" "")
3228 (match_operand:DF 1 "general_operand" ""))]
3232 /* Force DFmode constants into memory. */
3233 if (GET_CODE (operands[0]) == REG
3234 && CONSTANT_P (operands[1]))
3236 /* emit_group_store will send such bogosity to us when it is
3237 not storing directly into memory. So fix this up to avoid
3238 crashes in output_constant_pool. */
3239 if (operands [1] == const0_rtx)
3240 operands[1] = CONST0_RTX (DFmode);
3242 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3243 && fp_zero_operand (operands[1], DFmode))
3246 /* We are able to build any DF constant in integer registers. */
3247 if (REGNO (operands[0]) < 32
3248 && (reload_completed || reload_in_progress))
3251 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3255 /* Handle MEM cases first. */
3256 if (GET_CODE (operands[0]) == MEM)
3258 if (register_operand (operands[1], DFmode)
3259 || fp_zero_operand (operands[1], DFmode))
3262 if (! reload_in_progress)
3264 operands[0] = validize_mem (operands[0]);
3265 operands[1] = force_reg (DFmode, operands[1]);
3269 /* Fixup PIC cases. */
3272 if (CONSTANT_P (operands[1])
3273 && pic_address_needs_scratch (operands[1]))
3274 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3276 if (symbolic_operand (operands[1], DFmode))
3278 operands[1] = legitimize_pic_address (operands[1],
3280 (reload_in_progress ?
3290 ;; Be careful, fmovd does not exist when !v9.
3291 (define_insn "*movdf_insn_sp32"
3292 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
3293 (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3296 && (register_operand (operands[0], DFmode)
3297 || register_operand (operands[1], DFmode)
3298 || fp_zero_operand (operands[1], DFmode))"
3310 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3311 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3313 (define_insn "*movdf_no_e_insn_sp32"
3314 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3315 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3319 && (register_operand (operands[0], DFmode)
3320 || register_operand (operands[1], DFmode)
3321 || fp_zero_operand (operands[1], DFmode))"
3328 [(set_attr "type" "load,store,*,*,*")
3329 (set_attr "length" "*,*,2,2,2")])
3331 (define_insn "*movdf_no_e_insn_v9_sp32"
3332 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3333 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3337 && (register_operand (operands[0], DFmode)
3338 || register_operand (operands[1], DFmode)
3339 || fp_zero_operand (operands[1], DFmode))"
3346 [(set_attr "type" "load,store,store,*,*")
3347 (set_attr "length" "*,*,*,2,2")])
3349 ;; We have available v9 double floats but not 64-bit
3350 ;; integer registers and no VIS.
3351 (define_insn "*movdf_insn_v9only_novis"
3352 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,e,*r,o")
3353 (match_operand:DF 1 "input_operand" "e,W#F,G,e,T,U,o#F,*roF,*rGe"))]
3358 && (register_operand (operands[0], DFmode)
3359 || register_operand (operands[1], DFmode)
3360 || fp_zero_operand (operands[1], DFmode))"
3371 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3372 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3373 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3375 ;; We have available v9 double floats but not 64-bit
3376 ;; integer registers but we have VIS.
3377 (define_insn "*movdf_insn_v9only_vis"
3378 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,e,*r,o")
3379 (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGe"))]
3383 && (register_operand (operands[0], DFmode)
3384 || register_operand (operands[1], DFmode)
3385 || fp_zero_operand (operands[1], DFmode))"
3397 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3398 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3399 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3401 ;; We have available both v9 double floats and 64-bit
3402 ;; integer registers. No VIS though.
3403 (define_insn "*movdf_insn_sp64_novis"
3404 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3405 (match_operand:DF 1 "input_operand" "e,W#F,e,*rG,m,*rG,F"))]
3409 && (register_operand (operands[0], DFmode)
3410 || register_operand (operands[1], DFmode)
3411 || fp_zero_operand (operands[1], DFmode))"
3420 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3421 (set_attr "length" "*,*,*,*,*,*,2")
3422 (set_attr "fptype" "double,*,*,*,*,*,*")])
3424 ;; We have available both v9 double floats and 64-bit
3425 ;; integer registers. And we have VIS.
3426 (define_insn "*movdf_insn_sp64_vis"
3427 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3428 (match_operand:DF 1 "input_operand" "G,e,W#F,e,*rG,m,*rG,F"))]
3432 && (register_operand (operands[0], DFmode)
3433 || register_operand (operands[1], DFmode)
3434 || fp_zero_operand (operands[1], DFmode))"
3444 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3445 (set_attr "length" "*,*,*,*,*,*,*,2")
3446 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3448 (define_insn "*movdf_no_e_insn_sp64"
3449 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3450 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3453 && (register_operand (operands[0], DFmode)
3454 || register_operand (operands[1], DFmode)
3455 || fp_zero_operand (operands[1], DFmode))"
3460 [(set_attr "type" "*,load,store")])
3463 [(set (match_operand:DF 0 "register_operand" "")
3464 (match_operand:DF 1 "const_double_operand" ""))]
3466 && (GET_CODE (operands[0]) == REG
3467 && REGNO (operands[0]) < 32)
3468 && ! fp_zero_operand(operands[1], DFmode)
3469 && reload_completed"
3470 [(clobber (const_int 0))]
3476 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3477 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3478 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3482 #if HOST_BITS_PER_WIDE_INT == 64
3485 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3486 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3487 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3489 emit_insn (gen_movdi (operands[0],
3490 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3495 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3498 /* Slick... but this trick loses if this subreg constant part
3499 can be done in one insn. */
3501 && !(SPARC_SETHI32_P (l[0])
3502 || SPARC_SIMM13_P (l[0])))
3504 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3505 gen_highpart (SImode, operands[0])));
3509 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3516 ;; Ok, now the splits to handle all the multi insn and
3517 ;; mis-aligned memory address cases.
3518 ;; In these splits please take note that we must be
3519 ;; careful when V9 but not ARCH64 because the integer
3520 ;; register DFmode cases must be handled.
3522 [(set (match_operand:DF 0 "register_operand" "")
3523 (match_operand:DF 1 "register_operand" ""))]
3526 && ((GET_CODE (operands[0]) == REG
3527 && REGNO (operands[0]) < 32)
3528 || (GET_CODE (operands[0]) == SUBREG
3529 && GET_CODE (SUBREG_REG (operands[0])) == REG
3530 && REGNO (SUBREG_REG (operands[0])) < 32))))
3531 && reload_completed"
3532 [(clobber (const_int 0))]
3535 rtx set_dest = operands[0];
3536 rtx set_src = operands[1];
3540 dest1 = gen_highpart (SFmode, set_dest);
3541 dest2 = gen_lowpart (SFmode, set_dest);
3542 src1 = gen_highpart (SFmode, set_src);
3543 src2 = gen_lowpart (SFmode, set_src);
3545 /* Now emit using the real source and destination we found, swapping
3546 the order if we detect overlap. */
3547 if (reg_overlap_mentioned_p (dest1, src2))
3549 emit_insn (gen_movsf (dest2, src2));
3550 emit_insn (gen_movsf (dest1, src1));
3554 emit_insn (gen_movsf (dest1, src1));
3555 emit_insn (gen_movsf (dest2, src2));
3561 [(set (match_operand:DF 0 "register_operand" "")
3562 (match_operand:DF 1 "memory_operand" ""))]
3565 && (((REGNO (operands[0]) % 2) != 0)
3566 || ! mem_min_alignment (operands[1], 8))
3567 && offsettable_memref_p (operands[1])"
3568 [(clobber (const_int 0))]
3571 rtx word0 = adjust_address (operands[1], SFmode, 0);
3572 rtx word1 = adjust_address (operands[1], SFmode, 4);
3574 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3576 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3578 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3583 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3585 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3592 [(set (match_operand:DF 0 "memory_operand" "")
3593 (match_operand:DF 1 "register_operand" ""))]
3596 && (((REGNO (operands[1]) % 2) != 0)
3597 || ! mem_min_alignment (operands[0], 8))
3598 && offsettable_memref_p (operands[0])"
3599 [(clobber (const_int 0))]
3602 rtx word0 = adjust_address (operands[0], SFmode, 0);
3603 rtx word1 = adjust_address (operands[0], SFmode, 4);
3605 emit_insn (gen_movsf (word0,
3606 gen_highpart (SFmode, operands[1])));
3607 emit_insn (gen_movsf (word1,
3608 gen_lowpart (SFmode, operands[1])));
3613 [(set (match_operand:DF 0 "memory_operand" "")
3614 (match_operand:DF 1 "fp_zero_operand" ""))]
3618 && ! mem_min_alignment (operands[0], 8)))
3619 && offsettable_memref_p (operands[0])"
3620 [(clobber (const_int 0))]
3625 dest1 = adjust_address (operands[0], SFmode, 0);
3626 dest2 = adjust_address (operands[0], SFmode, 4);
3628 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3629 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3634 [(set (match_operand:DF 0 "register_operand" "")
3635 (match_operand:DF 1 "fp_zero_operand" ""))]
3638 && ((GET_CODE (operands[0]) == REG
3639 && REGNO (operands[0]) < 32)
3640 || (GET_CODE (operands[0]) == SUBREG
3641 && GET_CODE (SUBREG_REG (operands[0])) == REG
3642 && REGNO (SUBREG_REG (operands[0])) < 32))"
3643 [(clobber (const_int 0))]
3646 rtx set_dest = operands[0];
3649 dest1 = gen_highpart (SFmode, set_dest);
3650 dest2 = gen_lowpart (SFmode, set_dest);
3651 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3652 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3656 (define_expand "movtf"
3657 [(set (match_operand:TF 0 "general_operand" "")
3658 (match_operand:TF 1 "general_operand" ""))]
3662 /* Force TFmode constants into memory. */
3663 if (GET_CODE (operands[0]) == REG
3664 && CONSTANT_P (operands[1]))
3666 /* emit_group_store will send such bogosity to us when it is
3667 not storing directly into memory. So fix this up to avoid
3668 crashes in output_constant_pool. */
3669 if (operands [1] == const0_rtx)
3670 operands[1] = CONST0_RTX (TFmode);
3672 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3675 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3679 /* Handle MEM cases first, note that only v9 guarentees
3680 full 16-byte alignment for quads. */
3681 if (GET_CODE (operands[0]) == MEM)
3683 if (register_operand (operands[1], TFmode)
3684 || fp_zero_operand (operands[1], TFmode))
3687 if (! reload_in_progress)
3689 operands[0] = validize_mem (operands[0]);
3690 operands[1] = force_reg (TFmode, operands[1]);
3694 /* Fixup PIC cases. */
3697 if (CONSTANT_P (operands[1])
3698 && pic_address_needs_scratch (operands[1]))
3699 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3701 if (symbolic_operand (operands[1], TFmode))
3703 operands[1] = legitimize_pic_address (operands[1],
3705 (reload_in_progress ?
3715 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3716 ;; we must split them all. :-(
3717 (define_insn "*movtf_insn_sp32"
3718 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3719 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3723 && (register_operand (operands[0], TFmode)
3724 || register_operand (operands[1], TFmode)
3725 || fp_zero_operand (operands[1], TFmode))"
3727 [(set_attr "length" "4")])
3729 (define_insn "*movtf_insn_vis_sp32"
3730 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3731 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3735 && (register_operand (operands[0], TFmode)
3736 || register_operand (operands[1], TFmode)
3737 || fp_zero_operand (operands[1], TFmode))"
3739 [(set_attr "length" "4")])
3741 ;; Exactly the same as above, except that all `e' cases are deleted.
3742 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3745 (define_insn "*movtf_no_e_insn_sp32"
3746 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3747 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3750 && (register_operand (operands[0], TFmode)
3751 || register_operand (operands[1], TFmode)
3752 || fp_zero_operand (operands[1], TFmode))"
3754 [(set_attr "length" "4")])
3756 ;; Now handle the float reg cases directly when arch64,
3757 ;; hard_quad, and proper reg number alignment are all true.
3758 (define_insn "*movtf_insn_hq_sp64"
3759 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3760 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3765 && (register_operand (operands[0], TFmode)
3766 || register_operand (operands[1], TFmode)
3767 || fp_zero_operand (operands[1], TFmode))"
3774 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3775 (set_attr "length" "*,*,*,2,2")])
3777 (define_insn "*movtf_insn_hq_vis_sp64"
3778 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3779 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3784 && (register_operand (operands[0], TFmode)
3785 || register_operand (operands[1], TFmode)
3786 || fp_zero_operand (operands[1], TFmode))"
3794 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3795 (set_attr "length" "*,*,*,2,2,2")])
3797 ;; Now we allow the integer register cases even when
3798 ;; only arch64 is true.
3799 (define_insn "*movtf_insn_sp64"
3800 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3801 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3805 && ! TARGET_HARD_QUAD
3806 && (register_operand (operands[0], TFmode)
3807 || register_operand (operands[1], TFmode)
3808 || fp_zero_operand (operands[1], TFmode))"
3810 [(set_attr "length" "2")])
3812 (define_insn "*movtf_insn_vis_sp64"
3813 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3814 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3818 && ! TARGET_HARD_QUAD
3819 && (register_operand (operands[0], TFmode)
3820 || register_operand (operands[1], TFmode)
3821 || fp_zero_operand (operands[1], TFmode))"
3823 [(set_attr "length" "2")])
3825 (define_insn "*movtf_no_e_insn_sp64"
3826 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3827 (match_operand:TF 1 "input_operand" "orG,rG"))]
3830 && (register_operand (operands[0], TFmode)
3831 || register_operand (operands[1], TFmode)
3832 || fp_zero_operand (operands[1], TFmode))"
3834 [(set_attr "length" "2")])
3836 ;; Now all the splits to handle multi-insn TF mode moves.
3838 [(set (match_operand:TF 0 "register_operand" "")
3839 (match_operand:TF 1 "register_operand" ""))]
3843 && ! TARGET_HARD_QUAD)
3844 || ! fp_register_operand (operands[0], TFmode))"
3845 [(clobber (const_int 0))]
3848 rtx set_dest = operands[0];
3849 rtx set_src = operands[1];
3853 dest1 = gen_df_reg (set_dest, 0);
3854 dest2 = gen_df_reg (set_dest, 1);
3855 src1 = gen_df_reg (set_src, 0);
3856 src2 = gen_df_reg (set_src, 1);
3858 /* Now emit using the real source and destination we found, swapping
3859 the order if we detect overlap. */
3860 if (reg_overlap_mentioned_p (dest1, src2))
3862 emit_insn (gen_movdf (dest2, src2));
3863 emit_insn (gen_movdf (dest1, src1));
3867 emit_insn (gen_movdf (dest1, src1));
3868 emit_insn (gen_movdf (dest2, src2));
3874 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3875 (match_operand:TF 1 "fp_zero_operand" ""))]
3877 [(clobber (const_int 0))]
3880 rtx set_dest = operands[0];
3883 switch (GET_CODE (set_dest))
3886 dest1 = gen_df_reg (set_dest, 0);
3887 dest2 = gen_df_reg (set_dest, 1);
3890 dest1 = adjust_address (set_dest, DFmode, 0);
3891 dest2 = adjust_address (set_dest, DFmode, 8);
3897 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3898 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3903 [(set (match_operand:TF 0 "register_operand" "")
3904 (match_operand:TF 1 "memory_operand" ""))]
3906 && offsettable_memref_p (operands[1])
3908 || ! TARGET_HARD_QUAD
3909 || ! fp_register_operand (operands[0], TFmode)))"
3910 [(clobber (const_int 0))]
3913 rtx word0 = adjust_address (operands[1], DFmode, 0);
3914 rtx word1 = adjust_address (operands[1], DFmode, 8);
3915 rtx set_dest, dest1, dest2;
3917 set_dest = operands[0];
3919 dest1 = gen_df_reg (set_dest, 0);
3920 dest2 = gen_df_reg (set_dest, 1);
3922 /* Now output, ordering such that we don't clobber any registers
3923 mentioned in the address. */
3924 if (reg_overlap_mentioned_p (dest1, word1))
3927 emit_insn (gen_movdf (dest2, word1));
3928 emit_insn (gen_movdf (dest1, word0));
3932 emit_insn (gen_movdf (dest1, word0));
3933 emit_insn (gen_movdf (dest2, word1));
3939 [(set (match_operand:TF 0 "memory_operand" "")
3940 (match_operand:TF 1 "register_operand" ""))]
3942 && offsettable_memref_p (operands[0])
3944 || ! TARGET_HARD_QUAD
3945 || ! fp_register_operand (operands[1], TFmode)))"
3946 [(clobber (const_int 0))]
3949 rtx set_src = operands[1];
3951 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3952 gen_df_reg (set_src, 0)));
3953 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3954 gen_df_reg (set_src, 1)));
3958 ;; Sparc V9 conditional move instructions.
3960 ;; We can handle larger constants here for some flavors, but for now we keep
3961 ;; it simple and only allow those constants supported by all flavours.
3962 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3963 ;; 3 contains the constant if one is present, but we handle either for
3964 ;; generality (sparc.c puts a constant in operand 2).
3966 (define_expand "movqicc"
3967 [(set (match_operand:QI 0 "register_operand" "")
3968 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3969 (match_operand:QI 2 "arith10_operand" "")
3970 (match_operand:QI 3 "arith10_operand" "")))]
3974 enum rtx_code code = GET_CODE (operands[1]);
3976 if (GET_MODE (sparc_compare_op0) == DImode
3980 if (sparc_compare_op1 == const0_rtx
3981 && GET_CODE (sparc_compare_op0) == REG
3982 && GET_MODE (sparc_compare_op0) == DImode
3983 && v9_regcmp_p (code))
3985 operands[1] = gen_rtx_fmt_ee (code, DImode,
3986 sparc_compare_op0, sparc_compare_op1);
3990 rtx cc_reg = gen_compare_reg (code,
3991 sparc_compare_op0, sparc_compare_op1);
3992 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3996 (define_expand "movhicc"
3997 [(set (match_operand:HI 0 "register_operand" "")
3998 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3999 (match_operand:HI 2 "arith10_operand" "")
4000 (match_operand:HI 3 "arith10_operand" "")))]
4004 enum rtx_code code = GET_CODE (operands[1]);
4006 if (GET_MODE (sparc_compare_op0) == DImode
4010 if (sparc_compare_op1 == const0_rtx
4011 && GET_CODE (sparc_compare_op0) == REG
4012 && GET_MODE (sparc_compare_op0) == DImode
4013 && v9_regcmp_p (code))
4015 operands[1] = gen_rtx_fmt_ee (code, DImode,
4016 sparc_compare_op0, sparc_compare_op1);
4020 rtx cc_reg = gen_compare_reg (code,
4021 sparc_compare_op0, sparc_compare_op1);
4022 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4026 (define_expand "movsicc"
4027 [(set (match_operand:SI 0 "register_operand" "")
4028 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4029 (match_operand:SI 2 "arith10_operand" "")
4030 (match_operand:SI 3 "arith10_operand" "")))]
4034 enum rtx_code code = GET_CODE (operands[1]);
4035 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4037 if (sparc_compare_op1 == const0_rtx
4038 && GET_CODE (sparc_compare_op0) == REG
4039 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4041 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4042 sparc_compare_op0, sparc_compare_op1);
4046 rtx cc_reg = gen_compare_reg (code,
4047 sparc_compare_op0, sparc_compare_op1);
4048 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4049 cc_reg, const0_rtx);
4053 (define_expand "movdicc"
4054 [(set (match_operand:DI 0 "register_operand" "")
4055 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4056 (match_operand:DI 2 "arith10_double_operand" "")
4057 (match_operand:DI 3 "arith10_double_operand" "")))]
4061 enum rtx_code code = GET_CODE (operands[1]);
4063 if (sparc_compare_op1 == const0_rtx
4064 && GET_CODE (sparc_compare_op0) == REG
4065 && GET_MODE (sparc_compare_op0) == DImode
4066 && v9_regcmp_p (code))
4068 operands[1] = gen_rtx_fmt_ee (code, DImode,
4069 sparc_compare_op0, sparc_compare_op1);
4073 rtx cc_reg = gen_compare_reg (code,
4074 sparc_compare_op0, sparc_compare_op1);
4075 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4076 cc_reg, const0_rtx);
4080 (define_expand "movsfcc"
4081 [(set (match_operand:SF 0 "register_operand" "")
4082 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4083 (match_operand:SF 2 "register_operand" "")
4084 (match_operand:SF 3 "register_operand" "")))]
4085 "TARGET_V9 && TARGET_FPU"
4088 enum rtx_code code = GET_CODE (operands[1]);
4090 if (GET_MODE (sparc_compare_op0) == DImode
4094 if (sparc_compare_op1 == const0_rtx
4095 && GET_CODE (sparc_compare_op0) == REG
4096 && GET_MODE (sparc_compare_op0) == DImode
4097 && v9_regcmp_p (code))
4099 operands[1] = gen_rtx_fmt_ee (code, DImode,
4100 sparc_compare_op0, sparc_compare_op1);
4104 rtx cc_reg = gen_compare_reg (code,
4105 sparc_compare_op0, sparc_compare_op1);
4106 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4110 (define_expand "movdfcc"
4111 [(set (match_operand:DF 0 "register_operand" "")
4112 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4113 (match_operand:DF 2 "register_operand" "")
4114 (match_operand:DF 3 "register_operand" "")))]
4115 "TARGET_V9 && TARGET_FPU"
4118 enum rtx_code code = GET_CODE (operands[1]);
4120 if (GET_MODE (sparc_compare_op0) == DImode
4124 if (sparc_compare_op1 == const0_rtx
4125 && GET_CODE (sparc_compare_op0) == REG
4126 && GET_MODE (sparc_compare_op0) == DImode
4127 && v9_regcmp_p (code))
4129 operands[1] = gen_rtx_fmt_ee (code, DImode,
4130 sparc_compare_op0, sparc_compare_op1);
4134 rtx cc_reg = gen_compare_reg (code,
4135 sparc_compare_op0, sparc_compare_op1);
4136 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4140 (define_expand "movtfcc"
4141 [(set (match_operand:TF 0 "register_operand" "")
4142 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4143 (match_operand:TF 2 "register_operand" "")
4144 (match_operand:TF 3 "register_operand" "")))]
4145 "TARGET_V9 && TARGET_FPU"
4148 enum rtx_code code = GET_CODE (operands[1]);
4150 if (GET_MODE (sparc_compare_op0) == DImode
4154 if (sparc_compare_op1 == const0_rtx
4155 && GET_CODE (sparc_compare_op0) == REG
4156 && GET_MODE (sparc_compare_op0) == DImode
4157 && v9_regcmp_p (code))
4159 operands[1] = gen_rtx_fmt_ee (code, DImode,
4160 sparc_compare_op0, sparc_compare_op1);
4164 rtx cc_reg = gen_compare_reg (code,
4165 sparc_compare_op0, sparc_compare_op1);
4166 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4170 ;; Conditional move define_insns.
4172 (define_insn "*movqi_cc_sp64"
4173 [(set (match_operand:QI 0 "register_operand" "=r,r")
4174 (if_then_else:QI (match_operator 1 "comparison_operator"
4175 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4177 (match_operand:QI 3 "arith11_operand" "rL,0")
4178 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4181 mov%C1\\t%x2, %3, %0
4182 mov%c1\\t%x2, %4, %0"
4183 [(set_attr "type" "cmove")])
4185 (define_insn "*movhi_cc_sp64"
4186 [(set (match_operand:HI 0 "register_operand" "=r,r")
4187 (if_then_else:HI (match_operator 1 "comparison_operator"
4188 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4190 (match_operand:HI 3 "arith11_operand" "rL,0")
4191 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4194 mov%C1\\t%x2, %3, %0
4195 mov%c1\\t%x2, %4, %0"
4196 [(set_attr "type" "cmove")])
4198 (define_insn "*movsi_cc_sp64"
4199 [(set (match_operand:SI 0 "register_operand" "=r,r")
4200 (if_then_else:SI (match_operator 1 "comparison_operator"
4201 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4203 (match_operand:SI 3 "arith11_operand" "rL,0")
4204 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4207 mov%C1\\t%x2, %3, %0
4208 mov%c1\\t%x2, %4, %0"
4209 [(set_attr "type" "cmove")])
4211 ;; ??? The constraints of operands 3,4 need work.
4212 (define_insn "*movdi_cc_sp64"
4213 [(set (match_operand:DI 0 "register_operand" "=r,r")
4214 (if_then_else:DI (match_operator 1 "comparison_operator"
4215 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4217 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4218 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4221 mov%C1\\t%x2, %3, %0
4222 mov%c1\\t%x2, %4, %0"
4223 [(set_attr "type" "cmove")])
4225 (define_insn "*movdi_cc_sp64_trunc"
4226 [(set (match_operand:SI 0 "register_operand" "=r,r")
4227 (if_then_else:SI (match_operator 1 "comparison_operator"
4228 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4230 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4231 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4234 mov%C1\\t%x2, %3, %0
4235 mov%c1\\t%x2, %4, %0"
4236 [(set_attr "type" "cmove")])
4238 (define_insn "*movsf_cc_sp64"
4239 [(set (match_operand:SF 0 "register_operand" "=f,f")
4240 (if_then_else:SF (match_operator 1 "comparison_operator"
4241 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4243 (match_operand:SF 3 "register_operand" "f,0")
4244 (match_operand:SF 4 "register_operand" "0,f")))]
4245 "TARGET_V9 && TARGET_FPU"
4247 fmovs%C1\\t%x2, %3, %0
4248 fmovs%c1\\t%x2, %4, %0"
4249 [(set_attr "type" "fpcmove")])
4251 (define_insn "movdf_cc_sp64"
4252 [(set (match_operand:DF 0 "register_operand" "=e,e")
4253 (if_then_else:DF (match_operator 1 "comparison_operator"
4254 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4256 (match_operand:DF 3 "register_operand" "e,0")
4257 (match_operand:DF 4 "register_operand" "0,e")))]
4258 "TARGET_V9 && TARGET_FPU"
4260 fmovd%C1\\t%x2, %3, %0
4261 fmovd%c1\\t%x2, %4, %0"
4262 [(set_attr "type" "fpcmove")
4263 (set_attr "fptype" "double")])
4265 (define_insn "*movtf_cc_hq_sp64"
4266 [(set (match_operand:TF 0 "register_operand" "=e,e")
4267 (if_then_else:TF (match_operator 1 "comparison_operator"
4268 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4270 (match_operand:TF 3 "register_operand" "e,0")
4271 (match_operand:TF 4 "register_operand" "0,e")))]
4272 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4274 fmovq%C1\\t%x2, %3, %0
4275 fmovq%c1\\t%x2, %4, %0"
4276 [(set_attr "type" "fpcmove")])
4278 (define_insn "*movtf_cc_sp64"
4279 [(set (match_operand:TF 0 "register_operand" "=e,e")
4280 (if_then_else:TF (match_operator 1 "comparison_operator"
4281 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4283 (match_operand:TF 3 "register_operand" "e,0")
4284 (match_operand:TF 4 "register_operand" "0,e")))]
4285 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4287 [(set_attr "length" "2")])
4290 [(set (match_operand:TF 0 "register_operand" "")
4291 (if_then_else:TF (match_operator 1 "comparison_operator"
4292 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4294 (match_operand:TF 3 "register_operand" "")
4295 (match_operand:TF 4 "register_operand" "")))]
4296 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4297 [(clobber (const_int 0))]
4300 rtx set_dest = operands[0];
4301 rtx set_srca = operands[3];
4302 rtx set_srcb = operands[4];
4303 int third = rtx_equal_p (set_dest, set_srca);
4305 rtx srca1, srca2, srcb1, srcb2;
4307 dest1 = gen_df_reg (set_dest, 0);
4308 dest2 = gen_df_reg (set_dest, 1);
4309 srca1 = gen_df_reg (set_srca, 0);
4310 srca2 = gen_df_reg (set_srca, 1);
4311 srcb1 = gen_df_reg (set_srcb, 0);
4312 srcb2 = gen_df_reg (set_srcb, 1);
4314 /* Now emit using the real source and destination we found, swapping
4315 the order if we detect overlap. */
4316 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4317 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4319 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4320 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4324 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4325 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4330 (define_insn "*movqi_cc_reg_sp64"
4331 [(set (match_operand:QI 0 "register_operand" "=r,r")
4332 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4333 [(match_operand:DI 2 "register_operand" "r,r")
4335 (match_operand:QI 3 "arith10_operand" "rM,0")
4336 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4339 movr%D1\\t%2, %r3, %0
4340 movr%d1\\t%2, %r4, %0"
4341 [(set_attr "type" "cmove")])
4343 (define_insn "*movhi_cc_reg_sp64"
4344 [(set (match_operand:HI 0 "register_operand" "=r,r")
4345 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4346 [(match_operand:DI 2 "register_operand" "r,r")
4348 (match_operand:HI 3 "arith10_operand" "rM,0")
4349 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4352 movr%D1\\t%2, %r3, %0
4353 movr%d1\\t%2, %r4, %0"
4354 [(set_attr "type" "cmove")])
4356 (define_insn "*movsi_cc_reg_sp64"
4357 [(set (match_operand:SI 0 "register_operand" "=r,r")
4358 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4359 [(match_operand:DI 2 "register_operand" "r,r")
4361 (match_operand:SI 3 "arith10_operand" "rM,0")
4362 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4365 movr%D1\\t%2, %r3, %0
4366 movr%d1\\t%2, %r4, %0"
4367 [(set_attr "type" "cmove")])
4369 ;; ??? The constraints of operands 3,4 need work.
4370 (define_insn "*movdi_cc_reg_sp64"
4371 [(set (match_operand:DI 0 "register_operand" "=r,r")
4372 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4373 [(match_operand:DI 2 "register_operand" "r,r")
4375 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4376 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4379 movr%D1\\t%2, %r3, %0
4380 movr%d1\\t%2, %r4, %0"
4381 [(set_attr "type" "cmove")])
4383 (define_insn "*movdi_cc_reg_sp64_trunc"
4384 [(set (match_operand:SI 0 "register_operand" "=r,r")
4385 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4386 [(match_operand:DI 2 "register_operand" "r,r")
4388 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4389 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4392 movr%D1\\t%2, %r3, %0
4393 movr%d1\\t%2, %r4, %0"
4394 [(set_attr "type" "cmove")])
4396 (define_insn "*movsf_cc_reg_sp64"
4397 [(set (match_operand:SF 0 "register_operand" "=f,f")
4398 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4399 [(match_operand:DI 2 "register_operand" "r,r")
4401 (match_operand:SF 3 "register_operand" "f,0")
4402 (match_operand:SF 4 "register_operand" "0,f")))]
4403 "TARGET_ARCH64 && TARGET_FPU"
4405 fmovrs%D1\\t%2, %3, %0
4406 fmovrs%d1\\t%2, %4, %0"
4407 [(set_attr "type" "fpcmove")])
4409 (define_insn "movdf_cc_reg_sp64"
4410 [(set (match_operand:DF 0 "register_operand" "=e,e")
4411 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4412 [(match_operand:DI 2 "register_operand" "r,r")
4414 (match_operand:DF 3 "register_operand" "e,0")
4415 (match_operand:DF 4 "register_operand" "0,e")))]
4416 "TARGET_ARCH64 && TARGET_FPU"
4418 fmovrd%D1\\t%2, %3, %0
4419 fmovrd%d1\\t%2, %4, %0"
4420 [(set_attr "type" "fpcmove")
4421 (set_attr "fptype" "double")])
4423 (define_insn "*movtf_cc_reg_hq_sp64"
4424 [(set (match_operand:TF 0 "register_operand" "=e,e")
4425 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4426 [(match_operand:DI 2 "register_operand" "r,r")
4428 (match_operand:TF 3 "register_operand" "e,0")
4429 (match_operand:TF 4 "register_operand" "0,e")))]
4430 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4432 fmovrq%D1\\t%2, %3, %0
4433 fmovrq%d1\\t%2, %4, %0"
4434 [(set_attr "type" "fpcmove")])
4436 (define_insn "*movtf_cc_reg_sp64"
4437 [(set (match_operand:TF 0 "register_operand" "=e,e")
4438 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4439 [(match_operand:DI 2 "register_operand" "r,r")
4441 (match_operand:TF 3 "register_operand" "e,0")
4442 (match_operand:TF 4 "register_operand" "0,e")))]
4443 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4445 [(set_attr "length" "2")])
4448 [(set (match_operand:TF 0 "register_operand" "")
4449 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4450 [(match_operand:DI 2 "register_operand" "")
4452 (match_operand:TF 3 "register_operand" "")
4453 (match_operand:TF 4 "register_operand" "")))]
4454 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4455 [(clobber (const_int 0))]
4458 rtx set_dest = operands[0];
4459 rtx set_srca = operands[3];
4460 rtx set_srcb = operands[4];
4461 int third = rtx_equal_p (set_dest, set_srca);
4463 rtx srca1, srca2, srcb1, srcb2;
4465 dest1 = gen_df_reg (set_dest, 0);
4466 dest2 = gen_df_reg (set_dest, 1);
4467 srca1 = gen_df_reg (set_srca, 0);
4468 srca2 = gen_df_reg (set_srca, 1);
4469 srcb1 = gen_df_reg (set_srcb, 0);
4470 srcb2 = gen_df_reg (set_srcb, 1);
4472 /* Now emit using the real source and destination we found, swapping
4473 the order if we detect overlap. */
4474 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4475 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4477 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4478 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4482 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4483 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4489 ;;- zero extension instructions
4491 ;; These patterns originally accepted general_operands, however, slightly
4492 ;; better code is generated by only accepting register_operands, and then
4493 ;; letting combine generate the ldu[hb] insns.
4495 (define_expand "zero_extendhisi2"
4496 [(set (match_operand:SI 0 "register_operand" "")
4497 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4501 rtx temp = gen_reg_rtx (SImode);
4502 rtx shift_16 = GEN_INT (16);
4503 int op1_subbyte = 0;
4505 if (GET_CODE (operand1) == SUBREG)
4507 op1_subbyte = SUBREG_BYTE (operand1);
4508 op1_subbyte /= GET_MODE_SIZE (SImode);
4509 op1_subbyte *= GET_MODE_SIZE (SImode);
4510 operand1 = XEXP (operand1, 0);
4513 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4515 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4519 (define_insn "*zero_extendhisi2_insn"
4520 [(set (match_operand:SI 0 "register_operand" "=r")
4521 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4524 [(set_attr "type" "load")])
4526 (define_expand "zero_extendqihi2"
4527 [(set (match_operand:HI 0 "register_operand" "")
4528 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4532 (define_insn "*zero_extendqihi2_insn"
4533 [(set (match_operand:HI 0 "register_operand" "=r,r")
4534 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4535 "GET_CODE (operands[1]) != CONST_INT"
4539 [(set_attr "type" "*,load")])
4541 (define_expand "zero_extendqisi2"
4542 [(set (match_operand:SI 0 "register_operand" "")
4543 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4547 (define_insn "*zero_extendqisi2_insn"
4548 [(set (match_operand:SI 0 "register_operand" "=r,r")
4549 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4550 "GET_CODE (operands[1]) != CONST_INT"
4554 [(set_attr "type" "*,load")])
4556 (define_expand "zero_extendqidi2"
4557 [(set (match_operand:DI 0 "register_operand" "")
4558 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4562 (define_insn "*zero_extendqidi2_insn"
4563 [(set (match_operand:DI 0 "register_operand" "=r,r")
4564 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4565 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4569 [(set_attr "type" "*,load")])
4571 (define_expand "zero_extendhidi2"
4572 [(set (match_operand:DI 0 "register_operand" "")
4573 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4577 rtx temp = gen_reg_rtx (DImode);
4578 rtx shift_48 = GEN_INT (48);
4579 int op1_subbyte = 0;
4581 if (GET_CODE (operand1) == SUBREG)
4583 op1_subbyte = SUBREG_BYTE (operand1);
4584 op1_subbyte /= GET_MODE_SIZE (DImode);
4585 op1_subbyte *= GET_MODE_SIZE (DImode);
4586 operand1 = XEXP (operand1, 0);
4589 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4591 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4595 (define_insn "*zero_extendhidi2_insn"
4596 [(set (match_operand:DI 0 "register_operand" "=r")
4597 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4600 [(set_attr "type" "load")])
4603 ;; ??? Write truncdisi pattern using sra?
4605 (define_expand "zero_extendsidi2"
4606 [(set (match_operand:DI 0 "register_operand" "")
4607 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4611 (define_insn "*zero_extendsidi2_insn_sp64"
4612 [(set (match_operand:DI 0 "register_operand" "=r,r")
4613 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4614 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4618 [(set_attr "type" "shift,load")])
4620 (define_insn "*zero_extendsidi2_insn_sp32"
4621 [(set (match_operand:DI 0 "register_operand" "=r")
4622 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4625 [(set_attr "length" "2")])
4628 [(set (match_operand:DI 0 "register_operand" "")
4629 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4630 "! TARGET_ARCH64 && reload_completed"
4631 [(set (match_dup 2) (match_dup 3))
4632 (set (match_dup 4) (match_dup 5))]
4637 dest1 = gen_highpart (SImode, operands[0]);
4638 dest2 = gen_lowpart (SImode, operands[0]);
4640 /* Swap the order in case of overlap. */
4641 if (REGNO (dest1) == REGNO (operands[1]))
4643 operands[2] = dest2;
4644 operands[3] = operands[1];
4645 operands[4] = dest1;
4646 operands[5] = const0_rtx;
4650 operands[2] = dest1;
4651 operands[3] = const0_rtx;
4652 operands[4] = dest2;
4653 operands[5] = operands[1];
4657 ;; Simplify comparisons of extended values.
4659 (define_insn "*cmp_zero_extendqisi2"
4661 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4664 "andcc\\t%0, 0xff, %%g0"
4665 [(set_attr "type" "compare")])
4667 (define_insn "*cmp_zero_qi"
4669 (compare:CC (match_operand:QI 0 "register_operand" "r")
4672 "andcc\\t%0, 0xff, %%g0"
4673 [(set_attr "type" "compare")])
4675 (define_insn "*cmp_zero_extendqisi2_set"
4677 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4679 (set (match_operand:SI 0 "register_operand" "=r")
4680 (zero_extend:SI (match_dup 1)))]
4682 "andcc\\t%1, 0xff, %0"
4683 [(set_attr "type" "compare")])
4685 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4687 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4690 (set (match_operand:SI 0 "register_operand" "=r")
4691 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4693 "andcc\\t%1, 0xff, %0"
4694 [(set_attr "type" "compare")])
4696 (define_insn "*cmp_zero_extendqidi2"
4698 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4701 "andcc\\t%0, 0xff, %%g0"
4702 [(set_attr "type" "compare")])
4704 (define_insn "*cmp_zero_qi_sp64"
4706 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4709 "andcc\\t%0, 0xff, %%g0"
4710 [(set_attr "type" "compare")])
4712 (define_insn "*cmp_zero_extendqidi2_set"
4714 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4716 (set (match_operand:DI 0 "register_operand" "=r")
4717 (zero_extend:DI (match_dup 1)))]
4719 "andcc\\t%1, 0xff, %0"
4720 [(set_attr "type" "compare")])
4722 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4724 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4727 (set (match_operand:DI 0 "register_operand" "=r")
4728 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4730 "andcc\\t%1, 0xff, %0"
4731 [(set_attr "type" "compare")])
4733 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4735 (define_insn "*cmp_siqi_trunc"
4737 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4740 "andcc\\t%0, 0xff, %%g0"
4741 [(set_attr "type" "compare")])
4743 (define_insn "*cmp_siqi_trunc_set"
4745 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4747 (set (match_operand:QI 0 "register_operand" "=r")
4748 (subreg:QI (match_dup 1) 3))]
4750 "andcc\\t%1, 0xff, %0"
4751 [(set_attr "type" "compare")])
4753 (define_insn "*cmp_diqi_trunc"
4755 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4758 "andcc\\t%0, 0xff, %%g0"
4759 [(set_attr "type" "compare")])
4761 (define_insn "*cmp_diqi_trunc_set"
4763 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4765 (set (match_operand:QI 0 "register_operand" "=r")
4766 (subreg:QI (match_dup 1) 7))]
4768 "andcc\\t%1, 0xff, %0"
4769 [(set_attr "type" "compare")])
4771 ;;- sign extension instructions
4773 ;; These patterns originally accepted general_operands, however, slightly
4774 ;; better code is generated by only accepting register_operands, and then
4775 ;; letting combine generate the lds[hb] insns.
4777 (define_expand "extendhisi2"
4778 [(set (match_operand:SI 0 "register_operand" "")
4779 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4783 rtx temp = gen_reg_rtx (SImode);
4784 rtx shift_16 = GEN_INT (16);
4785 int op1_subbyte = 0;
4787 if (GET_CODE (operand1) == SUBREG)
4789 op1_subbyte = SUBREG_BYTE (operand1);
4790 op1_subbyte /= GET_MODE_SIZE (SImode);
4791 op1_subbyte *= GET_MODE_SIZE (SImode);
4792 operand1 = XEXP (operand1, 0);
4795 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4797 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4801 (define_insn "*sign_extendhisi2_insn"
4802 [(set (match_operand:SI 0 "register_operand" "=r")
4803 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4806 [(set_attr "type" "sload")])
4808 (define_expand "extendqihi2"
4809 [(set (match_operand:HI 0 "register_operand" "")
4810 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4814 rtx temp = gen_reg_rtx (SImode);
4815 rtx shift_24 = GEN_INT (24);
4816 int op1_subbyte = 0;
4817 int op0_subbyte = 0;
4819 if (GET_CODE (operand1) == SUBREG)
4821 op1_subbyte = SUBREG_BYTE (operand1);
4822 op1_subbyte /= GET_MODE_SIZE (SImode);
4823 op1_subbyte *= GET_MODE_SIZE (SImode);
4824 operand1 = XEXP (operand1, 0);
4826 if (GET_CODE (operand0) == SUBREG)
4828 op0_subbyte = SUBREG_BYTE (operand0);
4829 op0_subbyte /= GET_MODE_SIZE (SImode);
4830 op0_subbyte *= GET_MODE_SIZE (SImode);
4831 operand0 = XEXP (operand0, 0);
4833 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4835 if (GET_MODE (operand0) != SImode)
4836 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4837 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4841 (define_insn "*sign_extendqihi2_insn"
4842 [(set (match_operand:HI 0 "register_operand" "=r")
4843 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4846 [(set_attr "type" "sload")])
4848 (define_expand "extendqisi2"
4849 [(set (match_operand:SI 0 "register_operand" "")
4850 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4854 rtx temp = gen_reg_rtx (SImode);
4855 rtx shift_24 = GEN_INT (24);
4856 int op1_subbyte = 0;
4858 if (GET_CODE (operand1) == SUBREG)
4860 op1_subbyte = SUBREG_BYTE (operand1);
4861 op1_subbyte /= GET_MODE_SIZE (SImode);
4862 op1_subbyte *= GET_MODE_SIZE (SImode);
4863 operand1 = XEXP (operand1, 0);
4866 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4868 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4872 (define_insn "*sign_extendqisi2_insn"
4873 [(set (match_operand:SI 0 "register_operand" "=r")
4874 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4877 [(set_attr "type" "sload")])
4879 (define_expand "extendqidi2"
4880 [(set (match_operand:DI 0 "register_operand" "")
4881 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4885 rtx temp = gen_reg_rtx (DImode);
4886 rtx shift_56 = GEN_INT (56);
4887 int op1_subbyte = 0;
4889 if (GET_CODE (operand1) == SUBREG)
4891 op1_subbyte = SUBREG_BYTE (operand1);
4892 op1_subbyte /= GET_MODE_SIZE (DImode);
4893 op1_subbyte *= GET_MODE_SIZE (DImode);
4894 operand1 = XEXP (operand1, 0);
4897 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4899 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4903 (define_insn "*sign_extendqidi2_insn"
4904 [(set (match_operand:DI 0 "register_operand" "=r")
4905 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4908 [(set_attr "type" "sload")])
4910 (define_expand "extendhidi2"
4911 [(set (match_operand:DI 0 "register_operand" "")
4912 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4916 rtx temp = gen_reg_rtx (DImode);
4917 rtx shift_48 = GEN_INT (48);
4918 int op1_subbyte = 0;
4920 if (GET_CODE (operand1) == SUBREG)
4922 op1_subbyte = SUBREG_BYTE (operand1);
4923 op1_subbyte /= GET_MODE_SIZE (DImode);
4924 op1_subbyte *= GET_MODE_SIZE (DImode);
4925 operand1 = XEXP (operand1, 0);
4928 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4930 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4934 (define_insn "*sign_extendhidi2_insn"
4935 [(set (match_operand:DI 0 "register_operand" "=r")
4936 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4939 [(set_attr "type" "sload")])
4941 (define_expand "extendsidi2"
4942 [(set (match_operand:DI 0 "register_operand" "")
4943 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4947 (define_insn "*sign_extendsidi2_insn"
4948 [(set (match_operand:DI 0 "register_operand" "=r,r")
4949 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4954 [(set_attr "type" "shift,sload")])
4956 ;; Special pattern for optimizing bit-field compares. This is needed
4957 ;; because combine uses this as a canonical form.
4959 (define_insn "*cmp_zero_extract"
4962 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4963 (match_operand:SI 1 "small_int_or_double" "n")
4964 (match_operand:SI 2 "small_int_or_double" "n"))
4966 "(GET_CODE (operands[2]) == CONST_INT
4967 && INTVAL (operands[2]) > 19)
4968 || (GET_CODE (operands[2]) == CONST_DOUBLE
4969 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4972 int len = (GET_CODE (operands[1]) == CONST_INT
4973 ? INTVAL (operands[1])
4974 : CONST_DOUBLE_LOW (operands[1]));
4976 (GET_CODE (operands[2]) == CONST_INT
4977 ? INTVAL (operands[2])
4978 : CONST_DOUBLE_LOW (operands[2])) - len;
4979 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4981 operands[1] = GEN_INT (mask);
4982 return \"andcc\\t%0, %1, %%g0\";
4984 [(set_attr "type" "compare")])
4986 (define_insn "*cmp_zero_extract_sp64"
4989 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4990 (match_operand:SI 1 "small_int_or_double" "n")
4991 (match_operand:SI 2 "small_int_or_double" "n"))
4994 && ((GET_CODE (operands[2]) == CONST_INT
4995 && INTVAL (operands[2]) > 51)
4996 || (GET_CODE (operands[2]) == CONST_DOUBLE
4997 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5000 int len = (GET_CODE (operands[1]) == CONST_INT
5001 ? INTVAL (operands[1])
5002 : CONST_DOUBLE_LOW (operands[1]));
5004 (GET_CODE (operands[2]) == CONST_INT
5005 ? INTVAL (operands[2])
5006 : CONST_DOUBLE_LOW (operands[2])) - len;
5007 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5009 operands[1] = GEN_INT (mask);
5010 return \"andcc\\t%0, %1, %%g0\";
5012 [(set_attr "type" "compare")])
5014 ;; Conversions between float, double and long double.
5016 (define_insn "extendsfdf2"
5017 [(set (match_operand:DF 0 "register_operand" "=e")
5019 (match_operand:SF 1 "register_operand" "f")))]
5022 [(set_attr "type" "fp")
5023 (set_attr "fptype" "double")])
5025 (define_expand "extendsftf2"
5026 [(set (match_operand:TF 0 "register_operand" "=e")
5028 (match_operand:SF 1 "register_operand" "f")))]
5029 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5032 if (! TARGET_HARD_QUAD)
5036 if (GET_CODE (operands[0]) != MEM)
5037 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5039 slot0 = operands[0];
5041 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), LCT_NORMAL,
5043 XEXP (slot0, 0), Pmode,
5044 operands[1], SFmode);
5046 if (GET_CODE (operands[0]) != MEM)
5047 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5052 (define_insn "*extendsftf2_hq"
5053 [(set (match_operand:TF 0 "register_operand" "=e")
5055 (match_operand:SF 1 "register_operand" "f")))]
5056 "TARGET_FPU && TARGET_HARD_QUAD"
5058 [(set_attr "type" "fp")])
5060 (define_expand "extenddftf2"
5061 [(set (match_operand:TF 0 "register_operand" "=e")
5063 (match_operand:DF 1 "register_operand" "e")))]
5064 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5067 if (! TARGET_HARD_QUAD)
5071 if (GET_CODE (operands[0]) != MEM)
5072 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5074 slot0 = operands[0];
5076 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), LCT_NORMAL,
5078 XEXP (slot0, 0), Pmode,
5079 operands[1], DFmode);
5081 if (GET_CODE (operands[0]) != MEM)
5082 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5087 (define_insn "*extenddftf2_hq"
5088 [(set (match_operand:TF 0 "register_operand" "=e")
5090 (match_operand:DF 1 "register_operand" "e")))]
5091 "TARGET_FPU && TARGET_HARD_QUAD"
5093 [(set_attr "type" "fp")])
5095 (define_insn "truncdfsf2"
5096 [(set (match_operand:SF 0 "register_operand" "=f")
5098 (match_operand:DF 1 "register_operand" "e")))]
5101 [(set_attr "type" "fp")
5102 (set_attr "fptype" "double")])
5104 (define_expand "trunctfsf2"
5105 [(set (match_operand:SF 0 "register_operand" "=f")
5107 (match_operand:TF 1 "register_operand" "e")))]
5108 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5111 if (! TARGET_HARD_QUAD)
5115 if (GET_CODE (operands[1]) != MEM)
5117 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5118 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5121 slot0 = operands[1];
5123 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5124 operands[0], LCT_NORMAL, SFmode, 1,
5125 XEXP (slot0, 0), Pmode);
5130 (define_insn "*trunctfsf2_hq"
5131 [(set (match_operand:SF 0 "register_operand" "=f")
5133 (match_operand:TF 1 "register_operand" "e")))]
5134 "TARGET_FPU && TARGET_HARD_QUAD"
5136 [(set_attr "type" "fp")])
5138 (define_expand "trunctfdf2"
5139 [(set (match_operand:DF 0 "register_operand" "=f")
5141 (match_operand:TF 1 "register_operand" "e")))]
5142 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5145 if (! TARGET_HARD_QUAD)
5149 if (GET_CODE (operands[1]) != MEM)
5151 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5152 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5155 slot0 = operands[1];
5157 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5158 operands[0], LCT_NORMAL, DFmode, 1,
5159 XEXP (slot0, 0), Pmode);
5164 (define_insn "*trunctfdf2_hq"
5165 [(set (match_operand:DF 0 "register_operand" "=e")
5167 (match_operand:TF 1 "register_operand" "e")))]
5168 "TARGET_FPU && TARGET_HARD_QUAD"
5170 [(set_attr "type" "fp")])
5172 ;; Conversion between fixed point and floating point.
5174 (define_insn "floatsisf2"
5175 [(set (match_operand:SF 0 "register_operand" "=f")
5176 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5179 [(set_attr "type" "fp")
5180 (set_attr "fptype" "double")])
5182 (define_insn "floatsidf2"
5183 [(set (match_operand:DF 0 "register_operand" "=e")
5184 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5187 [(set_attr "type" "fp")
5188 (set_attr "fptype" "double")])
5190 (define_expand "floatsitf2"
5191 [(set (match_operand:TF 0 "register_operand" "=e")
5192 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5193 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5196 if (! TARGET_HARD_QUAD)
5200 if (GET_CODE (operands[1]) != MEM)
5201 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5203 slot0 = operands[1];
5205 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5207 XEXP (slot0, 0), Pmode,
5208 operands[1], SImode);
5210 if (GET_CODE (operands[0]) != MEM)
5211 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5216 (define_insn "*floatsitf2_hq"
5217 [(set (match_operand:TF 0 "register_operand" "=e")
5218 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5219 "TARGET_FPU && TARGET_HARD_QUAD"
5221 [(set_attr "type" "fp")])
5223 (define_expand "floatunssitf2"
5224 [(set (match_operand:TF 0 "register_operand" "=e")
5225 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5226 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5231 if (GET_CODE (operands[1]) != MEM)
5232 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5234 slot0 = operands[1];
5236 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5238 XEXP (slot0, 0), Pmode,
5239 operands[1], SImode);
5241 if (GET_CODE (operands[0]) != MEM)
5242 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5246 ;; Now the same for 64 bit sources.
5248 (define_insn "floatdisf2"
5249 [(set (match_operand:SF 0 "register_operand" "=f")
5250 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5251 "TARGET_V9 && TARGET_FPU"
5253 [(set_attr "type" "fp")
5254 (set_attr "fptype" "double")])
5256 (define_expand "floatunsdisf2"
5257 [(use (match_operand:SF 0 "register_operand" ""))
5258 (use (match_operand:DI 1 "register_operand" ""))]
5259 "TARGET_ARCH64 && TARGET_FPU"
5260 "sparc_emit_floatunsdi (operands); DONE;")
5262 (define_insn "floatdidf2"
5263 [(set (match_operand:DF 0 "register_operand" "=e")
5264 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5265 "TARGET_V9 && TARGET_FPU"
5267 [(set_attr "type" "fp")
5268 (set_attr "fptype" "double")])
5270 (define_expand "floatunsdidf2"
5271 [(use (match_operand:DF 0 "register_operand" ""))
5272 (use (match_operand:DI 1 "register_operand" ""))]
5273 "TARGET_ARCH64 && TARGET_FPU"
5274 "sparc_emit_floatunsdi (operands); DONE;")
5276 (define_expand "floatditf2"
5277 [(set (match_operand:TF 0 "register_operand" "=e")
5278 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5279 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5282 if (! TARGET_HARD_QUAD)
5286 if (GET_CODE (operands[1]) != MEM)
5287 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5289 slot0 = operands[1];
5291 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5293 XEXP (slot0, 0), Pmode,
5294 operands[1], DImode);
5296 if (GET_CODE (operands[0]) != MEM)
5297 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5302 (define_insn "*floatditf2_hq"
5303 [(set (match_operand:TF 0 "register_operand" "=e")
5304 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5305 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5307 [(set_attr "type" "fp")])
5309 (define_expand "floatunsditf2"
5310 [(set (match_operand:TF 0 "register_operand" "=e")
5311 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5312 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5317 if (GET_CODE (operands[1]) != MEM)
5318 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5320 slot0 = operands[1];
5322 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5324 XEXP (slot0, 0), Pmode,
5325 operands[1], DImode);
5327 if (GET_CODE (operands[0]) != MEM)
5328 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5332 ;; Convert a float to an actual integer.
5333 ;; Truncation is performed as part of the conversion.
5335 (define_insn "fix_truncsfsi2"
5336 [(set (match_operand:SI 0 "register_operand" "=f")
5337 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5340 [(set_attr "type" "fp")
5341 (set_attr "fptype" "double")])
5343 (define_insn "fix_truncdfsi2"
5344 [(set (match_operand:SI 0 "register_operand" "=f")
5345 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5348 [(set_attr "type" "fp")
5349 (set_attr "fptype" "double")])
5351 (define_expand "fix_trunctfsi2"
5352 [(set (match_operand:SI 0 "register_operand" "=f")
5353 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5354 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5357 if (! TARGET_HARD_QUAD)
5361 if (GET_CODE (operands[1]) != MEM)
5363 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5364 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5367 slot0 = operands[1];
5369 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5370 operands[0], LCT_NORMAL, SImode, 1,
5371 XEXP (slot0, 0), Pmode);
5376 (define_insn "*fix_trunctfsi2_hq"
5377 [(set (match_operand:SI 0 "register_operand" "=f")
5378 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5379 "TARGET_FPU && TARGET_HARD_QUAD"
5381 [(set_attr "type" "fp")])
5383 (define_expand "fixuns_trunctfsi2"
5384 [(set (match_operand:SI 0 "register_operand" "=f")
5385 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5386 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5391 if (GET_CODE (operands[1]) != MEM)
5393 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5394 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5397 slot0 = operands[1];
5399 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5400 operands[0], LCT_NORMAL, SImode, 1,
5401 XEXP (slot0, 0), Pmode);
5405 ;; Now the same, for V9 targets
5407 (define_insn "fix_truncsfdi2"
5408 [(set (match_operand:DI 0 "register_operand" "=e")
5409 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5410 "TARGET_V9 && TARGET_FPU"
5412 [(set_attr "type" "fp")
5413 (set_attr "fptype" "double")])
5415 (define_insn "fix_truncdfdi2"
5416 [(set (match_operand:DI 0 "register_operand" "=e")
5417 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5418 "TARGET_V9 && TARGET_FPU"
5420 [(set_attr "type" "fp")
5421 (set_attr "fptype" "double")])
5423 (define_expand "fix_trunctfdi2"
5424 [(set (match_operand:DI 0 "register_operand" "=e")
5425 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5426 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5429 if (! TARGET_HARD_QUAD)
5433 if (GET_CODE (operands[1]) != MEM)
5435 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5436 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5439 slot0 = operands[1];
5441 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5442 operands[0], LCT_NORMAL, DImode, 1,
5443 XEXP (slot0, 0), Pmode);
5448 (define_insn "*fix_trunctfdi2_hq"
5449 [(set (match_operand:DI 0 "register_operand" "=e")
5450 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5451 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5453 [(set_attr "type" "fp")])
5455 (define_expand "fixuns_trunctfdi2"
5456 [(set (match_operand:DI 0 "register_operand" "=f")
5457 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5458 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5463 if (GET_CODE (operands[1]) != MEM)
5465 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5466 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5469 slot0 = operands[1];
5471 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5472 operands[0], LCT_NORMAL, DImode, 1,
5473 XEXP (slot0, 0), Pmode);
5478 ;;- arithmetic instructions
5480 (define_expand "adddi3"
5481 [(set (match_operand:DI 0 "register_operand" "=r")
5482 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5483 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5489 if (! TARGET_ARCH64)
5491 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5492 gen_rtx_SET (VOIDmode, operands[0],
5493 gen_rtx_PLUS (DImode, operands[1],
5495 gen_rtx_CLOBBER (VOIDmode,
5496 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5499 if (arith_double_4096_operand(operands[2], DImode))
5501 switch (GET_CODE (operands[1]))
5503 case CONST_INT: i = INTVAL (operands[1]); break;
5504 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5506 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5507 gen_rtx_MINUS (DImode, operands[1],
5511 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5516 (define_insn "adddi3_insn_sp32"
5517 [(set (match_operand:DI 0 "register_operand" "=r")
5518 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5519 (match_operand:DI 2 "arith_double_operand" "rHI")))
5520 (clobber (reg:CC 100))]
5523 [(set_attr "length" "2")])
5526 [(set (match_operand:DI 0 "register_operand" "")
5527 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5528 (match_operand:DI 2 "arith_double_operand" "")))
5529 (clobber (reg:CC 100))]
5530 "! TARGET_ARCH64 && reload_completed"
5531 [(parallel [(set (reg:CC_NOOV 100)
5532 (compare:CC_NOOV (plus:SI (match_dup 4)
5536 (plus:SI (match_dup 4) (match_dup 5)))])
5538 (plus:SI (plus:SI (match_dup 7)
5540 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5543 operands[3] = gen_lowpart (SImode, operands[0]);
5544 operands[4] = gen_lowpart (SImode, operands[1]);
5545 operands[5] = gen_lowpart (SImode, operands[2]);
5546 operands[6] = gen_highpart (SImode, operands[0]);
5547 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5548 #if HOST_BITS_PER_WIDE_INT == 32
5549 if (GET_CODE (operands[2]) == CONST_INT)
5551 if (INTVAL (operands[2]) < 0)
5552 operands[8] = constm1_rtx;
5554 operands[8] = const0_rtx;
5558 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5562 [(set (match_operand:DI 0 "register_operand" "")
5563 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5564 (match_operand:DI 2 "arith_double_operand" "")))
5565 (clobber (reg:CC 100))]
5566 "! TARGET_ARCH64 && reload_completed"
5567 [(parallel [(set (reg:CC_NOOV 100)
5568 (compare:CC_NOOV (minus:SI (match_dup 4)
5572 (minus:SI (match_dup 4) (match_dup 5)))])
5574 (minus:SI (minus:SI (match_dup 7)
5576 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5579 operands[3] = gen_lowpart (SImode, operands[0]);
5580 operands[4] = gen_lowpart (SImode, operands[1]);
5581 operands[5] = gen_lowpart (SImode, operands[2]);
5582 operands[6] = gen_highpart (SImode, operands[0]);
5583 operands[7] = gen_highpart (SImode, operands[1]);
5584 #if HOST_BITS_PER_WIDE_INT == 32
5585 if (GET_CODE (operands[2]) == CONST_INT)
5587 if (INTVAL (operands[2]) < 0)
5588 operands[8] = constm1_rtx;
5590 operands[8] = const0_rtx;
5594 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5597 ;; LTU here means "carry set"
5599 [(set (match_operand:SI 0 "register_operand" "=r")
5600 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5601 (match_operand:SI 2 "arith_operand" "rI"))
5602 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5605 [(set_attr "type" "misc")])
5607 (define_insn "*addx_extend_sp32"
5608 [(set (match_operand:DI 0 "register_operand" "=r")
5609 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5610 (match_operand:SI 2 "arith_operand" "rI"))
5611 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5614 [(set_attr "length" "2")])
5617 [(set (match_operand:DI 0 "register_operand" "")
5618 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5619 (match_operand:SI 2 "arith_operand" ""))
5620 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5621 "! TARGET_ARCH64 && reload_completed"
5622 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5623 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5624 (set (match_dup 4) (const_int 0))]
5625 "operands[3] = gen_lowpart (SImode, operands[0]);
5626 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5628 (define_insn "*addx_extend_sp64"
5629 [(set (match_operand:DI 0 "register_operand" "=r")
5630 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5631 (match_operand:SI 2 "arith_operand" "rI"))
5632 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5634 "addx\\t%r1, %2, %0"
5635 [(set_attr "type" "misc")])
5638 [(set (match_operand:SI 0 "register_operand" "=r")
5639 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5640 (match_operand:SI 2 "arith_operand" "rI"))
5641 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5643 "subx\\t%r1, %2, %0"
5644 [(set_attr "type" "misc")])
5646 (define_insn "*subx_extend_sp64"
5647 [(set (match_operand:DI 0 "register_operand" "=r")
5648 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5649 (match_operand:SI 2 "arith_operand" "rI"))
5650 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5652 "subx\\t%r1, %2, %0"
5653 [(set_attr "type" "misc")])
5655 (define_insn "*subx_extend"
5656 [(set (match_operand:DI 0 "register_operand" "=r")
5657 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5658 (match_operand:SI 2 "arith_operand" "rI"))
5659 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5662 [(set_attr "length" "2")])
5665 [(set (match_operand:DI 0 "register_operand" "")
5666 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5667 (match_operand:SI 2 "arith_operand" ""))
5668 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5669 "! TARGET_ARCH64 && reload_completed"
5670 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5671 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5672 (set (match_dup 4) (const_int 0))]
5673 "operands[3] = gen_lowpart (SImode, operands[0]);
5674 operands[4] = gen_highpart (SImode, operands[0]);")
5677 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5679 (match_operand:DI 2 "register_operand" "r")))
5680 (clobber (reg:CC 100))]
5683 [(set_attr "length" "2")])
5686 [(set (match_operand:DI 0 "register_operand" "")
5687 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5688 (match_operand:DI 2 "register_operand" "")))
5689 (clobber (reg:CC 100))]
5690 "! TARGET_ARCH64 && reload_completed"
5691 [(parallel [(set (reg:CC_NOOV 100)
5692 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5694 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5696 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5697 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5698 "operands[3] = gen_lowpart (SImode, operands[2]);
5699 operands[4] = gen_highpart (SImode, operands[2]);
5700 operands[5] = gen_lowpart (SImode, operands[0]);
5701 operands[6] = gen_highpart (SImode, operands[0]);")
5703 (define_insn "*adddi3_sp64"
5704 [(set (match_operand:DI 0 "register_operand" "=r")
5705 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5706 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5710 (define_expand "addsi3"
5711 [(set (match_operand:SI 0 "register_operand" "=r,d")
5712 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5713 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5717 if (arith_4096_operand(operands[2], SImode))
5719 if (GET_CODE (operands[1]) == CONST_INT)
5720 emit_insn (gen_movsi (operands[0],
5721 GEN_INT (INTVAL (operands[1]) + 4096)));
5723 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5724 gen_rtx_MINUS (SImode, operands[1],
5730 (define_insn "*addsi3"
5731 [(set (match_operand:SI 0 "register_operand" "=r,d")
5732 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5733 (match_operand:SI 2 "arith_operand" "rI,d")))]
5737 fpadd32s\\t%1, %2, %0"
5738 [(set_attr "type" "*,fp")])
5740 (define_insn "*cmp_cc_plus"
5741 [(set (reg:CC_NOOV 100)
5742 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5743 (match_operand:SI 1 "arith_operand" "rI"))
5746 "addcc\\t%0, %1, %%g0"
5747 [(set_attr "type" "compare")])
5749 (define_insn "*cmp_ccx_plus"
5750 [(set (reg:CCX_NOOV 100)
5751 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5752 (match_operand:DI 1 "arith_double_operand" "rHI"))
5755 "addcc\\t%0, %1, %%g0"
5756 [(set_attr "type" "compare")])
5758 (define_insn "*cmp_cc_plus_set"
5759 [(set (reg:CC_NOOV 100)
5760 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5761 (match_operand:SI 2 "arith_operand" "rI"))
5763 (set (match_operand:SI 0 "register_operand" "=r")
5764 (plus:SI (match_dup 1) (match_dup 2)))]
5766 "addcc\\t%1, %2, %0"
5767 [(set_attr "type" "compare")])
5769 (define_insn "*cmp_ccx_plus_set"
5770 [(set (reg:CCX_NOOV 100)
5771 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5772 (match_operand:DI 2 "arith_double_operand" "rHI"))
5774 (set (match_operand:DI 0 "register_operand" "=r")
5775 (plus:DI (match_dup 1) (match_dup 2)))]
5777 "addcc\\t%1, %2, %0"
5778 [(set_attr "type" "compare")])
5780 (define_expand "subdi3"
5781 [(set (match_operand:DI 0 "register_operand" "=r")
5782 (minus:DI (match_operand:DI 1 "register_operand" "r")
5783 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5787 if (! TARGET_ARCH64)
5789 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5790 gen_rtx_SET (VOIDmode, operands[0],
5791 gen_rtx_MINUS (DImode, operands[1],
5793 gen_rtx_CLOBBER (VOIDmode,
5794 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5797 if (arith_double_4096_operand(operands[2], DImode))
5799 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5800 gen_rtx_PLUS (DImode, operands[1],
5806 (define_insn "*subdi3_sp32"
5807 [(set (match_operand:DI 0 "register_operand" "=r")
5808 (minus:DI (match_operand:DI 1 "register_operand" "r")
5809 (match_operand:DI 2 "arith_double_operand" "rHI")))
5810 (clobber (reg:CC 100))]
5813 [(set_attr "length" "2")])
5816 [(set (match_operand:DI 0 "register_operand" "")
5817 (minus:DI (match_operand:DI 1 "register_operand" "")
5818 (match_operand:DI 2 "arith_double_operand" "")))
5819 (clobber (reg:CC 100))]
5822 && (GET_CODE (operands[2]) == CONST_INT
5823 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5824 [(clobber (const_int 0))]
5829 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5830 lowp = gen_lowpart (SImode, operands[2]);
5831 if ((lowp == const0_rtx)
5832 && (operands[0] == operands[1]))
5834 emit_insn (gen_rtx_SET (VOIDmode,
5835 gen_highpart (SImode, operands[0]),
5836 gen_rtx_MINUS (SImode,
5837 gen_highpart_mode (SImode, DImode,
5843 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5844 gen_lowpart (SImode, operands[1]),
5846 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5847 gen_highpart_mode (SImode, DImode, operands[1]),
5854 [(set (match_operand:DI 0 "register_operand" "")
5855 (minus:DI (match_operand:DI 1 "register_operand" "")
5856 (match_operand:DI 2 "register_operand" "")))
5857 (clobber (reg:CC 100))]
5859 && reload_completed"
5860 [(clobber (const_int 0))]
5863 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5864 gen_lowpart (SImode, operands[1]),
5865 gen_lowpart (SImode, operands[2])));
5866 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5867 gen_highpart (SImode, operands[1]),
5868 gen_highpart (SImode, operands[2])));
5873 [(set (match_operand:DI 0 "register_operand" "=r")
5874 (minus:DI (match_operand:DI 1 "register_operand" "r")
5875 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5876 (clobber (reg:CC 100))]
5879 [(set_attr "length" "2")])
5882 [(set (match_operand:DI 0 "register_operand" "")
5883 (minus:DI (match_operand:DI 1 "register_operand" "")
5884 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5885 (clobber (reg:CC 100))]
5886 "! TARGET_ARCH64 && reload_completed"
5887 [(parallel [(set (reg:CC_NOOV 100)
5888 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5890 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5892 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5893 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5894 "operands[3] = gen_lowpart (SImode, operands[1]);
5895 operands[4] = gen_highpart (SImode, operands[1]);
5896 operands[5] = gen_lowpart (SImode, operands[0]);
5897 operands[6] = gen_highpart (SImode, operands[0]);")
5899 (define_insn "*subdi3_sp64"
5900 [(set (match_operand:DI 0 "register_operand" "=r")
5901 (minus:DI (match_operand:DI 1 "register_operand" "r")
5902 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5906 (define_expand "subsi3"
5907 [(set (match_operand:SI 0 "register_operand" "=r,d")
5908 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5909 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5913 if (arith_4096_operand(operands[2], SImode))
5915 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5916 gen_rtx_PLUS (SImode, operands[1],
5922 (define_insn "*subsi3"
5923 [(set (match_operand:SI 0 "register_operand" "=r,d")
5924 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5925 (match_operand:SI 2 "arith_operand" "rI,d")))]
5929 fpsub32s\\t%1, %2, %0"
5930 [(set_attr "type" "*,fp")])
5932 (define_insn "*cmp_minus_cc"
5933 [(set (reg:CC_NOOV 100)
5934 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5935 (match_operand:SI 1 "arith_operand" "rI"))
5938 "subcc\\t%r0, %1, %%g0"
5939 [(set_attr "type" "compare")])
5941 (define_insn "*cmp_minus_ccx"
5942 [(set (reg:CCX_NOOV 100)
5943 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5944 (match_operand:DI 1 "arith_double_operand" "rHI"))
5947 "subcc\\t%0, %1, %%g0"
5948 [(set_attr "type" "compare")])
5950 (define_insn "cmp_minus_cc_set"
5951 [(set (reg:CC_NOOV 100)
5952 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5953 (match_operand:SI 2 "arith_operand" "rI"))
5955 (set (match_operand:SI 0 "register_operand" "=r")
5956 (minus:SI (match_dup 1) (match_dup 2)))]
5958 "subcc\\t%r1, %2, %0"
5959 [(set_attr "type" "compare")])
5961 (define_insn "*cmp_minus_ccx_set"
5962 [(set (reg:CCX_NOOV 100)
5963 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5964 (match_operand:DI 2 "arith_double_operand" "rHI"))
5966 (set (match_operand:DI 0 "register_operand" "=r")
5967 (minus:DI (match_dup 1) (match_dup 2)))]
5969 "subcc\\t%1, %2, %0"
5970 [(set_attr "type" "compare")])
5972 ;; Integer Multiply/Divide.
5974 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5975 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5977 (define_insn "mulsi3"
5978 [(set (match_operand:SI 0 "register_operand" "=r")
5979 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5980 (match_operand:SI 2 "arith_operand" "rI")))]
5983 [(set_attr "type" "imul")])
5985 (define_expand "muldi3"
5986 [(set (match_operand:DI 0 "register_operand" "=r")
5987 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5988 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5989 "TARGET_ARCH64 || TARGET_V8PLUS"
5994 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5999 (define_insn "*muldi3_sp64"
6000 [(set (match_operand:DI 0 "register_operand" "=r")
6001 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6002 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6005 [(set_attr "type" "imul")])
6007 ;; V8plus wide multiply.
6009 (define_insn "muldi3_v8plus"
6010 [(set (match_operand:DI 0 "register_operand" "=r,h")
6011 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6012 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6013 (clobber (match_scratch:SI 3 "=&h,X"))
6014 (clobber (match_scratch:SI 4 "=&h,X"))]
6018 if (sparc_check_64 (operands[1], insn) <= 0)
6019 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6020 if (which_alternative == 1)
6021 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6022 if (GET_CODE (operands[2]) == CONST_INT)
6024 if (which_alternative == 1)
6025 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6027 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\";
6029 if (sparc_check_64 (operands[2], insn) <= 0)
6030 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6031 if (which_alternative == 1)
6032 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\";
6034 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\";
6036 [(set_attr "type" "multi")
6037 (set_attr "length" "9,8")])
6039 (define_insn "*cmp_mul_set"
6041 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6042 (match_operand:SI 2 "arith_operand" "rI"))
6044 (set (match_operand:SI 0 "register_operand" "=r")
6045 (mult:SI (match_dup 1) (match_dup 2)))]
6046 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6047 "smulcc\\t%1, %2, %0"
6048 [(set_attr "type" "imul")])
6050 (define_expand "mulsidi3"
6051 [(set (match_operand:DI 0 "register_operand" "")
6052 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6053 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6057 if (CONSTANT_P (operands[2]))
6060 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6063 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6069 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6074 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6075 ;; registers can hold 64 bit values in the V8plus environment.
6077 (define_insn "mulsidi3_v8plus"
6078 [(set (match_operand:DI 0 "register_operand" "=h,r")
6079 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6080 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6081 (clobber (match_scratch:SI 3 "=X,&h"))]
6084 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6085 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6086 [(set_attr "type" "multi")
6087 (set_attr "length" "2,3")])
6090 (define_insn "const_mulsidi3_v8plus"
6091 [(set (match_operand:DI 0 "register_operand" "=h,r")
6092 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6093 (match_operand:SI 2 "small_int" "I,I")))
6094 (clobber (match_scratch:SI 3 "=X,&h"))]
6097 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6098 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6099 [(set_attr "type" "multi")
6100 (set_attr "length" "2,3")])
6103 (define_insn "*mulsidi3_sp32"
6104 [(set (match_operand:DI 0 "register_operand" "=r")
6105 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6106 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6110 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6113 (if_then_else (eq_attr "isa" "sparclet")
6114 (const_string "imul") (const_string "multi")))
6115 (set (attr "length")
6116 (if_then_else (eq_attr "isa" "sparclet")
6117 (const_int 1) (const_int 2)))])
6119 (define_insn "*mulsidi3_sp64"
6120 [(set (match_operand:DI 0 "register_operand" "=r")
6121 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6122 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6123 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6125 [(set_attr "type" "imul")])
6127 ;; Extra pattern, because sign_extend of a constant isn't valid.
6130 (define_insn "const_mulsidi3_sp32"
6131 [(set (match_operand:DI 0 "register_operand" "=r")
6132 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6133 (match_operand:SI 2 "small_int" "I")))]
6137 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6140 (if_then_else (eq_attr "isa" "sparclet")
6141 (const_string "imul") (const_string "multi")))
6142 (set (attr "length")
6143 (if_then_else (eq_attr "isa" "sparclet")
6144 (const_int 1) (const_int 2)))])
6146 (define_insn "const_mulsidi3_sp64"
6147 [(set (match_operand:DI 0 "register_operand" "=r")
6148 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6149 (match_operand:SI 2 "small_int" "I")))]
6150 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6152 [(set_attr "type" "imul")])
6154 (define_expand "smulsi3_highpart"
6155 [(set (match_operand:SI 0 "register_operand" "")
6157 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6158 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6160 "TARGET_HARD_MUL && TARGET_ARCH32"
6163 if (CONSTANT_P (operands[2]))
6167 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6173 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6178 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6179 operands[2], GEN_INT (32)));
6185 (define_insn "smulsi3_highpart_v8plus"
6186 [(set (match_operand:SI 0 "register_operand" "=h,r")
6188 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6189 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6190 (match_operand:SI 3 "const_int_operand" "i,i"))))
6191 (clobber (match_scratch:SI 4 "=X,&h"))]
6194 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6195 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6196 [(set_attr "type" "multi")
6197 (set_attr "length" "2")])
6199 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6202 [(set (match_operand:SI 0 "register_operand" "=h,r")
6205 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6206 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6207 (match_operand:SI 3 "const_int_operand" "i,i"))
6209 (clobber (match_scratch:SI 4 "=X,&h"))]
6212 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6213 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6214 [(set_attr "type" "multi")
6215 (set_attr "length" "2")])
6218 (define_insn "const_smulsi3_highpart_v8plus"
6219 [(set (match_operand:SI 0 "register_operand" "=h,r")
6221 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6222 (match_operand 2 "small_int" "i,i"))
6223 (match_operand:SI 3 "const_int_operand" "i,i"))))
6224 (clobber (match_scratch:SI 4 "=X,&h"))]
6227 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6228 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6229 [(set_attr "type" "multi")
6230 (set_attr "length" "2")])
6233 (define_insn "*smulsi3_highpart_sp32"
6234 [(set (match_operand:SI 0 "register_operand" "=r")
6236 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6237 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6240 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6241 [(set_attr "type" "multi")
6242 (set_attr "length" "2")])
6245 (define_insn "const_smulsi3_highpart"
6246 [(set (match_operand:SI 0 "register_operand" "=r")
6248 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6249 (match_operand:SI 2 "register_operand" "r"))
6252 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6253 [(set_attr "type" "multi")
6254 (set_attr "length" "2")])
6256 (define_expand "umulsidi3"
6257 [(set (match_operand:DI 0 "register_operand" "")
6258 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6259 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6263 if (CONSTANT_P (operands[2]))
6266 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6269 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6275 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6281 (define_insn "umulsidi3_v8plus"
6282 [(set (match_operand:DI 0 "register_operand" "=h,r")
6283 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6284 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6285 (clobber (match_scratch:SI 3 "=X,&h"))]
6288 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6289 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6290 [(set_attr "type" "multi")
6291 (set_attr "length" "2,3")])
6294 (define_insn "*umulsidi3_sp32"
6295 [(set (match_operand:DI 0 "register_operand" "=r")
6296 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6297 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6301 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6304 (if_then_else (eq_attr "isa" "sparclet")
6305 (const_string "imul") (const_string "multi")))
6306 (set (attr "length")
6307 (if_then_else (eq_attr "isa" "sparclet")
6308 (const_int 1) (const_int 2)))])
6310 (define_insn "*umulsidi3_sp64"
6311 [(set (match_operand:DI 0 "register_operand" "=r")
6312 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6313 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6314 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6316 [(set_attr "type" "imul")])
6318 ;; Extra pattern, because sign_extend of a constant isn't valid.
6321 (define_insn "const_umulsidi3_sp32"
6322 [(set (match_operand:DI 0 "register_operand" "=r")
6323 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6324 (match_operand:SI 2 "uns_small_int" "")))]
6328 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6331 (if_then_else (eq_attr "isa" "sparclet")
6332 (const_string "imul") (const_string "multi")))
6333 (set (attr "length")
6334 (if_then_else (eq_attr "isa" "sparclet")
6335 (const_int 1) (const_int 2)))])
6337 (define_insn "const_umulsidi3_sp64"
6338 [(set (match_operand:DI 0 "register_operand" "=r")
6339 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6340 (match_operand:SI 2 "uns_small_int" "")))]
6341 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6343 [(set_attr "type" "imul")])
6346 (define_insn "const_umulsidi3_v8plus"
6347 [(set (match_operand:DI 0 "register_operand" "=h,r")
6348 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6349 (match_operand:SI 2 "uns_small_int" "")))
6350 (clobber (match_scratch:SI 3 "=X,h"))]
6353 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6354 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6355 [(set_attr "type" "multi")
6356 (set_attr "length" "2,3")])
6358 (define_expand "umulsi3_highpart"
6359 [(set (match_operand:SI 0 "register_operand" "")
6361 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6362 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6364 "TARGET_HARD_MUL && TARGET_ARCH32"
6367 if (CONSTANT_P (operands[2]))
6371 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6377 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6382 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6383 operands[2], GEN_INT (32)));
6389 (define_insn "umulsi3_highpart_v8plus"
6390 [(set (match_operand:SI 0 "register_operand" "=h,r")
6392 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6393 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6394 (match_operand:SI 3 "const_int_operand" "i,i"))))
6395 (clobber (match_scratch:SI 4 "=X,h"))]
6398 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6399 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6400 [(set_attr "type" "multi")
6401 (set_attr "length" "2")])
6404 (define_insn "const_umulsi3_highpart_v8plus"
6405 [(set (match_operand:SI 0 "register_operand" "=h,r")
6407 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6408 (match_operand:SI 2 "uns_small_int" ""))
6409 (match_operand:SI 3 "const_int_operand" "i,i"))))
6410 (clobber (match_scratch:SI 4 "=X,h"))]
6413 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6414 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6415 [(set_attr "type" "multi")
6416 (set_attr "length" "2")])
6419 (define_insn "*umulsi3_highpart_sp32"
6420 [(set (match_operand:SI 0 "register_operand" "=r")
6422 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6423 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6426 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6427 [(set_attr "type" "multi")
6428 (set_attr "length" "2")])
6431 (define_insn "const_umulsi3_highpart"
6432 [(set (match_operand:SI 0 "register_operand" "=r")
6434 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6435 (match_operand:SI 2 "uns_small_int" ""))
6438 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6439 [(set_attr "type" "multi")
6440 (set_attr "length" "2")])
6442 ;; The v8 architecture specifies that there must be 3 instructions between
6443 ;; a y register write and a use of it for correct results.
6445 (define_expand "divsi3"
6446 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6447 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6448 (match_operand:SI 2 "input_operand" "rI,m")))
6449 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6450 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6455 operands[3] = gen_reg_rtx(SImode);
6456 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6457 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6463 (define_insn "divsi3_sp32"
6464 [(set (match_operand:SI 0 "register_operand" "=r,r")
6465 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6466 (match_operand:SI 2 "input_operand" "rI,m")))
6467 (clobber (match_scratch:SI 3 "=&r,&r"))]
6468 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6472 if (which_alternative == 0)
6474 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6476 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6479 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6481 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\";
6483 [(set_attr "type" "multi")
6484 (set (attr "length")
6485 (if_then_else (eq_attr "isa" "v9")
6486 (const_int 4) (const_int 6)))])
6488 (define_insn "divsi3_sp64"
6489 [(set (match_operand:SI 0 "register_operand" "=r")
6490 (div:SI (match_operand:SI 1 "register_operand" "r")
6491 (match_operand:SI 2 "input_operand" "rI")))
6492 (use (match_operand:SI 3 "register_operand" "r"))]
6493 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6494 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6495 [(set_attr "type" "multi")
6496 (set_attr "length" "2")])
6498 (define_insn "divdi3"
6499 [(set (match_operand:DI 0 "register_operand" "=r")
6500 (div:DI (match_operand:DI 1 "register_operand" "r")
6501 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6503 "sdivx\\t%1, %2, %0"
6504 [(set_attr "type" "idiv")])
6506 (define_insn "*cmp_sdiv_cc_set"
6508 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6509 (match_operand:SI 2 "arith_operand" "rI"))
6511 (set (match_operand:SI 0 "register_operand" "=r")
6512 (div:SI (match_dup 1) (match_dup 2)))
6513 (clobber (match_scratch:SI 3 "=&r"))]
6514 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6518 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6520 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6522 [(set_attr "type" "multi")
6523 (set (attr "length")
6524 (if_then_else (eq_attr "isa" "v9")
6525 (const_int 3) (const_int 6)))])
6528 (define_expand "udivsi3"
6529 [(set (match_operand:SI 0 "register_operand" "")
6530 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6531 (match_operand:SI 2 "input_operand" "")))]
6532 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6535 (define_insn "udivsi3_sp32"
6536 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6537 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6538 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6540 || TARGET_DEPRECATED_V8_INSNS)
6544 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6545 switch (which_alternative)
6548 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6550 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6552 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6555 [(set_attr "type" "multi")
6556 (set_attr "length" "5")])
6558 (define_insn "udivsi3_sp64"
6559 [(set (match_operand:SI 0 "register_operand" "=r")
6560 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6561 (match_operand:SI 2 "input_operand" "rI")))]
6562 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6563 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6564 [(set_attr "type" "multi")
6565 (set_attr "length" "2")])
6567 (define_insn "udivdi3"
6568 [(set (match_operand:DI 0 "register_operand" "=r")
6569 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6570 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6572 "udivx\\t%1, %2, %0"
6573 [(set_attr "type" "idiv")])
6575 (define_insn "*cmp_udiv_cc_set"
6577 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6578 (match_operand:SI 2 "arith_operand" "rI"))
6580 (set (match_operand:SI 0 "register_operand" "=r")
6581 (udiv:SI (match_dup 1) (match_dup 2)))]
6583 || TARGET_DEPRECATED_V8_INSNS"
6587 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6589 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6591 [(set_attr "type" "multi")
6592 (set (attr "length")
6593 (if_then_else (eq_attr "isa" "v9")
6594 (const_int 2) (const_int 5)))])
6596 ; sparclet multiply/accumulate insns
6598 (define_insn "*smacsi"
6599 [(set (match_operand:SI 0 "register_operand" "=r")
6600 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6601 (match_operand:SI 2 "arith_operand" "rI"))
6602 (match_operand:SI 3 "register_operand" "0")))]
6605 [(set_attr "type" "imul")])
6607 (define_insn "*smacdi"
6608 [(set (match_operand:DI 0 "register_operand" "=r")
6609 (plus:DI (mult:DI (sign_extend:DI
6610 (match_operand:SI 1 "register_operand" "%r"))
6612 (match_operand:SI 2 "register_operand" "r")))
6613 (match_operand:DI 3 "register_operand" "0")))]
6615 "smacd\\t%1, %2, %L0"
6616 [(set_attr "type" "imul")])
6618 (define_insn "*umacdi"
6619 [(set (match_operand:DI 0 "register_operand" "=r")
6620 (plus:DI (mult:DI (zero_extend:DI
6621 (match_operand:SI 1 "register_operand" "%r"))
6623 (match_operand:SI 2 "register_operand" "r")))
6624 (match_operand:DI 3 "register_operand" "0")))]
6626 "umacd\\t%1, %2, %L0"
6627 [(set_attr "type" "imul")])
6629 ;;- Boolean instructions
6630 ;; We define DImode `and' so with DImode `not' we can get
6631 ;; DImode `andn'. Other combinations are possible.
6633 (define_expand "anddi3"
6634 [(set (match_operand:DI 0 "register_operand" "")
6635 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6636 (match_operand:DI 2 "arith_double_operand" "")))]
6640 (define_insn "*anddi3_sp32"
6641 [(set (match_operand:DI 0 "register_operand" "=r,b")
6642 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6643 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6648 [(set_attr "type" "*,fp")
6649 (set_attr "length" "2,*")
6650 (set_attr "fptype" "double")])
6652 (define_insn "*anddi3_sp64"
6653 [(set (match_operand:DI 0 "register_operand" "=r,b")
6654 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6655 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6660 [(set_attr "type" "*,fp")
6661 (set_attr "fptype" "double")])
6663 (define_insn "andsi3"
6664 [(set (match_operand:SI 0 "register_operand" "=r,d")
6665 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6666 (match_operand:SI 2 "arith_operand" "rI,d")))]
6671 [(set_attr "type" "*,fp")])
6674 [(set (match_operand:SI 0 "register_operand" "")
6675 (and:SI (match_operand:SI 1 "register_operand" "")
6676 (match_operand:SI 2 "" "")))
6677 (clobber (match_operand:SI 3 "register_operand" ""))]
6678 "GET_CODE (operands[2]) == CONST_INT
6679 && !SMALL_INT32 (operands[2])
6680 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6681 [(set (match_dup 3) (match_dup 4))
6682 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6685 operands[4] = GEN_INT (~INTVAL (operands[2]));
6688 ;; Split DImode logical operations requiring two instructions.
6690 [(set (match_operand:DI 0 "register_operand" "")
6691 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6692 [(match_operand:DI 2 "register_operand" "")
6693 (match_operand:DI 3 "arith_double_operand" "")]))]
6696 && ((GET_CODE (operands[0]) == REG
6697 && REGNO (operands[0]) < 32)
6698 || (GET_CODE (operands[0]) == SUBREG
6699 && GET_CODE (SUBREG_REG (operands[0])) == REG
6700 && REGNO (SUBREG_REG (operands[0])) < 32))"
6701 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6702 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6705 operands[4] = gen_highpart (SImode, operands[0]);
6706 operands[5] = gen_lowpart (SImode, operands[0]);
6707 operands[6] = gen_highpart (SImode, operands[2]);
6708 operands[7] = gen_lowpart (SImode, operands[2]);
6709 #if HOST_BITS_PER_WIDE_INT == 32
6710 if (GET_CODE (operands[3]) == CONST_INT)
6712 if (INTVAL (operands[3]) < 0)
6713 operands[8] = constm1_rtx;
6715 operands[8] = const0_rtx;
6719 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6720 operands[9] = gen_lowpart (SImode, operands[3]);
6723 (define_insn "*and_not_di_sp32"
6724 [(set (match_operand:DI 0 "register_operand" "=r,b")
6725 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6726 (match_operand:DI 2 "register_operand" "r,b")))]
6730 fandnot1\\t%1, %2, %0"
6731 [(set_attr "type" "*,fp")
6732 (set_attr "length" "2,*")
6733 (set_attr "fptype" "double")])
6736 [(set (match_operand:DI 0 "register_operand" "")
6737 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6738 (match_operand:DI 2 "register_operand" "")))]
6741 && ((GET_CODE (operands[0]) == REG
6742 && REGNO (operands[0]) < 32)
6743 || (GET_CODE (operands[0]) == SUBREG
6744 && GET_CODE (SUBREG_REG (operands[0])) == REG
6745 && REGNO (SUBREG_REG (operands[0])) < 32))"
6746 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6747 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6748 "operands[3] = gen_highpart (SImode, operands[0]);
6749 operands[4] = gen_highpart (SImode, operands[1]);
6750 operands[5] = gen_highpart (SImode, operands[2]);
6751 operands[6] = gen_lowpart (SImode, operands[0]);
6752 operands[7] = gen_lowpart (SImode, operands[1]);
6753 operands[8] = gen_lowpart (SImode, operands[2]);")
6755 (define_insn "*and_not_di_sp64"
6756 [(set (match_operand:DI 0 "register_operand" "=r,b")
6757 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6758 (match_operand:DI 2 "register_operand" "r,b")))]
6762 fandnot1\\t%1, %2, %0"
6763 [(set_attr "type" "*,fp")
6764 (set_attr "fptype" "double")])
6766 (define_insn "*and_not_si"
6767 [(set (match_operand:SI 0 "register_operand" "=r,d")
6768 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6769 (match_operand:SI 2 "register_operand" "r,d")))]
6773 fandnot1s\\t%1, %2, %0"
6774 [(set_attr "type" "*,fp")])
6776 (define_expand "iordi3"
6777 [(set (match_operand:DI 0 "register_operand" "")
6778 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6779 (match_operand:DI 2 "arith_double_operand" "")))]
6783 (define_insn "*iordi3_sp32"
6784 [(set (match_operand:DI 0 "register_operand" "=r,b")
6785 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6786 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6791 [(set_attr "type" "*,fp")
6792 (set_attr "length" "2,*")
6793 (set_attr "fptype" "double")])
6795 (define_insn "*iordi3_sp64"
6796 [(set (match_operand:DI 0 "register_operand" "=r,b")
6797 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6798 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6803 [(set_attr "type" "*,fp")
6804 (set_attr "fptype" "double")])
6806 (define_insn "iorsi3"
6807 [(set (match_operand:SI 0 "register_operand" "=r,d")
6808 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6809 (match_operand:SI 2 "arith_operand" "rI,d")))]
6814 [(set_attr "type" "*,fp")])
6817 [(set (match_operand:SI 0 "register_operand" "")
6818 (ior:SI (match_operand:SI 1 "register_operand" "")
6819 (match_operand:SI 2 "" "")))
6820 (clobber (match_operand:SI 3 "register_operand" ""))]
6821 "GET_CODE (operands[2]) == CONST_INT
6822 && !SMALL_INT32 (operands[2])
6823 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6824 [(set (match_dup 3) (match_dup 4))
6825 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6828 operands[4] = GEN_INT (~INTVAL (operands[2]));
6831 (define_insn "*or_not_di_sp32"
6832 [(set (match_operand:DI 0 "register_operand" "=r,b")
6833 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6834 (match_operand:DI 2 "register_operand" "r,b")))]
6838 fornot1\\t%1, %2, %0"
6839 [(set_attr "type" "*,fp")
6840 (set_attr "length" "2,*")
6841 (set_attr "fptype" "double")])
6844 [(set (match_operand:DI 0 "register_operand" "")
6845 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6846 (match_operand:DI 2 "register_operand" "")))]
6849 && ((GET_CODE (operands[0]) == REG
6850 && REGNO (operands[0]) < 32)
6851 || (GET_CODE (operands[0]) == SUBREG
6852 && GET_CODE (SUBREG_REG (operands[0])) == REG
6853 && REGNO (SUBREG_REG (operands[0])) < 32))"
6854 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6855 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6856 "operands[3] = gen_highpart (SImode, operands[0]);
6857 operands[4] = gen_highpart (SImode, operands[1]);
6858 operands[5] = gen_highpart (SImode, operands[2]);
6859 operands[6] = gen_lowpart (SImode, operands[0]);
6860 operands[7] = gen_lowpart (SImode, operands[1]);
6861 operands[8] = gen_lowpart (SImode, operands[2]);")
6863 (define_insn "*or_not_di_sp64"
6864 [(set (match_operand:DI 0 "register_operand" "=r,b")
6865 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6866 (match_operand:DI 2 "register_operand" "r,b")))]
6870 fornot1\\t%1, %2, %0"
6871 [(set_attr "type" "*,fp")
6872 (set_attr "fptype" "double")])
6874 (define_insn "*or_not_si"
6875 [(set (match_operand:SI 0 "register_operand" "=r,d")
6876 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6877 (match_operand:SI 2 "register_operand" "r,d")))]
6881 fornot1s\\t%1, %2, %0"
6882 [(set_attr "type" "*,fp")])
6884 (define_expand "xordi3"
6885 [(set (match_operand:DI 0 "register_operand" "")
6886 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6887 (match_operand:DI 2 "arith_double_operand" "")))]
6891 (define_insn "*xordi3_sp32"
6892 [(set (match_operand:DI 0 "register_operand" "=r,b")
6893 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6894 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6899 [(set_attr "type" "*,fp")
6900 (set_attr "length" "2,*")
6901 (set_attr "fptype" "double")])
6903 (define_insn "*xordi3_sp64"
6904 [(set (match_operand:DI 0 "register_operand" "=r,b")
6905 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6906 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6911 [(set_attr "type" "*,fp")
6912 (set_attr "fptype" "double")])
6914 (define_insn "*xordi3_sp64_dbl"
6915 [(set (match_operand:DI 0 "register_operand" "=r")
6916 (xor:DI (match_operand:DI 1 "register_operand" "r")
6917 (match_operand:DI 2 "const64_operand" "")))]
6919 && HOST_BITS_PER_WIDE_INT != 64)"
6922 (define_insn "xorsi3"
6923 [(set (match_operand:SI 0 "register_operand" "=r,d")
6924 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6925 (match_operand:SI 2 "arith_operand" "rI,d")))]
6930 [(set_attr "type" "*,fp")])
6933 [(set (match_operand:SI 0 "register_operand" "")
6934 (xor:SI (match_operand:SI 1 "register_operand" "")
6935 (match_operand:SI 2 "" "")))
6936 (clobber (match_operand:SI 3 "register_operand" ""))]
6937 "GET_CODE (operands[2]) == CONST_INT
6938 && !SMALL_INT32 (operands[2])
6939 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6940 [(set (match_dup 3) (match_dup 4))
6941 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6944 operands[4] = GEN_INT (~INTVAL (operands[2]));
6948 [(set (match_operand:SI 0 "register_operand" "")
6949 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6950 (match_operand:SI 2 "" ""))))
6951 (clobber (match_operand:SI 3 "register_operand" ""))]
6952 "GET_CODE (operands[2]) == CONST_INT
6953 && !SMALL_INT32 (operands[2])
6954 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6955 [(set (match_dup 3) (match_dup 4))
6956 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6959 operands[4] = GEN_INT (~INTVAL (operands[2]));
6962 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6963 ;; Combine now canonicalizes to the rightmost expression.
6964 (define_insn "*xor_not_di_sp32"
6965 [(set (match_operand:DI 0 "register_operand" "=r,b")
6966 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6967 (match_operand:DI 2 "register_operand" "r,b"))))]
6972 [(set_attr "type" "*,fp")
6973 (set_attr "length" "2,*")
6974 (set_attr "fptype" "double")])
6977 [(set (match_operand:DI 0 "register_operand" "")
6978 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6979 (match_operand:DI 2 "register_operand" ""))))]
6982 && ((GET_CODE (operands[0]) == REG
6983 && REGNO (operands[0]) < 32)
6984 || (GET_CODE (operands[0]) == SUBREG
6985 && GET_CODE (SUBREG_REG (operands[0])) == REG
6986 && REGNO (SUBREG_REG (operands[0])) < 32))"
6987 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6988 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6989 "operands[3] = gen_highpart (SImode, operands[0]);
6990 operands[4] = gen_highpart (SImode, operands[1]);
6991 operands[5] = gen_highpart (SImode, operands[2]);
6992 operands[6] = gen_lowpart (SImode, operands[0]);
6993 operands[7] = gen_lowpart (SImode, operands[1]);
6994 operands[8] = gen_lowpart (SImode, operands[2]);")
6996 (define_insn "*xor_not_di_sp64"
6997 [(set (match_operand:DI 0 "register_operand" "=r,b")
6998 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6999 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7004 [(set_attr "type" "*,fp")
7005 (set_attr "fptype" "double")])
7007 (define_insn "*xor_not_si"
7008 [(set (match_operand:SI 0 "register_operand" "=r,d")
7009 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7010 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7014 fxnors\\t%1, %2, %0"
7015 [(set_attr "type" "*,fp")])
7017 ;; These correspond to the above in the case where we also (or only)
7018 ;; want to set the condition code.
7020 (define_insn "*cmp_cc_arith_op"
7023 (match_operator:SI 2 "cc_arithop"
7024 [(match_operand:SI 0 "arith_operand" "%r")
7025 (match_operand:SI 1 "arith_operand" "rI")])
7028 "%A2cc\\t%0, %1, %%g0"
7029 [(set_attr "type" "compare")])
7031 (define_insn "*cmp_ccx_arith_op"
7034 (match_operator:DI 2 "cc_arithop"
7035 [(match_operand:DI 0 "arith_double_operand" "%r")
7036 (match_operand:DI 1 "arith_double_operand" "rHI")])
7039 "%A2cc\\t%0, %1, %%g0"
7040 [(set_attr "type" "compare")])
7042 (define_insn "*cmp_cc_arith_op_set"
7045 (match_operator:SI 3 "cc_arithop"
7046 [(match_operand:SI 1 "arith_operand" "%r")
7047 (match_operand:SI 2 "arith_operand" "rI")])
7049 (set (match_operand:SI 0 "register_operand" "=r")
7050 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7051 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7052 "%A3cc\\t%1, %2, %0"
7053 [(set_attr "type" "compare")])
7055 (define_insn "*cmp_ccx_arith_op_set"
7058 (match_operator:DI 3 "cc_arithop"
7059 [(match_operand:DI 1 "arith_double_operand" "%r")
7060 (match_operand:DI 2 "arith_double_operand" "rHI")])
7062 (set (match_operand:DI 0 "register_operand" "=r")
7063 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7064 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7065 "%A3cc\\t%1, %2, %0"
7066 [(set_attr "type" "compare")])
7068 (define_insn "*cmp_cc_xor_not"
7071 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7072 (match_operand:SI 1 "arith_operand" "rI")))
7075 "xnorcc\\t%r0, %1, %%g0"
7076 [(set_attr "type" "compare")])
7078 (define_insn "*cmp_ccx_xor_not"
7081 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7082 (match_operand:DI 1 "arith_double_operand" "rHI")))
7085 "xnorcc\\t%r0, %1, %%g0"
7086 [(set_attr "type" "compare")])
7088 (define_insn "*cmp_cc_xor_not_set"
7091 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7092 (match_operand:SI 2 "arith_operand" "rI")))
7094 (set (match_operand:SI 0 "register_operand" "=r")
7095 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7097 "xnorcc\\t%r1, %2, %0"
7098 [(set_attr "type" "compare")])
7100 (define_insn "*cmp_ccx_xor_not_set"
7103 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7104 (match_operand:DI 2 "arith_double_operand" "rHI")))
7106 (set (match_operand:DI 0 "register_operand" "=r")
7107 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7109 "xnorcc\\t%r1, %2, %0"
7110 [(set_attr "type" "compare")])
7112 (define_insn "*cmp_cc_arith_op_not"
7115 (match_operator:SI 2 "cc_arithopn"
7116 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7117 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7120 "%B2cc\\t%r1, %0, %%g0"
7121 [(set_attr "type" "compare")])
7123 (define_insn "*cmp_ccx_arith_op_not"
7126 (match_operator:DI 2 "cc_arithopn"
7127 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7128 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7131 "%B2cc\\t%r1, %0, %%g0"
7132 [(set_attr "type" "compare")])
7134 (define_insn "*cmp_cc_arith_op_not_set"
7137 (match_operator:SI 3 "cc_arithopn"
7138 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7139 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7141 (set (match_operand:SI 0 "register_operand" "=r")
7142 (match_operator:SI 4 "cc_arithopn"
7143 [(not:SI (match_dup 1)) (match_dup 2)]))]
7144 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7145 "%B3cc\\t%r2, %1, %0"
7146 [(set_attr "type" "compare")])
7148 (define_insn "*cmp_ccx_arith_op_not_set"
7151 (match_operator:DI 3 "cc_arithopn"
7152 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7153 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7155 (set (match_operand:DI 0 "register_operand" "=r")
7156 (match_operator:DI 4 "cc_arithopn"
7157 [(not:DI (match_dup 1)) (match_dup 2)]))]
7158 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7159 "%B3cc\\t%r2, %1, %0"
7160 [(set_attr "type" "compare")])
7162 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7163 ;; does not know how to make it work for constants.
7165 (define_expand "negdi2"
7166 [(set (match_operand:DI 0 "register_operand" "=r")
7167 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7171 if (! TARGET_ARCH64)
7173 emit_insn (gen_rtx_PARALLEL
7176 gen_rtx_SET (VOIDmode, operand0,
7177 gen_rtx_NEG (DImode, operand1)),
7178 gen_rtx_CLOBBER (VOIDmode,
7179 gen_rtx_REG (CCmode,
7185 (define_insn "*negdi2_sp32"
7186 [(set (match_operand:DI 0 "register_operand" "=r")
7187 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7188 (clobber (reg:CC 100))]
7191 [(set_attr "length" "2")])
7194 [(set (match_operand:DI 0 "register_operand" "")
7195 (neg:DI (match_operand:DI 1 "register_operand" "")))
7196 (clobber (reg:CC 100))]
7198 && reload_completed"
7199 [(parallel [(set (reg:CC_NOOV 100)
7200 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7202 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7203 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7204 (ltu:SI (reg:CC 100) (const_int 0))))]
7205 "operands[2] = gen_highpart (SImode, operands[0]);
7206 operands[3] = gen_highpart (SImode, operands[1]);
7207 operands[4] = gen_lowpart (SImode, operands[0]);
7208 operands[5] = gen_lowpart (SImode, operands[1]);")
7210 (define_insn "*negdi2_sp64"
7211 [(set (match_operand:DI 0 "register_operand" "=r")
7212 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7214 "sub\\t%%g0, %1, %0")
7216 (define_insn "negsi2"
7217 [(set (match_operand:SI 0 "register_operand" "=r")
7218 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7220 "sub\\t%%g0, %1, %0")
7222 (define_insn "*cmp_cc_neg"
7223 [(set (reg:CC_NOOV 100)
7224 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7227 "subcc\\t%%g0, %0, %%g0"
7228 [(set_attr "type" "compare")])
7230 (define_insn "*cmp_ccx_neg"
7231 [(set (reg:CCX_NOOV 100)
7232 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7235 "subcc\\t%%g0, %0, %%g0"
7236 [(set_attr "type" "compare")])
7238 (define_insn "*cmp_cc_set_neg"
7239 [(set (reg:CC_NOOV 100)
7240 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7242 (set (match_operand:SI 0 "register_operand" "=r")
7243 (neg:SI (match_dup 1)))]
7245 "subcc\\t%%g0, %1, %0"
7246 [(set_attr "type" "compare")])
7248 (define_insn "*cmp_ccx_set_neg"
7249 [(set (reg:CCX_NOOV 100)
7250 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7252 (set (match_operand:DI 0 "register_operand" "=r")
7253 (neg:DI (match_dup 1)))]
7255 "subcc\\t%%g0, %1, %0"
7256 [(set_attr "type" "compare")])
7258 ;; We cannot use the "not" pseudo insn because the Sun assembler
7259 ;; does not know how to make it work for constants.
7260 (define_expand "one_cmpldi2"
7261 [(set (match_operand:DI 0 "register_operand" "")
7262 (not:DI (match_operand:DI 1 "register_operand" "")))]
7266 (define_insn "*one_cmpldi2_sp32"
7267 [(set (match_operand:DI 0 "register_operand" "=r,b")
7268 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7273 [(set_attr "type" "*,fp")
7274 (set_attr "length" "2,*")
7275 (set_attr "fptype" "double")])
7278 [(set (match_operand:DI 0 "register_operand" "")
7279 (not:DI (match_operand:DI 1 "register_operand" "")))]
7282 && ((GET_CODE (operands[0]) == REG
7283 && REGNO (operands[0]) < 32)
7284 || (GET_CODE (operands[0]) == SUBREG
7285 && GET_CODE (SUBREG_REG (operands[0])) == REG
7286 && REGNO (SUBREG_REG (operands[0])) < 32))"
7287 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7288 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7289 "operands[2] = gen_highpart (SImode, operands[0]);
7290 operands[3] = gen_highpart (SImode, operands[1]);
7291 operands[4] = gen_lowpart (SImode, operands[0]);
7292 operands[5] = gen_lowpart (SImode, operands[1]);")
7294 (define_insn "*one_cmpldi2_sp64"
7295 [(set (match_operand:DI 0 "register_operand" "=r,b")
7296 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7301 [(set_attr "type" "*,fp")
7302 (set_attr "fptype" "double")])
7304 (define_insn "one_cmplsi2"
7305 [(set (match_operand:SI 0 "register_operand" "=r,d")
7306 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7311 [(set_attr "type" "*,fp")])
7313 (define_insn "*cmp_cc_not"
7315 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7318 "xnorcc\\t%%g0, %0, %%g0"
7319 [(set_attr "type" "compare")])
7321 (define_insn "*cmp_ccx_not"
7323 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7326 "xnorcc\\t%%g0, %0, %%g0"
7327 [(set_attr "type" "compare")])
7329 (define_insn "*cmp_cc_set_not"
7331 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7333 (set (match_operand:SI 0 "register_operand" "=r")
7334 (not:SI (match_dup 1)))]
7336 "xnorcc\\t%%g0, %1, %0"
7337 [(set_attr "type" "compare")])
7339 (define_insn "*cmp_ccx_set_not"
7341 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7343 (set (match_operand:DI 0 "register_operand" "=r")
7344 (not:DI (match_dup 1)))]
7346 "xnorcc\\t%%g0, %1, %0"
7347 [(set_attr "type" "compare")])
7349 (define_insn "*cmp_cc_set"
7350 [(set (match_operand:SI 0 "register_operand" "=r")
7351 (match_operand:SI 1 "register_operand" "r"))
7353 (compare:CC (match_dup 1)
7357 [(set_attr "type" "compare")])
7359 (define_insn "*cmp_ccx_set64"
7360 [(set (match_operand:DI 0 "register_operand" "=r")
7361 (match_operand:DI 1 "register_operand" "r"))
7363 (compare:CCX (match_dup 1)
7367 [(set_attr "type" "compare")])
7369 ;; Floating point arithmetic instructions.
7371 (define_expand "addtf3"
7372 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7373 (plus:TF (match_operand:TF 1 "general_operand" "")
7374 (match_operand:TF 2 "general_operand" "")))]
7375 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7378 if (! TARGET_HARD_QUAD)
7380 rtx slot0, slot1, slot2;
7382 if (GET_CODE (operands[0]) != MEM)
7383 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7385 slot0 = operands[0];
7386 if (GET_CODE (operands[1]) != MEM)
7388 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7389 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7392 slot1 = operands[1];
7393 if (GET_CODE (operands[2]) != MEM)
7395 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7396 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7399 slot2 = operands[2];
7401 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7403 XEXP (slot0, 0), Pmode,
7404 XEXP (slot1, 0), Pmode,
7405 XEXP (slot2, 0), Pmode);
7407 if (GET_CODE (operands[0]) != MEM)
7408 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7413 (define_insn "*addtf3_hq"
7414 [(set (match_operand:TF 0 "register_operand" "=e")
7415 (plus:TF (match_operand:TF 1 "register_operand" "e")
7416 (match_operand:TF 2 "register_operand" "e")))]
7417 "TARGET_FPU && TARGET_HARD_QUAD"
7418 "faddq\\t%1, %2, %0"
7419 [(set_attr "type" "fp")])
7421 (define_insn "adddf3"
7422 [(set (match_operand:DF 0 "register_operand" "=e")
7423 (plus:DF (match_operand:DF 1 "register_operand" "e")
7424 (match_operand:DF 2 "register_operand" "e")))]
7426 "faddd\\t%1, %2, %0"
7427 [(set_attr "type" "fp")
7428 (set_attr "fptype" "double")])
7430 (define_insn "addsf3"
7431 [(set (match_operand:SF 0 "register_operand" "=f")
7432 (plus:SF (match_operand:SF 1 "register_operand" "f")
7433 (match_operand:SF 2 "register_operand" "f")))]
7435 "fadds\\t%1, %2, %0"
7436 [(set_attr "type" "fp")])
7438 (define_expand "subtf3"
7439 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7440 (minus:TF (match_operand:TF 1 "general_operand" "")
7441 (match_operand:TF 2 "general_operand" "")))]
7442 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7445 if (! TARGET_HARD_QUAD)
7447 rtx slot0, slot1, slot2;
7449 if (GET_CODE (operands[0]) != MEM)
7450 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7452 slot0 = operands[0];
7453 if (GET_CODE (operands[1]) != MEM)
7455 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7456 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7459 slot1 = operands[1];
7460 if (GET_CODE (operands[2]) != MEM)
7462 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7463 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7466 slot2 = operands[2];
7468 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7470 XEXP (slot0, 0), Pmode,
7471 XEXP (slot1, 0), Pmode,
7472 XEXP (slot2, 0), Pmode);
7474 if (GET_CODE (operands[0]) != MEM)
7475 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7480 (define_insn "*subtf3_hq"
7481 [(set (match_operand:TF 0 "register_operand" "=e")
7482 (minus:TF (match_operand:TF 1 "register_operand" "e")
7483 (match_operand:TF 2 "register_operand" "e")))]
7484 "TARGET_FPU && TARGET_HARD_QUAD"
7485 "fsubq\\t%1, %2, %0"
7486 [(set_attr "type" "fp")])
7488 (define_insn "subdf3"
7489 [(set (match_operand:DF 0 "register_operand" "=e")
7490 (minus:DF (match_operand:DF 1 "register_operand" "e")
7491 (match_operand:DF 2 "register_operand" "e")))]
7493 "fsubd\\t%1, %2, %0"
7494 [(set_attr "type" "fp")
7495 (set_attr "fptype" "double")])
7497 (define_insn "subsf3"
7498 [(set (match_operand:SF 0 "register_operand" "=f")
7499 (minus:SF (match_operand:SF 1 "register_operand" "f")
7500 (match_operand:SF 2 "register_operand" "f")))]
7502 "fsubs\\t%1, %2, %0"
7503 [(set_attr "type" "fp")])
7505 (define_expand "multf3"
7506 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7507 (mult:TF (match_operand:TF 1 "general_operand" "")
7508 (match_operand:TF 2 "general_operand" "")))]
7509 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7512 if (! TARGET_HARD_QUAD)
7514 rtx slot0, slot1, slot2;
7516 if (GET_CODE (operands[0]) != MEM)
7517 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7519 slot0 = operands[0];
7520 if (GET_CODE (operands[1]) != MEM)
7522 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7523 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7526 slot1 = operands[1];
7527 if (GET_CODE (operands[2]) != MEM)
7529 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7530 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7533 slot2 = operands[2];
7535 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7537 XEXP (slot0, 0), Pmode,
7538 XEXP (slot1, 0), Pmode,
7539 XEXP (slot2, 0), Pmode);
7541 if (GET_CODE (operands[0]) != MEM)
7542 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7547 (define_insn "*multf3_hq"
7548 [(set (match_operand:TF 0 "register_operand" "=e")
7549 (mult:TF (match_operand:TF 1 "register_operand" "e")
7550 (match_operand:TF 2 "register_operand" "e")))]
7551 "TARGET_FPU && TARGET_HARD_QUAD"
7552 "fmulq\\t%1, %2, %0"
7553 [(set_attr "type" "fpmul")])
7555 (define_insn "muldf3"
7556 [(set (match_operand:DF 0 "register_operand" "=e")
7557 (mult:DF (match_operand:DF 1 "register_operand" "e")
7558 (match_operand:DF 2 "register_operand" "e")))]
7560 "fmuld\\t%1, %2, %0"
7561 [(set_attr "type" "fpmul")
7562 (set_attr "fptype" "double")])
7564 (define_insn "mulsf3"
7565 [(set (match_operand:SF 0 "register_operand" "=f")
7566 (mult:SF (match_operand:SF 1 "register_operand" "f")
7567 (match_operand:SF 2 "register_operand" "f")))]
7569 "fmuls\\t%1, %2, %0"
7570 [(set_attr "type" "fpmul")])
7572 (define_insn "*muldf3_extend"
7573 [(set (match_operand:DF 0 "register_operand" "=e")
7574 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7575 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7576 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7577 "fsmuld\\t%1, %2, %0"
7578 [(set_attr "type" "fpmul")
7579 (set_attr "fptype" "double")])
7581 (define_insn "*multf3_extend"
7582 [(set (match_operand:TF 0 "register_operand" "=e")
7583 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7584 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7585 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7586 "fdmulq\\t%1, %2, %0"
7587 [(set_attr "type" "fpmul")])
7589 (define_expand "divtf3"
7590 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7591 (div:TF (match_operand:TF 1 "general_operand" "")
7592 (match_operand:TF 2 "general_operand" "")))]
7593 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7596 if (! TARGET_HARD_QUAD)
7598 rtx slot0, slot1, slot2;
7600 if (GET_CODE (operands[0]) != MEM)
7601 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7603 slot0 = operands[0];
7604 if (GET_CODE (operands[1]) != MEM)
7606 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7607 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7610 slot1 = operands[1];
7611 if (GET_CODE (operands[2]) != MEM)
7613 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7614 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7617 slot2 = operands[2];
7619 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7621 XEXP (slot0, 0), Pmode,
7622 XEXP (slot1, 0), Pmode,
7623 XEXP (slot2, 0), Pmode);
7625 if (GET_CODE (operands[0]) != MEM)
7626 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7631 ;; don't have timing for quad-prec. divide.
7632 (define_insn "*divtf3_hq"
7633 [(set (match_operand:TF 0 "register_operand" "=e")
7634 (div:TF (match_operand:TF 1 "register_operand" "e")
7635 (match_operand:TF 2 "register_operand" "e")))]
7636 "TARGET_FPU && TARGET_HARD_QUAD"
7637 "fdivq\\t%1, %2, %0"
7638 [(set_attr "type" "fpdivd")])
7640 (define_insn "divdf3"
7641 [(set (match_operand:DF 0 "register_operand" "=e")
7642 (div:DF (match_operand:DF 1 "register_operand" "e")
7643 (match_operand:DF 2 "register_operand" "e")))]
7645 "fdivd\\t%1, %2, %0"
7646 [(set_attr "type" "fpdivd")
7647 (set_attr "fptype" "double")])
7649 (define_insn "divsf3"
7650 [(set (match_operand:SF 0 "register_operand" "=f")
7651 (div:SF (match_operand:SF 1 "register_operand" "f")
7652 (match_operand:SF 2 "register_operand" "f")))]
7654 "fdivs\\t%1, %2, %0"
7655 [(set_attr "type" "fpdivs")])
7657 (define_expand "negtf2"
7658 [(set (match_operand:TF 0 "register_operand" "=e,e")
7659 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7663 (define_insn "*negtf2_notv9"
7664 [(set (match_operand:TF 0 "register_operand" "=e,e")
7665 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7666 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7672 [(set_attr "type" "fpmove,*")
7673 (set_attr "length" "*,2")])
7676 [(set (match_operand:TF 0 "register_operand" "")
7677 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7681 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7682 [(set (match_dup 2) (neg:SF (match_dup 3)))
7683 (set (match_dup 4) (match_dup 5))
7684 (set (match_dup 6) (match_dup 7))]
7685 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7686 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7687 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7688 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7689 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7690 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7692 (define_insn "*negtf2_v9"
7693 [(set (match_operand:TF 0 "register_operand" "=e,e")
7694 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7695 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7696 "TARGET_FPU && TARGET_V9"
7700 [(set_attr "type" "fpmove,*")
7701 (set_attr "length" "*,2")
7702 (set_attr "fptype" "double")])
7705 [(set (match_operand:TF 0 "register_operand" "")
7706 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7710 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7711 [(set (match_dup 2) (neg:DF (match_dup 3)))
7712 (set (match_dup 4) (match_dup 5))]
7713 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7714 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7715 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7716 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7718 (define_expand "negdf2"
7719 [(set (match_operand:DF 0 "register_operand" "")
7720 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7724 (define_insn "*negdf2_notv9"
7725 [(set (match_operand:DF 0 "register_operand" "=e,e")
7726 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7727 "TARGET_FPU && ! TARGET_V9"
7731 [(set_attr "type" "fpmove,*")
7732 (set_attr "length" "*,2")])
7735 [(set (match_operand:DF 0 "register_operand" "")
7736 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7740 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7741 [(set (match_dup 2) (neg:SF (match_dup 3)))
7742 (set (match_dup 4) (match_dup 5))]
7743 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7744 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7745 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7746 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7748 (define_insn "*negdf2_v9"
7749 [(set (match_operand:DF 0 "register_operand" "=e")
7750 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7751 "TARGET_FPU && TARGET_V9"
7753 [(set_attr "type" "fpmove")
7754 (set_attr "fptype" "double")])
7756 (define_insn "negsf2"
7757 [(set (match_operand:SF 0 "register_operand" "=f")
7758 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7761 [(set_attr "type" "fpmove")])
7763 (define_expand "abstf2"
7764 [(set (match_operand:TF 0 "register_operand" "")
7765 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7769 (define_insn "*abstf2_notv9"
7770 [(set (match_operand:TF 0 "register_operand" "=e,e")
7771 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7772 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7773 "TARGET_FPU && ! TARGET_V9"
7777 [(set_attr "type" "fpmove,*")
7778 (set_attr "length" "*,2")])
7781 [(set (match_operand:TF 0 "register_operand" "")
7782 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7786 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7787 [(set (match_dup 2) (abs:SF (match_dup 3)))
7788 (set (match_dup 4) (match_dup 5))
7789 (set (match_dup 6) (match_dup 7))]
7790 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7791 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7792 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7793 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7794 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7795 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7797 (define_insn "*abstf2_hq_v9"
7798 [(set (match_operand:TF 0 "register_operand" "=e,e")
7799 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7800 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7804 [(set_attr "type" "fpmove")
7805 (set_attr "fptype" "double,*")])
7807 (define_insn "*abstf2_v9"
7808 [(set (match_operand:TF 0 "register_operand" "=e,e")
7809 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7810 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7814 [(set_attr "type" "fpmove,*")
7815 (set_attr "length" "*,2")
7816 (set_attr "fptype" "double,*")])
7819 [(set (match_operand:TF 0 "register_operand" "")
7820 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7824 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7825 [(set (match_dup 2) (abs:DF (match_dup 3)))
7826 (set (match_dup 4) (match_dup 5))]
7827 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7828 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7829 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7830 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7832 (define_expand "absdf2"
7833 [(set (match_operand:DF 0 "register_operand" "")
7834 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7838 (define_insn "*absdf2_notv9"
7839 [(set (match_operand:DF 0 "register_operand" "=e,e")
7840 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7841 "TARGET_FPU && ! TARGET_V9"
7845 [(set_attr "type" "fpmove,*")
7846 (set_attr "length" "*,2")])
7849 [(set (match_operand:DF 0 "register_operand" "")
7850 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7854 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7855 [(set (match_dup 2) (abs:SF (match_dup 3)))
7856 (set (match_dup 4) (match_dup 5))]
7857 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7858 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7859 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7860 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7862 (define_insn "*absdf2_v9"
7863 [(set (match_operand:DF 0 "register_operand" "=e")
7864 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7865 "TARGET_FPU && TARGET_V9"
7867 [(set_attr "type" "fpmove")
7868 (set_attr "fptype" "double")])
7870 (define_insn "abssf2"
7871 [(set (match_operand:SF 0 "register_operand" "=f")
7872 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7875 [(set_attr "type" "fpmove")])
7877 (define_expand "sqrttf2"
7878 [(set (match_operand:TF 0 "register_operand" "=e")
7879 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7880 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7883 if (! TARGET_HARD_QUAD)
7887 if (GET_CODE (operands[0]) != MEM)
7888 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7890 slot0 = operands[0];
7891 if (GET_CODE (operands[1]) != MEM)
7893 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7894 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7897 slot1 = operands[1];
7899 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7901 XEXP (slot0, 0), Pmode,
7902 XEXP (slot1, 0), Pmode);
7904 if (GET_CODE (operands[0]) != MEM)
7905 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7910 (define_insn "*sqrttf2_hq"
7911 [(set (match_operand:TF 0 "register_operand" "=e")
7912 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7913 "TARGET_FPU && TARGET_HARD_QUAD"
7915 [(set_attr "type" "fpsqrtd")])
7917 (define_insn "sqrtdf2"
7918 [(set (match_operand:DF 0 "register_operand" "=e")
7919 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7922 [(set_attr "type" "fpsqrtd")
7923 (set_attr "fptype" "double")])
7925 (define_insn "sqrtsf2"
7926 [(set (match_operand:SF 0 "register_operand" "=f")
7927 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7930 [(set_attr "type" "fpsqrts")])
7932 ;;- arithmetic shift instructions
7934 (define_insn "ashlsi3"
7935 [(set (match_operand:SI 0 "register_operand" "=r")
7936 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7937 (match_operand:SI 2 "arith_operand" "rI")))]
7941 if (GET_CODE (operands[2]) == CONST_INT
7942 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7943 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7945 return \"sll\\t%1, %2, %0\";
7947 [(set_attr "type" "shift")])
7949 ;; We special case multiplication by two, as add can be done
7950 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7951 (define_insn "*ashlsi3_const1"
7952 [(set (match_operand:SI 0 "register_operand" "=r")
7953 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7958 (define_expand "ashldi3"
7959 [(set (match_operand:DI 0 "register_operand" "=r")
7960 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7961 (match_operand:SI 2 "arith_operand" "rI")))]
7962 "TARGET_ARCH64 || TARGET_V8PLUS"
7965 if (! TARGET_ARCH64)
7967 if (GET_CODE (operands[2]) == CONST_INT)
7969 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7974 ;; We special case multiplication by two, as add can be done
7975 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7976 (define_insn "*ashldi3_const1"
7977 [(set (match_operand:DI 0 "register_operand" "=r")
7978 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7983 (define_insn "*ashldi3_sp64"
7984 [(set (match_operand:DI 0 "register_operand" "=r")
7985 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7986 (match_operand:SI 2 "arith_operand" "rI")))]
7990 if (GET_CODE (operands[2]) == CONST_INT
7991 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7992 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7994 return \"sllx\\t%1, %2, %0\";
7996 [(set_attr "type" "shift")])
7999 (define_insn "ashldi3_v8plus"
8000 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8001 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8002 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8003 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8005 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8006 [(set_attr "type" "multi")
8007 (set_attr "length" "5,5,6")])
8009 ;; Optimize (1LL<<x)-1
8010 ;; XXX this also needs to be fixed to handle equal subregs
8011 ;; XXX first before we could re-enable it.
8013 ; [(set (match_operand:DI 0 "register_operand" "=h")
8014 ; (plus:DI (ashift:DI (const_int 1)
8015 ; (match_operand:SI 1 "arith_operand" "rI"))
8017 ; "0 && TARGET_V8PLUS"
8020 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8021 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8022 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8024 ; [(set_attr "type" "multi")
8025 ; (set_attr "length" "4")])
8027 (define_insn "*cmp_cc_ashift_1"
8028 [(set (reg:CC_NOOV 100)
8029 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8033 "addcc\\t%0, %0, %%g0"
8034 [(set_attr "type" "compare")])
8036 (define_insn "*cmp_cc_set_ashift_1"
8037 [(set (reg:CC_NOOV 100)
8038 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8041 (set (match_operand:SI 0 "register_operand" "=r")
8042 (ashift:SI (match_dup 1) (const_int 1)))]
8044 "addcc\\t%1, %1, %0"
8045 [(set_attr "type" "compare")])
8047 (define_insn "ashrsi3"
8048 [(set (match_operand:SI 0 "register_operand" "=r")
8049 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8050 (match_operand:SI 2 "arith_operand" "rI")))]
8054 if (GET_CODE (operands[2]) == CONST_INT
8055 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8056 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8058 return \"sra\\t%1, %2, %0\";
8060 [(set_attr "type" "shift")])
8062 (define_insn "*ashrsi3_extend"
8063 [(set (match_operand:DI 0 "register_operand" "=r")
8064 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8065 (match_operand:SI 2 "arith_operand" "r"))))]
8068 [(set_attr "type" "shift")])
8070 ;; This handles the case as above, but with constant shift instead of
8071 ;; register. Combiner "simplifies" it for us a little bit though.
8072 (define_insn "*ashrsi3_extend2"
8073 [(set (match_operand:DI 0 "register_operand" "=r")
8074 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8076 (match_operand:SI 2 "small_int_or_double" "n")))]
8078 && ((GET_CODE (operands[2]) == CONST_INT
8079 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8080 || (GET_CODE (operands[2]) == CONST_DOUBLE
8081 && !CONST_DOUBLE_HIGH (operands[2])
8082 && CONST_DOUBLE_LOW (operands[2]) >= 32
8083 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8086 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8088 return \"sra\\t%1, %2, %0\";
8090 [(set_attr "type" "shift")])
8092 (define_expand "ashrdi3"
8093 [(set (match_operand:DI 0 "register_operand" "=r")
8094 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8095 (match_operand:SI 2 "arith_operand" "rI")))]
8096 "TARGET_ARCH64 || TARGET_V8PLUS"
8099 if (! TARGET_ARCH64)
8101 if (GET_CODE (operands[2]) == CONST_INT)
8102 FAIL; /* prefer generic code in this case */
8103 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8109 [(set (match_operand:DI 0 "register_operand" "=r")
8110 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8111 (match_operand:SI 2 "arith_operand" "rI")))]
8115 if (GET_CODE (operands[2]) == CONST_INT
8116 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8117 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8119 return \"srax\\t%1, %2, %0\";
8121 [(set_attr "type" "shift")])
8124 (define_insn "ashrdi3_v8plus"
8125 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8126 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8127 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8128 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8130 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8131 [(set_attr "type" "multi")
8132 (set_attr "length" "5,5,6")])
8134 (define_insn "lshrsi3"
8135 [(set (match_operand:SI 0 "register_operand" "=r")
8136 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8137 (match_operand:SI 2 "arith_operand" "rI")))]
8141 if (GET_CODE (operands[2]) == CONST_INT
8142 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8143 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8145 return \"srl\\t%1, %2, %0\";
8147 [(set_attr "type" "shift")])
8149 ;; This handles the case where
8150 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8151 ;; but combiner "simplifies" it for us.
8152 (define_insn "*lshrsi3_extend"
8153 [(set (match_operand:DI 0 "register_operand" "=r")
8154 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8155 (match_operand:SI 2 "arith_operand" "r")) 0)
8156 (match_operand 3 "" "")))]
8158 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8159 && CONST_DOUBLE_HIGH (operands[3]) == 0
8160 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8161 || (HOST_BITS_PER_WIDE_INT >= 64
8162 && GET_CODE (operands[3]) == CONST_INT
8163 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8165 [(set_attr "type" "shift")])
8167 ;; This handles the case where
8168 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8169 ;; but combiner "simplifies" it for us.
8170 (define_insn "*lshrsi3_extend2"
8171 [(set (match_operand:DI 0 "register_operand" "=r")
8172 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8173 (match_operand 2 "small_int_or_double" "n")
8176 && ((GET_CODE (operands[2]) == CONST_INT
8177 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8178 || (GET_CODE (operands[2]) == CONST_DOUBLE
8179 && CONST_DOUBLE_HIGH (operands[2]) == 0
8180 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8183 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8185 return \"srl\\t%1, %2, %0\";
8187 [(set_attr "type" "shift")])
8189 (define_expand "lshrdi3"
8190 [(set (match_operand:DI 0 "register_operand" "=r")
8191 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8192 (match_operand:SI 2 "arith_operand" "rI")))]
8193 "TARGET_ARCH64 || TARGET_V8PLUS"
8196 if (! TARGET_ARCH64)
8198 if (GET_CODE (operands[2]) == CONST_INT)
8200 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8206 [(set (match_operand:DI 0 "register_operand" "=r")
8207 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8208 (match_operand:SI 2 "arith_operand" "rI")))]
8212 if (GET_CODE (operands[2]) == CONST_INT
8213 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8214 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8216 return \"srlx\\t%1, %2, %0\";
8218 [(set_attr "type" "shift")])
8221 (define_insn "lshrdi3_v8plus"
8222 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8223 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8224 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8225 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8227 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8228 [(set_attr "type" "multi")
8229 (set_attr "length" "5,5,6")])
8232 [(set (match_operand:SI 0 "register_operand" "=r")
8233 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8235 (match_operand:SI 2 "small_int_or_double" "n")))]
8237 && ((GET_CODE (operands[2]) == CONST_INT
8238 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8239 || (GET_CODE (operands[2]) == CONST_DOUBLE
8240 && !CONST_DOUBLE_HIGH (operands[2])
8241 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8244 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8246 return \"srax\\t%1, %2, %0\";
8248 [(set_attr "type" "shift")])
8251 [(set (match_operand:SI 0 "register_operand" "=r")
8252 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8254 (match_operand:SI 2 "small_int_or_double" "n")))]
8256 && ((GET_CODE (operands[2]) == CONST_INT
8257 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8258 || (GET_CODE (operands[2]) == CONST_DOUBLE
8259 && !CONST_DOUBLE_HIGH (operands[2])
8260 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8263 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8265 return \"srlx\\t%1, %2, %0\";
8267 [(set_attr "type" "shift")])
8270 [(set (match_operand:SI 0 "register_operand" "=r")
8271 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8272 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8273 (match_operand:SI 3 "small_int_or_double" "n")))]
8275 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8276 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8277 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8278 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8281 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8283 return \"srax\\t%1, %2, %0\";
8285 [(set_attr "type" "shift")])
8288 [(set (match_operand:SI 0 "register_operand" "=r")
8289 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8290 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8291 (match_operand:SI 3 "small_int_or_double" "n")))]
8293 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8294 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8295 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8296 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8299 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8301 return \"srlx\\t%1, %2, %0\";
8303 [(set_attr "type" "shift")])
8305 ;; Unconditional and other jump instructions
8306 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8307 ;; following insn is never executed. This saves us a nop. Dbx does not
8308 ;; handle such branches though, so we only use them when optimizing.
8310 [(set (pc) (label_ref (match_operand 0 "" "")))]
8314 /* TurboSparc is reported to have problems with
8317 i.e. an empty loop with the annul bit set. The workaround is to use
8321 if (! TARGET_V9 && flag_delayed_branch
8322 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8323 == INSN_ADDRESSES (INSN_UID (insn))))
8324 return \"b\\t%l0%#\";
8326 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8328 [(set_attr "type" "uncond_branch")])
8330 (define_expand "tablejump"
8331 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8332 (use (label_ref (match_operand 1 "" "")))])]
8336 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8339 /* In pic mode, our address differences are against the base of the
8340 table. Add that base value back in; CSE ought to be able to combine
8341 the two address loads. */
8345 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8347 if (CASE_VECTOR_MODE != Pmode)
8348 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8349 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8350 operands[0] = memory_address (Pmode, tmp);
8354 (define_insn "*tablejump_sp32"
8355 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8356 (use (label_ref (match_operand 1 "" "")))]
8359 [(set_attr "type" "uncond_branch")])
8361 (define_insn "*tablejump_sp64"
8362 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8363 (use (label_ref (match_operand 1 "" "")))]
8366 [(set_attr "type" "uncond_branch")])
8368 ;; This pattern recognizes the "instruction" that appears in
8369 ;; a function call that wants a structure value,
8370 ;; to inform the called function if compiled with Sun CC.
8371 ;(define_insn "*unimp_insn"
8372 ; [(match_operand:SI 0 "immediate_operand" "")]
8373 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8375 ; [(set_attr "type" "marker")])
8377 ;;- jump to subroutine
8378 (define_expand "call"
8379 ;; Note that this expression is not used for generating RTL.
8380 ;; All the RTL is generated explicitly below.
8381 [(call (match_operand 0 "call_operand" "")
8382 (match_operand 3 "" "i"))]
8383 ;; operands[2] is next_arg_register
8384 ;; operands[3] is struct_value_size_rtx.
8388 rtx fn_rtx, nregs_rtx;
8390 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8393 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8395 /* This is really a PIC sequence. We want to represent
8396 it as a funny jump so its delay slots can be filled.
8398 ??? But if this really *is* a CALL, will not it clobber the
8399 call-clobbered registers? We lose this if it is a JUMP_INSN.
8400 Why cannot we have delay slots filled if it were a CALL? */
8402 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8407 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8409 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8415 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8416 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8420 fn_rtx = operands[0];
8422 /* Count the number of parameter registers being used by this call.
8423 if that argument is NULL, it means we are using them all, which
8424 means 6 on the sparc. */
8427 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8429 nregs_rtx = GEN_INT (6);
8431 nregs_rtx = const0_rtx;
8434 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8438 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8440 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8445 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8446 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8450 /* If this call wants a structure value,
8451 emit an unimp insn to let the called function know about this. */
8452 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8454 rtx insn = emit_insn (operands[3]);
8455 SCHED_GROUP_P (insn) = 1;
8462 ;; We can't use the same pattern for these two insns, because then registers
8463 ;; in the address may not be properly reloaded.
8465 (define_insn "*call_address_sp32"
8466 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8467 (match_operand 1 "" ""))
8468 (clobber (reg:SI 15))]
8469 ;;- Do not use operand 1 for most machines.
8472 [(set_attr "type" "call")])
8474 (define_insn "*call_symbolic_sp32"
8475 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8476 (match_operand 1 "" ""))
8477 (clobber (reg:SI 15))]
8478 ;;- Do not use operand 1 for most machines.
8481 [(set_attr "type" "call")])
8483 (define_insn "*call_address_sp64"
8484 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8485 (match_operand 1 "" ""))
8486 (clobber (reg:DI 15))]
8487 ;;- Do not use operand 1 for most machines.
8490 [(set_attr "type" "call")])
8492 (define_insn "*call_symbolic_sp64"
8493 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8494 (match_operand 1 "" ""))
8495 (clobber (reg:DI 15))]
8496 ;;- Do not use operand 1 for most machines.
8499 [(set_attr "type" "call")])
8501 ;; This is a call that wants a structure value.
8502 ;; There is no such critter for v9 (??? we may need one anyway).
8503 (define_insn "*call_address_struct_value_sp32"
8504 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8505 (match_operand 1 "" ""))
8506 (match_operand 2 "immediate_operand" "")
8507 (clobber (reg:SI 15))]
8508 ;;- Do not use operand 1 for most machines.
8509 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8510 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8511 [(set_attr "type" "call_no_delay_slot")
8512 (set_attr "length" "3")])
8514 ;; This is a call that wants a structure value.
8515 ;; There is no such critter for v9 (??? we may need one anyway).
8516 (define_insn "*call_symbolic_struct_value_sp32"
8517 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8518 (match_operand 1 "" ""))
8519 (match_operand 2 "immediate_operand" "")
8520 (clobber (reg:SI 15))]
8521 ;;- Do not use operand 1 for most machines.
8522 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8523 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8524 [(set_attr "type" "call_no_delay_slot")
8525 (set_attr "length" "3")])
8527 ;; This is a call that may want a structure value. This is used for
8529 (define_insn "*call_address_untyped_struct_value_sp32"
8530 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8531 (match_operand 1 "" ""))
8532 (match_operand 2 "immediate_operand" "")
8533 (clobber (reg:SI 15))]
8534 ;;- Do not use operand 1 for most machines.
8535 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8536 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8537 [(set_attr "type" "call_no_delay_slot")
8538 (set_attr "length" "3")])
8540 ;; This is a call that wants a structure value.
8541 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8542 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8543 (match_operand 1 "" ""))
8544 (match_operand 2 "immediate_operand" "")
8545 (clobber (reg:SI 15))]
8546 ;;- Do not use operand 1 for most machines.
8547 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8548 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8549 [(set_attr "type" "call_no_delay_slot")
8550 (set_attr "length" "3")])
8552 (define_expand "call_value"
8553 ;; Note that this expression is not used for generating RTL.
8554 ;; All the RTL is generated explicitly below.
8555 [(set (match_operand 0 "register_operand" "=rf")
8556 (call (match_operand 1 "" "")
8557 (match_operand 4 "" "")))]
8558 ;; operand 2 is stack_size_rtx
8559 ;; operand 3 is next_arg_register
8563 rtx fn_rtx, nregs_rtx;
8566 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8569 fn_rtx = operands[1];
8573 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8575 nregs_rtx = GEN_INT (6);
8577 nregs_rtx = const0_rtx;
8581 gen_rtx_SET (VOIDmode, operands[0],
8582 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8583 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8585 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8590 (define_insn "*call_value_address_sp32"
8591 [(set (match_operand 0 "" "=rf")
8592 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8593 (match_operand 2 "" "")))
8594 (clobber (reg:SI 15))]
8595 ;;- Do not use operand 2 for most machines.
8598 [(set_attr "type" "call")])
8600 (define_insn "*call_value_symbolic_sp32"
8601 [(set (match_operand 0 "" "=rf")
8602 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8603 (match_operand 2 "" "")))
8604 (clobber (reg:SI 15))]
8605 ;;- Do not use operand 2 for most machines.
8608 [(set_attr "type" "call")])
8610 (define_insn "*call_value_address_sp64"
8611 [(set (match_operand 0 "" "")
8612 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8613 (match_operand 2 "" "")))
8614 (clobber (reg:DI 15))]
8615 ;;- Do not use operand 2 for most machines.
8618 [(set_attr "type" "call")])
8620 (define_insn "*call_value_symbolic_sp64"
8621 [(set (match_operand 0 "" "")
8622 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8623 (match_operand 2 "" "")))
8624 (clobber (reg:DI 15))]
8625 ;;- Do not use operand 2 for most machines.
8628 [(set_attr "type" "call")])
8630 (define_expand "untyped_call"
8631 [(parallel [(call (match_operand 0 "" "")
8633 (match_operand 1 "" "")
8634 (match_operand 2 "" "")])]
8640 /* Pass constm1 to indicate that it may expect a structure value, but
8641 we don't know what size it is. */
8642 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8644 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8646 rtx set = XVECEXP (operands[2], 0, i);
8647 emit_move_insn (SET_DEST (set), SET_SRC (set));
8650 /* The optimizer does not know that the call sets the function value
8651 registers we stored in the result block. We avoid problems by
8652 claiming that all hard registers are used and clobbered at this
8654 emit_insn (gen_blockage ());
8660 (define_expand "sibcall"
8661 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8666 (define_insn "*sibcall_symbolic_sp32"
8667 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8668 (match_operand 1 "" ""))
8671 "* return output_sibcall(insn, operands[0]);"
8672 [(set_attr "type" "sibcall")])
8674 (define_insn "*sibcall_symbolic_sp64"
8675 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8676 (match_operand 1 "" ""))
8679 "* return output_sibcall(insn, operands[0]);"
8680 [(set_attr "type" "sibcall")])
8682 (define_expand "sibcall_value"
8683 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8684 (call (match_operand 1 "" "") (const_int 0)))
8689 (define_insn "*sibcall_value_symbolic_sp32"
8690 [(set (match_operand 0 "" "=rf")
8691 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8692 (match_operand 2 "" "")))
8695 "* return output_sibcall(insn, operands[1]);"
8696 [(set_attr "type" "sibcall")])
8698 (define_insn "*sibcall_value_symbolic_sp64"
8699 [(set (match_operand 0 "" "")
8700 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8701 (match_operand 2 "" "")))
8704 "* return output_sibcall(insn, operands[1]);"
8705 [(set_attr "type" "sibcall")])
8707 (define_expand "sibcall_epilogue"
8712 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8713 ;; all of memory. This blocks insns from being moved across this point.
8715 (define_insn "blockage"
8716 [(unspec_volatile [(const_int 0)] 0)]
8719 [(set_attr "length" "0")])
8721 ;; Prepare to return any type including a structure value.
8723 (define_expand "untyped_return"
8724 [(match_operand:BLK 0 "memory_operand" "")
8725 (match_operand 1 "" "")]
8729 rtx valreg1 = gen_rtx_REG (DImode, 24);
8730 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8731 rtx result = operands[0];
8733 if (! TARGET_ARCH64)
8735 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8737 rtx value = gen_reg_rtx (SImode);
8739 /* Fetch the instruction where we will return to and see if it's an unimp
8740 instruction (the most significant 10 bits will be zero). If so,
8741 update the return address to skip the unimp instruction. */
8742 emit_move_insn (value,
8743 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8744 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8745 emit_insn (gen_update_return (rtnreg, value));
8748 /* Reload the function value registers. */
8749 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8750 emit_move_insn (valreg2,
8751 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8753 /* Put USE insns before the return. */
8754 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8755 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8757 /* Construct the return. */
8758 expand_null_return ();
8763 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8764 ;; and parts of the compiler don't want to believe that the add is needed.
8766 (define_insn "update_return"
8767 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8768 (match_operand:SI 1 "register_operand" "r")] 1)]
8770 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8771 [(set_attr "type" "multi")
8772 (set_attr "length" "3")])
8779 (define_expand "indirect_jump"
8780 [(set (pc) (match_operand 0 "address_operand" "p"))]
8784 (define_insn "*branch_sp32"
8785 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8788 [(set_attr "type" "uncond_branch")])
8790 (define_insn "*branch_sp64"
8791 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8794 [(set_attr "type" "uncond_branch")])
8796 ;; ??? Doesn't work with -mflat.
8797 (define_expand "nonlocal_goto"
8798 [(match_operand:SI 0 "general_operand" "")
8799 (match_operand:SI 1 "general_operand" "")
8800 (match_operand:SI 2 "general_operand" "")
8801 (match_operand:SI 3 "" "")]
8806 rtx chain = operands[0];
8808 rtx lab = operands[1];
8809 rtx stack = operands[2];
8810 rtx fp = operands[3];
8813 /* Trap instruction to flush all the register windows. */
8814 emit_insn (gen_flush_register_windows ());
8816 /* Load the fp value for the containing fn into %fp. This is needed
8817 because STACK refers to %fp. Note that virtual register instantiation
8818 fails if the virtual %fp isn't set from a register. */
8819 if (GET_CODE (fp) != REG)
8820 fp = force_reg (Pmode, fp);
8821 emit_move_insn (virtual_stack_vars_rtx, fp);
8823 /* Find the containing function's current nonlocal goto handler,
8824 which will do any cleanups and then jump to the label. */
8825 labreg = gen_rtx_REG (Pmode, 8);
8826 emit_move_insn (labreg, lab);
8828 /* Restore %fp from stack pointer value for containing function.
8829 The restore insn that follows will move this to %sp,
8830 and reload the appropriate value into %fp. */
8831 emit_move_insn (hard_frame_pointer_rtx, stack);
8833 /* USE of frame_pointer_rtx added for consistency; not clear if
8835 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8836 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8839 /* Return, restoring reg window and jumping to goto handler. */
8840 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8841 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8843 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8849 /* Put in the static chain register the nonlocal label address. */
8850 emit_move_insn (static_chain_rtx, chain);
8853 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8854 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8859 ;; Special trap insn to flush register windows.
8860 (define_insn "flush_register_windows"
8861 [(unspec_volatile [(const_int 0)] 1)]
8863 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8864 [(set_attr "type" "misc")])
8866 (define_insn "goto_handler_and_restore"
8867 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8868 "GET_MODE (operands[0]) == Pmode"
8869 "jmp\\t%0+0\\n\\trestore"
8870 [(set_attr "type" "multi")
8871 (set_attr "length" "2")])
8873 ;;(define_insn "goto_handler_and_restore_v9"
8874 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8875 ;; (match_operand:SI 1 "register_operand" "=r,r")
8876 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8877 ;; "TARGET_V9 && ! TARGET_ARCH64"
8879 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8880 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8881 ;; [(set_attr "type" "multi")
8882 ;; (set_attr "length" "2,3")])
8884 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8885 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8886 ;; (match_operand:DI 1 "register_operand" "=r,r")
8887 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8888 ;; "TARGET_V9 && TARGET_ARCH64"
8890 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8891 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8892 ;; [(set_attr "type" "multi")
8893 ;; (set_attr "length" "2,3")])
8895 ;; For __builtin_setjmp we need to flush register windows iff the function
8896 ;; calls alloca as well, because otherwise the register window might be
8897 ;; saved after %sp adjustement and thus setjmp would crash
8898 (define_expand "builtin_setjmp_setup"
8899 [(match_operand 0 "register_operand" "r")]
8903 emit_insn (gen_do_builtin_setjmp_setup ());
8907 (define_insn "do_builtin_setjmp_setup"
8908 [(unspec_volatile [(const_int 0)] 5)]
8912 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
8914 fputs (\"\tflushw\n\", asm_out_file);
8916 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8917 TARGET_ARCH64 ? 'x' : 'w',
8918 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8919 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8920 TARGET_ARCH64 ? 'x' : 'w',
8921 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8922 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8923 TARGET_ARCH64 ? 'x' : 'w',
8924 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8927 [(set_attr "type" "misc")
8928 (set (attr "length") (if_then_else (eq_attr "pic" "true")
8933 [(unspec_volatile [(const_int 0)] 5)]
8934 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
8938 if (current_function_calls_alloca)
8939 emit_insn (gen_flush_register_windows ());
8943 ;; Pattern for use after a setjmp to store FP and the return register
8944 ;; into the stack area.
8946 (define_expand "setjmp"
8952 emit_insn (gen_setjmp_64 ());
8954 emit_insn (gen_setjmp_32 ());
8958 (define_expand "setjmp_32"
8959 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8960 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8963 { operands[0] = frame_pointer_rtx; }")
8965 (define_expand "setjmp_64"
8966 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8967 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8970 { operands[0] = frame_pointer_rtx; }")
8972 ;; Special pattern for the FLUSH instruction.
8974 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8975 ; of the define_insn otherwise missing a mode. We make "flush", aka
8976 ; gen_flush, the default one since sparc_initialize_trampoline uses
8977 ; it on SImode mem values.
8979 (define_insn "flush"
8980 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8982 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8983 [(set_attr "type" "misc")])
8985 (define_insn "flushdi"
8986 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8988 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8989 [(set_attr "type" "misc")])
8994 ;; The scan instruction searches from the most significant bit while ffs
8995 ;; searches from the least significant bit. The bit index and treatment of
8996 ;; zero also differ. It takes at least 7 instructions to get the proper
8997 ;; result. Here is an obvious 8 instruction sequence.
9000 (define_insn "ffssi2"
9001 [(set (match_operand:SI 0 "register_operand" "=&r")
9002 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9003 (clobber (match_scratch:SI 2 "=&r"))]
9004 "TARGET_SPARCLITE || TARGET_SPARCLET"
9007 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\";
9009 [(set_attr "type" "multi")
9010 (set_attr "length" "8")])
9012 ;; ??? This should be a define expand, so that the extra instruction have
9013 ;; a chance of being optimized away.
9015 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9016 ;; does, but no one uses that and we don't have a switch for it.
9018 ;(define_insn "ffsdi2"
9019 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9020 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9021 ; (clobber (match_scratch:DI 2 "=&r"))]
9023 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9024 ; [(set_attr "type" "multi")
9025 ; (set_attr "length" "4")])
9029 ;; Peepholes go at the end.
9031 ;; Optimize consecutive loads or stores into ldd and std when possible.
9032 ;; The conditions in which we do this are very restricted and are
9033 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9036 [(set (match_operand:SI 0 "memory_operand" "")
9038 (set (match_operand:SI 1 "memory_operand" "")
9041 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
9044 "operands[0] = change_address (operands[0], DImode, NULL);")
9047 [(set (match_operand:SI 0 "memory_operand" "")
9049 (set (match_operand:SI 1 "memory_operand" "")
9052 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9055 "operands[1] = change_address (operands[1], DImode, NULL);")
9058 [(set (match_operand:SI 0 "register_operand" "")
9059 (match_operand:SI 1 "memory_operand" ""))
9060 (set (match_operand:SI 2 "register_operand" "")
9061 (match_operand:SI 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], DImode, NULL);
9067 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9070 [(set (match_operand:SI 0 "memory_operand" "")
9071 (match_operand:SI 1 "register_operand" ""))
9072 (set (match_operand:SI 2 "memory_operand" "")
9073 (match_operand:SI 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], DImode, NULL);
9079 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9082 [(set (match_operand:SF 0 "register_operand" "")
9083 (match_operand:SF 1 "memory_operand" ""))
9084 (set (match_operand:SF 2 "register_operand" "")
9085 (match_operand:SF 3 "memory_operand" ""))]
9086 "registers_ok_for_ldd_peep (operands[0], operands[2])
9087 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9090 "operands[1] = change_address (operands[1], DFmode, NULL);
9091 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9094 [(set (match_operand:SF 0 "memory_operand" "")
9095 (match_operand:SF 1 "register_operand" ""))
9096 (set (match_operand:SF 2 "memory_operand" "")
9097 (match_operand:SF 3 "register_operand" ""))]
9098 "registers_ok_for_ldd_peep (operands[1], operands[3])
9099 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9102 "operands[0] = change_address (operands[0], DFmode, NULL);
9103 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9106 [(set (match_operand:SI 0 "register_operand" "")
9107 (match_operand:SI 1 "memory_operand" ""))
9108 (set (match_operand:SI 2 "register_operand" "")
9109 (match_operand:SI 3 "memory_operand" ""))]
9110 "registers_ok_for_ldd_peep (operands[2], operands[0])
9111 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9114 "operands[3] = change_address (operands[3], DImode, NULL);
9115 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9118 [(set (match_operand:SI 0 "memory_operand" "")
9119 (match_operand:SI 1 "register_operand" ""))
9120 (set (match_operand:SI 2 "memory_operand" "")
9121 (match_operand:SI 3 "register_operand" ""))]
9122 "registers_ok_for_ldd_peep (operands[3], operands[1])
9123 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9126 "operands[2] = change_address (operands[2], DImode, NULL);
9127 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9131 [(set (match_operand:SF 0 "register_operand" "")
9132 (match_operand:SF 1 "memory_operand" ""))
9133 (set (match_operand:SF 2 "register_operand" "")
9134 (match_operand:SF 3 "memory_operand" ""))]
9135 "registers_ok_for_ldd_peep (operands[2], operands[0])
9136 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9139 "operands[3] = change_address (operands[3], DFmode, NULL);
9140 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9143 [(set (match_operand:SF 0 "memory_operand" "")
9144 (match_operand:SF 1 "register_operand" ""))
9145 (set (match_operand:SF 2 "memory_operand" "")
9146 (match_operand:SF 3 "register_operand" ""))]
9147 "registers_ok_for_ldd_peep (operands[3], operands[1])
9148 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9151 "operands[2] = change_address (operands[2], DFmode, NULL);
9152 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9154 ;; Optimize the case of following a reg-reg move with a test
9155 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9156 ;; This can result from a float to fix conversion.
9159 [(set (match_operand:SI 0 "register_operand" "")
9160 (match_operand:SI 1 "register_operand" ""))
9162 (compare:CC (match_operand:SI 2 "register_operand" "")
9164 "(rtx_equal_p (operands[2], operands[0])
9165 || rtx_equal_p (operands[2], operands[1]))
9166 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9167 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9168 [(parallel [(set (match_dup 0) (match_dup 1))
9170 (compare:CC (match_dup 1) (const_int 0)))])]
9174 [(set (match_operand:DI 0 "register_operand" "")
9175 (match_operand:DI 1 "register_operand" ""))
9177 (compare:CCX (match_operand:DI 2 "register_operand" "")
9180 && (rtx_equal_p (operands[2], operands[0])
9181 || rtx_equal_p (operands[2], operands[1]))
9182 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9183 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9184 [(parallel [(set (match_dup 0) (match_dup 1))
9186 (compare:CCX (match_dup 1) (const_int 0)))])]
9189 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
9190 ;; who then immediately calls final_scan_insn.
9192 (define_insn "*return_qi"
9193 [(set (match_operand:QI 0 "restore_operand" "")
9194 (match_operand:QI 1 "arith_operand" "rI"))
9196 "sparc_emitting_epilogue"
9199 if (! TARGET_ARCH64 && current_function_returns_struct)
9200 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9201 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9202 || IN_OR_GLOBAL_P (operands[1])))
9203 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9205 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9207 [(set_attr "type" "multi")
9208 (set_attr "length" "2")])
9210 (define_insn "*return_hi"
9211 [(set (match_operand:HI 0 "restore_operand" "")
9212 (match_operand:HI 1 "arith_operand" "rI"))
9214 "sparc_emitting_epilogue"
9217 if (! TARGET_ARCH64 && current_function_returns_struct)
9218 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9219 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9220 || IN_OR_GLOBAL_P (operands[1])))
9221 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9223 return \"ret\;restore %%g0, %1, %Y0\";
9225 [(set_attr "type" "multi")
9226 (set_attr "length" "2")])
9228 (define_insn "*return_si"
9229 [(set (match_operand:SI 0 "restore_operand" "")
9230 (match_operand:SI 1 "arith_operand" "rI"))
9232 "sparc_emitting_epilogue"
9235 if (! TARGET_ARCH64 && current_function_returns_struct)
9236 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9237 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9238 || IN_OR_GLOBAL_P (operands[1])))
9239 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9241 return \"ret\;restore %%g0, %1, %Y0\";
9243 [(set_attr "type" "multi")
9244 (set_attr "length" "2")])
9246 (define_insn "*return_sf_no_fpu"
9247 [(set (match_operand:SF 0 "restore_operand" "=r")
9248 (match_operand:SF 1 "register_operand" "r"))
9250 "sparc_emitting_epilogue"
9253 if (! TARGET_ARCH64 && current_function_returns_struct)
9254 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9255 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9256 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9258 return \"ret\;restore %%g0, %1, %Y0\";
9260 [(set_attr "type" "multi")
9261 (set_attr "length" "2")])
9263 (define_insn "*return_df_no_fpu"
9264 [(set (match_operand:DF 0 "restore_operand" "=r")
9265 (match_operand:DF 1 "register_operand" "r"))
9267 "sparc_emitting_epilogue && TARGET_ARCH64"
9270 if (IN_OR_GLOBAL_P (operands[1]))
9271 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9273 return \"ret\;restore %%g0, %1, %Y0\";
9275 [(set_attr "type" "multi")
9276 (set_attr "length" "2")])
9278 (define_insn "*return_addsi"
9279 [(set (match_operand:SI 0 "restore_operand" "")
9280 (plus:SI (match_operand:SI 1 "register_operand" "r")
9281 (match_operand:SI 2 "arith_operand" "rI")))
9283 "sparc_emitting_epilogue"
9286 if (! TARGET_ARCH64 && current_function_returns_struct)
9287 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9288 /* If operands are global or in registers, can use return */
9289 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9290 && (GET_CODE (operands[2]) == CONST_INT
9291 || IN_OR_GLOBAL_P (operands[2])))
9292 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9294 return \"ret\;restore %r1, %2, %Y0\";
9296 [(set_attr "type" "multi")
9297 (set_attr "length" "2")])
9299 (define_insn "*return_losum_si"
9300 [(set (match_operand:SI 0 "restore_operand" "")
9301 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9302 (match_operand:SI 2 "immediate_operand" "in")))
9304 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
9307 if (! TARGET_ARCH64 && current_function_returns_struct)
9308 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9309 /* If operands are global or in registers, can use return */
9310 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9311 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9313 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9315 [(set_attr "type" "multi")
9316 (set_attr "length" "2")])
9318 (define_insn "*return_di"
9319 [(set (match_operand:DI 0 "restore_operand" "")
9320 (match_operand:DI 1 "arith_double_operand" "rHI"))
9322 "sparc_emitting_epilogue && TARGET_ARCH64"
9323 "ret\;restore %%g0, %1, %Y0"
9324 [(set_attr "type" "multi")
9325 (set_attr "length" "2")])
9327 (define_insn "*return_adddi"
9328 [(set (match_operand:DI 0 "restore_operand" "")
9329 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9330 (match_operand:DI 2 "arith_double_operand" "rHI")))
9332 "sparc_emitting_epilogue && TARGET_ARCH64"
9333 "ret\;restore %r1, %2, %Y0"
9334 [(set_attr "type" "multi")
9335 (set_attr "length" "2")])
9337 (define_insn "*return_losum_di"
9338 [(set (match_operand:DI 0 "restore_operand" "")
9339 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9340 (match_operand:DI 2 "immediate_operand" "in")))
9342 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
9343 "ret\;restore %r1, %%lo(%a2), %Y0"
9344 [(set_attr "type" "multi")
9345 (set_attr "length" "2")])
9347 (define_insn "*return_sf"
9349 (match_operand:SF 0 "register_operand" "f"))
9351 "sparc_emitting_epilogue"
9352 "ret\;fmovs\\t%0, %%f0"
9353 [(set_attr "type" "multi")
9354 (set_attr "length" "2")])
9356 ;; Now peepholes to do a call followed by a jump.
9359 [(parallel [(set (match_operand 0 "" "")
9360 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9361 (match_operand 2 "" "")))
9362 (clobber (reg:SI 15))])
9363 (set (pc) (label_ref (match_operand 3 "" "")))]
9364 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9365 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9366 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9369 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9370 (match_operand 1 "" ""))
9371 (clobber (reg:SI 15))])
9372 (set (pc) (label_ref (match_operand 2 "" "")))]
9373 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9374 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9375 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9378 [(parallel [(set (match_operand 0 "" "")
9379 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9380 (match_operand 2 "" "")))
9381 (clobber (reg:DI 15))])
9382 (set (pc) (label_ref (match_operand 3 "" "")))]
9384 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9385 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9386 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9389 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9390 (match_operand 1 "" ""))
9391 (clobber (reg:DI 15))])
9392 (set (pc) (label_ref (match_operand 2 "" "")))]
9394 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9395 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9396 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9398 (define_insn "prefetch"
9399 [(prefetch (match_operand:DI 0 "address_operand" "p")
9400 (match_operand:DI 1 "const_int_operand" "n")
9401 (match_operand:DI 2 "const_int_operand" "n"))]
9404 static const char * const prefetch_instr[2][4] = {
9406 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9407 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9408 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9409 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9412 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9413 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9414 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9415 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9418 int read_or_write = INTVAL (operands[1]);
9419 int locality = INTVAL (operands[2]);
9421 if (read_or_write != 0 && read_or_write != 1)
9423 if (locality < 0 || locality > 3)
9425 return prefetch_instr [read_or_write][locality];
9427 [(set_attr "type" "load")])
9429 (define_expand "prologue"
9431 "flag_pic && current_function_uses_pic_offset_table"
9434 load_pic_register ();
9438 ;; We need to reload %l7 for -mflat -fpic,
9439 ;; otherwise %l7 should be preserved simply
9440 ;; by loading the function's register window
9441 (define_expand "exception_receiver"
9443 "TARGET_FLAT && flag_pic"
9446 load_pic_register ();
9451 (define_expand "builtin_setjmp_receiver"
9452 [(label_ref (match_operand 0 "" ""))]
9453 "TARGET_FLAT && flag_pic"
9456 load_pic_register ();
9461 [(trap_if (const_int 1) (const_int 5))]
9464 [(set_attr "type" "misc")])
9466 (define_expand "conditional_trap"
9467 [(trap_if (match_operator 0 "noov_compare_op"
9468 [(match_dup 2) (match_dup 3)])
9469 (match_operand:SI 1 "arith_operand" ""))]
9471 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9472 sparc_compare_op0, sparc_compare_op1);
9473 operands[3] = const0_rtx;")
9476 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9477 (match_operand:SI 1 "arith_operand" "rM"))]
9480 [(set_attr "type" "misc")])
9483 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9484 (match_operand:SI 1 "arith_operand" "rM"))]
9487 [(set_attr "type" "misc")])