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 [(clobber (const_int 0))]
3847 rtx set_dest = operands[0];
3848 rtx set_src = operands[1];
3852 dest1 = gen_df_reg (set_dest, 0);
3853 dest2 = gen_df_reg (set_dest, 1);
3854 src1 = gen_df_reg (set_src, 0);
3855 src2 = gen_df_reg (set_src, 1);
3857 /* Now emit using the real source and destination we found, swapping
3858 the order if we detect overlap. */
3859 if (reg_overlap_mentioned_p (dest1, src2))
3861 emit_insn (gen_movdf (dest2, src2));
3862 emit_insn (gen_movdf (dest1, src1));
3866 emit_insn (gen_movdf (dest1, src1));
3867 emit_insn (gen_movdf (dest2, src2));
3873 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3874 (match_operand:TF 1 "fp_zero_operand" ""))]
3876 [(clobber (const_int 0))]
3879 rtx set_dest = operands[0];
3882 switch (GET_CODE (set_dest))
3885 dest1 = gen_df_reg (set_dest, 0);
3886 dest2 = gen_df_reg (set_dest, 1);
3889 dest1 = adjust_address (set_dest, DFmode, 0);
3890 dest2 = adjust_address (set_dest, DFmode, 8);
3896 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3897 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3902 [(set (match_operand:TF 0 "register_operand" "")
3903 (match_operand:TF 1 "memory_operand" ""))]
3905 && offsettable_memref_p (operands[1]))"
3906 [(clobber (const_int 0))]
3909 rtx word0 = adjust_address (operands[1], DFmode, 0);
3910 rtx word1 = adjust_address (operands[1], DFmode, 8);
3911 rtx set_dest, dest1, dest2;
3913 set_dest = operands[0];
3915 dest1 = gen_df_reg (set_dest, 0);
3916 dest2 = gen_df_reg (set_dest, 1);
3918 /* Now output, ordering such that we don't clobber any registers
3919 mentioned in the address. */
3920 if (reg_overlap_mentioned_p (dest1, word1))
3923 emit_insn (gen_movdf (dest2, word1));
3924 emit_insn (gen_movdf (dest1, word0));
3928 emit_insn (gen_movdf (dest1, word0));
3929 emit_insn (gen_movdf (dest2, word1));
3935 [(set (match_operand:TF 0 "memory_operand" "")
3936 (match_operand:TF 1 "register_operand" ""))]
3938 && offsettable_memref_p (operands[0]))"
3939 [(clobber (const_int 0))]
3942 rtx set_src = operands[1];
3944 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3945 gen_df_reg (set_src, 0)));
3946 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3947 gen_df_reg (set_src, 1)));
3951 ;; Sparc V9 conditional move instructions.
3953 ;; We can handle larger constants here for some flavors, but for now we keep
3954 ;; it simple and only allow those constants supported by all flavours.
3955 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3956 ;; 3 contains the constant if one is present, but we handle either for
3957 ;; generality (sparc.c puts a constant in operand 2).
3959 (define_expand "movqicc"
3960 [(set (match_operand:QI 0 "register_operand" "")
3961 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3962 (match_operand:QI 2 "arith10_operand" "")
3963 (match_operand:QI 3 "arith10_operand" "")))]
3967 enum rtx_code code = GET_CODE (operands[1]);
3969 if (GET_MODE (sparc_compare_op0) == DImode
3973 if (sparc_compare_op1 == const0_rtx
3974 && GET_CODE (sparc_compare_op0) == REG
3975 && GET_MODE (sparc_compare_op0) == DImode
3976 && v9_regcmp_p (code))
3978 operands[1] = gen_rtx_fmt_ee (code, DImode,
3979 sparc_compare_op0, sparc_compare_op1);
3983 rtx cc_reg = gen_compare_reg (code,
3984 sparc_compare_op0, sparc_compare_op1);
3985 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3989 (define_expand "movhicc"
3990 [(set (match_operand:HI 0 "register_operand" "")
3991 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3992 (match_operand:HI 2 "arith10_operand" "")
3993 (match_operand:HI 3 "arith10_operand" "")))]
3997 enum rtx_code code = GET_CODE (operands[1]);
3999 if (GET_MODE (sparc_compare_op0) == DImode
4003 if (sparc_compare_op1 == const0_rtx
4004 && GET_CODE (sparc_compare_op0) == REG
4005 && GET_MODE (sparc_compare_op0) == DImode
4006 && v9_regcmp_p (code))
4008 operands[1] = gen_rtx_fmt_ee (code, DImode,
4009 sparc_compare_op0, sparc_compare_op1);
4013 rtx cc_reg = gen_compare_reg (code,
4014 sparc_compare_op0, sparc_compare_op1);
4015 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4019 (define_expand "movsicc"
4020 [(set (match_operand:SI 0 "register_operand" "")
4021 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4022 (match_operand:SI 2 "arith10_operand" "")
4023 (match_operand:SI 3 "arith10_operand" "")))]
4027 enum rtx_code code = GET_CODE (operands[1]);
4028 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4030 if (sparc_compare_op1 == const0_rtx
4031 && GET_CODE (sparc_compare_op0) == REG
4032 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4034 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4035 sparc_compare_op0, sparc_compare_op1);
4039 rtx cc_reg = gen_compare_reg (code,
4040 sparc_compare_op0, sparc_compare_op1);
4041 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4042 cc_reg, const0_rtx);
4046 (define_expand "movdicc"
4047 [(set (match_operand:DI 0 "register_operand" "")
4048 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4049 (match_operand:DI 2 "arith10_double_operand" "")
4050 (match_operand:DI 3 "arith10_double_operand" "")))]
4054 enum rtx_code code = GET_CODE (operands[1]);
4056 if (sparc_compare_op1 == const0_rtx
4057 && GET_CODE (sparc_compare_op0) == REG
4058 && GET_MODE (sparc_compare_op0) == DImode
4059 && v9_regcmp_p (code))
4061 operands[1] = gen_rtx_fmt_ee (code, DImode,
4062 sparc_compare_op0, sparc_compare_op1);
4066 rtx cc_reg = gen_compare_reg (code,
4067 sparc_compare_op0, sparc_compare_op1);
4068 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4069 cc_reg, const0_rtx);
4073 (define_expand "movsfcc"
4074 [(set (match_operand:SF 0 "register_operand" "")
4075 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4076 (match_operand:SF 2 "register_operand" "")
4077 (match_operand:SF 3 "register_operand" "")))]
4078 "TARGET_V9 && TARGET_FPU"
4081 enum rtx_code code = GET_CODE (operands[1]);
4083 if (GET_MODE (sparc_compare_op0) == DImode
4087 if (sparc_compare_op1 == const0_rtx
4088 && GET_CODE (sparc_compare_op0) == REG
4089 && GET_MODE (sparc_compare_op0) == DImode
4090 && v9_regcmp_p (code))
4092 operands[1] = gen_rtx_fmt_ee (code, DImode,
4093 sparc_compare_op0, sparc_compare_op1);
4097 rtx cc_reg = gen_compare_reg (code,
4098 sparc_compare_op0, sparc_compare_op1);
4099 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4103 (define_expand "movdfcc"
4104 [(set (match_operand:DF 0 "register_operand" "")
4105 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4106 (match_operand:DF 2 "register_operand" "")
4107 (match_operand:DF 3 "register_operand" "")))]
4108 "TARGET_V9 && TARGET_FPU"
4111 enum rtx_code code = GET_CODE (operands[1]);
4113 if (GET_MODE (sparc_compare_op0) == DImode
4117 if (sparc_compare_op1 == const0_rtx
4118 && GET_CODE (sparc_compare_op0) == REG
4119 && GET_MODE (sparc_compare_op0) == DImode
4120 && v9_regcmp_p (code))
4122 operands[1] = gen_rtx_fmt_ee (code, DImode,
4123 sparc_compare_op0, sparc_compare_op1);
4127 rtx cc_reg = gen_compare_reg (code,
4128 sparc_compare_op0, sparc_compare_op1);
4129 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4133 (define_expand "movtfcc"
4134 [(set (match_operand:TF 0 "register_operand" "")
4135 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4136 (match_operand:TF 2 "register_operand" "")
4137 (match_operand:TF 3 "register_operand" "")))]
4138 "TARGET_V9 && TARGET_FPU"
4141 enum rtx_code code = GET_CODE (operands[1]);
4143 if (GET_MODE (sparc_compare_op0) == DImode
4147 if (sparc_compare_op1 == const0_rtx
4148 && GET_CODE (sparc_compare_op0) == REG
4149 && GET_MODE (sparc_compare_op0) == DImode
4150 && v9_regcmp_p (code))
4152 operands[1] = gen_rtx_fmt_ee (code, DImode,
4153 sparc_compare_op0, sparc_compare_op1);
4157 rtx cc_reg = gen_compare_reg (code,
4158 sparc_compare_op0, sparc_compare_op1);
4159 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4163 ;; Conditional move define_insns.
4165 (define_insn "*movqi_cc_sp64"
4166 [(set (match_operand:QI 0 "register_operand" "=r,r")
4167 (if_then_else:QI (match_operator 1 "comparison_operator"
4168 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4170 (match_operand:QI 3 "arith11_operand" "rL,0")
4171 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4174 mov%C1\\t%x2, %3, %0
4175 mov%c1\\t%x2, %4, %0"
4176 [(set_attr "type" "cmove")])
4178 (define_insn "*movhi_cc_sp64"
4179 [(set (match_operand:HI 0 "register_operand" "=r,r")
4180 (if_then_else:HI (match_operator 1 "comparison_operator"
4181 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4183 (match_operand:HI 3 "arith11_operand" "rL,0")
4184 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4187 mov%C1\\t%x2, %3, %0
4188 mov%c1\\t%x2, %4, %0"
4189 [(set_attr "type" "cmove")])
4191 (define_insn "*movsi_cc_sp64"
4192 [(set (match_operand:SI 0 "register_operand" "=r,r")
4193 (if_then_else:SI (match_operator 1 "comparison_operator"
4194 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4196 (match_operand:SI 3 "arith11_operand" "rL,0")
4197 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4200 mov%C1\\t%x2, %3, %0
4201 mov%c1\\t%x2, %4, %0"
4202 [(set_attr "type" "cmove")])
4204 ;; ??? The constraints of operands 3,4 need work.
4205 (define_insn "*movdi_cc_sp64"
4206 [(set (match_operand:DI 0 "register_operand" "=r,r")
4207 (if_then_else:DI (match_operator 1 "comparison_operator"
4208 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4210 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4211 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4214 mov%C1\\t%x2, %3, %0
4215 mov%c1\\t%x2, %4, %0"
4216 [(set_attr "type" "cmove")])
4218 (define_insn "*movdi_cc_sp64_trunc"
4219 [(set (match_operand:SI 0 "register_operand" "=r,r")
4220 (if_then_else:SI (match_operator 1 "comparison_operator"
4221 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4223 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4224 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4227 mov%C1\\t%x2, %3, %0
4228 mov%c1\\t%x2, %4, %0"
4229 [(set_attr "type" "cmove")])
4231 (define_insn "*movsf_cc_sp64"
4232 [(set (match_operand:SF 0 "register_operand" "=f,f")
4233 (if_then_else:SF (match_operator 1 "comparison_operator"
4234 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4236 (match_operand:SF 3 "register_operand" "f,0")
4237 (match_operand:SF 4 "register_operand" "0,f")))]
4238 "TARGET_V9 && TARGET_FPU"
4240 fmovs%C1\\t%x2, %3, %0
4241 fmovs%c1\\t%x2, %4, %0"
4242 [(set_attr "type" "fpcmove")])
4244 (define_insn "movdf_cc_sp64"
4245 [(set (match_operand:DF 0 "register_operand" "=e,e")
4246 (if_then_else:DF (match_operator 1 "comparison_operator"
4247 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4249 (match_operand:DF 3 "register_operand" "e,0")
4250 (match_operand:DF 4 "register_operand" "0,e")))]
4251 "TARGET_V9 && TARGET_FPU"
4253 fmovd%C1\\t%x2, %3, %0
4254 fmovd%c1\\t%x2, %4, %0"
4255 [(set_attr "type" "fpcmove")
4256 (set_attr "fptype" "double")])
4258 (define_insn "*movtf_cc_hq_sp64"
4259 [(set (match_operand:TF 0 "register_operand" "=e,e")
4260 (if_then_else:TF (match_operator 1 "comparison_operator"
4261 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4263 (match_operand:TF 3 "register_operand" "e,0")
4264 (match_operand:TF 4 "register_operand" "0,e")))]
4265 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4267 fmovq%C1\\t%x2, %3, %0
4268 fmovq%c1\\t%x2, %4, %0"
4269 [(set_attr "type" "fpcmove")])
4271 (define_insn "*movtf_cc_sp64"
4272 [(set (match_operand:TF 0 "register_operand" "=e,e")
4273 (if_then_else:TF (match_operator 1 "comparison_operator"
4274 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4276 (match_operand:TF 3 "register_operand" "e,0")
4277 (match_operand:TF 4 "register_operand" "0,e")))]
4278 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4280 [(set_attr "length" "2")])
4283 [(set (match_operand:TF 0 "register_operand" "")
4284 (if_then_else:TF (match_operator 1 "comparison_operator"
4285 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4287 (match_operand:TF 3 "register_operand" "")
4288 (match_operand:TF 4 "register_operand" "")))]
4289 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4290 [(clobber (const_int 0))]
4293 rtx set_dest = operands[0];
4294 rtx set_srca = operands[3];
4295 rtx set_srcb = operands[4];
4296 int third = rtx_equal_p (set_dest, set_srca);
4298 rtx srca1, srca2, srcb1, srcb2;
4300 dest1 = gen_df_reg (set_dest, 0);
4301 dest2 = gen_df_reg (set_dest, 1);
4302 srca1 = gen_df_reg (set_srca, 0);
4303 srca2 = gen_df_reg (set_srca, 1);
4304 srcb1 = gen_df_reg (set_srcb, 0);
4305 srcb2 = gen_df_reg (set_srcb, 1);
4307 /* Now emit using the real source and destination we found, swapping
4308 the order if we detect overlap. */
4309 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4310 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4312 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4313 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4317 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4318 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4323 (define_insn "*movqi_cc_reg_sp64"
4324 [(set (match_operand:QI 0 "register_operand" "=r,r")
4325 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4326 [(match_operand:DI 2 "register_operand" "r,r")
4328 (match_operand:QI 3 "arith10_operand" "rM,0")
4329 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4332 movr%D1\\t%2, %r3, %0
4333 movr%d1\\t%2, %r4, %0"
4334 [(set_attr "type" "cmove")])
4336 (define_insn "*movhi_cc_reg_sp64"
4337 [(set (match_operand:HI 0 "register_operand" "=r,r")
4338 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4339 [(match_operand:DI 2 "register_operand" "r,r")
4341 (match_operand:HI 3 "arith10_operand" "rM,0")
4342 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4345 movr%D1\\t%2, %r3, %0
4346 movr%d1\\t%2, %r4, %0"
4347 [(set_attr "type" "cmove")])
4349 (define_insn "*movsi_cc_reg_sp64"
4350 [(set (match_operand:SI 0 "register_operand" "=r,r")
4351 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4352 [(match_operand:DI 2 "register_operand" "r,r")
4354 (match_operand:SI 3 "arith10_operand" "rM,0")
4355 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4358 movr%D1\\t%2, %r3, %0
4359 movr%d1\\t%2, %r4, %0"
4360 [(set_attr "type" "cmove")])
4362 ;; ??? The constraints of operands 3,4 need work.
4363 (define_insn "*movdi_cc_reg_sp64"
4364 [(set (match_operand:DI 0 "register_operand" "=r,r")
4365 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4366 [(match_operand:DI 2 "register_operand" "r,r")
4368 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4369 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4372 movr%D1\\t%2, %r3, %0
4373 movr%d1\\t%2, %r4, %0"
4374 [(set_attr "type" "cmove")])
4376 (define_insn "*movdi_cc_reg_sp64_trunc"
4377 [(set (match_operand:SI 0 "register_operand" "=r,r")
4378 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4379 [(match_operand:DI 2 "register_operand" "r,r")
4381 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4382 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4385 movr%D1\\t%2, %r3, %0
4386 movr%d1\\t%2, %r4, %0"
4387 [(set_attr "type" "cmove")])
4389 (define_insn "*movsf_cc_reg_sp64"
4390 [(set (match_operand:SF 0 "register_operand" "=f,f")
4391 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4392 [(match_operand:DI 2 "register_operand" "r,r")
4394 (match_operand:SF 3 "register_operand" "f,0")
4395 (match_operand:SF 4 "register_operand" "0,f")))]
4396 "TARGET_ARCH64 && TARGET_FPU"
4398 fmovrs%D1\\t%2, %3, %0
4399 fmovrs%d1\\t%2, %4, %0"
4400 [(set_attr "type" "fpcmove")])
4402 (define_insn "movdf_cc_reg_sp64"
4403 [(set (match_operand:DF 0 "register_operand" "=e,e")
4404 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4405 [(match_operand:DI 2 "register_operand" "r,r")
4407 (match_operand:DF 3 "register_operand" "e,0")
4408 (match_operand:DF 4 "register_operand" "0,e")))]
4409 "TARGET_ARCH64 && TARGET_FPU"
4411 fmovrd%D1\\t%2, %3, %0
4412 fmovrd%d1\\t%2, %4, %0"
4413 [(set_attr "type" "fpcmove")
4414 (set_attr "fptype" "double")])
4416 (define_insn "*movtf_cc_reg_hq_sp64"
4417 [(set (match_operand:TF 0 "register_operand" "=e,e")
4418 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4419 [(match_operand:DI 2 "register_operand" "r,r")
4421 (match_operand:TF 3 "register_operand" "e,0")
4422 (match_operand:TF 4 "register_operand" "0,e")))]
4423 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4425 fmovrq%D1\\t%2, %3, %0
4426 fmovrq%d1\\t%2, %4, %0"
4427 [(set_attr "type" "fpcmove")])
4429 (define_insn "*movtf_cc_reg_sp64"
4430 [(set (match_operand:TF 0 "register_operand" "=e,e")
4431 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4432 [(match_operand:DI 2 "register_operand" "r,r")
4434 (match_operand:TF 3 "register_operand" "e,0")
4435 (match_operand:TF 4 "register_operand" "0,e")))]
4436 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4438 [(set_attr "length" "2")])
4441 [(set (match_operand:TF 0 "register_operand" "")
4442 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4443 [(match_operand:DI 2 "register_operand" "")
4445 (match_operand:TF 3 "register_operand" "")
4446 (match_operand:TF 4 "register_operand" "")))]
4447 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4448 [(clobber (const_int 0))]
4451 rtx set_dest = operands[0];
4452 rtx set_srca = operands[3];
4453 rtx set_srcb = operands[4];
4454 int third = rtx_equal_p (set_dest, set_srca);
4456 rtx srca1, srca2, srcb1, srcb2;
4458 dest1 = gen_df_reg (set_dest, 0);
4459 dest2 = gen_df_reg (set_dest, 1);
4460 srca1 = gen_df_reg (set_srca, 0);
4461 srca2 = gen_df_reg (set_srca, 1);
4462 srcb1 = gen_df_reg (set_srcb, 0);
4463 srcb2 = gen_df_reg (set_srcb, 1);
4465 /* Now emit using the real source and destination we found, swapping
4466 the order if we detect overlap. */
4467 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4468 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4470 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4471 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4475 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4476 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4482 ;;- zero extension instructions
4484 ;; These patterns originally accepted general_operands, however, slightly
4485 ;; better code is generated by only accepting register_operands, and then
4486 ;; letting combine generate the ldu[hb] insns.
4488 (define_expand "zero_extendhisi2"
4489 [(set (match_operand:SI 0 "register_operand" "")
4490 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4494 rtx temp = gen_reg_rtx (SImode);
4495 rtx shift_16 = GEN_INT (16);
4496 int op1_subbyte = 0;
4498 if (GET_CODE (operand1) == SUBREG)
4500 op1_subbyte = SUBREG_BYTE (operand1);
4501 op1_subbyte /= GET_MODE_SIZE (SImode);
4502 op1_subbyte *= GET_MODE_SIZE (SImode);
4503 operand1 = XEXP (operand1, 0);
4506 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4508 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4512 (define_insn "*zero_extendhisi2_insn"
4513 [(set (match_operand:SI 0 "register_operand" "=r")
4514 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4517 [(set_attr "type" "load")])
4519 (define_expand "zero_extendqihi2"
4520 [(set (match_operand:HI 0 "register_operand" "")
4521 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4525 (define_insn "*zero_extendqihi2_insn"
4526 [(set (match_operand:HI 0 "register_operand" "=r,r")
4527 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4528 "GET_CODE (operands[1]) != CONST_INT"
4532 [(set_attr "type" "*,load")])
4534 (define_expand "zero_extendqisi2"
4535 [(set (match_operand:SI 0 "register_operand" "")
4536 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4540 (define_insn "*zero_extendqisi2_insn"
4541 [(set (match_operand:SI 0 "register_operand" "=r,r")
4542 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4543 "GET_CODE (operands[1]) != CONST_INT"
4547 [(set_attr "type" "*,load")])
4549 (define_expand "zero_extendqidi2"
4550 [(set (match_operand:DI 0 "register_operand" "")
4551 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4555 (define_insn "*zero_extendqidi2_insn"
4556 [(set (match_operand:DI 0 "register_operand" "=r,r")
4557 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4558 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4562 [(set_attr "type" "*,load")])
4564 (define_expand "zero_extendhidi2"
4565 [(set (match_operand:DI 0 "register_operand" "")
4566 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4570 rtx temp = gen_reg_rtx (DImode);
4571 rtx shift_48 = GEN_INT (48);
4572 int op1_subbyte = 0;
4574 if (GET_CODE (operand1) == SUBREG)
4576 op1_subbyte = SUBREG_BYTE (operand1);
4577 op1_subbyte /= GET_MODE_SIZE (DImode);
4578 op1_subbyte *= GET_MODE_SIZE (DImode);
4579 operand1 = XEXP (operand1, 0);
4582 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4584 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4588 (define_insn "*zero_extendhidi2_insn"
4589 [(set (match_operand:DI 0 "register_operand" "=r")
4590 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4593 [(set_attr "type" "load")])
4596 ;; ??? Write truncdisi pattern using sra?
4598 (define_expand "zero_extendsidi2"
4599 [(set (match_operand:DI 0 "register_operand" "")
4600 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4604 (define_insn "*zero_extendsidi2_insn_sp64"
4605 [(set (match_operand:DI 0 "register_operand" "=r,r")
4606 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4607 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4611 [(set_attr "type" "shift,load")])
4613 (define_insn "*zero_extendsidi2_insn_sp32"
4614 [(set (match_operand:DI 0 "register_operand" "=r")
4615 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4618 [(set_attr "length" "2")])
4621 [(set (match_operand:DI 0 "register_operand" "")
4622 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4623 "! TARGET_ARCH64 && reload_completed"
4624 [(set (match_dup 2) (match_dup 3))
4625 (set (match_dup 4) (match_dup 5))]
4630 dest1 = gen_highpart (SImode, operands[0]);
4631 dest2 = gen_lowpart (SImode, operands[0]);
4633 /* Swap the order in case of overlap. */
4634 if (REGNO (dest1) == REGNO (operands[1]))
4636 operands[2] = dest2;
4637 operands[3] = operands[1];
4638 operands[4] = dest1;
4639 operands[5] = const0_rtx;
4643 operands[2] = dest1;
4644 operands[3] = const0_rtx;
4645 operands[4] = dest2;
4646 operands[5] = operands[1];
4650 ;; Simplify comparisons of extended values.
4652 (define_insn "*cmp_zero_extendqisi2"
4654 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4657 "andcc\\t%0, 0xff, %%g0"
4658 [(set_attr "type" "compare")])
4660 (define_insn "*cmp_zero_qi"
4662 (compare:CC (match_operand:QI 0 "register_operand" "r")
4665 "andcc\\t%0, 0xff, %%g0"
4666 [(set_attr "type" "compare")])
4668 (define_insn "*cmp_zero_extendqisi2_set"
4670 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4672 (set (match_operand:SI 0 "register_operand" "=r")
4673 (zero_extend:SI (match_dup 1)))]
4675 "andcc\\t%1, 0xff, %0"
4676 [(set_attr "type" "compare")])
4678 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4680 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4683 (set (match_operand:SI 0 "register_operand" "=r")
4684 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4686 "andcc\\t%1, 0xff, %0"
4687 [(set_attr "type" "compare")])
4689 (define_insn "*cmp_zero_extendqidi2"
4691 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4694 "andcc\\t%0, 0xff, %%g0"
4695 [(set_attr "type" "compare")])
4697 (define_insn "*cmp_zero_qi_sp64"
4699 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4702 "andcc\\t%0, 0xff, %%g0"
4703 [(set_attr "type" "compare")])
4705 (define_insn "*cmp_zero_extendqidi2_set"
4707 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4709 (set (match_operand:DI 0 "register_operand" "=r")
4710 (zero_extend:DI (match_dup 1)))]
4712 "andcc\\t%1, 0xff, %0"
4713 [(set_attr "type" "compare")])
4715 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4717 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4720 (set (match_operand:DI 0 "register_operand" "=r")
4721 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4723 "andcc\\t%1, 0xff, %0"
4724 [(set_attr "type" "compare")])
4726 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4728 (define_insn "*cmp_siqi_trunc"
4730 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4733 "andcc\\t%0, 0xff, %%g0"
4734 [(set_attr "type" "compare")])
4736 (define_insn "*cmp_siqi_trunc_set"
4738 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4740 (set (match_operand:QI 0 "register_operand" "=r")
4741 (subreg:QI (match_dup 1) 3))]
4743 "andcc\\t%1, 0xff, %0"
4744 [(set_attr "type" "compare")])
4746 (define_insn "*cmp_diqi_trunc"
4748 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4751 "andcc\\t%0, 0xff, %%g0"
4752 [(set_attr "type" "compare")])
4754 (define_insn "*cmp_diqi_trunc_set"
4756 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4758 (set (match_operand:QI 0 "register_operand" "=r")
4759 (subreg:QI (match_dup 1) 7))]
4761 "andcc\\t%1, 0xff, %0"
4762 [(set_attr "type" "compare")])
4764 ;;- sign extension instructions
4766 ;; These patterns originally accepted general_operands, however, slightly
4767 ;; better code is generated by only accepting register_operands, and then
4768 ;; letting combine generate the lds[hb] insns.
4770 (define_expand "extendhisi2"
4771 [(set (match_operand:SI 0 "register_operand" "")
4772 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4776 rtx temp = gen_reg_rtx (SImode);
4777 rtx shift_16 = GEN_INT (16);
4778 int op1_subbyte = 0;
4780 if (GET_CODE (operand1) == SUBREG)
4782 op1_subbyte = SUBREG_BYTE (operand1);
4783 op1_subbyte /= GET_MODE_SIZE (SImode);
4784 op1_subbyte *= GET_MODE_SIZE (SImode);
4785 operand1 = XEXP (operand1, 0);
4788 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4790 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4794 (define_insn "*sign_extendhisi2_insn"
4795 [(set (match_operand:SI 0 "register_operand" "=r")
4796 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4799 [(set_attr "type" "sload")])
4801 (define_expand "extendqihi2"
4802 [(set (match_operand:HI 0 "register_operand" "")
4803 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4807 rtx temp = gen_reg_rtx (SImode);
4808 rtx shift_24 = GEN_INT (24);
4809 int op1_subbyte = 0;
4810 int op0_subbyte = 0;
4812 if (GET_CODE (operand1) == SUBREG)
4814 op1_subbyte = SUBREG_BYTE (operand1);
4815 op1_subbyte /= GET_MODE_SIZE (SImode);
4816 op1_subbyte *= GET_MODE_SIZE (SImode);
4817 operand1 = XEXP (operand1, 0);
4819 if (GET_CODE (operand0) == SUBREG)
4821 op0_subbyte = SUBREG_BYTE (operand0);
4822 op0_subbyte /= GET_MODE_SIZE (SImode);
4823 op0_subbyte *= GET_MODE_SIZE (SImode);
4824 operand0 = XEXP (operand0, 0);
4826 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4828 if (GET_MODE (operand0) != SImode)
4829 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4830 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4834 (define_insn "*sign_extendqihi2_insn"
4835 [(set (match_operand:HI 0 "register_operand" "=r")
4836 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4839 [(set_attr "type" "sload")])
4841 (define_expand "extendqisi2"
4842 [(set (match_operand:SI 0 "register_operand" "")
4843 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4847 rtx temp = gen_reg_rtx (SImode);
4848 rtx shift_24 = GEN_INT (24);
4849 int op1_subbyte = 0;
4851 if (GET_CODE (operand1) == SUBREG)
4853 op1_subbyte = SUBREG_BYTE (operand1);
4854 op1_subbyte /= GET_MODE_SIZE (SImode);
4855 op1_subbyte *= GET_MODE_SIZE (SImode);
4856 operand1 = XEXP (operand1, 0);
4859 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4861 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4865 (define_insn "*sign_extendqisi2_insn"
4866 [(set (match_operand:SI 0 "register_operand" "=r")
4867 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4870 [(set_attr "type" "sload")])
4872 (define_expand "extendqidi2"
4873 [(set (match_operand:DI 0 "register_operand" "")
4874 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4878 rtx temp = gen_reg_rtx (DImode);
4879 rtx shift_56 = GEN_INT (56);
4880 int op1_subbyte = 0;
4882 if (GET_CODE (operand1) == SUBREG)
4884 op1_subbyte = SUBREG_BYTE (operand1);
4885 op1_subbyte /= GET_MODE_SIZE (DImode);
4886 op1_subbyte *= GET_MODE_SIZE (DImode);
4887 operand1 = XEXP (operand1, 0);
4890 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4892 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4896 (define_insn "*sign_extendqidi2_insn"
4897 [(set (match_operand:DI 0 "register_operand" "=r")
4898 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4901 [(set_attr "type" "sload")])
4903 (define_expand "extendhidi2"
4904 [(set (match_operand:DI 0 "register_operand" "")
4905 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4909 rtx temp = gen_reg_rtx (DImode);
4910 rtx shift_48 = GEN_INT (48);
4911 int op1_subbyte = 0;
4913 if (GET_CODE (operand1) == SUBREG)
4915 op1_subbyte = SUBREG_BYTE (operand1);
4916 op1_subbyte /= GET_MODE_SIZE (DImode);
4917 op1_subbyte *= GET_MODE_SIZE (DImode);
4918 operand1 = XEXP (operand1, 0);
4921 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4923 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4927 (define_insn "*sign_extendhidi2_insn"
4928 [(set (match_operand:DI 0 "register_operand" "=r")
4929 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4932 [(set_attr "type" "sload")])
4934 (define_expand "extendsidi2"
4935 [(set (match_operand:DI 0 "register_operand" "")
4936 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4940 (define_insn "*sign_extendsidi2_insn"
4941 [(set (match_operand:DI 0 "register_operand" "=r,r")
4942 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4947 [(set_attr "type" "shift,sload")])
4949 ;; Special pattern for optimizing bit-field compares. This is needed
4950 ;; because combine uses this as a canonical form.
4952 (define_insn "*cmp_zero_extract"
4955 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4956 (match_operand:SI 1 "small_int_or_double" "n")
4957 (match_operand:SI 2 "small_int_or_double" "n"))
4959 "(GET_CODE (operands[2]) == CONST_INT
4960 && INTVAL (operands[2]) > 19)
4961 || (GET_CODE (operands[2]) == CONST_DOUBLE
4962 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4965 int len = (GET_CODE (operands[1]) == CONST_INT
4966 ? INTVAL (operands[1])
4967 : CONST_DOUBLE_LOW (operands[1]));
4969 (GET_CODE (operands[2]) == CONST_INT
4970 ? INTVAL (operands[2])
4971 : CONST_DOUBLE_LOW (operands[2])) - len;
4972 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4974 operands[1] = GEN_INT (mask);
4975 return \"andcc\\t%0, %1, %%g0\";
4977 [(set_attr "type" "compare")])
4979 (define_insn "*cmp_zero_extract_sp64"
4982 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4983 (match_operand:SI 1 "small_int_or_double" "n")
4984 (match_operand:SI 2 "small_int_or_double" "n"))
4987 && ((GET_CODE (operands[2]) == CONST_INT
4988 && INTVAL (operands[2]) > 51)
4989 || (GET_CODE (operands[2]) == CONST_DOUBLE
4990 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4993 int len = (GET_CODE (operands[1]) == CONST_INT
4994 ? INTVAL (operands[1])
4995 : CONST_DOUBLE_LOW (operands[1]));
4997 (GET_CODE (operands[2]) == CONST_INT
4998 ? INTVAL (operands[2])
4999 : CONST_DOUBLE_LOW (operands[2])) - len;
5000 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5002 operands[1] = GEN_INT (mask);
5003 return \"andcc\\t%0, %1, %%g0\";
5005 [(set_attr "type" "compare")])
5007 ;; Conversions between float, double and long double.
5009 (define_insn "extendsfdf2"
5010 [(set (match_operand:DF 0 "register_operand" "=e")
5012 (match_operand:SF 1 "register_operand" "f")))]
5015 [(set_attr "type" "fp")
5016 (set_attr "fptype" "double")])
5018 (define_expand "extendsftf2"
5019 [(set (match_operand:TF 0 "register_operand" "=e")
5021 (match_operand:SF 1 "register_operand" "f")))]
5022 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5025 if (! TARGET_HARD_QUAD)
5029 if (GET_CODE (operands[0]) != MEM)
5030 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5032 slot0 = operands[0];
5034 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5036 XEXP (slot0, 0), Pmode,
5037 operands[1], SFmode);
5039 if (GET_CODE (operands[0]) != MEM)
5040 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5045 (define_insn "*extendsftf2_hq"
5046 [(set (match_operand:TF 0 "register_operand" "=e")
5048 (match_operand:SF 1 "register_operand" "f")))]
5049 "TARGET_FPU && TARGET_HARD_QUAD"
5051 [(set_attr "type" "fp")])
5053 (define_expand "extenddftf2"
5054 [(set (match_operand:TF 0 "register_operand" "=e")
5056 (match_operand:DF 1 "register_operand" "e")))]
5057 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5060 if (! TARGET_HARD_QUAD)
5064 if (GET_CODE (operands[0]) != MEM)
5065 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5067 slot0 = operands[0];
5069 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5071 XEXP (slot0, 0), Pmode,
5072 operands[1], DFmode);
5074 if (GET_CODE (operands[0]) != MEM)
5075 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5080 (define_insn "*extenddftf2_hq"
5081 [(set (match_operand:TF 0 "register_operand" "=e")
5083 (match_operand:DF 1 "register_operand" "e")))]
5084 "TARGET_FPU && TARGET_HARD_QUAD"
5086 [(set_attr "type" "fp")])
5088 (define_insn "truncdfsf2"
5089 [(set (match_operand:SF 0 "register_operand" "=f")
5091 (match_operand:DF 1 "register_operand" "e")))]
5094 [(set_attr "type" "fp")
5095 (set_attr "fptype" "double")])
5097 (define_expand "trunctfsf2"
5098 [(set (match_operand:SF 0 "register_operand" "=f")
5100 (match_operand:TF 1 "register_operand" "e")))]
5101 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5104 if (! TARGET_HARD_QUAD)
5108 if (GET_CODE (operands[1]) != MEM)
5110 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5111 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5114 slot0 = operands[1];
5116 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5117 operands[0], 0, SFmode, 1,
5118 XEXP (slot0, 0), Pmode);
5123 (define_insn "*trunctfsf2_hq"
5124 [(set (match_operand:SF 0 "register_operand" "=f")
5126 (match_operand:TF 1 "register_operand" "e")))]
5127 "TARGET_FPU && TARGET_HARD_QUAD"
5129 [(set_attr "type" "fp")])
5131 (define_expand "trunctfdf2"
5132 [(set (match_operand:DF 0 "register_operand" "=f")
5134 (match_operand:TF 1 "register_operand" "e")))]
5135 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5138 if (! TARGET_HARD_QUAD)
5142 if (GET_CODE (operands[1]) != MEM)
5144 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5145 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5148 slot0 = operands[1];
5150 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5151 operands[0], 0, DFmode, 1,
5152 XEXP (slot0, 0), Pmode);
5157 (define_insn "*trunctfdf2_hq"
5158 [(set (match_operand:DF 0 "register_operand" "=e")
5160 (match_operand:TF 1 "register_operand" "e")))]
5161 "TARGET_FPU && TARGET_HARD_QUAD"
5163 [(set_attr "type" "fp")])
5165 ;; Conversion between fixed point and floating point.
5167 (define_insn "floatsisf2"
5168 [(set (match_operand:SF 0 "register_operand" "=f")
5169 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5172 [(set_attr "type" "fp")
5173 (set_attr "fptype" "double")])
5175 (define_insn "floatsidf2"
5176 [(set (match_operand:DF 0 "register_operand" "=e")
5177 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5180 [(set_attr "type" "fp")
5181 (set_attr "fptype" "double")])
5183 (define_expand "floatsitf2"
5184 [(set (match_operand:TF 0 "register_operand" "=e")
5185 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5186 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5189 if (! TARGET_HARD_QUAD)
5193 if (GET_CODE (operands[1]) != MEM)
5194 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5196 slot0 = operands[1];
5198 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5200 XEXP (slot0, 0), Pmode,
5201 operands[1], SImode);
5203 if (GET_CODE (operands[0]) != MEM)
5204 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5209 (define_insn "*floatsitf2_hq"
5210 [(set (match_operand:TF 0 "register_operand" "=e")
5211 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5212 "TARGET_FPU && TARGET_HARD_QUAD"
5214 [(set_attr "type" "fp")])
5216 (define_expand "floatunssitf2"
5217 [(set (match_operand:TF 0 "register_operand" "=e")
5218 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5219 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5224 if (GET_CODE (operands[1]) != MEM)
5225 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5227 slot0 = operands[1];
5229 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5231 XEXP (slot0, 0), Pmode,
5232 operands[1], SImode);
5234 if (GET_CODE (operands[0]) != MEM)
5235 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5239 ;; Now the same for 64 bit sources.
5241 (define_insn "floatdisf2"
5242 [(set (match_operand:SF 0 "register_operand" "=f")
5243 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5244 "TARGET_V9 && TARGET_FPU"
5246 [(set_attr "type" "fp")
5247 (set_attr "fptype" "double")])
5249 (define_expand "floatunsdisf2"
5250 [(use (match_operand:SF 0 "register_operand" ""))
5251 (use (match_operand:DI 1 "register_operand" ""))]
5252 "TARGET_ARCH64 && TARGET_FPU"
5253 "sparc_emit_floatunsdi (operands); DONE;")
5255 (define_insn "floatdidf2"
5256 [(set (match_operand:DF 0 "register_operand" "=e")
5257 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5258 "TARGET_V9 && TARGET_FPU"
5260 [(set_attr "type" "fp")
5261 (set_attr "fptype" "double")])
5263 (define_expand "floatunsdidf2"
5264 [(use (match_operand:DF 0 "register_operand" ""))
5265 (use (match_operand:DI 1 "register_operand" ""))]
5266 "TARGET_ARCH64 && TARGET_FPU"
5267 "sparc_emit_floatunsdi (operands); DONE;")
5269 (define_expand "floatditf2"
5270 [(set (match_operand:TF 0 "register_operand" "=e")
5271 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5272 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5275 if (! TARGET_HARD_QUAD)
5279 if (GET_CODE (operands[1]) != MEM)
5280 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5282 slot0 = operands[1];
5284 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5286 XEXP (slot0, 0), Pmode,
5287 operands[1], DImode);
5289 if (GET_CODE (operands[0]) != MEM)
5290 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5295 (define_insn "*floatditf2_hq"
5296 [(set (match_operand:TF 0 "register_operand" "=e")
5297 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5298 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5300 [(set_attr "type" "fp")])
5302 (define_expand "floatunsditf2"
5303 [(set (match_operand:TF 0 "register_operand" "=e")
5304 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5305 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5310 if (GET_CODE (operands[1]) != MEM)
5311 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5313 slot0 = operands[1];
5315 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5317 XEXP (slot0, 0), Pmode,
5318 operands[1], DImode);
5320 if (GET_CODE (operands[0]) != MEM)
5321 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5325 ;; Convert a float to an actual integer.
5326 ;; Truncation is performed as part of the conversion.
5328 (define_insn "fix_truncsfsi2"
5329 [(set (match_operand:SI 0 "register_operand" "=f")
5330 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5333 [(set_attr "type" "fp")
5334 (set_attr "fptype" "double")])
5336 (define_insn "fix_truncdfsi2"
5337 [(set (match_operand:SI 0 "register_operand" "=f")
5338 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5341 [(set_attr "type" "fp")
5342 (set_attr "fptype" "double")])
5344 (define_expand "fix_trunctfsi2"
5345 [(set (match_operand:SI 0 "register_operand" "=f")
5346 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5347 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5350 if (! TARGET_HARD_QUAD)
5354 if (GET_CODE (operands[1]) != MEM)
5356 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5357 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5360 slot0 = operands[1];
5362 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5363 operands[0], 0, SImode, 1,
5364 XEXP (slot0, 0), Pmode);
5369 (define_insn "*fix_trunctfsi2_hq"
5370 [(set (match_operand:SI 0 "register_operand" "=f")
5371 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5372 "TARGET_FPU && TARGET_HARD_QUAD"
5374 [(set_attr "type" "fp")])
5376 (define_expand "fixuns_trunctfsi2"
5377 [(set (match_operand:SI 0 "register_operand" "=f")
5378 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5379 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5384 if (GET_CODE (operands[1]) != MEM)
5386 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5387 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5390 slot0 = operands[1];
5392 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5393 operands[0], 0, SImode, 1,
5394 XEXP (slot0, 0), Pmode);
5398 ;; Now the same, for V9 targets
5400 (define_insn "fix_truncsfdi2"
5401 [(set (match_operand:DI 0 "register_operand" "=e")
5402 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5403 "TARGET_V9 && TARGET_FPU"
5405 [(set_attr "type" "fp")
5406 (set_attr "fptype" "double")])
5408 (define_insn "fix_truncdfdi2"
5409 [(set (match_operand:DI 0 "register_operand" "=e")
5410 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5411 "TARGET_V9 && TARGET_FPU"
5413 [(set_attr "type" "fp")
5414 (set_attr "fptype" "double")])
5416 (define_expand "fix_trunctfdi2"
5417 [(set (match_operand:DI 0 "register_operand" "=e")
5418 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5419 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5422 if (! TARGET_HARD_QUAD)
5426 if (GET_CODE (operands[1]) != MEM)
5428 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5429 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5432 slot0 = operands[1];
5434 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5435 operands[0], 0, DImode, 1,
5436 XEXP (slot0, 0), Pmode);
5441 (define_insn "*fix_trunctfdi2_hq"
5442 [(set (match_operand:DI 0 "register_operand" "=e")
5443 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5444 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5446 [(set_attr "type" "fp")])
5448 (define_expand "fixuns_trunctfdi2"
5449 [(set (match_operand:DI 0 "register_operand" "=f")
5450 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5451 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5456 if (GET_CODE (operands[1]) != MEM)
5458 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5459 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5462 slot0 = operands[1];
5464 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5465 operands[0], 0, DImode, 1,
5466 XEXP (slot0, 0), Pmode);
5471 ;;- arithmetic instructions
5473 (define_expand "adddi3"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5475 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5476 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5482 if (! TARGET_ARCH64)
5484 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5485 gen_rtx_SET (VOIDmode, operands[0],
5486 gen_rtx_PLUS (DImode, operands[1],
5488 gen_rtx_CLOBBER (VOIDmode,
5489 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5492 if (arith_double_4096_operand(operands[2], DImode))
5494 switch (GET_CODE (operands[1]))
5496 case CONST_INT: i = INTVAL (operands[1]); break;
5497 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5499 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5500 gen_rtx_MINUS (DImode, operands[1],
5504 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5509 (define_insn "adddi3_insn_sp32"
5510 [(set (match_operand:DI 0 "register_operand" "=r")
5511 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5512 (match_operand:DI 2 "arith_double_operand" "rHI")))
5513 (clobber (reg:CC 100))]
5516 [(set_attr "length" "2")])
5519 [(set (match_operand:DI 0 "register_operand" "")
5520 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5521 (match_operand:DI 2 "arith_double_operand" "")))
5522 (clobber (reg:CC 100))]
5523 "! TARGET_ARCH64 && reload_completed"
5524 [(parallel [(set (reg:CC_NOOV 100)
5525 (compare:CC_NOOV (plus:SI (match_dup 4)
5529 (plus:SI (match_dup 4) (match_dup 5)))])
5531 (plus:SI (plus:SI (match_dup 7)
5533 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5536 operands[3] = gen_lowpart (SImode, operands[0]);
5537 operands[4] = gen_lowpart (SImode, operands[1]);
5538 operands[5] = gen_lowpart (SImode, operands[2]);
5539 operands[6] = gen_highpart (SImode, operands[0]);
5540 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5541 #if HOST_BITS_PER_WIDE_INT == 32
5542 if (GET_CODE (operands[2]) == CONST_INT)
5544 if (INTVAL (operands[2]) < 0)
5545 operands[8] = constm1_rtx;
5547 operands[8] = const0_rtx;
5551 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5555 [(set (match_operand:DI 0 "register_operand" "")
5556 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5557 (match_operand:DI 2 "arith_double_operand" "")))
5558 (clobber (reg:CC 100))]
5559 "! TARGET_ARCH64 && reload_completed"
5560 [(parallel [(set (reg:CC_NOOV 100)
5561 (compare:CC_NOOV (minus:SI (match_dup 4)
5565 (minus:SI (match_dup 4) (match_dup 5)))])
5567 (minus:SI (minus:SI (match_dup 7)
5569 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5572 operands[3] = gen_lowpart (SImode, operands[0]);
5573 operands[4] = gen_lowpart (SImode, operands[1]);
5574 operands[5] = gen_lowpart (SImode, operands[2]);
5575 operands[6] = gen_highpart (SImode, operands[0]);
5576 operands[7] = gen_highpart (SImode, operands[1]);
5577 #if HOST_BITS_PER_WIDE_INT == 32
5578 if (GET_CODE (operands[2]) == CONST_INT)
5580 if (INTVAL (operands[2]) < 0)
5581 operands[8] = constm1_rtx;
5583 operands[8] = const0_rtx;
5587 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5590 ;; LTU here means "carry set"
5592 [(set (match_operand:SI 0 "register_operand" "=r")
5593 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5594 (match_operand:SI 2 "arith_operand" "rI"))
5595 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5598 [(set_attr "type" "misc")])
5600 (define_insn "*addx_extend_sp32"
5601 [(set (match_operand:DI 0 "register_operand" "=r")
5602 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5603 (match_operand:SI 2 "arith_operand" "rI"))
5604 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5607 [(set_attr "length" "2")])
5610 [(set (match_operand:DI 0 "register_operand" "")
5611 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5612 (match_operand:SI 2 "arith_operand" ""))
5613 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5614 "! TARGET_ARCH64 && reload_completed"
5615 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5616 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5617 (set (match_dup 4) (const_int 0))]
5618 "operands[3] = gen_lowpart (SImode, operands[0]);
5619 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5621 (define_insn "*addx_extend_sp64"
5622 [(set (match_operand:DI 0 "register_operand" "=r")
5623 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5624 (match_operand:SI 2 "arith_operand" "rI"))
5625 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5627 "addx\\t%r1, %2, %0"
5628 [(set_attr "type" "misc")])
5631 [(set (match_operand:SI 0 "register_operand" "=r")
5632 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5633 (match_operand:SI 2 "arith_operand" "rI"))
5634 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5636 "subx\\t%r1, %2, %0"
5637 [(set_attr "type" "misc")])
5639 (define_insn "*subx_extend_sp64"
5640 [(set (match_operand:DI 0 "register_operand" "=r")
5641 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5642 (match_operand:SI 2 "arith_operand" "rI"))
5643 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5645 "subx\\t%r1, %2, %0"
5646 [(set_attr "type" "misc")])
5648 (define_insn "*subx_extend"
5649 [(set (match_operand:DI 0 "register_operand" "=r")
5650 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5651 (match_operand:SI 2 "arith_operand" "rI"))
5652 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5655 [(set_attr "length" "2")])
5658 [(set (match_operand:DI 0 "register_operand" "")
5659 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5660 (match_operand:SI 2 "arith_operand" ""))
5661 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5662 "! TARGET_ARCH64 && reload_completed"
5663 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5664 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5665 (set (match_dup 4) (const_int 0))]
5666 "operands[3] = gen_lowpart (SImode, operands[0]);
5667 operands[4] = gen_highpart (SImode, operands[0]);")
5670 [(set (match_operand:DI 0 "register_operand" "=r")
5671 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5672 (match_operand:DI 2 "register_operand" "r")))
5673 (clobber (reg:CC 100))]
5676 [(set_attr "length" "2")])
5679 [(set (match_operand:DI 0 "register_operand" "")
5680 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5681 (match_operand:DI 2 "register_operand" "")))
5682 (clobber (reg:CC 100))]
5683 "! TARGET_ARCH64 && reload_completed"
5684 [(parallel [(set (reg:CC_NOOV 100)
5685 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5687 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5689 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5690 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5691 "operands[3] = gen_lowpart (SImode, operands[2]);
5692 operands[4] = gen_highpart (SImode, operands[2]);
5693 operands[5] = gen_lowpart (SImode, operands[0]);
5694 operands[6] = gen_highpart (SImode, operands[0]);")
5696 (define_insn "*adddi3_sp64"
5697 [(set (match_operand:DI 0 "register_operand" "=r")
5698 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5699 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5703 (define_expand "addsi3"
5704 [(set (match_operand:SI 0 "register_operand" "=r,d")
5705 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5706 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5710 if (arith_4096_operand(operands[2], SImode))
5712 if (GET_CODE (operands[1]) == CONST_INT)
5713 emit_insn (gen_movsi (operands[0],
5714 GEN_INT (INTVAL (operands[1]) + 4096)));
5716 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5717 gen_rtx_MINUS (SImode, operands[1],
5723 (define_insn "*addsi3"
5724 [(set (match_operand:SI 0 "register_operand" "=r,d")
5725 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5726 (match_operand:SI 2 "arith_operand" "rI,d")))]
5730 fpadd32s\\t%1, %2, %0"
5731 [(set_attr "type" "*,fp")])
5733 (define_insn "*cmp_cc_plus"
5734 [(set (reg:CC_NOOV 100)
5735 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5736 (match_operand:SI 1 "arith_operand" "rI"))
5739 "addcc\\t%0, %1, %%g0"
5740 [(set_attr "type" "compare")])
5742 (define_insn "*cmp_ccx_plus"
5743 [(set (reg:CCX_NOOV 100)
5744 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5745 (match_operand:DI 1 "arith_double_operand" "rHI"))
5748 "addcc\\t%0, %1, %%g0"
5749 [(set_attr "type" "compare")])
5751 (define_insn "*cmp_cc_plus_set"
5752 [(set (reg:CC_NOOV 100)
5753 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5754 (match_operand:SI 2 "arith_operand" "rI"))
5756 (set (match_operand:SI 0 "register_operand" "=r")
5757 (plus:SI (match_dup 1) (match_dup 2)))]
5759 "addcc\\t%1, %2, %0"
5760 [(set_attr "type" "compare")])
5762 (define_insn "*cmp_ccx_plus_set"
5763 [(set (reg:CCX_NOOV 100)
5764 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5765 (match_operand:DI 2 "arith_double_operand" "rHI"))
5767 (set (match_operand:DI 0 "register_operand" "=r")
5768 (plus:DI (match_dup 1) (match_dup 2)))]
5770 "addcc\\t%1, %2, %0"
5771 [(set_attr "type" "compare")])
5773 (define_expand "subdi3"
5774 [(set (match_operand:DI 0 "register_operand" "=r")
5775 (minus:DI (match_operand:DI 1 "register_operand" "r")
5776 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5780 if (! TARGET_ARCH64)
5782 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5783 gen_rtx_SET (VOIDmode, operands[0],
5784 gen_rtx_MINUS (DImode, operands[1],
5786 gen_rtx_CLOBBER (VOIDmode,
5787 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5790 if (arith_double_4096_operand(operands[2], DImode))
5792 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5793 gen_rtx_PLUS (DImode, operands[1],
5799 (define_insn "*subdi3_sp32"
5800 [(set (match_operand:DI 0 "register_operand" "=r")
5801 (minus:DI (match_operand:DI 1 "register_operand" "r")
5802 (match_operand:DI 2 "arith_double_operand" "rHI")))
5803 (clobber (reg:CC 100))]
5806 [(set_attr "length" "2")])
5809 [(set (match_operand:DI 0 "register_operand" "")
5810 (minus:DI (match_operand:DI 1 "register_operand" "")
5811 (match_operand:DI 2 "arith_double_operand" "")))
5812 (clobber (reg:CC 100))]
5815 && (GET_CODE (operands[2]) == CONST_INT
5816 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5817 [(clobber (const_int 0))]
5822 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5823 lowp = gen_lowpart (SImode, operands[2]);
5824 if ((lowp == const0_rtx)
5825 && (operands[0] == operands[1]))
5827 emit_insn (gen_rtx_SET (VOIDmode,
5828 gen_highpart (SImode, operands[0]),
5829 gen_rtx_MINUS (SImode,
5830 gen_highpart_mode (SImode, DImode,
5836 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5837 gen_lowpart (SImode, operands[1]),
5839 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5840 gen_highpart_mode (SImode, DImode, operands[1]),
5847 [(set (match_operand:DI 0 "register_operand" "")
5848 (minus:DI (match_operand:DI 1 "register_operand" "")
5849 (match_operand:DI 2 "register_operand" "")))
5850 (clobber (reg:CC 100))]
5852 && reload_completed"
5853 [(clobber (const_int 0))]
5856 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5857 gen_lowpart (SImode, operands[1]),
5858 gen_lowpart (SImode, operands[2])));
5859 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5860 gen_highpart (SImode, operands[1]),
5861 gen_highpart (SImode, operands[2])));
5866 [(set (match_operand:DI 0 "register_operand" "=r")
5867 (minus:DI (match_operand:DI 1 "register_operand" "r")
5868 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5869 (clobber (reg:CC 100))]
5872 [(set_attr "length" "2")])
5875 [(set (match_operand:DI 0 "register_operand" "")
5876 (minus:DI (match_operand:DI 1 "register_operand" "")
5877 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5878 (clobber (reg:CC 100))]
5879 "! TARGET_ARCH64 && reload_completed"
5880 [(parallel [(set (reg:CC_NOOV 100)
5881 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5883 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5885 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5886 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5887 "operands[3] = gen_lowpart (SImode, operands[1]);
5888 operands[4] = gen_highpart (SImode, operands[1]);
5889 operands[5] = gen_lowpart (SImode, operands[0]);
5890 operands[6] = gen_highpart (SImode, operands[0]);")
5892 (define_insn "*subdi3_sp64"
5893 [(set (match_operand:DI 0 "register_operand" "=r")
5894 (minus:DI (match_operand:DI 1 "register_operand" "r")
5895 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5899 (define_expand "subsi3"
5900 [(set (match_operand:SI 0 "register_operand" "=r,d")
5901 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5902 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5906 if (arith_4096_operand(operands[2], SImode))
5908 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5909 gen_rtx_PLUS (SImode, operands[1],
5915 (define_insn "*subsi3"
5916 [(set (match_operand:SI 0 "register_operand" "=r,d")
5917 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5918 (match_operand:SI 2 "arith_operand" "rI,d")))]
5922 fpsub32s\\t%1, %2, %0"
5923 [(set_attr "type" "*,fp")])
5925 (define_insn "*cmp_minus_cc"
5926 [(set (reg:CC_NOOV 100)
5927 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5928 (match_operand:SI 1 "arith_operand" "rI"))
5931 "subcc\\t%r0, %1, %%g0"
5932 [(set_attr "type" "compare")])
5934 (define_insn "*cmp_minus_ccx"
5935 [(set (reg:CCX_NOOV 100)
5936 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5937 (match_operand:DI 1 "arith_double_operand" "rHI"))
5940 "subcc\\t%0, %1, %%g0"
5941 [(set_attr "type" "compare")])
5943 (define_insn "cmp_minus_cc_set"
5944 [(set (reg:CC_NOOV 100)
5945 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5946 (match_operand:SI 2 "arith_operand" "rI"))
5948 (set (match_operand:SI 0 "register_operand" "=r")
5949 (minus:SI (match_dup 1) (match_dup 2)))]
5951 "subcc\\t%r1, %2, %0"
5952 [(set_attr "type" "compare")])
5954 (define_insn "*cmp_minus_ccx_set"
5955 [(set (reg:CCX_NOOV 100)
5956 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5957 (match_operand:DI 2 "arith_double_operand" "rHI"))
5959 (set (match_operand:DI 0 "register_operand" "=r")
5960 (minus:DI (match_dup 1) (match_dup 2)))]
5962 "subcc\\t%1, %2, %0"
5963 [(set_attr "type" "compare")])
5965 ;; Integer Multiply/Divide.
5967 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5968 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5970 (define_insn "mulsi3"
5971 [(set (match_operand:SI 0 "register_operand" "=r")
5972 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5973 (match_operand:SI 2 "arith_operand" "rI")))]
5976 [(set_attr "type" "imul")])
5978 (define_expand "muldi3"
5979 [(set (match_operand:DI 0 "register_operand" "=r")
5980 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5981 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5982 "TARGET_ARCH64 || TARGET_V8PLUS"
5987 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5992 (define_insn "*muldi3_sp64"
5993 [(set (match_operand:DI 0 "register_operand" "=r")
5994 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5995 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5998 [(set_attr "type" "imul")])
6000 ;; V8plus wide multiply.
6002 (define_insn "muldi3_v8plus"
6003 [(set (match_operand:DI 0 "register_operand" "=r,h")
6004 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6005 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6006 (clobber (match_scratch:SI 3 "=&h,X"))
6007 (clobber (match_scratch:SI 4 "=&h,X"))]
6011 if (sparc_check_64 (operands[1], insn) <= 0)
6012 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6013 if (which_alternative == 1)
6014 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6015 if (GET_CODE (operands[2]) == CONST_INT)
6017 if (which_alternative == 1)
6018 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6020 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\";
6022 if (sparc_check_64 (operands[2], insn) <= 0)
6023 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6024 if (which_alternative == 1)
6025 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\";
6027 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\";
6029 [(set_attr "type" "multi")
6030 (set_attr "length" "9,8")])
6032 (define_insn "*cmp_mul_set"
6034 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6035 (match_operand:SI 2 "arith_operand" "rI"))
6037 (set (match_operand:SI 0 "register_operand" "=r")
6038 (mult:SI (match_dup 1) (match_dup 2)))]
6039 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6040 "smulcc\\t%1, %2, %0"
6041 [(set_attr "type" "imul")])
6043 (define_expand "mulsidi3"
6044 [(set (match_operand:DI 0 "register_operand" "")
6045 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6046 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6050 if (CONSTANT_P (operands[2]))
6053 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6056 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6062 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6067 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6068 ;; registers can hold 64 bit values in the V8plus environment.
6070 (define_insn "mulsidi3_v8plus"
6071 [(set (match_operand:DI 0 "register_operand" "=h,r")
6072 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6073 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6074 (clobber (match_scratch:SI 3 "=X,&h"))]
6077 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6078 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6079 [(set_attr "type" "multi")
6080 (set_attr "length" "2,3")])
6083 (define_insn "const_mulsidi3_v8plus"
6084 [(set (match_operand:DI 0 "register_operand" "=h,r")
6085 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6086 (match_operand:SI 2 "small_int" "I,I")))
6087 (clobber (match_scratch:SI 3 "=X,&h"))]
6090 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6091 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6092 [(set_attr "type" "multi")
6093 (set_attr "length" "2,3")])
6096 (define_insn "*mulsidi3_sp32"
6097 [(set (match_operand:DI 0 "register_operand" "=r")
6098 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6099 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6103 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6106 (if_then_else (eq_attr "isa" "sparclet")
6107 (const_string "imul") (const_string "multi")))
6108 (set (attr "length")
6109 (if_then_else (eq_attr "isa" "sparclet")
6110 (const_int 1) (const_int 2)))])
6112 (define_insn "*mulsidi3_sp64"
6113 [(set (match_operand:DI 0 "register_operand" "=r")
6114 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6115 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6116 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6118 [(set_attr "type" "imul")])
6120 ;; Extra pattern, because sign_extend of a constant isn't valid.
6123 (define_insn "const_mulsidi3_sp32"
6124 [(set (match_operand:DI 0 "register_operand" "=r")
6125 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6126 (match_operand:SI 2 "small_int" "I")))]
6130 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6133 (if_then_else (eq_attr "isa" "sparclet")
6134 (const_string "imul") (const_string "multi")))
6135 (set (attr "length")
6136 (if_then_else (eq_attr "isa" "sparclet")
6137 (const_int 1) (const_int 2)))])
6139 (define_insn "const_mulsidi3_sp64"
6140 [(set (match_operand:DI 0 "register_operand" "=r")
6141 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6142 (match_operand:SI 2 "small_int" "I")))]
6143 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6145 [(set_attr "type" "imul")])
6147 (define_expand "smulsi3_highpart"
6148 [(set (match_operand:SI 0 "register_operand" "")
6150 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6151 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6153 "TARGET_HARD_MUL && TARGET_ARCH32"
6156 if (CONSTANT_P (operands[2]))
6160 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6166 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6171 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6172 operands[2], GEN_INT (32)));
6178 (define_insn "smulsi3_highpart_v8plus"
6179 [(set (match_operand:SI 0 "register_operand" "=h,r")
6181 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6182 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6183 (match_operand:SI 3 "const_int_operand" "i,i"))))
6184 (clobber (match_scratch:SI 4 "=X,&h"))]
6187 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6188 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6189 [(set_attr "type" "multi")
6190 (set_attr "length" "2")])
6192 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6195 [(set (match_operand:SI 0 "register_operand" "=h,r")
6198 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6199 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6200 (match_operand:SI 3 "const_int_operand" "i,i"))
6202 (clobber (match_scratch:SI 4 "=X,&h"))]
6205 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6206 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6207 [(set_attr "type" "multi")
6208 (set_attr "length" "2")])
6211 (define_insn "const_smulsi3_highpart_v8plus"
6212 [(set (match_operand:SI 0 "register_operand" "=h,r")
6214 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6215 (match_operand 2 "small_int" "i,i"))
6216 (match_operand:SI 3 "const_int_operand" "i,i"))))
6217 (clobber (match_scratch:SI 4 "=X,&h"))]
6220 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6221 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6222 [(set_attr "type" "multi")
6223 (set_attr "length" "2")])
6226 (define_insn "*smulsi3_highpart_sp32"
6227 [(set (match_operand:SI 0 "register_operand" "=r")
6229 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6230 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6233 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6234 [(set_attr "type" "multi")
6235 (set_attr "length" "2")])
6238 (define_insn "const_smulsi3_highpart"
6239 [(set (match_operand:SI 0 "register_operand" "=r")
6241 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6242 (match_operand:SI 2 "register_operand" "r"))
6245 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6246 [(set_attr "type" "multi")
6247 (set_attr "length" "2")])
6249 (define_expand "umulsidi3"
6250 [(set (match_operand:DI 0 "register_operand" "")
6251 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6252 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6256 if (CONSTANT_P (operands[2]))
6259 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6262 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6268 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6274 (define_insn "umulsidi3_v8plus"
6275 [(set (match_operand:DI 0 "register_operand" "=h,r")
6276 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6277 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6278 (clobber (match_scratch:SI 3 "=X,&h"))]
6281 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6282 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6283 [(set_attr "type" "multi")
6284 (set_attr "length" "2,3")])
6287 (define_insn "*umulsidi3_sp32"
6288 [(set (match_operand:DI 0 "register_operand" "=r")
6289 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6290 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6294 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6297 (if_then_else (eq_attr "isa" "sparclet")
6298 (const_string "imul") (const_string "multi")))
6299 (set (attr "length")
6300 (if_then_else (eq_attr "isa" "sparclet")
6301 (const_int 1) (const_int 2)))])
6303 (define_insn "*umulsidi3_sp64"
6304 [(set (match_operand:DI 0 "register_operand" "=r")
6305 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6306 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6307 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6309 [(set_attr "type" "imul")])
6311 ;; Extra pattern, because sign_extend of a constant isn't valid.
6314 (define_insn "const_umulsidi3_sp32"
6315 [(set (match_operand:DI 0 "register_operand" "=r")
6316 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6317 (match_operand:SI 2 "uns_small_int" "")))]
6321 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6324 (if_then_else (eq_attr "isa" "sparclet")
6325 (const_string "imul") (const_string "multi")))
6326 (set (attr "length")
6327 (if_then_else (eq_attr "isa" "sparclet")
6328 (const_int 1) (const_int 2)))])
6330 (define_insn "const_umulsidi3_sp64"
6331 [(set (match_operand:DI 0 "register_operand" "=r")
6332 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6333 (match_operand:SI 2 "uns_small_int" "")))]
6334 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6336 [(set_attr "type" "imul")])
6339 (define_insn "const_umulsidi3_v8plus"
6340 [(set (match_operand:DI 0 "register_operand" "=h,r")
6341 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6342 (match_operand:SI 2 "uns_small_int" "")))
6343 (clobber (match_scratch:SI 3 "=X,h"))]
6346 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6347 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6348 [(set_attr "type" "multi")
6349 (set_attr "length" "2,3")])
6351 (define_expand "umulsi3_highpart"
6352 [(set (match_operand:SI 0 "register_operand" "")
6354 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6355 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6357 "TARGET_HARD_MUL && TARGET_ARCH32"
6360 if (CONSTANT_P (operands[2]))
6364 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6370 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6375 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6376 operands[2], GEN_INT (32)));
6382 (define_insn "umulsi3_highpart_v8plus"
6383 [(set (match_operand:SI 0 "register_operand" "=h,r")
6385 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6386 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6387 (match_operand:SI 3 "const_int_operand" "i,i"))))
6388 (clobber (match_scratch:SI 4 "=X,h"))]
6391 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6392 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6393 [(set_attr "type" "multi")
6394 (set_attr "length" "2")])
6397 (define_insn "const_umulsi3_highpart_v8plus"
6398 [(set (match_operand:SI 0 "register_operand" "=h,r")
6400 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6401 (match_operand:SI 2 "uns_small_int" ""))
6402 (match_operand:SI 3 "const_int_operand" "i,i"))))
6403 (clobber (match_scratch:SI 4 "=X,h"))]
6406 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6407 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6408 [(set_attr "type" "multi")
6409 (set_attr "length" "2")])
6412 (define_insn "*umulsi3_highpart_sp32"
6413 [(set (match_operand:SI 0 "register_operand" "=r")
6415 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6416 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6419 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6420 [(set_attr "type" "multi")
6421 (set_attr "length" "2")])
6424 (define_insn "const_umulsi3_highpart"
6425 [(set (match_operand:SI 0 "register_operand" "=r")
6427 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6428 (match_operand:SI 2 "uns_small_int" ""))
6431 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6432 [(set_attr "type" "multi")
6433 (set_attr "length" "2")])
6435 ;; The v8 architecture specifies that there must be 3 instructions between
6436 ;; a y register write and a use of it for correct results.
6438 (define_expand "divsi3"
6439 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6440 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6441 (match_operand:SI 2 "input_operand" "rI,m")))
6442 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6443 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6448 operands[3] = gen_reg_rtx(SImode);
6449 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6450 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6456 (define_insn "divsi3_sp32"
6457 [(set (match_operand:SI 0 "register_operand" "=r,r")
6458 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6459 (match_operand:SI 2 "input_operand" "rI,m")))
6460 (clobber (match_scratch:SI 3 "=&r,&r"))]
6461 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6465 if (which_alternative == 0)
6467 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6469 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6472 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6474 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\";
6476 [(set_attr "type" "multi")
6477 (set (attr "length")
6478 (if_then_else (eq_attr "isa" "v9")
6479 (const_int 4) (const_int 6)))])
6481 (define_insn "divsi3_sp64"
6482 [(set (match_operand:SI 0 "register_operand" "=r")
6483 (div:SI (match_operand:SI 1 "register_operand" "r")
6484 (match_operand:SI 2 "input_operand" "rI")))
6485 (use (match_operand:SI 3 "register_operand" "r"))]
6486 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6487 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6488 [(set_attr "type" "multi")
6489 (set_attr "length" "2")])
6491 (define_insn "divdi3"
6492 [(set (match_operand:DI 0 "register_operand" "=r")
6493 (div:DI (match_operand:DI 1 "register_operand" "r")
6494 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6496 "sdivx\\t%1, %2, %0"
6497 [(set_attr "type" "idiv")])
6499 (define_insn "*cmp_sdiv_cc_set"
6501 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6502 (match_operand:SI 2 "arith_operand" "rI"))
6504 (set (match_operand:SI 0 "register_operand" "=r")
6505 (div:SI (match_dup 1) (match_dup 2)))
6506 (clobber (match_scratch:SI 3 "=&r"))]
6507 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6511 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6513 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6515 [(set_attr "type" "multi")
6516 (set (attr "length")
6517 (if_then_else (eq_attr "isa" "v9")
6518 (const_int 3) (const_int 6)))])
6521 (define_expand "udivsi3"
6522 [(set (match_operand:SI 0 "register_operand" "")
6523 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6524 (match_operand:SI 2 "input_operand" "")))]
6525 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6528 (define_insn "udivsi3_sp32"
6529 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6530 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6531 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6533 || TARGET_DEPRECATED_V8_INSNS)
6537 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6538 switch (which_alternative)
6541 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6543 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6545 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6548 [(set_attr "type" "multi")
6549 (set_attr "length" "5")])
6551 (define_insn "udivsi3_sp64"
6552 [(set (match_operand:SI 0 "register_operand" "=r")
6553 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6554 (match_operand:SI 2 "input_operand" "rI")))]
6555 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6556 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6557 [(set_attr "type" "multi")
6558 (set_attr "length" "2")])
6560 (define_insn "udivdi3"
6561 [(set (match_operand:DI 0 "register_operand" "=r")
6562 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6563 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6565 "udivx\\t%1, %2, %0"
6566 [(set_attr "type" "idiv")])
6568 (define_insn "*cmp_udiv_cc_set"
6570 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6571 (match_operand:SI 2 "arith_operand" "rI"))
6573 (set (match_operand:SI 0 "register_operand" "=r")
6574 (udiv:SI (match_dup 1) (match_dup 2)))]
6576 || TARGET_DEPRECATED_V8_INSNS"
6580 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6582 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6584 [(set_attr "type" "multi")
6585 (set (attr "length")
6586 (if_then_else (eq_attr "isa" "v9")
6587 (const_int 2) (const_int 5)))])
6589 ; sparclet multiply/accumulate insns
6591 (define_insn "*smacsi"
6592 [(set (match_operand:SI 0 "register_operand" "=r")
6593 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6594 (match_operand:SI 2 "arith_operand" "rI"))
6595 (match_operand:SI 3 "register_operand" "0")))]
6598 [(set_attr "type" "imul")])
6600 (define_insn "*smacdi"
6601 [(set (match_operand:DI 0 "register_operand" "=r")
6602 (plus:DI (mult:DI (sign_extend:DI
6603 (match_operand:SI 1 "register_operand" "%r"))
6605 (match_operand:SI 2 "register_operand" "r")))
6606 (match_operand:DI 3 "register_operand" "0")))]
6608 "smacd\\t%1, %2, %L0"
6609 [(set_attr "type" "imul")])
6611 (define_insn "*umacdi"
6612 [(set (match_operand:DI 0 "register_operand" "=r")
6613 (plus:DI (mult:DI (zero_extend:DI
6614 (match_operand:SI 1 "register_operand" "%r"))
6616 (match_operand:SI 2 "register_operand" "r")))
6617 (match_operand:DI 3 "register_operand" "0")))]
6619 "umacd\\t%1, %2, %L0"
6620 [(set_attr "type" "imul")])
6622 ;;- Boolean instructions
6623 ;; We define DImode `and' so with DImode `not' we can get
6624 ;; DImode `andn'. Other combinations are possible.
6626 (define_expand "anddi3"
6627 [(set (match_operand:DI 0 "register_operand" "")
6628 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6629 (match_operand:DI 2 "arith_double_operand" "")))]
6633 (define_insn "*anddi3_sp32"
6634 [(set (match_operand:DI 0 "register_operand" "=r,b")
6635 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6636 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6641 [(set_attr "type" "*,fp")
6642 (set_attr "length" "2,*")
6643 (set_attr "fptype" "double")])
6645 (define_insn "*anddi3_sp64"
6646 [(set (match_operand:DI 0 "register_operand" "=r,b")
6647 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6648 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6653 [(set_attr "type" "*,fp")
6654 (set_attr "fptype" "double")])
6656 (define_insn "andsi3"
6657 [(set (match_operand:SI 0 "register_operand" "=r,d")
6658 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6659 (match_operand:SI 2 "arith_operand" "rI,d")))]
6664 [(set_attr "type" "*,fp")])
6667 [(set (match_operand:SI 0 "register_operand" "")
6668 (and:SI (match_operand:SI 1 "register_operand" "")
6669 (match_operand:SI 2 "" "")))
6670 (clobber (match_operand:SI 3 "register_operand" ""))]
6671 "GET_CODE (operands[2]) == CONST_INT
6672 && !SMALL_INT32 (operands[2])
6673 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6674 [(set (match_dup 3) (match_dup 4))
6675 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6678 operands[4] = GEN_INT (~INTVAL (operands[2]));
6681 ;; Split DImode logical operations requiring two instructions.
6683 [(set (match_operand:DI 0 "register_operand" "")
6684 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6685 [(match_operand:DI 2 "register_operand" "")
6686 (match_operand:DI 3 "arith_double_operand" "")]))]
6689 && ((GET_CODE (operands[0]) == REG
6690 && REGNO (operands[0]) < 32)
6691 || (GET_CODE (operands[0]) == SUBREG
6692 && GET_CODE (SUBREG_REG (operands[0])) == REG
6693 && REGNO (SUBREG_REG (operands[0])) < 32))"
6694 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6695 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6698 operands[4] = gen_highpart (SImode, operands[0]);
6699 operands[5] = gen_lowpart (SImode, operands[0]);
6700 operands[6] = gen_highpart (SImode, operands[2]);
6701 operands[7] = gen_lowpart (SImode, operands[2]);
6702 #if HOST_BITS_PER_WIDE_INT == 32
6703 if (GET_CODE (operands[3]) == CONST_INT)
6705 if (INTVAL (operands[3]) < 0)
6706 operands[8] = constm1_rtx;
6708 operands[8] = const0_rtx;
6712 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6713 operands[9] = gen_lowpart (SImode, operands[3]);
6716 (define_insn "*and_not_di_sp32"
6717 [(set (match_operand:DI 0 "register_operand" "=r,b")
6718 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6719 (match_operand:DI 2 "register_operand" "r,b")))]
6723 fandnot1\\t%1, %2, %0"
6724 [(set_attr "type" "*,fp")
6725 (set_attr "length" "2,*")
6726 (set_attr "fptype" "double")])
6729 [(set (match_operand:DI 0 "register_operand" "")
6730 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6731 (match_operand:DI 2 "register_operand" "")))]
6734 && ((GET_CODE (operands[0]) == REG
6735 && REGNO (operands[0]) < 32)
6736 || (GET_CODE (operands[0]) == SUBREG
6737 && GET_CODE (SUBREG_REG (operands[0])) == REG
6738 && REGNO (SUBREG_REG (operands[0])) < 32))"
6739 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6740 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6741 "operands[3] = gen_highpart (SImode, operands[0]);
6742 operands[4] = gen_highpart (SImode, operands[1]);
6743 operands[5] = gen_highpart (SImode, operands[2]);
6744 operands[6] = gen_lowpart (SImode, operands[0]);
6745 operands[7] = gen_lowpart (SImode, operands[1]);
6746 operands[8] = gen_lowpart (SImode, operands[2]);")
6748 (define_insn "*and_not_di_sp64"
6749 [(set (match_operand:DI 0 "register_operand" "=r,b")
6750 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6751 (match_operand:DI 2 "register_operand" "r,b")))]
6755 fandnot1\\t%1, %2, %0"
6756 [(set_attr "type" "*,fp")
6757 (set_attr "fptype" "double")])
6759 (define_insn "*and_not_si"
6760 [(set (match_operand:SI 0 "register_operand" "=r,d")
6761 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6762 (match_operand:SI 2 "register_operand" "r,d")))]
6766 fandnot1s\\t%1, %2, %0"
6767 [(set_attr "type" "*,fp")])
6769 (define_expand "iordi3"
6770 [(set (match_operand:DI 0 "register_operand" "")
6771 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6772 (match_operand:DI 2 "arith_double_operand" "")))]
6776 (define_insn "*iordi3_sp32"
6777 [(set (match_operand:DI 0 "register_operand" "=r,b")
6778 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6779 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6784 [(set_attr "type" "*,fp")
6785 (set_attr "length" "2,*")
6786 (set_attr "fptype" "double")])
6788 (define_insn "*iordi3_sp64"
6789 [(set (match_operand:DI 0 "register_operand" "=r,b")
6790 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6791 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6796 [(set_attr "type" "*,fp")
6797 (set_attr "fptype" "double")])
6799 (define_insn "iorsi3"
6800 [(set (match_operand:SI 0 "register_operand" "=r,d")
6801 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6802 (match_operand:SI 2 "arith_operand" "rI,d")))]
6807 [(set_attr "type" "*,fp")])
6810 [(set (match_operand:SI 0 "register_operand" "")
6811 (ior:SI (match_operand:SI 1 "register_operand" "")
6812 (match_operand:SI 2 "" "")))
6813 (clobber (match_operand:SI 3 "register_operand" ""))]
6814 "GET_CODE (operands[2]) == CONST_INT
6815 && !SMALL_INT32 (operands[2])
6816 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6817 [(set (match_dup 3) (match_dup 4))
6818 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6821 operands[4] = GEN_INT (~INTVAL (operands[2]));
6824 (define_insn "*or_not_di_sp32"
6825 [(set (match_operand:DI 0 "register_operand" "=r,b")
6826 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6827 (match_operand:DI 2 "register_operand" "r,b")))]
6831 fornot1\\t%1, %2, %0"
6832 [(set_attr "type" "*,fp")
6833 (set_attr "length" "2,*")
6834 (set_attr "fptype" "double")])
6837 [(set (match_operand:DI 0 "register_operand" "")
6838 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6839 (match_operand:DI 2 "register_operand" "")))]
6842 && ((GET_CODE (operands[0]) == REG
6843 && REGNO (operands[0]) < 32)
6844 || (GET_CODE (operands[0]) == SUBREG
6845 && GET_CODE (SUBREG_REG (operands[0])) == REG
6846 && REGNO (SUBREG_REG (operands[0])) < 32))"
6847 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6848 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6849 "operands[3] = gen_highpart (SImode, operands[0]);
6850 operands[4] = gen_highpart (SImode, operands[1]);
6851 operands[5] = gen_highpart (SImode, operands[2]);
6852 operands[6] = gen_lowpart (SImode, operands[0]);
6853 operands[7] = gen_lowpart (SImode, operands[1]);
6854 operands[8] = gen_lowpart (SImode, operands[2]);")
6856 (define_insn "*or_not_di_sp64"
6857 [(set (match_operand:DI 0 "register_operand" "=r,b")
6858 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6859 (match_operand:DI 2 "register_operand" "r,b")))]
6863 fornot1\\t%1, %2, %0"
6864 [(set_attr "type" "*,fp")
6865 (set_attr "fptype" "double")])
6867 (define_insn "*or_not_si"
6868 [(set (match_operand:SI 0 "register_operand" "=r,d")
6869 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6870 (match_operand:SI 2 "register_operand" "r,d")))]
6874 fornot1s\\t%1, %2, %0"
6875 [(set_attr "type" "*,fp")])
6877 (define_expand "xordi3"
6878 [(set (match_operand:DI 0 "register_operand" "")
6879 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6880 (match_operand:DI 2 "arith_double_operand" "")))]
6884 (define_insn "*xordi3_sp32"
6885 [(set (match_operand:DI 0 "register_operand" "=r,b")
6886 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6887 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6892 [(set_attr "type" "*,fp")
6893 (set_attr "length" "2,*")
6894 (set_attr "fptype" "double")])
6896 (define_insn "*xordi3_sp64"
6897 [(set (match_operand:DI 0 "register_operand" "=r,b")
6898 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6899 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6904 [(set_attr "type" "*,fp")
6905 (set_attr "fptype" "double")])
6907 (define_insn "*xordi3_sp64_dbl"
6908 [(set (match_operand:DI 0 "register_operand" "=r")
6909 (xor:DI (match_operand:DI 1 "register_operand" "r")
6910 (match_operand:DI 2 "const64_operand" "")))]
6912 && HOST_BITS_PER_WIDE_INT != 64)"
6915 (define_insn "xorsi3"
6916 [(set (match_operand:SI 0 "register_operand" "=r,d")
6917 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6918 (match_operand:SI 2 "arith_operand" "rI,d")))]
6923 [(set_attr "type" "*,fp")])
6926 [(set (match_operand:SI 0 "register_operand" "")
6927 (xor:SI (match_operand:SI 1 "register_operand" "")
6928 (match_operand:SI 2 "" "")))
6929 (clobber (match_operand:SI 3 "register_operand" ""))]
6930 "GET_CODE (operands[2]) == CONST_INT
6931 && !SMALL_INT32 (operands[2])
6932 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6933 [(set (match_dup 3) (match_dup 4))
6934 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6937 operands[4] = GEN_INT (~INTVAL (operands[2]));
6941 [(set (match_operand:SI 0 "register_operand" "")
6942 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6943 (match_operand:SI 2 "" ""))))
6944 (clobber (match_operand:SI 3 "register_operand" ""))]
6945 "GET_CODE (operands[2]) == CONST_INT
6946 && !SMALL_INT32 (operands[2])
6947 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6948 [(set (match_dup 3) (match_dup 4))
6949 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6952 operands[4] = GEN_INT (~INTVAL (operands[2]));
6955 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6956 ;; Combine now canonicalizes to the rightmost expression.
6957 (define_insn "*xor_not_di_sp32"
6958 [(set (match_operand:DI 0 "register_operand" "=r,b")
6959 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6960 (match_operand:DI 2 "register_operand" "r,b"))))]
6965 [(set_attr "type" "*,fp")
6966 (set_attr "length" "2,*")
6967 (set_attr "fptype" "double")])
6970 [(set (match_operand:DI 0 "register_operand" "")
6971 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6972 (match_operand:DI 2 "register_operand" ""))))]
6975 && ((GET_CODE (operands[0]) == REG
6976 && REGNO (operands[0]) < 32)
6977 || (GET_CODE (operands[0]) == SUBREG
6978 && GET_CODE (SUBREG_REG (operands[0])) == REG
6979 && REGNO (SUBREG_REG (operands[0])) < 32))"
6980 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6981 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6982 "operands[3] = gen_highpart (SImode, operands[0]);
6983 operands[4] = gen_highpart (SImode, operands[1]);
6984 operands[5] = gen_highpart (SImode, operands[2]);
6985 operands[6] = gen_lowpart (SImode, operands[0]);
6986 operands[7] = gen_lowpart (SImode, operands[1]);
6987 operands[8] = gen_lowpart (SImode, operands[2]);")
6989 (define_insn "*xor_not_di_sp64"
6990 [(set (match_operand:DI 0 "register_operand" "=r,b")
6991 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6992 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6997 [(set_attr "type" "*,fp")
6998 (set_attr "fptype" "double")])
7000 (define_insn "*xor_not_si"
7001 [(set (match_operand:SI 0 "register_operand" "=r,d")
7002 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7003 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7007 fxnors\\t%1, %2, %0"
7008 [(set_attr "type" "*,fp")])
7010 ;; These correspond to the above in the case where we also (or only)
7011 ;; want to set the condition code.
7013 (define_insn "*cmp_cc_arith_op"
7016 (match_operator:SI 2 "cc_arithop"
7017 [(match_operand:SI 0 "arith_operand" "%r")
7018 (match_operand:SI 1 "arith_operand" "rI")])
7021 "%A2cc\\t%0, %1, %%g0"
7022 [(set_attr "type" "compare")])
7024 (define_insn "*cmp_ccx_arith_op"
7027 (match_operator:DI 2 "cc_arithop"
7028 [(match_operand:DI 0 "arith_double_operand" "%r")
7029 (match_operand:DI 1 "arith_double_operand" "rHI")])
7032 "%A2cc\\t%0, %1, %%g0"
7033 [(set_attr "type" "compare")])
7035 (define_insn "*cmp_cc_arith_op_set"
7038 (match_operator:SI 3 "cc_arithop"
7039 [(match_operand:SI 1 "arith_operand" "%r")
7040 (match_operand:SI 2 "arith_operand" "rI")])
7042 (set (match_operand:SI 0 "register_operand" "=r")
7043 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7044 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7045 "%A3cc\\t%1, %2, %0"
7046 [(set_attr "type" "compare")])
7048 (define_insn "*cmp_ccx_arith_op_set"
7051 (match_operator:DI 3 "cc_arithop"
7052 [(match_operand:DI 1 "arith_double_operand" "%r")
7053 (match_operand:DI 2 "arith_double_operand" "rHI")])
7055 (set (match_operand:DI 0 "register_operand" "=r")
7056 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7057 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7058 "%A3cc\\t%1, %2, %0"
7059 [(set_attr "type" "compare")])
7061 (define_insn "*cmp_cc_xor_not"
7064 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7065 (match_operand:SI 1 "arith_operand" "rI")))
7068 "xnorcc\\t%r0, %1, %%g0"
7069 [(set_attr "type" "compare")])
7071 (define_insn "*cmp_ccx_xor_not"
7074 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7075 (match_operand:DI 1 "arith_double_operand" "rHI")))
7078 "xnorcc\\t%r0, %1, %%g0"
7079 [(set_attr "type" "compare")])
7081 (define_insn "*cmp_cc_xor_not_set"
7084 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7085 (match_operand:SI 2 "arith_operand" "rI")))
7087 (set (match_operand:SI 0 "register_operand" "=r")
7088 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7090 "xnorcc\\t%r1, %2, %0"
7091 [(set_attr "type" "compare")])
7093 (define_insn "*cmp_ccx_xor_not_set"
7096 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7097 (match_operand:DI 2 "arith_double_operand" "rHI")))
7099 (set (match_operand:DI 0 "register_operand" "=r")
7100 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7102 "xnorcc\\t%r1, %2, %0"
7103 [(set_attr "type" "compare")])
7105 (define_insn "*cmp_cc_arith_op_not"
7108 (match_operator:SI 2 "cc_arithopn"
7109 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7110 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7113 "%B2cc\\t%r1, %0, %%g0"
7114 [(set_attr "type" "compare")])
7116 (define_insn "*cmp_ccx_arith_op_not"
7119 (match_operator:DI 2 "cc_arithopn"
7120 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7121 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7124 "%B2cc\\t%r1, %0, %%g0"
7125 [(set_attr "type" "compare")])
7127 (define_insn "*cmp_cc_arith_op_not_set"
7130 (match_operator:SI 3 "cc_arithopn"
7131 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7132 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7134 (set (match_operand:SI 0 "register_operand" "=r")
7135 (match_operator:SI 4 "cc_arithopn"
7136 [(not:SI (match_dup 1)) (match_dup 2)]))]
7137 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7138 "%B3cc\\t%r2, %1, %0"
7139 [(set_attr "type" "compare")])
7141 (define_insn "*cmp_ccx_arith_op_not_set"
7144 (match_operator:DI 3 "cc_arithopn"
7145 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7146 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7148 (set (match_operand:DI 0 "register_operand" "=r")
7149 (match_operator:DI 4 "cc_arithopn"
7150 [(not:DI (match_dup 1)) (match_dup 2)]))]
7151 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7152 "%B3cc\\t%r2, %1, %0"
7153 [(set_attr "type" "compare")])
7155 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7156 ;; does not know how to make it work for constants.
7158 (define_expand "negdi2"
7159 [(set (match_operand:DI 0 "register_operand" "=r")
7160 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7164 if (! TARGET_ARCH64)
7166 emit_insn (gen_rtx_PARALLEL
7169 gen_rtx_SET (VOIDmode, operand0,
7170 gen_rtx_NEG (DImode, operand1)),
7171 gen_rtx_CLOBBER (VOIDmode,
7172 gen_rtx_REG (CCmode,
7178 (define_insn "*negdi2_sp32"
7179 [(set (match_operand:DI 0 "register_operand" "=r")
7180 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7181 (clobber (reg:CC 100))]
7184 [(set_attr "length" "2")])
7187 [(set (match_operand:DI 0 "register_operand" "")
7188 (neg:DI (match_operand:DI 1 "register_operand" "")))
7189 (clobber (reg:CC 100))]
7191 && reload_completed"
7192 [(parallel [(set (reg:CC_NOOV 100)
7193 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7195 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7196 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7197 (ltu:SI (reg:CC 100) (const_int 0))))]
7198 "operands[2] = gen_highpart (SImode, operands[0]);
7199 operands[3] = gen_highpart (SImode, operands[1]);
7200 operands[4] = gen_lowpart (SImode, operands[0]);
7201 operands[5] = gen_lowpart (SImode, operands[1]);")
7203 (define_insn "*negdi2_sp64"
7204 [(set (match_operand:DI 0 "register_operand" "=r")
7205 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7207 "sub\\t%%g0, %1, %0")
7209 (define_insn "negsi2"
7210 [(set (match_operand:SI 0 "register_operand" "=r")
7211 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7213 "sub\\t%%g0, %1, %0")
7215 (define_insn "*cmp_cc_neg"
7216 [(set (reg:CC_NOOV 100)
7217 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7220 "subcc\\t%%g0, %0, %%g0"
7221 [(set_attr "type" "compare")])
7223 (define_insn "*cmp_ccx_neg"
7224 [(set (reg:CCX_NOOV 100)
7225 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7228 "subcc\\t%%g0, %0, %%g0"
7229 [(set_attr "type" "compare")])
7231 (define_insn "*cmp_cc_set_neg"
7232 [(set (reg:CC_NOOV 100)
7233 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7235 (set (match_operand:SI 0 "register_operand" "=r")
7236 (neg:SI (match_dup 1)))]
7238 "subcc\\t%%g0, %1, %0"
7239 [(set_attr "type" "compare")])
7241 (define_insn "*cmp_ccx_set_neg"
7242 [(set (reg:CCX_NOOV 100)
7243 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7245 (set (match_operand:DI 0 "register_operand" "=r")
7246 (neg:DI (match_dup 1)))]
7248 "subcc\\t%%g0, %1, %0"
7249 [(set_attr "type" "compare")])
7251 ;; We cannot use the "not" pseudo insn because the Sun assembler
7252 ;; does not know how to make it work for constants.
7253 (define_expand "one_cmpldi2"
7254 [(set (match_operand:DI 0 "register_operand" "")
7255 (not:DI (match_operand:DI 1 "register_operand" "")))]
7259 (define_insn "*one_cmpldi2_sp32"
7260 [(set (match_operand:DI 0 "register_operand" "=r,b")
7261 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7266 [(set_attr "type" "*,fp")
7267 (set_attr "length" "2,*")
7268 (set_attr "fptype" "double")])
7271 [(set (match_operand:DI 0 "register_operand" "")
7272 (not:DI (match_operand:DI 1 "register_operand" "")))]
7275 && ((GET_CODE (operands[0]) == REG
7276 && REGNO (operands[0]) < 32)
7277 || (GET_CODE (operands[0]) == SUBREG
7278 && GET_CODE (SUBREG_REG (operands[0])) == REG
7279 && REGNO (SUBREG_REG (operands[0])) < 32))"
7280 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7281 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7282 "operands[2] = gen_highpart (SImode, operands[0]);
7283 operands[3] = gen_highpart (SImode, operands[1]);
7284 operands[4] = gen_lowpart (SImode, operands[0]);
7285 operands[5] = gen_lowpart (SImode, operands[1]);")
7287 (define_insn "*one_cmpldi2_sp64"
7288 [(set (match_operand:DI 0 "register_operand" "=r,b")
7289 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7294 [(set_attr "type" "*,fp")
7295 (set_attr "fptype" "double")])
7297 (define_insn "one_cmplsi2"
7298 [(set (match_operand:SI 0 "register_operand" "=r,d")
7299 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7304 [(set_attr "type" "*,fp")])
7306 (define_insn "*cmp_cc_not"
7308 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7311 "xnorcc\\t%%g0, %0, %%g0"
7312 [(set_attr "type" "compare")])
7314 (define_insn "*cmp_ccx_not"
7316 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7319 "xnorcc\\t%%g0, %0, %%g0"
7320 [(set_attr "type" "compare")])
7322 (define_insn "*cmp_cc_set_not"
7324 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7326 (set (match_operand:SI 0 "register_operand" "=r")
7327 (not:SI (match_dup 1)))]
7329 "xnorcc\\t%%g0, %1, %0"
7330 [(set_attr "type" "compare")])
7332 (define_insn "*cmp_ccx_set_not"
7334 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7336 (set (match_operand:DI 0 "register_operand" "=r")
7337 (not:DI (match_dup 1)))]
7339 "xnorcc\\t%%g0, %1, %0"
7340 [(set_attr "type" "compare")])
7342 (define_insn "*cmp_cc_set"
7343 [(set (match_operand:SI 0 "register_operand" "=r")
7344 (match_operand:SI 1 "register_operand" "r"))
7346 (compare:CC (match_dup 1)
7350 [(set_attr "type" "compare")])
7352 (define_insn "*cmp_ccx_set64"
7353 [(set (match_operand:DI 0 "register_operand" "=r")
7354 (match_operand:DI 1 "register_operand" "r"))
7356 (compare:CCX (match_dup 1)
7360 [(set_attr "type" "compare")])
7362 ;; Floating point arithmetic instructions.
7364 (define_expand "addtf3"
7365 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7366 (plus:TF (match_operand:TF 1 "general_operand" "")
7367 (match_operand:TF 2 "general_operand" "")))]
7368 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7371 if (! TARGET_HARD_QUAD)
7373 rtx slot0, slot1, slot2;
7375 if (GET_CODE (operands[0]) != MEM)
7376 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7378 slot0 = operands[0];
7379 if (GET_CODE (operands[1]) != MEM)
7381 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7382 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7385 slot1 = operands[1];
7386 if (GET_CODE (operands[2]) != MEM)
7388 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7389 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7392 slot2 = operands[2];
7394 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7396 XEXP (slot0, 0), Pmode,
7397 XEXP (slot1, 0), Pmode,
7398 XEXP (slot2, 0), Pmode);
7400 if (GET_CODE (operands[0]) != MEM)
7401 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7406 (define_insn "*addtf3_hq"
7407 [(set (match_operand:TF 0 "register_operand" "=e")
7408 (plus:TF (match_operand:TF 1 "register_operand" "e")
7409 (match_operand:TF 2 "register_operand" "e")))]
7410 "TARGET_FPU && TARGET_HARD_QUAD"
7411 "faddq\\t%1, %2, %0"
7412 [(set_attr "type" "fp")])
7414 (define_insn "adddf3"
7415 [(set (match_operand:DF 0 "register_operand" "=e")
7416 (plus:DF (match_operand:DF 1 "register_operand" "e")
7417 (match_operand:DF 2 "register_operand" "e")))]
7419 "faddd\\t%1, %2, %0"
7420 [(set_attr "type" "fp")
7421 (set_attr "fptype" "double")])
7423 (define_insn "addsf3"
7424 [(set (match_operand:SF 0 "register_operand" "=f")
7425 (plus:SF (match_operand:SF 1 "register_operand" "f")
7426 (match_operand:SF 2 "register_operand" "f")))]
7428 "fadds\\t%1, %2, %0"
7429 [(set_attr "type" "fp")])
7431 (define_expand "subtf3"
7432 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7433 (minus:TF (match_operand:TF 1 "general_operand" "")
7434 (match_operand:TF 2 "general_operand" "")))]
7435 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7438 if (! TARGET_HARD_QUAD)
7440 rtx slot0, slot1, slot2;
7442 if (GET_CODE (operands[0]) != MEM)
7443 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7445 slot0 = operands[0];
7446 if (GET_CODE (operands[1]) != MEM)
7448 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7449 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7452 slot1 = operands[1];
7453 if (GET_CODE (operands[2]) != MEM)
7455 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7456 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7459 slot2 = operands[2];
7461 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7463 XEXP (slot0, 0), Pmode,
7464 XEXP (slot1, 0), Pmode,
7465 XEXP (slot2, 0), Pmode);
7467 if (GET_CODE (operands[0]) != MEM)
7468 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7473 (define_insn "*subtf3_hq"
7474 [(set (match_operand:TF 0 "register_operand" "=e")
7475 (minus:TF (match_operand:TF 1 "register_operand" "e")
7476 (match_operand:TF 2 "register_operand" "e")))]
7477 "TARGET_FPU && TARGET_HARD_QUAD"
7478 "fsubq\\t%1, %2, %0"
7479 [(set_attr "type" "fp")])
7481 (define_insn "subdf3"
7482 [(set (match_operand:DF 0 "register_operand" "=e")
7483 (minus:DF (match_operand:DF 1 "register_operand" "e")
7484 (match_operand:DF 2 "register_operand" "e")))]
7486 "fsubd\\t%1, %2, %0"
7487 [(set_attr "type" "fp")
7488 (set_attr "fptype" "double")])
7490 (define_insn "subsf3"
7491 [(set (match_operand:SF 0 "register_operand" "=f")
7492 (minus:SF (match_operand:SF 1 "register_operand" "f")
7493 (match_operand:SF 2 "register_operand" "f")))]
7495 "fsubs\\t%1, %2, %0"
7496 [(set_attr "type" "fp")])
7498 (define_expand "multf3"
7499 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7500 (mult:TF (match_operand:TF 1 "general_operand" "")
7501 (match_operand:TF 2 "general_operand" "")))]
7502 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7505 if (! TARGET_HARD_QUAD)
7507 rtx slot0, slot1, slot2;
7509 if (GET_CODE (operands[0]) != MEM)
7510 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7512 slot0 = operands[0];
7513 if (GET_CODE (operands[1]) != MEM)
7515 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7516 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7519 slot1 = operands[1];
7520 if (GET_CODE (operands[2]) != MEM)
7522 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7523 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7526 slot2 = operands[2];
7528 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7530 XEXP (slot0, 0), Pmode,
7531 XEXP (slot1, 0), Pmode,
7532 XEXP (slot2, 0), Pmode);
7534 if (GET_CODE (operands[0]) != MEM)
7535 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7540 (define_insn "*multf3_hq"
7541 [(set (match_operand:TF 0 "register_operand" "=e")
7542 (mult:TF (match_operand:TF 1 "register_operand" "e")
7543 (match_operand:TF 2 "register_operand" "e")))]
7544 "TARGET_FPU && TARGET_HARD_QUAD"
7545 "fmulq\\t%1, %2, %0"
7546 [(set_attr "type" "fpmul")])
7548 (define_insn "muldf3"
7549 [(set (match_operand:DF 0 "register_operand" "=e")
7550 (mult:DF (match_operand:DF 1 "register_operand" "e")
7551 (match_operand:DF 2 "register_operand" "e")))]
7553 "fmuld\\t%1, %2, %0"
7554 [(set_attr "type" "fpmul")
7555 (set_attr "fptype" "double")])
7557 (define_insn "mulsf3"
7558 [(set (match_operand:SF 0 "register_operand" "=f")
7559 (mult:SF (match_operand:SF 1 "register_operand" "f")
7560 (match_operand:SF 2 "register_operand" "f")))]
7562 "fmuls\\t%1, %2, %0"
7563 [(set_attr "type" "fpmul")])
7565 (define_insn "*muldf3_extend"
7566 [(set (match_operand:DF 0 "register_operand" "=e")
7567 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7568 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7569 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7570 "fsmuld\\t%1, %2, %0"
7571 [(set_attr "type" "fpmul")
7572 (set_attr "fptype" "double")])
7574 (define_insn "*multf3_extend"
7575 [(set (match_operand:TF 0 "register_operand" "=e")
7576 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7577 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7578 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7579 "fdmulq\\t%1, %2, %0"
7580 [(set_attr "type" "fpmul")])
7582 (define_expand "divtf3"
7583 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7584 (div:TF (match_operand:TF 1 "general_operand" "")
7585 (match_operand:TF 2 "general_operand" "")))]
7586 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7589 if (! TARGET_HARD_QUAD)
7591 rtx slot0, slot1, slot2;
7593 if (GET_CODE (operands[0]) != MEM)
7594 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7596 slot0 = operands[0];
7597 if (GET_CODE (operands[1]) != MEM)
7599 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7600 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7603 slot1 = operands[1];
7604 if (GET_CODE (operands[2]) != MEM)
7606 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7607 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7610 slot2 = operands[2];
7612 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7614 XEXP (slot0, 0), Pmode,
7615 XEXP (slot1, 0), Pmode,
7616 XEXP (slot2, 0), Pmode);
7618 if (GET_CODE (operands[0]) != MEM)
7619 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7624 ;; don't have timing for quad-prec. divide.
7625 (define_insn "*divtf3_hq"
7626 [(set (match_operand:TF 0 "register_operand" "=e")
7627 (div:TF (match_operand:TF 1 "register_operand" "e")
7628 (match_operand:TF 2 "register_operand" "e")))]
7629 "TARGET_FPU && TARGET_HARD_QUAD"
7630 "fdivq\\t%1, %2, %0"
7631 [(set_attr "type" "fpdivd")])
7633 (define_insn "divdf3"
7634 [(set (match_operand:DF 0 "register_operand" "=e")
7635 (div:DF (match_operand:DF 1 "register_operand" "e")
7636 (match_operand:DF 2 "register_operand" "e")))]
7638 "fdivd\\t%1, %2, %0"
7639 [(set_attr "type" "fpdivd")
7640 (set_attr "fptype" "double")])
7642 (define_insn "divsf3"
7643 [(set (match_operand:SF 0 "register_operand" "=f")
7644 (div:SF (match_operand:SF 1 "register_operand" "f")
7645 (match_operand:SF 2 "register_operand" "f")))]
7647 "fdivs\\t%1, %2, %0"
7648 [(set_attr "type" "fpdivs")])
7650 (define_expand "negtf2"
7651 [(set (match_operand:TF 0 "register_operand" "=e,e")
7652 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7656 (define_insn "*negtf2_notv9"
7657 [(set (match_operand:TF 0 "register_operand" "=e,e")
7658 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7659 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7665 [(set_attr "type" "fpmove,*")
7666 (set_attr "length" "*,2")])
7669 [(set (match_operand:TF 0 "register_operand" "")
7670 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7674 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7675 [(set (match_dup 2) (neg:SF (match_dup 3)))
7676 (set (match_dup 4) (match_dup 5))
7677 (set (match_dup 6) (match_dup 7))]
7678 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7679 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7680 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7681 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7682 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7683 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7685 (define_insn "*negtf2_v9"
7686 [(set (match_operand:TF 0 "register_operand" "=e,e")
7687 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7688 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7689 "TARGET_FPU && TARGET_V9"
7693 [(set_attr "type" "fpmove,*")
7694 (set_attr "length" "*,2")
7695 (set_attr "fptype" "double")])
7698 [(set (match_operand:TF 0 "register_operand" "")
7699 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7703 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7704 [(set (match_dup 2) (neg:DF (match_dup 3)))
7705 (set (match_dup 4) (match_dup 5))]
7706 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7707 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7708 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7709 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7711 (define_expand "negdf2"
7712 [(set (match_operand:DF 0 "register_operand" "")
7713 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7717 (define_insn "*negdf2_notv9"
7718 [(set (match_operand:DF 0 "register_operand" "=e,e")
7719 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7720 "TARGET_FPU && ! TARGET_V9"
7724 [(set_attr "type" "fpmove,*")
7725 (set_attr "length" "*,2")])
7728 [(set (match_operand:DF 0 "register_operand" "")
7729 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7733 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7734 [(set (match_dup 2) (neg:SF (match_dup 3)))
7735 (set (match_dup 4) (match_dup 5))]
7736 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7737 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7738 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7739 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7741 (define_insn "*negdf2_v9"
7742 [(set (match_operand:DF 0 "register_operand" "=e")
7743 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7744 "TARGET_FPU && TARGET_V9"
7746 [(set_attr "type" "fpmove")
7747 (set_attr "fptype" "double")])
7749 (define_insn "negsf2"
7750 [(set (match_operand:SF 0 "register_operand" "=f")
7751 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7754 [(set_attr "type" "fpmove")])
7756 (define_expand "abstf2"
7757 [(set (match_operand:TF 0 "register_operand" "")
7758 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7762 (define_insn "*abstf2_notv9"
7763 [(set (match_operand:TF 0 "register_operand" "=e,e")
7764 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7765 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7766 "TARGET_FPU && ! TARGET_V9"
7770 [(set_attr "type" "fpmove,*")
7771 (set_attr "length" "*,2")])
7774 [(set (match_operand:TF 0 "register_operand" "")
7775 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7779 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7780 [(set (match_dup 2) (abs:SF (match_dup 3)))
7781 (set (match_dup 4) (match_dup 5))
7782 (set (match_dup 6) (match_dup 7))]
7783 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7784 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7785 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7786 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7787 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7788 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7790 (define_insn "*abstf2_hq_v9"
7791 [(set (match_operand:TF 0 "register_operand" "=e,e")
7792 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7793 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7797 [(set_attr "type" "fpmove")
7798 (set_attr "fptype" "double,*")])
7800 (define_insn "*abstf2_v9"
7801 [(set (match_operand:TF 0 "register_operand" "=e,e")
7802 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7803 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7807 [(set_attr "type" "fpmove,*")
7808 (set_attr "length" "*,2")
7809 (set_attr "fptype" "double,*")])
7812 [(set (match_operand:TF 0 "register_operand" "")
7813 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7817 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7818 [(set (match_dup 2) (abs:DF (match_dup 3)))
7819 (set (match_dup 4) (match_dup 5))]
7820 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7821 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7822 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7823 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7825 (define_expand "absdf2"
7826 [(set (match_operand:DF 0 "register_operand" "")
7827 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7831 (define_insn "*absdf2_notv9"
7832 [(set (match_operand:DF 0 "register_operand" "=e,e")
7833 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7834 "TARGET_FPU && ! TARGET_V9"
7838 [(set_attr "type" "fpmove,*")
7839 (set_attr "length" "*,2")])
7842 [(set (match_operand:DF 0 "register_operand" "")
7843 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7847 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7848 [(set (match_dup 2) (abs:SF (match_dup 3)))
7849 (set (match_dup 4) (match_dup 5))]
7850 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7851 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7852 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7853 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7855 (define_insn "*absdf2_v9"
7856 [(set (match_operand:DF 0 "register_operand" "=e")
7857 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7858 "TARGET_FPU && TARGET_V9"
7860 [(set_attr "type" "fpmove")
7861 (set_attr "fptype" "double")])
7863 (define_insn "abssf2"
7864 [(set (match_operand:SF 0 "register_operand" "=f")
7865 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7868 [(set_attr "type" "fpmove")])
7870 (define_expand "sqrttf2"
7871 [(set (match_operand:TF 0 "register_operand" "=e")
7872 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7873 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7876 if (! TARGET_HARD_QUAD)
7880 if (GET_CODE (operands[0]) != MEM)
7881 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7883 slot0 = operands[0];
7884 if (GET_CODE (operands[1]) != MEM)
7886 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7887 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7890 slot1 = operands[1];
7892 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7894 XEXP (slot0, 0), Pmode,
7895 XEXP (slot1, 0), Pmode);
7897 if (GET_CODE (operands[0]) != MEM)
7898 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7903 (define_insn "*sqrttf2_hq"
7904 [(set (match_operand:TF 0 "register_operand" "=e")
7905 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7906 "TARGET_FPU && TARGET_HARD_QUAD"
7908 [(set_attr "type" "fpsqrtd")])
7910 (define_insn "sqrtdf2"
7911 [(set (match_operand:DF 0 "register_operand" "=e")
7912 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7915 [(set_attr "type" "fpsqrtd")
7916 (set_attr "fptype" "double")])
7918 (define_insn "sqrtsf2"
7919 [(set (match_operand:SF 0 "register_operand" "=f")
7920 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7923 [(set_attr "type" "fpsqrts")])
7925 ;;- arithmetic shift instructions
7927 (define_insn "ashlsi3"
7928 [(set (match_operand:SI 0 "register_operand" "=r")
7929 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7930 (match_operand:SI 2 "arith_operand" "rI")))]
7934 if (GET_CODE (operands[2]) == CONST_INT
7935 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7936 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7938 return \"sll\\t%1, %2, %0\";
7940 [(set_attr "type" "shift")])
7942 ;; We special case multiplication by two, as add can be done
7943 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7944 (define_insn "*ashlsi3_const1"
7945 [(set (match_operand:SI 0 "register_operand" "=r")
7946 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7951 (define_expand "ashldi3"
7952 [(set (match_operand:DI 0 "register_operand" "=r")
7953 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7954 (match_operand:SI 2 "arith_operand" "rI")))]
7955 "TARGET_ARCH64 || TARGET_V8PLUS"
7958 if (! TARGET_ARCH64)
7960 if (GET_CODE (operands[2]) == CONST_INT)
7962 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7967 ;; We special case multiplication by two, as add can be done
7968 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7969 (define_insn "*ashldi3_const1"
7970 [(set (match_operand:DI 0 "register_operand" "=r")
7971 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7976 (define_insn "*ashldi3_sp64"
7977 [(set (match_operand:DI 0 "register_operand" "=r")
7978 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7979 (match_operand:SI 2 "arith_operand" "rI")))]
7983 if (GET_CODE (operands[2]) == CONST_INT
7984 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7985 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7987 return \"sllx\\t%1, %2, %0\";
7989 [(set_attr "type" "shift")])
7992 (define_insn "ashldi3_v8plus"
7993 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7994 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7995 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7996 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7998 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7999 [(set_attr "type" "multi")
8000 (set_attr "length" "5,5,6")])
8002 ;; Optimize (1LL<<x)-1
8003 ;; XXX this also needs to be fixed to handle equal subregs
8004 ;; XXX first before we could re-enable it.
8006 ; [(set (match_operand:DI 0 "register_operand" "=h")
8007 ; (plus:DI (ashift:DI (const_int 1)
8008 ; (match_operand:SI 1 "arith_operand" "rI"))
8010 ; "0 && TARGET_V8PLUS"
8013 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8014 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8015 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8017 ; [(set_attr "type" "multi")
8018 ; (set_attr "length" "4")])
8020 (define_insn "*cmp_cc_ashift_1"
8021 [(set (reg:CC_NOOV 100)
8022 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8026 "addcc\\t%0, %0, %%g0"
8027 [(set_attr "type" "compare")])
8029 (define_insn "*cmp_cc_set_ashift_1"
8030 [(set (reg:CC_NOOV 100)
8031 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8034 (set (match_operand:SI 0 "register_operand" "=r")
8035 (ashift:SI (match_dup 1) (const_int 1)))]
8037 "addcc\\t%1, %1, %0"
8038 [(set_attr "type" "compare")])
8040 (define_insn "ashrsi3"
8041 [(set (match_operand:SI 0 "register_operand" "=r")
8042 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8043 (match_operand:SI 2 "arith_operand" "rI")))]
8047 if (GET_CODE (operands[2]) == CONST_INT
8048 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8049 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8051 return \"sra\\t%1, %2, %0\";
8053 [(set_attr "type" "shift")])
8055 (define_insn "*ashrsi3_extend"
8056 [(set (match_operand:DI 0 "register_operand" "=r")
8057 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8058 (match_operand:SI 2 "arith_operand" "r"))))]
8061 [(set_attr "type" "shift")])
8063 ;; This handles the case as above, but with constant shift instead of
8064 ;; register. Combiner "simplifies" it for us a little bit though.
8065 (define_insn "*ashrsi3_extend2"
8066 [(set (match_operand:DI 0 "register_operand" "=r")
8067 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8069 (match_operand:SI 2 "small_int_or_double" "n")))]
8071 && ((GET_CODE (operands[2]) == CONST_INT
8072 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8073 || (GET_CODE (operands[2]) == CONST_DOUBLE
8074 && !CONST_DOUBLE_HIGH (operands[2])
8075 && CONST_DOUBLE_LOW (operands[2]) >= 32
8076 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8079 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8081 return \"sra\\t%1, %2, %0\";
8083 [(set_attr "type" "shift")])
8085 (define_expand "ashrdi3"
8086 [(set (match_operand:DI 0 "register_operand" "=r")
8087 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8088 (match_operand:SI 2 "arith_operand" "rI")))]
8089 "TARGET_ARCH64 || TARGET_V8PLUS"
8092 if (! TARGET_ARCH64)
8094 if (GET_CODE (operands[2]) == CONST_INT)
8095 FAIL; /* prefer generic code in this case */
8096 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8102 [(set (match_operand:DI 0 "register_operand" "=r")
8103 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8104 (match_operand:SI 2 "arith_operand" "rI")))]
8108 if (GET_CODE (operands[2]) == CONST_INT
8109 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8110 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8112 return \"srax\\t%1, %2, %0\";
8114 [(set_attr "type" "shift")])
8117 (define_insn "ashrdi3_v8plus"
8118 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8119 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8120 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8121 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8123 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8124 [(set_attr "type" "multi")
8125 (set_attr "length" "5,5,6")])
8127 (define_insn "lshrsi3"
8128 [(set (match_operand:SI 0 "register_operand" "=r")
8129 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8130 (match_operand:SI 2 "arith_operand" "rI")))]
8134 if (GET_CODE (operands[2]) == CONST_INT
8135 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8136 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8138 return \"srl\\t%1, %2, %0\";
8140 [(set_attr "type" "shift")])
8142 ;; This handles the case where
8143 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8144 ;; but combiner "simplifies" it for us.
8145 (define_insn "*lshrsi3_extend"
8146 [(set (match_operand:DI 0 "register_operand" "=r")
8147 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8148 (match_operand:SI 2 "arith_operand" "r")) 0)
8149 (match_operand 3 "" "")))]
8151 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8152 && CONST_DOUBLE_HIGH (operands[3]) == 0
8153 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8154 || (HOST_BITS_PER_WIDE_INT >= 64
8155 && GET_CODE (operands[3]) == CONST_INT
8156 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8158 [(set_attr "type" "shift")])
8160 ;; This handles the case where
8161 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8162 ;; but combiner "simplifies" it for us.
8163 (define_insn "*lshrsi3_extend2"
8164 [(set (match_operand:DI 0 "register_operand" "=r")
8165 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8166 (match_operand 2 "small_int_or_double" "n")
8169 && ((GET_CODE (operands[2]) == CONST_INT
8170 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8171 || (GET_CODE (operands[2]) == CONST_DOUBLE
8172 && CONST_DOUBLE_HIGH (operands[2]) == 0
8173 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8176 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8178 return \"srl\\t%1, %2, %0\";
8180 [(set_attr "type" "shift")])
8182 (define_expand "lshrdi3"
8183 [(set (match_operand:DI 0 "register_operand" "=r")
8184 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8185 (match_operand:SI 2 "arith_operand" "rI")))]
8186 "TARGET_ARCH64 || TARGET_V8PLUS"
8189 if (! TARGET_ARCH64)
8191 if (GET_CODE (operands[2]) == CONST_INT)
8193 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8199 [(set (match_operand:DI 0 "register_operand" "=r")
8200 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8201 (match_operand:SI 2 "arith_operand" "rI")))]
8205 if (GET_CODE (operands[2]) == CONST_INT
8206 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8207 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8209 return \"srlx\\t%1, %2, %0\";
8211 [(set_attr "type" "shift")])
8214 (define_insn "lshrdi3_v8plus"
8215 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8216 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8217 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8218 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8220 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8221 [(set_attr "type" "multi")
8222 (set_attr "length" "5,5,6")])
8225 [(set (match_operand:SI 0 "register_operand" "=r")
8226 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8228 (match_operand:SI 2 "small_int_or_double" "n")))]
8230 && ((GET_CODE (operands[2]) == CONST_INT
8231 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8232 || (GET_CODE (operands[2]) == CONST_DOUBLE
8233 && !CONST_DOUBLE_HIGH (operands[2])
8234 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8237 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8239 return \"srax\\t%1, %2, %0\";
8241 [(set_attr "type" "shift")])
8244 [(set (match_operand:SI 0 "register_operand" "=r")
8245 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8247 (match_operand:SI 2 "small_int_or_double" "n")))]
8249 && ((GET_CODE (operands[2]) == CONST_INT
8250 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8251 || (GET_CODE (operands[2]) == CONST_DOUBLE
8252 && !CONST_DOUBLE_HIGH (operands[2])
8253 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8256 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8258 return \"srlx\\t%1, %2, %0\";
8260 [(set_attr "type" "shift")])
8263 [(set (match_operand:SI 0 "register_operand" "=r")
8264 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8265 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8266 (match_operand:SI 3 "small_int_or_double" "n")))]
8268 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8269 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8270 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8271 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8274 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8276 return \"srax\\t%1, %2, %0\";
8278 [(set_attr "type" "shift")])
8281 [(set (match_operand:SI 0 "register_operand" "=r")
8282 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8283 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8284 (match_operand:SI 3 "small_int_or_double" "n")))]
8286 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8287 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8288 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8289 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8292 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8294 return \"srlx\\t%1, %2, %0\";
8296 [(set_attr "type" "shift")])
8298 ;; Unconditional and other jump instructions
8299 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8300 ;; following insn is never executed. This saves us a nop. Dbx does not
8301 ;; handle such branches though, so we only use them when optimizing.
8303 [(set (pc) (label_ref (match_operand 0 "" "")))]
8307 /* TurboSparc is reported to have problems with
8310 i.e. an empty loop with the annul bit set. The workaround is to use
8314 if (! TARGET_V9 && flag_delayed_branch
8315 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8316 == INSN_ADDRESSES (INSN_UID (insn))))
8317 return \"b\\t%l0%#\";
8319 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8321 [(set_attr "type" "uncond_branch")])
8323 (define_expand "tablejump"
8324 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8325 (use (label_ref (match_operand 1 "" "")))])]
8329 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8332 /* In pic mode, our address differences are against the base of the
8333 table. Add that base value back in; CSE ought to be able to combine
8334 the two address loads. */
8338 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8340 if (CASE_VECTOR_MODE != Pmode)
8341 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8342 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8343 operands[0] = memory_address (Pmode, tmp);
8347 (define_insn "*tablejump_sp32"
8348 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8349 (use (label_ref (match_operand 1 "" "")))]
8352 [(set_attr "type" "uncond_branch")])
8354 (define_insn "*tablejump_sp64"
8355 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8356 (use (label_ref (match_operand 1 "" "")))]
8359 [(set_attr "type" "uncond_branch")])
8361 ;; This pattern recognizes the "instruction" that appears in
8362 ;; a function call that wants a structure value,
8363 ;; to inform the called function if compiled with Sun CC.
8364 ;(define_insn "*unimp_insn"
8365 ; [(match_operand:SI 0 "immediate_operand" "")]
8366 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8368 ; [(set_attr "type" "marker")])
8370 ;;- jump to subroutine
8371 (define_expand "call"
8372 ;; Note that this expression is not used for generating RTL.
8373 ;; All the RTL is generated explicitly below.
8374 [(call (match_operand 0 "call_operand" "")
8375 (match_operand 3 "" "i"))]
8376 ;; operands[2] is next_arg_register
8377 ;; operands[3] is struct_value_size_rtx.
8381 rtx fn_rtx, nregs_rtx;
8383 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8386 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8388 /* This is really a PIC sequence. We want to represent
8389 it as a funny jump so its delay slots can be filled.
8391 ??? But if this really *is* a CALL, will not it clobber the
8392 call-clobbered registers? We lose this if it is a JUMP_INSN.
8393 Why cannot we have delay slots filled if it were a CALL? */
8395 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8400 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8402 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8408 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8409 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8413 fn_rtx = operands[0];
8415 /* Count the number of parameter registers being used by this call.
8416 if that argument is NULL, it means we are using them all, which
8417 means 6 on the sparc. */
8420 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8422 nregs_rtx = GEN_INT (6);
8424 nregs_rtx = const0_rtx;
8427 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8431 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8433 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8438 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8439 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8443 /* If this call wants a structure value,
8444 emit an unimp insn to let the called function know about this. */
8445 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8447 rtx insn = emit_insn (operands[3]);
8448 SCHED_GROUP_P (insn) = 1;
8455 ;; We can't use the same pattern for these two insns, because then registers
8456 ;; in the address may not be properly reloaded.
8458 (define_insn "*call_address_sp32"
8459 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8460 (match_operand 1 "" ""))
8461 (clobber (reg:SI 15))]
8462 ;;- Do not use operand 1 for most machines.
8465 [(set_attr "type" "call")])
8467 (define_insn "*call_symbolic_sp32"
8468 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8469 (match_operand 1 "" ""))
8470 (clobber (reg:SI 15))]
8471 ;;- Do not use operand 1 for most machines.
8474 [(set_attr "type" "call")])
8476 (define_insn "*call_address_sp64"
8477 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8478 (match_operand 1 "" ""))
8479 (clobber (reg:DI 15))]
8480 ;;- Do not use operand 1 for most machines.
8483 [(set_attr "type" "call")])
8485 (define_insn "*call_symbolic_sp64"
8486 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8487 (match_operand 1 "" ""))
8488 (clobber (reg:DI 15))]
8489 ;;- Do not use operand 1 for most machines.
8492 [(set_attr "type" "call")])
8494 ;; This is a call that wants a structure value.
8495 ;; There is no such critter for v9 (??? we may need one anyway).
8496 (define_insn "*call_address_struct_value_sp32"
8497 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8498 (match_operand 1 "" ""))
8499 (match_operand 2 "immediate_operand" "")
8500 (clobber (reg:SI 15))]
8501 ;;- Do not use operand 1 for most machines.
8502 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8503 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8504 [(set_attr "type" "call_no_delay_slot")
8505 (set_attr "length" "3")])
8507 ;; This is a call that wants a structure value.
8508 ;; There is no such critter for v9 (??? we may need one anyway).
8509 (define_insn "*call_symbolic_struct_value_sp32"
8510 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8511 (match_operand 1 "" ""))
8512 (match_operand 2 "immediate_operand" "")
8513 (clobber (reg:SI 15))]
8514 ;;- Do not use operand 1 for most machines.
8515 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8516 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8517 [(set_attr "type" "call_no_delay_slot")
8518 (set_attr "length" "3")])
8520 ;; This is a call that may want a structure value. This is used for
8522 (define_insn "*call_address_untyped_struct_value_sp32"
8523 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8524 (match_operand 1 "" ""))
8525 (match_operand 2 "immediate_operand" "")
8526 (clobber (reg:SI 15))]
8527 ;;- Do not use operand 1 for most machines.
8528 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8529 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8530 [(set_attr "type" "call_no_delay_slot")
8531 (set_attr "length" "3")])
8533 ;; This is a call that wants a structure value.
8534 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8535 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8536 (match_operand 1 "" ""))
8537 (match_operand 2 "immediate_operand" "")
8538 (clobber (reg:SI 15))]
8539 ;;- Do not use operand 1 for most machines.
8540 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8541 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8542 [(set_attr "type" "call_no_delay_slot")
8543 (set_attr "length" "3")])
8545 (define_expand "call_value"
8546 ;; Note that this expression is not used for generating RTL.
8547 ;; All the RTL is generated explicitly below.
8548 [(set (match_operand 0 "register_operand" "=rf")
8549 (call (match_operand 1 "" "")
8550 (match_operand 4 "" "")))]
8551 ;; operand 2 is stack_size_rtx
8552 ;; operand 3 is next_arg_register
8556 rtx fn_rtx, nregs_rtx;
8559 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8562 fn_rtx = operands[1];
8566 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8568 nregs_rtx = GEN_INT (6);
8570 nregs_rtx = const0_rtx;
8574 gen_rtx_SET (VOIDmode, operands[0],
8575 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8576 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8578 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8583 (define_insn "*call_value_address_sp32"
8584 [(set (match_operand 0 "" "=rf")
8585 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8586 (match_operand 2 "" "")))
8587 (clobber (reg:SI 15))]
8588 ;;- Do not use operand 2 for most machines.
8591 [(set_attr "type" "call")])
8593 (define_insn "*call_value_symbolic_sp32"
8594 [(set (match_operand 0 "" "=rf")
8595 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8596 (match_operand 2 "" "")))
8597 (clobber (reg:SI 15))]
8598 ;;- Do not use operand 2 for most machines.
8601 [(set_attr "type" "call")])
8603 (define_insn "*call_value_address_sp64"
8604 [(set (match_operand 0 "" "")
8605 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8606 (match_operand 2 "" "")))
8607 (clobber (reg:DI 15))]
8608 ;;- Do not use operand 2 for most machines.
8611 [(set_attr "type" "call")])
8613 (define_insn "*call_value_symbolic_sp64"
8614 [(set (match_operand 0 "" "")
8615 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8616 (match_operand 2 "" "")))
8617 (clobber (reg:DI 15))]
8618 ;;- Do not use operand 2 for most machines.
8621 [(set_attr "type" "call")])
8623 (define_expand "untyped_call"
8624 [(parallel [(call (match_operand 0 "" "")
8626 (match_operand 1 "" "")
8627 (match_operand 2 "" "")])]
8633 /* Pass constm1 to indicate that it may expect a structure value, but
8634 we don't know what size it is. */
8635 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8637 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8639 rtx set = XVECEXP (operands[2], 0, i);
8640 emit_move_insn (SET_DEST (set), SET_SRC (set));
8643 /* The optimizer does not know that the call sets the function value
8644 registers we stored in the result block. We avoid problems by
8645 claiming that all hard registers are used and clobbered at this
8647 emit_insn (gen_blockage ());
8653 (define_expand "sibcall"
8654 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8659 (define_insn "*sibcall_symbolic_sp32"
8660 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8661 (match_operand 1 "" ""))
8664 "* return output_sibcall(insn, operands[0]);"
8665 [(set_attr "type" "sibcall")])
8667 (define_insn "*sibcall_symbolic_sp64"
8668 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8669 (match_operand 1 "" ""))
8672 "* return output_sibcall(insn, operands[0]);"
8673 [(set_attr "type" "sibcall")])
8675 (define_expand "sibcall_value"
8676 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8677 (call (match_operand 1 "" "") (const_int 0)))
8682 (define_insn "*sibcall_value_symbolic_sp32"
8683 [(set (match_operand 0 "" "=rf")
8684 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8685 (match_operand 2 "" "")))
8688 "* return output_sibcall(insn, operands[1]);"
8689 [(set_attr "type" "sibcall")])
8691 (define_insn "*sibcall_value_symbolic_sp64"
8692 [(set (match_operand 0 "" "")
8693 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8694 (match_operand 2 "" "")))
8697 "* return output_sibcall(insn, operands[1]);"
8698 [(set_attr "type" "sibcall")])
8700 (define_expand "sibcall_epilogue"
8705 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8706 ;; all of memory. This blocks insns from being moved across this point.
8708 (define_insn "blockage"
8709 [(unspec_volatile [(const_int 0)] 0)]
8712 [(set_attr "length" "0")])
8714 ;; Prepare to return any type including a structure value.
8716 (define_expand "untyped_return"
8717 [(match_operand:BLK 0 "memory_operand" "")
8718 (match_operand 1 "" "")]
8722 rtx valreg1 = gen_rtx_REG (DImode, 24);
8723 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8724 rtx result = operands[0];
8726 if (! TARGET_ARCH64)
8728 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8730 rtx value = gen_reg_rtx (SImode);
8732 /* Fetch the instruction where we will return to and see if it's an unimp
8733 instruction (the most significant 10 bits will be zero). If so,
8734 update the return address to skip the unimp instruction. */
8735 emit_move_insn (value,
8736 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8737 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8738 emit_insn (gen_update_return (rtnreg, value));
8741 /* Reload the function value registers. */
8742 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8743 emit_move_insn (valreg2,
8744 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8746 /* Put USE insns before the return. */
8747 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8748 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8750 /* Construct the return. */
8751 expand_null_return ();
8756 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8757 ;; and parts of the compiler don't want to believe that the add is needed.
8759 (define_insn "update_return"
8760 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8761 (match_operand:SI 1 "register_operand" "r")] 1)]
8763 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8764 [(set_attr "type" "multi")
8765 (set_attr "length" "3")])
8772 (define_expand "indirect_jump"
8773 [(set (pc) (match_operand 0 "address_operand" "p"))]
8777 (define_insn "*branch_sp32"
8778 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8781 [(set_attr "type" "uncond_branch")])
8783 (define_insn "*branch_sp64"
8784 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8787 [(set_attr "type" "uncond_branch")])
8789 ;; ??? Doesn't work with -mflat.
8790 (define_expand "nonlocal_goto"
8791 [(match_operand:SI 0 "general_operand" "")
8792 (match_operand:SI 1 "general_operand" "")
8793 (match_operand:SI 2 "general_operand" "")
8794 (match_operand:SI 3 "" "")]
8799 rtx chain = operands[0];
8801 rtx lab = operands[1];
8802 rtx stack = operands[2];
8803 rtx fp = operands[3];
8806 /* Trap instruction to flush all the register windows. */
8807 emit_insn (gen_flush_register_windows ());
8809 /* Load the fp value for the containing fn into %fp. This is needed
8810 because STACK refers to %fp. Note that virtual register instantiation
8811 fails if the virtual %fp isn't set from a register. */
8812 if (GET_CODE (fp) != REG)
8813 fp = force_reg (Pmode, fp);
8814 emit_move_insn (virtual_stack_vars_rtx, fp);
8816 /* Find the containing function's current nonlocal goto handler,
8817 which will do any cleanups and then jump to the label. */
8818 labreg = gen_rtx_REG (Pmode, 8);
8819 emit_move_insn (labreg, lab);
8821 /* Restore %fp from stack pointer value for containing function.
8822 The restore insn that follows will move this to %sp,
8823 and reload the appropriate value into %fp. */
8824 emit_move_insn (hard_frame_pointer_rtx, stack);
8826 /* USE of frame_pointer_rtx added for consistency; not clear if
8828 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8829 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8832 /* Return, restoring reg window and jumping to goto handler. */
8833 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8834 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8836 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8842 /* Put in the static chain register the nonlocal label address. */
8843 emit_move_insn (static_chain_rtx, chain);
8846 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8847 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8852 ;; Special trap insn to flush register windows.
8853 (define_insn "flush_register_windows"
8854 [(unspec_volatile [(const_int 0)] 1)]
8856 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8857 [(set_attr "type" "misc")])
8859 (define_insn "goto_handler_and_restore"
8860 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8861 "GET_MODE (operands[0]) == Pmode"
8862 "jmp\\t%0+0\\n\\trestore"
8863 [(set_attr "type" "multi")
8864 (set_attr "length" "2")])
8866 ;;(define_insn "goto_handler_and_restore_v9"
8867 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8868 ;; (match_operand:SI 1 "register_operand" "=r,r")
8869 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8870 ;; "TARGET_V9 && ! TARGET_ARCH64"
8872 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8873 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8874 ;; [(set_attr "type" "multi")
8875 ;; (set_attr "length" "2,3")])
8877 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8878 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8879 ;; (match_operand:DI 1 "register_operand" "=r,r")
8880 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8881 ;; "TARGET_V9 && TARGET_ARCH64"
8883 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8884 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8885 ;; [(set_attr "type" "multi")
8886 ;; (set_attr "length" "2,3")])
8888 ;; For __builtin_setjmp we need to flush register windows iff the function
8889 ;; calls alloca as well, because otherwise the register window might be
8890 ;; saved after %sp adjustement and thus setjmp would crash
8891 (define_expand "builtin_setjmp_setup"
8892 [(match_operand 0 "register_operand" "r")]
8896 emit_insn (gen_do_builtin_setjmp_setup ());
8900 (define_insn "do_builtin_setjmp_setup"
8901 [(unspec_volatile [(const_int 0)] 5)]
8905 if (! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT)
8907 fputs (\"\tflushw\n\", asm_out_file);
8909 fprintf (asm_out_file, \"\tst%c\t%%l7, [%%sp+%d]\n\",
8910 TARGET_ARCH64 ? 'x' : 'w',
8911 SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
8912 fprintf (asm_out_file, \"\tst%c\t%%fp, [%%sp+%d]\n\",
8913 TARGET_ARCH64 ? 'x' : 'w',
8914 SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
8915 fprintf (asm_out_file, \"\tst%c\t%%i7, [%%sp+%d]\n\",
8916 TARGET_ARCH64 ? 'x' : 'w',
8917 SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
8920 [(set_attr "type" "misc")
8921 (set (attr "length") (if_then_else (eq_attr "pic" "true")
8926 [(unspec_volatile [(const_int 0)] 5)]
8927 "! current_function_calls_alloca || ! TARGET_V9 || TARGET_FLAT"
8931 if (current_function_calls_alloca)
8932 emit_insn (gen_flush_register_windows ());
8936 ;; Pattern for use after a setjmp to store FP and the return register
8937 ;; into the stack area.
8939 (define_expand "setjmp"
8945 emit_insn (gen_setjmp_64 ());
8947 emit_insn (gen_setjmp_32 ());
8951 (define_expand "setjmp_32"
8952 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8953 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8956 { operands[0] = frame_pointer_rtx; }")
8958 (define_expand "setjmp_64"
8959 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8960 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8963 { operands[0] = frame_pointer_rtx; }")
8965 ;; Special pattern for the FLUSH instruction.
8967 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8968 ; of the define_insn otherwise missing a mode. We make "flush", aka
8969 ; gen_flush, the default one since sparc_initialize_trampoline uses
8970 ; it on SImode mem values.
8972 (define_insn "flush"
8973 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8975 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8976 [(set_attr "type" "misc")])
8978 (define_insn "flushdi"
8979 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8981 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8982 [(set_attr "type" "misc")])
8987 ;; The scan instruction searches from the most significant bit while ffs
8988 ;; searches from the least significant bit. The bit index and treatment of
8989 ;; zero also differ. It takes at least 7 instructions to get the proper
8990 ;; result. Here is an obvious 8 instruction sequence.
8993 (define_insn "ffssi2"
8994 [(set (match_operand:SI 0 "register_operand" "=&r")
8995 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8996 (clobber (match_scratch:SI 2 "=&r"))]
8997 "TARGET_SPARCLITE || TARGET_SPARCLET"
9000 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\";
9002 [(set_attr "type" "multi")
9003 (set_attr "length" "8")])
9005 ;; ??? This should be a define expand, so that the extra instruction have
9006 ;; a chance of being optimized away.
9008 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9009 ;; does, but no one uses that and we don't have a switch for it.
9011 ;(define_insn "ffsdi2"
9012 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9013 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9014 ; (clobber (match_scratch:DI 2 "=&r"))]
9016 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9017 ; [(set_attr "type" "multi")
9018 ; (set_attr "length" "4")])
9022 ;; Peepholes go at the end.
9024 ;; Optimize consecutive loads or stores into ldd and std when possible.
9025 ;; The conditions in which we do this are very restricted and are
9026 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9029 [(set (match_operand:SI 0 "memory_operand" "")
9031 (set (match_operand:SI 1 "memory_operand" "")
9034 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
9037 "operands[0] = change_address (operands[0], DImode, NULL);")
9040 [(set (match_operand:SI 0 "memory_operand" "")
9042 (set (match_operand:SI 1 "memory_operand" "")
9045 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9048 "operands[1] = change_address (operands[1], DImode, NULL);")
9051 [(set (match_operand:SI 0 "register_operand" "")
9052 (match_operand:SI 1 "memory_operand" ""))
9053 (set (match_operand:SI 2 "register_operand" "")
9054 (match_operand:SI 3 "memory_operand" ""))]
9055 "registers_ok_for_ldd_peep (operands[0], operands[2])
9056 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9059 "operands[1] = change_address (operands[1], DImode, NULL);
9060 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9063 [(set (match_operand:SI 0 "memory_operand" "")
9064 (match_operand:SI 1 "register_operand" ""))
9065 (set (match_operand:SI 2 "memory_operand" "")
9066 (match_operand:SI 3 "register_operand" ""))]
9067 "registers_ok_for_ldd_peep (operands[1], operands[3])
9068 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9071 "operands[0] = change_address (operands[0], DImode, NULL);
9072 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9075 [(set (match_operand:SF 0 "register_operand" "")
9076 (match_operand:SF 1 "memory_operand" ""))
9077 (set (match_operand:SF 2 "register_operand" "")
9078 (match_operand:SF 3 "memory_operand" ""))]
9079 "registers_ok_for_ldd_peep (operands[0], operands[2])
9080 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9083 "operands[1] = change_address (operands[1], DFmode, NULL);
9084 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9087 [(set (match_operand:SF 0 "memory_operand" "")
9088 (match_operand:SF 1 "register_operand" ""))
9089 (set (match_operand:SF 2 "memory_operand" "")
9090 (match_operand:SF 3 "register_operand" ""))]
9091 "registers_ok_for_ldd_peep (operands[1], operands[3])
9092 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9095 "operands[0] = change_address (operands[0], DFmode, NULL);
9096 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9099 [(set (match_operand:SI 0 "register_operand" "")
9100 (match_operand:SI 1 "memory_operand" ""))
9101 (set (match_operand:SI 2 "register_operand" "")
9102 (match_operand:SI 3 "memory_operand" ""))]
9103 "registers_ok_for_ldd_peep (operands[2], operands[0])
9104 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9107 "operands[3] = change_address (operands[3], DImode, NULL);
9108 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9111 [(set (match_operand:SI 0 "memory_operand" "")
9112 (match_operand:SI 1 "register_operand" ""))
9113 (set (match_operand:SI 2 "memory_operand" "")
9114 (match_operand:SI 3 "register_operand" ""))]
9115 "registers_ok_for_ldd_peep (operands[3], operands[1])
9116 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9119 "operands[2] = change_address (operands[2], DImode, NULL);
9120 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9124 [(set (match_operand:SF 0 "register_operand" "")
9125 (match_operand:SF 1 "memory_operand" ""))
9126 (set (match_operand:SF 2 "register_operand" "")
9127 (match_operand:SF 3 "memory_operand" ""))]
9128 "registers_ok_for_ldd_peep (operands[2], operands[0])
9129 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9132 "operands[3] = change_address (operands[3], DFmode, NULL);
9133 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9136 [(set (match_operand:SF 0 "memory_operand" "")
9137 (match_operand:SF 1 "register_operand" ""))
9138 (set (match_operand:SF 2 "memory_operand" "")
9139 (match_operand:SF 3 "register_operand" ""))]
9140 "registers_ok_for_ldd_peep (operands[3], operands[1])
9141 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9144 "operands[2] = change_address (operands[2], DFmode, NULL);
9145 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9147 ;; Optimize the case of following a reg-reg move with a test
9148 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9149 ;; This can result from a float to fix conversion.
9152 [(set (match_operand:SI 0 "register_operand" "")
9153 (match_operand:SI 1 "register_operand" ""))
9155 (compare:CC (match_operand:SI 2 "register_operand" "")
9157 "(rtx_equal_p (operands[2], operands[0])
9158 || rtx_equal_p (operands[2], operands[1]))
9159 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9160 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9161 [(parallel [(set (match_dup 0) (match_dup 1))
9163 (compare:CC (match_dup 1) (const_int 0)))])]
9167 [(set (match_operand:DI 0 "register_operand" "")
9168 (match_operand:DI 1 "register_operand" ""))
9170 (compare:CCX (match_operand:DI 2 "register_operand" "")
9173 && (rtx_equal_p (operands[2], operands[0])
9174 || rtx_equal_p (operands[2], operands[1]))
9175 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9176 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9177 [(parallel [(set (match_dup 0) (match_dup 1))
9179 (compare:CC (match_dup 1) (const_int 0)))])]
9182 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
9183 ;; who then immediately calls final_scan_insn.
9185 (define_insn "*return_qi"
9186 [(set (match_operand:QI 0 "restore_operand" "")
9187 (match_operand:QI 1 "arith_operand" "rI"))
9189 "sparc_emitting_epilogue"
9192 if (! TARGET_ARCH64 && current_function_returns_struct)
9193 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9194 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9195 || IN_OR_GLOBAL_P (operands[1])))
9196 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9198 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9200 [(set_attr "type" "multi")
9201 (set_attr "length" "2")])
9203 (define_insn "*return_hi"
9204 [(set (match_operand:HI 0 "restore_operand" "")
9205 (match_operand:HI 1 "arith_operand" "rI"))
9207 "sparc_emitting_epilogue"
9210 if (! TARGET_ARCH64 && current_function_returns_struct)
9211 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9212 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9213 || IN_OR_GLOBAL_P (operands[1])))
9214 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9216 return \"ret\;restore %%g0, %1, %Y0\";
9218 [(set_attr "type" "multi")
9219 (set_attr "length" "2")])
9221 (define_insn "*return_si"
9222 [(set (match_operand:SI 0 "restore_operand" "")
9223 (match_operand:SI 1 "arith_operand" "rI"))
9225 "sparc_emitting_epilogue"
9228 if (! TARGET_ARCH64 && current_function_returns_struct)
9229 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9230 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9231 || IN_OR_GLOBAL_P (operands[1])))
9232 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9234 return \"ret\;restore %%g0, %1, %Y0\";
9236 [(set_attr "type" "multi")
9237 (set_attr "length" "2")])
9239 (define_insn "*return_sf_no_fpu"
9240 [(set (match_operand:SF 0 "restore_operand" "=r")
9241 (match_operand:SF 1 "register_operand" "r"))
9243 "sparc_emitting_epilogue"
9246 if (! TARGET_ARCH64 && current_function_returns_struct)
9247 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9248 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9249 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9251 return \"ret\;restore %%g0, %1, %Y0\";
9253 [(set_attr "type" "multi")
9254 (set_attr "length" "2")])
9256 (define_insn "*return_df_no_fpu"
9257 [(set (match_operand:DF 0 "restore_operand" "=r")
9258 (match_operand:DF 1 "register_operand" "r"))
9260 "sparc_emitting_epilogue && TARGET_ARCH64"
9263 if (IN_OR_GLOBAL_P (operands[1]))
9264 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9266 return \"ret\;restore %%g0, %1, %Y0\";
9268 [(set_attr "type" "multi")
9269 (set_attr "length" "2")])
9271 (define_insn "*return_addsi"
9272 [(set (match_operand:SI 0 "restore_operand" "")
9273 (plus:SI (match_operand:SI 1 "register_operand" "r")
9274 (match_operand:SI 2 "arith_operand" "rI")))
9276 "sparc_emitting_epilogue"
9279 if (! TARGET_ARCH64 && current_function_returns_struct)
9280 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9281 /* If operands are global or in registers, can use return */
9282 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9283 && (GET_CODE (operands[2]) == CONST_INT
9284 || IN_OR_GLOBAL_P (operands[2])))
9285 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9287 return \"ret\;restore %r1, %2, %Y0\";
9289 [(set_attr "type" "multi")
9290 (set_attr "length" "2")])
9292 (define_insn "*return_losum_si"
9293 [(set (match_operand:SI 0 "restore_operand" "")
9294 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9295 (match_operand:SI 2 "immediate_operand" "in")))
9297 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
9300 if (! TARGET_ARCH64 && current_function_returns_struct)
9301 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9302 /* If operands are global or in registers, can use return */
9303 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9304 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9306 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9308 [(set_attr "type" "multi")
9309 (set_attr "length" "2")])
9311 (define_insn "*return_di"
9312 [(set (match_operand:DI 0 "restore_operand" "")
9313 (match_operand:DI 1 "arith_double_operand" "rHI"))
9315 "sparc_emitting_epilogue && TARGET_ARCH64"
9316 "ret\;restore %%g0, %1, %Y0"
9317 [(set_attr "type" "multi")
9318 (set_attr "length" "2")])
9320 (define_insn "*return_adddi"
9321 [(set (match_operand:DI 0 "restore_operand" "")
9322 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9323 (match_operand:DI 2 "arith_double_operand" "rHI")))
9325 "sparc_emitting_epilogue && TARGET_ARCH64"
9326 "ret\;restore %r1, %2, %Y0"
9327 [(set_attr "type" "multi")
9328 (set_attr "length" "2")])
9330 (define_insn "*return_losum_di"
9331 [(set (match_operand:DI 0 "restore_operand" "")
9332 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9333 (match_operand:DI 2 "immediate_operand" "in")))
9335 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
9336 "ret\;restore %r1, %%lo(%a2), %Y0"
9337 [(set_attr "type" "multi")
9338 (set_attr "length" "2")])
9340 (define_insn "*return_sf"
9342 (match_operand:SF 0 "register_operand" "f"))
9344 "sparc_emitting_epilogue"
9345 "ret\;fmovs\\t%0, %%f0"
9346 [(set_attr "type" "multi")
9347 (set_attr "length" "2")])
9349 ;; Now peepholes to do a call followed by a jump.
9352 [(parallel [(set (match_operand 0 "" "")
9353 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9354 (match_operand 2 "" "")))
9355 (clobber (reg:SI 15))])
9356 (set (pc) (label_ref (match_operand 3 "" "")))]
9357 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9358 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9359 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9362 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9363 (match_operand 1 "" ""))
9364 (clobber (reg:SI 15))])
9365 (set (pc) (label_ref (match_operand 2 "" "")))]
9366 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9367 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9368 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9371 [(parallel [(set (match_operand 0 "" "")
9372 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9373 (match_operand 2 "" "")))
9374 (clobber (reg:DI 15))])
9375 (set (pc) (label_ref (match_operand 3 "" "")))]
9377 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9378 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9379 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9382 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9383 (match_operand 1 "" ""))
9384 (clobber (reg:DI 15))])
9385 (set (pc) (label_ref (match_operand 2 "" "")))]
9387 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9388 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9389 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9391 (define_insn "prefetch"
9392 [(prefetch (match_operand:DI 0 "address_operand" "p")
9393 (match_operand:DI 1 "const_int_operand" "n")
9394 (match_operand:DI 2 "const_int_operand" "n"))]
9397 static const char * const prefetch_instr[2][4] = {
9399 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9400 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9401 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9402 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9405 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9406 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9407 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9408 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9411 int read_or_write = INTVAL (operands[1]);
9412 int locality = INTVAL (operands[2]);
9414 if (read_or_write != 0 && read_or_write != 1)
9416 if (locality < 0 || locality > 3)
9418 return prefetch_instr [read_or_write][locality];
9420 [(set_attr "type" "load")])
9422 (define_expand "prologue"
9424 "flag_pic && current_function_uses_pic_offset_table"
9427 load_pic_register ();
9431 ;; We need to reload %l7 for -mflat -fpic,
9432 ;; otherwise %l7 should be preserved simply
9433 ;; by loading the function's register window
9434 (define_expand "exception_receiver"
9436 "TARGET_FLAT && flag_pic"
9439 load_pic_register ();
9444 (define_expand "builtin_setjmp_receiver"
9445 [(label_ref (match_operand 0 "" ""))]
9446 "TARGET_FLAT && flag_pic"
9449 load_pic_register ();
9454 [(trap_if (const_int 1) (const_int 5))]
9457 [(set_attr "type" "misc")])
9459 (define_expand "conditional_trap"
9460 [(trap_if (match_operator 0 "noov_compare_op"
9461 [(match_dup 2) (match_dup 3)])
9462 (match_operand:SI 1 "arith_operand" ""))]
9464 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9465 sparc_compare_op0, sparc_compare_op1);
9466 operands[3] = const0_rtx;")
9469 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9470 (match_operand:SI 1 "arith_operand" "rM"))]
9473 [(set_attr "type" "misc")])
9476 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9477 (match_operand:SI 1 "arith_operand" "rM"))]
9480 [(set_attr "type" "misc")])