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 ;; Length (in # of insns).
97 (define_attr "length" ""
98 (cond [(eq_attr "type" "uncond_branch,call,sibcall")
99 (if_then_else (eq_attr "empty_delay_slot" "true")
102 (eq_attr "branch_type" "icc")
103 (if_then_else (match_operand 0 "noov_compare64_op" "")
104 (if_then_else (lt (pc) (match_dup 1))
105 (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
106 (if_then_else (eq_attr "empty_delay_slot" "true")
109 (if_then_else (eq_attr "empty_delay_slot" "true")
112 (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
113 (if_then_else (eq_attr "empty_delay_slot" "true")
116 (if_then_else (eq_attr "empty_delay_slot" "true")
119 (if_then_else (eq_attr "empty_delay_slot" "true")
122 (eq_attr "branch_type" "fcc")
123 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
124 (if_then_else (eq_attr "empty_delay_slot" "true")
127 (if_then_else (lt (pc) (match_dup 2))
128 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
129 (if_then_else (eq_attr "empty_delay_slot" "true")
132 (if_then_else (eq_attr "empty_delay_slot" "true")
135 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
136 (if_then_else (eq_attr "empty_delay_slot" "true")
139 (if_then_else (eq_attr "empty_delay_slot" "true")
142 (eq_attr "branch_type" "reg")
143 (if_then_else (lt (pc) (match_dup 2))
144 (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
145 (if_then_else (eq_attr "empty_delay_slot" "true")
148 (if_then_else (eq_attr "empty_delay_slot" "true")
151 (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
152 (if_then_else (eq_attr "empty_delay_slot" "true")
155 (if_then_else (eq_attr "empty_delay_slot" "true")
161 (define_attr "fptype" "single,double" (const_string "single"))
163 (define_asm_attributes
164 [(set_attr "length" "2")
165 (set_attr "type" "multi")])
167 ;; Attributes for instruction and branch scheduling
169 (define_attr "in_call_delay" "false,true"
170 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
171 (const_string "false")
172 (eq_attr "type" "load,fpload,store,fpstore")
173 (if_then_else (eq_attr "length" "1")
174 (const_string "true")
175 (const_string "false"))]
176 (if_then_else (eq_attr "length" "1")
177 (const_string "true")
178 (const_string "false"))))
180 (define_delay (eq_attr "type" "call")
181 [(eq_attr "in_call_delay" "true") (nil) (nil)])
183 (define_attr "eligible_for_sibcall_delay" "false,true"
184 (symbol_ref "eligible_for_sibcall_delay (insn)"))
186 (define_delay (eq_attr "type" "sibcall")
187 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
189 (define_attr "leaf_function" "false,true"
190 (const (symbol_ref "current_function_uses_only_leaf_regs")))
192 (define_attr "eligible_for_return_delay" "false,true"
193 (symbol_ref "eligible_for_return_delay (insn)"))
195 (define_attr "in_return_delay" "false,true"
196 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
197 (eq_attr "length" "1"))
198 (eq_attr "leaf_function" "false"))
199 (eq_attr "eligible_for_return_delay" "false"))
200 (const_string "true")
201 (const_string "false")))
203 (define_delay (and (eq_attr "type" "return")
204 (eq_attr "isa" "v9"))
205 [(eq_attr "in_return_delay" "true") (nil) (nil)])
207 ;; ??? Should implement the notion of predelay slots for floating point
208 ;; branches. This would allow us to remove the nop always inserted before
209 ;; a floating point branch.
211 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
212 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
213 ;; This is because doing so will add several pipeline stalls to the path
214 ;; that the load/store did not come from. Unfortunately, there is no way
215 ;; to prevent fill_eager_delay_slots from using load/store without completely
216 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
217 ;; because it prevents us from moving back the final store of inner loops.
219 (define_attr "in_branch_delay" "false,true"
220 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
221 (eq_attr "length" "1"))
222 (const_string "true")
223 (const_string "false")))
225 (define_attr "in_uncond_branch_delay" "false,true"
226 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
227 (eq_attr "length" "1"))
228 (const_string "true")
229 (const_string "false")))
231 (define_attr "in_annul_branch_delay" "false,true"
232 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
233 (eq_attr "length" "1"))
234 (const_string "true")
235 (const_string "false")))
237 (define_delay (eq_attr "type" "branch")
238 [(eq_attr "in_branch_delay" "true")
239 (nil) (eq_attr "in_annul_branch_delay" "true")])
241 (define_delay (eq_attr "type" "uncond_branch")
242 [(eq_attr "in_uncond_branch_delay" "true")
245 ;; Function units of the SPARC
247 ;; (define_function_unit {name} {num-units} {n-users} {test}
248 ;; {ready-delay} {issue-delay} [{conflict-list}])
251 ;; (Noted only for documentation; units that take one cycle do not need to
254 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
257 ;; ---- cypress CY7C602 scheduling:
258 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
260 (define_function_unit "memory" 1 0
261 (and (eq_attr "cpu" "cypress")
262 (eq_attr "type" "load,sload,fpload"))
265 ;; SPARC has two floating-point units: the FP ALU,
266 ;; and the FP MUL/DIV/SQRT unit.
267 ;; Instruction timings on the CY7C602 are as follows
281 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
282 ;; More insns cause the chip to stall.
284 (define_function_unit "fp_alu" 1 0
285 (and (eq_attr "cpu" "cypress")
286 (eq_attr "type" "fp,fpmove"))
289 (define_function_unit "fp_mds" 1 0
290 (and (eq_attr "cpu" "cypress")
291 (eq_attr "type" "fpmul"))
294 (define_function_unit "fp_mds" 1 0
295 (and (eq_attr "cpu" "cypress")
296 (eq_attr "type" "fpdivs,fpdivd"))
299 (define_function_unit "fp_mds" 1 0
300 (and (eq_attr "cpu" "cypress")
301 (eq_attr "type" "fpsqrts,fpsqrtd"))
304 ;; ----- The TMS390Z55 scheduling
305 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
306 ;; one ld/st, one fp.
307 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
309 (define_function_unit "memory" 1 0
310 (and (eq_attr "cpu" "supersparc")
311 (eq_attr "type" "load,sload"))
314 (define_function_unit "memory" 1 0
315 (and (eq_attr "cpu" "supersparc")
316 (eq_attr "type" "fpload"))
319 (define_function_unit "memory" 1 0
320 (and (eq_attr "cpu" "supersparc")
321 (eq_attr "type" "store,fpstore"))
324 (define_function_unit "shift" 1 0
325 (and (eq_attr "cpu" "supersparc")
326 (eq_attr "type" "shift"))
329 ;; There are only two write ports to the integer register file
330 ;; A store also uses a write port
332 (define_function_unit "iwport" 2 0
333 (and (eq_attr "cpu" "supersparc")
334 (eq_attr "type" "load,sload,store,shift,ialu"))
337 ;; Timings; throughput/latency
338 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
346 (define_function_unit "fp_alu" 1 0
347 (and (eq_attr "cpu" "supersparc")
348 (eq_attr "type" "fp,fpmove,fpcmp"))
351 (define_function_unit "fp_mds" 1 0
352 (and (eq_attr "cpu" "supersparc")
353 (eq_attr "type" "fpmul"))
356 (define_function_unit "fp_mds" 1 0
357 (and (eq_attr "cpu" "supersparc")
358 (eq_attr "type" "fpdivs"))
361 (define_function_unit "fp_mds" 1 0
362 (and (eq_attr "cpu" "supersparc")
363 (eq_attr "type" "fpdivd"))
366 (define_function_unit "fp_mds" 1 0
367 (and (eq_attr "cpu" "supersparc")
368 (eq_attr "type" "fpsqrts,fpsqrtd"))
371 (define_function_unit "fp_mds" 1 0
372 (and (eq_attr "cpu" "supersparc")
373 (eq_attr "type" "imul"))
376 ;; ----- hypersparc/sparclite86x scheduling
377 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
378 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
379 ;; II/FF case is only when loading a 32 bit hi/lo constant
380 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
381 ;; Memory delivers its result in one cycle to IU
383 (define_function_unit "memory" 1 0
384 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
385 (eq_attr "type" "load,sload,fpload"))
388 (define_function_unit "memory" 1 0
389 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
390 (eq_attr "type" "store,fpstore"))
393 (define_function_unit "sparclite86x_branch" 1 0
394 (and (eq_attr "cpu" "sparclite86x")
395 (eq_attr "type" "branch"))
398 ;; integer multiply insns
399 (define_function_unit "sparclite86x_shift" 1 0
400 (and (eq_attr "cpu" "sparclite86x")
401 (eq_attr "type" "shift"))
404 (define_function_unit "fp_alu" 1 0
405 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
406 (eq_attr "type" "fp,fpmove,fpcmp"))
409 (define_function_unit "fp_mds" 1 0
410 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
411 (eq_attr "type" "fpmul"))
414 (define_function_unit "fp_mds" 1 0
415 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
416 (eq_attr "type" "fpdivs"))
419 (define_function_unit "fp_mds" 1 0
420 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
421 (eq_attr "type" "fpdivd"))
424 (define_function_unit "fp_mds" 1 0
425 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
426 (eq_attr "type" "fpsqrts,fpsqrtd"))
429 (define_function_unit "fp_mds" 1 0
430 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
431 (eq_attr "type" "imul"))
434 ;; ----- sparclet tsc701 scheduling
435 ;; The tsc701 issues 1 insn per cycle.
436 ;; Results may be written back out of order.
438 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
440 (define_function_unit "tsc701_load" 4 1
441 (and (eq_attr "cpu" "tsc701")
442 (eq_attr "type" "load,sload"))
445 ;; Stores take 2(?) extra cycles to complete.
446 ;; It is desirable to not have any memory operation in the following 2 cycles.
447 ;; (??? or 2 memory ops in the case of std).
449 (define_function_unit "tsc701_store" 1 0
450 (and (eq_attr "cpu" "tsc701")
451 (eq_attr "type" "store"))
453 [(eq_attr "type" "load,sload,store")])
455 ;; The multiply unit has a latency of 5.
456 (define_function_unit "tsc701_mul" 1 0
457 (and (eq_attr "cpu" "tsc701")
458 (eq_attr "type" "imul"))
461 ;; ----- The UltraSPARC-1 scheduling
462 ;; UltraSPARC has two integer units. Shift instructions can only execute
463 ;; on IE0. Condition code setting instructions, call, and jmpl (including
464 ;; the ret and retl pseudo-instructions) can only execute on IE1.
465 ;; Branch on register uses IE1, but branch on condition code does not.
466 ;; Conditional moves take 2 cycles. No other instruction can issue in the
467 ;; same cycle as a conditional move.
468 ;; Multiply and divide take many cycles during which no other instructions
470 ;; Memory delivers its result in two cycles (except for signed loads,
471 ;; which take one cycle more). One memory instruction can be issued per
474 (define_function_unit "memory" 1 0
475 (and (eq_attr "cpu" "ultrasparc")
476 (eq_attr "type" "load,fpload"))
479 (define_function_unit "memory" 1 0
480 (and (eq_attr "cpu" "ultrasparc")
481 (eq_attr "type" "sload"))
484 (define_function_unit "memory" 1 0
485 (and (eq_attr "cpu" "ultrasparc")
486 (eq_attr "type" "store,fpstore"))
489 (define_function_unit "ieuN" 2 0
490 (and (eq_attr "cpu" "ultrasparc")
491 (eq_attr "type" "ialu,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
494 (define_function_unit "ieu0" 1 0
495 (and (eq_attr "cpu" "ultrasparc")
496 (eq_attr "type" "shift"))
499 (define_function_unit "ieu0" 1 0
500 (and (eq_attr "cpu" "ultrasparc")
501 (eq_attr "type" "cmove"))
504 (define_function_unit "ieu1" 1 0
505 (and (eq_attr "cpu" "ultrasparc")
506 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
509 (define_function_unit "cti" 1 0
510 (and (eq_attr "cpu" "ultrasparc")
511 (eq_attr "type" "branch"))
514 ;; Timings; throughput/latency
515 ;; FMOV 1/1 fmov, fabs, fneg
517 ;; FADD 1/3 add/sub, format conv, compar
523 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
525 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
526 ;; use the FPM multiplier for final rounding 3 cycles before the
527 ;; end of their latency and we have no real way to model that.
529 ;; ??? This is really bogus because the timings really depend upon
530 ;; who uses the result. We should record who the user is with
531 ;; more descriptive 'type' attribute names and account for these
532 ;; issues in ultrasparc_adjust_cost.
534 (define_function_unit "fadd" 1 0
535 (and (eq_attr "cpu" "ultrasparc")
536 (eq_attr "type" "fpmove"))
539 (define_function_unit "fadd" 1 0
540 (and (eq_attr "cpu" "ultrasparc")
541 (eq_attr "type" "fpcmove"))
544 (define_function_unit "fadd" 1 0
545 (and (eq_attr "cpu" "ultrasparc")
546 (eq_attr "type" "fp"))
549 (define_function_unit "fadd" 1 0
550 (and (eq_attr "cpu" "ultrasparc")
551 (eq_attr "type" "fpcmp"))
554 (define_function_unit "fmul" 1 0
555 (and (eq_attr "cpu" "ultrasparc")
556 (eq_attr "type" "fpmul"))
559 (define_function_unit "fadd" 1 0
560 (and (eq_attr "cpu" "ultrasparc")
561 (eq_attr "type" "fpcmove"))
564 (define_function_unit "fdiv" 1 0
565 (and (eq_attr "cpu" "ultrasparc")
566 (eq_attr "type" "fpdivs"))
569 (define_function_unit "fdiv" 1 0
570 (and (eq_attr "cpu" "ultrasparc")
571 (eq_attr "type" "fpdivd"))
574 (define_function_unit "fdiv" 1 0
575 (and (eq_attr "cpu" "ultrasparc")
576 (eq_attr "type" "fpsqrts"))
579 (define_function_unit "fdiv" 1 0
580 (and (eq_attr "cpu" "ultrasparc")
581 (eq_attr "type" "fpsqrtd"))
584 ;; Compare instructions.
585 ;; This controls RTL generation and register allocation.
587 ;; We generate RTL for comparisons and branches by having the cmpxx
588 ;; patterns store away the operands. Then, the scc and bcc patterns
589 ;; emit RTL for both the compare and the branch.
591 ;; We do this because we want to generate different code for an sne and
592 ;; seq insn. In those cases, if the second operand of the compare is not
593 ;; const0_rtx, we want to compute the xor of the two operands and test
596 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
597 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
598 ;; insns that actually require more than one machine instruction.
600 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
602 (define_expand "cmpsi"
604 (compare:CC (match_operand:SI 0 "register_operand" "")
605 (match_operand:SI 1 "arith_operand" "")))]
609 sparc_compare_op0 = operands[0];
610 sparc_compare_op1 = operands[1];
614 (define_expand "cmpdi"
616 (compare:CCX (match_operand:DI 0 "register_operand" "")
617 (match_operand:DI 1 "arith_double_operand" "")))]
621 sparc_compare_op0 = operands[0];
622 sparc_compare_op1 = operands[1];
626 (define_expand "cmpsf"
627 ;; The 96 here isn't ever used by anyone.
629 (compare:CCFP (match_operand:SF 0 "register_operand" "")
630 (match_operand:SF 1 "register_operand" "")))]
634 sparc_compare_op0 = operands[0];
635 sparc_compare_op1 = operands[1];
639 (define_expand "cmpdf"
640 ;; The 96 here isn't ever used by anyone.
642 (compare:CCFP (match_operand:DF 0 "register_operand" "")
643 (match_operand:DF 1 "register_operand" "")))]
647 sparc_compare_op0 = operands[0];
648 sparc_compare_op1 = operands[1];
652 (define_expand "cmptf"
653 ;; The 96 here isn't ever used by anyone.
655 (compare:CCFP (match_operand:TF 0 "register_operand" "")
656 (match_operand:TF 1 "register_operand" "")))]
660 sparc_compare_op0 = operands[0];
661 sparc_compare_op1 = operands[1];
665 ;; Now the compare DEFINE_INSNs.
667 (define_insn "*cmpsi_insn"
669 (compare:CC (match_operand:SI 0 "register_operand" "r")
670 (match_operand:SI 1 "arith_operand" "rI")))]
673 [(set_attr "type" "compare")])
675 (define_insn "*cmpdi_sp64"
677 (compare:CCX (match_operand:DI 0 "register_operand" "r")
678 (match_operand:DI 1 "arith_double_operand" "rHI")))]
681 [(set_attr "type" "compare")])
683 (define_insn "*cmpsf_fpe"
684 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
685 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
686 (match_operand:SF 2 "register_operand" "f")))]
691 return \"fcmpes\\t%0, %1, %2\";
692 return \"fcmpes\\t%1, %2\";
694 [(set_attr "type" "fpcmp")])
696 (define_insn "*cmpdf_fpe"
697 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
698 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
699 (match_operand:DF 2 "register_operand" "e")))]
704 return \"fcmped\\t%0, %1, %2\";
705 return \"fcmped\\t%1, %2\";
707 [(set_attr "type" "fpcmp")
708 (set_attr "fptype" "double")])
710 (define_insn "*cmptf_fpe"
711 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
712 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
713 (match_operand:TF 2 "register_operand" "e")))]
714 "TARGET_FPU && TARGET_HARD_QUAD"
718 return \"fcmpeq\\t%0, %1, %2\";
719 return \"fcmpeq\\t%1, %2\";
721 [(set_attr "type" "fpcmp")])
723 (define_insn "*cmpsf_fp"
724 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
725 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
726 (match_operand:SF 2 "register_operand" "f")))]
731 return \"fcmps\\t%0, %1, %2\";
732 return \"fcmps\\t%1, %2\";
734 [(set_attr "type" "fpcmp")])
736 (define_insn "*cmpdf_fp"
737 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
738 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
739 (match_operand:DF 2 "register_operand" "e")))]
744 return \"fcmpd\\t%0, %1, %2\";
745 return \"fcmpd\\t%1, %2\";
747 [(set_attr "type" "fpcmp")
748 (set_attr "fptype" "double")])
750 (define_insn "*cmptf_fp"
751 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
752 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
753 (match_operand:TF 2 "register_operand" "e")))]
754 "TARGET_FPU && TARGET_HARD_QUAD"
758 return \"fcmpq\\t%0, %1, %2\";
759 return \"fcmpq\\t%1, %2\";
761 [(set_attr "type" "fpcmp")])
763 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
764 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
765 ;; the same code as v8 (the addx/subx method has more applications). The
766 ;; exception to this is "reg != 0" which can be done in one instruction on v9
767 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
770 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
771 ;; generate addcc/subcc instructions.
773 (define_expand "seqsi_special"
775 (xor:SI (match_operand:SI 1 "register_operand" "")
776 (match_operand:SI 2 "register_operand" "")))
777 (parallel [(set (match_operand:SI 0 "register_operand" "")
778 (eq:SI (match_dup 3) (const_int 0)))
779 (clobber (reg:CC 100))])]
781 "{ operands[3] = gen_reg_rtx (SImode); }")
783 (define_expand "seqdi_special"
785 (xor:DI (match_operand:DI 1 "register_operand" "")
786 (match_operand:DI 2 "register_operand" "")))
787 (set (match_operand:DI 0 "register_operand" "")
788 (eq:DI (match_dup 3) (const_int 0)))]
790 "{ operands[3] = gen_reg_rtx (DImode); }")
792 (define_expand "snesi_special"
794 (xor:SI (match_operand:SI 1 "register_operand" "")
795 (match_operand:SI 2 "register_operand" "")))
796 (parallel [(set (match_operand:SI 0 "register_operand" "")
797 (ne:SI (match_dup 3) (const_int 0)))
798 (clobber (reg:CC 100))])]
800 "{ operands[3] = gen_reg_rtx (SImode); }")
802 (define_expand "snedi_special"
804 (xor:DI (match_operand:DI 1 "register_operand" "")
805 (match_operand:DI 2 "register_operand" "")))
806 (set (match_operand:DI 0 "register_operand" "")
807 (ne:DI (match_dup 3) (const_int 0)))]
809 "{ operands[3] = gen_reg_rtx (DImode); }")
811 (define_expand "seqdi_special_trunc"
813 (xor:DI (match_operand:DI 1 "register_operand" "")
814 (match_operand:DI 2 "register_operand" "")))
815 (set (match_operand:SI 0 "register_operand" "")
816 (eq:SI (match_dup 3) (const_int 0)))]
818 "{ operands[3] = gen_reg_rtx (DImode); }")
820 (define_expand "snedi_special_trunc"
822 (xor:DI (match_operand:DI 1 "register_operand" "")
823 (match_operand:DI 2 "register_operand" "")))
824 (set (match_operand:SI 0 "register_operand" "")
825 (ne:SI (match_dup 3) (const_int 0)))]
827 "{ operands[3] = gen_reg_rtx (DImode); }")
829 (define_expand "seqsi_special_extend"
831 (xor:SI (match_operand:SI 1 "register_operand" "")
832 (match_operand:SI 2 "register_operand" "")))
833 (parallel [(set (match_operand:DI 0 "register_operand" "")
834 (eq:DI (match_dup 3) (const_int 0)))
835 (clobber (reg:CC 100))])]
837 "{ operands[3] = gen_reg_rtx (SImode); }")
839 (define_expand "snesi_special_extend"
841 (xor:SI (match_operand:SI 1 "register_operand" "")
842 (match_operand:SI 2 "register_operand" "")))
843 (parallel [(set (match_operand:DI 0 "register_operand" "")
844 (ne:DI (match_dup 3) (const_int 0)))
845 (clobber (reg:CC 100))])]
847 "{ operands[3] = gen_reg_rtx (SImode); }")
849 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
850 ;; However, the code handles both SImode and DImode.
852 [(set (match_operand:SI 0 "intreg_operand" "")
853 (eq:SI (match_dup 1) (const_int 0)))]
857 if (GET_MODE (sparc_compare_op0) == SImode)
861 if (GET_MODE (operands[0]) == SImode)
862 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
864 else if (! TARGET_ARCH64)
867 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
872 else if (GET_MODE (sparc_compare_op0) == DImode)
878 else if (GET_MODE (operands[0]) == SImode)
879 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
882 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
887 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
889 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
890 emit_jump_insn (gen_sne (operands[0]));
895 if (gen_v9_scc (EQ, operands))
902 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
903 ;; However, the code handles both SImode and DImode.
905 [(set (match_operand:SI 0 "intreg_operand" "")
906 (ne:SI (match_dup 1) (const_int 0)))]
910 if (GET_MODE (sparc_compare_op0) == SImode)
914 if (GET_MODE (operands[0]) == SImode)
915 pat = gen_snesi_special (operands[0], sparc_compare_op0,
917 else if (! TARGET_ARCH64)
920 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
925 else if (GET_MODE (sparc_compare_op0) == DImode)
931 else if (GET_MODE (operands[0]) == SImode)
932 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
935 pat = gen_snedi_special (operands[0], sparc_compare_op0,
940 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
942 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
943 emit_jump_insn (gen_sne (operands[0]));
948 if (gen_v9_scc (NE, operands))
956 [(set (match_operand:SI 0 "intreg_operand" "")
957 (gt:SI (match_dup 1) (const_int 0)))]
961 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
963 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
964 emit_jump_insn (gen_sne (operands[0]));
969 if (gen_v9_scc (GT, operands))
977 [(set (match_operand:SI 0 "intreg_operand" "")
978 (lt:SI (match_dup 1) (const_int 0)))]
982 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
984 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
985 emit_jump_insn (gen_sne (operands[0]));
990 if (gen_v9_scc (LT, operands))
998 [(set (match_operand:SI 0 "intreg_operand" "")
999 (ge:SI (match_dup 1) (const_int 0)))]
1003 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1005 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1006 emit_jump_insn (gen_sne (operands[0]));
1011 if (gen_v9_scc (GE, operands))
1018 (define_expand "sle"
1019 [(set (match_operand:SI 0 "intreg_operand" "")
1020 (le:SI (match_dup 1) (const_int 0)))]
1024 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1026 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1027 emit_jump_insn (gen_sne (operands[0]));
1032 if (gen_v9_scc (LE, operands))
1039 (define_expand "sgtu"
1040 [(set (match_operand:SI 0 "intreg_operand" "")
1041 (gtu:SI (match_dup 1) (const_int 0)))]
1049 /* We can do ltu easily, so if both operands are registers, swap them and
1051 if ((GET_CODE (sparc_compare_op0) == REG
1052 || GET_CODE (sparc_compare_op0) == SUBREG)
1053 && (GET_CODE (sparc_compare_op1) == REG
1054 || GET_CODE (sparc_compare_op1) == SUBREG))
1056 tem = sparc_compare_op0;
1057 sparc_compare_op0 = sparc_compare_op1;
1058 sparc_compare_op1 = tem;
1059 pat = gen_sltu (operands[0]);
1060 if (pat == NULL_RTX)
1068 if (gen_v9_scc (GTU, operands))
1074 (define_expand "sltu"
1075 [(set (match_operand:SI 0 "intreg_operand" "")
1076 (ltu:SI (match_dup 1) (const_int 0)))]
1082 if (gen_v9_scc (LTU, operands))
1085 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1088 (define_expand "sgeu"
1089 [(set (match_operand:SI 0 "intreg_operand" "")
1090 (geu:SI (match_dup 1) (const_int 0)))]
1096 if (gen_v9_scc (GEU, operands))
1099 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1102 (define_expand "sleu"
1103 [(set (match_operand:SI 0 "intreg_operand" "")
1104 (leu:SI (match_dup 1) (const_int 0)))]
1112 /* We can do geu easily, so if both operands are registers, swap them and
1114 if ((GET_CODE (sparc_compare_op0) == REG
1115 || GET_CODE (sparc_compare_op0) == SUBREG)
1116 && (GET_CODE (sparc_compare_op1) == REG
1117 || GET_CODE (sparc_compare_op1) == SUBREG))
1119 tem = sparc_compare_op0;
1120 sparc_compare_op0 = sparc_compare_op1;
1121 sparc_compare_op1 = tem;
1122 pat = gen_sgeu (operands[0]);
1123 if (pat == NULL_RTX)
1131 if (gen_v9_scc (LEU, operands))
1137 ;; Now the DEFINE_INSNs for the scc cases.
1139 ;; The SEQ and SNE patterns are special because they can be done
1140 ;; without any branching and do not involve a COMPARE. We want
1141 ;; them to always use the splitz below so the results can be
1144 (define_insn "*snesi_zero"
1145 [(set (match_operand:SI 0 "register_operand" "=r")
1146 (ne:SI (match_operand:SI 1 "register_operand" "r")
1148 (clobber (reg:CC 100))]
1151 [(set_attr "length" "2")])
1154 [(set (match_operand:SI 0 "register_operand" "")
1155 (ne:SI (match_operand:SI 1 "register_operand" "")
1157 (clobber (reg:CC 100))]
1159 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1161 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1164 (define_insn "*neg_snesi_zero"
1165 [(set (match_operand:SI 0 "register_operand" "=r")
1166 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1168 (clobber (reg:CC 100))]
1171 [(set_attr "length" "2")])
1174 [(set (match_operand:SI 0 "register_operand" "")
1175 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1177 (clobber (reg:CC 100))]
1179 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1181 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1184 (define_insn "*snesi_zero_extend"
1185 [(set (match_operand:DI 0 "register_operand" "=r")
1186 (ne:DI (match_operand:SI 1 "register_operand" "r")
1188 (clobber (reg:CC 100))]
1191 [(set_attr "length" "2")])
1194 [(set (match_operand:DI 0 "register_operand" "")
1195 (ne:DI (match_operand:SI 1 "register_operand" "")
1197 (clobber (reg:CC 100))]
1199 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1201 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1203 (ltu:SI (reg:CC_NOOV 100)
1207 (define_insn "*snedi_zero"
1208 [(set (match_operand:DI 0 "register_operand" "=&r")
1209 (ne:DI (match_operand:DI 1 "register_operand" "r")
1213 [(set_attr "length" "2")])
1216 [(set (match_operand:DI 0 "register_operand" "")
1217 (ne:DI (match_operand:DI 1 "register_operand" "")
1220 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1221 [(set (match_dup 0) (const_int 0))
1222 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1228 (define_insn "*neg_snedi_zero"
1229 [(set (match_operand:DI 0 "register_operand" "=&r")
1230 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1234 [(set_attr "length" "2")])
1237 [(set (match_operand:DI 0 "register_operand" "")
1238 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1241 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1242 [(set (match_dup 0) (const_int 0))
1243 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1249 (define_insn "*snedi_zero_trunc"
1250 [(set (match_operand:SI 0 "register_operand" "=&r")
1251 (ne:SI (match_operand:DI 1 "register_operand" "r")
1255 [(set_attr "length" "2")])
1258 [(set (match_operand:SI 0 "register_operand" "")
1259 (ne:SI (match_operand:DI 1 "register_operand" "")
1262 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1263 [(set (match_dup 0) (const_int 0))
1264 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1270 (define_insn "*seqsi_zero"
1271 [(set (match_operand:SI 0 "register_operand" "=r")
1272 (eq:SI (match_operand:SI 1 "register_operand" "r")
1274 (clobber (reg:CC 100))]
1277 [(set_attr "length" "2")])
1280 [(set (match_operand:SI 0 "register_operand" "")
1281 (eq:SI (match_operand:SI 1 "register_operand" "")
1283 (clobber (reg:CC 100))]
1285 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1287 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1290 (define_insn "*neg_seqsi_zero"
1291 [(set (match_operand:SI 0 "register_operand" "=r")
1292 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1294 (clobber (reg:CC 100))]
1297 [(set_attr "length" "2")])
1300 [(set (match_operand:SI 0 "register_operand" "")
1301 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1303 (clobber (reg:CC 100))]
1305 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1307 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1310 (define_insn "*seqsi_zero_extend"
1311 [(set (match_operand:DI 0 "register_operand" "=r")
1312 (eq:DI (match_operand:SI 1 "register_operand" "r")
1314 (clobber (reg:CC 100))]
1317 [(set_attr "length" "2")])
1320 [(set (match_operand:DI 0 "register_operand" "")
1321 (eq:DI (match_operand:SI 1 "register_operand" "")
1323 (clobber (reg:CC 100))]
1325 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1327 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1329 (ltu:SI (reg:CC_NOOV 100)
1333 (define_insn "*seqdi_zero"
1334 [(set (match_operand:DI 0 "register_operand" "=&r")
1335 (eq:DI (match_operand:DI 1 "register_operand" "r")
1339 [(set_attr "length" "2")])
1342 [(set (match_operand:DI 0 "register_operand" "")
1343 (eq:DI (match_operand:DI 1 "register_operand" "")
1346 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1347 [(set (match_dup 0) (const_int 0))
1348 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1354 (define_insn "*neg_seqdi_zero"
1355 [(set (match_operand:DI 0 "register_operand" "=&r")
1356 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1360 [(set_attr "length" "2")])
1363 [(set (match_operand:DI 0 "register_operand" "")
1364 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1367 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1368 [(set (match_dup 0) (const_int 0))
1369 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1375 (define_insn "*seqdi_zero_trunc"
1376 [(set (match_operand:SI 0 "register_operand" "=&r")
1377 (eq:SI (match_operand:DI 1 "register_operand" "r")
1381 [(set_attr "length" "2")])
1384 [(set (match_operand:SI 0 "register_operand" "")
1385 (eq:SI (match_operand:DI 1 "register_operand" "")
1388 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1389 [(set (match_dup 0) (const_int 0))
1390 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1396 ;; We can also do (x + (i == 0)) and related, so put them in.
1397 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1400 (define_insn "*x_plus_i_ne_0"
1401 [(set (match_operand:SI 0 "register_operand" "=r")
1402 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1404 (match_operand:SI 2 "register_operand" "r")))
1405 (clobber (reg:CC 100))]
1408 [(set_attr "length" "2")])
1411 [(set (match_operand:SI 0 "register_operand" "")
1412 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1414 (match_operand:SI 2 "register_operand" "")))
1415 (clobber (reg:CC 100))]
1417 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1419 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1423 (define_insn "*x_minus_i_ne_0"
1424 [(set (match_operand:SI 0 "register_operand" "=r")
1425 (minus:SI (match_operand:SI 2 "register_operand" "r")
1426 (ne:SI (match_operand:SI 1 "register_operand" "r")
1428 (clobber (reg:CC 100))]
1431 [(set_attr "length" "2")])
1434 [(set (match_operand:SI 0 "register_operand" "")
1435 (minus:SI (match_operand:SI 2 "register_operand" "")
1436 (ne:SI (match_operand:SI 1 "register_operand" "")
1438 (clobber (reg:CC 100))]
1440 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1442 (set (match_dup 0) (minus:SI (match_dup 2)
1443 (ltu:SI (reg:CC 100) (const_int 0))))]
1446 (define_insn "*x_plus_i_eq_0"
1447 [(set (match_operand:SI 0 "register_operand" "=r")
1448 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1450 (match_operand:SI 2 "register_operand" "r")))
1451 (clobber (reg:CC 100))]
1454 [(set_attr "length" "2")])
1457 [(set (match_operand:SI 0 "register_operand" "")
1458 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1460 (match_operand:SI 2 "register_operand" "")))
1461 (clobber (reg:CC 100))]
1463 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1465 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1469 (define_insn "*x_minus_i_eq_0"
1470 [(set (match_operand:SI 0 "register_operand" "=r")
1471 (minus:SI (match_operand:SI 2 "register_operand" "r")
1472 (eq:SI (match_operand:SI 1 "register_operand" "r")
1474 (clobber (reg:CC 100))]
1477 [(set_attr "length" "2")])
1480 [(set (match_operand:SI 0 "register_operand" "")
1481 (minus:SI (match_operand:SI 2 "register_operand" "")
1482 (eq:SI (match_operand:SI 1 "register_operand" "")
1484 (clobber (reg:CC 100))]
1486 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1488 (set (match_dup 0) (minus:SI (match_dup 2)
1489 (geu:SI (reg:CC 100) (const_int 0))))]
1492 ;; We can also do GEU and LTU directly, but these operate after a compare.
1493 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1496 (define_insn "*sltu_insn"
1497 [(set (match_operand:SI 0 "register_operand" "=r")
1498 (ltu:SI (reg:CC 100) (const_int 0)))]
1500 "addx\\t%%g0, 0, %0"
1501 [(set_attr "type" "misc")])
1503 (define_insn "*neg_sltu_insn"
1504 [(set (match_operand:SI 0 "register_operand" "=r")
1505 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1507 "subx\\t%%g0, 0, %0"
1508 [(set_attr "type" "misc")])
1510 ;; ??? Combine should canonicalize these next two to the same pattern.
1511 (define_insn "*neg_sltu_minus_x"
1512 [(set (match_operand:SI 0 "register_operand" "=r")
1513 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1514 (match_operand:SI 1 "arith_operand" "rI")))]
1516 "subx\\t%%g0, %1, %0"
1517 [(set_attr "type" "misc")])
1519 (define_insn "*neg_sltu_plus_x"
1520 [(set (match_operand:SI 0 "register_operand" "=r")
1521 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1522 (match_operand:SI 1 "arith_operand" "rI"))))]
1524 "subx\\t%%g0, %1, %0"
1525 [(set_attr "type" "misc")])
1527 (define_insn "*sgeu_insn"
1528 [(set (match_operand:SI 0 "register_operand" "=r")
1529 (geu:SI (reg:CC 100) (const_int 0)))]
1531 "subx\\t%%g0, -1, %0"
1532 [(set_attr "type" "misc")])
1534 (define_insn "*neg_sgeu_insn"
1535 [(set (match_operand:SI 0 "register_operand" "=r")
1536 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1538 "addx\\t%%g0, -1, %0"
1539 [(set_attr "type" "misc")])
1541 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1542 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1545 (define_insn "*sltu_plus_x"
1546 [(set (match_operand:SI 0 "register_operand" "=r")
1547 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1548 (match_operand:SI 1 "arith_operand" "rI")))]
1550 "addx\\t%%g0, %1, %0"
1551 [(set_attr "type" "misc")])
1553 (define_insn "*sltu_plus_x_plus_y"
1554 [(set (match_operand:SI 0 "register_operand" "=r")
1555 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1556 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1557 (match_operand:SI 2 "arith_operand" "rI"))))]
1560 [(set_attr "type" "misc")])
1562 (define_insn "*x_minus_sltu"
1563 [(set (match_operand:SI 0 "register_operand" "=r")
1564 (minus:SI (match_operand:SI 1 "register_operand" "r")
1565 (ltu:SI (reg:CC 100) (const_int 0))))]
1568 [(set_attr "type" "misc")])
1570 ;; ??? Combine should canonicalize these next two to the same pattern.
1571 (define_insn "*x_minus_y_minus_sltu"
1572 [(set (match_operand:SI 0 "register_operand" "=r")
1573 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1574 (match_operand:SI 2 "arith_operand" "rI"))
1575 (ltu:SI (reg:CC 100) (const_int 0))))]
1577 "subx\\t%r1, %2, %0"
1578 [(set_attr "type" "misc")])
1580 (define_insn "*x_minus_sltu_plus_y"
1581 [(set (match_operand:SI 0 "register_operand" "=r")
1582 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1583 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1584 (match_operand:SI 2 "arith_operand" "rI"))))]
1586 "subx\\t%r1, %2, %0"
1587 [(set_attr "type" "misc")])
1589 (define_insn "*sgeu_plus_x"
1590 [(set (match_operand:SI 0 "register_operand" "=r")
1591 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1592 (match_operand:SI 1 "register_operand" "r")))]
1595 [(set_attr "type" "misc")])
1597 (define_insn "*x_minus_sgeu"
1598 [(set (match_operand:SI 0 "register_operand" "=r")
1599 (minus:SI (match_operand:SI 1 "register_operand" "r")
1600 (geu:SI (reg:CC 100) (const_int 0))))]
1603 [(set_attr "type" "misc")])
1606 [(set (match_operand:SI 0 "register_operand" "")
1607 (match_operator:SI 2 "noov_compare_op"
1608 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1610 ;; 32 bit LTU/GEU are better implemented using addx/subx
1611 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1612 && (GET_MODE (operands[1]) == CCXmode
1613 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1614 [(set (match_dup 0) (const_int 0))
1616 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1622 ;; These control RTL generation for conditional jump insns
1624 ;; The quad-word fp compare library routines all return nonzero to indicate
1625 ;; true, which is different from the equivalent libgcc routines, so we must
1626 ;; handle them specially here.
1628 (define_expand "beq"
1630 (if_then_else (eq (match_dup 1) (const_int 0))
1631 (label_ref (match_operand 0 "" ""))
1636 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1637 && GET_CODE (sparc_compare_op0) == REG
1638 && GET_MODE (sparc_compare_op0) == DImode)
1640 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1643 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1645 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1646 emit_jump_insn (gen_bne (operands[0]));
1649 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1652 (define_expand "bne"
1654 (if_then_else (ne (match_dup 1) (const_int 0))
1655 (label_ref (match_operand 0 "" ""))
1660 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1661 && GET_CODE (sparc_compare_op0) == REG
1662 && GET_MODE (sparc_compare_op0) == DImode)
1664 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1667 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1669 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1670 emit_jump_insn (gen_bne (operands[0]));
1673 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1676 (define_expand "bgt"
1678 (if_then_else (gt (match_dup 1) (const_int 0))
1679 (label_ref (match_operand 0 "" ""))
1684 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1685 && GET_CODE (sparc_compare_op0) == REG
1686 && GET_MODE (sparc_compare_op0) == DImode)
1688 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1691 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1693 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1694 emit_jump_insn (gen_bne (operands[0]));
1697 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1700 (define_expand "bgtu"
1702 (if_then_else (gtu (match_dup 1) (const_int 0))
1703 (label_ref (match_operand 0 "" ""))
1707 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1710 (define_expand "blt"
1712 (if_then_else (lt (match_dup 1) (const_int 0))
1713 (label_ref (match_operand 0 "" ""))
1718 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1719 && GET_CODE (sparc_compare_op0) == REG
1720 && GET_MODE (sparc_compare_op0) == DImode)
1722 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1725 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1727 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1728 emit_jump_insn (gen_bne (operands[0]));
1731 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1734 (define_expand "bltu"
1736 (if_then_else (ltu (match_dup 1) (const_int 0))
1737 (label_ref (match_operand 0 "" ""))
1741 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1744 (define_expand "bge"
1746 (if_then_else (ge (match_dup 1) (const_int 0))
1747 (label_ref (match_operand 0 "" ""))
1752 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1753 && GET_CODE (sparc_compare_op0) == REG
1754 && GET_MODE (sparc_compare_op0) == DImode)
1756 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1759 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1761 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1762 emit_jump_insn (gen_bne (operands[0]));
1765 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1768 (define_expand "bgeu"
1770 (if_then_else (geu (match_dup 1) (const_int 0))
1771 (label_ref (match_operand 0 "" ""))
1775 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1778 (define_expand "ble"
1780 (if_then_else (le (match_dup 1) (const_int 0))
1781 (label_ref (match_operand 0 "" ""))
1786 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1787 && GET_CODE (sparc_compare_op0) == REG
1788 && GET_MODE (sparc_compare_op0) == DImode)
1790 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1793 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1795 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1796 emit_jump_insn (gen_bne (operands[0]));
1799 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1802 (define_expand "bleu"
1804 (if_then_else (leu (match_dup 1) (const_int 0))
1805 (label_ref (match_operand 0 "" ""))
1809 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1812 (define_expand "bunordered"
1814 (if_then_else (unordered (match_dup 1) (const_int 0))
1815 (label_ref (match_operand 0 "" ""))
1820 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1822 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1824 emit_jump_insn (gen_beq (operands[0]));
1827 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1831 (define_expand "bordered"
1833 (if_then_else (ordered (match_dup 1) (const_int 0))
1834 (label_ref (match_operand 0 "" ""))
1839 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1841 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1842 emit_jump_insn (gen_bne (operands[0]));
1845 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1849 (define_expand "bungt"
1851 (if_then_else (ungt (match_dup 1) (const_int 0))
1852 (label_ref (match_operand 0 "" ""))
1857 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1859 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1860 emit_jump_insn (gen_bgt (operands[0]));
1863 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1866 (define_expand "bunlt"
1868 (if_then_else (unlt (match_dup 1) (const_int 0))
1869 (label_ref (match_operand 0 "" ""))
1874 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1876 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1877 emit_jump_insn (gen_bne (operands[0]));
1880 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1883 (define_expand "buneq"
1885 (if_then_else (uneq (match_dup 1) (const_int 0))
1886 (label_ref (match_operand 0 "" ""))
1891 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1893 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1894 emit_jump_insn (gen_beq (operands[0]));
1897 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1900 (define_expand "bunge"
1902 (if_then_else (unge (match_dup 1) (const_int 0))
1903 (label_ref (match_operand 0 "" ""))
1908 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1910 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1911 emit_jump_insn (gen_bne (operands[0]));
1914 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1917 (define_expand "bunle"
1919 (if_then_else (unle (match_dup 1) (const_int 0))
1920 (label_ref (match_operand 0 "" ""))
1925 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1927 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1928 emit_jump_insn (gen_bne (operands[0]));
1931 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1934 (define_expand "bltgt"
1936 (if_then_else (ltgt (match_dup 1) (const_int 0))
1937 (label_ref (match_operand 0 "" ""))
1942 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1944 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1945 emit_jump_insn (gen_bne (operands[0]));
1948 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1951 ;; Now match both normal and inverted jump.
1953 ;; XXX fpcmp nop braindamage
1954 (define_insn "*normal_branch"
1956 (if_then_else (match_operator 0 "noov_compare_op"
1957 [(reg 100) (const_int 0)])
1958 (label_ref (match_operand 1 "" ""))
1963 return output_cbranch (operands[0], operands[1], 1, 0,
1964 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1965 ! final_sequence, insn);
1967 [(set_attr "type" "branch")
1968 (set_attr "branch_type" "icc")])
1970 ;; XXX fpcmp nop braindamage
1971 (define_insn "*inverted_branch"
1973 (if_then_else (match_operator 0 "noov_compare_op"
1974 [(reg 100) (const_int 0)])
1976 (label_ref (match_operand 1 "" ""))))]
1980 return output_cbranch (operands[0], operands[1], 1, 1,
1981 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1982 ! final_sequence, insn);
1984 [(set_attr "type" "branch")
1985 (set_attr "branch_type" "icc")])
1987 ;; XXX fpcmp nop braindamage
1988 (define_insn "*normal_fp_branch"
1990 (if_then_else (match_operator 1 "comparison_operator"
1991 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1993 (label_ref (match_operand 2 "" ""))
1998 return output_cbranch (operands[1], operands[2], 2, 0,
1999 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2000 ! final_sequence, insn);
2002 [(set_attr "type" "branch")
2003 (set_attr "branch_type" "fcc")])
2005 ;; XXX fpcmp nop braindamage
2006 (define_insn "*inverted_fp_branch"
2008 (if_then_else (match_operator 1 "comparison_operator"
2009 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
2012 (label_ref (match_operand 2 "" ""))))]
2016 return output_cbranch (operands[1], operands[2], 2, 1,
2017 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2018 ! final_sequence, insn);
2020 [(set_attr "type" "branch")
2021 (set_attr "branch_type" "fcc")])
2023 ;; XXX fpcmp nop braindamage
2024 (define_insn "*normal_fpe_branch"
2026 (if_then_else (match_operator 1 "comparison_operator"
2027 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2029 (label_ref (match_operand 2 "" ""))
2034 return output_cbranch (operands[1], operands[2], 2, 0,
2035 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2036 ! final_sequence, insn);
2038 [(set_attr "type" "branch")
2039 (set_attr "branch_type" "fcc")])
2041 ;; XXX fpcmp nop braindamage
2042 (define_insn "*inverted_fpe_branch"
2044 (if_then_else (match_operator 1 "comparison_operator"
2045 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2048 (label_ref (match_operand 2 "" ""))))]
2052 return output_cbranch (operands[1], operands[2], 2, 1,
2053 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2054 ! final_sequence, insn);
2056 [(set_attr "type" "branch")
2057 (set_attr "branch_type" "fcc")])
2059 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2060 ;; in the architecture.
2062 ;; There are no 32 bit brreg insns.
2065 (define_insn "*normal_int_branch_sp64"
2067 (if_then_else (match_operator 0 "v9_regcmp_op"
2068 [(match_operand:DI 1 "register_operand" "r")
2070 (label_ref (match_operand 2 "" ""))
2075 return output_v9branch (operands[0], operands[2], 1, 2, 0,
2076 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2077 ! final_sequence, insn);
2079 [(set_attr "type" "branch")
2080 (set_attr "branch_type" "reg")])
2083 (define_insn "*inverted_int_branch_sp64"
2085 (if_then_else (match_operator 0 "v9_regcmp_op"
2086 [(match_operand:DI 1 "register_operand" "r")
2089 (label_ref (match_operand 2 "" ""))))]
2093 return output_v9branch (operands[0], operands[2], 1, 2, 1,
2094 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2095 ! final_sequence, insn);
2097 [(set_attr "type" "branch")
2098 (set_attr "branch_type" "reg")])
2100 ;; Load program counter insns.
2102 (define_insn "get_pc"
2103 [(clobber (reg:SI 15))
2104 (set (match_operand 0 "register_operand" "=r")
2105 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2106 "flag_pic && REGNO (operands[0]) == 23"
2107 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2108 [(set_attr "type" "multi")
2109 (set_attr "length" "3")])
2111 ;; Currently unused...
2112 ;; (define_insn "get_pc_via_rdpc"
2113 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2116 ;; [(set_attr "type" "misc")])
2119 ;; Move instructions
2121 (define_expand "movqi"
2122 [(set (match_operand:QI 0 "general_operand" "")
2123 (match_operand:QI 1 "general_operand" ""))]
2127 /* Working with CONST_INTs is easier, so convert
2128 a double if needed. */
2129 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2131 operands[1] = GEN_INT (trunc_int_for_mode
2132 (CONST_DOUBLE_LOW (operands[1]), QImode));
2135 /* Handle sets of MEM first. */
2136 if (GET_CODE (operands[0]) == MEM)
2138 if (reg_or_0_operand (operands[1], QImode))
2141 if (! reload_in_progress)
2143 operands[0] = validize_mem (operands[0]);
2144 operands[1] = force_reg (QImode, operands[1]);
2148 /* Fixup PIC cases. */
2151 if (CONSTANT_P (operands[1])
2152 && pic_address_needs_scratch (operands[1]))
2153 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2155 if (symbolic_operand (operands[1], QImode))
2157 operands[1] = legitimize_pic_address (operands[1],
2159 (reload_in_progress ?
2166 /* All QI constants require only one insn, so proceed. */
2172 (define_insn "*movqi_insn"
2173 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2174 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2175 "(register_operand (operands[0], QImode)
2176 || reg_or_0_operand (operands[1], QImode))"
2181 [(set_attr "type" "*,load,store")])
2183 (define_expand "movhi"
2184 [(set (match_operand:HI 0 "general_operand" "")
2185 (match_operand:HI 1 "general_operand" ""))]
2189 /* Working with CONST_INTs is easier, so convert
2190 a double if needed. */
2191 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2192 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2194 /* Handle sets of MEM first. */
2195 if (GET_CODE (operands[0]) == MEM)
2197 if (reg_or_0_operand (operands[1], HImode))
2200 if (! reload_in_progress)
2202 operands[0] = validize_mem (operands[0]);
2203 operands[1] = force_reg (HImode, operands[1]);
2207 /* Fixup PIC cases. */
2210 if (CONSTANT_P (operands[1])
2211 && pic_address_needs_scratch (operands[1]))
2212 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2214 if (symbolic_operand (operands[1], HImode))
2216 operands[1] = legitimize_pic_address (operands[1],
2218 (reload_in_progress ?
2225 /* This makes sure we will not get rematched due to splittage. */
2226 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2228 else if (CONSTANT_P (operands[1])
2229 && GET_CODE (operands[1]) != HIGH
2230 && GET_CODE (operands[1]) != LO_SUM)
2232 sparc_emit_set_const32 (operands[0], operands[1]);
2239 (define_insn "*movhi_const64_special"
2240 [(set (match_operand:HI 0 "register_operand" "=r")
2241 (match_operand:HI 1 "const64_high_operand" ""))]
2243 "sethi\\t%%hi(%a1), %0")
2245 (define_insn "*movhi_insn"
2246 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2247 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2248 "(register_operand (operands[0], HImode)
2249 || reg_or_0_operand (operands[1], HImode))"
2252 sethi\\t%%hi(%a1), %0
2255 [(set_attr "type" "*,*,load,store")])
2257 ;; We always work with constants here.
2258 (define_insn "*movhi_lo_sum"
2259 [(set (match_operand:HI 0 "register_operand" "=r")
2260 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2261 (match_operand:HI 2 "arith_operand" "I")))]
2265 (define_expand "movsi"
2266 [(set (match_operand:SI 0 "general_operand" "")
2267 (match_operand:SI 1 "general_operand" ""))]
2271 /* Working with CONST_INTs is easier, so convert
2272 a double if needed. */
2273 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2274 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2276 /* Handle sets of MEM first. */
2277 if (GET_CODE (operands[0]) == MEM)
2279 if (reg_or_0_operand (operands[1], SImode))
2282 if (! reload_in_progress)
2284 operands[0] = validize_mem (operands[0]);
2285 operands[1] = force_reg (SImode, operands[1]);
2289 /* Fixup PIC cases. */
2292 if (CONSTANT_P (operands[1])
2293 && pic_address_needs_scratch (operands[1]))
2294 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2296 if (GET_CODE (operands[1]) == LABEL_REF)
2299 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2303 if (symbolic_operand (operands[1], SImode))
2305 operands[1] = legitimize_pic_address (operands[1],
2307 (reload_in_progress ?
2314 /* If we are trying to toss an integer constant into the
2315 FPU registers, force it into memory. */
2316 if (GET_CODE (operands[0]) == REG
2317 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2318 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2319 && CONSTANT_P (operands[1]))
2320 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2323 /* This makes sure we will not get rematched due to splittage. */
2324 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2326 else if (CONSTANT_P (operands[1])
2327 && GET_CODE (operands[1]) != HIGH
2328 && GET_CODE (operands[1]) != LO_SUM)
2330 sparc_emit_set_const32 (operands[0], operands[1]);
2337 ;; This is needed to show CSE exactly which bits are set
2338 ;; in a 64-bit register by sethi instructions.
2339 (define_insn "*movsi_const64_special"
2340 [(set (match_operand:SI 0 "register_operand" "=r")
2341 (match_operand:SI 1 "const64_high_operand" ""))]
2343 "sethi\\t%%hi(%a1), %0")
2345 (define_insn "*movsi_insn"
2346 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2347 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2348 "(register_operand (operands[0], SImode)
2349 || reg_or_0_operand (operands[1], SImode))"
2353 sethi\\t%%hi(%a1), %0
2360 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2362 (define_insn "*movsi_lo_sum"
2363 [(set (match_operand:SI 0 "register_operand" "=r")
2364 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2365 (match_operand:SI 2 "immediate_operand" "in")))]
2367 "or\\t%1, %%lo(%a2), %0")
2369 (define_insn "*movsi_high"
2370 [(set (match_operand:SI 0 "register_operand" "=r")
2371 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2373 "sethi\\t%%hi(%a1), %0")
2375 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2376 ;; so that CSE won't optimize the address computation away.
2377 (define_insn "movsi_lo_sum_pic"
2378 [(set (match_operand:SI 0 "register_operand" "=r")
2379 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2380 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2382 "or\\t%1, %%lo(%a2), %0")
2384 (define_insn "movsi_high_pic"
2385 [(set (match_operand:SI 0 "register_operand" "=r")
2386 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2387 "flag_pic && check_pic (1)"
2388 "sethi\\t%%hi(%a1), %0")
2390 (define_expand "movsi_pic_label_ref"
2391 [(set (match_dup 3) (high:SI
2392 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2394 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2395 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2396 (set (match_operand:SI 0 "register_operand" "=r")
2397 (minus:SI (match_dup 5) (match_dup 4)))]
2401 current_function_uses_pic_offset_table = 1;
2402 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2405 operands[3] = operands[0];
2406 operands[4] = operands[0];
2410 operands[3] = gen_reg_rtx (SImode);
2411 operands[4] = gen_reg_rtx (SImode);
2413 operands[5] = pic_offset_table_rtx;
2416 (define_insn "*movsi_high_pic_label_ref"
2417 [(set (match_operand:SI 0 "register_operand" "=r")
2419 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2420 (match_operand:SI 2 "" "")] 5)))]
2422 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2424 (define_insn "*movsi_lo_sum_pic_label_ref"
2425 [(set (match_operand:SI 0 "register_operand" "=r")
2426 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2427 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2428 (match_operand:SI 3 "" "")] 5)))]
2430 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2432 (define_expand "movdi"
2433 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2434 (match_operand:DI 1 "general_operand" ""))]
2438 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2439 if (GET_CODE (operands[1]) == CONST_DOUBLE
2440 #if HOST_BITS_PER_WIDE_INT == 32
2441 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2442 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2443 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2444 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2447 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2449 /* Handle MEM cases first. */
2450 if (GET_CODE (operands[0]) == MEM)
2452 /* If it's a REG, we can always do it.
2453 The const zero case is more complex, on v9
2454 we can always perform it. */
2455 if (register_operand (operands[1], DImode)
2457 && (operands[1] == const0_rtx)))
2460 if (! reload_in_progress)
2462 operands[0] = validize_mem (operands[0]);
2463 operands[1] = force_reg (DImode, operands[1]);
2469 if (CONSTANT_P (operands[1])
2470 && pic_address_needs_scratch (operands[1]))
2471 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2473 if (GET_CODE (operands[1]) == LABEL_REF)
2475 if (! TARGET_ARCH64)
2477 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2481 if (symbolic_operand (operands[1], DImode))
2483 operands[1] = legitimize_pic_address (operands[1],
2485 (reload_in_progress ?
2492 /* If we are trying to toss an integer constant into the
2493 FPU registers, force it into memory. */
2494 if (GET_CODE (operands[0]) == REG
2495 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2496 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2497 && CONSTANT_P (operands[1]))
2498 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2501 /* This makes sure we will not get rematched due to splittage. */
2502 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2504 else if (TARGET_ARCH64
2505 && CONSTANT_P (operands[1])
2506 && GET_CODE (operands[1]) != HIGH
2507 && GET_CODE (operands[1]) != LO_SUM)
2509 sparc_emit_set_const64 (operands[0], operands[1]);
2517 ;; Be careful, fmovd does not exist when !arch64.
2518 ;; We match MEM moves directly when we have correct even
2519 ;; numbered registers, but fall into splits otherwise.
2520 ;; The constraint ordering here is really important to
2521 ;; avoid insane problems in reload, especially for patterns
2524 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2525 ;; (const_int -5016)))
2529 (define_insn "*movdi_insn_sp32_v9"
2530 [(set (match_operand:DI 0 "nonimmediate_operand"
2531 "=m,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2532 (match_operand:DI 1 "input_operand"
2533 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2534 "! TARGET_ARCH64 && TARGET_V9
2535 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2549 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2550 (set_attr "length" "*,*,*,2,2,2,2,*,*,2,2,2")])
2552 (define_insn "*movdi_insn_sp32"
2553 [(set (match_operand:DI 0 "nonimmediate_operand"
2554 "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2555 (match_operand:DI 1 "input_operand"
2556 " U,T,r,o,i,r, f, T, o, f, f"))]
2558 && (register_operand (operands[0], DImode)
2559 || register_operand (operands[1], DImode))"
2572 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2573 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2575 ;; The following are generated by sparc_emit_set_const64
2576 (define_insn "*movdi_sp64_dbl"
2577 [(set (match_operand:DI 0 "register_operand" "=r")
2578 (match_operand:DI 1 "const64_operand" ""))]
2580 && HOST_BITS_PER_WIDE_INT != 64)"
2583 ;; This is needed to show CSE exactly which bits are set
2584 ;; in a 64-bit register by sethi instructions.
2585 (define_insn "*movdi_const64_special"
2586 [(set (match_operand:DI 0 "register_operand" "=r")
2587 (match_operand:DI 1 "const64_high_operand" ""))]
2589 "sethi\\t%%hi(%a1), %0")
2591 (define_insn "*movdi_insn_sp64_novis"
2592 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2593 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e"))]
2594 "TARGET_ARCH64 && ! TARGET_VIS
2595 && (register_operand (operands[0], DImode)
2596 || reg_or_0_operand (operands[1], DImode))"
2599 sethi\\t%%hi(%a1), %0
2606 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2607 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2609 (define_insn "*movdi_insn_sp64_vis"
2610 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2611 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e,J"))]
2612 "TARGET_ARCH64 && TARGET_VIS &&
2613 (register_operand (operands[0], DImode)
2614 || reg_or_0_operand (operands[1], DImode))"
2617 sethi\\t%%hi(%a1), %0
2625 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2626 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2628 (define_expand "movdi_pic_label_ref"
2629 [(set (match_dup 3) (high:DI
2630 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2632 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2633 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2634 (set (match_operand:DI 0 "register_operand" "=r")
2635 (minus:DI (match_dup 5) (match_dup 4)))]
2636 "TARGET_ARCH64 && flag_pic"
2639 current_function_uses_pic_offset_table = 1;
2640 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2643 operands[3] = operands[0];
2644 operands[4] = operands[0];
2648 operands[3] = gen_reg_rtx (DImode);
2649 operands[4] = gen_reg_rtx (DImode);
2651 operands[5] = pic_offset_table_rtx;
2654 (define_insn "*movdi_high_pic_label_ref"
2655 [(set (match_operand:DI 0 "register_operand" "=r")
2657 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2658 (match_operand:DI 2 "" "")] 5)))]
2659 "TARGET_ARCH64 && flag_pic"
2660 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2662 (define_insn "*movdi_lo_sum_pic_label_ref"
2663 [(set (match_operand:DI 0 "register_operand" "=r")
2664 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2665 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2666 (match_operand:DI 3 "" "")] 5)))]
2667 "TARGET_ARCH64 && flag_pic"
2668 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2670 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2671 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2673 (define_insn "movdi_lo_sum_pic"
2674 [(set (match_operand:DI 0 "register_operand" "=r")
2675 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2676 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2677 "TARGET_ARCH64 && flag_pic"
2678 "or\\t%1, %%lo(%a2), %0")
2680 (define_insn "movdi_high_pic"
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2683 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2684 "sethi\\t%%hi(%a1), %0")
2686 (define_insn "*sethi_di_medlow_embmedany_pic"
2687 [(set (match_operand:DI 0 "register_operand" "=r")
2688 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2689 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2690 "sethi\\t%%hi(%a1), %0")
2692 (define_insn "*sethi_di_medlow"
2693 [(set (match_operand:DI 0 "register_operand" "=r")
2694 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2695 "TARGET_CM_MEDLOW && check_pic (1)"
2696 "sethi\\t%%hi(%a1), %0")
2698 (define_insn "*losum_di_medlow"
2699 [(set (match_operand:DI 0 "register_operand" "=r")
2700 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2701 (match_operand:DI 2 "symbolic_operand" "")))]
2703 "or\\t%1, %%lo(%a2), %0")
2705 (define_insn "seth44"
2706 [(set (match_operand:DI 0 "register_operand" "=r")
2707 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2709 "sethi\\t%%h44(%a1), %0")
2711 (define_insn "setm44"
2712 [(set (match_operand:DI 0 "register_operand" "=r")
2713 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2714 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2716 "or\\t%1, %%m44(%a2), %0")
2718 (define_insn "setl44"
2719 [(set (match_operand:DI 0 "register_operand" "=r")
2720 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2721 (match_operand:DI 2 "symbolic_operand" "")))]
2723 "or\\t%1, %%l44(%a2), %0")
2725 (define_insn "sethh"
2726 [(set (match_operand:DI 0 "register_operand" "=r")
2727 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2729 "sethi\\t%%hh(%a1), %0")
2731 (define_insn "setlm"
2732 [(set (match_operand:DI 0 "register_operand" "=r")
2733 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2735 "sethi\\t%%lm(%a1), %0")
2737 (define_insn "sethm"
2738 [(set (match_operand:DI 0 "register_operand" "=r")
2739 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2740 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2742 "or\\t%1, %%hm(%a2), %0")
2744 (define_insn "setlo"
2745 [(set (match_operand:DI 0 "register_operand" "=r")
2746 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2747 (match_operand:DI 2 "symbolic_operand" "")))]
2749 "or\\t%1, %%lo(%a2), %0")
2751 (define_insn "embmedany_sethi"
2752 [(set (match_operand:DI 0 "register_operand" "=r")
2753 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2754 "TARGET_CM_EMBMEDANY && check_pic (1)"
2755 "sethi\\t%%hi(%a1), %0")
2757 (define_insn "embmedany_losum"
2758 [(set (match_operand:DI 0 "register_operand" "=r")
2759 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2760 (match_operand:DI 2 "data_segment_operand" "")))]
2761 "TARGET_CM_EMBMEDANY"
2762 "add\\t%1, %%lo(%a2), %0")
2764 (define_insn "embmedany_brsum"
2765 [(set (match_operand:DI 0 "register_operand" "=r")
2766 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2767 "TARGET_CM_EMBMEDANY"
2770 (define_insn "embmedany_textuhi"
2771 [(set (match_operand:DI 0 "register_operand" "=r")
2772 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2773 "TARGET_CM_EMBMEDANY && check_pic (1)"
2774 "sethi\\t%%uhi(%a1), %0")
2776 (define_insn "embmedany_texthi"
2777 [(set (match_operand:DI 0 "register_operand" "=r")
2778 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2779 "TARGET_CM_EMBMEDANY && check_pic (1)"
2780 "sethi\\t%%hi(%a1), %0")
2782 (define_insn "embmedany_textulo"
2783 [(set (match_operand:DI 0 "register_operand" "=r")
2784 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2785 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2786 "TARGET_CM_EMBMEDANY"
2787 "or\\t%1, %%ulo(%a2), %0")
2789 (define_insn "embmedany_textlo"
2790 [(set (match_operand:DI 0 "register_operand" "=r")
2791 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2792 (match_operand:DI 2 "text_segment_operand" "")))]
2793 "TARGET_CM_EMBMEDANY"
2794 "or\\t%1, %%lo(%a2), %0")
2796 ;; Now some patterns to help reload out a bit.
2797 (define_expand "reload_indi"
2798 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2799 (match_operand:DI 1 "immediate_operand" "")
2800 (match_operand:TI 2 "register_operand" "=&r")])]
2802 || TARGET_CM_EMBMEDANY)
2806 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2810 (define_expand "reload_outdi"
2811 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2812 (match_operand:DI 1 "immediate_operand" "")
2813 (match_operand:TI 2 "register_operand" "=&r")])]
2815 || TARGET_CM_EMBMEDANY)
2819 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2823 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2825 [(set (match_operand:DI 0 "register_operand" "")
2826 (match_operand:DI 1 "const_int_operand" ""))]
2827 "! TARGET_ARCH64 && reload_completed"
2828 [(clobber (const_int 0))]
2831 #if HOST_BITS_PER_WIDE_INT == 32
2832 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2833 (INTVAL (operands[1]) < 0) ?
2836 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2839 unsigned int low, high;
2841 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2842 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2843 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2845 /* Slick... but this trick loses if this subreg constant part
2846 can be done in one insn. */
2847 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2848 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2849 gen_highpart (SImode, operands[0])));
2851 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2857 [(set (match_operand:DI 0 "register_operand" "")
2858 (match_operand:DI 1 "const_double_operand" ""))]
2859 "! TARGET_ARCH64 && reload_completed"
2860 [(clobber (const_int 0))]
2863 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2864 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2866 /* Slick... but this trick loses if this subreg constant part
2867 can be done in one insn. */
2868 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2869 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2870 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2872 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2873 gen_highpart (SImode, operands[0])));
2877 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2878 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2884 [(set (match_operand:DI 0 "register_operand" "")
2885 (match_operand:DI 1 "register_operand" ""))]
2886 "! TARGET_ARCH64 && reload_completed"
2887 [(clobber (const_int 0))]
2890 rtx set_dest = operands[0];
2891 rtx set_src = operands[1];
2895 dest1 = gen_highpart (SImode, set_dest);
2896 dest2 = gen_lowpart (SImode, set_dest);
2897 src1 = gen_highpart (SImode, set_src);
2898 src2 = gen_lowpart (SImode, set_src);
2900 /* Now emit using the real source and destination we found, swapping
2901 the order if we detect overlap. */
2902 if (reg_overlap_mentioned_p (dest1, src2))
2904 emit_insn (gen_movsi (dest2, src2));
2905 emit_insn (gen_movsi (dest1, src1));
2909 emit_insn (gen_movsi (dest1, src1));
2910 emit_insn (gen_movsi (dest2, src2));
2915 ;; Now handle the cases of memory moves from/to non-even
2916 ;; DI mode register pairs.
2918 [(set (match_operand:DI 0 "register_operand" "")
2919 (match_operand:DI 1 "memory_operand" ""))]
2922 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2923 [(clobber (const_int 0))]
2926 rtx word0 = adjust_address (operands[1], SImode, 0);
2927 rtx word1 = adjust_address (operands[1], SImode, 4);
2928 rtx high_part = gen_highpart (SImode, operands[0]);
2929 rtx low_part = gen_lowpart (SImode, operands[0]);
2931 if (reg_overlap_mentioned_p (high_part, word1))
2933 emit_insn (gen_movsi (low_part, word1));
2934 emit_insn (gen_movsi (high_part, word0));
2938 emit_insn (gen_movsi (high_part, word0));
2939 emit_insn (gen_movsi (low_part, word1));
2945 [(set (match_operand:DI 0 "memory_operand" "")
2946 (match_operand:DI 1 "register_operand" ""))]
2949 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2950 [(clobber (const_int 0))]
2953 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2954 gen_highpart (SImode, operands[1])));
2955 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2956 gen_lowpart (SImode, operands[1])));
2961 ;; Floating point move insns
2963 (define_insn "*movsf_insn_novis"
2964 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2965 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2966 "(TARGET_FPU && ! TARGET_VIS)
2967 && (register_operand (operands[0], SFmode)
2968 || register_operand (operands[1], SFmode)
2969 || fp_zero_operand (operands[1], SFmode))"
2972 if (GET_CODE (operands[1]) == CONST_DOUBLE
2973 && (which_alternative == 2
2974 || which_alternative == 3
2975 || which_alternative == 4))
2980 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2981 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2982 operands[1] = GEN_INT (i);
2985 switch (which_alternative)
2988 return \"fmovs\\t%1, %0\";
2990 return \"clr\\t%0\";
2992 return \"sethi\\t%%hi(%a1), %0\";
2994 return \"mov\\t%1, %0\";
2999 return \"ld\\t%1, %0\";
3002 return \"st\\t%r1, %0\";
3007 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3009 (define_insn "*movsf_insn_vis"
3010 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3011 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3012 "(TARGET_FPU && TARGET_VIS)
3013 && (register_operand (operands[0], SFmode)
3014 || register_operand (operands[1], SFmode)
3015 || fp_zero_operand (operands[1], SFmode))"
3018 if (GET_CODE (operands[1]) == CONST_DOUBLE
3019 && (which_alternative == 3
3020 || which_alternative == 4
3021 || which_alternative == 5))
3026 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3027 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3028 operands[1] = GEN_INT (i);
3031 switch (which_alternative)
3034 return \"fmovs\\t%1, %0\";
3036 return \"fzeros\\t%0\";
3038 return \"clr\\t%0\";
3040 return \"sethi\\t%%hi(%a1), %0\";
3042 return \"mov\\t%1, %0\";
3047 return \"ld\\t%1, %0\";
3050 return \"st\\t%r1, %0\";
3055 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3057 ;; Exactly the same as above, except that all `f' cases are deleted.
3058 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3061 (define_insn "*movsf_no_f_insn"
3062 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3063 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3065 && (register_operand (operands[0], SFmode)
3066 || register_operand (operands[1], SFmode)
3067 || fp_zero_operand (operands[1], SFmode))"
3070 if (GET_CODE (operands[1]) == CONST_DOUBLE
3071 && (which_alternative == 1
3072 || which_alternative == 2
3073 || which_alternative == 3))
3078 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3079 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3080 operands[1] = GEN_INT (i);
3083 switch (which_alternative)
3086 return \"clr\\t%0\";
3088 return \"sethi\\t%%hi(%a1), %0\";
3090 return \"mov\\t%1, %0\";
3094 return \"ld\\t%1, %0\";
3096 return \"st\\t%r1, %0\";
3101 [(set_attr "type" "*,*,*,*,load,store")])
3103 (define_insn "*movsf_lo_sum"
3104 [(set (match_operand:SF 0 "register_operand" "=r")
3105 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3106 (match_operand:SF 2 "const_double_operand" "S")))]
3107 "fp_high_losum_p (operands[2])"
3113 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3114 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3115 operands[2] = GEN_INT (i);
3116 return \"or\\t%1, %%lo(%a2), %0\";
3119 (define_insn "*movsf_high"
3120 [(set (match_operand:SF 0 "register_operand" "=r")
3121 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3122 "fp_high_losum_p (operands[1])"
3128 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3129 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3130 operands[1] = GEN_INT (i);
3131 return \"sethi\\t%%hi(%1), %0\";
3135 [(set (match_operand:SF 0 "register_operand" "")
3136 (match_operand:SF 1 "const_double_operand" ""))]
3137 "fp_high_losum_p (operands[1])
3138 && (GET_CODE (operands[0]) == REG
3139 && REGNO (operands[0]) < 32)"
3140 [(set (match_dup 0) (high:SF (match_dup 1)))
3141 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3143 (define_expand "movsf"
3144 [(set (match_operand:SF 0 "general_operand" "")
3145 (match_operand:SF 1 "general_operand" ""))]
3149 /* Force SFmode constants into memory. */
3150 if (GET_CODE (operands[0]) == REG
3151 && CONSTANT_P (operands[1]))
3153 /* emit_group_store will send such bogosity to us when it is
3154 not storing directly into memory. So fix this up to avoid
3155 crashes in output_constant_pool. */
3156 if (operands [1] == const0_rtx)
3157 operands[1] = CONST0_RTX (SFmode);
3159 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3162 /* We are able to build any SF constant in integer registers
3163 with at most 2 instructions. */
3164 if (REGNO (operands[0]) < 32)
3167 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3171 /* Handle sets of MEM first. */
3172 if (GET_CODE (operands[0]) == MEM)
3174 if (register_operand (operands[1], SFmode)
3175 || fp_zero_operand (operands[1], SFmode))
3178 if (! reload_in_progress)
3180 operands[0] = validize_mem (operands[0]);
3181 operands[1] = force_reg (SFmode, operands[1]);
3185 /* Fixup PIC cases. */
3188 if (CONSTANT_P (operands[1])
3189 && pic_address_needs_scratch (operands[1]))
3190 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3192 if (symbolic_operand (operands[1], SFmode))
3194 operands[1] = legitimize_pic_address (operands[1],
3196 (reload_in_progress ?
3206 (define_expand "movdf"
3207 [(set (match_operand:DF 0 "general_operand" "")
3208 (match_operand:DF 1 "general_operand" ""))]
3212 /* Force DFmode constants into memory. */
3213 if (GET_CODE (operands[0]) == REG
3214 && CONSTANT_P (operands[1]))
3216 /* emit_group_store will send such bogosity to us when it is
3217 not storing directly into memory. So fix this up to avoid
3218 crashes in output_constant_pool. */
3219 if (operands [1] == const0_rtx)
3220 operands[1] = CONST0_RTX (DFmode);
3222 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3223 && fp_zero_operand (operands[1], DFmode))
3226 /* We are able to build any DF constant in integer registers. */
3227 if (REGNO (operands[0]) < 32
3228 && (reload_completed || reload_in_progress))
3231 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3235 /* Handle MEM cases first. */
3236 if (GET_CODE (operands[0]) == MEM)
3238 if (register_operand (operands[1], DFmode)
3239 || fp_zero_operand (operands[1], DFmode))
3242 if (! reload_in_progress)
3244 operands[0] = validize_mem (operands[0]);
3245 operands[1] = force_reg (DFmode, operands[1]);
3249 /* Fixup PIC cases. */
3252 if (CONSTANT_P (operands[1])
3253 && pic_address_needs_scratch (operands[1]))
3254 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3256 if (symbolic_operand (operands[1], DFmode))
3258 operands[1] = legitimize_pic_address (operands[1],
3260 (reload_in_progress ?
3270 ;; Be careful, fmovd does not exist when !v9.
3271 (define_insn "*movdf_insn_sp32"
3272 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3273 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3276 && (register_operand (operands[0], DFmode)
3277 || register_operand (operands[1], DFmode)
3278 || fp_zero_operand (operands[1], DFmode))"
3290 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3291 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3293 (define_insn "*movdf_no_e_insn_sp32"
3294 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3295 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3299 && (register_operand (operands[0], DFmode)
3300 || register_operand (operands[1], DFmode)
3301 || fp_zero_operand (operands[1], DFmode))"
3308 [(set_attr "type" "load,store,*,*,*")
3309 (set_attr "length" "*,*,2,2,2")])
3311 (define_insn "*movdf_no_e_insn_v9_sp32"
3312 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3313 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3317 && (register_operand (operands[0], DFmode)
3318 || register_operand (operands[1], DFmode)
3319 || fp_zero_operand (operands[1], DFmode))"
3326 [(set_attr "type" "load,store,store,*,*")
3327 (set_attr "length" "*,*,*,2,2")])
3329 ;; We have available v9 double floats but not 64-bit
3330 ;; integer registers and no VIS.
3331 (define_insn "*movdf_insn_v9only_novis"
3332 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3333 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3338 && (register_operand (operands[0], DFmode)
3339 || register_operand (operands[1], DFmode)
3340 || fp_zero_operand (operands[1], DFmode))"
3351 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3352 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3353 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3355 ;; We have available v9 double floats but not 64-bit
3356 ;; integer registers but we have VIS.
3357 (define_insn "*movdf_insn_v9only_vis"
3358 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3359 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3363 && (register_operand (operands[0], DFmode)
3364 || register_operand (operands[1], DFmode)
3365 || fp_zero_operand (operands[1], DFmode))"
3377 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3378 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3379 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3381 ;; We have available both v9 double floats and 64-bit
3382 ;; integer registers. No VIS though.
3383 (define_insn "*movdf_insn_sp64_novis"
3384 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3385 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3389 && (register_operand (operands[0], DFmode)
3390 || register_operand (operands[1], DFmode)
3391 || fp_zero_operand (operands[1], DFmode))"
3400 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3401 (set_attr "length" "*,*,*,*,*,*,2")
3402 (set_attr "fptype" "double,*,*,*,*,*,*")])
3404 ;; We have available both v9 double floats and 64-bit
3405 ;; integer registers. And we have VIS.
3406 (define_insn "*movdf_insn_sp64_vis"
3407 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3408 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3412 && (register_operand (operands[0], DFmode)
3413 || register_operand (operands[1], DFmode)
3414 || fp_zero_operand (operands[1], DFmode))"
3424 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3425 (set_attr "length" "*,*,*,*,*,*,*,2")
3426 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3428 (define_insn "*movdf_no_e_insn_sp64"
3429 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3430 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3433 && (register_operand (operands[0], DFmode)
3434 || register_operand (operands[1], DFmode)
3435 || fp_zero_operand (operands[1], DFmode))"
3440 [(set_attr "type" "*,load,store")])
3443 [(set (match_operand:DF 0 "register_operand" "")
3444 (match_operand:DF 1 "const_double_operand" ""))]
3446 && (GET_CODE (operands[0]) == REG
3447 && REGNO (operands[0]) < 32)
3448 && ! fp_zero_operand(operands[1], DFmode)
3449 && reload_completed"
3450 [(clobber (const_int 0))]
3456 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3457 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3458 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3462 #if HOST_BITS_PER_WIDE_INT == 64
3465 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3466 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3467 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3469 emit_insn (gen_movdi (operands[0],
3470 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3475 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3478 /* Slick... but this trick loses if this subreg constant part
3479 can be done in one insn. */
3481 && !(SPARC_SETHI32_P (l[0])
3482 || SPARC_SIMM13_P (l[0])))
3484 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3485 gen_highpart (SImode, operands[0])));
3489 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3496 ;; Ok, now the splits to handle all the multi insn and
3497 ;; mis-aligned memory address cases.
3498 ;; In these splits please take note that we must be
3499 ;; careful when V9 but not ARCH64 because the integer
3500 ;; register DFmode cases must be handled.
3502 [(set (match_operand:DF 0 "register_operand" "")
3503 (match_operand:DF 1 "register_operand" ""))]
3506 && ((GET_CODE (operands[0]) == REG
3507 && REGNO (operands[0]) < 32)
3508 || (GET_CODE (operands[0]) == SUBREG
3509 && GET_CODE (SUBREG_REG (operands[0])) == REG
3510 && REGNO (SUBREG_REG (operands[0])) < 32))))
3511 && reload_completed"
3512 [(clobber (const_int 0))]
3515 rtx set_dest = operands[0];
3516 rtx set_src = operands[1];
3520 dest1 = gen_highpart (SFmode, set_dest);
3521 dest2 = gen_lowpart (SFmode, set_dest);
3522 src1 = gen_highpart (SFmode, set_src);
3523 src2 = gen_lowpart (SFmode, set_src);
3525 /* Now emit using the real source and destination we found, swapping
3526 the order if we detect overlap. */
3527 if (reg_overlap_mentioned_p (dest1, src2))
3529 emit_insn (gen_movsf (dest2, src2));
3530 emit_insn (gen_movsf (dest1, src1));
3534 emit_insn (gen_movsf (dest1, src1));
3535 emit_insn (gen_movsf (dest2, src2));
3541 [(set (match_operand:DF 0 "register_operand" "")
3542 (match_operand:DF 1 "memory_operand" ""))]
3545 && (((REGNO (operands[0]) % 2) != 0)
3546 || ! mem_min_alignment (operands[1], 8))
3547 && offsettable_memref_p (operands[1])"
3548 [(clobber (const_int 0))]
3551 rtx word0 = adjust_address (operands[1], SFmode, 0);
3552 rtx word1 = adjust_address (operands[1], SFmode, 4);
3554 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3556 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3558 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3563 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3565 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3572 [(set (match_operand:DF 0 "memory_operand" "")
3573 (match_operand:DF 1 "register_operand" ""))]
3576 && (((REGNO (operands[1]) % 2) != 0)
3577 || ! mem_min_alignment (operands[0], 8))
3578 && offsettable_memref_p (operands[0])"
3579 [(clobber (const_int 0))]
3582 rtx word0 = adjust_address (operands[0], SFmode, 0);
3583 rtx word1 = adjust_address (operands[0], SFmode, 4);
3585 emit_insn (gen_movsf (word0,
3586 gen_highpart (SFmode, operands[1])));
3587 emit_insn (gen_movsf (word1,
3588 gen_lowpart (SFmode, operands[1])));
3593 [(set (match_operand:DF 0 "memory_operand" "")
3594 (match_operand:DF 1 "fp_zero_operand" ""))]
3598 && ! mem_min_alignment (operands[0], 8)))
3599 && offsettable_memref_p (operands[0])"
3600 [(clobber (const_int 0))]
3605 dest1 = adjust_address (operands[0], SFmode, 0);
3606 dest2 = adjust_address (operands[0], SFmode, 4);
3608 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3609 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3614 [(set (match_operand:DF 0 "register_operand" "")
3615 (match_operand:DF 1 "fp_zero_operand" ""))]
3618 && ((GET_CODE (operands[0]) == REG
3619 && REGNO (operands[0]) < 32)
3620 || (GET_CODE (operands[0]) == SUBREG
3621 && GET_CODE (SUBREG_REG (operands[0])) == REG
3622 && REGNO (SUBREG_REG (operands[0])) < 32))"
3623 [(clobber (const_int 0))]
3626 rtx set_dest = operands[0];
3629 dest1 = gen_highpart (SFmode, set_dest);
3630 dest2 = gen_lowpart (SFmode, set_dest);
3631 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3632 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3636 (define_expand "movtf"
3637 [(set (match_operand:TF 0 "general_operand" "")
3638 (match_operand:TF 1 "general_operand" ""))]
3642 /* Force TFmode constants into memory. */
3643 if (GET_CODE (operands[0]) == REG
3644 && CONSTANT_P (operands[1]))
3646 /* emit_group_store will send such bogosity to us when it is
3647 not storing directly into memory. So fix this up to avoid
3648 crashes in output_constant_pool. */
3649 if (operands [1] == const0_rtx)
3650 operands[1] = CONST0_RTX (TFmode);
3652 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3655 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3659 /* Handle MEM cases first, note that only v9 guarentees
3660 full 16-byte alignment for quads. */
3661 if (GET_CODE (operands[0]) == MEM)
3663 if (register_operand (operands[1], TFmode)
3664 || fp_zero_operand (operands[1], TFmode))
3667 if (! reload_in_progress)
3669 operands[0] = validize_mem (operands[0]);
3670 operands[1] = force_reg (TFmode, operands[1]);
3674 /* Fixup PIC cases. */
3677 if (CONSTANT_P (operands[1])
3678 && pic_address_needs_scratch (operands[1]))
3679 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3681 if (symbolic_operand (operands[1], TFmode))
3683 operands[1] = legitimize_pic_address (operands[1],
3685 (reload_in_progress ?
3695 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3696 ;; we must split them all. :-(
3697 (define_insn "*movtf_insn_sp32"
3698 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3699 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3703 && (register_operand (operands[0], TFmode)
3704 || register_operand (operands[1], TFmode)
3705 || fp_zero_operand (operands[1], TFmode))"
3707 [(set_attr "length" "4")])
3709 (define_insn "*movtf_insn_vis_sp32"
3710 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3711 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3715 && (register_operand (operands[0], TFmode)
3716 || register_operand (operands[1], TFmode)
3717 || fp_zero_operand (operands[1], TFmode))"
3719 [(set_attr "length" "4")])
3721 ;; Exactly the same as above, except that all `e' cases are deleted.
3722 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3725 (define_insn "*movtf_no_e_insn_sp32"
3726 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3727 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3730 && (register_operand (operands[0], TFmode)
3731 || register_operand (operands[1], TFmode)
3732 || fp_zero_operand (operands[1], TFmode))"
3734 [(set_attr "length" "4")])
3736 ;; Now handle the float reg cases directly when arch64,
3737 ;; hard_quad, and proper reg number alignment are all true.
3738 (define_insn "*movtf_insn_hq_sp64"
3739 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3740 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3745 && (register_operand (operands[0], TFmode)
3746 || register_operand (operands[1], TFmode)
3747 || fp_zero_operand (operands[1], TFmode))"
3754 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3755 (set_attr "length" "*,*,*,2,2")])
3757 (define_insn "*movtf_insn_hq_vis_sp64"
3758 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3759 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3764 && (register_operand (operands[0], TFmode)
3765 || register_operand (operands[1], TFmode)
3766 || fp_zero_operand (operands[1], TFmode))"
3774 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3775 (set_attr "length" "*,*,*,2,2,2")])
3777 ;; Now we allow the integer register cases even when
3778 ;; only arch64 is true.
3779 (define_insn "*movtf_insn_sp64"
3780 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3781 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3785 && ! TARGET_HARD_QUAD
3786 && (register_operand (operands[0], TFmode)
3787 || register_operand (operands[1], TFmode)
3788 || fp_zero_operand (operands[1], TFmode))"
3790 [(set_attr "length" "2")])
3792 (define_insn "*movtf_insn_vis_sp64"
3793 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3794 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3798 && ! TARGET_HARD_QUAD
3799 && (register_operand (operands[0], TFmode)
3800 || register_operand (operands[1], TFmode)
3801 || fp_zero_operand (operands[1], TFmode))"
3803 [(set_attr "length" "2")])
3805 (define_insn "*movtf_no_e_insn_sp64"
3806 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3807 (match_operand:TF 1 "input_operand" "orG,rG"))]
3810 && (register_operand (operands[0], TFmode)
3811 || register_operand (operands[1], TFmode)
3812 || fp_zero_operand (operands[1], TFmode))"
3814 [(set_attr "length" "2")])
3816 ;; Now all the splits to handle multi-insn TF mode moves.
3818 [(set (match_operand:TF 0 "register_operand" "")
3819 (match_operand:TF 1 "register_operand" ""))]
3823 && ! TARGET_HARD_QUAD))"
3824 [(clobber (const_int 0))]
3827 rtx set_dest = operands[0];
3828 rtx set_src = operands[1];
3832 dest1 = gen_df_reg (set_dest, 0);
3833 dest2 = gen_df_reg (set_dest, 1);
3834 src1 = gen_df_reg (set_src, 0);
3835 src2 = gen_df_reg (set_src, 1);
3837 /* Now emit using the real source and destination we found, swapping
3838 the order if we detect overlap. */
3839 if (reg_overlap_mentioned_p (dest1, src2))
3841 emit_insn (gen_movdf (dest2, src2));
3842 emit_insn (gen_movdf (dest1, src1));
3846 emit_insn (gen_movdf (dest1, src1));
3847 emit_insn (gen_movdf (dest2, src2));
3853 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3854 (match_operand:TF 1 "fp_zero_operand" ""))]
3856 [(clobber (const_int 0))]
3859 rtx set_dest = operands[0];
3862 switch (GET_CODE (set_dest))
3865 dest1 = gen_df_reg (set_dest, 0);
3866 dest2 = gen_df_reg (set_dest, 1);
3869 dest1 = adjust_address (set_dest, DFmode, 0);
3870 dest2 = adjust_address (set_dest, DFmode, 8);
3876 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3877 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3882 [(set (match_operand:TF 0 "register_operand" "")
3883 (match_operand:TF 1 "memory_operand" ""))]
3885 && offsettable_memref_p (operands[1]))"
3886 [(clobber (const_int 0))]
3889 rtx word0 = adjust_address (operands[1], DFmode, 0);
3890 rtx word1 = adjust_address (operands[1], DFmode, 8);
3891 rtx set_dest, dest1, dest2;
3893 set_dest = operands[0];
3895 dest1 = gen_df_reg (set_dest, 0);
3896 dest2 = gen_df_reg (set_dest, 1);
3898 /* Now output, ordering such that we don't clobber any registers
3899 mentioned in the address. */
3900 if (reg_overlap_mentioned_p (dest1, word1))
3903 emit_insn (gen_movdf (dest2, word1));
3904 emit_insn (gen_movdf (dest1, word0));
3908 emit_insn (gen_movdf (dest1, word0));
3909 emit_insn (gen_movdf (dest2, word1));
3915 [(set (match_operand:TF 0 "memory_operand" "")
3916 (match_operand:TF 1 "register_operand" ""))]
3918 && offsettable_memref_p (operands[0]))"
3919 [(clobber (const_int 0))]
3922 rtx set_src = operands[1];
3924 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3925 gen_df_reg (set_src, 0)));
3926 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3927 gen_df_reg (set_src, 1)));
3931 ;; Sparc V9 conditional move instructions.
3933 ;; We can handle larger constants here for some flavors, but for now we keep
3934 ;; it simple and only allow those constants supported by all flavours.
3935 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3936 ;; 3 contains the constant if one is present, but we handle either for
3937 ;; generality (sparc.c puts a constant in operand 2).
3939 (define_expand "movqicc"
3940 [(set (match_operand:QI 0 "register_operand" "")
3941 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3942 (match_operand:QI 2 "arith10_operand" "")
3943 (match_operand:QI 3 "arith10_operand" "")))]
3947 enum rtx_code code = GET_CODE (operands[1]);
3949 if (GET_MODE (sparc_compare_op0) == DImode
3953 if (sparc_compare_op1 == const0_rtx
3954 && GET_CODE (sparc_compare_op0) == REG
3955 && GET_MODE (sparc_compare_op0) == DImode
3956 && v9_regcmp_p (code))
3958 operands[1] = gen_rtx_fmt_ee (code, DImode,
3959 sparc_compare_op0, sparc_compare_op1);
3963 rtx cc_reg = gen_compare_reg (code,
3964 sparc_compare_op0, sparc_compare_op1);
3965 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3969 (define_expand "movhicc"
3970 [(set (match_operand:HI 0 "register_operand" "")
3971 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3972 (match_operand:HI 2 "arith10_operand" "")
3973 (match_operand:HI 3 "arith10_operand" "")))]
3977 enum rtx_code code = GET_CODE (operands[1]);
3979 if (GET_MODE (sparc_compare_op0) == DImode
3983 if (sparc_compare_op1 == const0_rtx
3984 && GET_CODE (sparc_compare_op0) == REG
3985 && GET_MODE (sparc_compare_op0) == DImode
3986 && v9_regcmp_p (code))
3988 operands[1] = gen_rtx_fmt_ee (code, DImode,
3989 sparc_compare_op0, sparc_compare_op1);
3993 rtx cc_reg = gen_compare_reg (code,
3994 sparc_compare_op0, sparc_compare_op1);
3995 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3999 (define_expand "movsicc"
4000 [(set (match_operand:SI 0 "register_operand" "")
4001 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4002 (match_operand:SI 2 "arith10_operand" "")
4003 (match_operand:SI 3 "arith10_operand" "")))]
4007 enum rtx_code code = GET_CODE (operands[1]);
4008 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4010 if (sparc_compare_op1 == const0_rtx
4011 && GET_CODE (sparc_compare_op0) == REG
4012 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4014 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4015 sparc_compare_op0, sparc_compare_op1);
4019 rtx cc_reg = gen_compare_reg (code,
4020 sparc_compare_op0, sparc_compare_op1);
4021 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4022 cc_reg, const0_rtx);
4026 (define_expand "movdicc"
4027 [(set (match_operand:DI 0 "register_operand" "")
4028 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4029 (match_operand:DI 2 "arith10_double_operand" "")
4030 (match_operand:DI 3 "arith10_double_operand" "")))]
4034 enum rtx_code code = GET_CODE (operands[1]);
4036 if (sparc_compare_op1 == const0_rtx
4037 && GET_CODE (sparc_compare_op0) == REG
4038 && GET_MODE (sparc_compare_op0) == DImode
4039 && v9_regcmp_p (code))
4041 operands[1] = gen_rtx_fmt_ee (code, DImode,
4042 sparc_compare_op0, sparc_compare_op1);
4046 rtx cc_reg = gen_compare_reg (code,
4047 sparc_compare_op0, sparc_compare_op1);
4048 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4049 cc_reg, const0_rtx);
4053 (define_expand "movsfcc"
4054 [(set (match_operand:SF 0 "register_operand" "")
4055 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4056 (match_operand:SF 2 "register_operand" "")
4057 (match_operand:SF 3 "register_operand" "")))]
4058 "TARGET_V9 && TARGET_FPU"
4061 enum rtx_code code = GET_CODE (operands[1]);
4063 if (GET_MODE (sparc_compare_op0) == DImode
4067 if (sparc_compare_op1 == const0_rtx
4068 && GET_CODE (sparc_compare_op0) == REG
4069 && GET_MODE (sparc_compare_op0) == DImode
4070 && v9_regcmp_p (code))
4072 operands[1] = gen_rtx_fmt_ee (code, DImode,
4073 sparc_compare_op0, sparc_compare_op1);
4077 rtx cc_reg = gen_compare_reg (code,
4078 sparc_compare_op0, sparc_compare_op1);
4079 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4083 (define_expand "movdfcc"
4084 [(set (match_operand:DF 0 "register_operand" "")
4085 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4086 (match_operand:DF 2 "register_operand" "")
4087 (match_operand:DF 3 "register_operand" "")))]
4088 "TARGET_V9 && TARGET_FPU"
4091 enum rtx_code code = GET_CODE (operands[1]);
4093 if (GET_MODE (sparc_compare_op0) == DImode
4097 if (sparc_compare_op1 == const0_rtx
4098 && GET_CODE (sparc_compare_op0) == REG
4099 && GET_MODE (sparc_compare_op0) == DImode
4100 && v9_regcmp_p (code))
4102 operands[1] = gen_rtx_fmt_ee (code, DImode,
4103 sparc_compare_op0, sparc_compare_op1);
4107 rtx cc_reg = gen_compare_reg (code,
4108 sparc_compare_op0, sparc_compare_op1);
4109 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4113 (define_expand "movtfcc"
4114 [(set (match_operand:TF 0 "register_operand" "")
4115 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4116 (match_operand:TF 2 "register_operand" "")
4117 (match_operand:TF 3 "register_operand" "")))]
4118 "TARGET_V9 && TARGET_FPU"
4121 enum rtx_code code = GET_CODE (operands[1]);
4123 if (GET_MODE (sparc_compare_op0) == DImode
4127 if (sparc_compare_op1 == const0_rtx
4128 && GET_CODE (sparc_compare_op0) == REG
4129 && GET_MODE (sparc_compare_op0) == DImode
4130 && v9_regcmp_p (code))
4132 operands[1] = gen_rtx_fmt_ee (code, DImode,
4133 sparc_compare_op0, sparc_compare_op1);
4137 rtx cc_reg = gen_compare_reg (code,
4138 sparc_compare_op0, sparc_compare_op1);
4139 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4143 ;; Conditional move define_insns.
4145 (define_insn "*movqi_cc_sp64"
4146 [(set (match_operand:QI 0 "register_operand" "=r,r")
4147 (if_then_else:QI (match_operator 1 "comparison_operator"
4148 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4150 (match_operand:QI 3 "arith11_operand" "rL,0")
4151 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4154 mov%C1\\t%x2, %3, %0
4155 mov%c1\\t%x2, %4, %0"
4156 [(set_attr "type" "cmove")])
4158 (define_insn "*movhi_cc_sp64"
4159 [(set (match_operand:HI 0 "register_operand" "=r,r")
4160 (if_then_else:HI (match_operator 1 "comparison_operator"
4161 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4163 (match_operand:HI 3 "arith11_operand" "rL,0")
4164 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4167 mov%C1\\t%x2, %3, %0
4168 mov%c1\\t%x2, %4, %0"
4169 [(set_attr "type" "cmove")])
4171 (define_insn "*movsi_cc_sp64"
4172 [(set (match_operand:SI 0 "register_operand" "=r,r")
4173 (if_then_else:SI (match_operator 1 "comparison_operator"
4174 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4176 (match_operand:SI 3 "arith11_operand" "rL,0")
4177 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4180 mov%C1\\t%x2, %3, %0
4181 mov%c1\\t%x2, %4, %0"
4182 [(set_attr "type" "cmove")])
4184 ;; ??? The constraints of operands 3,4 need work.
4185 (define_insn "*movdi_cc_sp64"
4186 [(set (match_operand:DI 0 "register_operand" "=r,r")
4187 (if_then_else:DI (match_operator 1 "comparison_operator"
4188 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4190 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4191 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4194 mov%C1\\t%x2, %3, %0
4195 mov%c1\\t%x2, %4, %0"
4196 [(set_attr "type" "cmove")])
4198 (define_insn "*movdi_cc_sp64_trunc"
4199 [(set (match_operand:SI 0 "register_operand" "=r,r")
4200 (if_then_else:SI (match_operator 1 "comparison_operator"
4201 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4203 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4204 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4207 mov%C1\\t%x2, %3, %0
4208 mov%c1\\t%x2, %4, %0"
4209 [(set_attr "type" "cmove")])
4211 (define_insn "*movsf_cc_sp64"
4212 [(set (match_operand:SF 0 "register_operand" "=f,f")
4213 (if_then_else:SF (match_operator 1 "comparison_operator"
4214 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4216 (match_operand:SF 3 "register_operand" "f,0")
4217 (match_operand:SF 4 "register_operand" "0,f")))]
4218 "TARGET_V9 && TARGET_FPU"
4220 fmovs%C1\\t%x2, %3, %0
4221 fmovs%c1\\t%x2, %4, %0"
4222 [(set_attr "type" "fpcmove")])
4224 (define_insn "movdf_cc_sp64"
4225 [(set (match_operand:DF 0 "register_operand" "=e,e")
4226 (if_then_else:DF (match_operator 1 "comparison_operator"
4227 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4229 (match_operand:DF 3 "register_operand" "e,0")
4230 (match_operand:DF 4 "register_operand" "0,e")))]
4231 "TARGET_V9 && TARGET_FPU"
4233 fmovd%C1\\t%x2, %3, %0
4234 fmovd%c1\\t%x2, %4, %0"
4235 [(set_attr "type" "fpcmove")
4236 (set_attr "fptype" "double")])
4238 (define_insn "*movtf_cc_hq_sp64"
4239 [(set (match_operand:TF 0 "register_operand" "=e,e")
4240 (if_then_else:TF (match_operator 1 "comparison_operator"
4241 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4243 (match_operand:TF 3 "register_operand" "e,0")
4244 (match_operand:TF 4 "register_operand" "0,e")))]
4245 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4247 fmovq%C1\\t%x2, %3, %0
4248 fmovq%c1\\t%x2, %4, %0"
4249 [(set_attr "type" "fpcmove")])
4251 (define_insn "*movtf_cc_sp64"
4252 [(set (match_operand:TF 0 "register_operand" "=e,e")
4253 (if_then_else:TF (match_operator 1 "comparison_operator"
4254 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4256 (match_operand:TF 3 "register_operand" "e,0")
4257 (match_operand:TF 4 "register_operand" "0,e")))]
4258 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4260 [(set_attr "length" "2")])
4263 [(set (match_operand:TF 0 "register_operand" "")
4264 (if_then_else:TF (match_operator 1 "comparison_operator"
4265 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4267 (match_operand:TF 3 "register_operand" "")
4268 (match_operand:TF 4 "register_operand" "")))]
4269 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4270 [(clobber (const_int 0))]
4273 rtx set_dest = operands[0];
4274 rtx set_srca = operands[3];
4275 rtx set_srcb = operands[4];
4276 int third = rtx_equal_p (set_dest, set_srca);
4278 rtx srca1, srca2, srcb1, srcb2;
4280 dest1 = gen_df_reg (set_dest, 0);
4281 dest2 = gen_df_reg (set_dest, 1);
4282 srca1 = gen_df_reg (set_srca, 0);
4283 srca2 = gen_df_reg (set_srca, 1);
4284 srcb1 = gen_df_reg (set_srcb, 0);
4285 srcb2 = gen_df_reg (set_srcb, 1);
4287 /* Now emit using the real source and destination we found, swapping
4288 the order if we detect overlap. */
4289 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4290 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4292 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4293 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4297 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4298 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4303 (define_insn "*movqi_cc_reg_sp64"
4304 [(set (match_operand:QI 0 "register_operand" "=r,r")
4305 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4306 [(match_operand:DI 2 "register_operand" "r,r")
4308 (match_operand:QI 3 "arith10_operand" "rM,0")
4309 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4312 movr%D1\\t%2, %r3, %0
4313 movr%d1\\t%2, %r4, %0"
4314 [(set_attr "type" "cmove")])
4316 (define_insn "*movhi_cc_reg_sp64"
4317 [(set (match_operand:HI 0 "register_operand" "=r,r")
4318 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4319 [(match_operand:DI 2 "register_operand" "r,r")
4321 (match_operand:HI 3 "arith10_operand" "rM,0")
4322 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4325 movr%D1\\t%2, %r3, %0
4326 movr%d1\\t%2, %r4, %0"
4327 [(set_attr "type" "cmove")])
4329 (define_insn "*movsi_cc_reg_sp64"
4330 [(set (match_operand:SI 0 "register_operand" "=r,r")
4331 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4332 [(match_operand:DI 2 "register_operand" "r,r")
4334 (match_operand:SI 3 "arith10_operand" "rM,0")
4335 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4338 movr%D1\\t%2, %r3, %0
4339 movr%d1\\t%2, %r4, %0"
4340 [(set_attr "type" "cmove")])
4342 ;; ??? The constraints of operands 3,4 need work.
4343 (define_insn "*movdi_cc_reg_sp64"
4344 [(set (match_operand:DI 0 "register_operand" "=r,r")
4345 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4346 [(match_operand:DI 2 "register_operand" "r,r")
4348 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4349 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4352 movr%D1\\t%2, %r3, %0
4353 movr%d1\\t%2, %r4, %0"
4354 [(set_attr "type" "cmove")])
4356 (define_insn "*movdi_cc_reg_sp64_trunc"
4357 [(set (match_operand:SI 0 "register_operand" "=r,r")
4358 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4359 [(match_operand:DI 2 "register_operand" "r,r")
4361 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4362 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4365 movr%D1\\t%2, %r3, %0
4366 movr%d1\\t%2, %r4, %0"
4367 [(set_attr "type" "cmove")])
4369 (define_insn "*movsf_cc_reg_sp64"
4370 [(set (match_operand:SF 0 "register_operand" "=f,f")
4371 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4372 [(match_operand:DI 2 "register_operand" "r,r")
4374 (match_operand:SF 3 "register_operand" "f,0")
4375 (match_operand:SF 4 "register_operand" "0,f")))]
4376 "TARGET_ARCH64 && TARGET_FPU"
4378 fmovrs%D1\\t%2, %3, %0
4379 fmovrs%d1\\t%2, %4, %0"
4380 [(set_attr "type" "fpcmove")])
4382 (define_insn "movdf_cc_reg_sp64"
4383 [(set (match_operand:DF 0 "register_operand" "=e,e")
4384 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4385 [(match_operand:DI 2 "register_operand" "r,r")
4387 (match_operand:DF 3 "register_operand" "e,0")
4388 (match_operand:DF 4 "register_operand" "0,e")))]
4389 "TARGET_ARCH64 && TARGET_FPU"
4391 fmovrd%D1\\t%2, %3, %0
4392 fmovrd%d1\\t%2, %4, %0"
4393 [(set_attr "type" "fpcmove")
4394 (set_attr "fptype" "double")])
4396 (define_insn "*movtf_cc_reg_hq_sp64"
4397 [(set (match_operand:TF 0 "register_operand" "=e,e")
4398 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4399 [(match_operand:DI 2 "register_operand" "r,r")
4401 (match_operand:TF 3 "register_operand" "e,0")
4402 (match_operand:TF 4 "register_operand" "0,e")))]
4403 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4405 fmovrq%D1\\t%2, %3, %0
4406 fmovrq%d1\\t%2, %4, %0"
4407 [(set_attr "type" "fpcmove")])
4409 (define_insn "*movtf_cc_reg_sp64"
4410 [(set (match_operand:TF 0 "register_operand" "=e,e")
4411 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4412 [(match_operand:DI 2 "register_operand" "r,r")
4414 (match_operand:TF 3 "register_operand" "e,0")
4415 (match_operand:TF 4 "register_operand" "0,e")))]
4416 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4418 [(set_attr "length" "2")])
4421 [(set (match_operand:TF 0 "register_operand" "")
4422 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4423 [(match_operand:DI 2 "register_operand" "")
4425 (match_operand:TF 3 "register_operand" "")
4426 (match_operand:TF 4 "register_operand" "")))]
4427 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4428 [(clobber (const_int 0))]
4431 rtx set_dest = operands[0];
4432 rtx set_srca = operands[3];
4433 rtx set_srcb = operands[4];
4434 int third = rtx_equal_p (set_dest, set_srca);
4436 rtx srca1, srca2, srcb1, srcb2;
4438 dest1 = gen_df_reg (set_dest, 0);
4439 dest2 = gen_df_reg (set_dest, 1);
4440 srca1 = gen_df_reg (set_srca, 0);
4441 srca2 = gen_df_reg (set_srca, 1);
4442 srcb1 = gen_df_reg (set_srcb, 0);
4443 srcb2 = gen_df_reg (set_srcb, 1);
4445 /* Now emit using the real source and destination we found, swapping
4446 the order if we detect overlap. */
4447 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4448 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4450 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4451 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4455 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4456 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4462 ;;- zero extension instructions
4464 ;; These patterns originally accepted general_operands, however, slightly
4465 ;; better code is generated by only accepting register_operands, and then
4466 ;; letting combine generate the ldu[hb] insns.
4468 (define_expand "zero_extendhisi2"
4469 [(set (match_operand:SI 0 "register_operand" "")
4470 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4474 rtx temp = gen_reg_rtx (SImode);
4475 rtx shift_16 = GEN_INT (16);
4476 int op1_subbyte = 0;
4478 if (GET_CODE (operand1) == SUBREG)
4480 op1_subbyte = SUBREG_BYTE (operand1);
4481 op1_subbyte /= GET_MODE_SIZE (SImode);
4482 op1_subbyte *= GET_MODE_SIZE (SImode);
4483 operand1 = XEXP (operand1, 0);
4486 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4488 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4492 (define_insn "*zero_extendhisi2_insn"
4493 [(set (match_operand:SI 0 "register_operand" "=r")
4494 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4497 [(set_attr "type" "load")])
4499 (define_expand "zero_extendqihi2"
4500 [(set (match_operand:HI 0 "register_operand" "")
4501 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4505 (define_insn "*zero_extendqihi2_insn"
4506 [(set (match_operand:HI 0 "register_operand" "=r,r")
4507 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4508 "GET_CODE (operands[1]) != CONST_INT"
4512 [(set_attr "type" "*,load")])
4514 (define_expand "zero_extendqisi2"
4515 [(set (match_operand:SI 0 "register_operand" "")
4516 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4520 (define_insn "*zero_extendqisi2_insn"
4521 [(set (match_operand:SI 0 "register_operand" "=r,r")
4522 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4523 "GET_CODE (operands[1]) != CONST_INT"
4527 [(set_attr "type" "*,load")])
4529 (define_expand "zero_extendqidi2"
4530 [(set (match_operand:DI 0 "register_operand" "")
4531 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4535 (define_insn "*zero_extendqidi2_insn"
4536 [(set (match_operand:DI 0 "register_operand" "=r,r")
4537 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4538 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4542 [(set_attr "type" "*,load")])
4544 (define_expand "zero_extendhidi2"
4545 [(set (match_operand:DI 0 "register_operand" "")
4546 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4550 rtx temp = gen_reg_rtx (DImode);
4551 rtx shift_48 = GEN_INT (48);
4552 int op1_subbyte = 0;
4554 if (GET_CODE (operand1) == SUBREG)
4556 op1_subbyte = SUBREG_BYTE (operand1);
4557 op1_subbyte /= GET_MODE_SIZE (DImode);
4558 op1_subbyte *= GET_MODE_SIZE (DImode);
4559 operand1 = XEXP (operand1, 0);
4562 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4564 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4568 (define_insn "*zero_extendhidi2_insn"
4569 [(set (match_operand:DI 0 "register_operand" "=r")
4570 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4573 [(set_attr "type" "load")])
4576 ;; ??? Write truncdisi pattern using sra?
4578 (define_expand "zero_extendsidi2"
4579 [(set (match_operand:DI 0 "register_operand" "")
4580 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4584 (define_insn "*zero_extendsidi2_insn_sp64"
4585 [(set (match_operand:DI 0 "register_operand" "=r,r")
4586 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4587 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4591 [(set_attr "type" "shift,load")])
4593 (define_insn "*zero_extendsidi2_insn_sp32"
4594 [(set (match_operand:DI 0 "register_operand" "=r")
4595 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4598 [(set_attr "length" "2")])
4601 [(set (match_operand:DI 0 "register_operand" "")
4602 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4603 "! TARGET_ARCH64 && reload_completed"
4604 [(set (match_dup 2) (match_dup 3))
4605 (set (match_dup 4) (match_dup 5))]
4610 dest1 = gen_highpart (SImode, operands[0]);
4611 dest2 = gen_lowpart (SImode, operands[0]);
4613 /* Swap the order in case of overlap. */
4614 if (REGNO (dest1) == REGNO (operands[1]))
4616 operands[2] = dest2;
4617 operands[3] = operands[1];
4618 operands[4] = dest1;
4619 operands[5] = const0_rtx;
4623 operands[2] = dest1;
4624 operands[3] = const0_rtx;
4625 operands[4] = dest2;
4626 operands[5] = operands[1];
4630 ;; Simplify comparisons of extended values.
4632 (define_insn "*cmp_zero_extendqisi2"
4634 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4637 "andcc\\t%0, 0xff, %%g0"
4638 [(set_attr "type" "compare")])
4640 (define_insn "*cmp_zero_qi"
4642 (compare:CC (match_operand:QI 0 "register_operand" "r")
4645 "andcc\\t%0, 0xff, %%g0"
4646 [(set_attr "type" "compare")])
4648 (define_insn "*cmp_zero_extendqisi2_set"
4650 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4652 (set (match_operand:SI 0 "register_operand" "=r")
4653 (zero_extend:SI (match_dup 1)))]
4655 "andcc\\t%1, 0xff, %0"
4656 [(set_attr "type" "compare")])
4658 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4660 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4663 (set (match_operand:SI 0 "register_operand" "=r")
4664 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4666 "andcc\\t%1, 0xff, %0"
4667 [(set_attr "type" "compare")])
4669 (define_insn "*cmp_zero_extendqidi2"
4671 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4674 "andcc\\t%0, 0xff, %%g0"
4675 [(set_attr "type" "compare")])
4677 (define_insn "*cmp_zero_qi_sp64"
4679 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4682 "andcc\\t%0, 0xff, %%g0"
4683 [(set_attr "type" "compare")])
4685 (define_insn "*cmp_zero_extendqidi2_set"
4687 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4689 (set (match_operand:DI 0 "register_operand" "=r")
4690 (zero_extend:DI (match_dup 1)))]
4692 "andcc\\t%1, 0xff, %0"
4693 [(set_attr "type" "compare")])
4695 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4697 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4700 (set (match_operand:DI 0 "register_operand" "=r")
4701 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4703 "andcc\\t%1, 0xff, %0"
4704 [(set_attr "type" "compare")])
4706 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4708 (define_insn "*cmp_siqi_trunc"
4710 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4713 "andcc\\t%0, 0xff, %%g0"
4714 [(set_attr "type" "compare")])
4716 (define_insn "*cmp_siqi_trunc_set"
4718 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4720 (set (match_operand:QI 0 "register_operand" "=r")
4721 (subreg:QI (match_dup 1) 3))]
4723 "andcc\\t%1, 0xff, %0"
4724 [(set_attr "type" "compare")])
4726 (define_insn "*cmp_diqi_trunc"
4728 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4731 "andcc\\t%0, 0xff, %%g0"
4732 [(set_attr "type" "compare")])
4734 (define_insn "*cmp_diqi_trunc_set"
4736 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4738 (set (match_operand:QI 0 "register_operand" "=r")
4739 (subreg:QI (match_dup 1) 7))]
4741 "andcc\\t%1, 0xff, %0"
4742 [(set_attr "type" "compare")])
4744 ;;- sign extension instructions
4746 ;; These patterns originally accepted general_operands, however, slightly
4747 ;; better code is generated by only accepting register_operands, and then
4748 ;; letting combine generate the lds[hb] insns.
4750 (define_expand "extendhisi2"
4751 [(set (match_operand:SI 0 "register_operand" "")
4752 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4756 rtx temp = gen_reg_rtx (SImode);
4757 rtx shift_16 = GEN_INT (16);
4758 int op1_subbyte = 0;
4760 if (GET_CODE (operand1) == SUBREG)
4762 op1_subbyte = SUBREG_BYTE (operand1);
4763 op1_subbyte /= GET_MODE_SIZE (SImode);
4764 op1_subbyte *= GET_MODE_SIZE (SImode);
4765 operand1 = XEXP (operand1, 0);
4768 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4770 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4774 (define_insn "*sign_extendhisi2_insn"
4775 [(set (match_operand:SI 0 "register_operand" "=r")
4776 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4779 [(set_attr "type" "sload")])
4781 (define_expand "extendqihi2"
4782 [(set (match_operand:HI 0 "register_operand" "")
4783 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4787 rtx temp = gen_reg_rtx (SImode);
4788 rtx shift_24 = GEN_INT (24);
4789 int op1_subbyte = 0;
4790 int op0_subbyte = 0;
4792 if (GET_CODE (operand1) == SUBREG)
4794 op1_subbyte = SUBREG_BYTE (operand1);
4795 op1_subbyte /= GET_MODE_SIZE (SImode);
4796 op1_subbyte *= GET_MODE_SIZE (SImode);
4797 operand1 = XEXP (operand1, 0);
4799 if (GET_CODE (operand0) == SUBREG)
4801 op0_subbyte = SUBREG_BYTE (operand0);
4802 op0_subbyte /= GET_MODE_SIZE (SImode);
4803 op0_subbyte *= GET_MODE_SIZE (SImode);
4804 operand0 = XEXP (operand0, 0);
4806 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4808 if (GET_MODE (operand0) != SImode)
4809 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4810 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4814 (define_insn "*sign_extendqihi2_insn"
4815 [(set (match_operand:HI 0 "register_operand" "=r")
4816 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4819 [(set_attr "type" "sload")])
4821 (define_expand "extendqisi2"
4822 [(set (match_operand:SI 0 "register_operand" "")
4823 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4827 rtx temp = gen_reg_rtx (SImode);
4828 rtx shift_24 = GEN_INT (24);
4829 int op1_subbyte = 0;
4831 if (GET_CODE (operand1) == SUBREG)
4833 op1_subbyte = SUBREG_BYTE (operand1);
4834 op1_subbyte /= GET_MODE_SIZE (SImode);
4835 op1_subbyte *= GET_MODE_SIZE (SImode);
4836 operand1 = XEXP (operand1, 0);
4839 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4841 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4845 (define_insn "*sign_extendqisi2_insn"
4846 [(set (match_operand:SI 0 "register_operand" "=r")
4847 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4850 [(set_attr "type" "sload")])
4852 (define_expand "extendqidi2"
4853 [(set (match_operand:DI 0 "register_operand" "")
4854 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4858 rtx temp = gen_reg_rtx (DImode);
4859 rtx shift_56 = GEN_INT (56);
4860 int op1_subbyte = 0;
4862 if (GET_CODE (operand1) == SUBREG)
4864 op1_subbyte = SUBREG_BYTE (operand1);
4865 op1_subbyte /= GET_MODE_SIZE (DImode);
4866 op1_subbyte *= GET_MODE_SIZE (DImode);
4867 operand1 = XEXP (operand1, 0);
4870 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4872 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4876 (define_insn "*sign_extendqidi2_insn"
4877 [(set (match_operand:DI 0 "register_operand" "=r")
4878 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4881 [(set_attr "type" "sload")])
4883 (define_expand "extendhidi2"
4884 [(set (match_operand:DI 0 "register_operand" "")
4885 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4889 rtx temp = gen_reg_rtx (DImode);
4890 rtx shift_48 = GEN_INT (48);
4891 int op1_subbyte = 0;
4893 if (GET_CODE (operand1) == SUBREG)
4895 op1_subbyte = SUBREG_BYTE (operand1);
4896 op1_subbyte /= GET_MODE_SIZE (DImode);
4897 op1_subbyte *= GET_MODE_SIZE (DImode);
4898 operand1 = XEXP (operand1, 0);
4901 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4903 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4907 (define_insn "*sign_extendhidi2_insn"
4908 [(set (match_operand:DI 0 "register_operand" "=r")
4909 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4912 [(set_attr "type" "sload")])
4914 (define_expand "extendsidi2"
4915 [(set (match_operand:DI 0 "register_operand" "")
4916 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4920 (define_insn "*sign_extendsidi2_insn"
4921 [(set (match_operand:DI 0 "register_operand" "=r,r")
4922 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4927 [(set_attr "type" "shift,sload")])
4929 ;; Special pattern for optimizing bit-field compares. This is needed
4930 ;; because combine uses this as a canonical form.
4932 (define_insn "*cmp_zero_extract"
4935 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4936 (match_operand:SI 1 "small_int_or_double" "n")
4937 (match_operand:SI 2 "small_int_or_double" "n"))
4939 "(GET_CODE (operands[2]) == CONST_INT
4940 && INTVAL (operands[2]) > 19)
4941 || (GET_CODE (operands[2]) == CONST_DOUBLE
4942 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4945 int len = (GET_CODE (operands[1]) == CONST_INT
4946 ? INTVAL (operands[1])
4947 : CONST_DOUBLE_LOW (operands[1]));
4949 (GET_CODE (operands[2]) == CONST_INT
4950 ? INTVAL (operands[2])
4951 : CONST_DOUBLE_LOW (operands[2])) - len;
4952 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4954 operands[1] = GEN_INT (mask);
4955 return \"andcc\\t%0, %1, %%g0\";
4957 [(set_attr "type" "compare")])
4959 (define_insn "*cmp_zero_extract_sp64"
4962 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4963 (match_operand:SI 1 "small_int_or_double" "n")
4964 (match_operand:SI 2 "small_int_or_double" "n"))
4967 && ((GET_CODE (operands[2]) == CONST_INT
4968 && INTVAL (operands[2]) > 51)
4969 || (GET_CODE (operands[2]) == CONST_DOUBLE
4970 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4973 int len = (GET_CODE (operands[1]) == CONST_INT
4974 ? INTVAL (operands[1])
4975 : CONST_DOUBLE_LOW (operands[1]));
4977 (GET_CODE (operands[2]) == CONST_INT
4978 ? INTVAL (operands[2])
4979 : CONST_DOUBLE_LOW (operands[2])) - len;
4980 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4982 operands[1] = GEN_INT (mask);
4983 return \"andcc\\t%0, %1, %%g0\";
4985 [(set_attr "type" "compare")])
4987 ;; Conversions between float, double and long double.
4989 (define_insn "extendsfdf2"
4990 [(set (match_operand:DF 0 "register_operand" "=e")
4992 (match_operand:SF 1 "register_operand" "f")))]
4995 [(set_attr "type" "fp")
4996 (set_attr "fptype" "double")])
4998 (define_expand "extendsftf2"
4999 [(set (match_operand:TF 0 "register_operand" "=e")
5001 (match_operand:SF 1 "register_operand" "f")))]
5002 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5005 if (! TARGET_HARD_QUAD)
5009 if (GET_CODE (operands[0]) != MEM)
5010 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5012 slot0 = operands[0];
5014 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5016 XEXP (slot0, 0), Pmode,
5017 operands[1], SFmode);
5019 if (GET_CODE (operands[0]) != MEM)
5020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5025 (define_insn "*extendsftf2_hq"
5026 [(set (match_operand:TF 0 "register_operand" "=e")
5028 (match_operand:SF 1 "register_operand" "f")))]
5029 "TARGET_FPU && TARGET_HARD_QUAD"
5031 [(set_attr "type" "fp")])
5033 (define_expand "extenddftf2"
5034 [(set (match_operand:TF 0 "register_operand" "=e")
5036 (match_operand:DF 1 "register_operand" "e")))]
5037 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5040 if (! TARGET_HARD_QUAD)
5044 if (GET_CODE (operands[0]) != MEM)
5045 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5047 slot0 = operands[0];
5049 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5051 XEXP (slot0, 0), Pmode,
5052 operands[1], DFmode);
5054 if (GET_CODE (operands[0]) != MEM)
5055 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5060 (define_insn "*extenddftf2_hq"
5061 [(set (match_operand:TF 0 "register_operand" "=e")
5063 (match_operand:DF 1 "register_operand" "e")))]
5064 "TARGET_FPU && TARGET_HARD_QUAD"
5066 [(set_attr "type" "fp")])
5068 (define_insn "truncdfsf2"
5069 [(set (match_operand:SF 0 "register_operand" "=f")
5071 (match_operand:DF 1 "register_operand" "e")))]
5074 [(set_attr "type" "fp")
5075 (set_attr "fptype" "double")])
5077 (define_expand "trunctfsf2"
5078 [(set (match_operand:SF 0 "register_operand" "=f")
5080 (match_operand:TF 1 "register_operand" "e")))]
5081 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5084 if (! TARGET_HARD_QUAD)
5088 if (GET_CODE (operands[1]) != MEM)
5090 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5091 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5094 slot0 = operands[1];
5096 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5097 operands[0], 0, SFmode, 1,
5098 XEXP (slot0, 0), Pmode);
5103 (define_insn "*trunctfsf2_hq"
5104 [(set (match_operand:SF 0 "register_operand" "=f")
5106 (match_operand:TF 1 "register_operand" "e")))]
5107 "TARGET_FPU && TARGET_HARD_QUAD"
5109 [(set_attr "type" "fp")])
5111 (define_expand "trunctfdf2"
5112 [(set (match_operand:DF 0 "register_operand" "=f")
5114 (match_operand:TF 1 "register_operand" "e")))]
5115 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5118 if (! TARGET_HARD_QUAD)
5122 if (GET_CODE (operands[1]) != MEM)
5124 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5125 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5128 slot0 = operands[1];
5130 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5131 operands[0], 0, DFmode, 1,
5132 XEXP (slot0, 0), Pmode);
5137 (define_insn "*trunctfdf2_hq"
5138 [(set (match_operand:DF 0 "register_operand" "=e")
5140 (match_operand:TF 1 "register_operand" "e")))]
5141 "TARGET_FPU && TARGET_HARD_QUAD"
5143 [(set_attr "type" "fp")])
5145 ;; Conversion between fixed point and floating point.
5147 (define_insn "floatsisf2"
5148 [(set (match_operand:SF 0 "register_operand" "=f")
5149 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5152 [(set_attr "type" "fp")
5153 (set_attr "fptype" "double")])
5155 (define_insn "floatsidf2"
5156 [(set (match_operand:DF 0 "register_operand" "=e")
5157 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5160 [(set_attr "type" "fp")
5161 (set_attr "fptype" "double")])
5163 (define_expand "floatsitf2"
5164 [(set (match_operand:TF 0 "register_operand" "=e")
5165 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5166 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5169 if (! TARGET_HARD_QUAD)
5173 if (GET_CODE (operands[1]) != MEM)
5174 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5176 slot0 = operands[1];
5178 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5180 XEXP (slot0, 0), Pmode,
5181 operands[1], SImode);
5183 if (GET_CODE (operands[0]) != MEM)
5184 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5189 (define_insn "*floatsitf2_hq"
5190 [(set (match_operand:TF 0 "register_operand" "=e")
5191 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5192 "TARGET_FPU && TARGET_HARD_QUAD"
5194 [(set_attr "type" "fp")])
5196 (define_expand "floatunssitf2"
5197 [(set (match_operand:TF 0 "register_operand" "=e")
5198 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5199 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5204 if (GET_CODE (operands[1]) != MEM)
5205 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5207 slot0 = operands[1];
5209 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5211 XEXP (slot0, 0), Pmode,
5212 operands[1], SImode);
5214 if (GET_CODE (operands[0]) != MEM)
5215 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5219 ;; Now the same for 64 bit sources.
5221 (define_insn "floatdisf2"
5222 [(set (match_operand:SF 0 "register_operand" "=f")
5223 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5224 "TARGET_V9 && TARGET_FPU"
5226 [(set_attr "type" "fp")
5227 (set_attr "fptype" "double")])
5229 (define_expand "floatunsdisf2"
5230 [(use (match_operand:SF 0 "register_operand" ""))
5231 (use (match_operand:DI 1 "register_operand" ""))]
5232 "TARGET_ARCH64 && TARGET_FPU"
5233 "sparc_emit_floatunsdi (operands); DONE;")
5235 (define_insn "floatdidf2"
5236 [(set (match_operand:DF 0 "register_operand" "=e")
5237 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5238 "TARGET_V9 && TARGET_FPU"
5240 [(set_attr "type" "fp")
5241 (set_attr "fptype" "double")])
5243 (define_expand "floatunsdidf2"
5244 [(use (match_operand:DF 0 "register_operand" ""))
5245 (use (match_operand:DI 1 "register_operand" ""))]
5246 "TARGET_ARCH64 && TARGET_FPU"
5247 "sparc_emit_floatunsdi (operands); DONE;")
5249 (define_expand "floatditf2"
5250 [(set (match_operand:TF 0 "register_operand" "=e")
5251 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5252 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5255 if (! TARGET_HARD_QUAD)
5259 if (GET_CODE (operands[1]) != MEM)
5260 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5262 slot0 = operands[1];
5264 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5266 XEXP (slot0, 0), Pmode,
5267 operands[1], DImode);
5269 if (GET_CODE (operands[0]) != MEM)
5270 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5275 (define_insn "*floatditf2_hq"
5276 [(set (match_operand:TF 0 "register_operand" "=e")
5277 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5278 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5280 [(set_attr "type" "fp")])
5282 (define_expand "floatunsditf2"
5283 [(set (match_operand:TF 0 "register_operand" "=e")
5284 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5285 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5290 if (GET_CODE (operands[1]) != MEM)
5291 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5293 slot0 = operands[1];
5295 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5297 XEXP (slot0, 0), Pmode,
5298 operands[1], DImode);
5300 if (GET_CODE (operands[0]) != MEM)
5301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5305 ;; Convert a float to an actual integer.
5306 ;; Truncation is performed as part of the conversion.
5308 (define_insn "fix_truncsfsi2"
5309 [(set (match_operand:SI 0 "register_operand" "=f")
5310 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5313 [(set_attr "type" "fp")
5314 (set_attr "fptype" "double")])
5316 (define_insn "fix_truncdfsi2"
5317 [(set (match_operand:SI 0 "register_operand" "=f")
5318 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5321 [(set_attr "type" "fp")
5322 (set_attr "fptype" "double")])
5324 (define_expand "fix_trunctfsi2"
5325 [(set (match_operand:SI 0 "register_operand" "=f")
5326 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5327 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5330 if (! TARGET_HARD_QUAD)
5334 if (GET_CODE (operands[1]) != MEM)
5336 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5337 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5340 slot0 = operands[1];
5342 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5343 operands[0], 0, SImode, 1,
5344 XEXP (slot0, 0), Pmode);
5349 (define_insn "*fix_trunctfsi2_hq"
5350 [(set (match_operand:SI 0 "register_operand" "=f")
5351 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5352 "TARGET_FPU && TARGET_HARD_QUAD"
5354 [(set_attr "type" "fp")])
5356 (define_expand "fixuns_trunctfsi2"
5357 [(set (match_operand:SI 0 "register_operand" "=f")
5358 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5359 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5364 if (GET_CODE (operands[1]) != MEM)
5366 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5367 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5370 slot0 = operands[1];
5372 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5373 operands[0], 0, SImode, 1,
5374 XEXP (slot0, 0), Pmode);
5378 ;; Now the same, for V9 targets
5380 (define_insn "fix_truncsfdi2"
5381 [(set (match_operand:DI 0 "register_operand" "=e")
5382 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5383 "TARGET_V9 && TARGET_FPU"
5385 [(set_attr "type" "fp")
5386 (set_attr "fptype" "double")])
5388 (define_insn "fix_truncdfdi2"
5389 [(set (match_operand:DI 0 "register_operand" "=e")
5390 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5391 "TARGET_V9 && TARGET_FPU"
5393 [(set_attr "type" "fp")
5394 (set_attr "fptype" "double")])
5396 (define_expand "fix_trunctfdi2"
5397 [(set (match_operand:DI 0 "register_operand" "=e")
5398 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5399 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5402 if (! TARGET_HARD_QUAD)
5406 if (GET_CODE (operands[1]) != MEM)
5408 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5409 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5412 slot0 = operands[1];
5414 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5415 operands[0], 0, DImode, 1,
5416 XEXP (slot0, 0), Pmode);
5421 (define_insn "*fix_trunctfdi2_hq"
5422 [(set (match_operand:DI 0 "register_operand" "=e")
5423 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5424 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5426 [(set_attr "type" "fp")])
5428 (define_expand "fixuns_trunctfdi2"
5429 [(set (match_operand:DI 0 "register_operand" "=f")
5430 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5431 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5436 if (GET_CODE (operands[1]) != MEM)
5438 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5439 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5442 slot0 = operands[1];
5444 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5445 operands[0], 0, DImode, 1,
5446 XEXP (slot0, 0), Pmode);
5451 ;;- arithmetic instructions
5453 (define_expand "adddi3"
5454 [(set (match_operand:DI 0 "register_operand" "=r")
5455 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5456 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5462 if (! TARGET_ARCH64)
5464 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5465 gen_rtx_SET (VOIDmode, operands[0],
5466 gen_rtx_PLUS (DImode, operands[1],
5468 gen_rtx_CLOBBER (VOIDmode,
5469 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5472 if (arith_double_4096_operand(operands[2], DImode))
5474 switch (GET_CODE (operands[1]))
5476 case CONST_INT: i = INTVAL (operands[1]); break;
5477 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5479 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5480 gen_rtx_MINUS (DImode, operands[1],
5484 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5489 (define_insn "adddi3_insn_sp32"
5490 [(set (match_operand:DI 0 "register_operand" "=r")
5491 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5492 (match_operand:DI 2 "arith_double_operand" "rHI")))
5493 (clobber (reg:CC 100))]
5496 [(set_attr "length" "2")])
5499 [(set (match_operand:DI 0 "register_operand" "")
5500 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5501 (match_operand:DI 2 "arith_double_operand" "")))
5502 (clobber (reg:CC 100))]
5503 "! TARGET_ARCH64 && reload_completed"
5504 [(parallel [(set (reg:CC_NOOV 100)
5505 (compare:CC_NOOV (plus:SI (match_dup 4)
5509 (plus:SI (match_dup 4) (match_dup 5)))])
5511 (plus:SI (plus:SI (match_dup 7)
5513 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5516 operands[3] = gen_lowpart (SImode, operands[0]);
5517 operands[4] = gen_lowpart (SImode, operands[1]);
5518 operands[5] = gen_lowpart (SImode, operands[2]);
5519 operands[6] = gen_highpart (SImode, operands[0]);
5520 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5521 #if HOST_BITS_PER_WIDE_INT == 32
5522 if (GET_CODE (operands[2]) == CONST_INT)
5524 if (INTVAL (operands[2]) < 0)
5525 operands[8] = constm1_rtx;
5527 operands[8] = const0_rtx;
5531 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5535 [(set (match_operand:DI 0 "register_operand" "")
5536 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5537 (match_operand:DI 2 "arith_double_operand" "")))
5538 (clobber (reg:CC 100))]
5539 "! TARGET_ARCH64 && reload_completed"
5540 [(parallel [(set (reg:CC_NOOV 100)
5541 (compare:CC_NOOV (minus:SI (match_dup 4)
5545 (minus:SI (match_dup 4) (match_dup 5)))])
5547 (minus:SI (minus:SI (match_dup 7)
5549 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5552 operands[3] = gen_lowpart (SImode, operands[0]);
5553 operands[4] = gen_lowpart (SImode, operands[1]);
5554 operands[5] = gen_lowpart (SImode, operands[2]);
5555 operands[6] = gen_highpart (SImode, operands[0]);
5556 operands[7] = gen_highpart (SImode, operands[1]);
5557 #if HOST_BITS_PER_WIDE_INT == 32
5558 if (GET_CODE (operands[2]) == CONST_INT)
5560 if (INTVAL (operands[2]) < 0)
5561 operands[8] = constm1_rtx;
5563 operands[8] = const0_rtx;
5567 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5570 ;; LTU here means "carry set"
5572 [(set (match_operand:SI 0 "register_operand" "=r")
5573 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5574 (match_operand:SI 2 "arith_operand" "rI"))
5575 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5578 [(set_attr "type" "misc")])
5580 (define_insn "*addx_extend_sp32"
5581 [(set (match_operand:DI 0 "register_operand" "=r")
5582 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5583 (match_operand:SI 2 "arith_operand" "rI"))
5584 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5587 [(set_attr "length" "2")])
5590 [(set (match_operand:DI 0 "register_operand" "")
5591 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5592 (match_operand:SI 2 "arith_operand" ""))
5593 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5594 "! TARGET_ARCH64 && reload_completed"
5595 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5596 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5597 (set (match_dup 4) (const_int 0))]
5598 "operands[3] = gen_lowpart (SImode, operands[0]);
5599 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5601 (define_insn "*addx_extend_sp64"
5602 [(set (match_operand:DI 0 "register_operand" "=r")
5603 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5604 (match_operand:SI 2 "arith_operand" "rI"))
5605 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5607 "addx\\t%r1, %2, %0"
5608 [(set_attr "type" "misc")])
5611 [(set (match_operand:SI 0 "register_operand" "=r")
5612 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5613 (match_operand:SI 2 "arith_operand" "rI"))
5614 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5616 "subx\\t%r1, %2, %0"
5617 [(set_attr "type" "misc")])
5619 (define_insn "*subx_extend_sp64"
5620 [(set (match_operand:DI 0 "register_operand" "=r")
5621 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5622 (match_operand:SI 2 "arith_operand" "rI"))
5623 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5625 "subx\\t%r1, %2, %0"
5626 [(set_attr "type" "misc")])
5628 (define_insn "*subx_extend"
5629 [(set (match_operand:DI 0 "register_operand" "=r")
5630 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5631 (match_operand:SI 2 "arith_operand" "rI"))
5632 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5635 [(set_attr "length" "2")])
5638 [(set (match_operand:DI 0 "register_operand" "")
5639 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5640 (match_operand:SI 2 "arith_operand" ""))
5641 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5642 "! TARGET_ARCH64 && reload_completed"
5643 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5644 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5645 (set (match_dup 4) (const_int 0))]
5646 "operands[3] = gen_lowpart (SImode, operands[0]);
5647 operands[4] = gen_highpart (SImode, operands[0]);")
5650 [(set (match_operand:DI 0 "register_operand" "=r")
5651 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5652 (match_operand:DI 2 "register_operand" "r")))
5653 (clobber (reg:CC 100))]
5656 [(set_attr "length" "2")])
5659 [(set (match_operand:DI 0 "register_operand" "")
5660 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5661 (match_operand:DI 2 "register_operand" "")))
5662 (clobber (reg:CC 100))]
5663 "! TARGET_ARCH64 && reload_completed"
5664 [(parallel [(set (reg:CC_NOOV 100)
5665 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5667 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5669 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5670 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5671 "operands[3] = gen_lowpart (SImode, operands[2]);
5672 operands[4] = gen_highpart (SImode, operands[2]);
5673 operands[5] = gen_lowpart (SImode, operands[0]);
5674 operands[6] = gen_highpart (SImode, operands[0]);")
5676 (define_insn "*adddi3_sp64"
5677 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5679 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5683 (define_expand "addsi3"
5684 [(set (match_operand:SI 0 "register_operand" "=r,d")
5685 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5686 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5690 if (arith_4096_operand(operands[2], SImode))
5692 if (GET_CODE (operands[1]) == CONST_INT)
5693 emit_insn (gen_movsi (operands[0],
5694 GEN_INT (INTVAL (operands[1]) + 4096)));
5696 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5697 gen_rtx_MINUS (SImode, operands[1],
5703 (define_insn "*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_operand" "rI,d")))]
5710 fpadd32s\\t%1, %2, %0"
5711 [(set_attr "type" "*,fp")])
5713 (define_insn "*cmp_cc_plus"
5714 [(set (reg:CC_NOOV 100)
5715 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5716 (match_operand:SI 1 "arith_operand" "rI"))
5719 "addcc\\t%0, %1, %%g0"
5720 [(set_attr "type" "compare")])
5722 (define_insn "*cmp_ccx_plus"
5723 [(set (reg:CCX_NOOV 100)
5724 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5725 (match_operand:DI 1 "arith_double_operand" "rHI"))
5728 "addcc\\t%0, %1, %%g0"
5729 [(set_attr "type" "compare")])
5731 (define_insn "*cmp_cc_plus_set"
5732 [(set (reg:CC_NOOV 100)
5733 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5734 (match_operand:SI 2 "arith_operand" "rI"))
5736 (set (match_operand:SI 0 "register_operand" "=r")
5737 (plus:SI (match_dup 1) (match_dup 2)))]
5739 "addcc\\t%1, %2, %0"
5740 [(set_attr "type" "compare")])
5742 (define_insn "*cmp_ccx_plus_set"
5743 [(set (reg:CCX_NOOV 100)
5744 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5745 (match_operand:DI 2 "arith_double_operand" "rHI"))
5747 (set (match_operand:DI 0 "register_operand" "=r")
5748 (plus:DI (match_dup 1) (match_dup 2)))]
5750 "addcc\\t%1, %2, %0"
5751 [(set_attr "type" "compare")])
5753 (define_expand "subdi3"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5755 (minus:DI (match_operand:DI 1 "register_operand" "r")
5756 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5760 if (! TARGET_ARCH64)
5762 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5763 gen_rtx_SET (VOIDmode, operands[0],
5764 gen_rtx_MINUS (DImode, operands[1],
5766 gen_rtx_CLOBBER (VOIDmode,
5767 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5770 if (arith_double_4096_operand(operands[2], DImode))
5772 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5773 gen_rtx_PLUS (DImode, operands[1],
5779 (define_insn "*subdi3_sp32"
5780 [(set (match_operand:DI 0 "register_operand" "=r")
5781 (minus:DI (match_operand:DI 1 "register_operand" "r")
5782 (match_operand:DI 2 "arith_double_operand" "rHI")))
5783 (clobber (reg:CC 100))]
5786 [(set_attr "length" "2")])
5789 [(set (match_operand:DI 0 "register_operand" "")
5790 (minus:DI (match_operand:DI 1 "register_operand" "")
5791 (match_operand:DI 2 "arith_double_operand" "")))
5792 (clobber (reg:CC 100))]
5795 && (GET_CODE (operands[2]) == CONST_INT
5796 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5797 [(clobber (const_int 0))]
5802 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5803 lowp = gen_lowpart (SImode, operands[2]);
5804 if ((lowp == const0_rtx)
5805 && (operands[0] == operands[1]))
5807 emit_insn (gen_rtx_SET (VOIDmode,
5808 gen_highpart (SImode, operands[0]),
5809 gen_rtx_MINUS (SImode,
5810 gen_highpart_mode (SImode, DImode,
5816 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5817 gen_lowpart (SImode, operands[1]),
5819 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5820 gen_highpart_mode (SImode, DImode, operands[1]),
5827 [(set (match_operand:DI 0 "register_operand" "")
5828 (minus:DI (match_operand:DI 1 "register_operand" "")
5829 (match_operand:DI 2 "register_operand" "")))
5830 (clobber (reg:CC 100))]
5832 && reload_completed"
5833 [(clobber (const_int 0))]
5836 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5837 gen_lowpart (SImode, operands[1]),
5838 gen_lowpart (SImode, operands[2])));
5839 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5840 gen_highpart (SImode, operands[1]),
5841 gen_highpart (SImode, operands[2])));
5846 [(set (match_operand:DI 0 "register_operand" "=r")
5847 (minus:DI (match_operand:DI 1 "register_operand" "r")
5848 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5849 (clobber (reg:CC 100))]
5852 [(set_attr "length" "2")])
5855 [(set (match_operand:DI 0 "register_operand" "")
5856 (minus:DI (match_operand:DI 1 "register_operand" "")
5857 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5858 (clobber (reg:CC 100))]
5859 "! TARGET_ARCH64 && reload_completed"
5860 [(parallel [(set (reg:CC_NOOV 100)
5861 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5863 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5865 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5866 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5867 "operands[3] = gen_lowpart (SImode, operands[1]);
5868 operands[4] = gen_highpart (SImode, operands[1]);
5869 operands[5] = gen_lowpart (SImode, operands[0]);
5870 operands[6] = gen_highpart (SImode, operands[0]);")
5872 (define_insn "*subdi3_sp64"
5873 [(set (match_operand:DI 0 "register_operand" "=r")
5874 (minus:DI (match_operand:DI 1 "register_operand" "r")
5875 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5879 (define_expand "subsi3"
5880 [(set (match_operand:SI 0 "register_operand" "=r,d")
5881 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5882 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5886 if (arith_4096_operand(operands[2], SImode))
5888 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5889 gen_rtx_PLUS (SImode, operands[1],
5895 (define_insn "*subsi3"
5896 [(set (match_operand:SI 0 "register_operand" "=r,d")
5897 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5898 (match_operand:SI 2 "arith_operand" "rI,d")))]
5902 fpsub32s\\t%1, %2, %0"
5903 [(set_attr "type" "*,fp")])
5905 (define_insn "*cmp_minus_cc"
5906 [(set (reg:CC_NOOV 100)
5907 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5908 (match_operand:SI 1 "arith_operand" "rI"))
5911 "subcc\\t%r0, %1, %%g0"
5912 [(set_attr "type" "compare")])
5914 (define_insn "*cmp_minus_ccx"
5915 [(set (reg:CCX_NOOV 100)
5916 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5917 (match_operand:DI 1 "arith_double_operand" "rHI"))
5920 "subcc\\t%0, %1, %%g0"
5921 [(set_attr "type" "compare")])
5923 (define_insn "cmp_minus_cc_set"
5924 [(set (reg:CC_NOOV 100)
5925 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5926 (match_operand:SI 2 "arith_operand" "rI"))
5928 (set (match_operand:SI 0 "register_operand" "=r")
5929 (minus:SI (match_dup 1) (match_dup 2)))]
5931 "subcc\\t%r1, %2, %0"
5932 [(set_attr "type" "compare")])
5934 (define_insn "*cmp_minus_ccx_set"
5935 [(set (reg:CCX_NOOV 100)
5936 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5937 (match_operand:DI 2 "arith_double_operand" "rHI"))
5939 (set (match_operand:DI 0 "register_operand" "=r")
5940 (minus:DI (match_dup 1) (match_dup 2)))]
5942 "subcc\\t%1, %2, %0"
5943 [(set_attr "type" "compare")])
5945 ;; Integer Multiply/Divide.
5947 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5948 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5950 (define_insn "mulsi3"
5951 [(set (match_operand:SI 0 "register_operand" "=r")
5952 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5953 (match_operand:SI 2 "arith_operand" "rI")))]
5956 [(set_attr "type" "imul")])
5958 (define_expand "muldi3"
5959 [(set (match_operand:DI 0 "register_operand" "=r")
5960 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5961 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5962 "TARGET_ARCH64 || TARGET_V8PLUS"
5967 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5972 (define_insn "*muldi3_sp64"
5973 [(set (match_operand:DI 0 "register_operand" "=r")
5974 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5975 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5978 [(set_attr "type" "imul")])
5980 ;; V8plus wide multiply.
5982 (define_insn "muldi3_v8plus"
5983 [(set (match_operand:DI 0 "register_operand" "=r,h")
5984 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5985 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5986 (clobber (match_scratch:SI 3 "=&h,X"))
5987 (clobber (match_scratch:SI 4 "=&h,X"))]
5991 if (sparc_check_64 (operands[1], insn) <= 0)
5992 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5993 if (which_alternative == 1)
5994 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5995 if (GET_CODE (operands[2]) == CONST_INT)
5997 if (which_alternative == 1)
5998 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6000 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\";
6002 if (sparc_check_64 (operands[2], insn) <= 0)
6003 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6004 if (which_alternative == 1)
6005 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\";
6007 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\";
6009 [(set_attr "type" "multi")
6010 (set_attr "length" "9,8")])
6012 (define_insn "*cmp_mul_set"
6014 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6015 (match_operand:SI 2 "arith_operand" "rI"))
6017 (set (match_operand:SI 0 "register_operand" "=r")
6018 (mult:SI (match_dup 1) (match_dup 2)))]
6019 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6020 "smulcc\\t%1, %2, %0"
6021 [(set_attr "type" "imul")])
6023 (define_expand "mulsidi3"
6024 [(set (match_operand:DI 0 "register_operand" "")
6025 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6026 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6030 if (CONSTANT_P (operands[2]))
6033 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6036 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6042 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6047 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6048 ;; registers can hold 64 bit values in the V8plus environment.
6050 (define_insn "mulsidi3_v8plus"
6051 [(set (match_operand:DI 0 "register_operand" "=h,r")
6052 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6053 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6054 (clobber (match_scratch:SI 3 "=X,&h"))]
6057 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6058 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6059 [(set_attr "type" "multi")
6060 (set_attr "length" "2,3")])
6063 (define_insn "const_mulsidi3_v8plus"
6064 [(set (match_operand:DI 0 "register_operand" "=h,r")
6065 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6066 (match_operand:SI 2 "small_int" "I,I")))
6067 (clobber (match_scratch:SI 3 "=X,&h"))]
6070 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6071 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6072 [(set_attr "type" "multi")
6073 (set_attr "length" "2,3")])
6076 (define_insn "*mulsidi3_sp32"
6077 [(set (match_operand:DI 0 "register_operand" "=r")
6078 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6079 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6083 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6086 (if_then_else (eq_attr "isa" "sparclet")
6087 (const_string "imul") (const_string "multi")))
6088 (set (attr "length")
6089 (if_then_else (eq_attr "isa" "sparclet")
6090 (const_int 1) (const_int 2)))])
6092 (define_insn "*mulsidi3_sp64"
6093 [(set (match_operand:DI 0 "register_operand" "=r")
6094 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6095 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6096 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6098 [(set_attr "type" "imul")])
6100 ;; Extra pattern, because sign_extend of a constant isn't valid.
6103 (define_insn "const_mulsidi3_sp32"
6104 [(set (match_operand:DI 0 "register_operand" "=r")
6105 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6106 (match_operand:SI 2 "small_int" "I")))]
6110 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6113 (if_then_else (eq_attr "isa" "sparclet")
6114 (const_string "imul") (const_string "multi")))
6115 (set (attr "length")
6116 (if_then_else (eq_attr "isa" "sparclet")
6117 (const_int 1) (const_int 2)))])
6119 (define_insn "const_mulsidi3_sp64"
6120 [(set (match_operand:DI 0 "register_operand" "=r")
6121 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6122 (match_operand:SI 2 "small_int" "I")))]
6123 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6125 [(set_attr "type" "imul")])
6127 (define_expand "smulsi3_highpart"
6128 [(set (match_operand:SI 0 "register_operand" "")
6130 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6131 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6133 "TARGET_HARD_MUL && TARGET_ARCH32"
6136 if (CONSTANT_P (operands[2]))
6140 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6146 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6151 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6152 operands[2], GEN_INT (32)));
6158 (define_insn "smulsi3_highpart_v8plus"
6159 [(set (match_operand:SI 0 "register_operand" "=h,r")
6161 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6162 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6163 (match_operand:SI 3 "const_int_operand" "i,i"))))
6164 (clobber (match_scratch:SI 4 "=X,&h"))]
6167 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6168 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6169 [(set_attr "type" "multi")
6170 (set_attr "length" "2")])
6172 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6175 [(set (match_operand:SI 0 "register_operand" "=h,r")
6178 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6179 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6180 (match_operand:SI 3 "const_int_operand" "i,i"))
6182 (clobber (match_scratch:SI 4 "=X,&h"))]
6185 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6186 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6187 [(set_attr "type" "multi")
6188 (set_attr "length" "2")])
6191 (define_insn "const_smulsi3_highpart_v8plus"
6192 [(set (match_operand:SI 0 "register_operand" "=h,r")
6194 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6195 (match_operand 2 "small_int" "i,i"))
6196 (match_operand:SI 3 "const_int_operand" "i,i"))))
6197 (clobber (match_scratch:SI 4 "=X,&h"))]
6200 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6201 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6202 [(set_attr "type" "multi")
6203 (set_attr "length" "2")])
6206 (define_insn "*smulsi3_highpart_sp32"
6207 [(set (match_operand:SI 0 "register_operand" "=r")
6209 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6210 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6213 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6214 [(set_attr "type" "multi")
6215 (set_attr "length" "2")])
6218 (define_insn "const_smulsi3_highpart"
6219 [(set (match_operand:SI 0 "register_operand" "=r")
6221 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6222 (match_operand:SI 2 "register_operand" "r"))
6225 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6226 [(set_attr "type" "multi")
6227 (set_attr "length" "2")])
6229 (define_expand "umulsidi3"
6230 [(set (match_operand:DI 0 "register_operand" "")
6231 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6232 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6236 if (CONSTANT_P (operands[2]))
6239 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6242 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6248 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6254 (define_insn "umulsidi3_v8plus"
6255 [(set (match_operand:DI 0 "register_operand" "=h,r")
6256 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6257 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6258 (clobber (match_scratch:SI 3 "=X,&h"))]
6261 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6262 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6263 [(set_attr "type" "multi")
6264 (set_attr "length" "2,3")])
6267 (define_insn "*umulsidi3_sp32"
6268 [(set (match_operand:DI 0 "register_operand" "=r")
6269 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6270 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6274 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6277 (if_then_else (eq_attr "isa" "sparclet")
6278 (const_string "imul") (const_string "multi")))
6279 (set (attr "length")
6280 (if_then_else (eq_attr "isa" "sparclet")
6281 (const_int 1) (const_int 2)))])
6283 (define_insn "*umulsidi3_sp64"
6284 [(set (match_operand:DI 0 "register_operand" "=r")
6285 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6286 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6287 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6289 [(set_attr "type" "imul")])
6291 ;; Extra pattern, because sign_extend of a constant isn't valid.
6294 (define_insn "const_umulsidi3_sp32"
6295 [(set (match_operand:DI 0 "register_operand" "=r")
6296 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6297 (match_operand:SI 2 "uns_small_int" "")))]
6301 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6304 (if_then_else (eq_attr "isa" "sparclet")
6305 (const_string "imul") (const_string "multi")))
6306 (set (attr "length")
6307 (if_then_else (eq_attr "isa" "sparclet")
6308 (const_int 1) (const_int 2)))])
6310 (define_insn "const_umulsidi3_sp64"
6311 [(set (match_operand:DI 0 "register_operand" "=r")
6312 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6313 (match_operand:SI 2 "uns_small_int" "")))]
6314 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6316 [(set_attr "type" "imul")])
6319 (define_insn "const_umulsidi3_v8plus"
6320 [(set (match_operand:DI 0 "register_operand" "=h,r")
6321 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6322 (match_operand:SI 2 "uns_small_int" "")))
6323 (clobber (match_scratch:SI 3 "=X,h"))]
6326 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6327 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6328 [(set_attr "type" "multi")
6329 (set_attr "length" "2,3")])
6331 (define_expand "umulsi3_highpart"
6332 [(set (match_operand:SI 0 "register_operand" "")
6334 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6335 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6337 "TARGET_HARD_MUL && TARGET_ARCH32"
6340 if (CONSTANT_P (operands[2]))
6344 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6350 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6355 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6356 operands[2], GEN_INT (32)));
6362 (define_insn "umulsi3_highpart_v8plus"
6363 [(set (match_operand:SI 0 "register_operand" "=h,r")
6365 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6366 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6367 (match_operand:SI 3 "const_int_operand" "i,i"))))
6368 (clobber (match_scratch:SI 4 "=X,h"))]
6371 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6372 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6373 [(set_attr "type" "multi")
6374 (set_attr "length" "2")])
6377 (define_insn "const_umulsi3_highpart_v8plus"
6378 [(set (match_operand:SI 0 "register_operand" "=h,r")
6380 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6381 (match_operand:SI 2 "uns_small_int" ""))
6382 (match_operand:SI 3 "const_int_operand" "i,i"))))
6383 (clobber (match_scratch:SI 4 "=X,h"))]
6386 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6387 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6388 [(set_attr "type" "multi")
6389 (set_attr "length" "2")])
6392 (define_insn "*umulsi3_highpart_sp32"
6393 [(set (match_operand:SI 0 "register_operand" "=r")
6395 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6396 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6399 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6400 [(set_attr "type" "multi")
6401 (set_attr "length" "2")])
6404 (define_insn "const_umulsi3_highpart"
6405 [(set (match_operand:SI 0 "register_operand" "=r")
6407 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6408 (match_operand:SI 2 "uns_small_int" ""))
6411 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6412 [(set_attr "type" "multi")
6413 (set_attr "length" "2")])
6415 ;; The v8 architecture specifies that there must be 3 instructions between
6416 ;; a y register write and a use of it for correct results.
6418 (define_expand "divsi3"
6419 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6420 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6421 (match_operand:SI 2 "input_operand" "rI,m")))
6422 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6423 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6428 operands[3] = gen_reg_rtx(SImode);
6429 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6430 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6436 (define_insn "divsi3_sp32"
6437 [(set (match_operand:SI 0 "register_operand" "=r,r")
6438 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6439 (match_operand:SI 2 "input_operand" "rI,m")))
6440 (clobber (match_scratch:SI 3 "=&r,&r"))]
6441 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6445 if (which_alternative == 0)
6447 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6449 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6452 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6454 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\";
6456 [(set_attr "type" "multi")
6457 (set (attr "length")
6458 (if_then_else (eq_attr "isa" "v9")
6459 (const_int 4) (const_int 6)))])
6461 (define_insn "divsi3_sp64"
6462 [(set (match_operand:SI 0 "register_operand" "=r")
6463 (div:SI (match_operand:SI 1 "register_operand" "r")
6464 (match_operand:SI 2 "input_operand" "rI")))
6465 (use (match_operand:SI 3 "register_operand" "r"))]
6466 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6467 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6468 [(set_attr "type" "multi")
6469 (set_attr "length" "2")])
6471 (define_insn "divdi3"
6472 [(set (match_operand:DI 0 "register_operand" "=r")
6473 (div:DI (match_operand:DI 1 "register_operand" "r")
6474 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6476 "sdivx\\t%1, %2, %0"
6477 [(set_attr "type" "idiv")])
6479 (define_insn "*cmp_sdiv_cc_set"
6481 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6482 (match_operand:SI 2 "arith_operand" "rI"))
6484 (set (match_operand:SI 0 "register_operand" "=r")
6485 (div:SI (match_dup 1) (match_dup 2)))
6486 (clobber (match_scratch:SI 3 "=&r"))]
6487 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6491 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6493 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6495 [(set_attr "type" "multi")
6496 (set (attr "length")
6497 (if_then_else (eq_attr "isa" "v9")
6498 (const_int 3) (const_int 6)))])
6501 (define_expand "udivsi3"
6502 [(set (match_operand:SI 0 "register_operand" "")
6503 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6504 (match_operand:SI 2 "input_operand" "")))]
6505 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6508 (define_insn "udivsi3_sp32"
6509 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6510 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6511 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6513 || TARGET_DEPRECATED_V8_INSNS)
6517 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6518 switch (which_alternative)
6521 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6523 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6525 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6528 [(set_attr "type" "multi")
6529 (set_attr "length" "5")])
6531 (define_insn "udivsi3_sp64"
6532 [(set (match_operand:SI 0 "register_operand" "=r")
6533 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6534 (match_operand:SI 2 "input_operand" "rI")))]
6535 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6536 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6537 [(set_attr "type" "multi")
6538 (set_attr "length" "2")])
6540 (define_insn "udivdi3"
6541 [(set (match_operand:DI 0 "register_operand" "=r")
6542 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6543 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6545 "udivx\\t%1, %2, %0"
6546 [(set_attr "type" "idiv")])
6548 (define_insn "*cmp_udiv_cc_set"
6550 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6551 (match_operand:SI 2 "arith_operand" "rI"))
6553 (set (match_operand:SI 0 "register_operand" "=r")
6554 (udiv:SI (match_dup 1) (match_dup 2)))]
6556 || TARGET_DEPRECATED_V8_INSNS"
6560 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6562 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6564 [(set_attr "type" "multi")
6565 (set (attr "length")
6566 (if_then_else (eq_attr "isa" "v9")
6567 (const_int 2) (const_int 5)))])
6569 ; sparclet multiply/accumulate insns
6571 (define_insn "*smacsi"
6572 [(set (match_operand:SI 0 "register_operand" "=r")
6573 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6574 (match_operand:SI 2 "arith_operand" "rI"))
6575 (match_operand:SI 3 "register_operand" "0")))]
6578 [(set_attr "type" "imul")])
6580 (define_insn "*smacdi"
6581 [(set (match_operand:DI 0 "register_operand" "=r")
6582 (plus:DI (mult:DI (sign_extend:DI
6583 (match_operand:SI 1 "register_operand" "%r"))
6585 (match_operand:SI 2 "register_operand" "r")))
6586 (match_operand:DI 3 "register_operand" "0")))]
6588 "smacd\\t%1, %2, %L0"
6589 [(set_attr "type" "imul")])
6591 (define_insn "*umacdi"
6592 [(set (match_operand:DI 0 "register_operand" "=r")
6593 (plus:DI (mult:DI (zero_extend:DI
6594 (match_operand:SI 1 "register_operand" "%r"))
6596 (match_operand:SI 2 "register_operand" "r")))
6597 (match_operand:DI 3 "register_operand" "0")))]
6599 "umacd\\t%1, %2, %L0"
6600 [(set_attr "type" "imul")])
6602 ;;- Boolean instructions
6603 ;; We define DImode `and' so with DImode `not' we can get
6604 ;; DImode `andn'. Other combinations are possible.
6606 (define_expand "anddi3"
6607 [(set (match_operand:DI 0 "register_operand" "")
6608 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6609 (match_operand:DI 2 "arith_double_operand" "")))]
6613 (define_insn "*anddi3_sp32"
6614 [(set (match_operand:DI 0 "register_operand" "=r,b")
6615 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6616 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6621 [(set_attr "type" "*,fp")
6622 (set_attr "length" "2,*")
6623 (set_attr "fptype" "double")])
6625 (define_insn "*anddi3_sp64"
6626 [(set (match_operand:DI 0 "register_operand" "=r,b")
6627 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6628 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6633 [(set_attr "type" "*,fp")
6634 (set_attr "fptype" "double")])
6636 (define_insn "andsi3"
6637 [(set (match_operand:SI 0 "register_operand" "=r,d")
6638 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6639 (match_operand:SI 2 "arith_operand" "rI,d")))]
6644 [(set_attr "type" "*,fp")])
6647 [(set (match_operand:SI 0 "register_operand" "")
6648 (and:SI (match_operand:SI 1 "register_operand" "")
6649 (match_operand:SI 2 "" "")))
6650 (clobber (match_operand:SI 3 "register_operand" ""))]
6651 "GET_CODE (operands[2]) == CONST_INT
6652 && !SMALL_INT32 (operands[2])
6653 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6654 [(set (match_dup 3) (match_dup 4))
6655 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6658 operands[4] = GEN_INT (~INTVAL (operands[2]));
6661 ;; Split DImode logical operations requiring two instructions.
6663 [(set (match_operand:DI 0 "register_operand" "")
6664 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6665 [(match_operand:DI 2 "register_operand" "")
6666 (match_operand:DI 3 "arith_double_operand" "")]))]
6669 && ((GET_CODE (operands[0]) == REG
6670 && REGNO (operands[0]) < 32)
6671 || (GET_CODE (operands[0]) == SUBREG
6672 && GET_CODE (SUBREG_REG (operands[0])) == REG
6673 && REGNO (SUBREG_REG (operands[0])) < 32))"
6674 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6675 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6678 operands[4] = gen_highpart (SImode, operands[0]);
6679 operands[5] = gen_lowpart (SImode, operands[0]);
6680 operands[6] = gen_highpart (SImode, operands[2]);
6681 operands[7] = gen_lowpart (SImode, operands[2]);
6682 #if HOST_BITS_PER_WIDE_INT == 32
6683 if (GET_CODE (operands[3]) == CONST_INT)
6685 if (INTVAL (operands[3]) < 0)
6686 operands[8] = constm1_rtx;
6688 operands[8] = const0_rtx;
6692 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6693 operands[9] = gen_lowpart (SImode, operands[3]);
6696 (define_insn "*and_not_di_sp32"
6697 [(set (match_operand:DI 0 "register_operand" "=r,b")
6698 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6699 (match_operand:DI 2 "register_operand" "r,b")))]
6703 fandnot1\\t%1, %2, %0"
6704 [(set_attr "type" "*,fp")
6705 (set_attr "length" "2,*")
6706 (set_attr "fptype" "double")])
6709 [(set (match_operand:DI 0 "register_operand" "")
6710 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6711 (match_operand:DI 2 "register_operand" "")))]
6714 && ((GET_CODE (operands[0]) == REG
6715 && REGNO (operands[0]) < 32)
6716 || (GET_CODE (operands[0]) == SUBREG
6717 && GET_CODE (SUBREG_REG (operands[0])) == REG
6718 && REGNO (SUBREG_REG (operands[0])) < 32))"
6719 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6720 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6721 "operands[3] = gen_highpart (SImode, operands[0]);
6722 operands[4] = gen_highpart (SImode, operands[1]);
6723 operands[5] = gen_highpart (SImode, operands[2]);
6724 operands[6] = gen_lowpart (SImode, operands[0]);
6725 operands[7] = gen_lowpart (SImode, operands[1]);
6726 operands[8] = gen_lowpart (SImode, operands[2]);")
6728 (define_insn "*and_not_di_sp64"
6729 [(set (match_operand:DI 0 "register_operand" "=r,b")
6730 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6731 (match_operand:DI 2 "register_operand" "r,b")))]
6735 fandnot1\\t%1, %2, %0"
6736 [(set_attr "type" "*,fp")
6737 (set_attr "fptype" "double")])
6739 (define_insn "*and_not_si"
6740 [(set (match_operand:SI 0 "register_operand" "=r,d")
6741 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6742 (match_operand:SI 2 "register_operand" "r,d")))]
6746 fandnot1s\\t%1, %2, %0"
6747 [(set_attr "type" "*,fp")])
6749 (define_expand "iordi3"
6750 [(set (match_operand:DI 0 "register_operand" "")
6751 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6752 (match_operand:DI 2 "arith_double_operand" "")))]
6756 (define_insn "*iordi3_sp32"
6757 [(set (match_operand:DI 0 "register_operand" "=r,b")
6758 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6759 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6764 [(set_attr "type" "*,fp")
6765 (set_attr "length" "2,*")
6766 (set_attr "fptype" "double")])
6768 (define_insn "*iordi3_sp64"
6769 [(set (match_operand:DI 0 "register_operand" "=r,b")
6770 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6771 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6776 [(set_attr "type" "*,fp")
6777 (set_attr "fptype" "double")])
6779 (define_insn "iorsi3"
6780 [(set (match_operand:SI 0 "register_operand" "=r,d")
6781 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6782 (match_operand:SI 2 "arith_operand" "rI,d")))]
6787 [(set_attr "type" "*,fp")])
6790 [(set (match_operand:SI 0 "register_operand" "")
6791 (ior:SI (match_operand:SI 1 "register_operand" "")
6792 (match_operand:SI 2 "" "")))
6793 (clobber (match_operand:SI 3 "register_operand" ""))]
6794 "GET_CODE (operands[2]) == CONST_INT
6795 && !SMALL_INT32 (operands[2])
6796 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6797 [(set (match_dup 3) (match_dup 4))
6798 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6801 operands[4] = GEN_INT (~INTVAL (operands[2]));
6804 (define_insn "*or_not_di_sp32"
6805 [(set (match_operand:DI 0 "register_operand" "=r,b")
6806 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6807 (match_operand:DI 2 "register_operand" "r,b")))]
6811 fornot1\\t%1, %2, %0"
6812 [(set_attr "type" "*,fp")
6813 (set_attr "length" "2,*")
6814 (set_attr "fptype" "double")])
6817 [(set (match_operand:DI 0 "register_operand" "")
6818 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6819 (match_operand:DI 2 "register_operand" "")))]
6822 && ((GET_CODE (operands[0]) == REG
6823 && REGNO (operands[0]) < 32)
6824 || (GET_CODE (operands[0]) == SUBREG
6825 && GET_CODE (SUBREG_REG (operands[0])) == REG
6826 && REGNO (SUBREG_REG (operands[0])) < 32))"
6827 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6828 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6829 "operands[3] = gen_highpart (SImode, operands[0]);
6830 operands[4] = gen_highpart (SImode, operands[1]);
6831 operands[5] = gen_highpart (SImode, operands[2]);
6832 operands[6] = gen_lowpart (SImode, operands[0]);
6833 operands[7] = gen_lowpart (SImode, operands[1]);
6834 operands[8] = gen_lowpart (SImode, operands[2]);")
6836 (define_insn "*or_not_di_sp64"
6837 [(set (match_operand:DI 0 "register_operand" "=r,b")
6838 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6839 (match_operand:DI 2 "register_operand" "r,b")))]
6843 fornot1\\t%1, %2, %0"
6844 [(set_attr "type" "*,fp")
6845 (set_attr "fptype" "double")])
6847 (define_insn "*or_not_si"
6848 [(set (match_operand:SI 0 "register_operand" "=r,d")
6849 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6850 (match_operand:SI 2 "register_operand" "r,d")))]
6854 fornot1s\\t%1, %2, %0"
6855 [(set_attr "type" "*,fp")])
6857 (define_expand "xordi3"
6858 [(set (match_operand:DI 0 "register_operand" "")
6859 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6860 (match_operand:DI 2 "arith_double_operand" "")))]
6864 (define_insn "*xordi3_sp32"
6865 [(set (match_operand:DI 0 "register_operand" "=r,b")
6866 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6867 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6872 [(set_attr "type" "*,fp")
6873 (set_attr "length" "2,*")
6874 (set_attr "fptype" "double")])
6876 (define_insn "*xordi3_sp64"
6877 [(set (match_operand:DI 0 "register_operand" "=r,b")
6878 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6879 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6884 [(set_attr "type" "*,fp")
6885 (set_attr "fptype" "double")])
6887 (define_insn "*xordi3_sp64_dbl"
6888 [(set (match_operand:DI 0 "register_operand" "=r")
6889 (xor:DI (match_operand:DI 1 "register_operand" "r")
6890 (match_operand:DI 2 "const64_operand" "")))]
6892 && HOST_BITS_PER_WIDE_INT != 64)"
6895 (define_insn "xorsi3"
6896 [(set (match_operand:SI 0 "register_operand" "=r,d")
6897 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6898 (match_operand:SI 2 "arith_operand" "rI,d")))]
6903 [(set_attr "type" "*,fp")])
6906 [(set (match_operand:SI 0 "register_operand" "")
6907 (xor:SI (match_operand:SI 1 "register_operand" "")
6908 (match_operand:SI 2 "" "")))
6909 (clobber (match_operand:SI 3 "register_operand" ""))]
6910 "GET_CODE (operands[2]) == CONST_INT
6911 && !SMALL_INT32 (operands[2])
6912 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6913 [(set (match_dup 3) (match_dup 4))
6914 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6917 operands[4] = GEN_INT (~INTVAL (operands[2]));
6921 [(set (match_operand:SI 0 "register_operand" "")
6922 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6923 (match_operand:SI 2 "" ""))))
6924 (clobber (match_operand:SI 3 "register_operand" ""))]
6925 "GET_CODE (operands[2]) == CONST_INT
6926 && !SMALL_INT32 (operands[2])
6927 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6928 [(set (match_dup 3) (match_dup 4))
6929 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6932 operands[4] = GEN_INT (~INTVAL (operands[2]));
6935 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6936 ;; Combine now canonicalizes to the rightmost expression.
6937 (define_insn "*xor_not_di_sp32"
6938 [(set (match_operand:DI 0 "register_operand" "=r,b")
6939 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6940 (match_operand:DI 2 "register_operand" "r,b"))))]
6945 [(set_attr "type" "*,fp")
6946 (set_attr "length" "2,*")
6947 (set_attr "fptype" "double")])
6950 [(set (match_operand:DI 0 "register_operand" "")
6951 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6952 (match_operand:DI 2 "register_operand" ""))))]
6955 && ((GET_CODE (operands[0]) == REG
6956 && REGNO (operands[0]) < 32)
6957 || (GET_CODE (operands[0]) == SUBREG
6958 && GET_CODE (SUBREG_REG (operands[0])) == REG
6959 && REGNO (SUBREG_REG (operands[0])) < 32))"
6960 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6961 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6962 "operands[3] = gen_highpart (SImode, operands[0]);
6963 operands[4] = gen_highpart (SImode, operands[1]);
6964 operands[5] = gen_highpart (SImode, operands[2]);
6965 operands[6] = gen_lowpart (SImode, operands[0]);
6966 operands[7] = gen_lowpart (SImode, operands[1]);
6967 operands[8] = gen_lowpart (SImode, operands[2]);")
6969 (define_insn "*xor_not_di_sp64"
6970 [(set (match_operand:DI 0 "register_operand" "=r,b")
6971 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6972 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6977 [(set_attr "type" "*,fp")
6978 (set_attr "fptype" "double")])
6980 (define_insn "*xor_not_si"
6981 [(set (match_operand:SI 0 "register_operand" "=r,d")
6982 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6983 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6987 fxnors\\t%1, %2, %0"
6988 [(set_attr "type" "*,fp")])
6990 ;; These correspond to the above in the case where we also (or only)
6991 ;; want to set the condition code.
6993 (define_insn "*cmp_cc_arith_op"
6996 (match_operator:SI 2 "cc_arithop"
6997 [(match_operand:SI 0 "arith_operand" "%r")
6998 (match_operand:SI 1 "arith_operand" "rI")])
7001 "%A2cc\\t%0, %1, %%g0"
7002 [(set_attr "type" "compare")])
7004 (define_insn "*cmp_ccx_arith_op"
7007 (match_operator:DI 2 "cc_arithop"
7008 [(match_operand:DI 0 "arith_double_operand" "%r")
7009 (match_operand:DI 1 "arith_double_operand" "rHI")])
7012 "%A2cc\\t%0, %1, %%g0"
7013 [(set_attr "type" "compare")])
7015 (define_insn "*cmp_cc_arith_op_set"
7018 (match_operator:SI 3 "cc_arithop"
7019 [(match_operand:SI 1 "arith_operand" "%r")
7020 (match_operand:SI 2 "arith_operand" "rI")])
7022 (set (match_operand:SI 0 "register_operand" "=r")
7023 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7024 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7025 "%A3cc\\t%1, %2, %0"
7026 [(set_attr "type" "compare")])
7028 (define_insn "*cmp_ccx_arith_op_set"
7031 (match_operator:DI 3 "cc_arithop"
7032 [(match_operand:DI 1 "arith_double_operand" "%r")
7033 (match_operand:DI 2 "arith_double_operand" "rHI")])
7035 (set (match_operand:DI 0 "register_operand" "=r")
7036 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7037 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7038 "%A3cc\\t%1, %2, %0"
7039 [(set_attr "type" "compare")])
7041 (define_insn "*cmp_cc_xor_not"
7044 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7045 (match_operand:SI 1 "arith_operand" "rI")))
7048 "xnorcc\\t%r0, %1, %%g0"
7049 [(set_attr "type" "compare")])
7051 (define_insn "*cmp_ccx_xor_not"
7054 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7055 (match_operand:DI 1 "arith_double_operand" "rHI")))
7058 "xnorcc\\t%r0, %1, %%g0"
7059 [(set_attr "type" "compare")])
7061 (define_insn "*cmp_cc_xor_not_set"
7064 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7065 (match_operand:SI 2 "arith_operand" "rI")))
7067 (set (match_operand:SI 0 "register_operand" "=r")
7068 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7070 "xnorcc\\t%r1, %2, %0"
7071 [(set_attr "type" "compare")])
7073 (define_insn "*cmp_ccx_xor_not_set"
7076 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7077 (match_operand:DI 2 "arith_double_operand" "rHI")))
7079 (set (match_operand:DI 0 "register_operand" "=r")
7080 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7082 "xnorcc\\t%r1, %2, %0"
7083 [(set_attr "type" "compare")])
7085 (define_insn "*cmp_cc_arith_op_not"
7088 (match_operator:SI 2 "cc_arithopn"
7089 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7090 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7093 "%B2cc\\t%r1, %0, %%g0"
7094 [(set_attr "type" "compare")])
7096 (define_insn "*cmp_ccx_arith_op_not"
7099 (match_operator:DI 2 "cc_arithopn"
7100 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7101 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7104 "%B2cc\\t%r1, %0, %%g0"
7105 [(set_attr "type" "compare")])
7107 (define_insn "*cmp_cc_arith_op_not_set"
7110 (match_operator:SI 3 "cc_arithopn"
7111 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7112 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7114 (set (match_operand:SI 0 "register_operand" "=r")
7115 (match_operator:SI 4 "cc_arithopn"
7116 [(not:SI (match_dup 1)) (match_dup 2)]))]
7117 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7118 "%B3cc\\t%r2, %1, %0"
7119 [(set_attr "type" "compare")])
7121 (define_insn "*cmp_ccx_arith_op_not_set"
7124 (match_operator:DI 3 "cc_arithopn"
7125 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7126 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7128 (set (match_operand:DI 0 "register_operand" "=r")
7129 (match_operator:DI 4 "cc_arithopn"
7130 [(not:DI (match_dup 1)) (match_dup 2)]))]
7131 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7132 "%B3cc\\t%r2, %1, %0"
7133 [(set_attr "type" "compare")])
7135 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7136 ;; does not know how to make it work for constants.
7138 (define_expand "negdi2"
7139 [(set (match_operand:DI 0 "register_operand" "=r")
7140 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7144 if (! TARGET_ARCH64)
7146 emit_insn (gen_rtx_PARALLEL
7149 gen_rtx_SET (VOIDmode, operand0,
7150 gen_rtx_NEG (DImode, operand1)),
7151 gen_rtx_CLOBBER (VOIDmode,
7152 gen_rtx_REG (CCmode,
7158 (define_insn "*negdi2_sp32"
7159 [(set (match_operand:DI 0 "register_operand" "=r")
7160 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7161 (clobber (reg:CC 100))]
7164 [(set_attr "length" "2")])
7167 [(set (match_operand:DI 0 "register_operand" "")
7168 (neg:DI (match_operand:DI 1 "register_operand" "")))
7169 (clobber (reg:CC 100))]
7171 && reload_completed"
7172 [(parallel [(set (reg:CC_NOOV 100)
7173 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7175 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7176 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7177 (ltu:SI (reg:CC 100) (const_int 0))))]
7178 "operands[2] = gen_highpart (SImode, operands[0]);
7179 operands[3] = gen_highpart (SImode, operands[1]);
7180 operands[4] = gen_lowpart (SImode, operands[0]);
7181 operands[5] = gen_lowpart (SImode, operands[1]);")
7183 (define_insn "*negdi2_sp64"
7184 [(set (match_operand:DI 0 "register_operand" "=r")
7185 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7187 "sub\\t%%g0, %1, %0")
7189 (define_insn "negsi2"
7190 [(set (match_operand:SI 0 "register_operand" "=r")
7191 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7193 "sub\\t%%g0, %1, %0")
7195 (define_insn "*cmp_cc_neg"
7196 [(set (reg:CC_NOOV 100)
7197 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7200 "subcc\\t%%g0, %0, %%g0"
7201 [(set_attr "type" "compare")])
7203 (define_insn "*cmp_ccx_neg"
7204 [(set (reg:CCX_NOOV 100)
7205 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7208 "subcc\\t%%g0, %0, %%g0"
7209 [(set_attr "type" "compare")])
7211 (define_insn "*cmp_cc_set_neg"
7212 [(set (reg:CC_NOOV 100)
7213 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7215 (set (match_operand:SI 0 "register_operand" "=r")
7216 (neg:SI (match_dup 1)))]
7218 "subcc\\t%%g0, %1, %0"
7219 [(set_attr "type" "compare")])
7221 (define_insn "*cmp_ccx_set_neg"
7222 [(set (reg:CCX_NOOV 100)
7223 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7225 (set (match_operand:DI 0 "register_operand" "=r")
7226 (neg:DI (match_dup 1)))]
7228 "subcc\\t%%g0, %1, %0"
7229 [(set_attr "type" "compare")])
7231 ;; We cannot use the "not" pseudo insn because the Sun assembler
7232 ;; does not know how to make it work for constants.
7233 (define_expand "one_cmpldi2"
7234 [(set (match_operand:DI 0 "register_operand" "")
7235 (not:DI (match_operand:DI 1 "register_operand" "")))]
7239 (define_insn "*one_cmpldi2_sp32"
7240 [(set (match_operand:DI 0 "register_operand" "=r,b")
7241 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7246 [(set_attr "type" "*,fp")
7247 (set_attr "length" "2,*")
7248 (set_attr "fptype" "double")])
7251 [(set (match_operand:DI 0 "register_operand" "")
7252 (not:DI (match_operand:DI 1 "register_operand" "")))]
7255 && ((GET_CODE (operands[0]) == REG
7256 && REGNO (operands[0]) < 32)
7257 || (GET_CODE (operands[0]) == SUBREG
7258 && GET_CODE (SUBREG_REG (operands[0])) == REG
7259 && REGNO (SUBREG_REG (operands[0])) < 32))"
7260 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7261 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7262 "operands[2] = gen_highpart (SImode, operands[0]);
7263 operands[3] = gen_highpart (SImode, operands[1]);
7264 operands[4] = gen_lowpart (SImode, operands[0]);
7265 operands[5] = gen_lowpart (SImode, operands[1]);")
7267 (define_insn "*one_cmpldi2_sp64"
7268 [(set (match_operand:DI 0 "register_operand" "=r,b")
7269 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7274 [(set_attr "type" "*,fp")
7275 (set_attr "fptype" "double")])
7277 (define_insn "one_cmplsi2"
7278 [(set (match_operand:SI 0 "register_operand" "=r,d")
7279 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7284 [(set_attr "type" "*,fp")])
7286 (define_insn "*cmp_cc_not"
7288 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7291 "xnorcc\\t%%g0, %0, %%g0"
7292 [(set_attr "type" "compare")])
7294 (define_insn "*cmp_ccx_not"
7296 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7299 "xnorcc\\t%%g0, %0, %%g0"
7300 [(set_attr "type" "compare")])
7302 (define_insn "*cmp_cc_set_not"
7304 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7306 (set (match_operand:SI 0 "register_operand" "=r")
7307 (not:SI (match_dup 1)))]
7309 "xnorcc\\t%%g0, %1, %0"
7310 [(set_attr "type" "compare")])
7312 (define_insn "*cmp_ccx_set_not"
7314 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7316 (set (match_operand:DI 0 "register_operand" "=r")
7317 (not:DI (match_dup 1)))]
7319 "xnorcc\\t%%g0, %1, %0"
7320 [(set_attr "type" "compare")])
7322 (define_insn "*cmp_cc_set"
7323 [(set (match_operand:SI 0 "register_operand" "=r")
7324 (match_operand:SI 1 "register_operand" "r"))
7326 (compare:CC (match_dup 1)
7330 [(set_attr "type" "compare")])
7332 (define_insn "*cmp_ccx_set64"
7333 [(set (match_operand:DI 0 "register_operand" "=r")
7334 (match_operand:DI 1 "register_operand" "r"))
7336 (compare:CCX (match_dup 1)
7340 [(set_attr "type" "compare")])
7342 ;; Floating point arithmetic instructions.
7344 (define_expand "addtf3"
7345 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7346 (plus:TF (match_operand:TF 1 "general_operand" "")
7347 (match_operand:TF 2 "general_operand" "")))]
7348 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7351 if (! TARGET_HARD_QUAD)
7353 rtx slot0, slot1, slot2;
7355 if (GET_CODE (operands[0]) != MEM)
7356 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7358 slot0 = operands[0];
7359 if (GET_CODE (operands[1]) != MEM)
7361 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7362 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7365 slot1 = operands[1];
7366 if (GET_CODE (operands[2]) != MEM)
7368 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7369 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7372 slot2 = operands[2];
7374 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7376 XEXP (slot0, 0), Pmode,
7377 XEXP (slot1, 0), Pmode,
7378 XEXP (slot2, 0), Pmode);
7380 if (GET_CODE (operands[0]) != MEM)
7381 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7386 (define_insn "*addtf3_hq"
7387 [(set (match_operand:TF 0 "register_operand" "=e")
7388 (plus:TF (match_operand:TF 1 "register_operand" "e")
7389 (match_operand:TF 2 "register_operand" "e")))]
7390 "TARGET_FPU && TARGET_HARD_QUAD"
7391 "faddq\\t%1, %2, %0"
7392 [(set_attr "type" "fp")])
7394 (define_insn "adddf3"
7395 [(set (match_operand:DF 0 "register_operand" "=e")
7396 (plus:DF (match_operand:DF 1 "register_operand" "e")
7397 (match_operand:DF 2 "register_operand" "e")))]
7399 "faddd\\t%1, %2, %0"
7400 [(set_attr "type" "fp")
7401 (set_attr "fptype" "double")])
7403 (define_insn "addsf3"
7404 [(set (match_operand:SF 0 "register_operand" "=f")
7405 (plus:SF (match_operand:SF 1 "register_operand" "f")
7406 (match_operand:SF 2 "register_operand" "f")))]
7408 "fadds\\t%1, %2, %0"
7409 [(set_attr "type" "fp")])
7411 (define_expand "subtf3"
7412 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7413 (minus:TF (match_operand:TF 1 "general_operand" "")
7414 (match_operand:TF 2 "general_operand" "")))]
7415 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7418 if (! TARGET_HARD_QUAD)
7420 rtx slot0, slot1, slot2;
7422 if (GET_CODE (operands[0]) != MEM)
7423 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7425 slot0 = operands[0];
7426 if (GET_CODE (operands[1]) != MEM)
7428 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7429 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7432 slot1 = operands[1];
7433 if (GET_CODE (operands[2]) != MEM)
7435 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7436 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7439 slot2 = operands[2];
7441 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7443 XEXP (slot0, 0), Pmode,
7444 XEXP (slot1, 0), Pmode,
7445 XEXP (slot2, 0), Pmode);
7447 if (GET_CODE (operands[0]) != MEM)
7448 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7453 (define_insn "*subtf3_hq"
7454 [(set (match_operand:TF 0 "register_operand" "=e")
7455 (minus:TF (match_operand:TF 1 "register_operand" "e")
7456 (match_operand:TF 2 "register_operand" "e")))]
7457 "TARGET_FPU && TARGET_HARD_QUAD"
7458 "fsubq\\t%1, %2, %0"
7459 [(set_attr "type" "fp")])
7461 (define_insn "subdf3"
7462 [(set (match_operand:DF 0 "register_operand" "=e")
7463 (minus:DF (match_operand:DF 1 "register_operand" "e")
7464 (match_operand:DF 2 "register_operand" "e")))]
7466 "fsubd\\t%1, %2, %0"
7467 [(set_attr "type" "fp")
7468 (set_attr "fptype" "double")])
7470 (define_insn "subsf3"
7471 [(set (match_operand:SF 0 "register_operand" "=f")
7472 (minus:SF (match_operand:SF 1 "register_operand" "f")
7473 (match_operand:SF 2 "register_operand" "f")))]
7475 "fsubs\\t%1, %2, %0"
7476 [(set_attr "type" "fp")])
7478 (define_expand "multf3"
7479 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7480 (mult:TF (match_operand:TF 1 "general_operand" "")
7481 (match_operand:TF 2 "general_operand" "")))]
7482 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7485 if (! TARGET_HARD_QUAD)
7487 rtx slot0, slot1, slot2;
7489 if (GET_CODE (operands[0]) != MEM)
7490 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7492 slot0 = operands[0];
7493 if (GET_CODE (operands[1]) != MEM)
7495 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7496 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7499 slot1 = operands[1];
7500 if (GET_CODE (operands[2]) != MEM)
7502 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7503 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7506 slot2 = operands[2];
7508 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7510 XEXP (slot0, 0), Pmode,
7511 XEXP (slot1, 0), Pmode,
7512 XEXP (slot2, 0), Pmode);
7514 if (GET_CODE (operands[0]) != MEM)
7515 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7520 (define_insn "*multf3_hq"
7521 [(set (match_operand:TF 0 "register_operand" "=e")
7522 (mult:TF (match_operand:TF 1 "register_operand" "e")
7523 (match_operand:TF 2 "register_operand" "e")))]
7524 "TARGET_FPU && TARGET_HARD_QUAD"
7525 "fmulq\\t%1, %2, %0"
7526 [(set_attr "type" "fpmul")])
7528 (define_insn "muldf3"
7529 [(set (match_operand:DF 0 "register_operand" "=e")
7530 (mult:DF (match_operand:DF 1 "register_operand" "e")
7531 (match_operand:DF 2 "register_operand" "e")))]
7533 "fmuld\\t%1, %2, %0"
7534 [(set_attr "type" "fpmul")
7535 (set_attr "fptype" "double")])
7537 (define_insn "mulsf3"
7538 [(set (match_operand:SF 0 "register_operand" "=f")
7539 (mult:SF (match_operand:SF 1 "register_operand" "f")
7540 (match_operand:SF 2 "register_operand" "f")))]
7542 "fmuls\\t%1, %2, %0"
7543 [(set_attr "type" "fpmul")])
7545 (define_insn "*muldf3_extend"
7546 [(set (match_operand:DF 0 "register_operand" "=e")
7547 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7548 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7549 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7550 "fsmuld\\t%1, %2, %0"
7551 [(set_attr "type" "fpmul")
7552 (set_attr "fptype" "double")])
7554 (define_insn "*multf3_extend"
7555 [(set (match_operand:TF 0 "register_operand" "=e")
7556 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7557 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7558 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7559 "fdmulq\\t%1, %2, %0"
7560 [(set_attr "type" "fpmul")])
7562 (define_expand "divtf3"
7563 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7564 (div:TF (match_operand:TF 1 "general_operand" "")
7565 (match_operand:TF 2 "general_operand" "")))]
7566 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7569 if (! TARGET_HARD_QUAD)
7571 rtx slot0, slot1, slot2;
7573 if (GET_CODE (operands[0]) != MEM)
7574 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7576 slot0 = operands[0];
7577 if (GET_CODE (operands[1]) != MEM)
7579 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7580 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7583 slot1 = operands[1];
7584 if (GET_CODE (operands[2]) != MEM)
7586 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7587 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7590 slot2 = operands[2];
7592 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7594 XEXP (slot0, 0), Pmode,
7595 XEXP (slot1, 0), Pmode,
7596 XEXP (slot2, 0), Pmode);
7598 if (GET_CODE (operands[0]) != MEM)
7599 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7604 ;; don't have timing for quad-prec. divide.
7605 (define_insn "*divtf3_hq"
7606 [(set (match_operand:TF 0 "register_operand" "=e")
7607 (div:TF (match_operand:TF 1 "register_operand" "e")
7608 (match_operand:TF 2 "register_operand" "e")))]
7609 "TARGET_FPU && TARGET_HARD_QUAD"
7610 "fdivq\\t%1, %2, %0"
7611 [(set_attr "type" "fpdivd")])
7613 (define_insn "divdf3"
7614 [(set (match_operand:DF 0 "register_operand" "=e")
7615 (div:DF (match_operand:DF 1 "register_operand" "e")
7616 (match_operand:DF 2 "register_operand" "e")))]
7618 "fdivd\\t%1, %2, %0"
7619 [(set_attr "type" "fpdivd")
7620 (set_attr "fptype" "double")])
7622 (define_insn "divsf3"
7623 [(set (match_operand:SF 0 "register_operand" "=f")
7624 (div:SF (match_operand:SF 1 "register_operand" "f")
7625 (match_operand:SF 2 "register_operand" "f")))]
7627 "fdivs\\t%1, %2, %0"
7628 [(set_attr "type" "fpdivs")])
7630 (define_expand "negtf2"
7631 [(set (match_operand:TF 0 "register_operand" "=e,e")
7632 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7636 (define_insn "*negtf2_notv9"
7637 [(set (match_operand:TF 0 "register_operand" "=e,e")
7638 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7639 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7645 [(set_attr "type" "fpmove,*")
7646 (set_attr "length" "*,2")])
7649 [(set (match_operand:TF 0 "register_operand" "")
7650 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7654 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7655 [(set (match_dup 2) (neg:SF (match_dup 3)))
7656 (set (match_dup 4) (match_dup 5))
7657 (set (match_dup 6) (match_dup 7))]
7658 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7659 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7660 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7661 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7662 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7663 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7665 (define_insn "*negtf2_v9"
7666 [(set (match_operand:TF 0 "register_operand" "=e,e")
7667 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7668 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7669 "TARGET_FPU && TARGET_V9"
7673 [(set_attr "type" "fpmove,*")
7674 (set_attr "length" "*,2")
7675 (set_attr "fptype" "double")])
7678 [(set (match_operand:TF 0 "register_operand" "")
7679 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7683 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7684 [(set (match_dup 2) (neg:DF (match_dup 3)))
7685 (set (match_dup 4) (match_dup 5))]
7686 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7687 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7688 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7689 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7691 (define_expand "negdf2"
7692 [(set (match_operand:DF 0 "register_operand" "")
7693 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7697 (define_insn "*negdf2_notv9"
7698 [(set (match_operand:DF 0 "register_operand" "=e,e")
7699 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7700 "TARGET_FPU && ! TARGET_V9"
7704 [(set_attr "type" "fpmove,*")
7705 (set_attr "length" "*,2")])
7708 [(set (match_operand:DF 0 "register_operand" "")
7709 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7713 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7714 [(set (match_dup 2) (neg:SF (match_dup 3)))
7715 (set (match_dup 4) (match_dup 5))]
7716 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7717 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7718 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7719 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7721 (define_insn "*negdf2_v9"
7722 [(set (match_operand:DF 0 "register_operand" "=e")
7723 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7724 "TARGET_FPU && TARGET_V9"
7726 [(set_attr "type" "fpmove")
7727 (set_attr "fptype" "double")])
7729 (define_insn "negsf2"
7730 [(set (match_operand:SF 0 "register_operand" "=f")
7731 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7734 [(set_attr "type" "fpmove")])
7736 (define_expand "abstf2"
7737 [(set (match_operand:TF 0 "register_operand" "")
7738 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7742 (define_insn "*abstf2_notv9"
7743 [(set (match_operand:TF 0 "register_operand" "=e,e")
7744 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7745 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7746 "TARGET_FPU && ! TARGET_V9"
7750 [(set_attr "type" "fpmove,*")
7751 (set_attr "length" "*,2")])
7754 [(set (match_operand:TF 0 "register_operand" "")
7755 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7759 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7760 [(set (match_dup 2) (abs:SF (match_dup 3)))
7761 (set (match_dup 4) (match_dup 5))
7762 (set (match_dup 6) (match_dup 7))]
7763 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7764 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7765 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7766 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7767 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7768 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7770 (define_insn "*abstf2_hq_v9"
7771 [(set (match_operand:TF 0 "register_operand" "=e,e")
7772 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7773 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7777 [(set_attr "type" "fpmove")
7778 (set_attr "fptype" "double,*")])
7780 (define_insn "*abstf2_v9"
7781 [(set (match_operand:TF 0 "register_operand" "=e,e")
7782 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7783 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7787 [(set_attr "type" "fpmove,*")
7788 (set_attr "length" "*,2")
7789 (set_attr "fptype" "double,*")])
7792 [(set (match_operand:TF 0 "register_operand" "")
7793 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7797 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7798 [(set (match_dup 2) (abs:DF (match_dup 3)))
7799 (set (match_dup 4) (match_dup 5))]
7800 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7801 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7802 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7803 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7805 (define_expand "absdf2"
7806 [(set (match_operand:DF 0 "register_operand" "")
7807 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7811 (define_insn "*absdf2_notv9"
7812 [(set (match_operand:DF 0 "register_operand" "=e,e")
7813 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7814 "TARGET_FPU && ! TARGET_V9"
7818 [(set_attr "type" "fpmove,*")
7819 (set_attr "length" "*,2")])
7822 [(set (match_operand:DF 0 "register_operand" "")
7823 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7827 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7828 [(set (match_dup 2) (abs:SF (match_dup 3)))
7829 (set (match_dup 4) (match_dup 5))]
7830 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7831 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7832 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7833 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7835 (define_insn "*absdf2_v9"
7836 [(set (match_operand:DF 0 "register_operand" "=e")
7837 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7838 "TARGET_FPU && TARGET_V9"
7840 [(set_attr "type" "fpmove")
7841 (set_attr "fptype" "double")])
7843 (define_insn "abssf2"
7844 [(set (match_operand:SF 0 "register_operand" "=f")
7845 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7848 [(set_attr "type" "fpmove")])
7850 (define_expand "sqrttf2"
7851 [(set (match_operand:TF 0 "register_operand" "=e")
7852 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7853 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7856 if (! TARGET_HARD_QUAD)
7860 if (GET_CODE (operands[0]) != MEM)
7861 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7863 slot0 = operands[0];
7864 if (GET_CODE (operands[1]) != MEM)
7866 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7867 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7870 slot1 = operands[1];
7872 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7874 XEXP (slot0, 0), Pmode,
7875 XEXP (slot1, 0), Pmode);
7877 if (GET_CODE (operands[0]) != MEM)
7878 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7883 (define_insn "*sqrttf2_hq"
7884 [(set (match_operand:TF 0 "register_operand" "=e")
7885 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7886 "TARGET_FPU && TARGET_HARD_QUAD"
7888 [(set_attr "type" "fpsqrtd")])
7890 (define_insn "sqrtdf2"
7891 [(set (match_operand:DF 0 "register_operand" "=e")
7892 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7895 [(set_attr "type" "fpsqrtd")
7896 (set_attr "fptype" "double")])
7898 (define_insn "sqrtsf2"
7899 [(set (match_operand:SF 0 "register_operand" "=f")
7900 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7903 [(set_attr "type" "fpsqrts")])
7905 ;;- arithmetic shift instructions
7907 (define_insn "ashlsi3"
7908 [(set (match_operand:SI 0 "register_operand" "=r")
7909 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7910 (match_operand:SI 2 "arith_operand" "rI")))]
7914 if (GET_CODE (operands[2]) == CONST_INT
7915 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7916 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7918 return \"sll\\t%1, %2, %0\";
7920 [(set_attr "type" "shift")])
7922 ;; We special case multiplication by two, as add can be done
7923 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7924 (define_insn "*ashlsi3_const1"
7925 [(set (match_operand:SI 0 "register_operand" "=r")
7926 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7931 (define_expand "ashldi3"
7932 [(set (match_operand:DI 0 "register_operand" "=r")
7933 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7934 (match_operand:SI 2 "arith_operand" "rI")))]
7935 "TARGET_ARCH64 || TARGET_V8PLUS"
7938 if (! TARGET_ARCH64)
7940 if (GET_CODE (operands[2]) == CONST_INT)
7942 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7947 ;; We special case multiplication by two, as add can be done
7948 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7949 (define_insn "*ashldi3_const1"
7950 [(set (match_operand:DI 0 "register_operand" "=r")
7951 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7956 (define_insn "*ashldi3_sp64"
7957 [(set (match_operand:DI 0 "register_operand" "=r")
7958 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7959 (match_operand:SI 2 "arith_operand" "rI")))]
7963 if (GET_CODE (operands[2]) == CONST_INT
7964 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7965 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7967 return \"sllx\\t%1, %2, %0\";
7969 [(set_attr "type" "shift")])
7972 (define_insn "ashldi3_v8plus"
7973 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7974 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7975 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7976 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7978 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7979 [(set_attr "type" "multi")
7980 (set_attr "length" "5,5,6")])
7982 ;; Optimize (1LL<<x)-1
7983 ;; XXX this also needs to be fixed to handle equal subregs
7984 ;; XXX first before we could re-enable it.
7986 ; [(set (match_operand:DI 0 "register_operand" "=h")
7987 ; (plus:DI (ashift:DI (const_int 1)
7988 ; (match_operand:SI 1 "arith_operand" "rI"))
7990 ; "0 && TARGET_V8PLUS"
7993 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7994 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7995 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7997 ; [(set_attr "type" "multi")
7998 ; (set_attr "length" "4")])
8000 (define_insn "*cmp_cc_ashift_1"
8001 [(set (reg:CC_NOOV 100)
8002 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8006 "addcc\\t%0, %0, %%g0"
8007 [(set_attr "type" "compare")])
8009 (define_insn "*cmp_cc_set_ashift_1"
8010 [(set (reg:CC_NOOV 100)
8011 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8014 (set (match_operand:SI 0 "register_operand" "=r")
8015 (ashift:SI (match_dup 1) (const_int 1)))]
8017 "addcc\\t%1, %1, %0"
8018 [(set_attr "type" "compare")])
8020 (define_insn "ashrsi3"
8021 [(set (match_operand:SI 0 "register_operand" "=r")
8022 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8023 (match_operand:SI 2 "arith_operand" "rI")))]
8027 if (GET_CODE (operands[2]) == CONST_INT
8028 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8029 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8031 return \"sra\\t%1, %2, %0\";
8033 [(set_attr "type" "shift")])
8035 (define_insn "*ashrsi3_extend"
8036 [(set (match_operand:DI 0 "register_operand" "=r")
8037 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8038 (match_operand:SI 2 "arith_operand" "r"))))]
8041 [(set_attr "type" "shift")])
8043 ;; This handles the case as above, but with constant shift instead of
8044 ;; register. Combiner "simplifies" it for us a little bit though.
8045 (define_insn "*ashrsi3_extend2"
8046 [(set (match_operand:DI 0 "register_operand" "=r")
8047 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8049 (match_operand:SI 2 "small_int_or_double" "n")))]
8051 && ((GET_CODE (operands[2]) == CONST_INT
8052 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8053 || (GET_CODE (operands[2]) == CONST_DOUBLE
8054 && !CONST_DOUBLE_HIGH (operands[2])
8055 && CONST_DOUBLE_LOW (operands[2]) >= 32
8056 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8059 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8061 return \"sra\\t%1, %2, %0\";
8063 [(set_attr "type" "shift")])
8065 (define_expand "ashrdi3"
8066 [(set (match_operand:DI 0 "register_operand" "=r")
8067 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8068 (match_operand:SI 2 "arith_operand" "rI")))]
8069 "TARGET_ARCH64 || TARGET_V8PLUS"
8072 if (! TARGET_ARCH64)
8074 if (GET_CODE (operands[2]) == CONST_INT)
8075 FAIL; /* prefer generic code in this case */
8076 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8082 [(set (match_operand:DI 0 "register_operand" "=r")
8083 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8084 (match_operand:SI 2 "arith_operand" "rI")))]
8088 if (GET_CODE (operands[2]) == CONST_INT
8089 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8090 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8092 return \"srax\\t%1, %2, %0\";
8094 [(set_attr "type" "shift")])
8097 (define_insn "ashrdi3_v8plus"
8098 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8099 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8100 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8101 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8103 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8104 [(set_attr "type" "multi")
8105 (set_attr "length" "5,5,6")])
8107 (define_insn "lshrsi3"
8108 [(set (match_operand:SI 0 "register_operand" "=r")
8109 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8110 (match_operand:SI 2 "arith_operand" "rI")))]
8114 if (GET_CODE (operands[2]) == CONST_INT
8115 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8116 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8118 return \"srl\\t%1, %2, %0\";
8120 [(set_attr "type" "shift")])
8122 ;; This handles the case where
8123 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8124 ;; but combiner "simplifies" it for us.
8125 (define_insn "*lshrsi3_extend"
8126 [(set (match_operand:DI 0 "register_operand" "=r")
8127 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8128 (match_operand:SI 2 "arith_operand" "r")) 0)
8129 (match_operand 3 "" "")))]
8131 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8132 && CONST_DOUBLE_HIGH (operands[3]) == 0
8133 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8134 || (HOST_BITS_PER_WIDE_INT >= 64
8135 && GET_CODE (operands[3]) == CONST_INT
8136 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8138 [(set_attr "type" "shift")])
8140 ;; This handles the case where
8141 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8142 ;; but combiner "simplifies" it for us.
8143 (define_insn "*lshrsi3_extend2"
8144 [(set (match_operand:DI 0 "register_operand" "=r")
8145 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8146 (match_operand 2 "small_int_or_double" "n")
8149 && ((GET_CODE (operands[2]) == CONST_INT
8150 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8151 || (GET_CODE (operands[2]) == CONST_DOUBLE
8152 && CONST_DOUBLE_HIGH (operands[2]) == 0
8153 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8156 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8158 return \"srl\\t%1, %2, %0\";
8160 [(set_attr "type" "shift")])
8162 (define_expand "lshrdi3"
8163 [(set (match_operand:DI 0 "register_operand" "=r")
8164 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8165 (match_operand:SI 2 "arith_operand" "rI")))]
8166 "TARGET_ARCH64 || TARGET_V8PLUS"
8169 if (! TARGET_ARCH64)
8171 if (GET_CODE (operands[2]) == CONST_INT)
8173 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8179 [(set (match_operand:DI 0 "register_operand" "=r")
8180 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8181 (match_operand:SI 2 "arith_operand" "rI")))]
8185 if (GET_CODE (operands[2]) == CONST_INT
8186 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8187 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8189 return \"srlx\\t%1, %2, %0\";
8191 [(set_attr "type" "shift")])
8194 (define_insn "lshrdi3_v8plus"
8195 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8196 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8197 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8198 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8200 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8201 [(set_attr "type" "multi")
8202 (set_attr "length" "5,5,6")])
8205 [(set (match_operand:SI 0 "register_operand" "=r")
8206 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8208 (match_operand:SI 2 "small_int_or_double" "n")))]
8210 && ((GET_CODE (operands[2]) == CONST_INT
8211 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8212 || (GET_CODE (operands[2]) == CONST_DOUBLE
8213 && !CONST_DOUBLE_HIGH (operands[2])
8214 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8217 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8219 return \"srax\\t%1, %2, %0\";
8221 [(set_attr "type" "shift")])
8224 [(set (match_operand:SI 0 "register_operand" "=r")
8225 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8227 (match_operand:SI 2 "small_int_or_double" "n")))]
8229 && ((GET_CODE (operands[2]) == CONST_INT
8230 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8231 || (GET_CODE (operands[2]) == CONST_DOUBLE
8232 && !CONST_DOUBLE_HIGH (operands[2])
8233 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8236 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8238 return \"srlx\\t%1, %2, %0\";
8240 [(set_attr "type" "shift")])
8243 [(set (match_operand:SI 0 "register_operand" "=r")
8244 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8245 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8246 (match_operand:SI 3 "small_int_or_double" "n")))]
8248 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8249 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8250 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8251 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8254 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8256 return \"srax\\t%1, %2, %0\";
8258 [(set_attr "type" "shift")])
8261 [(set (match_operand:SI 0 "register_operand" "=r")
8262 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8263 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8264 (match_operand:SI 3 "small_int_or_double" "n")))]
8266 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8267 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8268 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8269 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8272 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8274 return \"srlx\\t%1, %2, %0\";
8276 [(set_attr "type" "shift")])
8278 ;; Unconditional and other jump instructions
8279 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8280 ;; following insn is never executed. This saves us a nop. Dbx does not
8281 ;; handle such branches though, so we only use them when optimizing.
8283 [(set (pc) (label_ref (match_operand 0 "" "")))]
8287 /* TurboSparc is reported to have problems with
8290 i.e. an empty loop with the annul bit set. The workaround is to use
8294 if (! TARGET_V9 && flag_delayed_branch
8295 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8296 == INSN_ADDRESSES (INSN_UID (insn))))
8297 return \"b\\t%l0%#\";
8299 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8301 [(set_attr "type" "uncond_branch")])
8303 (define_expand "tablejump"
8304 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8305 (use (label_ref (match_operand 1 "" "")))])]
8309 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8312 /* In pic mode, our address differences are against the base of the
8313 table. Add that base value back in; CSE ought to be able to combine
8314 the two address loads. */
8318 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8320 if (CASE_VECTOR_MODE != Pmode)
8321 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8322 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8323 operands[0] = memory_address (Pmode, tmp);
8327 (define_insn "*tablejump_sp32"
8328 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8329 (use (label_ref (match_operand 1 "" "")))]
8332 [(set_attr "type" "uncond_branch")])
8334 (define_insn "*tablejump_sp64"
8335 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8336 (use (label_ref (match_operand 1 "" "")))]
8339 [(set_attr "type" "uncond_branch")])
8341 ;; This pattern recognizes the "instruction" that appears in
8342 ;; a function call that wants a structure value,
8343 ;; to inform the called function if compiled with Sun CC.
8344 ;(define_insn "*unimp_insn"
8345 ; [(match_operand:SI 0 "immediate_operand" "")]
8346 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8348 ; [(set_attr "type" "marker")])
8350 ;;- jump to subroutine
8351 (define_expand "call"
8352 ;; Note that this expression is not used for generating RTL.
8353 ;; All the RTL is generated explicitly below.
8354 [(call (match_operand 0 "call_operand" "")
8355 (match_operand 3 "" "i"))]
8356 ;; operands[2] is next_arg_register
8357 ;; operands[3] is struct_value_size_rtx.
8361 rtx fn_rtx, nregs_rtx;
8363 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8366 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8368 /* This is really a PIC sequence. We want to represent
8369 it as a funny jump so its delay slots can be filled.
8371 ??? But if this really *is* a CALL, will not it clobber the
8372 call-clobbered registers? We lose this if it is a JUMP_INSN.
8373 Why cannot we have delay slots filled if it were a CALL? */
8375 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8380 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8382 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8388 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8389 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8393 fn_rtx = operands[0];
8395 /* Count the number of parameter registers being used by this call.
8396 if that argument is NULL, it means we are using them all, which
8397 means 6 on the sparc. */
8400 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8402 nregs_rtx = GEN_INT (6);
8404 nregs_rtx = const0_rtx;
8407 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8411 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8413 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8418 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8419 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8423 /* If this call wants a structure value,
8424 emit an unimp insn to let the called function know about this. */
8425 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8427 rtx insn = emit_insn (operands[3]);
8428 SCHED_GROUP_P (insn) = 1;
8435 ;; We can't use the same pattern for these two insns, because then registers
8436 ;; in the address may not be properly reloaded.
8438 (define_insn "*call_address_sp32"
8439 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8440 (match_operand 1 "" ""))
8441 (clobber (reg:SI 15))]
8442 ;;- Do not use operand 1 for most machines.
8445 [(set_attr "type" "call")])
8447 (define_insn "*call_symbolic_sp32"
8448 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8449 (match_operand 1 "" ""))
8450 (clobber (reg:SI 15))]
8451 ;;- Do not use operand 1 for most machines.
8454 [(set_attr "type" "call")])
8456 (define_insn "*call_address_sp64"
8457 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8458 (match_operand 1 "" ""))
8459 (clobber (reg:DI 15))]
8460 ;;- Do not use operand 1 for most machines.
8463 [(set_attr "type" "call")])
8465 (define_insn "*call_symbolic_sp64"
8466 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8467 (match_operand 1 "" ""))
8468 (clobber (reg:DI 15))]
8469 ;;- Do not use operand 1 for most machines.
8472 [(set_attr "type" "call")])
8474 ;; This is a call that wants a structure value.
8475 ;; There is no such critter for v9 (??? we may need one anyway).
8476 (define_insn "*call_address_struct_value_sp32"
8477 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8478 (match_operand 1 "" ""))
8479 (match_operand 2 "immediate_operand" "")
8480 (clobber (reg:SI 15))]
8481 ;;- Do not use operand 1 for most machines.
8482 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8483 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8484 [(set_attr "type" "call_no_delay_slot")
8485 (set_attr "length" "3")])
8487 ;; This is a call that wants a structure value.
8488 ;; There is no such critter for v9 (??? we may need one anyway).
8489 (define_insn "*call_symbolic_struct_value_sp32"
8490 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8491 (match_operand 1 "" ""))
8492 (match_operand 2 "immediate_operand" "")
8493 (clobber (reg:SI 15))]
8494 ;;- Do not use operand 1 for most machines.
8495 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8496 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8497 [(set_attr "type" "call_no_delay_slot")
8498 (set_attr "length" "3")])
8500 ;; This is a call that may want a structure value. This is used for
8502 (define_insn "*call_address_untyped_struct_value_sp32"
8503 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8504 (match_operand 1 "" ""))
8505 (match_operand 2 "immediate_operand" "")
8506 (clobber (reg:SI 15))]
8507 ;;- Do not use operand 1 for most machines.
8508 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8509 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8510 [(set_attr "type" "call_no_delay_slot")
8511 (set_attr "length" "3")])
8513 ;; This is a call that wants a structure value.
8514 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8515 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8516 (match_operand 1 "" ""))
8517 (match_operand 2 "immediate_operand" "")
8518 (clobber (reg:SI 15))]
8519 ;;- Do not use operand 1 for most machines.
8520 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8521 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8522 [(set_attr "type" "call_no_delay_slot")
8523 (set_attr "length" "3")])
8525 (define_expand "call_value"
8526 ;; Note that this expression is not used for generating RTL.
8527 ;; All the RTL is generated explicitly below.
8528 [(set (match_operand 0 "register_operand" "=rf")
8529 (call (match_operand 1 "" "")
8530 (match_operand 4 "" "")))]
8531 ;; operand 2 is stack_size_rtx
8532 ;; operand 3 is next_arg_register
8536 rtx fn_rtx, nregs_rtx;
8539 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8542 fn_rtx = operands[1];
8546 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8548 nregs_rtx = GEN_INT (6);
8550 nregs_rtx = const0_rtx;
8554 gen_rtx_SET (VOIDmode, operands[0],
8555 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8556 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8558 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8563 (define_insn "*call_value_address_sp32"
8564 [(set (match_operand 0 "" "=rf")
8565 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8566 (match_operand 2 "" "")))
8567 (clobber (reg:SI 15))]
8568 ;;- Do not use operand 2 for most machines.
8571 [(set_attr "type" "call")])
8573 (define_insn "*call_value_symbolic_sp32"
8574 [(set (match_operand 0 "" "=rf")
8575 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8576 (match_operand 2 "" "")))
8577 (clobber (reg:SI 15))]
8578 ;;- Do not use operand 2 for most machines.
8581 [(set_attr "type" "call")])
8583 (define_insn "*call_value_address_sp64"
8584 [(set (match_operand 0 "" "")
8585 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8586 (match_operand 2 "" "")))
8587 (clobber (reg:DI 15))]
8588 ;;- Do not use operand 2 for most machines.
8591 [(set_attr "type" "call")])
8593 (define_insn "*call_value_symbolic_sp64"
8594 [(set (match_operand 0 "" "")
8595 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8596 (match_operand 2 "" "")))
8597 (clobber (reg:DI 15))]
8598 ;;- Do not use operand 2 for most machines.
8601 [(set_attr "type" "call")])
8603 (define_expand "untyped_call"
8604 [(parallel [(call (match_operand 0 "" "")
8606 (match_operand 1 "" "")
8607 (match_operand 2 "" "")])]
8613 /* Pass constm1 to indicate that it may expect a structure value, but
8614 we don't know what size it is. */
8615 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8617 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8619 rtx set = XVECEXP (operands[2], 0, i);
8620 emit_move_insn (SET_DEST (set), SET_SRC (set));
8623 /* The optimizer does not know that the call sets the function value
8624 registers we stored in the result block. We avoid problems by
8625 claiming that all hard registers are used and clobbered at this
8627 emit_insn (gen_blockage ());
8633 (define_expand "sibcall"
8634 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8639 (define_insn "*sibcall_symbolic_sp32"
8640 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8641 (match_operand 1 "" ""))
8644 "* return output_sibcall(insn, operands[0]);"
8645 [(set_attr "type" "sibcall")])
8647 (define_insn "*sibcall_symbolic_sp64"
8648 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8649 (match_operand 1 "" ""))
8652 "* return output_sibcall(insn, operands[0]);"
8653 [(set_attr "type" "sibcall")])
8655 (define_expand "sibcall_value"
8656 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8657 (call (match_operand 1 "" "") (const_int 0)))
8662 (define_insn "*sibcall_value_symbolic_sp32"
8663 [(set (match_operand 0 "" "=rf")
8664 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8665 (match_operand 2 "" "")))
8668 "* return output_sibcall(insn, operands[1]);"
8669 [(set_attr "type" "sibcall")])
8671 (define_insn "*sibcall_value_symbolic_sp64"
8672 [(set (match_operand 0 "" "")
8673 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8674 (match_operand 2 "" "")))
8677 "* return output_sibcall(insn, operands[1]);"
8678 [(set_attr "type" "sibcall")])
8680 (define_expand "sibcall_epilogue"
8685 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8686 ;; all of memory. This blocks insns from being moved across this point.
8688 (define_insn "blockage"
8689 [(unspec_volatile [(const_int 0)] 0)]
8692 [(set_attr "length" "0")])
8694 ;; Prepare to return any type including a structure value.
8696 (define_expand "untyped_return"
8697 [(match_operand:BLK 0 "memory_operand" "")
8698 (match_operand 1 "" "")]
8702 rtx valreg1 = gen_rtx_REG (DImode, 24);
8703 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8704 rtx result = operands[0];
8706 if (! TARGET_ARCH64)
8708 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8710 rtx value = gen_reg_rtx (SImode);
8712 /* Fetch the instruction where we will return to and see if it's an unimp
8713 instruction (the most significant 10 bits will be zero). If so,
8714 update the return address to skip the unimp instruction. */
8715 emit_move_insn (value,
8716 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8717 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8718 emit_insn (gen_update_return (rtnreg, value));
8721 /* Reload the function value registers. */
8722 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8723 emit_move_insn (valreg2,
8724 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8726 /* Put USE insns before the return. */
8727 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8728 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8730 /* Construct the return. */
8731 expand_null_return ();
8736 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8737 ;; and parts of the compiler don't want to believe that the add is needed.
8739 (define_insn "update_return"
8740 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8741 (match_operand:SI 1 "register_operand" "r")] 1)]
8743 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8744 [(set_attr "type" "multi")
8745 (set_attr "length" "3")])
8752 (define_expand "indirect_jump"
8753 [(set (pc) (match_operand 0 "address_operand" "p"))]
8757 (define_insn "*branch_sp32"
8758 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8761 [(set_attr "type" "uncond_branch")])
8763 (define_insn "*branch_sp64"
8764 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8767 [(set_attr "type" "uncond_branch")])
8769 ;; ??? Doesn't work with -mflat.
8770 (define_expand "nonlocal_goto"
8771 [(match_operand:SI 0 "general_operand" "")
8772 (match_operand:SI 1 "general_operand" "")
8773 (match_operand:SI 2 "general_operand" "")
8774 (match_operand:SI 3 "" "")]
8779 rtx chain = operands[0];
8781 rtx lab = operands[1];
8782 rtx stack = operands[2];
8783 rtx fp = operands[3];
8786 /* Trap instruction to flush all the register windows. */
8787 emit_insn (gen_flush_register_windows ());
8789 /* Load the fp value for the containing fn into %fp. This is needed
8790 because STACK refers to %fp. Note that virtual register instantiation
8791 fails if the virtual %fp isn't set from a register. */
8792 if (GET_CODE (fp) != REG)
8793 fp = force_reg (Pmode, fp);
8794 emit_move_insn (virtual_stack_vars_rtx, fp);
8796 /* Find the containing function's current nonlocal goto handler,
8797 which will do any cleanups and then jump to the label. */
8798 labreg = gen_rtx_REG (Pmode, 8);
8799 emit_move_insn (labreg, lab);
8801 /* Restore %fp from stack pointer value for containing function.
8802 The restore insn that follows will move this to %sp,
8803 and reload the appropriate value into %fp. */
8804 emit_move_insn (hard_frame_pointer_rtx, stack);
8806 /* USE of frame_pointer_rtx added for consistency; not clear if
8808 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8809 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8812 /* Return, restoring reg window and jumping to goto handler. */
8813 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8814 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8816 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8822 /* Put in the static chain register the nonlocal label address. */
8823 emit_move_insn (static_chain_rtx, chain);
8826 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8827 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8832 ;; Special trap insn to flush register windows.
8833 (define_insn "flush_register_windows"
8834 [(unspec_volatile [(const_int 0)] 1)]
8836 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8837 [(set_attr "type" "misc")])
8839 (define_insn "goto_handler_and_restore"
8840 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8841 "GET_MODE (operands[0]) == Pmode"
8842 "jmp\\t%0+0\\n\\trestore"
8843 [(set_attr "type" "multi")
8844 (set_attr "length" "2")])
8846 ;;(define_insn "goto_handler_and_restore_v9"
8847 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8848 ;; (match_operand:SI 1 "register_operand" "=r,r")
8849 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8850 ;; "TARGET_V9 && ! TARGET_ARCH64"
8852 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8853 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8854 ;; [(set_attr "type" "multi")
8855 ;; (set_attr "length" "2,3")])
8857 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8858 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8859 ;; (match_operand:DI 1 "register_operand" "=r,r")
8860 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8861 ;; "TARGET_V9 && TARGET_ARCH64"
8863 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8864 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8865 ;; [(set_attr "type" "multi")
8866 ;; (set_attr "length" "2,3")])
8868 ;; For __builtin_setjmp we need to flush register windows iff the function
8869 ;; calls alloca as well, because otherwise the register window might be
8870 ;; saved after %sp adjustement and thus setjmp would crash
8871 (define_expand "builtin_setjmp_setup"
8872 [(match_operand 0 "register_operand" "r")]
8876 emit_insn (gen_do_builtin_setjmp_setup ());
8880 ;; ??? Should set length to zero when !current_function_calls_alloca,
8881 ;; ??? but there is no easy way to get at that definition. It would
8882 ;; ??? require including function.h into sparc-protos.h and that is
8883 ;; ??? likely not a good idea. -DaveM
8884 (define_insn "do_builtin_setjmp_setup"
8885 [(unspec_volatile [(const_int 0)] 5)]
8889 if (!current_function_calls_alloca)
8895 [(set_attr "type" "misc")])
8897 ;; Pattern for use after a setjmp to store FP and the return register
8898 ;; into the stack area.
8900 (define_expand "setjmp"
8906 emit_insn (gen_setjmp_64 ());
8908 emit_insn (gen_setjmp_32 ());
8912 (define_expand "setjmp_32"
8913 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8914 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8917 { operands[0] = frame_pointer_rtx; }")
8919 (define_expand "setjmp_64"
8920 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8921 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8924 { operands[0] = frame_pointer_rtx; }")
8926 ;; Special pattern for the FLUSH instruction.
8928 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8929 ; of the define_insn otherwise missing a mode. We make "flush", aka
8930 ; gen_flush, the default one since sparc_initialize_trampoline uses
8931 ; it on SImode mem values.
8933 (define_insn "flush"
8934 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8936 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8937 [(set_attr "type" "misc")])
8939 (define_insn "flushdi"
8940 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8942 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8943 [(set_attr "type" "misc")])
8948 ;; The scan instruction searches from the most significant bit while ffs
8949 ;; searches from the least significant bit. The bit index and treatment of
8950 ;; zero also differ. It takes at least 7 instructions to get the proper
8951 ;; result. Here is an obvious 8 instruction sequence.
8954 (define_insn "ffssi2"
8955 [(set (match_operand:SI 0 "register_operand" "=&r")
8956 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8957 (clobber (match_scratch:SI 2 "=&r"))]
8958 "TARGET_SPARCLITE || TARGET_SPARCLET"
8961 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\";
8963 [(set_attr "type" "multi")
8964 (set_attr "length" "8")])
8966 ;; ??? This should be a define expand, so that the extra instruction have
8967 ;; a chance of being optimized away.
8969 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8970 ;; does, but no one uses that and we don't have a switch for it.
8972 ;(define_insn "ffsdi2"
8973 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8974 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8975 ; (clobber (match_scratch:DI 2 "=&r"))]
8977 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8978 ; [(set_attr "type" "multi")
8979 ; (set_attr "length" "4")])
8983 ;; Peepholes go at the end.
8985 ;; Optimize consecutive loads or stores into ldd and std when possible.
8986 ;; The conditions in which we do this are very restricted and are
8987 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8990 [(set (match_operand:SI 0 "memory_operand" "")
8992 (set (match_operand:SI 1 "memory_operand" "")
8995 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8998 "operands[0] = change_address (operands[0], DImode, NULL);")
9001 [(set (match_operand:SI 0 "memory_operand" "")
9003 (set (match_operand:SI 1 "memory_operand" "")
9006 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9009 "operands[1] = change_address (operands[1], DImode, NULL);")
9012 [(set (match_operand:SI 0 "register_operand" "")
9013 (match_operand:SI 1 "memory_operand" ""))
9014 (set (match_operand:SI 2 "register_operand" "")
9015 (match_operand:SI 3 "memory_operand" ""))]
9016 "registers_ok_for_ldd_peep (operands[0], operands[2])
9017 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9020 "operands[1] = change_address (operands[1], DImode, NULL);
9021 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9024 [(set (match_operand:SI 0 "memory_operand" "")
9025 (match_operand:SI 1 "register_operand" ""))
9026 (set (match_operand:SI 2 "memory_operand" "")
9027 (match_operand:SI 3 "register_operand" ""))]
9028 "registers_ok_for_ldd_peep (operands[1], operands[3])
9029 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9032 "operands[0] = change_address (operands[0], DImode, NULL);
9033 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9036 [(set (match_operand:SF 0 "register_operand" "")
9037 (match_operand:SF 1 "memory_operand" ""))
9038 (set (match_operand:SF 2 "register_operand" "")
9039 (match_operand:SF 3 "memory_operand" ""))]
9040 "registers_ok_for_ldd_peep (operands[0], operands[2])
9041 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9044 "operands[1] = change_address (operands[1], DFmode, NULL);
9045 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9048 [(set (match_operand:SF 0 "memory_operand" "")
9049 (match_operand:SF 1 "register_operand" ""))
9050 (set (match_operand:SF 2 "memory_operand" "")
9051 (match_operand:SF 3 "register_operand" ""))]
9052 "registers_ok_for_ldd_peep (operands[1], operands[3])
9053 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9056 "operands[0] = change_address (operands[0], DFmode, NULL);
9057 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9060 [(set (match_operand:SI 0 "register_operand" "")
9061 (match_operand:SI 1 "memory_operand" ""))
9062 (set (match_operand:SI 2 "register_operand" "")
9063 (match_operand:SI 3 "memory_operand" ""))]
9064 "registers_ok_for_ldd_peep (operands[2], operands[0])
9065 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9068 "operands[3] = change_address (operands[3], DImode, NULL);
9069 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9072 [(set (match_operand:SI 0 "memory_operand" "")
9073 (match_operand:SI 1 "register_operand" ""))
9074 (set (match_operand:SI 2 "memory_operand" "")
9075 (match_operand:SI 3 "register_operand" ""))]
9076 "registers_ok_for_ldd_peep (operands[3], operands[1])
9077 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9080 "operands[2] = change_address (operands[2], DImode, NULL);
9081 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9085 [(set (match_operand:SF 0 "register_operand" "")
9086 (match_operand:SF 1 "memory_operand" ""))
9087 (set (match_operand:SF 2 "register_operand" "")
9088 (match_operand:SF 3 "memory_operand" ""))]
9089 "registers_ok_for_ldd_peep (operands[2], operands[0])
9090 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
9093 "operands[3] = change_address (operands[3], DFmode, NULL);
9094 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9097 [(set (match_operand:SF 0 "memory_operand" "")
9098 (match_operand:SF 1 "register_operand" ""))
9099 (set (match_operand:SF 2 "memory_operand" "")
9100 (match_operand:SF 3 "register_operand" ""))]
9101 "registers_ok_for_ldd_peep (operands[3], operands[1])
9102 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9105 "operands[2] = change_address (operands[2], DFmode, NULL);
9106 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9108 ;; Optimize the case of following a reg-reg move with a test
9109 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9110 ;; This can result from a float to fix conversion.
9113 [(set (match_operand:SI 0 "register_operand" "")
9114 (match_operand:SI 1 "register_operand" ""))
9116 (compare:CC (match_operand:SI 2 "register_operand" "")
9118 "(rtx_equal_p (operands[2], operands[0])
9119 || rtx_equal_p (operands[2], operands[1]))
9120 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9121 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9122 [(parallel [(set (match_dup 0) (match_dup 1))
9124 (compare:CC (match_dup 1) (const_int 0)))])]
9128 [(set (match_operand:DI 0 "register_operand" "")
9129 (match_operand:DI 1 "register_operand" ""))
9131 (compare:CCX (match_operand:DI 2 "register_operand" "")
9134 && (rtx_equal_p (operands[2], operands[0])
9135 || rtx_equal_p (operands[2], operands[1]))
9136 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9137 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9138 [(parallel [(set (match_dup 0) (match_dup 1))
9140 (compare:CC (match_dup 1) (const_int 0)))])]
9143 ;; Return peepholes. These are generated by sparc_nonflat_function_epilogue
9144 ;; who then immediately calls final_scan_insn.
9146 (define_insn "*return_qi"
9147 [(set (match_operand:QI 0 "restore_operand" "")
9148 (match_operand:QI 1 "arith_operand" "rI"))
9150 "sparc_emitting_epilogue"
9153 if (! TARGET_ARCH64 && current_function_returns_struct)
9154 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9155 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9156 || IN_OR_GLOBAL_P (operands[1])))
9157 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9159 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9161 [(set_attr "type" "multi")
9162 (set_attr "length" "2")])
9164 (define_insn "*return_hi"
9165 [(set (match_operand:HI 0 "restore_operand" "")
9166 (match_operand:HI 1 "arith_operand" "rI"))
9168 "sparc_emitting_epilogue"
9171 if (! TARGET_ARCH64 && current_function_returns_struct)
9172 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9173 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9174 || IN_OR_GLOBAL_P (operands[1])))
9175 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9177 return \"ret\;restore %%g0, %1, %Y0\";
9179 [(set_attr "type" "multi")
9180 (set_attr "length" "2")])
9182 (define_insn "*return_si"
9183 [(set (match_operand:SI 0 "restore_operand" "")
9184 (match_operand:SI 1 "arith_operand" "rI"))
9186 "sparc_emitting_epilogue"
9189 if (! TARGET_ARCH64 && current_function_returns_struct)
9190 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9191 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9192 || IN_OR_GLOBAL_P (operands[1])))
9193 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9195 return \"ret\;restore %%g0, %1, %Y0\";
9197 [(set_attr "type" "multi")
9198 (set_attr "length" "2")])
9200 (define_insn "*return_sf_no_fpu"
9201 [(set (match_operand:SF 0 "restore_operand" "=r")
9202 (match_operand:SF 1 "register_operand" "r"))
9204 "sparc_emitting_epilogue"
9207 if (! TARGET_ARCH64 && current_function_returns_struct)
9208 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9209 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9210 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9212 return \"ret\;restore %%g0, %1, %Y0\";
9214 [(set_attr "type" "multi")
9215 (set_attr "length" "2")])
9217 (define_insn "*return_df_no_fpu"
9218 [(set (match_operand:DF 0 "restore_operand" "=r")
9219 (match_operand:DF 1 "register_operand" "r"))
9221 "sparc_emitting_epilogue && TARGET_ARCH64"
9224 if (IN_OR_GLOBAL_P (operands[1]))
9225 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9227 return \"ret\;restore %%g0, %1, %Y0\";
9229 [(set_attr "type" "multi")
9230 (set_attr "length" "2")])
9232 (define_insn "*return_addsi"
9233 [(set (match_operand:SI 0 "restore_operand" "")
9234 (plus:SI (match_operand:SI 1 "register_operand" "r")
9235 (match_operand:SI 2 "arith_operand" "rI")))
9237 "sparc_emitting_epilogue"
9240 if (! TARGET_ARCH64 && current_function_returns_struct)
9241 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9242 /* If operands are global or in registers, can use return */
9243 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9244 && (GET_CODE (operands[2]) == CONST_INT
9245 || IN_OR_GLOBAL_P (operands[2])))
9246 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9248 return \"ret\;restore %r1, %2, %Y0\";
9250 [(set_attr "type" "multi")
9251 (set_attr "length" "2")])
9253 (define_insn "*return_losum_si"
9254 [(set (match_operand:SI 0 "restore_operand" "")
9255 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9256 (match_operand:SI 2 "immediate_operand" "in")))
9258 "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
9261 if (! TARGET_ARCH64 && current_function_returns_struct)
9262 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9263 /* If operands are global or in registers, can use return */
9264 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9265 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9267 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9269 [(set_attr "type" "multi")
9270 (set_attr "length" "2")])
9272 (define_insn "*return_di"
9273 [(set (match_operand:DI 0 "restore_operand" "")
9274 (match_operand:DI 1 "arith_double_operand" "rHI"))
9276 "sparc_emitting_epilogue && TARGET_ARCH64"
9277 "ret\;restore %%g0, %1, %Y0"
9278 [(set_attr "type" "multi")
9279 (set_attr "length" "2")])
9281 (define_insn "*return_adddi"
9282 [(set (match_operand:DI 0 "restore_operand" "")
9283 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9284 (match_operand:DI 2 "arith_double_operand" "rHI")))
9286 "sparc_emitting_epilogue && TARGET_ARCH64"
9287 "ret\;restore %r1, %2, %Y0"
9288 [(set_attr "type" "multi")
9289 (set_attr "length" "2")])
9291 (define_insn "*return_losum_di"
9292 [(set (match_operand:DI 0 "restore_operand" "")
9293 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9294 (match_operand:DI 2 "immediate_operand" "in")))
9296 "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
9297 "ret\;restore %r1, %%lo(%a2), %Y0"
9298 [(set_attr "type" "multi")
9299 (set_attr "length" "2")])
9301 (define_insn "*return_sf"
9303 (match_operand:SF 0 "register_operand" "f"))
9305 "sparc_emitting_epilogue"
9306 "ret\;fmovs\\t%0, %%f0"
9307 [(set_attr "type" "multi")
9308 (set_attr "length" "2")])
9310 ;; Now peepholes to do a call followed by a jump.
9313 [(parallel [(set (match_operand 0 "" "")
9314 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9315 (match_operand 2 "" "")))
9316 (clobber (reg:SI 15))])
9317 (set (pc) (label_ref (match_operand 3 "" "")))]
9318 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9319 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9320 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9323 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9324 (match_operand 1 "" ""))
9325 (clobber (reg:SI 15))])
9326 (set (pc) (label_ref (match_operand 2 "" "")))]
9327 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9328 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9329 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9332 [(parallel [(set (match_operand 0 "" "")
9333 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9334 (match_operand 2 "" "")))
9335 (clobber (reg:DI 15))])
9336 (set (pc) (label_ref (match_operand 3 "" "")))]
9338 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9339 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9340 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9343 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9344 (match_operand 1 "" ""))
9345 (clobber (reg:DI 15))])
9346 (set (pc) (label_ref (match_operand 2 "" "")))]
9348 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9349 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9350 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9352 (define_insn "prefetch"
9353 [(prefetch (match_operand:DI 0 "address_operand" "p")
9354 (match_operand:DI 1 "const_int_operand" "n")
9355 (match_operand:DI 2 "const_int_operand" "n"))]
9358 static const char * const prefetch_instr[2][4] = {
9360 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9361 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9362 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9363 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9366 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9367 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9368 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9369 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9372 int read_or_write = INTVAL (operands[1]);
9373 int locality = INTVAL (operands[2]);
9375 if (read_or_write != 0 && read_or_write != 1)
9377 if (locality < 0 || locality > 3)
9379 return prefetch_instr [read_or_write][locality];
9381 [(set_attr "type" "load")])
9383 (define_expand "prologue"
9385 "flag_pic && current_function_uses_pic_offset_table"
9388 load_pic_register ();
9392 ;; We need to reload %l7 for -mflat -fpic,
9393 ;; otherwise %l7 should be preserved simply
9394 ;; by loading the function's register window
9395 (define_expand "exception_receiver"
9397 "TARGET_FLAT && flag_pic"
9400 load_pic_register ();
9405 (define_expand "builtin_setjmp_receiver"
9406 [(label_ref (match_operand 0 "" ""))]
9407 "TARGET_FLAT && flag_pic"
9410 load_pic_register ();
9415 [(trap_if (const_int 1) (const_int 5))]
9418 [(set_attr "type" "misc")])
9420 (define_expand "conditional_trap"
9421 [(trap_if (match_operator 0 "noov_compare_op"
9422 [(match_dup 2) (match_dup 3)])
9423 (match_operand:SI 1 "arith_operand" ""))]
9425 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9426 sparc_compare_op0, sparc_compare_op1);
9427 operands[3] = const0_rtx;")
9430 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9431 (match_operand:SI 1 "arith_operand" "rM"))]
9434 [(set_attr "type" "misc")])
9437 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9438 (match_operand:SI 1 "arith_operand" "rM"))]
9441 [(set_attr "type" "misc")])