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 ;; Length (in # of insns).
91 (define_attr "length" "" (const_int 1))
94 (define_attr "fptype" "single,double" (const_string "single"))
96 (define_asm_attributes
97 [(set_attr "length" "2")
98 (set_attr "type" "multi")])
100 ;; Attributes for instruction and branch scheduling
102 (define_attr "in_call_delay" "false,true"
103 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
104 (const_string "false")
105 (eq_attr "type" "load,fpload,store,fpstore")
106 (if_then_else (eq_attr "length" "1")
107 (const_string "true")
108 (const_string "false"))]
109 (if_then_else (eq_attr "length" "1")
110 (const_string "true")
111 (const_string "false"))))
113 (define_delay (eq_attr "type" "call")
114 [(eq_attr "in_call_delay" "true") (nil) (nil)])
116 (define_attr "eligible_for_sibcall_delay" "false,true"
117 (symbol_ref "eligible_for_sibcall_delay (insn)"))
119 (define_delay (eq_attr "type" "sibcall")
120 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
122 (define_attr "leaf_function" "false,true"
123 (const (symbol_ref "current_function_uses_only_leaf_regs")))
125 (define_attr "eligible_for_return_delay" "false,true"
126 (symbol_ref "eligible_for_return_delay (insn)"))
128 (define_attr "in_return_delay" "false,true"
129 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
130 (eq_attr "length" "1"))
131 (eq_attr "leaf_function" "false"))
132 (eq_attr "eligible_for_return_delay" "false"))
133 (const_string "true")
134 (const_string "false")))
136 (define_delay (and (eq_attr "type" "return")
137 (eq_attr "isa" "v9"))
138 [(eq_attr "in_return_delay" "true") (nil) (nil)])
140 ;; ??? Should implement the notion of predelay slots for floating point
141 ;; branches. This would allow us to remove the nop always inserted before
142 ;; a floating point branch.
144 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
145 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
146 ;; This is because doing so will add several pipeline stalls to the path
147 ;; that the load/store did not come from. Unfortunately, there is no way
148 ;; to prevent fill_eager_delay_slots from using load/store without completely
149 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
150 ;; because it prevents us from moving back the final store of inner loops.
152 (define_attr "in_branch_delay" "false,true"
153 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
154 (eq_attr "length" "1"))
155 (const_string "true")
156 (const_string "false")))
158 (define_attr "in_uncond_branch_delay" "false,true"
159 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
160 (eq_attr "length" "1"))
161 (const_string "true")
162 (const_string "false")))
164 (define_attr "in_annul_branch_delay" "false,true"
165 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
166 (eq_attr "length" "1"))
167 (const_string "true")
168 (const_string "false")))
170 (define_delay (eq_attr "type" "branch")
171 [(eq_attr "in_branch_delay" "true")
172 (nil) (eq_attr "in_annul_branch_delay" "true")])
174 (define_delay (eq_attr "type" "uncond_branch")
175 [(eq_attr "in_uncond_branch_delay" "true")
178 ;; Function units of the SPARC
180 ;; (define_function_unit {name} {num-units} {n-users} {test}
181 ;; {ready-delay} {issue-delay} [{conflict-list}])
184 ;; (Noted only for documentation; units that take one cycle do not need to
187 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
190 ;; ---- cypress CY7C602 scheduling:
191 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
193 (define_function_unit "memory" 1 0
194 (and (eq_attr "cpu" "cypress")
195 (eq_attr "type" "load,sload,fpload"))
198 ;; SPARC has two floating-point units: the FP ALU,
199 ;; and the FP MUL/DIV/SQRT unit.
200 ;; Instruction timings on the CY7C602 are as follows
214 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
215 ;; More insns cause the chip to stall.
217 (define_function_unit "fp_alu" 1 0
218 (and (eq_attr "cpu" "cypress")
219 (eq_attr "type" "fp,fpmove"))
222 (define_function_unit "fp_mds" 1 0
223 (and (eq_attr "cpu" "cypress")
224 (eq_attr "type" "fpmul"))
227 (define_function_unit "fp_mds" 1 0
228 (and (eq_attr "cpu" "cypress")
229 (eq_attr "type" "fpdivs,fpdivd"))
232 (define_function_unit "fp_mds" 1 0
233 (and (eq_attr "cpu" "cypress")
234 (eq_attr "type" "fpsqrts,fpsqrtd"))
237 ;; ----- The TMS390Z55 scheduling
238 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
239 ;; one ld/st, one fp.
240 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
242 (define_function_unit "memory" 1 0
243 (and (eq_attr "cpu" "supersparc")
244 (eq_attr "type" "load,sload"))
247 (define_function_unit "memory" 1 0
248 (and (eq_attr "cpu" "supersparc")
249 (eq_attr "type" "fpload"))
252 (define_function_unit "memory" 1 0
253 (and (eq_attr "cpu" "supersparc")
254 (eq_attr "type" "store,fpstore"))
257 (define_function_unit "shift" 1 0
258 (and (eq_attr "cpu" "supersparc")
259 (eq_attr "type" "shift"))
262 ;; There are only two write ports to the integer register file
263 ;; A store also uses a write port
265 (define_function_unit "iwport" 2 0
266 (and (eq_attr "cpu" "supersparc")
267 (eq_attr "type" "load,sload,store,shift,ialu"))
270 ;; Timings; throughput/latency
271 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
279 (define_function_unit "fp_alu" 1 0
280 (and (eq_attr "cpu" "supersparc")
281 (eq_attr "type" "fp,fpmove,fpcmp"))
284 (define_function_unit "fp_mds" 1 0
285 (and (eq_attr "cpu" "supersparc")
286 (eq_attr "type" "fpmul"))
289 (define_function_unit "fp_mds" 1 0
290 (and (eq_attr "cpu" "supersparc")
291 (eq_attr "type" "fpdivs"))
294 (define_function_unit "fp_mds" 1 0
295 (and (eq_attr "cpu" "supersparc")
296 (eq_attr "type" "fpdivd"))
299 (define_function_unit "fp_mds" 1 0
300 (and (eq_attr "cpu" "supersparc")
301 (eq_attr "type" "fpsqrts,fpsqrtd"))
304 (define_function_unit "fp_mds" 1 0
305 (and (eq_attr "cpu" "supersparc")
306 (eq_attr "type" "imul"))
309 ;; ----- hypersparc/sparclite86x scheduling
310 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
311 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
312 ;; II/FF case is only when loading a 32 bit hi/lo constant
313 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
314 ;; Memory delivers its result in one cycle to IU
316 (define_function_unit "memory" 1 0
317 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
318 (eq_attr "type" "load,sload,fpload"))
321 (define_function_unit "memory" 1 0
322 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
323 (eq_attr "type" "store,fpstore"))
326 (define_function_unit "sparclite86x_branch" 1 0
327 (and (eq_attr "cpu" "sparclite86x")
328 (eq_attr "type" "branch"))
331 ;; integer multiply insns
332 (define_function_unit "sparclite86x_shift" 1 0
333 (and (eq_attr "cpu" "sparclite86x")
334 (eq_attr "type" "shift"))
337 (define_function_unit "fp_alu" 1 0
338 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
339 (eq_attr "type" "fp,fpmove,fpcmp"))
342 (define_function_unit "fp_mds" 1 0
343 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
344 (eq_attr "type" "fpmul"))
347 (define_function_unit "fp_mds" 1 0
348 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
349 (eq_attr "type" "fpdivs"))
352 (define_function_unit "fp_mds" 1 0
353 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
354 (eq_attr "type" "fpdivd"))
357 (define_function_unit "fp_mds" 1 0
358 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
359 (eq_attr "type" "fpsqrts,fpsqrtd"))
362 (define_function_unit "fp_mds" 1 0
363 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
364 (eq_attr "type" "imul"))
367 ;; ----- sparclet tsc701 scheduling
368 ;; The tsc701 issues 1 insn per cycle.
369 ;; Results may be written back out of order.
371 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
373 (define_function_unit "tsc701_load" 4 1
374 (and (eq_attr "cpu" "tsc701")
375 (eq_attr "type" "load,sload"))
378 ;; Stores take 2(?) extra cycles to complete.
379 ;; It is desirable to not have any memory operation in the following 2 cycles.
380 ;; (??? or 2 memory ops in the case of std).
382 (define_function_unit "tsc701_store" 1 0
383 (and (eq_attr "cpu" "tsc701")
384 (eq_attr "type" "store"))
386 [(eq_attr "type" "load,sload,store")])
388 ;; The multiply unit has a latency of 5.
389 (define_function_unit "tsc701_mul" 1 0
390 (and (eq_attr "cpu" "tsc701")
391 (eq_attr "type" "imul"))
394 ;; ----- The UltraSPARC-1 scheduling
395 ;; UltraSPARC has two integer units. Shift instructions can only execute
396 ;; on IE0. Condition code setting instructions, call, and jmpl (including
397 ;; the ret and retl pseudo-instructions) can only execute on IE1.
398 ;; Branch on register uses IE1, but branch on condition code does not.
399 ;; Conditional moves take 2 cycles. No other instruction can issue in the
400 ;; same cycle as a conditional move.
401 ;; Multiply and divide take many cycles during which no other instructions
403 ;; Memory delivers its result in two cycles (except for signed loads,
404 ;; which take one cycle more). One memory instruction can be issued per
407 (define_function_unit "memory" 1 0
408 (and (eq_attr "cpu" "ultrasparc")
409 (eq_attr "type" "load,fpload"))
412 (define_function_unit "memory" 1 0
413 (and (eq_attr "cpu" "ultrasparc")
414 (eq_attr "type" "sload"))
417 (define_function_unit "memory" 1 0
418 (and (eq_attr "cpu" "ultrasparc")
419 (eq_attr "type" "store,fpstore"))
422 (define_function_unit "ieuN" 2 0
423 (and (eq_attr "cpu" "ultrasparc")
424 (eq_attr "type" "ialu,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
427 (define_function_unit "ieu0" 1 0
428 (and (eq_attr "cpu" "ultrasparc")
429 (eq_attr "type" "shift"))
432 (define_function_unit "ieu0" 1 0
433 (and (eq_attr "cpu" "ultrasparc")
434 (eq_attr "type" "cmove"))
437 (define_function_unit "ieu1" 1 0
438 (and (eq_attr "cpu" "ultrasparc")
439 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
442 (define_function_unit "cti" 1 0
443 (and (eq_attr "cpu" "ultrasparc")
444 (eq_attr "type" "branch"))
447 ;; Timings; throughput/latency
448 ;; FMOV 1/1 fmov, fabs, fneg
450 ;; FADD 1/3 add/sub, format conv, compar
456 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
458 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
459 ;; use the FPM multiplier for final rounding 3 cycles before the
460 ;; end of their latency and we have no real way to model that.
462 ;; ??? This is really bogus because the timings really depend upon
463 ;; who uses the result. We should record who the user is with
464 ;; more descriptive 'type' attribute names and account for these
465 ;; issues in ultrasparc_adjust_cost.
467 (define_function_unit "fadd" 1 0
468 (and (eq_attr "cpu" "ultrasparc")
469 (eq_attr "type" "fpmove"))
472 (define_function_unit "fadd" 1 0
473 (and (eq_attr "cpu" "ultrasparc")
474 (eq_attr "type" "fpcmove"))
477 (define_function_unit "fadd" 1 0
478 (and (eq_attr "cpu" "ultrasparc")
479 (eq_attr "type" "fp"))
482 (define_function_unit "fadd" 1 0
483 (and (eq_attr "cpu" "ultrasparc")
484 (eq_attr "type" "fpcmp"))
487 (define_function_unit "fmul" 1 0
488 (and (eq_attr "cpu" "ultrasparc")
489 (eq_attr "type" "fpmul"))
492 (define_function_unit "fadd" 1 0
493 (and (eq_attr "cpu" "ultrasparc")
494 (eq_attr "type" "fpcmove"))
497 (define_function_unit "fdiv" 1 0
498 (and (eq_attr "cpu" "ultrasparc")
499 (eq_attr "type" "fpdivs"))
502 (define_function_unit "fdiv" 1 0
503 (and (eq_attr "cpu" "ultrasparc")
504 (eq_attr "type" "fpdivd"))
507 (define_function_unit "fdiv" 1 0
508 (and (eq_attr "cpu" "ultrasparc")
509 (eq_attr "type" "fpsqrts"))
512 (define_function_unit "fdiv" 1 0
513 (and (eq_attr "cpu" "ultrasparc")
514 (eq_attr "type" "fpsqrtd"))
517 ;; Compare instructions.
518 ;; This controls RTL generation and register allocation.
520 ;; We generate RTL for comparisons and branches by having the cmpxx
521 ;; patterns store away the operands. Then, the scc and bcc patterns
522 ;; emit RTL for both the compare and the branch.
524 ;; We do this because we want to generate different code for an sne and
525 ;; seq insn. In those cases, if the second operand of the compare is not
526 ;; const0_rtx, we want to compute the xor of the two operands and test
529 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
530 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
531 ;; insns that actually require more than one machine instruction.
533 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
535 (define_expand "cmpsi"
537 (compare:CC (match_operand:SI 0 "register_operand" "")
538 (match_operand:SI 1 "arith_operand" "")))]
542 sparc_compare_op0 = operands[0];
543 sparc_compare_op1 = operands[1];
547 (define_expand "cmpdi"
549 (compare:CCX (match_operand:DI 0 "register_operand" "")
550 (match_operand:DI 1 "arith_double_operand" "")))]
554 sparc_compare_op0 = operands[0];
555 sparc_compare_op1 = operands[1];
559 (define_expand "cmpsf"
560 ;; The 96 here isn't ever used by anyone.
562 (compare:CCFP (match_operand:SF 0 "register_operand" "")
563 (match_operand:SF 1 "register_operand" "")))]
567 sparc_compare_op0 = operands[0];
568 sparc_compare_op1 = operands[1];
572 (define_expand "cmpdf"
573 ;; The 96 here isn't ever used by anyone.
575 (compare:CCFP (match_operand:DF 0 "register_operand" "")
576 (match_operand:DF 1 "register_operand" "")))]
580 sparc_compare_op0 = operands[0];
581 sparc_compare_op1 = operands[1];
585 (define_expand "cmptf"
586 ;; The 96 here isn't ever used by anyone.
588 (compare:CCFP (match_operand:TF 0 "register_operand" "")
589 (match_operand:TF 1 "register_operand" "")))]
593 sparc_compare_op0 = operands[0];
594 sparc_compare_op1 = operands[1];
598 ;; Now the compare DEFINE_INSNs.
600 (define_insn "*cmpsi_insn"
602 (compare:CC (match_operand:SI 0 "register_operand" "r")
603 (match_operand:SI 1 "arith_operand" "rI")))]
606 [(set_attr "type" "compare")])
608 (define_insn "*cmpdi_sp64"
610 (compare:CCX (match_operand:DI 0 "register_operand" "r")
611 (match_operand:DI 1 "arith_double_operand" "rHI")))]
614 [(set_attr "type" "compare")])
616 (define_insn "*cmpsf_fpe"
617 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
618 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
619 (match_operand:SF 2 "register_operand" "f")))]
624 return \"fcmpes\\t%0, %1, %2\";
625 return \"fcmpes\\t%1, %2\";
627 [(set_attr "type" "fpcmp")])
629 (define_insn "*cmpdf_fpe"
630 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
631 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
632 (match_operand:DF 2 "register_operand" "e")))]
637 return \"fcmped\\t%0, %1, %2\";
638 return \"fcmped\\t%1, %2\";
640 [(set_attr "type" "fpcmp")
641 (set_attr "fptype" "double")])
643 (define_insn "*cmptf_fpe"
644 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
645 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
646 (match_operand:TF 2 "register_operand" "e")))]
647 "TARGET_FPU && TARGET_HARD_QUAD"
651 return \"fcmpeq\\t%0, %1, %2\";
652 return \"fcmpeq\\t%1, %2\";
654 [(set_attr "type" "fpcmp")])
656 (define_insn "*cmpsf_fp"
657 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
658 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
659 (match_operand:SF 2 "register_operand" "f")))]
664 return \"fcmps\\t%0, %1, %2\";
665 return \"fcmps\\t%1, %2\";
667 [(set_attr "type" "fpcmp")])
669 (define_insn "*cmpdf_fp"
670 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
671 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
672 (match_operand:DF 2 "register_operand" "e")))]
677 return \"fcmpd\\t%0, %1, %2\";
678 return \"fcmpd\\t%1, %2\";
680 [(set_attr "type" "fpcmp")
681 (set_attr "fptype" "double")])
683 (define_insn "*cmptf_fp"
684 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
685 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
686 (match_operand:TF 2 "register_operand" "e")))]
687 "TARGET_FPU && TARGET_HARD_QUAD"
691 return \"fcmpq\\t%0, %1, %2\";
692 return \"fcmpq\\t%1, %2\";
694 [(set_attr "type" "fpcmp")])
696 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
697 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
698 ;; the same code as v8 (the addx/subx method has more applications). The
699 ;; exception to this is "reg != 0" which can be done in one instruction on v9
700 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
703 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
704 ;; generate addcc/subcc instructions.
706 (define_expand "seqsi_special"
708 (xor:SI (match_operand:SI 1 "register_operand" "")
709 (match_operand:SI 2 "register_operand" "")))
710 (parallel [(set (match_operand:SI 0 "register_operand" "")
711 (eq:SI (match_dup 3) (const_int 0)))
712 (clobber (reg:CC 100))])]
714 "{ operands[3] = gen_reg_rtx (SImode); }")
716 (define_expand "seqdi_special"
718 (xor:DI (match_operand:DI 1 "register_operand" "")
719 (match_operand:DI 2 "register_operand" "")))
720 (set (match_operand:DI 0 "register_operand" "")
721 (eq:DI (match_dup 3) (const_int 0)))]
723 "{ operands[3] = gen_reg_rtx (DImode); }")
725 (define_expand "snesi_special"
727 (xor:SI (match_operand:SI 1 "register_operand" "")
728 (match_operand:SI 2 "register_operand" "")))
729 (parallel [(set (match_operand:SI 0 "register_operand" "")
730 (ne:SI (match_dup 3) (const_int 0)))
731 (clobber (reg:CC 100))])]
733 "{ operands[3] = gen_reg_rtx (SImode); }")
735 (define_expand "snedi_special"
737 (xor:DI (match_operand:DI 1 "register_operand" "")
738 (match_operand:DI 2 "register_operand" "")))
739 (set (match_operand:DI 0 "register_operand" "")
740 (ne:DI (match_dup 3) (const_int 0)))]
742 "{ operands[3] = gen_reg_rtx (DImode); }")
744 (define_expand "seqdi_special_trunc"
746 (xor:DI (match_operand:DI 1 "register_operand" "")
747 (match_operand:DI 2 "register_operand" "")))
748 (set (match_operand:SI 0 "register_operand" "")
749 (eq:SI (match_dup 3) (const_int 0)))]
751 "{ operands[3] = gen_reg_rtx (DImode); }")
753 (define_expand "snedi_special_trunc"
755 (xor:DI (match_operand:DI 1 "register_operand" "")
756 (match_operand:DI 2 "register_operand" "")))
757 (set (match_operand:SI 0 "register_operand" "")
758 (ne:SI (match_dup 3) (const_int 0)))]
760 "{ operands[3] = gen_reg_rtx (DImode); }")
762 (define_expand "seqsi_special_extend"
764 (xor:SI (match_operand:SI 1 "register_operand" "")
765 (match_operand:SI 2 "register_operand" "")))
766 (parallel [(set (match_operand:DI 0 "register_operand" "")
767 (eq:DI (match_dup 3) (const_int 0)))
768 (clobber (reg:CC 100))])]
770 "{ operands[3] = gen_reg_rtx (SImode); }")
772 (define_expand "snesi_special_extend"
774 (xor:SI (match_operand:SI 1 "register_operand" "")
775 (match_operand:SI 2 "register_operand" "")))
776 (parallel [(set (match_operand:DI 0 "register_operand" "")
777 (ne:DI (match_dup 3) (const_int 0)))
778 (clobber (reg:CC 100))])]
780 "{ operands[3] = gen_reg_rtx (SImode); }")
782 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
783 ;; However, the code handles both SImode and DImode.
785 [(set (match_operand:SI 0 "intreg_operand" "")
786 (eq:SI (match_dup 1) (const_int 0)))]
790 if (GET_MODE (sparc_compare_op0) == SImode)
794 if (GET_MODE (operands[0]) == SImode)
795 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
797 else if (! TARGET_ARCH64)
800 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
805 else if (GET_MODE (sparc_compare_op0) == DImode)
811 else if (GET_MODE (operands[0]) == SImode)
812 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
815 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
820 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
822 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
823 emit_jump_insn (gen_sne (operands[0]));
828 if (gen_v9_scc (EQ, operands))
835 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
836 ;; However, the code handles both SImode and DImode.
838 [(set (match_operand:SI 0 "intreg_operand" "")
839 (ne:SI (match_dup 1) (const_int 0)))]
843 if (GET_MODE (sparc_compare_op0) == SImode)
847 if (GET_MODE (operands[0]) == SImode)
848 pat = gen_snesi_special (operands[0], sparc_compare_op0,
850 else if (! TARGET_ARCH64)
853 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
858 else if (GET_MODE (sparc_compare_op0) == DImode)
864 else if (GET_MODE (operands[0]) == SImode)
865 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
868 pat = gen_snedi_special (operands[0], sparc_compare_op0,
873 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
875 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
876 emit_jump_insn (gen_sne (operands[0]));
881 if (gen_v9_scc (NE, operands))
889 [(set (match_operand:SI 0 "intreg_operand" "")
890 (gt:SI (match_dup 1) (const_int 0)))]
894 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
896 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
897 emit_jump_insn (gen_sne (operands[0]));
902 if (gen_v9_scc (GT, operands))
910 [(set (match_operand:SI 0 "intreg_operand" "")
911 (lt:SI (match_dup 1) (const_int 0)))]
915 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
917 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
918 emit_jump_insn (gen_sne (operands[0]));
923 if (gen_v9_scc (LT, operands))
931 [(set (match_operand:SI 0 "intreg_operand" "")
932 (ge:SI (match_dup 1) (const_int 0)))]
936 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
938 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
939 emit_jump_insn (gen_sne (operands[0]));
944 if (gen_v9_scc (GE, operands))
952 [(set (match_operand:SI 0 "intreg_operand" "")
953 (le:SI (match_dup 1) (const_int 0)))]
957 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
959 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
960 emit_jump_insn (gen_sne (operands[0]));
965 if (gen_v9_scc (LE, operands))
972 (define_expand "sgtu"
973 [(set (match_operand:SI 0 "intreg_operand" "")
974 (gtu:SI (match_dup 1) (const_int 0)))]
982 /* We can do ltu easily, so if both operands are registers, swap them and
984 if ((GET_CODE (sparc_compare_op0) == REG
985 || GET_CODE (sparc_compare_op0) == SUBREG)
986 && (GET_CODE (sparc_compare_op1) == REG
987 || GET_CODE (sparc_compare_op1) == SUBREG))
989 tem = sparc_compare_op0;
990 sparc_compare_op0 = sparc_compare_op1;
991 sparc_compare_op1 = tem;
992 pat = gen_sltu (operands[0]);
1001 if (gen_v9_scc (GTU, operands))
1007 (define_expand "sltu"
1008 [(set (match_operand:SI 0 "intreg_operand" "")
1009 (ltu:SI (match_dup 1) (const_int 0)))]
1015 if (gen_v9_scc (LTU, operands))
1018 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1021 (define_expand "sgeu"
1022 [(set (match_operand:SI 0 "intreg_operand" "")
1023 (geu:SI (match_dup 1) (const_int 0)))]
1029 if (gen_v9_scc (GEU, operands))
1032 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1035 (define_expand "sleu"
1036 [(set (match_operand:SI 0 "intreg_operand" "")
1037 (leu:SI (match_dup 1) (const_int 0)))]
1045 /* We can do geu easily, so if both operands are registers, swap them and
1047 if ((GET_CODE (sparc_compare_op0) == REG
1048 || GET_CODE (sparc_compare_op0) == SUBREG)
1049 && (GET_CODE (sparc_compare_op1) == REG
1050 || GET_CODE (sparc_compare_op1) == SUBREG))
1052 tem = sparc_compare_op0;
1053 sparc_compare_op0 = sparc_compare_op1;
1054 sparc_compare_op1 = tem;
1055 pat = gen_sgeu (operands[0]);
1056 if (pat == NULL_RTX)
1064 if (gen_v9_scc (LEU, operands))
1070 ;; Now the DEFINE_INSNs for the scc cases.
1072 ;; The SEQ and SNE patterns are special because they can be done
1073 ;; without any branching and do not involve a COMPARE. We want
1074 ;; them to always use the splitz below so the results can be
1077 (define_insn "*snesi_zero"
1078 [(set (match_operand:SI 0 "register_operand" "=r")
1079 (ne:SI (match_operand:SI 1 "register_operand" "r")
1081 (clobber (reg:CC 100))]
1084 [(set_attr "length" "2")])
1087 [(set (match_operand:SI 0 "register_operand" "")
1088 (ne:SI (match_operand:SI 1 "register_operand" "")
1090 (clobber (reg:CC 100))]
1092 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1094 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1097 (define_insn "*neg_snesi_zero"
1098 [(set (match_operand:SI 0 "register_operand" "=r")
1099 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1101 (clobber (reg:CC 100))]
1104 [(set_attr "length" "2")])
1107 [(set (match_operand:SI 0 "register_operand" "")
1108 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1110 (clobber (reg:CC 100))]
1112 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1114 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1117 (define_insn "*snesi_zero_extend"
1118 [(set (match_operand:DI 0 "register_operand" "=r")
1119 (ne:DI (match_operand:SI 1 "register_operand" "r")
1121 (clobber (reg:CC 100))]
1124 [(set_attr "length" "2")])
1127 [(set (match_operand:DI 0 "register_operand" "")
1128 (ne:DI (match_operand:SI 1 "register_operand" "")
1130 (clobber (reg:CC 100))]
1132 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1134 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1136 (ltu:SI (reg:CC_NOOV 100)
1140 (define_insn "*snedi_zero"
1141 [(set (match_operand:DI 0 "register_operand" "=&r")
1142 (ne:DI (match_operand:DI 1 "register_operand" "r")
1146 [(set_attr "length" "2")])
1149 [(set (match_operand:DI 0 "register_operand" "")
1150 (ne:DI (match_operand:DI 1 "register_operand" "")
1153 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1154 [(set (match_dup 0) (const_int 0))
1155 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1161 (define_insn "*neg_snedi_zero"
1162 [(set (match_operand:DI 0 "register_operand" "=&r")
1163 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1167 [(set_attr "length" "2")])
1170 [(set (match_operand:DI 0 "register_operand" "")
1171 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1174 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1175 [(set (match_dup 0) (const_int 0))
1176 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1182 (define_insn "*snedi_zero_trunc"
1183 [(set (match_operand:SI 0 "register_operand" "=&r")
1184 (ne:SI (match_operand:DI 1 "register_operand" "r")
1188 [(set_attr "length" "2")])
1191 [(set (match_operand:SI 0 "register_operand" "")
1192 (ne:SI (match_operand:DI 1 "register_operand" "")
1195 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1196 [(set (match_dup 0) (const_int 0))
1197 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1203 (define_insn "*seqsi_zero"
1204 [(set (match_operand:SI 0 "register_operand" "=r")
1205 (eq:SI (match_operand:SI 1 "register_operand" "r")
1207 (clobber (reg:CC 100))]
1210 [(set_attr "length" "2")])
1213 [(set (match_operand:SI 0 "register_operand" "")
1214 (eq:SI (match_operand:SI 1 "register_operand" "")
1216 (clobber (reg:CC 100))]
1218 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1220 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1223 (define_insn "*neg_seqsi_zero"
1224 [(set (match_operand:SI 0 "register_operand" "=r")
1225 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1227 (clobber (reg:CC 100))]
1230 [(set_attr "length" "2")])
1233 [(set (match_operand:SI 0 "register_operand" "")
1234 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1236 (clobber (reg:CC 100))]
1238 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1240 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1243 (define_insn "*seqsi_zero_extend"
1244 [(set (match_operand:DI 0 "register_operand" "=r")
1245 (eq:DI (match_operand:SI 1 "register_operand" "r")
1247 (clobber (reg:CC 100))]
1250 [(set_attr "length" "2")])
1253 [(set (match_operand:DI 0 "register_operand" "")
1254 (eq:DI (match_operand:SI 1 "register_operand" "")
1256 (clobber (reg:CC 100))]
1258 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1260 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1262 (ltu:SI (reg:CC_NOOV 100)
1266 (define_insn "*seqdi_zero"
1267 [(set (match_operand:DI 0 "register_operand" "=&r")
1268 (eq:DI (match_operand:DI 1 "register_operand" "r")
1272 [(set_attr "length" "2")])
1275 [(set (match_operand:DI 0 "register_operand" "")
1276 (eq:DI (match_operand:DI 1 "register_operand" "")
1279 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1280 [(set (match_dup 0) (const_int 0))
1281 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1287 (define_insn "*neg_seqdi_zero"
1288 [(set (match_operand:DI 0 "register_operand" "=&r")
1289 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1293 [(set_attr "length" "2")])
1296 [(set (match_operand:DI 0 "register_operand" "")
1297 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1300 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1301 [(set (match_dup 0) (const_int 0))
1302 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1308 (define_insn "*seqdi_zero_trunc"
1309 [(set (match_operand:SI 0 "register_operand" "=&r")
1310 (eq:SI (match_operand:DI 1 "register_operand" "r")
1314 [(set_attr "length" "2")])
1317 [(set (match_operand:SI 0 "register_operand" "")
1318 (eq:SI (match_operand:DI 1 "register_operand" "")
1321 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1322 [(set (match_dup 0) (const_int 0))
1323 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1329 ;; We can also do (x + (i == 0)) and related, so put them in.
1330 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1333 (define_insn "*x_plus_i_ne_0"
1334 [(set (match_operand:SI 0 "register_operand" "=r")
1335 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1337 (match_operand:SI 2 "register_operand" "r")))
1338 (clobber (reg:CC 100))]
1341 [(set_attr "length" "2")])
1344 [(set (match_operand:SI 0 "register_operand" "")
1345 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1347 (match_operand:SI 2 "register_operand" "")))
1348 (clobber (reg:CC 100))]
1350 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1352 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1356 (define_insn "*x_minus_i_ne_0"
1357 [(set (match_operand:SI 0 "register_operand" "=r")
1358 (minus:SI (match_operand:SI 2 "register_operand" "r")
1359 (ne:SI (match_operand:SI 1 "register_operand" "r")
1361 (clobber (reg:CC 100))]
1364 [(set_attr "length" "2")])
1367 [(set (match_operand:SI 0 "register_operand" "")
1368 (minus:SI (match_operand:SI 2 "register_operand" "")
1369 (ne:SI (match_operand:SI 1 "register_operand" "")
1371 (clobber (reg:CC 100))]
1373 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1375 (set (match_dup 0) (minus:SI (match_dup 2)
1376 (ltu:SI (reg:CC 100) (const_int 0))))]
1379 (define_insn "*x_plus_i_eq_0"
1380 [(set (match_operand:SI 0 "register_operand" "=r")
1381 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1383 (match_operand:SI 2 "register_operand" "r")))
1384 (clobber (reg:CC 100))]
1387 [(set_attr "length" "2")])
1390 [(set (match_operand:SI 0 "register_operand" "")
1391 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1393 (match_operand:SI 2 "register_operand" "")))
1394 (clobber (reg:CC 100))]
1396 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1398 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1402 (define_insn "*x_minus_i_eq_0"
1403 [(set (match_operand:SI 0 "register_operand" "=r")
1404 (minus:SI (match_operand:SI 2 "register_operand" "r")
1405 (eq:SI (match_operand:SI 1 "register_operand" "r")
1407 (clobber (reg:CC 100))]
1410 [(set_attr "length" "2")])
1413 [(set (match_operand:SI 0 "register_operand" "")
1414 (minus:SI (match_operand:SI 2 "register_operand" "")
1415 (eq:SI (match_operand:SI 1 "register_operand" "")
1417 (clobber (reg:CC 100))]
1419 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1421 (set (match_dup 0) (minus:SI (match_dup 2)
1422 (geu:SI (reg:CC 100) (const_int 0))))]
1425 ;; We can also do GEU and LTU directly, but these operate after a compare.
1426 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1429 (define_insn "*sltu_insn"
1430 [(set (match_operand:SI 0 "register_operand" "=r")
1431 (ltu:SI (reg:CC 100) (const_int 0)))]
1433 "addx\\t%%g0, 0, %0"
1434 [(set_attr "type" "misc")])
1436 (define_insn "*neg_sltu_insn"
1437 [(set (match_operand:SI 0 "register_operand" "=r")
1438 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1440 "subx\\t%%g0, 0, %0"
1441 [(set_attr "type" "misc")])
1443 ;; ??? Combine should canonicalize these next two to the same pattern.
1444 (define_insn "*neg_sltu_minus_x"
1445 [(set (match_operand:SI 0 "register_operand" "=r")
1446 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1447 (match_operand:SI 1 "arith_operand" "rI")))]
1449 "subx\\t%%g0, %1, %0"
1450 [(set_attr "type" "misc")])
1452 (define_insn "*neg_sltu_plus_x"
1453 [(set (match_operand:SI 0 "register_operand" "=r")
1454 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1455 (match_operand:SI 1 "arith_operand" "rI"))))]
1457 "subx\\t%%g0, %1, %0"
1458 [(set_attr "type" "misc")])
1460 (define_insn "*sgeu_insn"
1461 [(set (match_operand:SI 0 "register_operand" "=r")
1462 (geu:SI (reg:CC 100) (const_int 0)))]
1464 "subx\\t%%g0, -1, %0"
1465 [(set_attr "type" "misc")])
1467 (define_insn "*neg_sgeu_insn"
1468 [(set (match_operand:SI 0 "register_operand" "=r")
1469 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1471 "addx\\t%%g0, -1, %0"
1472 [(set_attr "type" "misc")])
1474 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1475 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1478 (define_insn "*sltu_plus_x"
1479 [(set (match_operand:SI 0 "register_operand" "=r")
1480 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1481 (match_operand:SI 1 "arith_operand" "rI")))]
1483 "addx\\t%%g0, %1, %0"
1484 [(set_attr "type" "misc")])
1486 (define_insn "*sltu_plus_x_plus_y"
1487 [(set (match_operand:SI 0 "register_operand" "=r")
1488 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1489 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1490 (match_operand:SI 2 "arith_operand" "rI"))))]
1493 [(set_attr "type" "misc")])
1495 (define_insn "*x_minus_sltu"
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (minus:SI (match_operand:SI 1 "register_operand" "r")
1498 (ltu:SI (reg:CC 100) (const_int 0))))]
1501 [(set_attr "type" "misc")])
1503 ;; ??? Combine should canonicalize these next two to the same pattern.
1504 (define_insn "*x_minus_y_minus_sltu"
1505 [(set (match_operand:SI 0 "register_operand" "=r")
1506 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1507 (match_operand:SI 2 "arith_operand" "rI"))
1508 (ltu:SI (reg:CC 100) (const_int 0))))]
1510 "subx\\t%r1, %2, %0"
1511 [(set_attr "type" "misc")])
1513 (define_insn "*x_minus_sltu_plus_y"
1514 [(set (match_operand:SI 0 "register_operand" "=r")
1515 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1516 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1517 (match_operand:SI 2 "arith_operand" "rI"))))]
1519 "subx\\t%r1, %2, %0"
1520 [(set_attr "type" "misc")])
1522 (define_insn "*sgeu_plus_x"
1523 [(set (match_operand:SI 0 "register_operand" "=r")
1524 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1525 (match_operand:SI 1 "register_operand" "r")))]
1528 [(set_attr "type" "misc")])
1530 (define_insn "*x_minus_sgeu"
1531 [(set (match_operand:SI 0 "register_operand" "=r")
1532 (minus:SI (match_operand:SI 1 "register_operand" "r")
1533 (geu:SI (reg:CC 100) (const_int 0))))]
1536 [(set_attr "type" "misc")])
1539 [(set (match_operand:SI 0 "register_operand" "")
1540 (match_operator:SI 2 "noov_compare_op"
1541 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1543 ;; 32 bit LTU/GEU are better implemented using addx/subx
1544 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1545 && (GET_MODE (operands[1]) == CCXmode
1546 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1547 [(set (match_dup 0) (const_int 0))
1549 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1555 ;; These control RTL generation for conditional jump insns
1557 ;; The quad-word fp compare library routines all return nonzero to indicate
1558 ;; true, which is different from the equivalent libgcc routines, so we must
1559 ;; handle them specially here.
1561 (define_expand "beq"
1563 (if_then_else (eq (match_dup 1) (const_int 0))
1564 (label_ref (match_operand 0 "" ""))
1569 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1570 && GET_CODE (sparc_compare_op0) == REG
1571 && GET_MODE (sparc_compare_op0) == DImode)
1573 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1576 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1578 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1579 emit_jump_insn (gen_bne (operands[0]));
1582 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1585 (define_expand "bne"
1587 (if_then_else (ne (match_dup 1) (const_int 0))
1588 (label_ref (match_operand 0 "" ""))
1593 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1594 && GET_CODE (sparc_compare_op0) == REG
1595 && GET_MODE (sparc_compare_op0) == DImode)
1597 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1600 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1602 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1603 emit_jump_insn (gen_bne (operands[0]));
1606 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1609 (define_expand "bgt"
1611 (if_then_else (gt (match_dup 1) (const_int 0))
1612 (label_ref (match_operand 0 "" ""))
1617 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1618 && GET_CODE (sparc_compare_op0) == REG
1619 && GET_MODE (sparc_compare_op0) == DImode)
1621 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1624 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1626 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1627 emit_jump_insn (gen_bne (operands[0]));
1630 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1633 (define_expand "bgtu"
1635 (if_then_else (gtu (match_dup 1) (const_int 0))
1636 (label_ref (match_operand 0 "" ""))
1640 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1643 (define_expand "blt"
1645 (if_then_else (lt (match_dup 1) (const_int 0))
1646 (label_ref (match_operand 0 "" ""))
1651 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1652 && GET_CODE (sparc_compare_op0) == REG
1653 && GET_MODE (sparc_compare_op0) == DImode)
1655 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1658 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1660 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1661 emit_jump_insn (gen_bne (operands[0]));
1664 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1667 (define_expand "bltu"
1669 (if_then_else (ltu (match_dup 1) (const_int 0))
1670 (label_ref (match_operand 0 "" ""))
1674 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1677 (define_expand "bge"
1679 (if_then_else (ge (match_dup 1) (const_int 0))
1680 (label_ref (match_operand 0 "" ""))
1685 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1686 && GET_CODE (sparc_compare_op0) == REG
1687 && GET_MODE (sparc_compare_op0) == DImode)
1689 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1692 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1694 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1695 emit_jump_insn (gen_bne (operands[0]));
1698 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1701 (define_expand "bgeu"
1703 (if_then_else (geu (match_dup 1) (const_int 0))
1704 (label_ref (match_operand 0 "" ""))
1708 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1711 (define_expand "ble"
1713 (if_then_else (le (match_dup 1) (const_int 0))
1714 (label_ref (match_operand 0 "" ""))
1719 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1720 && GET_CODE (sparc_compare_op0) == REG
1721 && GET_MODE (sparc_compare_op0) == DImode)
1723 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1726 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1728 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1729 emit_jump_insn (gen_bne (operands[0]));
1732 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1735 (define_expand "bleu"
1737 (if_then_else (leu (match_dup 1) (const_int 0))
1738 (label_ref (match_operand 0 "" ""))
1742 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1745 (define_expand "bunordered"
1747 (if_then_else (unordered (match_dup 1) (const_int 0))
1748 (label_ref (match_operand 0 "" ""))
1753 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1755 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1757 emit_jump_insn (gen_beq (operands[0]));
1760 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1764 (define_expand "bordered"
1766 (if_then_else (ordered (match_dup 1) (const_int 0))
1767 (label_ref (match_operand 0 "" ""))
1772 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1774 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1775 emit_jump_insn (gen_bne (operands[0]));
1778 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1782 (define_expand "bungt"
1784 (if_then_else (ungt (match_dup 1) (const_int 0))
1785 (label_ref (match_operand 0 "" ""))
1790 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1792 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1793 emit_jump_insn (gen_bgt (operands[0]));
1796 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1799 (define_expand "bunlt"
1801 (if_then_else (unlt (match_dup 1) (const_int 0))
1802 (label_ref (match_operand 0 "" ""))
1807 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1809 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1810 emit_jump_insn (gen_bne (operands[0]));
1813 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1816 (define_expand "buneq"
1818 (if_then_else (uneq (match_dup 1) (const_int 0))
1819 (label_ref (match_operand 0 "" ""))
1824 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1826 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1827 emit_jump_insn (gen_beq (operands[0]));
1830 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1833 (define_expand "bunge"
1835 (if_then_else (unge (match_dup 1) (const_int 0))
1836 (label_ref (match_operand 0 "" ""))
1841 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1843 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1844 emit_jump_insn (gen_bne (operands[0]));
1847 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1850 (define_expand "bunle"
1852 (if_then_else (unle (match_dup 1) (const_int 0))
1853 (label_ref (match_operand 0 "" ""))
1858 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1860 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1861 emit_jump_insn (gen_bne (operands[0]));
1864 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1867 (define_expand "bltgt"
1869 (if_then_else (ltgt (match_dup 1) (const_int 0))
1870 (label_ref (match_operand 0 "" ""))
1875 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1877 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1878 emit_jump_insn (gen_bne (operands[0]));
1881 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1884 ;; Now match both normal and inverted jump.
1886 ;; XXX fpcmp nop braindamage
1887 (define_insn "*normal_branch"
1889 (if_then_else (match_operator 0 "noov_compare_op"
1890 [(reg 100) (const_int 0)])
1891 (label_ref (match_operand 1 "" ""))
1896 return output_cbranch (operands[0], operands[1], 1, 0,
1897 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1898 ! final_sequence, insn);
1900 [(set_attr "type" "branch")
1901 (set (attr "length")
1902 (if_then_else (match_operand 0 "noov_compare64_op" "")
1903 (if_then_else (lt (pc) (match_dup 1))
1904 (if_then_else (lt (minus (match_dup 1) (pc))
1908 (if_then_else (lt (minus (pc) (match_dup 1))
1914 ;; XXX fpcmp nop braindamage
1915 (define_insn "*inverted_branch"
1917 (if_then_else (match_operator 0 "noov_compare_op"
1918 [(reg 100) (const_int 0)])
1920 (label_ref (match_operand 1 "" ""))))]
1924 return output_cbranch (operands[0], operands[1], 1, 1,
1925 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1926 ! final_sequence, insn);
1928 [(set_attr "type" "branch")
1929 (set (attr "length")
1930 (if_then_else (match_operand 0 "noov_compare64_op" "")
1931 (if_then_else (lt (pc) (match_dup 1))
1932 (if_then_else (lt (minus (match_dup 1) (pc))
1936 (if_then_else (lt (minus (pc) (match_dup 1))
1942 ;; XXX fpcmp nop braindamage
1943 (define_insn "*normal_fp_branch"
1945 (if_then_else (match_operator 1 "comparison_operator"
1946 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1948 (label_ref (match_operand 2 "" ""))
1953 return output_cbranch (operands[1], operands[2], 2, 0,
1954 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1955 ! final_sequence, insn);
1957 [(set_attr "type" "branch")
1958 (set (attr "length")
1959 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
1961 (if_then_else (lt (pc) (match_dup 2))
1962 (if_then_else (lt (minus (match_dup 2) (pc))
1966 (if_then_else (lt (minus (pc) (match_dup 2))
1971 ;; XXX fpcmp nop braindamage
1972 (define_insn "*inverted_fp_branch"
1974 (if_then_else (match_operator 1 "comparison_operator"
1975 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1978 (label_ref (match_operand 2 "" ""))))]
1982 return output_cbranch (operands[1], operands[2], 2, 1,
1983 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1984 ! final_sequence, insn);
1986 [(set_attr "type" "branch")
1987 (set (attr "length")
1988 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
1990 (if_then_else (lt (pc) (match_dup 2))
1991 (if_then_else (lt (minus (match_dup 2) (pc))
1995 (if_then_else (lt (minus (pc) (match_dup 2))
2000 ;; XXX fpcmp nop braindamage
2001 (define_insn "*normal_fpe_branch"
2003 (if_then_else (match_operator 1 "comparison_operator"
2004 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2006 (label_ref (match_operand 2 "" ""))
2011 return output_cbranch (operands[1], operands[2], 2, 0,
2012 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2013 ! final_sequence, insn);
2015 [(set_attr "type" "branch")
2016 (set (attr "length")
2017 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
2019 (if_then_else (lt (pc) (match_dup 2))
2020 (if_then_else (lt (minus (match_dup 2) (pc))
2024 (if_then_else (lt (minus (pc) (match_dup 2))
2029 ;; XXX fpcmp nop braindamage
2030 (define_insn "*inverted_fpe_branch"
2032 (if_then_else (match_operator 1 "comparison_operator"
2033 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2036 (label_ref (match_operand 2 "" ""))))]
2040 return output_cbranch (operands[1], operands[2], 2, 1,
2041 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2042 ! final_sequence, insn);
2044 [(set_attr "type" "branch")
2045 (set (attr "length")
2046 (if_then_else (match_operand 0 "fcc0_reg_operand" "")
2048 (if_then_else (lt (pc) (match_dup 2))
2049 (if_then_else (lt (minus (match_dup 2) (pc))
2053 (if_then_else (lt (minus (pc) (match_dup 2))
2058 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2059 ;; in the architecture.
2061 ;; There are no 32 bit brreg insns.
2064 (define_insn "*normal_int_branch_sp64"
2066 (if_then_else (match_operator 0 "v9_regcmp_op"
2067 [(match_operand:DI 1 "register_operand" "r")
2069 (label_ref (match_operand 2 "" ""))
2074 return output_v9branch (operands[0], operands[2], 1, 2, 0,
2075 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2076 ! final_sequence, insn);
2078 [(set_attr "type" "branch")
2079 (set (attr "length")
2080 (if_then_else (lt (pc) (match_dup 2))
2081 (if_then_else (lt (minus (match_dup 2) (pc))
2085 (if_then_else (lt (minus (pc) (match_dup 2))
2091 (define_insn "*inverted_int_branch_sp64"
2093 (if_then_else (match_operator 0 "v9_regcmp_op"
2094 [(match_operand:DI 1 "register_operand" "r")
2097 (label_ref (match_operand 2 "" ""))))]
2101 return output_v9branch (operands[0], operands[2], 1, 2, 1,
2102 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2103 ! final_sequence, insn);
2105 [(set_attr "type" "branch")
2106 (set (attr "length")
2107 (if_then_else (lt (pc) (match_dup 2))
2108 (if_then_else (lt (minus (match_dup 2) (pc))
2112 (if_then_else (lt (minus (pc) (match_dup 2))
2117 ;; Load program counter insns.
2119 (define_insn "get_pc"
2120 [(clobber (reg:SI 15))
2121 (set (match_operand 0 "register_operand" "=r")
2122 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2123 "flag_pic && REGNO (operands[0]) == 23"
2124 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2125 [(set_attr "type" "multi")
2126 (set_attr "length" "3")])
2128 ;; Currently unused...
2129 ;; (define_insn "get_pc_via_rdpc"
2130 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2133 ;; [(set_attr "type" "misc")])
2136 ;; Move instructions
2138 (define_expand "movqi"
2139 [(set (match_operand:QI 0 "general_operand" "")
2140 (match_operand:QI 1 "general_operand" ""))]
2144 /* Working with CONST_INTs is easier, so convert
2145 a double if needed. */
2146 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2148 operands[1] = GEN_INT (trunc_int_for_mode
2149 (CONST_DOUBLE_LOW (operands[1]), QImode));
2152 /* Handle sets of MEM first. */
2153 if (GET_CODE (operands[0]) == MEM)
2155 if (reg_or_0_operand (operands[1], QImode))
2158 if (! reload_in_progress)
2160 operands[0] = validize_mem (operands[0]);
2161 operands[1] = force_reg (QImode, operands[1]);
2165 /* Fixup PIC cases. */
2168 if (CONSTANT_P (operands[1])
2169 && pic_address_needs_scratch (operands[1]))
2170 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2172 if (symbolic_operand (operands[1], QImode))
2174 operands[1] = legitimize_pic_address (operands[1],
2176 (reload_in_progress ?
2183 /* All QI constants require only one insn, so proceed. */
2189 (define_insn "*movqi_insn"
2190 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2191 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2192 "(register_operand (operands[0], QImode)
2193 || reg_or_0_operand (operands[1], QImode))"
2198 [(set_attr "type" "*,load,store")])
2200 (define_expand "movhi"
2201 [(set (match_operand:HI 0 "general_operand" "")
2202 (match_operand:HI 1 "general_operand" ""))]
2206 /* Working with CONST_INTs is easier, so convert
2207 a double if needed. */
2208 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2209 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2211 /* Handle sets of MEM first. */
2212 if (GET_CODE (operands[0]) == MEM)
2214 if (reg_or_0_operand (operands[1], HImode))
2217 if (! reload_in_progress)
2219 operands[0] = validize_mem (operands[0]);
2220 operands[1] = force_reg (HImode, operands[1]);
2224 /* Fixup PIC cases. */
2227 if (CONSTANT_P (operands[1])
2228 && pic_address_needs_scratch (operands[1]))
2229 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2231 if (symbolic_operand (operands[1], HImode))
2233 operands[1] = legitimize_pic_address (operands[1],
2235 (reload_in_progress ?
2242 /* This makes sure we will not get rematched due to splittage. */
2243 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2245 else if (CONSTANT_P (operands[1])
2246 && GET_CODE (operands[1]) != HIGH
2247 && GET_CODE (operands[1]) != LO_SUM)
2249 sparc_emit_set_const32 (operands[0], operands[1]);
2256 (define_insn "*movhi_const64_special"
2257 [(set (match_operand:HI 0 "register_operand" "=r")
2258 (match_operand:HI 1 "const64_high_operand" ""))]
2260 "sethi\\t%%hi(%a1), %0")
2262 (define_insn "*movhi_insn"
2263 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2264 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2265 "(register_operand (operands[0], HImode)
2266 || reg_or_0_operand (operands[1], HImode))"
2269 sethi\\t%%hi(%a1), %0
2272 [(set_attr "type" "*,*,load,store")])
2274 ;; We always work with constants here.
2275 (define_insn "*movhi_lo_sum"
2276 [(set (match_operand:HI 0 "register_operand" "=r")
2277 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2278 (match_operand:HI 2 "arith_operand" "I")))]
2282 (define_expand "movsi"
2283 [(set (match_operand:SI 0 "general_operand" "")
2284 (match_operand:SI 1 "general_operand" ""))]
2288 /* Working with CONST_INTs is easier, so convert
2289 a double if needed. */
2290 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2291 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2293 /* Handle sets of MEM first. */
2294 if (GET_CODE (operands[0]) == MEM)
2296 if (reg_or_0_operand (operands[1], SImode))
2299 if (! reload_in_progress)
2301 operands[0] = validize_mem (operands[0]);
2302 operands[1] = force_reg (SImode, operands[1]);
2306 /* Fixup PIC cases. */
2309 if (CONSTANT_P (operands[1])
2310 && pic_address_needs_scratch (operands[1]))
2311 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2313 if (GET_CODE (operands[1]) == LABEL_REF)
2316 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2320 if (symbolic_operand (operands[1], SImode))
2322 operands[1] = legitimize_pic_address (operands[1],
2324 (reload_in_progress ?
2331 /* If we are trying to toss an integer constant into the
2332 FPU registers, force it into memory. */
2333 if (GET_CODE (operands[0]) == REG
2334 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2335 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2336 && CONSTANT_P (operands[1]))
2337 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2340 /* This makes sure we will not get rematched due to splittage. */
2341 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2343 else if (CONSTANT_P (operands[1])
2344 && GET_CODE (operands[1]) != HIGH
2345 && GET_CODE (operands[1]) != LO_SUM)
2347 sparc_emit_set_const32 (operands[0], operands[1]);
2354 ;; This is needed to show CSE exactly which bits are set
2355 ;; in a 64-bit register by sethi instructions.
2356 (define_insn "*movsi_const64_special"
2357 [(set (match_operand:SI 0 "register_operand" "=r")
2358 (match_operand:SI 1 "const64_high_operand" ""))]
2360 "sethi\\t%%hi(%a1), %0")
2362 (define_insn "*movsi_insn"
2363 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2364 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2365 "(register_operand (operands[0], SImode)
2366 || reg_or_0_operand (operands[1], SImode))"
2370 sethi\\t%%hi(%a1), %0
2377 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2379 (define_insn "*movsi_lo_sum"
2380 [(set (match_operand:SI 0 "register_operand" "=r")
2381 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2382 (match_operand:SI 2 "immediate_operand" "in")))]
2384 "or\\t%1, %%lo(%a2), %0")
2386 (define_insn "*movsi_high"
2387 [(set (match_operand:SI 0 "register_operand" "=r")
2388 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2390 "sethi\\t%%hi(%a1), %0")
2392 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2393 ;; so that CSE won't optimize the address computation away.
2394 (define_insn "movsi_lo_sum_pic"
2395 [(set (match_operand:SI 0 "register_operand" "=r")
2396 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2397 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2399 "or\\t%1, %%lo(%a2), %0")
2401 (define_insn "movsi_high_pic"
2402 [(set (match_operand:SI 0 "register_operand" "=r")
2403 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2404 "flag_pic && check_pic (1)"
2405 "sethi\\t%%hi(%a1), %0")
2407 (define_expand "movsi_pic_label_ref"
2408 [(set (match_dup 3) (high:SI
2409 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2411 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2412 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2413 (set (match_operand:SI 0 "register_operand" "=r")
2414 (minus:SI (match_dup 5) (match_dup 4)))]
2418 current_function_uses_pic_offset_table = 1;
2419 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2422 operands[3] = operands[0];
2423 operands[4] = operands[0];
2427 operands[3] = gen_reg_rtx (SImode);
2428 operands[4] = gen_reg_rtx (SImode);
2430 operands[5] = pic_offset_table_rtx;
2433 (define_insn "*movsi_high_pic_label_ref"
2434 [(set (match_operand:SI 0 "register_operand" "=r")
2436 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2437 (match_operand:SI 2 "" "")] 5)))]
2439 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2441 (define_insn "*movsi_lo_sum_pic_label_ref"
2442 [(set (match_operand:SI 0 "register_operand" "=r")
2443 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2444 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2445 (match_operand:SI 3 "" "")] 5)))]
2447 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2449 (define_expand "movdi"
2450 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2451 (match_operand:DI 1 "general_operand" ""))]
2455 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2456 if (GET_CODE (operands[1]) == CONST_DOUBLE
2457 #if HOST_BITS_PER_WIDE_INT == 32
2458 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2459 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2460 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2461 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2464 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2466 /* Handle MEM cases first. */
2467 if (GET_CODE (operands[0]) == MEM)
2469 /* If it's a REG, we can always do it.
2470 The const zero case is more complex, on v9
2471 we can always perform it. */
2472 if (register_operand (operands[1], DImode)
2474 && (operands[1] == const0_rtx)))
2477 if (! reload_in_progress)
2479 operands[0] = validize_mem (operands[0]);
2480 operands[1] = force_reg (DImode, operands[1]);
2486 if (CONSTANT_P (operands[1])
2487 && pic_address_needs_scratch (operands[1]))
2488 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2490 if (GET_CODE (operands[1]) == LABEL_REF)
2492 if (! TARGET_ARCH64)
2494 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2498 if (symbolic_operand (operands[1], DImode))
2500 operands[1] = legitimize_pic_address (operands[1],
2502 (reload_in_progress ?
2509 /* If we are trying to toss an integer constant into the
2510 FPU registers, force it into memory. */
2511 if (GET_CODE (operands[0]) == REG
2512 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2513 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2514 && CONSTANT_P (operands[1]))
2515 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2518 /* This makes sure we will not get rematched due to splittage. */
2519 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2521 else if (TARGET_ARCH64
2522 && CONSTANT_P (operands[1])
2523 && GET_CODE (operands[1]) != HIGH
2524 && GET_CODE (operands[1]) != LO_SUM)
2526 sparc_emit_set_const64 (operands[0], operands[1]);
2534 ;; Be careful, fmovd does not exist when !arch64.
2535 ;; We match MEM moves directly when we have correct even
2536 ;; numbered registers, but fall into splits otherwise.
2537 ;; The constraint ordering here is really important to
2538 ;; avoid insane problems in reload, especially for patterns
2541 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2542 ;; (const_int -5016)))
2546 (define_insn "*movdi_insn_sp32_v9"
2547 [(set (match_operand:DI 0 "nonimmediate_operand"
2548 "=m,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2549 (match_operand:DI 1 "input_operand"
2550 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2551 "! TARGET_ARCH64 && TARGET_V9
2552 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2566 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2567 (set_attr "length" "*,*,*,2,2,2,2,*,*,2,2,2")])
2569 (define_insn "*movdi_insn_sp32"
2570 [(set (match_operand:DI 0 "nonimmediate_operand"
2571 "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2572 (match_operand:DI 1 "input_operand"
2573 " U,T,r,o,i,r, f, T, o, f, f"))]
2575 && (register_operand (operands[0], DImode)
2576 || register_operand (operands[1], DImode))"
2589 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2590 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2592 ;; The following are generated by sparc_emit_set_const64
2593 (define_insn "*movdi_sp64_dbl"
2594 [(set (match_operand:DI 0 "register_operand" "=r")
2595 (match_operand:DI 1 "const64_operand" ""))]
2597 && HOST_BITS_PER_WIDE_INT != 64)"
2600 ;; This is needed to show CSE exactly which bits are set
2601 ;; in a 64-bit register by sethi instructions.
2602 (define_insn "*movdi_const64_special"
2603 [(set (match_operand:DI 0 "register_operand" "=r")
2604 (match_operand:DI 1 "const64_high_operand" ""))]
2606 "sethi\\t%%hi(%a1), %0")
2608 (define_insn "*movdi_insn_sp64_novis"
2609 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2610 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e"))]
2611 "TARGET_ARCH64 && ! TARGET_VIS
2612 && (register_operand (operands[0], DImode)
2613 || reg_or_0_operand (operands[1], DImode))"
2616 sethi\\t%%hi(%a1), %0
2623 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2624 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2626 (define_insn "*movdi_insn_sp64_vis"
2627 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2628 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e,J"))]
2629 "TARGET_ARCH64 && TARGET_VIS &&
2630 (register_operand (operands[0], DImode)
2631 || reg_or_0_operand (operands[1], DImode))"
2634 sethi\\t%%hi(%a1), %0
2642 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2643 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2645 (define_expand "movdi_pic_label_ref"
2646 [(set (match_dup 3) (high:DI
2647 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2649 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2650 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2651 (set (match_operand:DI 0 "register_operand" "=r")
2652 (minus:DI (match_dup 5) (match_dup 4)))]
2653 "TARGET_ARCH64 && flag_pic"
2656 current_function_uses_pic_offset_table = 1;
2657 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2660 operands[3] = operands[0];
2661 operands[4] = operands[0];
2665 operands[3] = gen_reg_rtx (DImode);
2666 operands[4] = gen_reg_rtx (DImode);
2668 operands[5] = pic_offset_table_rtx;
2671 (define_insn "*movdi_high_pic_label_ref"
2672 [(set (match_operand:DI 0 "register_operand" "=r")
2674 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2675 (match_operand:DI 2 "" "")] 5)))]
2676 "TARGET_ARCH64 && flag_pic"
2677 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2679 (define_insn "*movdi_lo_sum_pic_label_ref"
2680 [(set (match_operand:DI 0 "register_operand" "=r")
2681 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2682 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2683 (match_operand:DI 3 "" "")] 5)))]
2684 "TARGET_ARCH64 && flag_pic"
2685 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2687 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2688 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2690 (define_insn "movdi_lo_sum_pic"
2691 [(set (match_operand:DI 0 "register_operand" "=r")
2692 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2693 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2694 "TARGET_ARCH64 && flag_pic"
2695 "or\\t%1, %%lo(%a2), %0")
2697 (define_insn "movdi_high_pic"
2698 [(set (match_operand:DI 0 "register_operand" "=r")
2699 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2700 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2701 "sethi\\t%%hi(%a1), %0")
2703 (define_insn "*sethi_di_medlow_embmedany_pic"
2704 [(set (match_operand:DI 0 "register_operand" "=r")
2705 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2706 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2707 "sethi\\t%%hi(%a1), %0")
2709 (define_insn "*sethi_di_medlow"
2710 [(set (match_operand:DI 0 "register_operand" "=r")
2711 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2712 "TARGET_CM_MEDLOW && check_pic (1)"
2713 "sethi\\t%%hi(%a1), %0")
2715 (define_insn "*losum_di_medlow"
2716 [(set (match_operand:DI 0 "register_operand" "=r")
2717 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2718 (match_operand:DI 2 "symbolic_operand" "")))]
2720 "or\\t%1, %%lo(%a2), %0")
2722 (define_insn "seth44"
2723 [(set (match_operand:DI 0 "register_operand" "=r")
2724 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2726 "sethi\\t%%h44(%a1), %0")
2728 (define_insn "setm44"
2729 [(set (match_operand:DI 0 "register_operand" "=r")
2730 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2731 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2733 "or\\t%1, %%m44(%a2), %0")
2735 (define_insn "setl44"
2736 [(set (match_operand:DI 0 "register_operand" "=r")
2737 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2738 (match_operand:DI 2 "symbolic_operand" "")))]
2740 "or\\t%1, %%l44(%a2), %0")
2742 (define_insn "sethh"
2743 [(set (match_operand:DI 0 "register_operand" "=r")
2744 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2746 "sethi\\t%%hh(%a1), %0")
2748 (define_insn "setlm"
2749 [(set (match_operand:DI 0 "register_operand" "=r")
2750 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2752 "sethi\\t%%lm(%a1), %0")
2754 (define_insn "sethm"
2755 [(set (match_operand:DI 0 "register_operand" "=r")
2756 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2757 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2759 "or\\t%1, %%hm(%a2), %0")
2761 (define_insn "setlo"
2762 [(set (match_operand:DI 0 "register_operand" "=r")
2763 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2764 (match_operand:DI 2 "symbolic_operand" "")))]
2766 "or\\t%1, %%lo(%a2), %0")
2768 (define_insn "embmedany_sethi"
2769 [(set (match_operand:DI 0 "register_operand" "=r")
2770 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2771 "TARGET_CM_EMBMEDANY && check_pic (1)"
2772 "sethi\\t%%hi(%a1), %0")
2774 (define_insn "embmedany_losum"
2775 [(set (match_operand:DI 0 "register_operand" "=r")
2776 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2777 (match_operand:DI 2 "data_segment_operand" "")))]
2778 "TARGET_CM_EMBMEDANY"
2779 "add\\t%1, %%lo(%a2), %0")
2781 (define_insn "embmedany_brsum"
2782 [(set (match_operand:DI 0 "register_operand" "=r")
2783 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2784 "TARGET_CM_EMBMEDANY"
2787 (define_insn "embmedany_textuhi"
2788 [(set (match_operand:DI 0 "register_operand" "=r")
2789 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2790 "TARGET_CM_EMBMEDANY && check_pic (1)"
2791 "sethi\\t%%uhi(%a1), %0")
2793 (define_insn "embmedany_texthi"
2794 [(set (match_operand:DI 0 "register_operand" "=r")
2795 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2796 "TARGET_CM_EMBMEDANY && check_pic (1)"
2797 "sethi\\t%%hi(%a1), %0")
2799 (define_insn "embmedany_textulo"
2800 [(set (match_operand:DI 0 "register_operand" "=r")
2801 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2802 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2803 "TARGET_CM_EMBMEDANY"
2804 "or\\t%1, %%ulo(%a2), %0")
2806 (define_insn "embmedany_textlo"
2807 [(set (match_operand:DI 0 "register_operand" "=r")
2808 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2809 (match_operand:DI 2 "text_segment_operand" "")))]
2810 "TARGET_CM_EMBMEDANY"
2811 "or\\t%1, %%lo(%a2), %0")
2813 ;; Now some patterns to help reload out a bit.
2814 (define_expand "reload_indi"
2815 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2816 (match_operand:DI 1 "immediate_operand" "")
2817 (match_operand:TI 2 "register_operand" "=&r")])]
2819 || TARGET_CM_EMBMEDANY)
2823 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2827 (define_expand "reload_outdi"
2828 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2829 (match_operand:DI 1 "immediate_operand" "")
2830 (match_operand:TI 2 "register_operand" "=&r")])]
2832 || TARGET_CM_EMBMEDANY)
2836 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2840 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2842 [(set (match_operand:DI 0 "register_operand" "")
2843 (match_operand:DI 1 "const_int_operand" ""))]
2844 "! TARGET_ARCH64 && reload_completed"
2845 [(clobber (const_int 0))]
2848 #if HOST_BITS_PER_WIDE_INT == 32
2849 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2850 (INTVAL (operands[1]) < 0) ?
2853 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2856 unsigned int low, high;
2858 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2859 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2860 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2862 /* Slick... but this trick loses if this subreg constant part
2863 can be done in one insn. */
2864 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2865 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2866 gen_highpart (SImode, operands[0])));
2868 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2874 [(set (match_operand:DI 0 "register_operand" "")
2875 (match_operand:DI 1 "const_double_operand" ""))]
2876 "! TARGET_ARCH64 && reload_completed"
2877 [(clobber (const_int 0))]
2880 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2881 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2883 /* Slick... but this trick loses if this subreg constant part
2884 can be done in one insn. */
2885 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2886 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2887 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2889 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2890 gen_highpart (SImode, operands[0])));
2894 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2895 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2901 [(set (match_operand:DI 0 "register_operand" "")
2902 (match_operand:DI 1 "register_operand" ""))]
2903 "! TARGET_ARCH64 && reload_completed"
2904 [(clobber (const_int 0))]
2907 rtx set_dest = operands[0];
2908 rtx set_src = operands[1];
2912 dest1 = gen_highpart (SImode, set_dest);
2913 dest2 = gen_lowpart (SImode, set_dest);
2914 src1 = gen_highpart (SImode, set_src);
2915 src2 = gen_lowpart (SImode, set_src);
2917 /* Now emit using the real source and destination we found, swapping
2918 the order if we detect overlap. */
2919 if (reg_overlap_mentioned_p (dest1, src2))
2921 emit_insn (gen_movsi (dest2, src2));
2922 emit_insn (gen_movsi (dest1, src1));
2926 emit_insn (gen_movsi (dest1, src1));
2927 emit_insn (gen_movsi (dest2, src2));
2932 ;; Now handle the cases of memory moves from/to non-even
2933 ;; DI mode register pairs.
2935 [(set (match_operand:DI 0 "register_operand" "")
2936 (match_operand:DI 1 "memory_operand" ""))]
2939 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2940 [(clobber (const_int 0))]
2943 rtx word0 = adjust_address (operands[1], SImode, 0);
2944 rtx word1 = adjust_address (operands[1], SImode, 4);
2945 rtx high_part = gen_highpart (SImode, operands[0]);
2946 rtx low_part = gen_lowpart (SImode, operands[0]);
2948 if (reg_overlap_mentioned_p (high_part, word1))
2950 emit_insn (gen_movsi (low_part, word1));
2951 emit_insn (gen_movsi (high_part, word0));
2955 emit_insn (gen_movsi (high_part, word0));
2956 emit_insn (gen_movsi (low_part, word1));
2962 [(set (match_operand:DI 0 "memory_operand" "")
2963 (match_operand:DI 1 "register_operand" ""))]
2966 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2967 [(clobber (const_int 0))]
2970 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2971 gen_highpart (SImode, operands[1])));
2972 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2973 gen_lowpart (SImode, operands[1])));
2978 ;; Floating point move insns
2980 (define_insn "*movsf_insn_novis"
2981 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2982 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2983 "(TARGET_FPU && ! TARGET_VIS)
2984 && (register_operand (operands[0], SFmode)
2985 || register_operand (operands[1], SFmode)
2986 || fp_zero_operand (operands[1], SFmode))"
2989 if (GET_CODE (operands[1]) == CONST_DOUBLE
2990 && (which_alternative == 2
2991 || which_alternative == 3
2992 || which_alternative == 4))
2997 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2998 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2999 operands[1] = GEN_INT (i);
3002 switch (which_alternative)
3005 return \"fmovs\\t%1, %0\";
3007 return \"clr\\t%0\";
3009 return \"sethi\\t%%hi(%a1), %0\";
3011 return \"mov\\t%1, %0\";
3016 return \"ld\\t%1, %0\";
3019 return \"st\\t%r1, %0\";
3024 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
3026 (define_insn "*movsf_insn_vis"
3027 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3028 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3029 "(TARGET_FPU && TARGET_VIS)
3030 && (register_operand (operands[0], SFmode)
3031 || register_operand (operands[1], SFmode)
3032 || fp_zero_operand (operands[1], SFmode))"
3035 if (GET_CODE (operands[1]) == CONST_DOUBLE
3036 && (which_alternative == 3
3037 || which_alternative == 4
3038 || which_alternative == 5))
3043 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3044 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3045 operands[1] = GEN_INT (i);
3048 switch (which_alternative)
3051 return \"fmovs\\t%1, %0\";
3053 return \"fzeros\\t%0\";
3055 return \"clr\\t%0\";
3057 return \"sethi\\t%%hi(%a1), %0\";
3059 return \"mov\\t%1, %0\";
3064 return \"ld\\t%1, %0\";
3067 return \"st\\t%r1, %0\";
3072 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
3074 ;; Exactly the same as above, except that all `f' cases are deleted.
3075 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3078 (define_insn "*movsf_no_f_insn"
3079 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3080 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3082 && (register_operand (operands[0], SFmode)
3083 || register_operand (operands[1], SFmode)
3084 || fp_zero_operand (operands[1], SFmode))"
3087 if (GET_CODE (operands[1]) == CONST_DOUBLE
3088 && (which_alternative == 1
3089 || which_alternative == 2
3090 || which_alternative == 3))
3095 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3096 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3097 operands[1] = GEN_INT (i);
3100 switch (which_alternative)
3103 return \"clr\\t%0\";
3105 return \"sethi\\t%%hi(%a1), %0\";
3107 return \"mov\\t%1, %0\";
3111 return \"ld\\t%1, %0\";
3113 return \"st\\t%r1, %0\";
3118 [(set_attr "type" "*,*,*,*,load,store")])
3120 (define_insn "*movsf_lo_sum"
3121 [(set (match_operand:SF 0 "register_operand" "=r")
3122 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3123 (match_operand:SF 2 "const_double_operand" "S")))]
3124 "fp_high_losum_p (operands[2])"
3130 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3131 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3132 operands[2] = GEN_INT (i);
3133 return \"or\\t%1, %%lo(%a2), %0\";
3136 (define_insn "*movsf_high"
3137 [(set (match_operand:SF 0 "register_operand" "=r")
3138 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3139 "fp_high_losum_p (operands[1])"
3145 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3146 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3147 operands[1] = GEN_INT (i);
3148 return \"sethi\\t%%hi(%1), %0\";
3152 [(set (match_operand:SF 0 "register_operand" "")
3153 (match_operand:SF 1 "const_double_operand" ""))]
3154 "fp_high_losum_p (operands[1])
3155 && (GET_CODE (operands[0]) == REG
3156 && REGNO (operands[0]) < 32)"
3157 [(set (match_dup 0) (high:SF (match_dup 1)))
3158 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3160 (define_expand "movsf"
3161 [(set (match_operand:SF 0 "general_operand" "")
3162 (match_operand:SF 1 "general_operand" ""))]
3166 /* Force SFmode constants into memory. */
3167 if (GET_CODE (operands[0]) == REG
3168 && CONSTANT_P (operands[1]))
3170 /* emit_group_store will send such bogosity to us when it is
3171 not storing directly into memory. So fix this up to avoid
3172 crashes in output_constant_pool. */
3173 if (operands [1] == const0_rtx)
3174 operands[1] = CONST0_RTX (SFmode);
3176 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3179 /* We are able to build any SF constant in integer registers
3180 with at most 2 instructions. */
3181 if (REGNO (operands[0]) < 32)
3184 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3188 /* Handle sets of MEM first. */
3189 if (GET_CODE (operands[0]) == MEM)
3191 if (register_operand (operands[1], SFmode)
3192 || fp_zero_operand (operands[1], SFmode))
3195 if (! reload_in_progress)
3197 operands[0] = validize_mem (operands[0]);
3198 operands[1] = force_reg (SFmode, operands[1]);
3202 /* Fixup PIC cases. */
3205 if (CONSTANT_P (operands[1])
3206 && pic_address_needs_scratch (operands[1]))
3207 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3209 if (symbolic_operand (operands[1], SFmode))
3211 operands[1] = legitimize_pic_address (operands[1],
3213 (reload_in_progress ?
3223 (define_expand "movdf"
3224 [(set (match_operand:DF 0 "general_operand" "")
3225 (match_operand:DF 1 "general_operand" ""))]
3229 /* Force DFmode constants into memory. */
3230 if (GET_CODE (operands[0]) == REG
3231 && CONSTANT_P (operands[1]))
3233 /* emit_group_store will send such bogosity to us when it is
3234 not storing directly into memory. So fix this up to avoid
3235 crashes in output_constant_pool. */
3236 if (operands [1] == const0_rtx)
3237 operands[1] = CONST0_RTX (DFmode);
3239 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3240 && fp_zero_operand (operands[1], DFmode))
3243 /* We are able to build any DF constant in integer registers. */
3244 if (REGNO (operands[0]) < 32
3245 && (reload_completed || reload_in_progress))
3248 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3252 /* Handle MEM cases first. */
3253 if (GET_CODE (operands[0]) == MEM)
3255 if (register_operand (operands[1], DFmode)
3256 || fp_zero_operand (operands[1], DFmode))
3259 if (! reload_in_progress)
3261 operands[0] = validize_mem (operands[0]);
3262 operands[1] = force_reg (DFmode, operands[1]);
3266 /* Fixup PIC cases. */
3269 if (CONSTANT_P (operands[1])
3270 && pic_address_needs_scratch (operands[1]))
3271 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3273 if (symbolic_operand (operands[1], DFmode))
3275 operands[1] = legitimize_pic_address (operands[1],
3277 (reload_in_progress ?
3287 ;; Be careful, fmovd does not exist when !v9.
3288 (define_insn "*movdf_insn_sp32"
3289 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3290 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3293 && (register_operand (operands[0], DFmode)
3294 || register_operand (operands[1], DFmode)
3295 || fp_zero_operand (operands[1], DFmode))"
3307 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3308 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3310 (define_insn "*movdf_no_e_insn_sp32"
3311 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3312 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3316 && (register_operand (operands[0], DFmode)
3317 || register_operand (operands[1], DFmode)
3318 || fp_zero_operand (operands[1], DFmode))"
3325 [(set_attr "type" "load,store,*,*,*")
3326 (set_attr "length" "*,*,2,2,2")])
3328 (define_insn "*movdf_no_e_insn_v9_sp32"
3329 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3330 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3334 && (register_operand (operands[0], DFmode)
3335 || register_operand (operands[1], DFmode)
3336 || fp_zero_operand (operands[1], DFmode))"
3343 [(set_attr "type" "load,store,store,*,*")
3344 (set_attr "length" "*,*,*,2,2")])
3346 ;; We have available v9 double floats but not 64-bit
3347 ;; integer registers and no VIS.
3348 (define_insn "*movdf_insn_v9only_novis"
3349 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3350 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3355 && (register_operand (operands[0], DFmode)
3356 || register_operand (operands[1], DFmode)
3357 || fp_zero_operand (operands[1], DFmode))"
3368 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3369 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3370 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3372 ;; We have available v9 double floats but not 64-bit
3373 ;; integer registers but we have VIS.
3374 (define_insn "*movdf_insn_v9only_vis"
3375 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3376 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3380 && (register_operand (operands[0], DFmode)
3381 || register_operand (operands[1], DFmode)
3382 || fp_zero_operand (operands[1], DFmode))"
3394 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3395 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3396 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3398 ;; We have available both v9 double floats and 64-bit
3399 ;; integer registers. No VIS though.
3400 (define_insn "*movdf_insn_sp64_novis"
3401 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3402 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3406 && (register_operand (operands[0], DFmode)
3407 || register_operand (operands[1], DFmode)
3408 || fp_zero_operand (operands[1], DFmode))"
3417 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3418 (set_attr "length" "*,*,*,*,*,*,2")
3419 (set_attr "fptype" "double,*,*,*,*,*,*")])
3421 ;; We have available both v9 double floats and 64-bit
3422 ;; integer registers. And we have VIS.
3423 (define_insn "*movdf_insn_sp64_vis"
3424 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3425 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3429 && (register_operand (operands[0], DFmode)
3430 || register_operand (operands[1], DFmode)
3431 || fp_zero_operand (operands[1], DFmode))"
3441 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3442 (set_attr "length" "*,*,*,*,*,*,*,2")
3443 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3445 (define_insn "*movdf_no_e_insn_sp64"
3446 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3447 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3450 && (register_operand (operands[0], DFmode)
3451 || register_operand (operands[1], DFmode)
3452 || fp_zero_operand (operands[1], DFmode))"
3457 [(set_attr "type" "*,load,store")])
3460 [(set (match_operand:DF 0 "register_operand" "")
3461 (match_operand:DF 1 "const_double_operand" ""))]
3463 && (GET_CODE (operands[0]) == REG
3464 && REGNO (operands[0]) < 32)
3465 && ! fp_zero_operand(operands[1], DFmode)
3466 && reload_completed"
3467 [(clobber (const_int 0))]
3473 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3474 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3475 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3479 #if HOST_BITS_PER_WIDE_INT == 64
3482 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3483 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3484 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3486 emit_insn (gen_movdi (operands[0],
3487 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3492 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3495 /* Slick... but this trick loses if this subreg constant part
3496 can be done in one insn. */
3498 && !(SPARC_SETHI32_P (l[0])
3499 || SPARC_SIMM13_P (l[0])))
3501 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3502 gen_highpart (SImode, operands[0])));
3506 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3513 ;; Ok, now the splits to handle all the multi insn and
3514 ;; mis-aligned memory address cases.
3515 ;; In these splits please take note that we must be
3516 ;; careful when V9 but not ARCH64 because the integer
3517 ;; register DFmode cases must be handled.
3519 [(set (match_operand:DF 0 "register_operand" "")
3520 (match_operand:DF 1 "register_operand" ""))]
3523 && ((GET_CODE (operands[0]) == REG
3524 && REGNO (operands[0]) < 32)
3525 || (GET_CODE (operands[0]) == SUBREG
3526 && GET_CODE (SUBREG_REG (operands[0])) == REG
3527 && REGNO (SUBREG_REG (operands[0])) < 32))))
3528 && reload_completed"
3529 [(clobber (const_int 0))]
3532 rtx set_dest = operands[0];
3533 rtx set_src = operands[1];
3537 dest1 = gen_highpart (SFmode, set_dest);
3538 dest2 = gen_lowpart (SFmode, set_dest);
3539 src1 = gen_highpart (SFmode, set_src);
3540 src2 = gen_lowpart (SFmode, set_src);
3542 /* Now emit using the real source and destination we found, swapping
3543 the order if we detect overlap. */
3544 if (reg_overlap_mentioned_p (dest1, src2))
3546 emit_insn (gen_movsf (dest2, src2));
3547 emit_insn (gen_movsf (dest1, src1));
3551 emit_insn (gen_movsf (dest1, src1));
3552 emit_insn (gen_movsf (dest2, src2));
3558 [(set (match_operand:DF 0 "register_operand" "")
3559 (match_operand:DF 1 "memory_operand" ""))]
3562 && (((REGNO (operands[0]) % 2) != 0)
3563 || ! mem_min_alignment (operands[1], 8))
3564 && offsettable_memref_p (operands[1])"
3565 [(clobber (const_int 0))]
3568 rtx word0 = adjust_address (operands[1], SFmode, 0);
3569 rtx word1 = adjust_address (operands[1], SFmode, 4);
3571 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3573 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3575 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3580 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3582 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3589 [(set (match_operand:DF 0 "memory_operand" "")
3590 (match_operand:DF 1 "register_operand" ""))]
3593 && (((REGNO (operands[1]) % 2) != 0)
3594 || ! mem_min_alignment (operands[0], 8))
3595 && offsettable_memref_p (operands[0])"
3596 [(clobber (const_int 0))]
3599 rtx word0 = adjust_address (operands[0], SFmode, 0);
3600 rtx word1 = adjust_address (operands[0], SFmode, 4);
3602 emit_insn (gen_movsf (word0,
3603 gen_highpart (SFmode, operands[1])));
3604 emit_insn (gen_movsf (word1,
3605 gen_lowpart (SFmode, operands[1])));
3610 [(set (match_operand:DF 0 "memory_operand" "")
3611 (match_operand:DF 1 "fp_zero_operand" ""))]
3615 && ! mem_min_alignment (operands[0], 8)))
3616 && offsettable_memref_p (operands[0])"
3617 [(clobber (const_int 0))]
3622 dest1 = adjust_address (operands[0], SFmode, 0);
3623 dest2 = adjust_address (operands[0], SFmode, 4);
3625 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3626 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3631 [(set (match_operand:DF 0 "register_operand" "")
3632 (match_operand:DF 1 "fp_zero_operand" ""))]
3635 && ((GET_CODE (operands[0]) == REG
3636 && REGNO (operands[0]) < 32)
3637 || (GET_CODE (operands[0]) == SUBREG
3638 && GET_CODE (SUBREG_REG (operands[0])) == REG
3639 && REGNO (SUBREG_REG (operands[0])) < 32))"
3640 [(clobber (const_int 0))]
3643 rtx set_dest = operands[0];
3646 dest1 = gen_highpart (SFmode, set_dest);
3647 dest2 = gen_lowpart (SFmode, set_dest);
3648 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3649 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3653 (define_expand "movtf"
3654 [(set (match_operand:TF 0 "general_operand" "")
3655 (match_operand:TF 1 "general_operand" ""))]
3659 /* Force TFmode constants into memory. */
3660 if (GET_CODE (operands[0]) == REG
3661 && CONSTANT_P (operands[1]))
3663 /* emit_group_store will send such bogosity to us when it is
3664 not storing directly into memory. So fix this up to avoid
3665 crashes in output_constant_pool. */
3666 if (operands [1] == const0_rtx)
3667 operands[1] = CONST0_RTX (TFmode);
3669 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3672 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3676 /* Handle MEM cases first, note that only v9 guarentees
3677 full 16-byte alignment for quads. */
3678 if (GET_CODE (operands[0]) == MEM)
3680 if (register_operand (operands[1], TFmode)
3681 || fp_zero_operand (operands[1], TFmode))
3684 if (! reload_in_progress)
3686 operands[0] = validize_mem (operands[0]);
3687 operands[1] = force_reg (TFmode, operands[1]);
3691 /* Fixup PIC cases. */
3694 if (CONSTANT_P (operands[1])
3695 && pic_address_needs_scratch (operands[1]))
3696 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3698 if (symbolic_operand (operands[1], TFmode))
3700 operands[1] = legitimize_pic_address (operands[1],
3702 (reload_in_progress ?
3712 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3713 ;; we must split them all. :-(
3714 (define_insn "*movtf_insn_sp32"
3715 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3716 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3720 && (register_operand (operands[0], TFmode)
3721 || register_operand (operands[1], TFmode)
3722 || fp_zero_operand (operands[1], TFmode))"
3724 [(set_attr "length" "4")])
3726 (define_insn "*movtf_insn_vis_sp32"
3727 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3728 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3732 && (register_operand (operands[0], TFmode)
3733 || register_operand (operands[1], TFmode)
3734 || fp_zero_operand (operands[1], TFmode))"
3736 [(set_attr "length" "4")])
3738 ;; Exactly the same as above, except that all `e' cases are deleted.
3739 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3742 (define_insn "*movtf_no_e_insn_sp32"
3743 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3744 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3747 && (register_operand (operands[0], TFmode)
3748 || register_operand (operands[1], TFmode)
3749 || fp_zero_operand (operands[1], TFmode))"
3751 [(set_attr "length" "4")])
3753 ;; Now handle the float reg cases directly when arch64,
3754 ;; hard_quad, and proper reg number alignment are all true.
3755 (define_insn "*movtf_insn_hq_sp64"
3756 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3757 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3762 && (register_operand (operands[0], TFmode)
3763 || register_operand (operands[1], TFmode)
3764 || fp_zero_operand (operands[1], TFmode))"
3771 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3772 (set_attr "length" "*,*,*,2,2")])
3774 (define_insn "*movtf_insn_hq_vis_sp64"
3775 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3776 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3781 && (register_operand (operands[0], TFmode)
3782 || register_operand (operands[1], TFmode)
3783 || fp_zero_operand (operands[1], TFmode))"
3791 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3792 (set_attr "length" "*,*,*,2,2,2")])
3794 ;; Now we allow the integer register cases even when
3795 ;; only arch64 is true.
3796 (define_insn "*movtf_insn_sp64"
3797 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3798 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3802 && ! TARGET_HARD_QUAD
3803 && (register_operand (operands[0], TFmode)
3804 || register_operand (operands[1], TFmode)
3805 || fp_zero_operand (operands[1], TFmode))"
3807 [(set_attr "length" "2")])
3809 (define_insn "*movtf_insn_vis_sp64"
3810 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3811 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3815 && ! TARGET_HARD_QUAD
3816 && (register_operand (operands[0], TFmode)
3817 || register_operand (operands[1], TFmode)
3818 || fp_zero_operand (operands[1], TFmode))"
3820 [(set_attr "length" "2")])
3822 (define_insn "*movtf_no_e_insn_sp64"
3823 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3824 (match_operand:TF 1 "input_operand" "orG,rG"))]
3827 && (register_operand (operands[0], TFmode)
3828 || register_operand (operands[1], TFmode)
3829 || fp_zero_operand (operands[1], TFmode))"
3831 [(set_attr "length" "2")])
3833 ;; Now all the splits to handle multi-insn TF mode moves.
3835 [(set (match_operand:TF 0 "register_operand" "")
3836 (match_operand:TF 1 "register_operand" ""))]
3840 && ! TARGET_HARD_QUAD))"
3841 [(clobber (const_int 0))]
3844 rtx set_dest = operands[0];
3845 rtx set_src = operands[1];
3849 dest1 = gen_df_reg (set_dest, 0);
3850 dest2 = gen_df_reg (set_dest, 1);
3851 src1 = gen_df_reg (set_src, 0);
3852 src2 = gen_df_reg (set_src, 1);
3854 /* Now emit using the real source and destination we found, swapping
3855 the order if we detect overlap. */
3856 if (reg_overlap_mentioned_p (dest1, src2))
3858 emit_insn (gen_movdf (dest2, src2));
3859 emit_insn (gen_movdf (dest1, src1));
3863 emit_insn (gen_movdf (dest1, src1));
3864 emit_insn (gen_movdf (dest2, src2));
3870 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3871 (match_operand:TF 1 "fp_zero_operand" ""))]
3873 [(clobber (const_int 0))]
3876 rtx set_dest = operands[0];
3879 switch (GET_CODE (set_dest))
3882 dest1 = gen_df_reg (set_dest, 0);
3883 dest2 = gen_df_reg (set_dest, 1);
3886 dest1 = adjust_address (set_dest, DFmode, 0);
3887 dest2 = adjust_address (set_dest, DFmode, 8);
3893 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3894 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3899 [(set (match_operand:TF 0 "register_operand" "")
3900 (match_operand:TF 1 "memory_operand" ""))]
3902 && offsettable_memref_p (operands[1]))"
3903 [(clobber (const_int 0))]
3906 rtx word0 = adjust_address (operands[1], DFmode, 0);
3907 rtx word1 = adjust_address (operands[1], DFmode, 8);
3908 rtx set_dest, dest1, dest2;
3910 set_dest = operands[0];
3912 dest1 = gen_df_reg (set_dest, 0);
3913 dest2 = gen_df_reg (set_dest, 1);
3915 /* Now output, ordering such that we don't clobber any registers
3916 mentioned in the address. */
3917 if (reg_overlap_mentioned_p (dest1, word1))
3920 emit_insn (gen_movdf (dest2, word1));
3921 emit_insn (gen_movdf (dest1, word0));
3925 emit_insn (gen_movdf (dest1, word0));
3926 emit_insn (gen_movdf (dest2, word1));
3932 [(set (match_operand:TF 0 "memory_operand" "")
3933 (match_operand:TF 1 "register_operand" ""))]
3935 && offsettable_memref_p (operands[0]))"
3936 [(clobber (const_int 0))]
3939 rtx set_src = operands[1];
3941 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3942 gen_df_reg (set_src, 0)));
3943 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3944 gen_df_reg (set_src, 1)));
3948 ;; Sparc V9 conditional move instructions.
3950 ;; We can handle larger constants here for some flavors, but for now we keep
3951 ;; it simple and only allow those constants supported by all flavours.
3952 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3953 ;; 3 contains the constant if one is present, but we handle either for
3954 ;; generality (sparc.c puts a constant in operand 2).
3956 (define_expand "movqicc"
3957 [(set (match_operand:QI 0 "register_operand" "")
3958 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3959 (match_operand:QI 2 "arith10_operand" "")
3960 (match_operand:QI 3 "arith10_operand" "")))]
3964 enum rtx_code code = GET_CODE (operands[1]);
3966 if (GET_MODE (sparc_compare_op0) == DImode
3970 if (sparc_compare_op1 == const0_rtx
3971 && GET_CODE (sparc_compare_op0) == REG
3972 && GET_MODE (sparc_compare_op0) == DImode
3973 && v9_regcmp_p (code))
3975 operands[1] = gen_rtx_fmt_ee (code, DImode,
3976 sparc_compare_op0, sparc_compare_op1);
3980 rtx cc_reg = gen_compare_reg (code,
3981 sparc_compare_op0, sparc_compare_op1);
3982 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3986 (define_expand "movhicc"
3987 [(set (match_operand:HI 0 "register_operand" "")
3988 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3989 (match_operand:HI 2 "arith10_operand" "")
3990 (match_operand:HI 3 "arith10_operand" "")))]
3994 enum rtx_code code = GET_CODE (operands[1]);
3996 if (GET_MODE (sparc_compare_op0) == DImode
4000 if (sparc_compare_op1 == const0_rtx
4001 && GET_CODE (sparc_compare_op0) == REG
4002 && GET_MODE (sparc_compare_op0) == DImode
4003 && v9_regcmp_p (code))
4005 operands[1] = gen_rtx_fmt_ee (code, DImode,
4006 sparc_compare_op0, sparc_compare_op1);
4010 rtx cc_reg = gen_compare_reg (code,
4011 sparc_compare_op0, sparc_compare_op1);
4012 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4016 (define_expand "movsicc"
4017 [(set (match_operand:SI 0 "register_operand" "")
4018 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4019 (match_operand:SI 2 "arith10_operand" "")
4020 (match_operand:SI 3 "arith10_operand" "")))]
4024 enum rtx_code code = GET_CODE (operands[1]);
4025 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4027 if (sparc_compare_op1 == const0_rtx
4028 && GET_CODE (sparc_compare_op0) == REG
4029 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4031 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4032 sparc_compare_op0, sparc_compare_op1);
4036 rtx cc_reg = gen_compare_reg (code,
4037 sparc_compare_op0, sparc_compare_op1);
4038 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4039 cc_reg, const0_rtx);
4043 (define_expand "movdicc"
4044 [(set (match_operand:DI 0 "register_operand" "")
4045 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4046 (match_operand:DI 2 "arith10_double_operand" "")
4047 (match_operand:DI 3 "arith10_double_operand" "")))]
4051 enum rtx_code code = GET_CODE (operands[1]);
4053 if (sparc_compare_op1 == const0_rtx
4054 && GET_CODE (sparc_compare_op0) == REG
4055 && GET_MODE (sparc_compare_op0) == DImode
4056 && v9_regcmp_p (code))
4058 operands[1] = gen_rtx_fmt_ee (code, DImode,
4059 sparc_compare_op0, sparc_compare_op1);
4063 rtx cc_reg = gen_compare_reg (code,
4064 sparc_compare_op0, sparc_compare_op1);
4065 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4066 cc_reg, const0_rtx);
4070 (define_expand "movsfcc"
4071 [(set (match_operand:SF 0 "register_operand" "")
4072 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4073 (match_operand:SF 2 "register_operand" "")
4074 (match_operand:SF 3 "register_operand" "")))]
4075 "TARGET_V9 && TARGET_FPU"
4078 enum rtx_code code = GET_CODE (operands[1]);
4080 if (GET_MODE (sparc_compare_op0) == DImode
4084 if (sparc_compare_op1 == const0_rtx
4085 && GET_CODE (sparc_compare_op0) == REG
4086 && GET_MODE (sparc_compare_op0) == DImode
4087 && v9_regcmp_p (code))
4089 operands[1] = gen_rtx_fmt_ee (code, DImode,
4090 sparc_compare_op0, sparc_compare_op1);
4094 rtx cc_reg = gen_compare_reg (code,
4095 sparc_compare_op0, sparc_compare_op1);
4096 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4100 (define_expand "movdfcc"
4101 [(set (match_operand:DF 0 "register_operand" "")
4102 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4103 (match_operand:DF 2 "register_operand" "")
4104 (match_operand:DF 3 "register_operand" "")))]
4105 "TARGET_V9 && TARGET_FPU"
4108 enum rtx_code code = GET_CODE (operands[1]);
4110 if (GET_MODE (sparc_compare_op0) == DImode
4114 if (sparc_compare_op1 == const0_rtx
4115 && GET_CODE (sparc_compare_op0) == REG
4116 && GET_MODE (sparc_compare_op0) == DImode
4117 && v9_regcmp_p (code))
4119 operands[1] = gen_rtx_fmt_ee (code, DImode,
4120 sparc_compare_op0, sparc_compare_op1);
4124 rtx cc_reg = gen_compare_reg (code,
4125 sparc_compare_op0, sparc_compare_op1);
4126 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4130 (define_expand "movtfcc"
4131 [(set (match_operand:TF 0 "register_operand" "")
4132 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4133 (match_operand:TF 2 "register_operand" "")
4134 (match_operand:TF 3 "register_operand" "")))]
4135 "TARGET_V9 && TARGET_FPU"
4138 enum rtx_code code = GET_CODE (operands[1]);
4140 if (GET_MODE (sparc_compare_op0) == DImode
4144 if (sparc_compare_op1 == const0_rtx
4145 && GET_CODE (sparc_compare_op0) == REG
4146 && GET_MODE (sparc_compare_op0) == DImode
4147 && v9_regcmp_p (code))
4149 operands[1] = gen_rtx_fmt_ee (code, DImode,
4150 sparc_compare_op0, sparc_compare_op1);
4154 rtx cc_reg = gen_compare_reg (code,
4155 sparc_compare_op0, sparc_compare_op1);
4156 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4160 ;; Conditional move define_insns.
4162 (define_insn "*movqi_cc_sp64"
4163 [(set (match_operand:QI 0 "register_operand" "=r,r")
4164 (if_then_else:QI (match_operator 1 "comparison_operator"
4165 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4167 (match_operand:QI 3 "arith11_operand" "rL,0")
4168 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4171 mov%C1\\t%x2, %3, %0
4172 mov%c1\\t%x2, %4, %0"
4173 [(set_attr "type" "cmove")])
4175 (define_insn "*movhi_cc_sp64"
4176 [(set (match_operand:HI 0 "register_operand" "=r,r")
4177 (if_then_else:HI (match_operator 1 "comparison_operator"
4178 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4180 (match_operand:HI 3 "arith11_operand" "rL,0")
4181 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4184 mov%C1\\t%x2, %3, %0
4185 mov%c1\\t%x2, %4, %0"
4186 [(set_attr "type" "cmove")])
4188 (define_insn "*movsi_cc_sp64"
4189 [(set (match_operand:SI 0 "register_operand" "=r,r")
4190 (if_then_else:SI (match_operator 1 "comparison_operator"
4191 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4193 (match_operand:SI 3 "arith11_operand" "rL,0")
4194 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4197 mov%C1\\t%x2, %3, %0
4198 mov%c1\\t%x2, %4, %0"
4199 [(set_attr "type" "cmove")])
4201 ;; ??? The constraints of operands 3,4 need work.
4202 (define_insn "*movdi_cc_sp64"
4203 [(set (match_operand:DI 0 "register_operand" "=r,r")
4204 (if_then_else:DI (match_operator 1 "comparison_operator"
4205 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4207 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4208 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4211 mov%C1\\t%x2, %3, %0
4212 mov%c1\\t%x2, %4, %0"
4213 [(set_attr "type" "cmove")])
4215 (define_insn "*movdi_cc_sp64_trunc"
4216 [(set (match_operand:SI 0 "register_operand" "=r,r")
4217 (if_then_else:SI (match_operator 1 "comparison_operator"
4218 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4220 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4221 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4224 mov%C1\\t%x2, %3, %0
4225 mov%c1\\t%x2, %4, %0"
4226 [(set_attr "type" "cmove")])
4228 (define_insn "*movsf_cc_sp64"
4229 [(set (match_operand:SF 0 "register_operand" "=f,f")
4230 (if_then_else:SF (match_operator 1 "comparison_operator"
4231 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4233 (match_operand:SF 3 "register_operand" "f,0")
4234 (match_operand:SF 4 "register_operand" "0,f")))]
4235 "TARGET_V9 && TARGET_FPU"
4237 fmovs%C1\\t%x2, %3, %0
4238 fmovs%c1\\t%x2, %4, %0"
4239 [(set_attr "type" "fpcmove")])
4241 (define_insn "movdf_cc_sp64"
4242 [(set (match_operand:DF 0 "register_operand" "=e,e")
4243 (if_then_else:DF (match_operator 1 "comparison_operator"
4244 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4246 (match_operand:DF 3 "register_operand" "e,0")
4247 (match_operand:DF 4 "register_operand" "0,e")))]
4248 "TARGET_V9 && TARGET_FPU"
4250 fmovd%C1\\t%x2, %3, %0
4251 fmovd%c1\\t%x2, %4, %0"
4252 [(set_attr "type" "fpcmove")
4253 (set_attr "fptype" "double")])
4255 (define_insn "*movtf_cc_hq_sp64"
4256 [(set (match_operand:TF 0 "register_operand" "=e,e")
4257 (if_then_else:TF (match_operator 1 "comparison_operator"
4258 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4260 (match_operand:TF 3 "register_operand" "e,0")
4261 (match_operand:TF 4 "register_operand" "0,e")))]
4262 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4264 fmovq%C1\\t%x2, %3, %0
4265 fmovq%c1\\t%x2, %4, %0"
4266 [(set_attr "type" "fpcmove")])
4268 (define_insn "*movtf_cc_sp64"
4269 [(set (match_operand:TF 0 "register_operand" "=e,e")
4270 (if_then_else:TF (match_operator 1 "comparison_operator"
4271 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4273 (match_operand:TF 3 "register_operand" "e,0")
4274 (match_operand:TF 4 "register_operand" "0,e")))]
4275 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4277 [(set_attr "length" "2")])
4280 [(set (match_operand:TF 0 "register_operand" "")
4281 (if_then_else:TF (match_operator 1 "comparison_operator"
4282 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4284 (match_operand:TF 3 "register_operand" "")
4285 (match_operand:TF 4 "register_operand" "")))]
4286 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4287 [(clobber (const_int 0))]
4290 rtx set_dest = operands[0];
4291 rtx set_srca = operands[3];
4292 rtx set_srcb = operands[4];
4293 int third = rtx_equal_p (set_dest, set_srca);
4295 rtx srca1, srca2, srcb1, srcb2;
4297 dest1 = gen_df_reg (set_dest, 0);
4298 dest2 = gen_df_reg (set_dest, 1);
4299 srca1 = gen_df_reg (set_srca, 0);
4300 srca2 = gen_df_reg (set_srca, 1);
4301 srcb1 = gen_df_reg (set_srcb, 0);
4302 srcb2 = gen_df_reg (set_srcb, 1);
4304 /* Now emit using the real source and destination we found, swapping
4305 the order if we detect overlap. */
4306 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4307 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4309 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4310 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4314 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4315 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4320 (define_insn "*movqi_cc_reg_sp64"
4321 [(set (match_operand:QI 0 "register_operand" "=r,r")
4322 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4323 [(match_operand:DI 2 "register_operand" "r,r")
4325 (match_operand:QI 3 "arith10_operand" "rM,0")
4326 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4329 movr%D1\\t%2, %r3, %0
4330 movr%d1\\t%2, %r4, %0"
4331 [(set_attr "type" "cmove")])
4333 (define_insn "*movhi_cc_reg_sp64"
4334 [(set (match_operand:HI 0 "register_operand" "=r,r")
4335 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4336 [(match_operand:DI 2 "register_operand" "r,r")
4338 (match_operand:HI 3 "arith10_operand" "rM,0")
4339 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4342 movr%D1\\t%2, %r3, %0
4343 movr%d1\\t%2, %r4, %0"
4344 [(set_attr "type" "cmove")])
4346 (define_insn "*movsi_cc_reg_sp64"
4347 [(set (match_operand:SI 0 "register_operand" "=r,r")
4348 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4349 [(match_operand:DI 2 "register_operand" "r,r")
4351 (match_operand:SI 3 "arith10_operand" "rM,0")
4352 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4355 movr%D1\\t%2, %r3, %0
4356 movr%d1\\t%2, %r4, %0"
4357 [(set_attr "type" "cmove")])
4359 ;; ??? The constraints of operands 3,4 need work.
4360 (define_insn "*movdi_cc_reg_sp64"
4361 [(set (match_operand:DI 0 "register_operand" "=r,r")
4362 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4363 [(match_operand:DI 2 "register_operand" "r,r")
4365 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4366 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4369 movr%D1\\t%2, %r3, %0
4370 movr%d1\\t%2, %r4, %0"
4371 [(set_attr "type" "cmove")])
4373 (define_insn "*movdi_cc_reg_sp64_trunc"
4374 [(set (match_operand:SI 0 "register_operand" "=r,r")
4375 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4376 [(match_operand:DI 2 "register_operand" "r,r")
4378 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4379 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4382 movr%D1\\t%2, %r3, %0
4383 movr%d1\\t%2, %r4, %0"
4384 [(set_attr "type" "cmove")])
4386 (define_insn "*movsf_cc_reg_sp64"
4387 [(set (match_operand:SF 0 "register_operand" "=f,f")
4388 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4389 [(match_operand:DI 2 "register_operand" "r,r")
4391 (match_operand:SF 3 "register_operand" "f,0")
4392 (match_operand:SF 4 "register_operand" "0,f")))]
4393 "TARGET_ARCH64 && TARGET_FPU"
4395 fmovrs%D1\\t%2, %3, %0
4396 fmovrs%d1\\t%2, %4, %0"
4397 [(set_attr "type" "fpcmove")])
4399 (define_insn "movdf_cc_reg_sp64"
4400 [(set (match_operand:DF 0 "register_operand" "=e,e")
4401 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4402 [(match_operand:DI 2 "register_operand" "r,r")
4404 (match_operand:DF 3 "register_operand" "e,0")
4405 (match_operand:DF 4 "register_operand" "0,e")))]
4406 "TARGET_ARCH64 && TARGET_FPU"
4408 fmovrd%D1\\t%2, %3, %0
4409 fmovrd%d1\\t%2, %4, %0"
4410 [(set_attr "type" "fpcmove")
4411 (set_attr "fptype" "double")])
4413 (define_insn "*movtf_cc_reg_hq_sp64"
4414 [(set (match_operand:TF 0 "register_operand" "=e,e")
4415 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4416 [(match_operand:DI 2 "register_operand" "r,r")
4418 (match_operand:TF 3 "register_operand" "e,0")
4419 (match_operand:TF 4 "register_operand" "0,e")))]
4420 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4422 fmovrq%D1\\t%2, %3, %0
4423 fmovrq%d1\\t%2, %4, %0"
4424 [(set_attr "type" "fpcmove")])
4426 (define_insn "*movtf_cc_reg_sp64"
4427 [(set (match_operand:TF 0 "register_operand" "=e,e")
4428 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4429 [(match_operand:DI 2 "register_operand" "r,r")
4431 (match_operand:TF 3 "register_operand" "e,0")
4432 (match_operand:TF 4 "register_operand" "0,e")))]
4433 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4435 [(set_attr "length" "2")])
4438 [(set (match_operand:TF 0 "register_operand" "")
4439 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4440 [(match_operand:DI 2 "register_operand" "")
4442 (match_operand:TF 3 "register_operand" "")
4443 (match_operand:TF 4 "register_operand" "")))]
4444 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4445 [(clobber (const_int 0))]
4448 rtx set_dest = operands[0];
4449 rtx set_srca = operands[3];
4450 rtx set_srcb = operands[4];
4451 int third = rtx_equal_p (set_dest, set_srca);
4453 rtx srca1, srca2, srcb1, srcb2;
4455 dest1 = gen_df_reg (set_dest, 0);
4456 dest2 = gen_df_reg (set_dest, 1);
4457 srca1 = gen_df_reg (set_srca, 0);
4458 srca2 = gen_df_reg (set_srca, 1);
4459 srcb1 = gen_df_reg (set_srcb, 0);
4460 srcb2 = gen_df_reg (set_srcb, 1);
4462 /* Now emit using the real source and destination we found, swapping
4463 the order if we detect overlap. */
4464 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4465 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4467 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4468 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4472 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4473 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4479 ;;- zero extension instructions
4481 ;; These patterns originally accepted general_operands, however, slightly
4482 ;; better code is generated by only accepting register_operands, and then
4483 ;; letting combine generate the ldu[hb] insns.
4485 (define_expand "zero_extendhisi2"
4486 [(set (match_operand:SI 0 "register_operand" "")
4487 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4491 rtx temp = gen_reg_rtx (SImode);
4492 rtx shift_16 = GEN_INT (16);
4493 int op1_subbyte = 0;
4495 if (GET_CODE (operand1) == SUBREG)
4497 op1_subbyte = SUBREG_BYTE (operand1);
4498 op1_subbyte /= GET_MODE_SIZE (SImode);
4499 op1_subbyte *= GET_MODE_SIZE (SImode);
4500 operand1 = XEXP (operand1, 0);
4503 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4505 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4509 (define_insn "*zero_extendhisi2_insn"
4510 [(set (match_operand:SI 0 "register_operand" "=r")
4511 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4514 [(set_attr "type" "load")])
4516 (define_expand "zero_extendqihi2"
4517 [(set (match_operand:HI 0 "register_operand" "")
4518 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4522 (define_insn "*zero_extendqihi2_insn"
4523 [(set (match_operand:HI 0 "register_operand" "=r,r")
4524 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4525 "GET_CODE (operands[1]) != CONST_INT"
4529 [(set_attr "type" "*,load")])
4531 (define_expand "zero_extendqisi2"
4532 [(set (match_operand:SI 0 "register_operand" "")
4533 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4537 (define_insn "*zero_extendqisi2_insn"
4538 [(set (match_operand:SI 0 "register_operand" "=r,r")
4539 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4540 "GET_CODE (operands[1]) != CONST_INT"
4544 [(set_attr "type" "*,load")])
4546 (define_expand "zero_extendqidi2"
4547 [(set (match_operand:DI 0 "register_operand" "")
4548 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4552 (define_insn "*zero_extendqidi2_insn"
4553 [(set (match_operand:DI 0 "register_operand" "=r,r")
4554 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4555 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4559 [(set_attr "type" "*,load")])
4561 (define_expand "zero_extendhidi2"
4562 [(set (match_operand:DI 0 "register_operand" "")
4563 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4567 rtx temp = gen_reg_rtx (DImode);
4568 rtx shift_48 = GEN_INT (48);
4569 int op1_subbyte = 0;
4571 if (GET_CODE (operand1) == SUBREG)
4573 op1_subbyte = SUBREG_BYTE (operand1);
4574 op1_subbyte /= GET_MODE_SIZE (DImode);
4575 op1_subbyte *= GET_MODE_SIZE (DImode);
4576 operand1 = XEXP (operand1, 0);
4579 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4581 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4585 (define_insn "*zero_extendhidi2_insn"
4586 [(set (match_operand:DI 0 "register_operand" "=r")
4587 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4590 [(set_attr "type" "load")])
4593 ;; ??? Write truncdisi pattern using sra?
4595 (define_expand "zero_extendsidi2"
4596 [(set (match_operand:DI 0 "register_operand" "")
4597 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4601 (define_insn "*zero_extendsidi2_insn_sp64"
4602 [(set (match_operand:DI 0 "register_operand" "=r,r")
4603 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4604 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4608 [(set_attr "type" "shift,load")])
4610 (define_insn "*zero_extendsidi2_insn_sp32"
4611 [(set (match_operand:DI 0 "register_operand" "=r")
4612 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4615 [(set_attr "length" "2")])
4618 [(set (match_operand:DI 0 "register_operand" "")
4619 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4620 "! TARGET_ARCH64 && reload_completed"
4621 [(set (match_dup 2) (match_dup 3))
4622 (set (match_dup 4) (match_dup 5))]
4627 dest1 = gen_highpart (SImode, operands[0]);
4628 dest2 = gen_lowpart (SImode, operands[0]);
4630 /* Swap the order in case of overlap. */
4631 if (REGNO (dest1) == REGNO (operands[1]))
4633 operands[2] = dest2;
4634 operands[3] = operands[1];
4635 operands[4] = dest1;
4636 operands[5] = const0_rtx;
4640 operands[2] = dest1;
4641 operands[3] = const0_rtx;
4642 operands[4] = dest2;
4643 operands[5] = operands[1];
4647 ;; Simplify comparisons of extended values.
4649 (define_insn "*cmp_zero_extendqisi2"
4651 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4654 "andcc\\t%0, 0xff, %%g0"
4655 [(set_attr "type" "compare")])
4657 (define_insn "*cmp_zero_qi"
4659 (compare:CC (match_operand:QI 0 "register_operand" "r")
4662 "andcc\\t%0, 0xff, %%g0"
4663 [(set_attr "type" "compare")])
4665 (define_insn "*cmp_zero_extendqisi2_set"
4667 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4669 (set (match_operand:SI 0 "register_operand" "=r")
4670 (zero_extend:SI (match_dup 1)))]
4672 "andcc\\t%1, 0xff, %0"
4673 [(set_attr "type" "compare")])
4675 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4677 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4680 (set (match_operand:SI 0 "register_operand" "=r")
4681 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4683 "andcc\\t%1, 0xff, %0"
4684 [(set_attr "type" "compare")])
4686 (define_insn "*cmp_zero_extendqidi2"
4688 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4691 "andcc\\t%0, 0xff, %%g0"
4692 [(set_attr "type" "compare")])
4694 (define_insn "*cmp_zero_qi_sp64"
4696 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4699 "andcc\\t%0, 0xff, %%g0"
4700 [(set_attr "type" "compare")])
4702 (define_insn "*cmp_zero_extendqidi2_set"
4704 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4706 (set (match_operand:DI 0 "register_operand" "=r")
4707 (zero_extend:DI (match_dup 1)))]
4709 "andcc\\t%1, 0xff, %0"
4710 [(set_attr "type" "compare")])
4712 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4714 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4717 (set (match_operand:DI 0 "register_operand" "=r")
4718 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4720 "andcc\\t%1, 0xff, %0"
4721 [(set_attr "type" "compare")])
4723 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4725 (define_insn "*cmp_siqi_trunc"
4727 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4730 "andcc\\t%0, 0xff, %%g0"
4731 [(set_attr "type" "compare")])
4733 (define_insn "*cmp_siqi_trunc_set"
4735 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4737 (set (match_operand:QI 0 "register_operand" "=r")
4738 (subreg:QI (match_dup 1) 3))]
4740 "andcc\\t%1, 0xff, %0"
4741 [(set_attr "type" "compare")])
4743 (define_insn "*cmp_diqi_trunc"
4745 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4748 "andcc\\t%0, 0xff, %%g0"
4749 [(set_attr "type" "compare")])
4751 (define_insn "*cmp_diqi_trunc_set"
4753 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4755 (set (match_operand:QI 0 "register_operand" "=r")
4756 (subreg:QI (match_dup 1) 7))]
4758 "andcc\\t%1, 0xff, %0"
4759 [(set_attr "type" "compare")])
4761 ;;- sign extension instructions
4763 ;; These patterns originally accepted general_operands, however, slightly
4764 ;; better code is generated by only accepting register_operands, and then
4765 ;; letting combine generate the lds[hb] insns.
4767 (define_expand "extendhisi2"
4768 [(set (match_operand:SI 0 "register_operand" "")
4769 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4773 rtx temp = gen_reg_rtx (SImode);
4774 rtx shift_16 = GEN_INT (16);
4775 int op1_subbyte = 0;
4777 if (GET_CODE (operand1) == SUBREG)
4779 op1_subbyte = SUBREG_BYTE (operand1);
4780 op1_subbyte /= GET_MODE_SIZE (SImode);
4781 op1_subbyte *= GET_MODE_SIZE (SImode);
4782 operand1 = XEXP (operand1, 0);
4785 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4787 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4791 (define_insn "*sign_extendhisi2_insn"
4792 [(set (match_operand:SI 0 "register_operand" "=r")
4793 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4796 [(set_attr "type" "sload")])
4798 (define_expand "extendqihi2"
4799 [(set (match_operand:HI 0 "register_operand" "")
4800 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4804 rtx temp = gen_reg_rtx (SImode);
4805 rtx shift_24 = GEN_INT (24);
4806 int op1_subbyte = 0;
4807 int op0_subbyte = 0;
4809 if (GET_CODE (operand1) == SUBREG)
4811 op1_subbyte = SUBREG_BYTE (operand1);
4812 op1_subbyte /= GET_MODE_SIZE (SImode);
4813 op1_subbyte *= GET_MODE_SIZE (SImode);
4814 operand1 = XEXP (operand1, 0);
4816 if (GET_CODE (operand0) == SUBREG)
4818 op0_subbyte = SUBREG_BYTE (operand0);
4819 op0_subbyte /= GET_MODE_SIZE (SImode);
4820 op0_subbyte *= GET_MODE_SIZE (SImode);
4821 operand0 = XEXP (operand0, 0);
4823 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4825 if (GET_MODE (operand0) != SImode)
4826 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4827 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4831 (define_insn "*sign_extendqihi2_insn"
4832 [(set (match_operand:HI 0 "register_operand" "=r")
4833 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4836 [(set_attr "type" "sload")])
4838 (define_expand "extendqisi2"
4839 [(set (match_operand:SI 0 "register_operand" "")
4840 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4844 rtx temp = gen_reg_rtx (SImode);
4845 rtx shift_24 = GEN_INT (24);
4846 int op1_subbyte = 0;
4848 if (GET_CODE (operand1) == SUBREG)
4850 op1_subbyte = SUBREG_BYTE (operand1);
4851 op1_subbyte /= GET_MODE_SIZE (SImode);
4852 op1_subbyte *= GET_MODE_SIZE (SImode);
4853 operand1 = XEXP (operand1, 0);
4856 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4858 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4862 (define_insn "*sign_extendqisi2_insn"
4863 [(set (match_operand:SI 0 "register_operand" "=r")
4864 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4867 [(set_attr "type" "sload")])
4869 (define_expand "extendqidi2"
4870 [(set (match_operand:DI 0 "register_operand" "")
4871 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4875 rtx temp = gen_reg_rtx (DImode);
4876 rtx shift_56 = GEN_INT (56);
4877 int op1_subbyte = 0;
4879 if (GET_CODE (operand1) == SUBREG)
4881 op1_subbyte = SUBREG_BYTE (operand1);
4882 op1_subbyte /= GET_MODE_SIZE (DImode);
4883 op1_subbyte *= GET_MODE_SIZE (DImode);
4884 operand1 = XEXP (operand1, 0);
4887 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4889 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4893 (define_insn "*sign_extendqidi2_insn"
4894 [(set (match_operand:DI 0 "register_operand" "=r")
4895 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4898 [(set_attr "type" "sload")])
4900 (define_expand "extendhidi2"
4901 [(set (match_operand:DI 0 "register_operand" "")
4902 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4906 rtx temp = gen_reg_rtx (DImode);
4907 rtx shift_48 = GEN_INT (48);
4908 int op1_subbyte = 0;
4910 if (GET_CODE (operand1) == SUBREG)
4912 op1_subbyte = SUBREG_BYTE (operand1);
4913 op1_subbyte /= GET_MODE_SIZE (DImode);
4914 op1_subbyte *= GET_MODE_SIZE (DImode);
4915 operand1 = XEXP (operand1, 0);
4918 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4920 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4924 (define_insn "*sign_extendhidi2_insn"
4925 [(set (match_operand:DI 0 "register_operand" "=r")
4926 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4929 [(set_attr "type" "sload")])
4931 (define_expand "extendsidi2"
4932 [(set (match_operand:DI 0 "register_operand" "")
4933 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4937 (define_insn "*sign_extendsidi2_insn"
4938 [(set (match_operand:DI 0 "register_operand" "=r,r")
4939 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4944 [(set_attr "type" "shift,sload")])
4946 ;; Special pattern for optimizing bit-field compares. This is needed
4947 ;; because combine uses this as a canonical form.
4949 (define_insn "*cmp_zero_extract"
4952 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4953 (match_operand:SI 1 "small_int_or_double" "n")
4954 (match_operand:SI 2 "small_int_or_double" "n"))
4956 "(GET_CODE (operands[2]) == CONST_INT
4957 && INTVAL (operands[2]) > 19)
4958 || (GET_CODE (operands[2]) == CONST_DOUBLE
4959 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4962 int len = (GET_CODE (operands[1]) == CONST_INT
4963 ? INTVAL (operands[1])
4964 : CONST_DOUBLE_LOW (operands[1]));
4966 (GET_CODE (operands[2]) == CONST_INT
4967 ? INTVAL (operands[2])
4968 : CONST_DOUBLE_LOW (operands[2])) - len;
4969 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4971 operands[1] = GEN_INT (mask);
4972 return \"andcc\\t%0, %1, %%g0\";
4974 [(set_attr "type" "compare")])
4976 (define_insn "*cmp_zero_extract_sp64"
4979 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4980 (match_operand:SI 1 "small_int_or_double" "n")
4981 (match_operand:SI 2 "small_int_or_double" "n"))
4984 && ((GET_CODE (operands[2]) == CONST_INT
4985 && INTVAL (operands[2]) > 51)
4986 || (GET_CODE (operands[2]) == CONST_DOUBLE
4987 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4990 int len = (GET_CODE (operands[1]) == CONST_INT
4991 ? INTVAL (operands[1])
4992 : CONST_DOUBLE_LOW (operands[1]));
4994 (GET_CODE (operands[2]) == CONST_INT
4995 ? INTVAL (operands[2])
4996 : CONST_DOUBLE_LOW (operands[2])) - len;
4997 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4999 operands[1] = GEN_INT (mask);
5000 return \"andcc\\t%0, %1, %%g0\";
5002 [(set_attr "type" "compare")])
5004 ;; Conversions between float, double and long double.
5006 (define_insn "extendsfdf2"
5007 [(set (match_operand:DF 0 "register_operand" "=e")
5009 (match_operand:SF 1 "register_operand" "f")))]
5012 [(set_attr "type" "fp")
5013 (set_attr "fptype" "double")])
5015 (define_expand "extendsftf2"
5016 [(set (match_operand:TF 0 "register_operand" "=e")
5018 (match_operand:SF 1 "register_operand" "f")))]
5019 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5022 if (! TARGET_HARD_QUAD)
5026 if (GET_CODE (operands[0]) != MEM)
5027 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5029 slot0 = operands[0];
5031 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5033 XEXP (slot0, 0), Pmode,
5034 operands[1], SFmode);
5036 if (GET_CODE (operands[0]) != MEM)
5037 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5042 (define_insn "*extendsftf2_hq"
5043 [(set (match_operand:TF 0 "register_operand" "=e")
5045 (match_operand:SF 1 "register_operand" "f")))]
5046 "TARGET_FPU && TARGET_HARD_QUAD"
5048 [(set_attr "type" "fp")])
5050 (define_expand "extenddftf2"
5051 [(set (match_operand:TF 0 "register_operand" "=e")
5053 (match_operand:DF 1 "register_operand" "e")))]
5054 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5057 if (! TARGET_HARD_QUAD)
5061 if (GET_CODE (operands[0]) != MEM)
5062 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5064 slot0 = operands[0];
5066 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5068 XEXP (slot0, 0), Pmode,
5069 operands[1], DFmode);
5071 if (GET_CODE (operands[0]) != MEM)
5072 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5077 (define_insn "*extenddftf2_hq"
5078 [(set (match_operand:TF 0 "register_operand" "=e")
5080 (match_operand:DF 1 "register_operand" "e")))]
5081 "TARGET_FPU && TARGET_HARD_QUAD"
5083 [(set_attr "type" "fp")])
5085 (define_insn "truncdfsf2"
5086 [(set (match_operand:SF 0 "register_operand" "=f")
5088 (match_operand:DF 1 "register_operand" "e")))]
5091 [(set_attr "type" "fp")
5092 (set_attr "fptype" "double")])
5094 (define_expand "trunctfsf2"
5095 [(set (match_operand:SF 0 "register_operand" "=f")
5097 (match_operand:TF 1 "register_operand" "e")))]
5098 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5101 if (! TARGET_HARD_QUAD)
5105 if (GET_CODE (operands[1]) != MEM)
5107 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5108 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5111 slot0 = operands[1];
5113 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5114 operands[0], 0, SFmode, 1,
5115 XEXP (slot0, 0), Pmode);
5120 (define_insn "*trunctfsf2_hq"
5121 [(set (match_operand:SF 0 "register_operand" "=f")
5123 (match_operand:TF 1 "register_operand" "e")))]
5124 "TARGET_FPU && TARGET_HARD_QUAD"
5126 [(set_attr "type" "fp")])
5128 (define_expand "trunctfdf2"
5129 [(set (match_operand:DF 0 "register_operand" "=f")
5131 (match_operand:TF 1 "register_operand" "e")))]
5132 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5135 if (! TARGET_HARD_QUAD)
5139 if (GET_CODE (operands[1]) != MEM)
5141 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5142 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5145 slot0 = operands[1];
5147 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5148 operands[0], 0, DFmode, 1,
5149 XEXP (slot0, 0), Pmode);
5154 (define_insn "*trunctfdf2_hq"
5155 [(set (match_operand:DF 0 "register_operand" "=e")
5157 (match_operand:TF 1 "register_operand" "e")))]
5158 "TARGET_FPU && TARGET_HARD_QUAD"
5160 [(set_attr "type" "fp")])
5162 ;; Conversion between fixed point and floating point.
5164 (define_insn "floatsisf2"
5165 [(set (match_operand:SF 0 "register_operand" "=f")
5166 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5169 [(set_attr "type" "fp")
5170 (set_attr "fptype" "double")])
5172 (define_insn "floatsidf2"
5173 [(set (match_operand:DF 0 "register_operand" "=e")
5174 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5177 [(set_attr "type" "fp")
5178 (set_attr "fptype" "double")])
5180 (define_expand "floatsitf2"
5181 [(set (match_operand:TF 0 "register_operand" "=e")
5182 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5183 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5186 if (! TARGET_HARD_QUAD)
5190 if (GET_CODE (operands[1]) != MEM)
5191 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5193 slot0 = operands[1];
5195 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5197 XEXP (slot0, 0), Pmode,
5198 operands[1], SImode);
5200 if (GET_CODE (operands[0]) != MEM)
5201 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5206 (define_insn "*floatsitf2_hq"
5207 [(set (match_operand:TF 0 "register_operand" "=e")
5208 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5209 "TARGET_FPU && TARGET_HARD_QUAD"
5211 [(set_attr "type" "fp")])
5213 (define_expand "floatunssitf2"
5214 [(set (match_operand:TF 0 "register_operand" "=e")
5215 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5216 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5221 if (GET_CODE (operands[1]) != MEM)
5222 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5224 slot0 = operands[1];
5226 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5228 XEXP (slot0, 0), Pmode,
5229 operands[1], SImode);
5231 if (GET_CODE (operands[0]) != MEM)
5232 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5236 ;; Now the same for 64 bit sources.
5238 (define_insn "floatdisf2"
5239 [(set (match_operand:SF 0 "register_operand" "=f")
5240 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5241 "TARGET_V9 && TARGET_FPU"
5243 [(set_attr "type" "fp")
5244 (set_attr "fptype" "double")])
5246 (define_expand "floatunsdisf2"
5247 [(use (match_operand:SF 0 "register_operand" ""))
5248 (use (match_operand:DI 1 "register_operand" ""))]
5249 "TARGET_ARCH64 && TARGET_FPU"
5250 "sparc_emit_floatunsdi (operands); DONE;")
5252 (define_insn "floatdidf2"
5253 [(set (match_operand:DF 0 "register_operand" "=e")
5254 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5255 "TARGET_V9 && TARGET_FPU"
5257 [(set_attr "type" "fp")
5258 (set_attr "fptype" "double")])
5260 (define_expand "floatunsdidf2"
5261 [(use (match_operand:DF 0 "register_operand" ""))
5262 (use (match_operand:DI 1 "register_operand" ""))]
5263 "TARGET_ARCH64 && TARGET_FPU"
5264 "sparc_emit_floatunsdi (operands); DONE;")
5266 (define_expand "floatditf2"
5267 [(set (match_operand:TF 0 "register_operand" "=e")
5268 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5269 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5272 if (! TARGET_HARD_QUAD)
5276 if (GET_CODE (operands[1]) != MEM)
5277 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5279 slot0 = operands[1];
5281 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5283 XEXP (slot0, 0), Pmode,
5284 operands[1], DImode);
5286 if (GET_CODE (operands[0]) != MEM)
5287 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5292 (define_insn "*floatditf2_hq"
5293 [(set (match_operand:TF 0 "register_operand" "=e")
5294 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5295 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5297 [(set_attr "type" "fp")])
5299 (define_expand "floatunsditf2"
5300 [(set (match_operand:TF 0 "register_operand" "=e")
5301 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5302 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5307 if (GET_CODE (operands[1]) != MEM)
5308 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5310 slot0 = operands[1];
5312 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5314 XEXP (slot0, 0), Pmode,
5315 operands[1], DImode);
5317 if (GET_CODE (operands[0]) != MEM)
5318 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5322 ;; Convert a float to an actual integer.
5323 ;; Truncation is performed as part of the conversion.
5325 (define_insn "fix_truncsfsi2"
5326 [(set (match_operand:SI 0 "register_operand" "=f")
5327 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5330 [(set_attr "type" "fp")
5331 (set_attr "fptype" "double")])
5333 (define_insn "fix_truncdfsi2"
5334 [(set (match_operand:SI 0 "register_operand" "=f")
5335 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5338 [(set_attr "type" "fp")
5339 (set_attr "fptype" "double")])
5341 (define_expand "fix_trunctfsi2"
5342 [(set (match_operand:SI 0 "register_operand" "=f")
5343 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5344 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5347 if (! TARGET_HARD_QUAD)
5351 if (GET_CODE (operands[1]) != MEM)
5353 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5354 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5357 slot0 = operands[1];
5359 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5360 operands[0], 0, SImode, 1,
5361 XEXP (slot0, 0), Pmode);
5366 (define_insn "*fix_trunctfsi2_hq"
5367 [(set (match_operand:SI 0 "register_operand" "=f")
5368 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5369 "TARGET_FPU && TARGET_HARD_QUAD"
5371 [(set_attr "type" "fp")])
5373 (define_expand "fixuns_trunctfsi2"
5374 [(set (match_operand:SI 0 "register_operand" "=f")
5375 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5376 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5381 if (GET_CODE (operands[1]) != MEM)
5383 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5384 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5387 slot0 = operands[1];
5389 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5390 operands[0], 0, SImode, 1,
5391 XEXP (slot0, 0), Pmode);
5395 ;; Now the same, for V9 targets
5397 (define_insn "fix_truncsfdi2"
5398 [(set (match_operand:DI 0 "register_operand" "=e")
5399 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5400 "TARGET_V9 && TARGET_FPU"
5402 [(set_attr "type" "fp")
5403 (set_attr "fptype" "double")])
5405 (define_insn "fix_truncdfdi2"
5406 [(set (match_operand:DI 0 "register_operand" "=e")
5407 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5408 "TARGET_V9 && TARGET_FPU"
5410 [(set_attr "type" "fp")
5411 (set_attr "fptype" "double")])
5413 (define_expand "fix_trunctfdi2"
5414 [(set (match_operand:DI 0 "register_operand" "=e")
5415 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5416 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5419 if (! TARGET_HARD_QUAD)
5423 if (GET_CODE (operands[1]) != MEM)
5425 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5426 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5429 slot0 = operands[1];
5431 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5432 operands[0], 0, DImode, 1,
5433 XEXP (slot0, 0), Pmode);
5438 (define_insn "*fix_trunctfdi2_hq"
5439 [(set (match_operand:DI 0 "register_operand" "=e")
5440 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5441 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5443 [(set_attr "type" "fp")])
5445 (define_expand "fixuns_trunctfdi2"
5446 [(set (match_operand:DI 0 "register_operand" "=f")
5447 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5448 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5453 if (GET_CODE (operands[1]) != MEM)
5455 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5456 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5459 slot0 = operands[1];
5461 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5462 operands[0], 0, DImode, 1,
5463 XEXP (slot0, 0), Pmode);
5468 ;;- arithmetic instructions
5470 (define_expand "adddi3"
5471 [(set (match_operand:DI 0 "register_operand" "=r")
5472 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5473 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5479 if (! TARGET_ARCH64)
5481 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5482 gen_rtx_SET (VOIDmode, operands[0],
5483 gen_rtx_PLUS (DImode, operands[1],
5485 gen_rtx_CLOBBER (VOIDmode,
5486 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5489 if (arith_double_4096_operand(operands[2], DImode))
5491 switch (GET_CODE (operands[1]))
5493 case CONST_INT: i = INTVAL (operands[1]); break;
5494 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5496 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5497 gen_rtx_MINUS (DImode, operands[1],
5501 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5506 (define_insn "adddi3_insn_sp32"
5507 [(set (match_operand:DI 0 "register_operand" "=r")
5508 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5509 (match_operand:DI 2 "arith_double_operand" "rHI")))
5510 (clobber (reg:CC 100))]
5513 [(set_attr "length" "2")])
5516 [(set (match_operand:DI 0 "register_operand" "")
5517 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5518 (match_operand:DI 2 "arith_double_operand" "")))
5519 (clobber (reg:CC 100))]
5520 "! TARGET_ARCH64 && reload_completed"
5521 [(parallel [(set (reg:CC_NOOV 100)
5522 (compare:CC_NOOV (plus:SI (match_dup 4)
5526 (plus:SI (match_dup 4) (match_dup 5)))])
5528 (plus:SI (plus:SI (match_dup 7)
5530 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5533 operands[3] = gen_lowpart (SImode, operands[0]);
5534 operands[4] = gen_lowpart (SImode, operands[1]);
5535 operands[5] = gen_lowpart (SImode, operands[2]);
5536 operands[6] = gen_highpart (SImode, operands[0]);
5537 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5538 #if HOST_BITS_PER_WIDE_INT == 32
5539 if (GET_CODE (operands[2]) == CONST_INT)
5541 if (INTVAL (operands[2]) < 0)
5542 operands[8] = constm1_rtx;
5544 operands[8] = const0_rtx;
5548 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5552 [(set (match_operand:DI 0 "register_operand" "")
5553 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5554 (match_operand:DI 2 "arith_double_operand" "")))
5555 (clobber (reg:CC 100))]
5556 "! TARGET_ARCH64 && reload_completed"
5557 [(parallel [(set (reg:CC_NOOV 100)
5558 (compare:CC_NOOV (minus:SI (match_dup 4)
5562 (minus:SI (match_dup 4) (match_dup 5)))])
5564 (minus:SI (minus:SI (match_dup 7)
5566 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5569 operands[3] = gen_lowpart (SImode, operands[0]);
5570 operands[4] = gen_lowpart (SImode, operands[1]);
5571 operands[5] = gen_lowpart (SImode, operands[2]);
5572 operands[6] = gen_highpart (SImode, operands[0]);
5573 operands[7] = gen_highpart (SImode, operands[1]);
5574 #if HOST_BITS_PER_WIDE_INT == 32
5575 if (GET_CODE (operands[2]) == CONST_INT)
5577 if (INTVAL (operands[2]) < 0)
5578 operands[8] = constm1_rtx;
5580 operands[8] = const0_rtx;
5584 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5587 ;; LTU here means "carry set"
5589 [(set (match_operand:SI 0 "register_operand" "=r")
5590 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5591 (match_operand:SI 2 "arith_operand" "rI"))
5592 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5595 [(set_attr "type" "misc")])
5597 (define_insn "*addx_extend_sp32"
5598 [(set (match_operand:DI 0 "register_operand" "=r")
5599 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5600 (match_operand:SI 2 "arith_operand" "rI"))
5601 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5604 [(set_attr "length" "2")])
5607 [(set (match_operand:DI 0 "register_operand" "")
5608 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5609 (match_operand:SI 2 "arith_operand" ""))
5610 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5611 "! TARGET_ARCH64 && reload_completed"
5612 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5613 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5614 (set (match_dup 4) (const_int 0))]
5615 "operands[3] = gen_lowpart (SImode, operands[0]);
5616 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5618 (define_insn "*addx_extend_sp64"
5619 [(set (match_operand:DI 0 "register_operand" "=r")
5620 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5621 (match_operand:SI 2 "arith_operand" "rI"))
5622 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5624 "addx\\t%r1, %2, %0"
5625 [(set_attr "type" "misc")])
5628 [(set (match_operand:SI 0 "register_operand" "=r")
5629 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5630 (match_operand:SI 2 "arith_operand" "rI"))
5631 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5633 "subx\\t%r1, %2, %0"
5634 [(set_attr "type" "misc")])
5636 (define_insn "*subx_extend_sp64"
5637 [(set (match_operand:DI 0 "register_operand" "=r")
5638 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5639 (match_operand:SI 2 "arith_operand" "rI"))
5640 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5642 "subx\\t%r1, %2, %0"
5643 [(set_attr "type" "misc")])
5645 (define_insn "*subx_extend"
5646 [(set (match_operand:DI 0 "register_operand" "=r")
5647 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5648 (match_operand:SI 2 "arith_operand" "rI"))
5649 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5652 [(set_attr "length" "2")])
5655 [(set (match_operand:DI 0 "register_operand" "")
5656 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5657 (match_operand:SI 2 "arith_operand" ""))
5658 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5659 "! TARGET_ARCH64 && reload_completed"
5660 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5661 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5662 (set (match_dup 4) (const_int 0))]
5663 "operands[3] = gen_lowpart (SImode, operands[0]);
5664 operands[4] = gen_highpart (SImode, operands[0]);")
5667 [(set (match_operand:DI 0 "register_operand" "=r")
5668 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5669 (match_operand:DI 2 "register_operand" "r")))
5670 (clobber (reg:CC 100))]
5673 [(set_attr "length" "2")])
5676 [(set (match_operand:DI 0 "register_operand" "")
5677 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5678 (match_operand:DI 2 "register_operand" "")))
5679 (clobber (reg:CC 100))]
5680 "! TARGET_ARCH64 && reload_completed"
5681 [(parallel [(set (reg:CC_NOOV 100)
5682 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5684 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5686 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5687 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5688 "operands[3] = gen_lowpart (SImode, operands[2]);
5689 operands[4] = gen_highpart (SImode, operands[2]);
5690 operands[5] = gen_lowpart (SImode, operands[0]);
5691 operands[6] = gen_highpart (SImode, operands[0]);")
5693 (define_insn "*adddi3_sp64"
5694 [(set (match_operand:DI 0 "register_operand" "=r")
5695 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5696 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5700 (define_expand "addsi3"
5701 [(set (match_operand:SI 0 "register_operand" "=r,d")
5702 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5703 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5707 if (arith_4096_operand(operands[2], SImode))
5709 if (GET_CODE (operands[1]) == CONST_INT)
5710 emit_insn (gen_movsi (operands[0],
5711 GEN_INT (INTVAL (operands[1]) + 4096)));
5713 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5714 gen_rtx_MINUS (SImode, operands[1],
5720 (define_insn "*addsi3"
5721 [(set (match_operand:SI 0 "register_operand" "=r,d")
5722 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5723 (match_operand:SI 2 "arith_operand" "rI,d")))]
5727 fpadd32s\\t%1, %2, %0"
5728 [(set_attr "type" "*,fp")])
5730 (define_insn "*cmp_cc_plus"
5731 [(set (reg:CC_NOOV 100)
5732 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5733 (match_operand:SI 1 "arith_operand" "rI"))
5736 "addcc\\t%0, %1, %%g0"
5737 [(set_attr "type" "compare")])
5739 (define_insn "*cmp_ccx_plus"
5740 [(set (reg:CCX_NOOV 100)
5741 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5742 (match_operand:DI 1 "arith_double_operand" "rHI"))
5745 "addcc\\t%0, %1, %%g0"
5746 [(set_attr "type" "compare")])
5748 (define_insn "*cmp_cc_plus_set"
5749 [(set (reg:CC_NOOV 100)
5750 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5751 (match_operand:SI 2 "arith_operand" "rI"))
5753 (set (match_operand:SI 0 "register_operand" "=r")
5754 (plus:SI (match_dup 1) (match_dup 2)))]
5756 "addcc\\t%1, %2, %0"
5757 [(set_attr "type" "compare")])
5759 (define_insn "*cmp_ccx_plus_set"
5760 [(set (reg:CCX_NOOV 100)
5761 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5762 (match_operand:DI 2 "arith_double_operand" "rHI"))
5764 (set (match_operand:DI 0 "register_operand" "=r")
5765 (plus:DI (match_dup 1) (match_dup 2)))]
5767 "addcc\\t%1, %2, %0"
5768 [(set_attr "type" "compare")])
5770 (define_expand "subdi3"
5771 [(set (match_operand:DI 0 "register_operand" "=r")
5772 (minus:DI (match_operand:DI 1 "register_operand" "r")
5773 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5777 if (! TARGET_ARCH64)
5779 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5780 gen_rtx_SET (VOIDmode, operands[0],
5781 gen_rtx_MINUS (DImode, operands[1],
5783 gen_rtx_CLOBBER (VOIDmode,
5784 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5787 if (arith_double_4096_operand(operands[2], DImode))
5789 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5790 gen_rtx_PLUS (DImode, operands[1],
5796 (define_insn "*subdi3_sp32"
5797 [(set (match_operand:DI 0 "register_operand" "=r")
5798 (minus:DI (match_operand:DI 1 "register_operand" "r")
5799 (match_operand:DI 2 "arith_double_operand" "rHI")))
5800 (clobber (reg:CC 100))]
5803 [(set_attr "length" "2")])
5806 [(set (match_operand:DI 0 "register_operand" "")
5807 (minus:DI (match_operand:DI 1 "register_operand" "")
5808 (match_operand:DI 2 "arith_double_operand" "")))
5809 (clobber (reg:CC 100))]
5812 && (GET_CODE (operands[2]) == CONST_INT
5813 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5814 [(clobber (const_int 0))]
5819 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5820 lowp = gen_lowpart (SImode, operands[2]);
5821 if ((lowp == const0_rtx)
5822 && (operands[0] == operands[1]))
5824 emit_insn (gen_rtx_SET (VOIDmode,
5825 gen_highpart (SImode, operands[0]),
5826 gen_rtx_MINUS (SImode,
5827 gen_highpart_mode (SImode, DImode,
5833 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5834 gen_lowpart (SImode, operands[1]),
5836 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5837 gen_highpart_mode (SImode, DImode, operands[1]),
5844 [(set (match_operand:DI 0 "register_operand" "")
5845 (minus:DI (match_operand:DI 1 "register_operand" "")
5846 (match_operand:DI 2 "register_operand" "")))
5847 (clobber (reg:CC 100))]
5849 && reload_completed"
5850 [(clobber (const_int 0))]
5853 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5854 gen_lowpart (SImode, operands[1]),
5855 gen_lowpart (SImode, operands[2])));
5856 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5857 gen_highpart (SImode, operands[1]),
5858 gen_highpart (SImode, operands[2])));
5863 [(set (match_operand:DI 0 "register_operand" "=r")
5864 (minus:DI (match_operand:DI 1 "register_operand" "r")
5865 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5866 (clobber (reg:CC 100))]
5869 [(set_attr "length" "2")])
5872 [(set (match_operand:DI 0 "register_operand" "")
5873 (minus:DI (match_operand:DI 1 "register_operand" "")
5874 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5875 (clobber (reg:CC 100))]
5876 "! TARGET_ARCH64 && reload_completed"
5877 [(parallel [(set (reg:CC_NOOV 100)
5878 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5880 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5882 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5883 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5884 "operands[3] = gen_lowpart (SImode, operands[1]);
5885 operands[4] = gen_highpart (SImode, operands[1]);
5886 operands[5] = gen_lowpart (SImode, operands[0]);
5887 operands[6] = gen_highpart (SImode, operands[0]);")
5889 (define_insn "*subdi3_sp64"
5890 [(set (match_operand:DI 0 "register_operand" "=r")
5891 (minus:DI (match_operand:DI 1 "register_operand" "r")
5892 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5896 (define_expand "subsi3"
5897 [(set (match_operand:SI 0 "register_operand" "=r,d")
5898 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5899 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5903 if (arith_4096_operand(operands[2], SImode))
5905 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5906 gen_rtx_PLUS (SImode, operands[1],
5912 (define_insn "*subsi3"
5913 [(set (match_operand:SI 0 "register_operand" "=r,d")
5914 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5915 (match_operand:SI 2 "arith_operand" "rI,d")))]
5919 fpsub32s\\t%1, %2, %0"
5920 [(set_attr "type" "*,fp")])
5922 (define_insn "*cmp_minus_cc"
5923 [(set (reg:CC_NOOV 100)
5924 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5925 (match_operand:SI 1 "arith_operand" "rI"))
5928 "subcc\\t%r0, %1, %%g0"
5929 [(set_attr "type" "compare")])
5931 (define_insn "*cmp_minus_ccx"
5932 [(set (reg:CCX_NOOV 100)
5933 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5934 (match_operand:DI 1 "arith_double_operand" "rHI"))
5937 "subcc\\t%0, %1, %%g0"
5938 [(set_attr "type" "compare")])
5940 (define_insn "cmp_minus_cc_set"
5941 [(set (reg:CC_NOOV 100)
5942 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5943 (match_operand:SI 2 "arith_operand" "rI"))
5945 (set (match_operand:SI 0 "register_operand" "=r")
5946 (minus:SI (match_dup 1) (match_dup 2)))]
5948 "subcc\\t%r1, %2, %0"
5949 [(set_attr "type" "compare")])
5951 (define_insn "*cmp_minus_ccx_set"
5952 [(set (reg:CCX_NOOV 100)
5953 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5954 (match_operand:DI 2 "arith_double_operand" "rHI"))
5956 (set (match_operand:DI 0 "register_operand" "=r")
5957 (minus:DI (match_dup 1) (match_dup 2)))]
5959 "subcc\\t%1, %2, %0"
5960 [(set_attr "type" "compare")])
5962 ;; Integer Multiply/Divide.
5964 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5965 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5967 (define_insn "mulsi3"
5968 [(set (match_operand:SI 0 "register_operand" "=r")
5969 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5970 (match_operand:SI 2 "arith_operand" "rI")))]
5973 [(set_attr "type" "imul")])
5975 (define_expand "muldi3"
5976 [(set (match_operand:DI 0 "register_operand" "=r")
5977 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5978 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5979 "TARGET_ARCH64 || TARGET_V8PLUS"
5984 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5989 (define_insn "*muldi3_sp64"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5991 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5992 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5995 [(set_attr "type" "imul")])
5997 ;; V8plus wide multiply.
5999 (define_insn "muldi3_v8plus"
6000 [(set (match_operand:DI 0 "register_operand" "=r,h")
6001 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6002 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6003 (clobber (match_scratch:SI 3 "=&h,X"))
6004 (clobber (match_scratch:SI 4 "=&h,X"))]
6008 if (sparc_check_64 (operands[1], insn) <= 0)
6009 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6010 if (which_alternative == 1)
6011 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6012 if (GET_CODE (operands[2]) == CONST_INT)
6014 if (which_alternative == 1)
6015 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6017 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\";
6019 if (sparc_check_64 (operands[2], insn) <= 0)
6020 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6021 if (which_alternative == 1)
6022 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\";
6024 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\";
6026 [(set_attr "type" "multi")
6027 (set_attr "length" "9,8")])
6029 (define_insn "*cmp_mul_set"
6031 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6032 (match_operand:SI 2 "arith_operand" "rI"))
6034 (set (match_operand:SI 0 "register_operand" "=r")
6035 (mult:SI (match_dup 1) (match_dup 2)))]
6036 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6037 "smulcc\\t%1, %2, %0"
6038 [(set_attr "type" "imul")])
6040 (define_expand "mulsidi3"
6041 [(set (match_operand:DI 0 "register_operand" "")
6042 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6043 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6047 if (CONSTANT_P (operands[2]))
6050 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6053 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6059 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6064 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6065 ;; registers can hold 64 bit values in the V8plus environment.
6067 (define_insn "mulsidi3_v8plus"
6068 [(set (match_operand:DI 0 "register_operand" "=h,r")
6069 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6070 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6071 (clobber (match_scratch:SI 3 "=X,&h"))]
6074 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6075 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6076 [(set_attr "type" "multi")
6077 (set_attr "length" "2,3")])
6080 (define_insn "const_mulsidi3_v8plus"
6081 [(set (match_operand:DI 0 "register_operand" "=h,r")
6082 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6083 (match_operand:SI 2 "small_int" "I,I")))
6084 (clobber (match_scratch:SI 3 "=X,&h"))]
6087 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6088 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6089 [(set_attr "type" "multi")
6090 (set_attr "length" "2,3")])
6093 (define_insn "*mulsidi3_sp32"
6094 [(set (match_operand:DI 0 "register_operand" "=r")
6095 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6096 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6100 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6103 (if_then_else (eq_attr "isa" "sparclet")
6104 (const_string "imul") (const_string "multi")))
6105 (set (attr "length")
6106 (if_then_else (eq_attr "isa" "sparclet")
6107 (const_int 1) (const_int 2)))])
6109 (define_insn "*mulsidi3_sp64"
6110 [(set (match_operand:DI 0 "register_operand" "=r")
6111 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6112 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6113 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6115 [(set_attr "type" "imul")])
6117 ;; Extra pattern, because sign_extend of a constant isn't valid.
6120 (define_insn "const_mulsidi3_sp32"
6121 [(set (match_operand:DI 0 "register_operand" "=r")
6122 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6123 (match_operand:SI 2 "small_int" "I")))]
6127 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6130 (if_then_else (eq_attr "isa" "sparclet")
6131 (const_string "imul") (const_string "multi")))
6132 (set (attr "length")
6133 (if_then_else (eq_attr "isa" "sparclet")
6134 (const_int 1) (const_int 2)))])
6136 (define_insn "const_mulsidi3_sp64"
6137 [(set (match_operand:DI 0 "register_operand" "=r")
6138 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6139 (match_operand:SI 2 "small_int" "I")))]
6140 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6142 [(set_attr "type" "imul")])
6144 (define_expand "smulsi3_highpart"
6145 [(set (match_operand:SI 0 "register_operand" "")
6147 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6148 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6150 "TARGET_HARD_MUL && TARGET_ARCH32"
6153 if (CONSTANT_P (operands[2]))
6157 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6163 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6168 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6169 operands[2], GEN_INT (32)));
6175 (define_insn "smulsi3_highpart_v8plus"
6176 [(set (match_operand:SI 0 "register_operand" "=h,r")
6178 (lshiftrt:DI (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"))))
6181 (clobber (match_scratch:SI 4 "=X,&h"))]
6184 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6185 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6186 [(set_attr "type" "multi")
6187 (set_attr "length" "2")])
6189 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6192 [(set (match_operand:SI 0 "register_operand" "=h,r")
6195 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6196 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6197 (match_operand:SI 3 "const_int_operand" "i,i"))
6199 (clobber (match_scratch:SI 4 "=X,&h"))]
6202 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6203 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6204 [(set_attr "type" "multi")
6205 (set_attr "length" "2")])
6208 (define_insn "const_smulsi3_highpart_v8plus"
6209 [(set (match_operand:SI 0 "register_operand" "=h,r")
6211 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6212 (match_operand 2 "small_int" "i,i"))
6213 (match_operand:SI 3 "const_int_operand" "i,i"))))
6214 (clobber (match_scratch:SI 4 "=X,&h"))]
6217 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6218 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6219 [(set_attr "type" "multi")
6220 (set_attr "length" "2")])
6223 (define_insn "*smulsi3_highpart_sp32"
6224 [(set (match_operand:SI 0 "register_operand" "=r")
6226 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6227 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6230 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6231 [(set_attr "type" "multi")
6232 (set_attr "length" "2")])
6235 (define_insn "const_smulsi3_highpart"
6236 [(set (match_operand:SI 0 "register_operand" "=r")
6238 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6239 (match_operand:SI 2 "register_operand" "r"))
6242 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6243 [(set_attr "type" "multi")
6244 (set_attr "length" "2")])
6246 (define_expand "umulsidi3"
6247 [(set (match_operand:DI 0 "register_operand" "")
6248 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6249 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6253 if (CONSTANT_P (operands[2]))
6256 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6259 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6265 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6271 (define_insn "umulsidi3_v8plus"
6272 [(set (match_operand:DI 0 "register_operand" "=h,r")
6273 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6274 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6275 (clobber (match_scratch:SI 3 "=X,&h"))]
6278 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6279 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6280 [(set_attr "type" "multi")
6281 (set_attr "length" "2,3")])
6284 (define_insn "*umulsidi3_sp32"
6285 [(set (match_operand:DI 0 "register_operand" "=r")
6286 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6287 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6291 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6294 (if_then_else (eq_attr "isa" "sparclet")
6295 (const_string "imul") (const_string "multi")))
6296 (set (attr "length")
6297 (if_then_else (eq_attr "isa" "sparclet")
6298 (const_int 1) (const_int 2)))])
6300 (define_insn "*umulsidi3_sp64"
6301 [(set (match_operand:DI 0 "register_operand" "=r")
6302 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6303 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6304 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6306 [(set_attr "type" "imul")])
6308 ;; Extra pattern, because sign_extend of a constant isn't valid.
6311 (define_insn "const_umulsidi3_sp32"
6312 [(set (match_operand:DI 0 "register_operand" "=r")
6313 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6314 (match_operand:SI 2 "uns_small_int" "")))]
6318 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6321 (if_then_else (eq_attr "isa" "sparclet")
6322 (const_string "imul") (const_string "multi")))
6323 (set (attr "length")
6324 (if_then_else (eq_attr "isa" "sparclet")
6325 (const_int 1) (const_int 2)))])
6327 (define_insn "const_umulsidi3_sp64"
6328 [(set (match_operand:DI 0 "register_operand" "=r")
6329 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6330 (match_operand:SI 2 "uns_small_int" "")))]
6331 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6333 [(set_attr "type" "imul")])
6336 (define_insn "const_umulsidi3_v8plus"
6337 [(set (match_operand:DI 0 "register_operand" "=h,r")
6338 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6339 (match_operand:SI 2 "uns_small_int" "")))
6340 (clobber (match_scratch:SI 3 "=X,h"))]
6343 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6344 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6345 [(set_attr "type" "multi")
6346 (set_attr "length" "2,3")])
6348 (define_expand "umulsi3_highpart"
6349 [(set (match_operand:SI 0 "register_operand" "")
6351 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6352 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6354 "TARGET_HARD_MUL && TARGET_ARCH32"
6357 if (CONSTANT_P (operands[2]))
6361 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6367 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6372 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6373 operands[2], GEN_INT (32)));
6379 (define_insn "umulsi3_highpart_v8plus"
6380 [(set (match_operand:SI 0 "register_operand" "=h,r")
6382 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6383 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6384 (match_operand:SI 3 "const_int_operand" "i,i"))))
6385 (clobber (match_scratch:SI 4 "=X,h"))]
6388 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6389 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6390 [(set_attr "type" "multi")
6391 (set_attr "length" "2")])
6394 (define_insn "const_umulsi3_highpart_v8plus"
6395 [(set (match_operand:SI 0 "register_operand" "=h,r")
6397 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6398 (match_operand:SI 2 "uns_small_int" ""))
6399 (match_operand:SI 3 "const_int_operand" "i,i"))))
6400 (clobber (match_scratch:SI 4 "=X,h"))]
6403 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6404 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6405 [(set_attr "type" "multi")
6406 (set_attr "length" "2")])
6409 (define_insn "*umulsi3_highpart_sp32"
6410 [(set (match_operand:SI 0 "register_operand" "=r")
6412 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6413 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6416 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6417 [(set_attr "type" "multi")
6418 (set_attr "length" "2")])
6421 (define_insn "const_umulsi3_highpart"
6422 [(set (match_operand:SI 0 "register_operand" "=r")
6424 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6425 (match_operand:SI 2 "uns_small_int" ""))
6428 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6429 [(set_attr "type" "multi")
6430 (set_attr "length" "2")])
6432 ;; The v8 architecture specifies that there must be 3 instructions between
6433 ;; a y register write and a use of it for correct results.
6435 (define_expand "divsi3"
6436 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6437 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6438 (match_operand:SI 2 "input_operand" "rI,m")))
6439 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6440 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6445 operands[3] = gen_reg_rtx(SImode);
6446 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6447 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6453 (define_insn "divsi3_sp32"
6454 [(set (match_operand:SI 0 "register_operand" "=r,r")
6455 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6456 (match_operand:SI 2 "input_operand" "rI,m")))
6457 (clobber (match_scratch:SI 3 "=&r,&r"))]
6458 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6462 if (which_alternative == 0)
6464 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6466 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6469 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6471 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\";
6473 [(set_attr "type" "multi")
6474 (set (attr "length")
6475 (if_then_else (eq_attr "isa" "v9")
6476 (const_int 4) (const_int 7)))])
6478 (define_insn "divsi3_sp64"
6479 [(set (match_operand:SI 0 "register_operand" "=r")
6480 (div:SI (match_operand:SI 1 "register_operand" "r")
6481 (match_operand:SI 2 "input_operand" "rI")))
6482 (use (match_operand:SI 3 "register_operand" "r"))]
6483 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6484 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6485 [(set_attr "type" "multi")
6486 (set_attr "length" "2")])
6488 (define_insn "divdi3"
6489 [(set (match_operand:DI 0 "register_operand" "=r")
6490 (div:DI (match_operand:DI 1 "register_operand" "r")
6491 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6493 "sdivx\\t%1, %2, %0"
6494 [(set_attr "type" "idiv")])
6496 (define_insn "*cmp_sdiv_cc_set"
6498 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6499 (match_operand:SI 2 "arith_operand" "rI"))
6501 (set (match_operand:SI 0 "register_operand" "=r")
6502 (div:SI (match_dup 1) (match_dup 2)))
6503 (clobber (match_scratch:SI 3 "=&r"))]
6504 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6508 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6510 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6512 [(set_attr "type" "multi")
6513 (set (attr "length")
6514 (if_then_else (eq_attr "isa" "v9")
6515 (const_int 3) (const_int 6)))])
6518 (define_expand "udivsi3"
6519 [(set (match_operand:SI 0 "register_operand" "")
6520 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6521 (match_operand:SI 2 "input_operand" "")))]
6522 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6525 (define_insn "udivsi3_sp32"
6526 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6527 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6528 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6530 || TARGET_DEPRECATED_V8_INSNS)
6534 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6535 switch (which_alternative)
6538 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6540 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6542 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6545 [(set_attr "type" "multi")
6546 (set_attr "length" "5")])
6548 (define_insn "udivsi3_sp64"
6549 [(set (match_operand:SI 0 "register_operand" "=r")
6550 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6551 (match_operand:SI 2 "input_operand" "rI")))]
6552 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6553 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6554 [(set_attr "type" "multi")
6555 (set_attr "length" "2")])
6557 (define_insn "udivdi3"
6558 [(set (match_operand:DI 0 "register_operand" "=r")
6559 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6560 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6562 "udivx\\t%1, %2, %0"
6563 [(set_attr "type" "idiv")])
6565 (define_insn "*cmp_udiv_cc_set"
6567 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6568 (match_operand:SI 2 "arith_operand" "rI"))
6570 (set (match_operand:SI 0 "register_operand" "=r")
6571 (udiv:SI (match_dup 1) (match_dup 2)))]
6573 || TARGET_DEPRECATED_V8_INSNS"
6577 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6579 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6581 [(set_attr "type" "multi")
6582 (set (attr "length")
6583 (if_then_else (eq_attr "isa" "v9")
6584 (const_int 2) (const_int 5)))])
6586 ; sparclet multiply/accumulate insns
6588 (define_insn "*smacsi"
6589 [(set (match_operand:SI 0 "register_operand" "=r")
6590 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6591 (match_operand:SI 2 "arith_operand" "rI"))
6592 (match_operand:SI 3 "register_operand" "0")))]
6595 [(set_attr "type" "imul")])
6597 (define_insn "*smacdi"
6598 [(set (match_operand:DI 0 "register_operand" "=r")
6599 (plus:DI (mult:DI (sign_extend:DI
6600 (match_operand:SI 1 "register_operand" "%r"))
6602 (match_operand:SI 2 "register_operand" "r")))
6603 (match_operand:DI 3 "register_operand" "0")))]
6605 "smacd\\t%1, %2, %L0"
6606 [(set_attr "type" "imul")])
6608 (define_insn "*umacdi"
6609 [(set (match_operand:DI 0 "register_operand" "=r")
6610 (plus:DI (mult:DI (zero_extend:DI
6611 (match_operand:SI 1 "register_operand" "%r"))
6613 (match_operand:SI 2 "register_operand" "r")))
6614 (match_operand:DI 3 "register_operand" "0")))]
6616 "umacd\\t%1, %2, %L0"
6617 [(set_attr "type" "imul")])
6619 ;;- Boolean instructions
6620 ;; We define DImode `and' so with DImode `not' we can get
6621 ;; DImode `andn'. Other combinations are possible.
6623 (define_expand "anddi3"
6624 [(set (match_operand:DI 0 "register_operand" "")
6625 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6626 (match_operand:DI 2 "arith_double_operand" "")))]
6630 (define_insn "*anddi3_sp32"
6631 [(set (match_operand:DI 0 "register_operand" "=r,b")
6632 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6633 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6638 [(set_attr "type" "*,fp")
6639 (set_attr "length" "2,*")
6640 (set_attr "fptype" "double")])
6642 (define_insn "*anddi3_sp64"
6643 [(set (match_operand:DI 0 "register_operand" "=r,b")
6644 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6645 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6650 [(set_attr "type" "*,fp")
6651 (set_attr "fptype" "double")])
6653 (define_insn "andsi3"
6654 [(set (match_operand:SI 0 "register_operand" "=r,d")
6655 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6656 (match_operand:SI 2 "arith_operand" "rI,d")))]
6661 [(set_attr "type" "*,fp")])
6664 [(set (match_operand:SI 0 "register_operand" "")
6665 (and:SI (match_operand:SI 1 "register_operand" "")
6666 (match_operand:SI 2 "" "")))
6667 (clobber (match_operand:SI 3 "register_operand" ""))]
6668 "GET_CODE (operands[2]) == CONST_INT
6669 && !SMALL_INT32 (operands[2])
6670 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6671 [(set (match_dup 3) (match_dup 4))
6672 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6675 operands[4] = GEN_INT (~INTVAL (operands[2]));
6678 ;; Split DImode logical operations requiring two instructions.
6680 [(set (match_operand:DI 0 "register_operand" "")
6681 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6682 [(match_operand:DI 2 "register_operand" "")
6683 (match_operand:DI 3 "arith_double_operand" "")]))]
6686 && ((GET_CODE (operands[0]) == REG
6687 && REGNO (operands[0]) < 32)
6688 || (GET_CODE (operands[0]) == SUBREG
6689 && GET_CODE (SUBREG_REG (operands[0])) == REG
6690 && REGNO (SUBREG_REG (operands[0])) < 32))"
6691 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6692 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6695 operands[4] = gen_highpart (SImode, operands[0]);
6696 operands[5] = gen_lowpart (SImode, operands[0]);
6697 operands[6] = gen_highpart (SImode, operands[2]);
6698 operands[7] = gen_lowpart (SImode, operands[2]);
6699 #if HOST_BITS_PER_WIDE_INT == 32
6700 if (GET_CODE (operands[3]) == CONST_INT)
6702 if (INTVAL (operands[3]) < 0)
6703 operands[8] = constm1_rtx;
6705 operands[8] = const0_rtx;
6709 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6710 operands[9] = gen_lowpart (SImode, operands[3]);
6713 (define_insn "*and_not_di_sp32"
6714 [(set (match_operand:DI 0 "register_operand" "=r,b")
6715 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6716 (match_operand:DI 2 "register_operand" "r,b")))]
6720 fandnot1\\t%1, %2, %0"
6721 [(set_attr "type" "*,fp")
6722 (set_attr "length" "2,*")
6723 (set_attr "fptype" "double")])
6726 [(set (match_operand:DI 0 "register_operand" "")
6727 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6728 (match_operand:DI 2 "register_operand" "")))]
6731 && ((GET_CODE (operands[0]) == REG
6732 && REGNO (operands[0]) < 32)
6733 || (GET_CODE (operands[0]) == SUBREG
6734 && GET_CODE (SUBREG_REG (operands[0])) == REG
6735 && REGNO (SUBREG_REG (operands[0])) < 32))"
6736 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6737 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6738 "operands[3] = gen_highpart (SImode, operands[0]);
6739 operands[4] = gen_highpart (SImode, operands[1]);
6740 operands[5] = gen_highpart (SImode, operands[2]);
6741 operands[6] = gen_lowpart (SImode, operands[0]);
6742 operands[7] = gen_lowpart (SImode, operands[1]);
6743 operands[8] = gen_lowpart (SImode, operands[2]);")
6745 (define_insn "*and_not_di_sp64"
6746 [(set (match_operand:DI 0 "register_operand" "=r,b")
6747 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6748 (match_operand:DI 2 "register_operand" "r,b")))]
6752 fandnot1\\t%1, %2, %0"
6753 [(set_attr "type" "*,fp")
6754 (set_attr "fptype" "double")])
6756 (define_insn "*and_not_si"
6757 [(set (match_operand:SI 0 "register_operand" "=r,d")
6758 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6759 (match_operand:SI 2 "register_operand" "r,d")))]
6763 fandnot1s\\t%1, %2, %0"
6764 [(set_attr "type" "*,fp")])
6766 (define_expand "iordi3"
6767 [(set (match_operand:DI 0 "register_operand" "")
6768 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6769 (match_operand:DI 2 "arith_double_operand" "")))]
6773 (define_insn "*iordi3_sp32"
6774 [(set (match_operand:DI 0 "register_operand" "=r,b")
6775 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6776 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6781 [(set_attr "type" "*,fp")
6782 (set_attr "length" "2,*")
6783 (set_attr "fptype" "double")])
6785 (define_insn "*iordi3_sp64"
6786 [(set (match_operand:DI 0 "register_operand" "=r,b")
6787 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6788 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6793 [(set_attr "type" "*,fp")
6794 (set_attr "fptype" "double")])
6796 (define_insn "iorsi3"
6797 [(set (match_operand:SI 0 "register_operand" "=r,d")
6798 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6799 (match_operand:SI 2 "arith_operand" "rI,d")))]
6804 [(set_attr "type" "*,fp")])
6807 [(set (match_operand:SI 0 "register_operand" "")
6808 (ior:SI (match_operand:SI 1 "register_operand" "")
6809 (match_operand:SI 2 "" "")))
6810 (clobber (match_operand:SI 3 "register_operand" ""))]
6811 "GET_CODE (operands[2]) == CONST_INT
6812 && !SMALL_INT32 (operands[2])
6813 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6814 [(set (match_dup 3) (match_dup 4))
6815 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6818 operands[4] = GEN_INT (~INTVAL (operands[2]));
6821 (define_insn "*or_not_di_sp32"
6822 [(set (match_operand:DI 0 "register_operand" "=r,b")
6823 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6824 (match_operand:DI 2 "register_operand" "r,b")))]
6828 fornot1\\t%1, %2, %0"
6829 [(set_attr "type" "*,fp")
6830 (set_attr "length" "2,*")
6831 (set_attr "fptype" "double")])
6834 [(set (match_operand:DI 0 "register_operand" "")
6835 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6836 (match_operand:DI 2 "register_operand" "")))]
6839 && ((GET_CODE (operands[0]) == REG
6840 && REGNO (operands[0]) < 32)
6841 || (GET_CODE (operands[0]) == SUBREG
6842 && GET_CODE (SUBREG_REG (operands[0])) == REG
6843 && REGNO (SUBREG_REG (operands[0])) < 32))"
6844 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6845 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6846 "operands[3] = gen_highpart (SImode, operands[0]);
6847 operands[4] = gen_highpart (SImode, operands[1]);
6848 operands[5] = gen_highpart (SImode, operands[2]);
6849 operands[6] = gen_lowpart (SImode, operands[0]);
6850 operands[7] = gen_lowpart (SImode, operands[1]);
6851 operands[8] = gen_lowpart (SImode, operands[2]);")
6853 (define_insn "*or_not_di_sp64"
6854 [(set (match_operand:DI 0 "register_operand" "=r,b")
6855 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6856 (match_operand:DI 2 "register_operand" "r,b")))]
6860 fornot1\\t%1, %2, %0"
6861 [(set_attr "type" "*,fp")
6862 (set_attr "fptype" "double")])
6864 (define_insn "*or_not_si"
6865 [(set (match_operand:SI 0 "register_operand" "=r,d")
6866 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6867 (match_operand:SI 2 "register_operand" "r,d")))]
6871 fornot1s\\t%1, %2, %0"
6872 [(set_attr "type" "*,fp")])
6874 (define_expand "xordi3"
6875 [(set (match_operand:DI 0 "register_operand" "")
6876 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6877 (match_operand:DI 2 "arith_double_operand" "")))]
6881 (define_insn "*xordi3_sp32"
6882 [(set (match_operand:DI 0 "register_operand" "=r,b")
6883 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6884 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6889 [(set_attr "type" "*,fp")
6890 (set_attr "length" "2,*")
6891 (set_attr "fptype" "double")])
6893 (define_insn "*xordi3_sp64"
6894 [(set (match_operand:DI 0 "register_operand" "=r,b")
6895 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6896 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6901 [(set_attr "type" "*,fp")
6902 (set_attr "fptype" "double")])
6904 (define_insn "*xordi3_sp64_dbl"
6905 [(set (match_operand:DI 0 "register_operand" "=r")
6906 (xor:DI (match_operand:DI 1 "register_operand" "r")
6907 (match_operand:DI 2 "const64_operand" "")))]
6909 && HOST_BITS_PER_WIDE_INT != 64)"
6912 (define_insn "xorsi3"
6913 [(set (match_operand:SI 0 "register_operand" "=r,d")
6914 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6915 (match_operand:SI 2 "arith_operand" "rI,d")))]
6920 [(set_attr "type" "*,fp")])
6923 [(set (match_operand:SI 0 "register_operand" "")
6924 (xor:SI (match_operand:SI 1 "register_operand" "")
6925 (match_operand:SI 2 "" "")))
6926 (clobber (match_operand:SI 3 "register_operand" ""))]
6927 "GET_CODE (operands[2]) == CONST_INT
6928 && !SMALL_INT32 (operands[2])
6929 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6930 [(set (match_dup 3) (match_dup 4))
6931 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6934 operands[4] = GEN_INT (~INTVAL (operands[2]));
6938 [(set (match_operand:SI 0 "register_operand" "")
6939 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6940 (match_operand:SI 2 "" ""))))
6941 (clobber (match_operand:SI 3 "register_operand" ""))]
6942 "GET_CODE (operands[2]) == CONST_INT
6943 && !SMALL_INT32 (operands[2])
6944 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6945 [(set (match_dup 3) (match_dup 4))
6946 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6949 operands[4] = GEN_INT (~INTVAL (operands[2]));
6952 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6953 ;; Combine now canonicalizes to the rightmost expression.
6954 (define_insn "*xor_not_di_sp32"
6955 [(set (match_operand:DI 0 "register_operand" "=r,b")
6956 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6957 (match_operand:DI 2 "register_operand" "r,b"))))]
6962 [(set_attr "type" "*,fp")
6963 (set_attr "length" "2,*")
6964 (set_attr "fptype" "double")])
6967 [(set (match_operand:DI 0 "register_operand" "")
6968 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6969 (match_operand:DI 2 "register_operand" ""))))]
6972 && ((GET_CODE (operands[0]) == REG
6973 && REGNO (operands[0]) < 32)
6974 || (GET_CODE (operands[0]) == SUBREG
6975 && GET_CODE (SUBREG_REG (operands[0])) == REG
6976 && REGNO (SUBREG_REG (operands[0])) < 32))"
6977 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6978 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6979 "operands[3] = gen_highpart (SImode, operands[0]);
6980 operands[4] = gen_highpart (SImode, operands[1]);
6981 operands[5] = gen_highpart (SImode, operands[2]);
6982 operands[6] = gen_lowpart (SImode, operands[0]);
6983 operands[7] = gen_lowpart (SImode, operands[1]);
6984 operands[8] = gen_lowpart (SImode, operands[2]);")
6986 (define_insn "*xor_not_di_sp64"
6987 [(set (match_operand:DI 0 "register_operand" "=r,b")
6988 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6989 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6994 [(set_attr "type" "*,fp")
6995 (set_attr "fptype" "double")])
6997 (define_insn "*xor_not_si"
6998 [(set (match_operand:SI 0 "register_operand" "=r,d")
6999 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7000 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7004 fxnors\\t%1, %2, %0"
7005 [(set_attr "type" "*,fp")])
7007 ;; These correspond to the above in the case where we also (or only)
7008 ;; want to set the condition code.
7010 (define_insn "*cmp_cc_arith_op"
7013 (match_operator:SI 2 "cc_arithop"
7014 [(match_operand:SI 0 "arith_operand" "%r")
7015 (match_operand:SI 1 "arith_operand" "rI")])
7018 "%A2cc\\t%0, %1, %%g0"
7019 [(set_attr "type" "compare")])
7021 (define_insn "*cmp_ccx_arith_op"
7024 (match_operator:DI 2 "cc_arithop"
7025 [(match_operand:DI 0 "arith_double_operand" "%r")
7026 (match_operand:DI 1 "arith_double_operand" "rHI")])
7029 "%A2cc\\t%0, %1, %%g0"
7030 [(set_attr "type" "compare")])
7032 (define_insn "*cmp_cc_arith_op_set"
7035 (match_operator:SI 3 "cc_arithop"
7036 [(match_operand:SI 1 "arith_operand" "%r")
7037 (match_operand:SI 2 "arith_operand" "rI")])
7039 (set (match_operand:SI 0 "register_operand" "=r")
7040 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7041 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7042 "%A3cc\\t%1, %2, %0"
7043 [(set_attr "type" "compare")])
7045 (define_insn "*cmp_ccx_arith_op_set"
7048 (match_operator:DI 3 "cc_arithop"
7049 [(match_operand:DI 1 "arith_double_operand" "%r")
7050 (match_operand:DI 2 "arith_double_operand" "rHI")])
7052 (set (match_operand:DI 0 "register_operand" "=r")
7053 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7054 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7055 "%A3cc\\t%1, %2, %0"
7056 [(set_attr "type" "compare")])
7058 (define_insn "*cmp_cc_xor_not"
7061 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7062 (match_operand:SI 1 "arith_operand" "rI")))
7065 "xnorcc\\t%r0, %1, %%g0"
7066 [(set_attr "type" "compare")])
7068 (define_insn "*cmp_ccx_xor_not"
7071 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7072 (match_operand:DI 1 "arith_double_operand" "rHI")))
7075 "xnorcc\\t%r0, %1, %%g0"
7076 [(set_attr "type" "compare")])
7078 (define_insn "*cmp_cc_xor_not_set"
7081 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7082 (match_operand:SI 2 "arith_operand" "rI")))
7084 (set (match_operand:SI 0 "register_operand" "=r")
7085 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7087 "xnorcc\\t%r1, %2, %0"
7088 [(set_attr "type" "compare")])
7090 (define_insn "*cmp_ccx_xor_not_set"
7093 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7094 (match_operand:DI 2 "arith_double_operand" "rHI")))
7096 (set (match_operand:DI 0 "register_operand" "=r")
7097 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7099 "xnorcc\\t%r1, %2, %0"
7100 [(set_attr "type" "compare")])
7102 (define_insn "*cmp_cc_arith_op_not"
7105 (match_operator:SI 2 "cc_arithopn"
7106 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7107 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7110 "%B2cc\\t%r1, %0, %%g0"
7111 [(set_attr "type" "compare")])
7113 (define_insn "*cmp_ccx_arith_op_not"
7116 (match_operator:DI 2 "cc_arithopn"
7117 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7118 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7121 "%B2cc\\t%r1, %0, %%g0"
7122 [(set_attr "type" "compare")])
7124 (define_insn "*cmp_cc_arith_op_not_set"
7127 (match_operator:SI 3 "cc_arithopn"
7128 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7129 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7131 (set (match_operand:SI 0 "register_operand" "=r")
7132 (match_operator:SI 4 "cc_arithopn"
7133 [(not:SI (match_dup 1)) (match_dup 2)]))]
7134 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7135 "%B3cc\\t%r2, %1, %0"
7136 [(set_attr "type" "compare")])
7138 (define_insn "*cmp_ccx_arith_op_not_set"
7141 (match_operator:DI 3 "cc_arithopn"
7142 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7143 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7145 (set (match_operand:DI 0 "register_operand" "=r")
7146 (match_operator:DI 4 "cc_arithopn"
7147 [(not:DI (match_dup 1)) (match_dup 2)]))]
7148 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7149 "%B3cc\\t%r2, %1, %0"
7150 [(set_attr "type" "compare")])
7152 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7153 ;; does not know how to make it work for constants.
7155 (define_expand "negdi2"
7156 [(set (match_operand:DI 0 "register_operand" "=r")
7157 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7161 if (! TARGET_ARCH64)
7163 emit_insn (gen_rtx_PARALLEL
7166 gen_rtx_SET (VOIDmode, operand0,
7167 gen_rtx_NEG (DImode, operand1)),
7168 gen_rtx_CLOBBER (VOIDmode,
7169 gen_rtx_REG (CCmode,
7175 (define_insn "*negdi2_sp32"
7176 [(set (match_operand:DI 0 "register_operand" "=r")
7177 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7178 (clobber (reg:CC 100))]
7181 [(set_attr "length" "2")])
7184 [(set (match_operand:DI 0 "register_operand" "")
7185 (neg:DI (match_operand:DI 1 "register_operand" "")))
7186 (clobber (reg:CC 100))]
7188 && reload_completed"
7189 [(parallel [(set (reg:CC_NOOV 100)
7190 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7192 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7193 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7194 (ltu:SI (reg:CC 100) (const_int 0))))]
7195 "operands[2] = gen_highpart (SImode, operands[0]);
7196 operands[3] = gen_highpart (SImode, operands[1]);
7197 operands[4] = gen_lowpart (SImode, operands[0]);
7198 operands[5] = gen_lowpart (SImode, operands[1]);")
7200 (define_insn "*negdi2_sp64"
7201 [(set (match_operand:DI 0 "register_operand" "=r")
7202 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7204 "sub\\t%%g0, %1, %0")
7206 (define_insn "negsi2"
7207 [(set (match_operand:SI 0 "register_operand" "=r")
7208 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7210 "sub\\t%%g0, %1, %0")
7212 (define_insn "*cmp_cc_neg"
7213 [(set (reg:CC_NOOV 100)
7214 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7217 "subcc\\t%%g0, %0, %%g0"
7218 [(set_attr "type" "compare")])
7220 (define_insn "*cmp_ccx_neg"
7221 [(set (reg:CCX_NOOV 100)
7222 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7225 "subcc\\t%%g0, %0, %%g0"
7226 [(set_attr "type" "compare")])
7228 (define_insn "*cmp_cc_set_neg"
7229 [(set (reg:CC_NOOV 100)
7230 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7232 (set (match_operand:SI 0 "register_operand" "=r")
7233 (neg:SI (match_dup 1)))]
7235 "subcc\\t%%g0, %1, %0"
7236 [(set_attr "type" "compare")])
7238 (define_insn "*cmp_ccx_set_neg"
7239 [(set (reg:CCX_NOOV 100)
7240 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7242 (set (match_operand:DI 0 "register_operand" "=r")
7243 (neg:DI (match_dup 1)))]
7245 "subcc\\t%%g0, %1, %0"
7246 [(set_attr "type" "compare")])
7248 ;; We cannot use the "not" pseudo insn because the Sun assembler
7249 ;; does not know how to make it work for constants.
7250 (define_expand "one_cmpldi2"
7251 [(set (match_operand:DI 0 "register_operand" "")
7252 (not:DI (match_operand:DI 1 "register_operand" "")))]
7256 (define_insn "*one_cmpldi2_sp32"
7257 [(set (match_operand:DI 0 "register_operand" "=r,b")
7258 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7263 [(set_attr "type" "*,fp")
7264 (set_attr "length" "2,*")
7265 (set_attr "fptype" "double")])
7268 [(set (match_operand:DI 0 "register_operand" "")
7269 (not:DI (match_operand:DI 1 "register_operand" "")))]
7272 && ((GET_CODE (operands[0]) == REG
7273 && REGNO (operands[0]) < 32)
7274 || (GET_CODE (operands[0]) == SUBREG
7275 && GET_CODE (SUBREG_REG (operands[0])) == REG
7276 && REGNO (SUBREG_REG (operands[0])) < 32))"
7277 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7278 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7279 "operands[2] = gen_highpart (SImode, operands[0]);
7280 operands[3] = gen_highpart (SImode, operands[1]);
7281 operands[4] = gen_lowpart (SImode, operands[0]);
7282 operands[5] = gen_lowpart (SImode, operands[1]);")
7284 (define_insn "*one_cmpldi2_sp64"
7285 [(set (match_operand:DI 0 "register_operand" "=r,b")
7286 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7291 [(set_attr "type" "*,fp")
7292 (set_attr "fptype" "double")])
7294 (define_insn "one_cmplsi2"
7295 [(set (match_operand:SI 0 "register_operand" "=r,d")
7296 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7301 [(set_attr "type" "*,fp")])
7303 (define_insn "*cmp_cc_not"
7305 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7308 "xnorcc\\t%%g0, %0, %%g0"
7309 [(set_attr "type" "compare")])
7311 (define_insn "*cmp_ccx_not"
7313 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7316 "xnorcc\\t%%g0, %0, %%g0"
7317 [(set_attr "type" "compare")])
7319 (define_insn "*cmp_cc_set_not"
7321 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7323 (set (match_operand:SI 0 "register_operand" "=r")
7324 (not:SI (match_dup 1)))]
7326 "xnorcc\\t%%g0, %1, %0"
7327 [(set_attr "type" "compare")])
7329 (define_insn "*cmp_ccx_set_not"
7331 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7333 (set (match_operand:DI 0 "register_operand" "=r")
7334 (not:DI (match_dup 1)))]
7336 "xnorcc\\t%%g0, %1, %0"
7337 [(set_attr "type" "compare")])
7339 (define_insn "*cmp_cc_set"
7340 [(set (match_operand:SI 0 "register_operand" "=r")
7341 (match_operand:SI 1 "register_operand" "r"))
7343 (compare:CC (match_dup 1)
7347 [(set_attr "type" "compare")])
7349 (define_insn "*cmp_ccx_set64"
7350 [(set (match_operand:DI 0 "register_operand" "=r")
7351 (match_operand:DI 1 "register_operand" "r"))
7353 (compare:CCX (match_dup 1)
7357 [(set_attr "type" "compare")])
7359 ;; Floating point arithmetic instructions.
7361 (define_expand "addtf3"
7362 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7363 (plus:TF (match_operand:TF 1 "general_operand" "")
7364 (match_operand:TF 2 "general_operand" "")))]
7365 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7368 if (! TARGET_HARD_QUAD)
7370 rtx slot0, slot1, slot2;
7372 if (GET_CODE (operands[0]) != MEM)
7373 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7375 slot0 = operands[0];
7376 if (GET_CODE (operands[1]) != MEM)
7378 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7379 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7382 slot1 = operands[1];
7383 if (GET_CODE (operands[2]) != MEM)
7385 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7386 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7389 slot2 = operands[2];
7391 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7393 XEXP (slot0, 0), Pmode,
7394 XEXP (slot1, 0), Pmode,
7395 XEXP (slot2, 0), Pmode);
7397 if (GET_CODE (operands[0]) != MEM)
7398 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7403 (define_insn "*addtf3_hq"
7404 [(set (match_operand:TF 0 "register_operand" "=e")
7405 (plus:TF (match_operand:TF 1 "register_operand" "e")
7406 (match_operand:TF 2 "register_operand" "e")))]
7407 "TARGET_FPU && TARGET_HARD_QUAD"
7408 "faddq\\t%1, %2, %0"
7409 [(set_attr "type" "fp")])
7411 (define_insn "adddf3"
7412 [(set (match_operand:DF 0 "register_operand" "=e")
7413 (plus:DF (match_operand:DF 1 "register_operand" "e")
7414 (match_operand:DF 2 "register_operand" "e")))]
7416 "faddd\\t%1, %2, %0"
7417 [(set_attr "type" "fp")
7418 (set_attr "fptype" "double")])
7420 (define_insn "addsf3"
7421 [(set (match_operand:SF 0 "register_operand" "=f")
7422 (plus:SF (match_operand:SF 1 "register_operand" "f")
7423 (match_operand:SF 2 "register_operand" "f")))]
7425 "fadds\\t%1, %2, %0"
7426 [(set_attr "type" "fp")])
7428 (define_expand "subtf3"
7429 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7430 (minus:TF (match_operand:TF 1 "general_operand" "")
7431 (match_operand:TF 2 "general_operand" "")))]
7432 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7435 if (! TARGET_HARD_QUAD)
7437 rtx slot0, slot1, slot2;
7439 if (GET_CODE (operands[0]) != MEM)
7440 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7442 slot0 = operands[0];
7443 if (GET_CODE (operands[1]) != MEM)
7445 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7446 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7449 slot1 = operands[1];
7450 if (GET_CODE (operands[2]) != MEM)
7452 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7453 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7456 slot2 = operands[2];
7458 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7460 XEXP (slot0, 0), Pmode,
7461 XEXP (slot1, 0), Pmode,
7462 XEXP (slot2, 0), Pmode);
7464 if (GET_CODE (operands[0]) != MEM)
7465 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7470 (define_insn "*subtf3_hq"
7471 [(set (match_operand:TF 0 "register_operand" "=e")
7472 (minus:TF (match_operand:TF 1 "register_operand" "e")
7473 (match_operand:TF 2 "register_operand" "e")))]
7474 "TARGET_FPU && TARGET_HARD_QUAD"
7475 "fsubq\\t%1, %2, %0"
7476 [(set_attr "type" "fp")])
7478 (define_insn "subdf3"
7479 [(set (match_operand:DF 0 "register_operand" "=e")
7480 (minus:DF (match_operand:DF 1 "register_operand" "e")
7481 (match_operand:DF 2 "register_operand" "e")))]
7483 "fsubd\\t%1, %2, %0"
7484 [(set_attr "type" "fp")
7485 (set_attr "fptype" "double")])
7487 (define_insn "subsf3"
7488 [(set (match_operand:SF 0 "register_operand" "=f")
7489 (minus:SF (match_operand:SF 1 "register_operand" "f")
7490 (match_operand:SF 2 "register_operand" "f")))]
7492 "fsubs\\t%1, %2, %0"
7493 [(set_attr "type" "fp")])
7495 (define_expand "multf3"
7496 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7497 (mult:TF (match_operand:TF 1 "general_operand" "")
7498 (match_operand:TF 2 "general_operand" "")))]
7499 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7502 if (! TARGET_HARD_QUAD)
7504 rtx slot0, slot1, slot2;
7506 if (GET_CODE (operands[0]) != MEM)
7507 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7509 slot0 = operands[0];
7510 if (GET_CODE (operands[1]) != MEM)
7512 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7513 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7516 slot1 = operands[1];
7517 if (GET_CODE (operands[2]) != MEM)
7519 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7520 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7523 slot2 = operands[2];
7525 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7527 XEXP (slot0, 0), Pmode,
7528 XEXP (slot1, 0), Pmode,
7529 XEXP (slot2, 0), Pmode);
7531 if (GET_CODE (operands[0]) != MEM)
7532 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7537 (define_insn "*multf3_hq"
7538 [(set (match_operand:TF 0 "register_operand" "=e")
7539 (mult:TF (match_operand:TF 1 "register_operand" "e")
7540 (match_operand:TF 2 "register_operand" "e")))]
7541 "TARGET_FPU && TARGET_HARD_QUAD"
7542 "fmulq\\t%1, %2, %0"
7543 [(set_attr "type" "fpmul")])
7545 (define_insn "muldf3"
7546 [(set (match_operand:DF 0 "register_operand" "=e")
7547 (mult:DF (match_operand:DF 1 "register_operand" "e")
7548 (match_operand:DF 2 "register_operand" "e")))]
7550 "fmuld\\t%1, %2, %0"
7551 [(set_attr "type" "fpmul")
7552 (set_attr "fptype" "double")])
7554 (define_insn "mulsf3"
7555 [(set (match_operand:SF 0 "register_operand" "=f")
7556 (mult:SF (match_operand:SF 1 "register_operand" "f")
7557 (match_operand:SF 2 "register_operand" "f")))]
7559 "fmuls\\t%1, %2, %0"
7560 [(set_attr "type" "fpmul")])
7562 (define_insn "*muldf3_extend"
7563 [(set (match_operand:DF 0 "register_operand" "=e")
7564 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7565 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7566 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7567 "fsmuld\\t%1, %2, %0"
7568 [(set_attr "type" "fpmul")
7569 (set_attr "fptype" "double")])
7571 (define_insn "*multf3_extend"
7572 [(set (match_operand:TF 0 "register_operand" "=e")
7573 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7574 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7575 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7576 "fdmulq\\t%1, %2, %0"
7577 [(set_attr "type" "fpmul")])
7579 (define_expand "divtf3"
7580 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7581 (div:TF (match_operand:TF 1 "general_operand" "")
7582 (match_operand:TF 2 "general_operand" "")))]
7583 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7586 if (! TARGET_HARD_QUAD)
7588 rtx slot0, slot1, slot2;
7590 if (GET_CODE (operands[0]) != MEM)
7591 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7593 slot0 = operands[0];
7594 if (GET_CODE (operands[1]) != MEM)
7596 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7597 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7600 slot1 = operands[1];
7601 if (GET_CODE (operands[2]) != MEM)
7603 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7604 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7607 slot2 = operands[2];
7609 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7611 XEXP (slot0, 0), Pmode,
7612 XEXP (slot1, 0), Pmode,
7613 XEXP (slot2, 0), Pmode);
7615 if (GET_CODE (operands[0]) != MEM)
7616 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7621 ;; don't have timing for quad-prec. divide.
7622 (define_insn "*divtf3_hq"
7623 [(set (match_operand:TF 0 "register_operand" "=e")
7624 (div:TF (match_operand:TF 1 "register_operand" "e")
7625 (match_operand:TF 2 "register_operand" "e")))]
7626 "TARGET_FPU && TARGET_HARD_QUAD"
7627 "fdivq\\t%1, %2, %0"
7628 [(set_attr "type" "fpdivd")])
7630 (define_insn "divdf3"
7631 [(set (match_operand:DF 0 "register_operand" "=e")
7632 (div:DF (match_operand:DF 1 "register_operand" "e")
7633 (match_operand:DF 2 "register_operand" "e")))]
7635 "fdivd\\t%1, %2, %0"
7636 [(set_attr "type" "fpdivd")
7637 (set_attr "fptype" "double")])
7639 (define_insn "divsf3"
7640 [(set (match_operand:SF 0 "register_operand" "=f")
7641 (div:SF (match_operand:SF 1 "register_operand" "f")
7642 (match_operand:SF 2 "register_operand" "f")))]
7644 "fdivs\\t%1, %2, %0"
7645 [(set_attr "type" "fpdivs")])
7647 (define_expand "negtf2"
7648 [(set (match_operand:TF 0 "register_operand" "=e,e")
7649 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7653 (define_insn "*negtf2_notv9"
7654 [(set (match_operand:TF 0 "register_operand" "=e,e")
7655 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7656 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7662 [(set_attr "type" "fpmove,*")
7663 (set_attr "length" "*,2")])
7666 [(set (match_operand:TF 0 "register_operand" "")
7667 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7671 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7672 [(set (match_dup 2) (neg:SF (match_dup 3)))
7673 (set (match_dup 4) (match_dup 5))
7674 (set (match_dup 6) (match_dup 7))]
7675 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7676 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7677 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7678 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7679 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7680 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7682 (define_insn "*negtf2_v9"
7683 [(set (match_operand:TF 0 "register_operand" "=e,e")
7684 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7685 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7686 "TARGET_FPU && TARGET_V9"
7690 [(set_attr "type" "fpmove,*")
7691 (set_attr "length" "*,2")
7692 (set_attr "fptype" "double")])
7695 [(set (match_operand:TF 0 "register_operand" "")
7696 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7700 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7701 [(set (match_dup 2) (neg:DF (match_dup 3)))
7702 (set (match_dup 4) (match_dup 5))]
7703 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7704 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7705 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7706 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7708 (define_expand "negdf2"
7709 [(set (match_operand:DF 0 "register_operand" "")
7710 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7714 (define_insn "*negdf2_notv9"
7715 [(set (match_operand:DF 0 "register_operand" "=e,e")
7716 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7717 "TARGET_FPU && ! TARGET_V9"
7721 [(set_attr "type" "fpmove,*")
7722 (set_attr "length" "*,2")])
7725 [(set (match_operand:DF 0 "register_operand" "")
7726 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7730 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7731 [(set (match_dup 2) (neg:SF (match_dup 3)))
7732 (set (match_dup 4) (match_dup 5))]
7733 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7734 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7735 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7736 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7738 (define_insn "*negdf2_v9"
7739 [(set (match_operand:DF 0 "register_operand" "=e")
7740 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7741 "TARGET_FPU && TARGET_V9"
7743 [(set_attr "type" "fpmove")
7744 (set_attr "fptype" "double")])
7746 (define_insn "negsf2"
7747 [(set (match_operand:SF 0 "register_operand" "=f")
7748 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7751 [(set_attr "type" "fpmove")])
7753 (define_expand "abstf2"
7754 [(set (match_operand:TF 0 "register_operand" "")
7755 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7759 (define_insn "*abstf2_notv9"
7760 [(set (match_operand:TF 0 "register_operand" "=e,e")
7761 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7762 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7763 "TARGET_FPU && ! TARGET_V9"
7767 [(set_attr "type" "fpmove,*")
7768 (set_attr "length" "*,2")])
7771 [(set (match_operand:TF 0 "register_operand" "")
7772 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7776 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7777 [(set (match_dup 2) (abs:SF (match_dup 3)))
7778 (set (match_dup 4) (match_dup 5))
7779 (set (match_dup 6) (match_dup 7))]
7780 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7781 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7782 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7783 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7784 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7785 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7787 (define_insn "*abstf2_hq_v9"
7788 [(set (match_operand:TF 0 "register_operand" "=e,e")
7789 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7790 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7794 [(set_attr "type" "fpmove")
7795 (set_attr "fptype" "double,*")])
7797 (define_insn "*abstf2_v9"
7798 [(set (match_operand:TF 0 "register_operand" "=e,e")
7799 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7800 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7804 [(set_attr "type" "fpmove,*")
7805 (set_attr "length" "*,2")
7806 (set_attr "fptype" "double,*")])
7809 [(set (match_operand:TF 0 "register_operand" "")
7810 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7814 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7815 [(set (match_dup 2) (abs:DF (match_dup 3)))
7816 (set (match_dup 4) (match_dup 5))]
7817 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7818 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7819 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7820 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7822 (define_expand "absdf2"
7823 [(set (match_operand:DF 0 "register_operand" "")
7824 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7828 (define_insn "*absdf2_notv9"
7829 [(set (match_operand:DF 0 "register_operand" "=e,e")
7830 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7831 "TARGET_FPU && ! TARGET_V9"
7835 [(set_attr "type" "fpmove,*")
7836 (set_attr "length" "*,2")])
7839 [(set (match_operand:DF 0 "register_operand" "")
7840 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7844 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7845 [(set (match_dup 2) (abs:SF (match_dup 3)))
7846 (set (match_dup 4) (match_dup 5))]
7847 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7848 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7849 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7850 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7852 (define_insn "*absdf2_v9"
7853 [(set (match_operand:DF 0 "register_operand" "=e")
7854 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7855 "TARGET_FPU && TARGET_V9"
7857 [(set_attr "type" "fpmove")
7858 (set_attr "fptype" "double")])
7860 (define_insn "abssf2"
7861 [(set (match_operand:SF 0 "register_operand" "=f")
7862 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7865 [(set_attr "type" "fpmove")])
7867 (define_expand "sqrttf2"
7868 [(set (match_operand:TF 0 "register_operand" "=e")
7869 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7870 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7873 if (! TARGET_HARD_QUAD)
7877 if (GET_CODE (operands[0]) != MEM)
7878 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7880 slot0 = operands[0];
7881 if (GET_CODE (operands[1]) != MEM)
7883 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7884 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7887 slot1 = operands[1];
7889 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7891 XEXP (slot0, 0), Pmode,
7892 XEXP (slot1, 0), Pmode);
7894 if (GET_CODE (operands[0]) != MEM)
7895 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7900 (define_insn "*sqrttf2_hq"
7901 [(set (match_operand:TF 0 "register_operand" "=e")
7902 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7903 "TARGET_FPU && TARGET_HARD_QUAD"
7905 [(set_attr "type" "fpsqrtd")])
7907 (define_insn "sqrtdf2"
7908 [(set (match_operand:DF 0 "register_operand" "=e")
7909 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7912 [(set_attr "type" "fpsqrtd")
7913 (set_attr "fptype" "double")])
7915 (define_insn "sqrtsf2"
7916 [(set (match_operand:SF 0 "register_operand" "=f")
7917 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7920 [(set_attr "type" "fpsqrts")])
7922 ;;- arithmetic shift instructions
7924 (define_insn "ashlsi3"
7925 [(set (match_operand:SI 0 "register_operand" "=r")
7926 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7927 (match_operand:SI 2 "arith_operand" "rI")))]
7931 if (GET_CODE (operands[2]) == CONST_INT
7932 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7933 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7935 return \"sll\\t%1, %2, %0\";
7937 [(set_attr "type" "shift")])
7939 ;; We special case multiplication by two, as add can be done
7940 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7941 (define_insn "*ashlsi3_const1"
7942 [(set (match_operand:SI 0 "register_operand" "=r")
7943 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7948 (define_expand "ashldi3"
7949 [(set (match_operand:DI 0 "register_operand" "=r")
7950 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7951 (match_operand:SI 2 "arith_operand" "rI")))]
7952 "TARGET_ARCH64 || TARGET_V8PLUS"
7955 if (! TARGET_ARCH64)
7957 if (GET_CODE (operands[2]) == CONST_INT)
7959 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7964 ;; We special case multiplication by two, as add can be done
7965 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7966 (define_insn "*ashldi3_const1"
7967 [(set (match_operand:DI 0 "register_operand" "=r")
7968 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7973 (define_insn "*ashldi3_sp64"
7974 [(set (match_operand:DI 0 "register_operand" "=r")
7975 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7976 (match_operand:SI 2 "arith_operand" "rI")))]
7980 if (GET_CODE (operands[2]) == CONST_INT
7981 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7982 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7984 return \"sllx\\t%1, %2, %0\";
7986 [(set_attr "type" "shift")])
7989 (define_insn "ashldi3_v8plus"
7990 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7991 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7992 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7993 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7995 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7996 [(set_attr "type" "multi")
7997 (set_attr "length" "5,5,6")])
7999 ;; Optimize (1LL<<x)-1
8000 ;; XXX this also needs to be fixed to handle equal subregs
8001 ;; XXX first before we could re-enable it.
8003 ; [(set (match_operand:DI 0 "register_operand" "=h")
8004 ; (plus:DI (ashift:DI (const_int 1)
8005 ; (match_operand:SI 1 "arith_operand" "rI"))
8007 ; "0 && TARGET_V8PLUS"
8010 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8011 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8012 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8014 ; [(set_attr "type" "multi")
8015 ; (set_attr "length" "4")])
8017 (define_insn "*cmp_cc_ashift_1"
8018 [(set (reg:CC_NOOV 100)
8019 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8023 "addcc\\t%0, %0, %%g0"
8024 [(set_attr "type" "compare")])
8026 (define_insn "*cmp_cc_set_ashift_1"
8027 [(set (reg:CC_NOOV 100)
8028 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8031 (set (match_operand:SI 0 "register_operand" "=r")
8032 (ashift:SI (match_dup 1) (const_int 1)))]
8034 "addcc\\t%1, %1, %0"
8035 [(set_attr "type" "compare")])
8037 (define_insn "ashrsi3"
8038 [(set (match_operand:SI 0 "register_operand" "=r")
8039 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8040 (match_operand:SI 2 "arith_operand" "rI")))]
8044 if (GET_CODE (operands[2]) == CONST_INT
8045 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8046 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8048 return \"sra\\t%1, %2, %0\";
8050 [(set_attr "type" "shift")])
8052 (define_insn "*ashrsi3_extend"
8053 [(set (match_operand:DI 0 "register_operand" "=r")
8054 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8055 (match_operand:SI 2 "arith_operand" "r"))))]
8058 [(set_attr "type" "shift")])
8060 ;; This handles the case as above, but with constant shift instead of
8061 ;; register. Combiner "simplifies" it for us a little bit though.
8062 (define_insn "*ashrsi3_extend2"
8063 [(set (match_operand:DI 0 "register_operand" "=r")
8064 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8066 (match_operand:SI 2 "small_int_or_double" "n")))]
8068 && ((GET_CODE (operands[2]) == CONST_INT
8069 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8070 || (GET_CODE (operands[2]) == CONST_DOUBLE
8071 && !CONST_DOUBLE_HIGH (operands[2])
8072 && CONST_DOUBLE_LOW (operands[2]) >= 32
8073 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8076 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8078 return \"sra\\t%1, %2, %0\";
8080 [(set_attr "type" "shift")])
8082 (define_expand "ashrdi3"
8083 [(set (match_operand:DI 0 "register_operand" "=r")
8084 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8085 (match_operand:SI 2 "arith_operand" "rI")))]
8086 "TARGET_ARCH64 || TARGET_V8PLUS"
8089 if (! TARGET_ARCH64)
8091 if (GET_CODE (operands[2]) == CONST_INT)
8092 FAIL; /* prefer generic code in this case */
8093 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8099 [(set (match_operand:DI 0 "register_operand" "=r")
8100 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8101 (match_operand:SI 2 "arith_operand" "rI")))]
8105 if (GET_CODE (operands[2]) == CONST_INT
8106 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8107 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8109 return \"srax\\t%1, %2, %0\";
8111 [(set_attr "type" "shift")])
8114 (define_insn "ashrdi3_v8plus"
8115 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8116 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8117 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8118 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8120 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8121 [(set_attr "type" "multi")
8122 (set_attr "length" "5,5,6")])
8124 (define_insn "lshrsi3"
8125 [(set (match_operand:SI 0 "register_operand" "=r")
8126 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8127 (match_operand:SI 2 "arith_operand" "rI")))]
8131 if (GET_CODE (operands[2]) == CONST_INT
8132 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8133 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8135 return \"srl\\t%1, %2, %0\";
8137 [(set_attr "type" "shift")])
8139 ;; This handles the case where
8140 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8141 ;; but combiner "simplifies" it for us.
8142 (define_insn "*lshrsi3_extend"
8143 [(set (match_operand:DI 0 "register_operand" "=r")
8144 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8145 (match_operand:SI 2 "arith_operand" "r")) 0)
8146 (match_operand 3 "" "")))]
8148 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8149 && CONST_DOUBLE_HIGH (operands[3]) == 0
8150 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8151 || (HOST_BITS_PER_WIDE_INT >= 64
8152 && GET_CODE (operands[3]) == CONST_INT
8153 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8155 [(set_attr "type" "shift")])
8157 ;; This handles the case where
8158 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8159 ;; but combiner "simplifies" it for us.
8160 (define_insn "*lshrsi3_extend2"
8161 [(set (match_operand:DI 0 "register_operand" "=r")
8162 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8163 (match_operand 2 "small_int_or_double" "n")
8166 && ((GET_CODE (operands[2]) == CONST_INT
8167 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8168 || (GET_CODE (operands[2]) == CONST_DOUBLE
8169 && CONST_DOUBLE_HIGH (operands[2]) == 0
8170 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8173 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8175 return \"srl\\t%1, %2, %0\";
8177 [(set_attr "type" "shift")])
8179 (define_expand "lshrdi3"
8180 [(set (match_operand:DI 0 "register_operand" "=r")
8181 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8182 (match_operand:SI 2 "arith_operand" "rI")))]
8183 "TARGET_ARCH64 || TARGET_V8PLUS"
8186 if (! TARGET_ARCH64)
8188 if (GET_CODE (operands[2]) == CONST_INT)
8190 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8196 [(set (match_operand:DI 0 "register_operand" "=r")
8197 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8198 (match_operand:SI 2 "arith_operand" "rI")))]
8202 if (GET_CODE (operands[2]) == CONST_INT
8203 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8204 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8206 return \"srlx\\t%1, %2, %0\";
8208 [(set_attr "type" "shift")])
8211 (define_insn "lshrdi3_v8plus"
8212 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8213 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8214 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8215 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8217 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8218 [(set_attr "type" "multi")
8219 (set_attr "length" "5,5,6")])
8222 [(set (match_operand:SI 0 "register_operand" "=r")
8223 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8225 (match_operand:SI 2 "small_int_or_double" "n")))]
8227 && ((GET_CODE (operands[2]) == CONST_INT
8228 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8229 || (GET_CODE (operands[2]) == CONST_DOUBLE
8230 && !CONST_DOUBLE_HIGH (operands[2])
8231 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8234 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8236 return \"srax\\t%1, %2, %0\";
8238 [(set_attr "type" "shift")])
8241 [(set (match_operand:SI 0 "register_operand" "=r")
8242 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8244 (match_operand:SI 2 "small_int_or_double" "n")))]
8246 && ((GET_CODE (operands[2]) == CONST_INT
8247 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8248 || (GET_CODE (operands[2]) == CONST_DOUBLE
8249 && !CONST_DOUBLE_HIGH (operands[2])
8250 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8253 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8255 return \"srlx\\t%1, %2, %0\";
8257 [(set_attr "type" "shift")])
8260 [(set (match_operand:SI 0 "register_operand" "=r")
8261 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8262 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8263 (match_operand:SI 3 "small_int_or_double" "n")))]
8265 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8266 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8267 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8268 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8271 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8273 return \"srax\\t%1, %2, %0\";
8275 [(set_attr "type" "shift")])
8278 [(set (match_operand:SI 0 "register_operand" "=r")
8279 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8280 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8281 (match_operand:SI 3 "small_int_or_double" "n")))]
8283 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8284 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8285 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8286 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8289 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8291 return \"srlx\\t%1, %2, %0\";
8293 [(set_attr "type" "shift")])
8295 ;; Unconditional and other jump instructions
8296 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8297 ;; following insn is never executed. This saves us a nop. Dbx does not
8298 ;; handle such branches though, so we only use them when optimizing.
8300 [(set (pc) (label_ref (match_operand 0 "" "")))]
8304 /* TurboSparc is reported to have problems with
8307 i.e. an empty loop with the annul bit set. The workaround is to use
8311 if (! TARGET_V9 && flag_delayed_branch
8312 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8313 == INSN_ADDRESSES (INSN_UID (insn))))
8314 return \"b\\t%l0%#\";
8316 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8318 [(set_attr "type" "uncond_branch")])
8320 (define_expand "tablejump"
8321 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8322 (use (label_ref (match_operand 1 "" "")))])]
8326 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8329 /* In pic mode, our address differences are against the base of the
8330 table. Add that base value back in; CSE ought to be able to combine
8331 the two address loads. */
8335 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8337 if (CASE_VECTOR_MODE != Pmode)
8338 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8339 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8340 operands[0] = memory_address (Pmode, tmp);
8344 (define_insn "*tablejump_sp32"
8345 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8346 (use (label_ref (match_operand 1 "" "")))]
8349 [(set_attr "type" "uncond_branch")])
8351 (define_insn "*tablejump_sp64"
8352 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8353 (use (label_ref (match_operand 1 "" "")))]
8356 [(set_attr "type" "uncond_branch")])
8358 ;; This pattern recognizes the "instruction" that appears in
8359 ;; a function call that wants a structure value,
8360 ;; to inform the called function if compiled with Sun CC.
8361 ;(define_insn "*unimp_insn"
8362 ; [(match_operand:SI 0 "immediate_operand" "")]
8363 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8365 ; [(set_attr "type" "marker")])
8367 ;;- jump to subroutine
8368 (define_expand "call"
8369 ;; Note that this expression is not used for generating RTL.
8370 ;; All the RTL is generated explicitly below.
8371 [(call (match_operand 0 "call_operand" "")
8372 (match_operand 3 "" "i"))]
8373 ;; operands[2] is next_arg_register
8374 ;; operands[3] is struct_value_size_rtx.
8378 rtx fn_rtx, nregs_rtx;
8380 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8383 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8385 /* This is really a PIC sequence. We want to represent
8386 it as a funny jump so its delay slots can be filled.
8388 ??? But if this really *is* a CALL, will not it clobber the
8389 call-clobbered registers? We lose this if it is a JUMP_INSN.
8390 Why cannot we have delay slots filled if it were a CALL? */
8392 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8397 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8399 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8405 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8406 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8410 fn_rtx = operands[0];
8412 /* Count the number of parameter registers being used by this call.
8413 if that argument is NULL, it means we are using them all, which
8414 means 6 on the sparc. */
8417 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8419 nregs_rtx = GEN_INT (6);
8421 nregs_rtx = const0_rtx;
8424 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8428 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8430 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8435 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8436 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8440 /* If this call wants a structure value,
8441 emit an unimp insn to let the called function know about this. */
8442 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8444 rtx insn = emit_insn (operands[3]);
8445 SCHED_GROUP_P (insn) = 1;
8452 ;; We can't use the same pattern for these two insns, because then registers
8453 ;; in the address may not be properly reloaded.
8455 (define_insn "*call_address_sp32"
8456 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8457 (match_operand 1 "" ""))
8458 (clobber (reg:SI 15))]
8459 ;;- Do not use operand 1 for most machines.
8462 [(set_attr "type" "call")])
8464 (define_insn "*call_symbolic_sp32"
8465 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8466 (match_operand 1 "" ""))
8467 (clobber (reg:SI 15))]
8468 ;;- Do not use operand 1 for most machines.
8471 [(set_attr "type" "call")])
8473 (define_insn "*call_address_sp64"
8474 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8475 (match_operand 1 "" ""))
8476 (clobber (reg:DI 15))]
8477 ;;- Do not use operand 1 for most machines.
8480 [(set_attr "type" "call")])
8482 (define_insn "*call_symbolic_sp64"
8483 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8484 (match_operand 1 "" ""))
8485 (clobber (reg:DI 15))]
8486 ;;- Do not use operand 1 for most machines.
8489 [(set_attr "type" "call")])
8491 ;; This is a call that wants a structure value.
8492 ;; There is no such critter for v9 (??? we may need one anyway).
8493 (define_insn "*call_address_struct_value_sp32"
8494 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8495 (match_operand 1 "" ""))
8496 (match_operand 2 "immediate_operand" "")
8497 (clobber (reg:SI 15))]
8498 ;;- Do not use operand 1 for most machines.
8499 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8500 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8501 [(set_attr "type" "call_no_delay_slot")
8502 (set_attr "length" "2")])
8504 ;; This is a call that wants a structure value.
8505 ;; There is no such critter for v9 (??? we may need one anyway).
8506 (define_insn "*call_symbolic_struct_value_sp32"
8507 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8508 (match_operand 1 "" ""))
8509 (match_operand 2 "immediate_operand" "")
8510 (clobber (reg:SI 15))]
8511 ;;- Do not use operand 1 for most machines.
8512 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8513 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8514 [(set_attr "type" "call_no_delay_slot")
8515 (set_attr "length" "2")])
8517 ;; This is a call that may want a structure value. This is used for
8519 (define_insn "*call_address_untyped_struct_value_sp32"
8520 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8521 (match_operand 1 "" ""))
8522 (match_operand 2 "immediate_operand" "")
8523 (clobber (reg:SI 15))]
8524 ;;- Do not use operand 1 for most machines.
8525 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8526 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8527 [(set_attr "type" "call_no_delay_slot")
8528 (set_attr "length" "2")])
8530 ;; This is a call that wants a structure value.
8531 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8532 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8533 (match_operand 1 "" ""))
8534 (match_operand 2 "immediate_operand" "")
8535 (clobber (reg:SI 15))]
8536 ;;- Do not use operand 1 for most machines.
8537 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8538 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8539 [(set_attr "type" "call_no_delay_slot")
8540 (set_attr "length" "2")])
8542 (define_expand "call_value"
8543 ;; Note that this expression is not used for generating RTL.
8544 ;; All the RTL is generated explicitly below.
8545 [(set (match_operand 0 "register_operand" "=rf")
8546 (call (match_operand 1 "" "")
8547 (match_operand 4 "" "")))]
8548 ;; operand 2 is stack_size_rtx
8549 ;; operand 3 is next_arg_register
8553 rtx fn_rtx, nregs_rtx;
8556 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8559 fn_rtx = operands[1];
8563 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8565 nregs_rtx = GEN_INT (6);
8567 nregs_rtx = const0_rtx;
8571 gen_rtx_SET (VOIDmode, operands[0],
8572 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8573 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8575 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8580 (define_insn "*call_value_address_sp32"
8581 [(set (match_operand 0 "" "=rf")
8582 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8583 (match_operand 2 "" "")))
8584 (clobber (reg:SI 15))]
8585 ;;- Do not use operand 2 for most machines.
8588 [(set_attr "type" "call")])
8590 (define_insn "*call_value_symbolic_sp32"
8591 [(set (match_operand 0 "" "=rf")
8592 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8593 (match_operand 2 "" "")))
8594 (clobber (reg:SI 15))]
8595 ;;- Do not use operand 2 for most machines.
8598 [(set_attr "type" "call")])
8600 (define_insn "*call_value_address_sp64"
8601 [(set (match_operand 0 "" "")
8602 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8603 (match_operand 2 "" "")))
8604 (clobber (reg:DI 15))]
8605 ;;- Do not use operand 2 for most machines.
8608 [(set_attr "type" "call")])
8610 (define_insn "*call_value_symbolic_sp64"
8611 [(set (match_operand 0 "" "")
8612 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8613 (match_operand 2 "" "")))
8614 (clobber (reg:DI 15))]
8615 ;;- Do not use operand 2 for most machines.
8618 [(set_attr "type" "call")])
8620 (define_expand "untyped_call"
8621 [(parallel [(call (match_operand 0 "" "")
8623 (match_operand 1 "" "")
8624 (match_operand 2 "" "")])]
8630 /* Pass constm1 to indicate that it may expect a structure value, but
8631 we don't know what size it is. */
8632 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8634 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8636 rtx set = XVECEXP (operands[2], 0, i);
8637 emit_move_insn (SET_DEST (set), SET_SRC (set));
8640 /* The optimizer does not know that the call sets the function value
8641 registers we stored in the result block. We avoid problems by
8642 claiming that all hard registers are used and clobbered at this
8644 emit_insn (gen_blockage ());
8650 (define_expand "sibcall"
8651 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8656 (define_insn "*sibcall_symbolic_sp32"
8657 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8658 (match_operand 1 "" ""))
8661 "* return output_sibcall(insn, operands[0]);"
8662 [(set_attr "type" "sibcall")])
8664 (define_insn "*sibcall_symbolic_sp64"
8665 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8666 (match_operand 1 "" ""))
8669 "* return output_sibcall(insn, operands[0]);"
8670 [(set_attr "type" "sibcall")])
8672 (define_expand "sibcall_value"
8673 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8674 (call (match_operand 1 "" "") (const_int 0)))
8679 (define_insn "*sibcall_value_symbolic_sp32"
8680 [(set (match_operand 0 "" "=rf")
8681 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8682 (match_operand 2 "" "")))
8685 "* return output_sibcall(insn, operands[1]);"
8686 [(set_attr "type" "sibcall")])
8688 (define_insn "*sibcall_value_symbolic_sp64"
8689 [(set (match_operand 0 "" "")
8690 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8691 (match_operand 2 "" "")))
8694 "* return output_sibcall(insn, operands[1]);"
8695 [(set_attr "type" "sibcall")])
8697 (define_expand "sibcall_epilogue"
8702 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8703 ;; all of memory. This blocks insns from being moved across this point.
8705 (define_insn "blockage"
8706 [(unspec_volatile [(const_int 0)] 0)]
8709 [(set_attr "length" "0")])
8711 ;; Prepare to return any type including a structure value.
8713 (define_expand "untyped_return"
8714 [(match_operand:BLK 0 "memory_operand" "")
8715 (match_operand 1 "" "")]
8719 rtx valreg1 = gen_rtx_REG (DImode, 24);
8720 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8721 rtx result = operands[0];
8723 if (! TARGET_ARCH64)
8725 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8727 rtx value = gen_reg_rtx (SImode);
8729 /* Fetch the instruction where we will return to and see if it's an unimp
8730 instruction (the most significant 10 bits will be zero). If so,
8731 update the return address to skip the unimp instruction. */
8732 emit_move_insn (value,
8733 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8734 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8735 emit_insn (gen_update_return (rtnreg, value));
8738 /* Reload the function value registers. */
8739 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8740 emit_move_insn (valreg2,
8741 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8743 /* Put USE insns before the return. */
8744 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8745 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8747 /* Construct the return. */
8748 expand_null_return ();
8753 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8754 ;; and parts of the compiler don't want to believe that the add is needed.
8756 (define_insn "update_return"
8757 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8758 (match_operand:SI 1 "register_operand" "r")] 1)]
8760 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8761 [(set_attr "type" "multi")
8762 (set_attr "length" "3")])
8764 (define_insn "return"
8768 "* return output_return (operands);"
8769 [(set_attr "type" "return")])
8772 [(set (match_operand:SI 0 "register_operand" "=r")
8773 (match_operand:SI 1 "arith_operand" "rI"))
8775 (use (reg:SI 31))])]
8776 "sparc_return_peephole_ok (operands[0], operands[1])"
8777 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8784 (define_expand "indirect_jump"
8785 [(set (pc) (match_operand 0 "address_operand" "p"))]
8789 (define_insn "*branch_sp32"
8790 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8793 [(set_attr "type" "uncond_branch")])
8795 (define_insn "*branch_sp64"
8796 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8799 [(set_attr "type" "uncond_branch")])
8801 ;; ??? Doesn't work with -mflat.
8802 (define_expand "nonlocal_goto"
8803 [(match_operand:SI 0 "general_operand" "")
8804 (match_operand:SI 1 "general_operand" "")
8805 (match_operand:SI 2 "general_operand" "")
8806 (match_operand:SI 3 "" "")]
8811 rtx chain = operands[0];
8813 rtx lab = operands[1];
8814 rtx stack = operands[2];
8815 rtx fp = operands[3];
8818 /* Trap instruction to flush all the register windows. */
8819 emit_insn (gen_flush_register_windows ());
8821 /* Load the fp value for the containing fn into %fp. This is needed
8822 because STACK refers to %fp. Note that virtual register instantiation
8823 fails if the virtual %fp isn't set from a register. */
8824 if (GET_CODE (fp) != REG)
8825 fp = force_reg (Pmode, fp);
8826 emit_move_insn (virtual_stack_vars_rtx, fp);
8828 /* Find the containing function's current nonlocal goto handler,
8829 which will do any cleanups and then jump to the label. */
8830 labreg = gen_rtx_REG (Pmode, 8);
8831 emit_move_insn (labreg, lab);
8833 /* Restore %fp from stack pointer value for containing function.
8834 The restore insn that follows will move this to %sp,
8835 and reload the appropriate value into %fp. */
8836 emit_move_insn (hard_frame_pointer_rtx, stack);
8838 /* USE of frame_pointer_rtx added for consistency; not clear if
8840 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8841 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8844 /* Return, restoring reg window and jumping to goto handler. */
8845 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8846 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8848 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8854 /* Put in the static chain register the nonlocal label address. */
8855 emit_move_insn (static_chain_rtx, chain);
8858 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8859 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8864 ;; Special trap insn to flush register windows.
8865 (define_insn "flush_register_windows"
8866 [(unspec_volatile [(const_int 0)] 1)]
8868 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8869 [(set_attr "type" "misc")])
8871 (define_insn "goto_handler_and_restore"
8872 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8873 "GET_MODE (operands[0]) == Pmode"
8874 "jmp\\t%0+0\\n\\trestore"
8875 [(set_attr "type" "multi")
8876 (set_attr "length" "2")])
8878 ;;(define_insn "goto_handler_and_restore_v9"
8879 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8880 ;; (match_operand:SI 1 "register_operand" "=r,r")
8881 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8882 ;; "TARGET_V9 && ! TARGET_ARCH64"
8884 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8885 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8886 ;; [(set_attr "type" "multi")
8887 ;; (set_attr "length" "2,3")])
8889 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8890 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8891 ;; (match_operand:DI 1 "register_operand" "=r,r")
8892 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8893 ;; "TARGET_V9 && TARGET_ARCH64"
8895 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8896 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8897 ;; [(set_attr "type" "multi")
8898 ;; (set_attr "length" "2,3")])
8900 ;; For __builtin_setjmp we need to flush register windows iff the function
8901 ;; calls alloca as well, because otherwise the register window might be
8902 ;; saved after %sp adjustement and thus setjmp would crash
8903 (define_expand "builtin_setjmp_setup"
8904 [(match_operand 0 "register_operand" "r")]
8908 emit_insn (gen_do_builtin_setjmp_setup ());
8912 ;; ??? Should set length to zero when !current_function_calls_alloca,
8913 ;; ??? but there is no easy way to get at that definition. It would
8914 ;; ??? require including function.h into sparc-protos.h and that is
8915 ;; ??? likely not a good idea. -DaveM
8916 (define_insn "do_builtin_setjmp_setup"
8917 [(unspec_volatile [(const_int 0)] 5)]
8921 if (!current_function_calls_alloca)
8927 [(set_attr "type" "misc")])
8929 ;; Pattern for use after a setjmp to store FP and the return register
8930 ;; into the stack area.
8932 (define_expand "setjmp"
8938 emit_insn (gen_setjmp_64 ());
8940 emit_insn (gen_setjmp_32 ());
8944 (define_expand "setjmp_32"
8945 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8946 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8949 { operands[0] = frame_pointer_rtx; }")
8951 (define_expand "setjmp_64"
8952 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8953 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8956 { operands[0] = frame_pointer_rtx; }")
8958 ;; Special pattern for the FLUSH instruction.
8960 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8961 ; of the define_insn otherwise missing a mode. We make "flush", aka
8962 ; gen_flush, the default one since sparc_initialize_trampoline uses
8963 ; it on SImode mem values.
8965 (define_insn "flush"
8966 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8968 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8969 [(set_attr "type" "misc")])
8971 (define_insn "flushdi"
8972 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8974 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8975 [(set_attr "type" "misc")])
8980 ;; The scan instruction searches from the most significant bit while ffs
8981 ;; searches from the least significant bit. The bit index and treatment of
8982 ;; zero also differ. It takes at least 7 instructions to get the proper
8983 ;; result. Here is an obvious 8 instruction sequence.
8986 (define_insn "ffssi2"
8987 [(set (match_operand:SI 0 "register_operand" "=&r")
8988 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8989 (clobber (match_scratch:SI 2 "=&r"))]
8990 "TARGET_SPARCLITE || TARGET_SPARCLET"
8993 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\";
8995 [(set_attr "type" "multi")
8996 (set_attr "length" "8")])
8998 ;; ??? This should be a define expand, so that the extra instruction have
8999 ;; a chance of being optimized away.
9001 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9002 ;; does, but no one uses that and we don't have a switch for it.
9004 ;(define_insn "ffsdi2"
9005 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9006 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9007 ; (clobber (match_scratch:DI 2 "=&r"))]
9009 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9010 ; [(set_attr "type" "multi")
9011 ; (set_attr "length" "4")])
9015 ;; Peepholes go at the end.
9017 ;; Optimize consecutive loads or stores into ldd and std when possible.
9018 ;; The conditions in which we do this are very restricted and are
9019 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9022 [(set (match_operand:SI 0 "memory_operand" "")
9024 (set (match_operand:SI 1 "memory_operand" "")
9027 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
9030 "operands[0] = change_address (operands[0], DImode, NULL);")
9033 [(set (match_operand:SI 0 "memory_operand" "")
9035 (set (match_operand:SI 1 "memory_operand" "")
9038 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9041 "operands[1] = change_address (operands[1], DImode, NULL);")
9044 [(set (match_operand:SI 0 "register_operand" "")
9045 (match_operand:SI 1 "memory_operand" ""))
9046 (set (match_operand:SI 2 "register_operand" "")
9047 (match_operand:SI 3 "memory_operand" ""))]
9048 "registers_ok_for_ldd_peep (operands[0], operands[2])
9049 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9052 "operands[1] = change_address (operands[1], DImode, NULL);
9053 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9056 [(set (match_operand:SI 0 "memory_operand" "")
9057 (match_operand:SI 1 "register_operand" ""))
9058 (set (match_operand:SI 2 "memory_operand" "")
9059 (match_operand:SI 3 "register_operand" ""))]
9060 "registers_ok_for_ldd_peep (operands[1], operands[3])
9061 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9064 "operands[0] = change_address (operands[0], DImode, NULL);
9065 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9068 [(set (match_operand:SF 0 "register_operand" "")
9069 (match_operand:SF 1 "memory_operand" ""))
9070 (set (match_operand:SF 2 "register_operand" "")
9071 (match_operand:SF 3 "memory_operand" ""))]
9072 "registers_ok_for_ldd_peep (operands[0], operands[2])
9073 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9076 "operands[1] = change_address (operands[1], DFmode, NULL);
9077 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9080 [(set (match_operand:SF 0 "memory_operand" "")
9081 (match_operand:SF 1 "register_operand" ""))
9082 (set (match_operand:SF 2 "memory_operand" "")
9083 (match_operand:SF 3 "register_operand" ""))]
9084 "registers_ok_for_ldd_peep (operands[1], operands[3])
9085 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9088 "operands[0] = change_address (operands[0], DFmode, NULL);
9089 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9092 [(set (match_operand:SI 0 "register_operand" "")
9093 (match_operand:SI 1 "memory_operand" ""))
9094 (set (match_operand:SI 2 "register_operand" "")
9095 (match_operand:SI 3 "memory_operand" ""))]
9096 "registers_ok_for_ldd_peep (operands[2], operands[0])
9097 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9100 "operands[3] = change_address (operands[3], DImode, NULL);
9101 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9104 [(set (match_operand:SI 0 "memory_operand" "")
9105 (match_operand:SI 1 "register_operand" ""))
9106 (set (match_operand:SI 2 "memory_operand" "")
9107 (match_operand:SI 3 "register_operand" ""))]
9108 "registers_ok_for_ldd_peep (operands[3], operands[1])
9109 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9112 "operands[2] = change_address (operands[2], DImode, NULL);
9113 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9117 [(set (match_operand:SF 0 "register_operand" "")
9118 (match_operand:SF 1 "memory_operand" ""))
9119 (set (match_operand:SF 2 "register_operand" "")
9120 (match_operand:SF 3 "memory_operand" ""))]
9121 "registers_ok_for_ldd_peep (operands[2], operands[0])
9122 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9125 "operands[3] = change_address (operands[3], DFmode, NULL);
9126 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9129 [(set (match_operand:SF 0 "memory_operand" "")
9130 (match_operand:SF 1 "register_operand" ""))
9131 (set (match_operand:SF 2 "memory_operand" "")
9132 (match_operand:SF 3 "register_operand" ""))]
9133 "registers_ok_for_ldd_peep (operands[3], operands[1])
9134 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9137 "operands[2] = change_address (operands[2], DFmode, NULL);
9138 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9140 ;; Optimize the case of following a reg-reg move with a test
9141 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9142 ;; This can result from a float to fix conversion.
9145 [(set (match_operand:SI 0 "register_operand" "")
9146 (match_operand:SI 1 "register_operand" ""))
9148 (compare:CC (match_operand:SI 2 "register_operand" "")
9150 "(rtx_equal_p (operands[2], operands[0])
9151 || rtx_equal_p (operands[2], operands[1]))
9152 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9153 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9154 [(parallel [(set (match_dup 0) (match_dup 1))
9156 (compare:CC (match_dup 1) (const_int 0)))])]
9160 [(set (match_operand:DI 0 "register_operand" "")
9161 (match_operand:DI 1 "register_operand" ""))
9163 (compare:CCX (match_operand:DI 2 "register_operand" "")
9166 && (rtx_equal_p (operands[2], operands[0])
9167 || rtx_equal_p (operands[2], operands[1]))
9168 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9169 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9170 [(parallel [(set (match_dup 0) (match_dup 1))
9172 (compare:CC (match_dup 1) (const_int 0)))])]
9175 ;; Return peepholes. First the "normal" ones.
9176 ;; These are necessary to catch insns ending up in the epilogue delay list.
9178 (define_insn "*return_qi"
9179 [(set (match_operand:QI 0 "restore_operand" "")
9180 (match_operand:QI 1 "arith_operand" "rI"))
9185 if (! TARGET_ARCH64 && current_function_returns_struct)
9186 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9187 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9188 || IN_OR_GLOBAL_P (operands[1])))
9189 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9191 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9193 [(set_attr "type" "multi")
9194 (set_attr "length" "2")])
9196 (define_insn "*return_hi"
9197 [(set (match_operand:HI 0 "restore_operand" "")
9198 (match_operand:HI 1 "arith_operand" "rI"))
9203 if (! TARGET_ARCH64 && current_function_returns_struct)
9204 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9205 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9206 || IN_OR_GLOBAL_P (operands[1])))
9207 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9209 return \"ret\;restore %%g0, %1, %Y0\";
9211 [(set_attr "type" "multi")
9212 (set_attr "length" "2")])
9214 (define_insn "*return_si"
9215 [(set (match_operand:SI 0 "restore_operand" "")
9216 (match_operand:SI 1 "arith_operand" "rI"))
9221 if (! TARGET_ARCH64 && current_function_returns_struct)
9222 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9223 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9224 || 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 ;; The following pattern is only generated by delayed-branch scheduling,
9233 ;; when the insn winds up in the epilogue. This can happen not only when
9234 ;; ! TARGET_FPU because we move complex types around by parts using
9236 (define_insn "*return_sf_no_fpu"
9237 [(set (match_operand:SF 0 "restore_operand" "=r")
9238 (match_operand:SF 1 "register_operand" "r"))
9243 if (! TARGET_ARCH64 && current_function_returns_struct)
9244 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9245 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9246 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9248 return \"ret\;restore %%g0, %1, %Y0\";
9250 [(set_attr "type" "multi")
9251 (set_attr "length" "2")])
9253 (define_insn "*return_df_no_fpu"
9254 [(set (match_operand:DF 0 "restore_operand" "=r")
9255 (match_operand:DF 1 "register_operand" "r"))
9257 "! TARGET_EPILOGUE && TARGET_ARCH64"
9260 if (IN_OR_GLOBAL_P (operands[1]))
9261 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9263 return \"ret\;restore %%g0, %1, %Y0\";
9265 [(set_attr "type" "multi")
9266 (set_attr "length" "2")])
9268 (define_insn "*return_addsi"
9269 [(set (match_operand:SI 0 "restore_operand" "")
9270 (plus:SI (match_operand:SI 1 "register_operand" "r")
9271 (match_operand:SI 2 "arith_operand" "rI")))
9276 if (! TARGET_ARCH64 && current_function_returns_struct)
9277 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9278 /* If operands are global or in registers, can use return */
9279 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9280 && (GET_CODE (operands[2]) == CONST_INT
9281 || IN_OR_GLOBAL_P (operands[2])))
9282 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9284 return \"ret\;restore %r1, %2, %Y0\";
9286 [(set_attr "type" "multi")
9287 (set_attr "length" "2")])
9289 (define_insn "*return_losum_si"
9290 [(set (match_operand:SI 0 "restore_operand" "")
9291 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9292 (match_operand:SI 2 "immediate_operand" "in")))
9294 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9297 if (! TARGET_ARCH64 && current_function_returns_struct)
9298 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9299 /* If operands are global or in registers, can use return */
9300 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9301 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9303 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9305 [(set_attr "type" "multi")
9306 (set_attr "length" "2")])
9308 (define_insn "*return_di"
9309 [(set (match_operand:DI 0 "restore_operand" "")
9310 (match_operand:DI 1 "arith_double_operand" "rHI"))
9312 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9313 "ret\;restore %%g0, %1, %Y0"
9314 [(set_attr "type" "multi")
9315 (set_attr "length" "2")])
9317 (define_insn "*return_adddi"
9318 [(set (match_operand:DI 0 "restore_operand" "")
9319 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9320 (match_operand:DI 2 "arith_double_operand" "rHI")))
9322 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9323 "ret\;restore %r1, %2, %Y0"
9324 [(set_attr "type" "multi")
9325 (set_attr "length" "2")])
9327 (define_insn "*return_losum_di"
9328 [(set (match_operand:DI 0 "restore_operand" "")
9329 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9330 (match_operand:DI 2 "immediate_operand" "in")))
9332 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9333 "ret\;restore %r1, %%lo(%a2), %Y0"
9334 [(set_attr "type" "multi")
9335 (set_attr "length" "2")])
9337 ;; The following pattern is only generated by delayed-branch scheduling,
9338 ;; when the insn winds up in the epilogue.
9339 (define_insn "*return_sf"
9341 (match_operand:SF 0 "register_operand" "f"))
9344 "ret\;fmovs\\t%0, %%f0"
9345 [(set_attr "type" "multi")
9346 (set_attr "length" "2")])
9348 ;; Now peepholes to do a call followed by a jump.
9351 [(parallel [(set (match_operand 0 "" "")
9352 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9353 (match_operand 2 "" "")))
9354 (clobber (reg:SI 15))])
9355 (set (pc) (label_ref (match_operand 3 "" "")))]
9356 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9357 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9358 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9361 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9362 (match_operand 1 "" ""))
9363 (clobber (reg:SI 15))])
9364 (set (pc) (label_ref (match_operand 2 "" "")))]
9365 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9366 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9367 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9370 [(parallel [(set (match_operand 0 "" "")
9371 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9372 (match_operand 2 "" "")))
9373 (clobber (reg:DI 15))])
9374 (set (pc) (label_ref (match_operand 3 "" "")))]
9376 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9377 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9378 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9381 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9382 (match_operand 1 "" ""))
9383 (clobber (reg:DI 15))])
9384 (set (pc) (label_ref (match_operand 2 "" "")))]
9386 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9387 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9388 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9390 (define_insn "prefetch"
9391 [(prefetch (match_operand:DI 0 "address_operand" "p")
9392 (match_operand:DI 1 "const_int_operand" "n")
9393 (match_operand:DI 2 "const_int_operand" "n"))]
9396 static const char * const prefetch_instr[2][4] = {
9398 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9399 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9400 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9401 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9404 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9405 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9406 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9407 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9410 int read_or_write = INTVAL (operands[1]);
9411 int locality = INTVAL (operands[2]);
9413 if (read_or_write != 0 && read_or_write != 1)
9415 if (locality < 0 || locality > 3)
9417 return prefetch_instr [read_or_write][locality];
9419 [(set_attr "type" "load")])
9421 (define_expand "prologue"
9423 "flag_pic && current_function_uses_pic_offset_table"
9426 load_pic_register ();
9430 ;; We need to reload %l7 for -mflat -fpic,
9431 ;; otherwise %l7 should be preserved simply
9432 ;; by loading the function's register window
9433 (define_expand "exception_receiver"
9435 "TARGET_FLAT && flag_pic"
9438 load_pic_register ();
9443 (define_expand "builtin_setjmp_receiver"
9444 [(label_ref (match_operand 0 "" ""))]
9445 "TARGET_FLAT && flag_pic"
9448 load_pic_register ();
9453 [(trap_if (const_int 1) (const_int 5))]
9456 [(set_attr "type" "misc")])
9458 (define_expand "conditional_trap"
9459 [(trap_if (match_operator 0 "noov_compare_op"
9460 [(match_dup 2) (match_dup 3)])
9461 (match_operand:SI 1 "arith_operand" ""))]
9463 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9464 sparc_compare_op0, sparc_compare_op1);
9465 operands[3] = const0_rtx;")
9468 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9469 (match_operand:SI 1 "arith_operand" "rM"))]
9472 [(set_attr "type" "misc")])
9475 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9476 (match_operand:SI 1 "arith_operand" "rM"))]
9479 [(set_attr "type" "misc")])