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_insn "floatdidf2"
5247 [(set (match_operand:DF 0 "register_operand" "=e")
5248 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5249 "TARGET_V9 && TARGET_FPU"
5251 [(set_attr "type" "fp")
5252 (set_attr "fptype" "double")])
5254 (define_expand "floatditf2"
5255 [(set (match_operand:TF 0 "register_operand" "=e")
5256 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5257 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5260 if (! TARGET_HARD_QUAD)
5264 if (GET_CODE (operands[1]) != MEM)
5265 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5267 slot0 = operands[1];
5269 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5271 XEXP (slot0, 0), Pmode,
5272 operands[1], DImode);
5274 if (GET_CODE (operands[0]) != MEM)
5275 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5280 (define_insn "*floatditf2_hq"
5281 [(set (match_operand:TF 0 "register_operand" "=e")
5282 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5283 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5285 [(set_attr "type" "fp")])
5287 (define_expand "floatunsditf2"
5288 [(set (match_operand:TF 0 "register_operand" "=e")
5289 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5290 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5295 if (GET_CODE (operands[1]) != MEM)
5296 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5298 slot0 = operands[1];
5300 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5302 XEXP (slot0, 0), Pmode,
5303 operands[1], DImode);
5305 if (GET_CODE (operands[0]) != MEM)
5306 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5310 ;; Convert a float to an actual integer.
5311 ;; Truncation is performed as part of the conversion.
5313 (define_insn "fix_truncsfsi2"
5314 [(set (match_operand:SI 0 "register_operand" "=f")
5315 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5318 [(set_attr "type" "fp")
5319 (set_attr "fptype" "double")])
5321 (define_insn "fix_truncdfsi2"
5322 [(set (match_operand:SI 0 "register_operand" "=f")
5323 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5326 [(set_attr "type" "fp")
5327 (set_attr "fptype" "double")])
5329 (define_expand "fix_trunctfsi2"
5330 [(set (match_operand:SI 0 "register_operand" "=f")
5331 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5332 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5335 if (! TARGET_HARD_QUAD)
5339 if (GET_CODE (operands[1]) != MEM)
5341 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5342 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5345 slot0 = operands[1];
5347 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5348 operands[0], 0, SImode, 1,
5349 XEXP (slot0, 0), Pmode);
5354 (define_insn "*fix_trunctfsi2_hq"
5355 [(set (match_operand:SI 0 "register_operand" "=f")
5356 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5357 "TARGET_FPU && TARGET_HARD_QUAD"
5359 [(set_attr "type" "fp")])
5361 (define_expand "fixuns_trunctfsi2"
5362 [(set (match_operand:SI 0 "register_operand" "=f")
5363 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5364 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5369 if (GET_CODE (operands[1]) != MEM)
5371 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5372 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5375 slot0 = operands[1];
5377 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5378 operands[0], 0, SImode, 1,
5379 XEXP (slot0, 0), Pmode);
5383 ;; Now the same, for V9 targets
5385 (define_insn "fix_truncsfdi2"
5386 [(set (match_operand:DI 0 "register_operand" "=e")
5387 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5388 "TARGET_V9 && TARGET_FPU"
5390 [(set_attr "type" "fp")
5391 (set_attr "fptype" "double")])
5393 (define_insn "fix_truncdfdi2"
5394 [(set (match_operand:DI 0 "register_operand" "=e")
5395 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5396 "TARGET_V9 && TARGET_FPU"
5398 [(set_attr "type" "fp")
5399 (set_attr "fptype" "double")])
5401 (define_expand "fix_trunctfdi2"
5402 [(set (match_operand:DI 0 "register_operand" "=e")
5403 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5404 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5407 if (! TARGET_HARD_QUAD)
5411 if (GET_CODE (operands[1]) != MEM)
5413 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5414 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5417 slot0 = operands[1];
5419 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5420 operands[0], 0, DImode, 1,
5421 XEXP (slot0, 0), Pmode);
5426 (define_insn "*fix_trunctfdi2_hq"
5427 [(set (match_operand:DI 0 "register_operand" "=e")
5428 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5429 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5431 [(set_attr "type" "fp")])
5433 (define_expand "fixuns_trunctfdi2"
5434 [(set (match_operand:DI 0 "register_operand" "=f")
5435 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5436 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5441 if (GET_CODE (operands[1]) != MEM)
5443 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5444 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5447 slot0 = operands[1];
5449 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5450 operands[0], 0, DImode, 1,
5451 XEXP (slot0, 0), Pmode);
5456 ;;- arithmetic instructions
5458 (define_expand "adddi3"
5459 [(set (match_operand:DI 0 "register_operand" "=r")
5460 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5461 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5467 if (! TARGET_ARCH64)
5469 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5470 gen_rtx_SET (VOIDmode, operands[0],
5471 gen_rtx_PLUS (DImode, operands[1],
5473 gen_rtx_CLOBBER (VOIDmode,
5474 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5477 if (arith_double_4096_operand(operands[2], DImode))
5479 switch (GET_CODE (operands[1]))
5481 case CONST_INT: i = INTVAL (operands[1]); break;
5482 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5484 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5485 gen_rtx_MINUS (DImode, operands[1],
5489 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5494 (define_insn "adddi3_insn_sp32"
5495 [(set (match_operand:DI 0 "register_operand" "=r")
5496 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5497 (match_operand:DI 2 "arith_double_operand" "rHI")))
5498 (clobber (reg:CC 100))]
5501 [(set_attr "length" "2")])
5504 [(set (match_operand:DI 0 "register_operand" "")
5505 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5506 (match_operand:DI 2 "arith_double_operand" "")))
5507 (clobber (reg:CC 100))]
5508 "! TARGET_ARCH64 && reload_completed"
5509 [(parallel [(set (reg:CC_NOOV 100)
5510 (compare:CC_NOOV (plus:SI (match_dup 4)
5514 (plus:SI (match_dup 4) (match_dup 5)))])
5516 (plus:SI (plus:SI (match_dup 7)
5518 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5521 operands[3] = gen_lowpart (SImode, operands[0]);
5522 operands[4] = gen_lowpart (SImode, operands[1]);
5523 operands[5] = gen_lowpart (SImode, operands[2]);
5524 operands[6] = gen_highpart (SImode, operands[0]);
5525 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5526 #if HOST_BITS_PER_WIDE_INT == 32
5527 if (GET_CODE (operands[2]) == CONST_INT)
5529 if (INTVAL (operands[2]) < 0)
5530 operands[8] = constm1_rtx;
5532 operands[8] = const0_rtx;
5536 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5540 [(set (match_operand:DI 0 "register_operand" "")
5541 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5542 (match_operand:DI 2 "arith_double_operand" "")))
5543 (clobber (reg:CC 100))]
5544 "! TARGET_ARCH64 && reload_completed"
5545 [(parallel [(set (reg:CC_NOOV 100)
5546 (compare:CC_NOOV (minus:SI (match_dup 4)
5550 (minus:SI (match_dup 4) (match_dup 5)))])
5552 (minus:SI (minus:SI (match_dup 7)
5554 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5557 operands[3] = gen_lowpart (SImode, operands[0]);
5558 operands[4] = gen_lowpart (SImode, operands[1]);
5559 operands[5] = gen_lowpart (SImode, operands[2]);
5560 operands[6] = gen_highpart (SImode, operands[0]);
5561 operands[7] = gen_highpart (SImode, operands[1]);
5562 #if HOST_BITS_PER_WIDE_INT == 32
5563 if (GET_CODE (operands[2]) == CONST_INT)
5565 if (INTVAL (operands[2]) < 0)
5566 operands[8] = constm1_rtx;
5568 operands[8] = const0_rtx;
5572 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5575 ;; LTU here means "carry set"
5577 [(set (match_operand:SI 0 "register_operand" "=r")
5578 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5579 (match_operand:SI 2 "arith_operand" "rI"))
5580 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5583 [(set_attr "type" "misc")])
5585 (define_insn "*addx_extend_sp32"
5586 [(set (match_operand:DI 0 "register_operand" "=r")
5587 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5588 (match_operand:SI 2 "arith_operand" "rI"))
5589 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5592 [(set_attr "length" "2")])
5595 [(set (match_operand:DI 0 "register_operand" "")
5596 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5597 (match_operand:SI 2 "arith_operand" ""))
5598 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5599 "! TARGET_ARCH64 && reload_completed"
5600 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5601 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5602 (set (match_dup 4) (const_int 0))]
5603 "operands[3] = gen_lowpart (SImode, operands[0]);
5604 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5606 (define_insn "*addx_extend_sp64"
5607 [(set (match_operand:DI 0 "register_operand" "=r")
5608 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5609 (match_operand:SI 2 "arith_operand" "rI"))
5610 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5612 "addx\\t%r1, %2, %0"
5613 [(set_attr "type" "misc")])
5616 [(set (match_operand:SI 0 "register_operand" "=r")
5617 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5618 (match_operand:SI 2 "arith_operand" "rI"))
5619 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5621 "subx\\t%r1, %2, %0"
5622 [(set_attr "type" "misc")])
5624 (define_insn "*subx_extend_sp64"
5625 [(set (match_operand:DI 0 "register_operand" "=r")
5626 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5627 (match_operand:SI 2 "arith_operand" "rI"))
5628 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5630 "subx\\t%r1, %2, %0"
5631 [(set_attr "type" "misc")])
5633 (define_insn "*subx_extend"
5634 [(set (match_operand:DI 0 "register_operand" "=r")
5635 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5636 (match_operand:SI 2 "arith_operand" "rI"))
5637 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5640 [(set_attr "length" "2")])
5643 [(set (match_operand:DI 0 "register_operand" "")
5644 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5645 (match_operand:SI 2 "arith_operand" ""))
5646 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5647 "! TARGET_ARCH64 && reload_completed"
5648 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5649 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5650 (set (match_dup 4) (const_int 0))]
5651 "operands[3] = gen_lowpart (SImode, operands[0]);
5652 operands[4] = gen_highpart (SImode, operands[0]);")
5655 [(set (match_operand:DI 0 "register_operand" "=r")
5656 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5657 (match_operand:DI 2 "register_operand" "r")))
5658 (clobber (reg:CC 100))]
5661 [(set_attr "length" "2")])
5664 [(set (match_operand:DI 0 "register_operand" "")
5665 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5666 (match_operand:DI 2 "register_operand" "")))
5667 (clobber (reg:CC 100))]
5668 "! TARGET_ARCH64 && reload_completed"
5669 [(parallel [(set (reg:CC_NOOV 100)
5670 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5672 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5674 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5675 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5676 "operands[3] = gen_lowpart (SImode, operands[2]);
5677 operands[4] = gen_highpart (SImode, operands[2]);
5678 operands[5] = gen_lowpart (SImode, operands[0]);
5679 operands[6] = gen_highpart (SImode, operands[0]);")
5681 (define_insn "*adddi3_sp64"
5682 [(set (match_operand:DI 0 "register_operand" "=r")
5683 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5684 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5688 (define_expand "addsi3"
5689 [(set (match_operand:SI 0 "register_operand" "=r,d")
5690 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5691 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5695 if (arith_4096_operand(operands[2], SImode))
5697 if (GET_CODE (operands[1]) == CONST_INT)
5698 emit_insn (gen_movsi (operands[0],
5699 GEN_INT (INTVAL (operands[1]) + 4096)));
5701 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5702 gen_rtx_MINUS (SImode, operands[1],
5708 (define_insn "*addsi3"
5709 [(set (match_operand:SI 0 "register_operand" "=r,d")
5710 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5711 (match_operand:SI 2 "arith_operand" "rI,d")))]
5715 fpadd32s\\t%1, %2, %0"
5716 [(set_attr "type" "*,fp")])
5718 (define_insn "*cmp_cc_plus"
5719 [(set (reg:CC_NOOV 100)
5720 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5721 (match_operand:SI 1 "arith_operand" "rI"))
5724 "addcc\\t%0, %1, %%g0"
5725 [(set_attr "type" "compare")])
5727 (define_insn "*cmp_ccx_plus"
5728 [(set (reg:CCX_NOOV 100)
5729 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5730 (match_operand:DI 1 "arith_double_operand" "rHI"))
5733 "addcc\\t%0, %1, %%g0"
5734 [(set_attr "type" "compare")])
5736 (define_insn "*cmp_cc_plus_set"
5737 [(set (reg:CC_NOOV 100)
5738 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5739 (match_operand:SI 2 "arith_operand" "rI"))
5741 (set (match_operand:SI 0 "register_operand" "=r")
5742 (plus:SI (match_dup 1) (match_dup 2)))]
5744 "addcc\\t%1, %2, %0"
5745 [(set_attr "type" "compare")])
5747 (define_insn "*cmp_ccx_plus_set"
5748 [(set (reg:CCX_NOOV 100)
5749 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5750 (match_operand:DI 2 "arith_double_operand" "rHI"))
5752 (set (match_operand:DI 0 "register_operand" "=r")
5753 (plus:DI (match_dup 1) (match_dup 2)))]
5755 "addcc\\t%1, %2, %0"
5756 [(set_attr "type" "compare")])
5758 (define_expand "subdi3"
5759 [(set (match_operand:DI 0 "register_operand" "=r")
5760 (minus:DI (match_operand:DI 1 "register_operand" "r")
5761 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5765 if (! TARGET_ARCH64)
5767 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5768 gen_rtx_SET (VOIDmode, operands[0],
5769 gen_rtx_MINUS (DImode, operands[1],
5771 gen_rtx_CLOBBER (VOIDmode,
5772 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5775 if (arith_double_4096_operand(operands[2], DImode))
5777 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5778 gen_rtx_PLUS (DImode, operands[1],
5784 (define_insn "*subdi3_sp32"
5785 [(set (match_operand:DI 0 "register_operand" "=r")
5786 (minus:DI (match_operand:DI 1 "register_operand" "r")
5787 (match_operand:DI 2 "arith_double_operand" "rHI")))
5788 (clobber (reg:CC 100))]
5791 [(set_attr "length" "2")])
5794 [(set (match_operand:DI 0 "register_operand" "")
5795 (minus:DI (match_operand:DI 1 "register_operand" "")
5796 (match_operand:DI 2 "arith_double_operand" "")))
5797 (clobber (reg:CC 100))]
5800 && (GET_CODE (operands[2]) == CONST_INT
5801 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5802 [(clobber (const_int 0))]
5807 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5808 lowp = gen_lowpart (SImode, operands[2]);
5809 if ((lowp == const0_rtx)
5810 && (operands[0] == operands[1]))
5812 emit_insn (gen_rtx_SET (VOIDmode,
5813 gen_highpart (SImode, operands[0]),
5814 gen_rtx_MINUS (SImode,
5815 gen_highpart_mode (SImode, DImode,
5821 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5822 gen_lowpart (SImode, operands[1]),
5824 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5825 gen_highpart_mode (SImode, DImode, operands[1]),
5832 [(set (match_operand:DI 0 "register_operand" "")
5833 (minus:DI (match_operand:DI 1 "register_operand" "")
5834 (match_operand:DI 2 "register_operand" "")))
5835 (clobber (reg:CC 100))]
5837 && reload_completed"
5838 [(clobber (const_int 0))]
5841 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5842 gen_lowpart (SImode, operands[1]),
5843 gen_lowpart (SImode, operands[2])));
5844 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5845 gen_highpart (SImode, operands[1]),
5846 gen_highpart (SImode, operands[2])));
5851 [(set (match_operand:DI 0 "register_operand" "=r")
5852 (minus:DI (match_operand:DI 1 "register_operand" "r")
5853 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5854 (clobber (reg:CC 100))]
5857 [(set_attr "length" "2")])
5860 [(set (match_operand:DI 0 "register_operand" "")
5861 (minus:DI (match_operand:DI 1 "register_operand" "")
5862 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5863 (clobber (reg:CC 100))]
5864 "! TARGET_ARCH64 && reload_completed"
5865 [(parallel [(set (reg:CC_NOOV 100)
5866 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5868 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5870 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5871 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5872 "operands[3] = gen_lowpart (SImode, operands[1]);
5873 operands[4] = gen_highpart (SImode, operands[1]);
5874 operands[5] = gen_lowpart (SImode, operands[0]);
5875 operands[6] = gen_highpart (SImode, operands[0]);")
5877 (define_insn "*subdi3_sp64"
5878 [(set (match_operand:DI 0 "register_operand" "=r")
5879 (minus:DI (match_operand:DI 1 "register_operand" "r")
5880 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5884 (define_expand "subsi3"
5885 [(set (match_operand:SI 0 "register_operand" "=r,d")
5886 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5887 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5891 if (arith_4096_operand(operands[2], SImode))
5893 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5894 gen_rtx_PLUS (SImode, operands[1],
5900 (define_insn "*subsi3"
5901 [(set (match_operand:SI 0 "register_operand" "=r,d")
5902 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5903 (match_operand:SI 2 "arith_operand" "rI,d")))]
5907 fpsub32s\\t%1, %2, %0"
5908 [(set_attr "type" "*,fp")])
5910 (define_insn "*cmp_minus_cc"
5911 [(set (reg:CC_NOOV 100)
5912 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5913 (match_operand:SI 1 "arith_operand" "rI"))
5916 "subcc\\t%r0, %1, %%g0"
5917 [(set_attr "type" "compare")])
5919 (define_insn "*cmp_minus_ccx"
5920 [(set (reg:CCX_NOOV 100)
5921 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5922 (match_operand:DI 1 "arith_double_operand" "rHI"))
5925 "subcc\\t%0, %1, %%g0"
5926 [(set_attr "type" "compare")])
5928 (define_insn "cmp_minus_cc_set"
5929 [(set (reg:CC_NOOV 100)
5930 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5931 (match_operand:SI 2 "arith_operand" "rI"))
5933 (set (match_operand:SI 0 "register_operand" "=r")
5934 (minus:SI (match_dup 1) (match_dup 2)))]
5936 "subcc\\t%r1, %2, %0"
5937 [(set_attr "type" "compare")])
5939 (define_insn "*cmp_minus_ccx_set"
5940 [(set (reg:CCX_NOOV 100)
5941 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5942 (match_operand:DI 2 "arith_double_operand" "rHI"))
5944 (set (match_operand:DI 0 "register_operand" "=r")
5945 (minus:DI (match_dup 1) (match_dup 2)))]
5947 "subcc\\t%1, %2, %0"
5948 [(set_attr "type" "compare")])
5950 ;; Integer Multiply/Divide.
5952 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5953 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5955 (define_insn "mulsi3"
5956 [(set (match_operand:SI 0 "register_operand" "=r")
5957 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5958 (match_operand:SI 2 "arith_operand" "rI")))]
5961 [(set_attr "type" "imul")])
5963 (define_expand "muldi3"
5964 [(set (match_operand:DI 0 "register_operand" "=r")
5965 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5966 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5967 "TARGET_ARCH64 || TARGET_V8PLUS"
5972 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5977 (define_insn "*muldi3_sp64"
5978 [(set (match_operand:DI 0 "register_operand" "=r")
5979 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5980 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5983 [(set_attr "type" "imul")])
5985 ;; V8plus wide multiply.
5987 (define_insn "muldi3_v8plus"
5988 [(set (match_operand:DI 0 "register_operand" "=r,h")
5989 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5990 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5991 (clobber (match_scratch:SI 3 "=&h,X"))
5992 (clobber (match_scratch:SI 4 "=&h,X"))]
5996 if (sparc_check_64 (operands[1], insn) <= 0)
5997 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5998 if (which_alternative == 1)
5999 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6000 if (GET_CODE (operands[2]) == CONST_INT)
6002 if (which_alternative == 1)
6003 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6005 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\";
6007 if (sparc_check_64 (operands[2], insn) <= 0)
6008 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6009 if (which_alternative == 1)
6010 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\";
6012 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\";
6014 [(set_attr "type" "multi")
6015 (set_attr "length" "9,8")])
6017 (define_insn "*cmp_mul_set"
6019 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6020 (match_operand:SI 2 "arith_operand" "rI"))
6022 (set (match_operand:SI 0 "register_operand" "=r")
6023 (mult:SI (match_dup 1) (match_dup 2)))]
6024 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6025 "smulcc\\t%1, %2, %0"
6026 [(set_attr "type" "imul")])
6028 (define_expand "mulsidi3"
6029 [(set (match_operand:DI 0 "register_operand" "")
6030 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6031 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6035 if (CONSTANT_P (operands[2]))
6038 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6041 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6047 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6052 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6053 ;; registers can hold 64 bit values in the V8plus environment.
6055 (define_insn "mulsidi3_v8plus"
6056 [(set (match_operand:DI 0 "register_operand" "=h,r")
6057 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6058 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6059 (clobber (match_scratch:SI 3 "=X,&h"))]
6062 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6063 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6064 [(set_attr "type" "multi")
6065 (set_attr "length" "2,3")])
6068 (define_insn "const_mulsidi3_v8plus"
6069 [(set (match_operand:DI 0 "register_operand" "=h,r")
6070 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6071 (match_operand:SI 2 "small_int" "I,I")))
6072 (clobber (match_scratch:SI 3 "=X,&h"))]
6075 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6076 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6077 [(set_attr "type" "multi")
6078 (set_attr "length" "2,3")])
6081 (define_insn "*mulsidi3_sp32"
6082 [(set (match_operand:DI 0 "register_operand" "=r")
6083 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6084 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6088 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6091 (if_then_else (eq_attr "isa" "sparclet")
6092 (const_string "imul") (const_string "multi")))
6093 (set (attr "length")
6094 (if_then_else (eq_attr "isa" "sparclet")
6095 (const_int 1) (const_int 2)))])
6097 (define_insn "*mulsidi3_sp64"
6098 [(set (match_operand:DI 0 "register_operand" "=r")
6099 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6100 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6101 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6103 [(set_attr "type" "imul")])
6105 ;; Extra pattern, because sign_extend of a constant isn't valid.
6108 (define_insn "const_mulsidi3_sp32"
6109 [(set (match_operand:DI 0 "register_operand" "=r")
6110 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6111 (match_operand:SI 2 "small_int" "I")))]
6115 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6118 (if_then_else (eq_attr "isa" "sparclet")
6119 (const_string "imul") (const_string "multi")))
6120 (set (attr "length")
6121 (if_then_else (eq_attr "isa" "sparclet")
6122 (const_int 1) (const_int 2)))])
6124 (define_insn "const_mulsidi3_sp64"
6125 [(set (match_operand:DI 0 "register_operand" "=r")
6126 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6127 (match_operand:SI 2 "small_int" "I")))]
6128 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6130 [(set_attr "type" "imul")])
6132 (define_expand "smulsi3_highpart"
6133 [(set (match_operand:SI 0 "register_operand" "")
6135 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6136 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6138 "TARGET_HARD_MUL && TARGET_ARCH32"
6141 if (CONSTANT_P (operands[2]))
6145 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6151 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6156 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6157 operands[2], GEN_INT (32)));
6163 (define_insn "smulsi3_highpart_v8plus"
6164 [(set (match_operand:SI 0 "register_operand" "=h,r")
6166 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6167 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6168 (match_operand:SI 3 "const_int_operand" "i,i"))))
6169 (clobber (match_scratch:SI 4 "=X,&h"))]
6172 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6173 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6174 [(set_attr "type" "multi")
6175 (set_attr "length" "2")])
6177 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6180 [(set (match_operand:SI 0 "register_operand" "=h,r")
6183 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6184 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6185 (match_operand:SI 3 "const_int_operand" "i,i"))
6187 (clobber (match_scratch:SI 4 "=X,&h"))]
6190 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6191 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6192 [(set_attr "type" "multi")
6193 (set_attr "length" "2")])
6196 (define_insn "const_smulsi3_highpart_v8plus"
6197 [(set (match_operand:SI 0 "register_operand" "=h,r")
6199 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6200 (match_operand 2 "small_int" "i,i"))
6201 (match_operand:SI 3 "const_int_operand" "i,i"))))
6202 (clobber (match_scratch:SI 4 "=X,&h"))]
6205 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6206 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6207 [(set_attr "type" "multi")
6208 (set_attr "length" "2")])
6211 (define_insn "*smulsi3_highpart_sp32"
6212 [(set (match_operand:SI 0 "register_operand" "=r")
6214 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6215 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6218 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6219 [(set_attr "type" "multi")
6220 (set_attr "length" "2")])
6223 (define_insn "const_smulsi3_highpart"
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 (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")])
6234 (define_expand "umulsidi3"
6235 [(set (match_operand:DI 0 "register_operand" "")
6236 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6237 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6241 if (CONSTANT_P (operands[2]))
6244 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6247 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6253 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6259 (define_insn "umulsidi3_v8plus"
6260 [(set (match_operand:DI 0 "register_operand" "=h,r")
6261 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6262 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6263 (clobber (match_scratch:SI 3 "=X,&h"))]
6266 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6267 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6268 [(set_attr "type" "multi")
6269 (set_attr "length" "2,3")])
6272 (define_insn "*umulsidi3_sp32"
6273 [(set (match_operand:DI 0 "register_operand" "=r")
6274 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6275 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6279 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6282 (if_then_else (eq_attr "isa" "sparclet")
6283 (const_string "imul") (const_string "multi")))
6284 (set (attr "length")
6285 (if_then_else (eq_attr "isa" "sparclet")
6286 (const_int 1) (const_int 2)))])
6288 (define_insn "*umulsidi3_sp64"
6289 [(set (match_operand:DI 0 "register_operand" "=r")
6290 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6291 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6292 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6294 [(set_attr "type" "imul")])
6296 ;; Extra pattern, because sign_extend of a constant isn't valid.
6299 (define_insn "const_umulsidi3_sp32"
6300 [(set (match_operand:DI 0 "register_operand" "=r")
6301 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6302 (match_operand:SI 2 "uns_small_int" "")))]
6306 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6309 (if_then_else (eq_attr "isa" "sparclet")
6310 (const_string "imul") (const_string "multi")))
6311 (set (attr "length")
6312 (if_then_else (eq_attr "isa" "sparclet")
6313 (const_int 1) (const_int 2)))])
6315 (define_insn "const_umulsidi3_sp64"
6316 [(set (match_operand:DI 0 "register_operand" "=r")
6317 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6318 (match_operand:SI 2 "uns_small_int" "")))]
6319 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6321 [(set_attr "type" "imul")])
6324 (define_insn "const_umulsidi3_v8plus"
6325 [(set (match_operand:DI 0 "register_operand" "=h,r")
6326 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6327 (match_operand:SI 2 "uns_small_int" "")))
6328 (clobber (match_scratch:SI 3 "=X,h"))]
6331 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6332 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6333 [(set_attr "type" "multi")
6334 (set_attr "length" "2,3")])
6336 (define_expand "umulsi3_highpart"
6337 [(set (match_operand:SI 0 "register_operand" "")
6339 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6340 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6342 "TARGET_HARD_MUL && TARGET_ARCH32"
6345 if (CONSTANT_P (operands[2]))
6349 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6355 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6360 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6361 operands[2], GEN_INT (32)));
6367 (define_insn "umulsi3_highpart_v8plus"
6368 [(set (match_operand:SI 0 "register_operand" "=h,r")
6370 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6371 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6372 (match_operand:SI 3 "const_int_operand" "i,i"))))
6373 (clobber (match_scratch:SI 4 "=X,h"))]
6376 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6377 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6378 [(set_attr "type" "multi")
6379 (set_attr "length" "2")])
6382 (define_insn "const_umulsi3_highpart_v8plus"
6383 [(set (match_operand:SI 0 "register_operand" "=h,r")
6385 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6386 (match_operand:SI 2 "uns_small_int" ""))
6387 (match_operand:SI 3 "const_int_operand" "i,i"))))
6388 (clobber (match_scratch:SI 4 "=X,h"))]
6391 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6392 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6393 [(set_attr "type" "multi")
6394 (set_attr "length" "2")])
6397 (define_insn "*umulsi3_highpart_sp32"
6398 [(set (match_operand:SI 0 "register_operand" "=r")
6400 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6401 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6404 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6405 [(set_attr "type" "multi")
6406 (set_attr "length" "2")])
6409 (define_insn "const_umulsi3_highpart"
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 (match_operand:SI 2 "uns_small_int" ""))
6416 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6417 [(set_attr "type" "multi")
6418 (set_attr "length" "2")])
6420 ;; The v8 architecture specifies that there must be 3 instructions between
6421 ;; a y register write and a use of it for correct results.
6423 (define_expand "divsi3"
6424 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6425 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6426 (match_operand:SI 2 "input_operand" "rI,m")))
6427 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6428 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6433 operands[3] = gen_reg_rtx(SImode);
6434 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6435 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6441 (define_insn "divsi3_sp32"
6442 [(set (match_operand:SI 0 "register_operand" "=r,r")
6443 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6444 (match_operand:SI 2 "input_operand" "rI,m")))
6445 (clobber (match_scratch:SI 3 "=&r,&r"))]
6446 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6450 if (which_alternative == 0)
6452 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6454 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6457 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6459 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\";
6461 [(set_attr "type" "multi")
6462 (set (attr "length")
6463 (if_then_else (eq_attr "isa" "v9")
6464 (const_int 4) (const_int 7)))])
6466 (define_insn "divsi3_sp64"
6467 [(set (match_operand:SI 0 "register_operand" "=r")
6468 (div:SI (match_operand:SI 1 "register_operand" "r")
6469 (match_operand:SI 2 "input_operand" "rI")))
6470 (use (match_operand:SI 3 "register_operand" "r"))]
6471 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6472 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6473 [(set_attr "type" "multi")
6474 (set_attr "length" "2")])
6476 (define_insn "divdi3"
6477 [(set (match_operand:DI 0 "register_operand" "=r")
6478 (div:DI (match_operand:DI 1 "register_operand" "r")
6479 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6481 "sdivx\\t%1, %2, %0"
6482 [(set_attr "type" "idiv")])
6484 (define_insn "*cmp_sdiv_cc_set"
6486 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6487 (match_operand:SI 2 "arith_operand" "rI"))
6489 (set (match_operand:SI 0 "register_operand" "=r")
6490 (div:SI (match_dup 1) (match_dup 2)))
6491 (clobber (match_scratch:SI 3 "=&r"))]
6492 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6496 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6498 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6500 [(set_attr "type" "multi")
6501 (set (attr "length")
6502 (if_then_else (eq_attr "isa" "v9")
6503 (const_int 3) (const_int 6)))])
6506 (define_expand "udivsi3"
6507 [(set (match_operand:SI 0 "register_operand" "")
6508 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6509 (match_operand:SI 2 "input_operand" "")))]
6510 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6513 (define_insn "udivsi3_sp32"
6514 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6515 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6516 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6518 || TARGET_DEPRECATED_V8_INSNS)
6522 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6523 switch (which_alternative)
6526 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6528 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6530 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6533 [(set_attr "type" "multi")
6534 (set_attr "length" "5")])
6536 (define_insn "udivsi3_sp64"
6537 [(set (match_operand:SI 0 "register_operand" "=r")
6538 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6539 (match_operand:SI 2 "input_operand" "rI")))]
6540 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6541 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6542 [(set_attr "type" "multi")
6543 (set_attr "length" "2")])
6545 (define_insn "udivdi3"
6546 [(set (match_operand:DI 0 "register_operand" "=r")
6547 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6548 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6550 "udivx\\t%1, %2, %0"
6551 [(set_attr "type" "idiv")])
6553 (define_insn "*cmp_udiv_cc_set"
6555 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6556 (match_operand:SI 2 "arith_operand" "rI"))
6558 (set (match_operand:SI 0 "register_operand" "=r")
6559 (udiv:SI (match_dup 1) (match_dup 2)))]
6561 || TARGET_DEPRECATED_V8_INSNS"
6565 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6567 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6569 [(set_attr "type" "multi")
6570 (set (attr "length")
6571 (if_then_else (eq_attr "isa" "v9")
6572 (const_int 2) (const_int 5)))])
6574 ; sparclet multiply/accumulate insns
6576 (define_insn "*smacsi"
6577 [(set (match_operand:SI 0 "register_operand" "=r")
6578 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6579 (match_operand:SI 2 "arith_operand" "rI"))
6580 (match_operand:SI 3 "register_operand" "0")))]
6583 [(set_attr "type" "imul")])
6585 (define_insn "*smacdi"
6586 [(set (match_operand:DI 0 "register_operand" "=r")
6587 (plus:DI (mult:DI (sign_extend:DI
6588 (match_operand:SI 1 "register_operand" "%r"))
6590 (match_operand:SI 2 "register_operand" "r")))
6591 (match_operand:DI 3 "register_operand" "0")))]
6593 "smacd\\t%1, %2, %L0"
6594 [(set_attr "type" "imul")])
6596 (define_insn "*umacdi"
6597 [(set (match_operand:DI 0 "register_operand" "=r")
6598 (plus:DI (mult:DI (zero_extend:DI
6599 (match_operand:SI 1 "register_operand" "%r"))
6601 (match_operand:SI 2 "register_operand" "r")))
6602 (match_operand:DI 3 "register_operand" "0")))]
6604 "umacd\\t%1, %2, %L0"
6605 [(set_attr "type" "imul")])
6607 ;;- Boolean instructions
6608 ;; We define DImode `and' so with DImode `not' we can get
6609 ;; DImode `andn'. Other combinations are possible.
6611 (define_expand "anddi3"
6612 [(set (match_operand:DI 0 "register_operand" "")
6613 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6614 (match_operand:DI 2 "arith_double_operand" "")))]
6618 (define_insn "*anddi3_sp32"
6619 [(set (match_operand:DI 0 "register_operand" "=r,b")
6620 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6621 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6626 [(set_attr "type" "*,fp")
6627 (set_attr "length" "2,*")
6628 (set_attr "fptype" "double")])
6630 (define_insn "*anddi3_sp64"
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 "fptype" "double")])
6641 (define_insn "andsi3"
6642 [(set (match_operand:SI 0 "register_operand" "=r,d")
6643 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6644 (match_operand:SI 2 "arith_operand" "rI,d")))]
6649 [(set_attr "type" "*,fp")])
6652 [(set (match_operand:SI 0 "register_operand" "")
6653 (and:SI (match_operand:SI 1 "register_operand" "")
6654 (match_operand:SI 2 "" "")))
6655 (clobber (match_operand:SI 3 "register_operand" ""))]
6656 "GET_CODE (operands[2]) == CONST_INT
6657 && !SMALL_INT32 (operands[2])
6658 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6659 [(set (match_dup 3) (match_dup 4))
6660 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6663 operands[4] = GEN_INT (~INTVAL (operands[2]));
6666 ;; Split DImode logical operations requiring two instructions.
6668 [(set (match_operand:DI 0 "register_operand" "")
6669 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6670 [(match_operand:DI 2 "register_operand" "")
6671 (match_operand:DI 3 "arith_double_operand" "")]))]
6674 && ((GET_CODE (operands[0]) == REG
6675 && REGNO (operands[0]) < 32)
6676 || (GET_CODE (operands[0]) == SUBREG
6677 && GET_CODE (SUBREG_REG (operands[0])) == REG
6678 && REGNO (SUBREG_REG (operands[0])) < 32))"
6679 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6680 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6683 operands[4] = gen_highpart (SImode, operands[0]);
6684 operands[5] = gen_lowpart (SImode, operands[0]);
6685 operands[6] = gen_highpart (SImode, operands[2]);
6686 operands[7] = gen_lowpart (SImode, operands[2]);
6687 #if HOST_BITS_PER_WIDE_INT == 32
6688 if (GET_CODE (operands[3]) == CONST_INT)
6690 if (INTVAL (operands[3]) < 0)
6691 operands[8] = constm1_rtx;
6693 operands[8] = const0_rtx;
6697 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6698 operands[9] = gen_lowpart (SImode, operands[3]);
6701 (define_insn "*and_not_di_sp32"
6702 [(set (match_operand:DI 0 "register_operand" "=r,b")
6703 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6704 (match_operand:DI 2 "register_operand" "r,b")))]
6708 fandnot1\\t%1, %2, %0"
6709 [(set_attr "type" "*,fp")
6710 (set_attr "length" "2,*")
6711 (set_attr "fptype" "double")])
6714 [(set (match_operand:DI 0 "register_operand" "")
6715 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6716 (match_operand:DI 2 "register_operand" "")))]
6719 && ((GET_CODE (operands[0]) == REG
6720 && REGNO (operands[0]) < 32)
6721 || (GET_CODE (operands[0]) == SUBREG
6722 && GET_CODE (SUBREG_REG (operands[0])) == REG
6723 && REGNO (SUBREG_REG (operands[0])) < 32))"
6724 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6725 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6726 "operands[3] = gen_highpart (SImode, operands[0]);
6727 operands[4] = gen_highpart (SImode, operands[1]);
6728 operands[5] = gen_highpart (SImode, operands[2]);
6729 operands[6] = gen_lowpart (SImode, operands[0]);
6730 operands[7] = gen_lowpart (SImode, operands[1]);
6731 operands[8] = gen_lowpart (SImode, operands[2]);")
6733 (define_insn "*and_not_di_sp64"
6734 [(set (match_operand:DI 0 "register_operand" "=r,b")
6735 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6736 (match_operand:DI 2 "register_operand" "r,b")))]
6740 fandnot1\\t%1, %2, %0"
6741 [(set_attr "type" "*,fp")
6742 (set_attr "fptype" "double")])
6744 (define_insn "*and_not_si"
6745 [(set (match_operand:SI 0 "register_operand" "=r,d")
6746 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6747 (match_operand:SI 2 "register_operand" "r,d")))]
6751 fandnot1s\\t%1, %2, %0"
6752 [(set_attr "type" "*,fp")])
6754 (define_expand "iordi3"
6755 [(set (match_operand:DI 0 "register_operand" "")
6756 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6757 (match_operand:DI 2 "arith_double_operand" "")))]
6761 (define_insn "*iordi3_sp32"
6762 [(set (match_operand:DI 0 "register_operand" "=r,b")
6763 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6764 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6769 [(set_attr "type" "*,fp")
6770 (set_attr "length" "2,*")
6771 (set_attr "fptype" "double")])
6773 (define_insn "*iordi3_sp64"
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 "fptype" "double")])
6784 (define_insn "iorsi3"
6785 [(set (match_operand:SI 0 "register_operand" "=r,d")
6786 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6787 (match_operand:SI 2 "arith_operand" "rI,d")))]
6792 [(set_attr "type" "*,fp")])
6795 [(set (match_operand:SI 0 "register_operand" "")
6796 (ior:SI (match_operand:SI 1 "register_operand" "")
6797 (match_operand:SI 2 "" "")))
6798 (clobber (match_operand:SI 3 "register_operand" ""))]
6799 "GET_CODE (operands[2]) == CONST_INT
6800 && !SMALL_INT32 (operands[2])
6801 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6802 [(set (match_dup 3) (match_dup 4))
6803 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6806 operands[4] = GEN_INT (~INTVAL (operands[2]));
6809 (define_insn "*or_not_di_sp32"
6810 [(set (match_operand:DI 0 "register_operand" "=r,b")
6811 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6812 (match_operand:DI 2 "register_operand" "r,b")))]
6816 fornot1\\t%1, %2, %0"
6817 [(set_attr "type" "*,fp")
6818 (set_attr "length" "2,*")
6819 (set_attr "fptype" "double")])
6822 [(set (match_operand:DI 0 "register_operand" "")
6823 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6824 (match_operand:DI 2 "register_operand" "")))]
6827 && ((GET_CODE (operands[0]) == REG
6828 && REGNO (operands[0]) < 32)
6829 || (GET_CODE (operands[0]) == SUBREG
6830 && GET_CODE (SUBREG_REG (operands[0])) == REG
6831 && REGNO (SUBREG_REG (operands[0])) < 32))"
6832 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6833 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6834 "operands[3] = gen_highpart (SImode, operands[0]);
6835 operands[4] = gen_highpart (SImode, operands[1]);
6836 operands[5] = gen_highpart (SImode, operands[2]);
6837 operands[6] = gen_lowpart (SImode, operands[0]);
6838 operands[7] = gen_lowpart (SImode, operands[1]);
6839 operands[8] = gen_lowpart (SImode, operands[2]);")
6841 (define_insn "*or_not_di_sp64"
6842 [(set (match_operand:DI 0 "register_operand" "=r,b")
6843 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6844 (match_operand:DI 2 "register_operand" "r,b")))]
6848 fornot1\\t%1, %2, %0"
6849 [(set_attr "type" "*,fp")
6850 (set_attr "fptype" "double")])
6852 (define_insn "*or_not_si"
6853 [(set (match_operand:SI 0 "register_operand" "=r,d")
6854 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6855 (match_operand:SI 2 "register_operand" "r,d")))]
6859 fornot1s\\t%1, %2, %0"
6860 [(set_attr "type" "*,fp")])
6862 (define_expand "xordi3"
6863 [(set (match_operand:DI 0 "register_operand" "")
6864 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6865 (match_operand:DI 2 "arith_double_operand" "")))]
6869 (define_insn "*xordi3_sp32"
6870 [(set (match_operand:DI 0 "register_operand" "=r,b")
6871 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6872 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6877 [(set_attr "type" "*,fp")
6878 (set_attr "length" "2,*")
6879 (set_attr "fptype" "double")])
6881 (define_insn "*xordi3_sp64"
6882 [(set (match_operand:DI 0 "register_operand" "=r,b")
6883 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6884 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6889 [(set_attr "type" "*,fp")
6890 (set_attr "fptype" "double")])
6892 (define_insn "*xordi3_sp64_dbl"
6893 [(set (match_operand:DI 0 "register_operand" "=r")
6894 (xor:DI (match_operand:DI 1 "register_operand" "r")
6895 (match_operand:DI 2 "const64_operand" "")))]
6897 && HOST_BITS_PER_WIDE_INT != 64)"
6900 (define_insn "xorsi3"
6901 [(set (match_operand:SI 0 "register_operand" "=r,d")
6902 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6903 (match_operand:SI 2 "arith_operand" "rI,d")))]
6908 [(set_attr "type" "*,fp")])
6911 [(set (match_operand:SI 0 "register_operand" "")
6912 (xor:SI (match_operand:SI 1 "register_operand" "")
6913 (match_operand:SI 2 "" "")))
6914 (clobber (match_operand:SI 3 "register_operand" ""))]
6915 "GET_CODE (operands[2]) == CONST_INT
6916 && !SMALL_INT32 (operands[2])
6917 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6918 [(set (match_dup 3) (match_dup 4))
6919 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6922 operands[4] = GEN_INT (~INTVAL (operands[2]));
6926 [(set (match_operand:SI 0 "register_operand" "")
6927 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6928 (match_operand:SI 2 "" ""))))
6929 (clobber (match_operand:SI 3 "register_operand" ""))]
6930 "GET_CODE (operands[2]) == CONST_INT
6931 && !SMALL_INT32 (operands[2])
6932 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6933 [(set (match_dup 3) (match_dup 4))
6934 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6937 operands[4] = GEN_INT (~INTVAL (operands[2]));
6940 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6941 ;; Combine now canonicalizes to the rightmost expression.
6942 (define_insn "*xor_not_di_sp32"
6943 [(set (match_operand:DI 0 "register_operand" "=r,b")
6944 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6945 (match_operand:DI 2 "register_operand" "r,b"))))]
6950 [(set_attr "type" "*,fp")
6951 (set_attr "length" "2,*")
6952 (set_attr "fptype" "double")])
6955 [(set (match_operand:DI 0 "register_operand" "")
6956 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6957 (match_operand:DI 2 "register_operand" ""))))]
6960 && ((GET_CODE (operands[0]) == REG
6961 && REGNO (operands[0]) < 32)
6962 || (GET_CODE (operands[0]) == SUBREG
6963 && GET_CODE (SUBREG_REG (operands[0])) == REG
6964 && REGNO (SUBREG_REG (operands[0])) < 32))"
6965 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6966 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6967 "operands[3] = gen_highpart (SImode, operands[0]);
6968 operands[4] = gen_highpart (SImode, operands[1]);
6969 operands[5] = gen_highpart (SImode, operands[2]);
6970 operands[6] = gen_lowpart (SImode, operands[0]);
6971 operands[7] = gen_lowpart (SImode, operands[1]);
6972 operands[8] = gen_lowpart (SImode, operands[2]);")
6974 (define_insn "*xor_not_di_sp64"
6975 [(set (match_operand:DI 0 "register_operand" "=r,b")
6976 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6977 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6982 [(set_attr "type" "*,fp")
6983 (set_attr "fptype" "double")])
6985 (define_insn "*xor_not_si"
6986 [(set (match_operand:SI 0 "register_operand" "=r,d")
6987 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6988 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6992 fxnors\\t%1, %2, %0"
6993 [(set_attr "type" "*,fp")])
6995 ;; These correspond to the above in the case where we also (or only)
6996 ;; want to set the condition code.
6998 (define_insn "*cmp_cc_arith_op"
7001 (match_operator:SI 2 "cc_arithop"
7002 [(match_operand:SI 0 "arith_operand" "%r")
7003 (match_operand:SI 1 "arith_operand" "rI")])
7006 "%A2cc\\t%0, %1, %%g0"
7007 [(set_attr "type" "compare")])
7009 (define_insn "*cmp_ccx_arith_op"
7012 (match_operator:DI 2 "cc_arithop"
7013 [(match_operand:DI 0 "arith_double_operand" "%r")
7014 (match_operand:DI 1 "arith_double_operand" "rHI")])
7017 "%A2cc\\t%0, %1, %%g0"
7018 [(set_attr "type" "compare")])
7020 (define_insn "*cmp_cc_arith_op_set"
7023 (match_operator:SI 3 "cc_arithop"
7024 [(match_operand:SI 1 "arith_operand" "%r")
7025 (match_operand:SI 2 "arith_operand" "rI")])
7027 (set (match_operand:SI 0 "register_operand" "=r")
7028 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7029 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7030 "%A3cc\\t%1, %2, %0"
7031 [(set_attr "type" "compare")])
7033 (define_insn "*cmp_ccx_arith_op_set"
7036 (match_operator:DI 3 "cc_arithop"
7037 [(match_operand:DI 1 "arith_double_operand" "%r")
7038 (match_operand:DI 2 "arith_double_operand" "rHI")])
7040 (set (match_operand:DI 0 "register_operand" "=r")
7041 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7042 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7043 "%A3cc\\t%1, %2, %0"
7044 [(set_attr "type" "compare")])
7046 (define_insn "*cmp_cc_xor_not"
7049 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7050 (match_operand:SI 1 "arith_operand" "rI")))
7053 "xnorcc\\t%r0, %1, %%g0"
7054 [(set_attr "type" "compare")])
7056 (define_insn "*cmp_ccx_xor_not"
7059 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7060 (match_operand:DI 1 "arith_double_operand" "rHI")))
7063 "xnorcc\\t%r0, %1, %%g0"
7064 [(set_attr "type" "compare")])
7066 (define_insn "*cmp_cc_xor_not_set"
7069 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7070 (match_operand:SI 2 "arith_operand" "rI")))
7072 (set (match_operand:SI 0 "register_operand" "=r")
7073 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7075 "xnorcc\\t%r1, %2, %0"
7076 [(set_attr "type" "compare")])
7078 (define_insn "*cmp_ccx_xor_not_set"
7081 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7082 (match_operand:DI 2 "arith_double_operand" "rHI")))
7084 (set (match_operand:DI 0 "register_operand" "=r")
7085 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7087 "xnorcc\\t%r1, %2, %0"
7088 [(set_attr "type" "compare")])
7090 (define_insn "*cmp_cc_arith_op_not"
7093 (match_operator:SI 2 "cc_arithopn"
7094 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7095 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7098 "%B2cc\\t%r1, %0, %%g0"
7099 [(set_attr "type" "compare")])
7101 (define_insn "*cmp_ccx_arith_op_not"
7104 (match_operator:DI 2 "cc_arithopn"
7105 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7106 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7109 "%B2cc\\t%r1, %0, %%g0"
7110 [(set_attr "type" "compare")])
7112 (define_insn "*cmp_cc_arith_op_not_set"
7115 (match_operator:SI 3 "cc_arithopn"
7116 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7117 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7119 (set (match_operand:SI 0 "register_operand" "=r")
7120 (match_operator:SI 4 "cc_arithopn"
7121 [(not:SI (match_dup 1)) (match_dup 2)]))]
7122 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7123 "%B3cc\\t%r2, %1, %0"
7124 [(set_attr "type" "compare")])
7126 (define_insn "*cmp_ccx_arith_op_not_set"
7129 (match_operator:DI 3 "cc_arithopn"
7130 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7131 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7133 (set (match_operand:DI 0 "register_operand" "=r")
7134 (match_operator:DI 4 "cc_arithopn"
7135 [(not:DI (match_dup 1)) (match_dup 2)]))]
7136 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7137 "%B3cc\\t%r2, %1, %0"
7138 [(set_attr "type" "compare")])
7140 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7141 ;; does not know how to make it work for constants.
7143 (define_expand "negdi2"
7144 [(set (match_operand:DI 0 "register_operand" "=r")
7145 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7149 if (! TARGET_ARCH64)
7151 emit_insn (gen_rtx_PARALLEL
7154 gen_rtx_SET (VOIDmode, operand0,
7155 gen_rtx_NEG (DImode, operand1)),
7156 gen_rtx_CLOBBER (VOIDmode,
7157 gen_rtx_REG (CCmode,
7163 (define_insn "*negdi2_sp32"
7164 [(set (match_operand:DI 0 "register_operand" "=r")
7165 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7166 (clobber (reg:CC 100))]
7169 [(set_attr "length" "2")])
7172 [(set (match_operand:DI 0 "register_operand" "")
7173 (neg:DI (match_operand:DI 1 "register_operand" "")))
7174 (clobber (reg:CC 100))]
7176 && reload_completed"
7177 [(parallel [(set (reg:CC_NOOV 100)
7178 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7180 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7181 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7182 (ltu:SI (reg:CC 100) (const_int 0))))]
7183 "operands[2] = gen_highpart (SImode, operands[0]);
7184 operands[3] = gen_highpart (SImode, operands[1]);
7185 operands[4] = gen_lowpart (SImode, operands[0]);
7186 operands[5] = gen_lowpart (SImode, operands[1]);")
7188 (define_insn "*negdi2_sp64"
7189 [(set (match_operand:DI 0 "register_operand" "=r")
7190 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7192 "sub\\t%%g0, %1, %0")
7194 (define_insn "negsi2"
7195 [(set (match_operand:SI 0 "register_operand" "=r")
7196 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7198 "sub\\t%%g0, %1, %0")
7200 (define_insn "*cmp_cc_neg"
7201 [(set (reg:CC_NOOV 100)
7202 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7205 "subcc\\t%%g0, %0, %%g0"
7206 [(set_attr "type" "compare")])
7208 (define_insn "*cmp_ccx_neg"
7209 [(set (reg:CCX_NOOV 100)
7210 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7213 "subcc\\t%%g0, %0, %%g0"
7214 [(set_attr "type" "compare")])
7216 (define_insn "*cmp_cc_set_neg"
7217 [(set (reg:CC_NOOV 100)
7218 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7220 (set (match_operand:SI 0 "register_operand" "=r")
7221 (neg:SI (match_dup 1)))]
7223 "subcc\\t%%g0, %1, %0"
7224 [(set_attr "type" "compare")])
7226 (define_insn "*cmp_ccx_set_neg"
7227 [(set (reg:CCX_NOOV 100)
7228 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7230 (set (match_operand:DI 0 "register_operand" "=r")
7231 (neg:DI (match_dup 1)))]
7233 "subcc\\t%%g0, %1, %0"
7234 [(set_attr "type" "compare")])
7236 ;; We cannot use the "not" pseudo insn because the Sun assembler
7237 ;; does not know how to make it work for constants.
7238 (define_expand "one_cmpldi2"
7239 [(set (match_operand:DI 0 "register_operand" "")
7240 (not:DI (match_operand:DI 1 "register_operand" "")))]
7244 (define_insn "*one_cmpldi2_sp32"
7245 [(set (match_operand:DI 0 "register_operand" "=r,b")
7246 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7251 [(set_attr "type" "*,fp")
7252 (set_attr "length" "2,*")
7253 (set_attr "fptype" "double")])
7256 [(set (match_operand:DI 0 "register_operand" "")
7257 (not:DI (match_operand:DI 1 "register_operand" "")))]
7260 && ((GET_CODE (operands[0]) == REG
7261 && REGNO (operands[0]) < 32)
7262 || (GET_CODE (operands[0]) == SUBREG
7263 && GET_CODE (SUBREG_REG (operands[0])) == REG
7264 && REGNO (SUBREG_REG (operands[0])) < 32))"
7265 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7266 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7267 "operands[2] = gen_highpart (SImode, operands[0]);
7268 operands[3] = gen_highpart (SImode, operands[1]);
7269 operands[4] = gen_lowpart (SImode, operands[0]);
7270 operands[5] = gen_lowpart (SImode, operands[1]);")
7272 (define_insn "*one_cmpldi2_sp64"
7273 [(set (match_operand:DI 0 "register_operand" "=r,b")
7274 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7279 [(set_attr "type" "*,fp")
7280 (set_attr "fptype" "double")])
7282 (define_insn "one_cmplsi2"
7283 [(set (match_operand:SI 0 "register_operand" "=r,d")
7284 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7289 [(set_attr "type" "*,fp")])
7291 (define_insn "*cmp_cc_not"
7293 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7296 "xnorcc\\t%%g0, %0, %%g0"
7297 [(set_attr "type" "compare")])
7299 (define_insn "*cmp_ccx_not"
7301 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7304 "xnorcc\\t%%g0, %0, %%g0"
7305 [(set_attr "type" "compare")])
7307 (define_insn "*cmp_cc_set_not"
7309 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7311 (set (match_operand:SI 0 "register_operand" "=r")
7312 (not:SI (match_dup 1)))]
7314 "xnorcc\\t%%g0, %1, %0"
7315 [(set_attr "type" "compare")])
7317 (define_insn "*cmp_ccx_set_not"
7319 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7321 (set (match_operand:DI 0 "register_operand" "=r")
7322 (not:DI (match_dup 1)))]
7324 "xnorcc\\t%%g0, %1, %0"
7325 [(set_attr "type" "compare")])
7327 (define_insn "*cmp_cc_set"
7328 [(set (match_operand:SI 0 "register_operand" "=r")
7329 (match_operand:SI 1 "register_operand" "r"))
7331 (compare:CC (match_dup 1)
7335 [(set_attr "type" "compare")])
7337 (define_insn "*cmp_ccx_set64"
7338 [(set (match_operand:DI 0 "register_operand" "=r")
7339 (match_operand:DI 1 "register_operand" "r"))
7341 (compare:CCX (match_dup 1)
7345 [(set_attr "type" "compare")])
7347 ;; Floating point arithmetic instructions.
7349 (define_expand "addtf3"
7350 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7351 (plus:TF (match_operand:TF 1 "general_operand" "")
7352 (match_operand:TF 2 "general_operand" "")))]
7353 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7356 if (! TARGET_HARD_QUAD)
7358 rtx slot0, slot1, slot2;
7360 if (GET_CODE (operands[0]) != MEM)
7361 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7363 slot0 = operands[0];
7364 if (GET_CODE (operands[1]) != MEM)
7366 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7367 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7370 slot1 = operands[1];
7371 if (GET_CODE (operands[2]) != MEM)
7373 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7374 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7377 slot2 = operands[2];
7379 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7381 XEXP (slot0, 0), Pmode,
7382 XEXP (slot1, 0), Pmode,
7383 XEXP (slot2, 0), Pmode);
7385 if (GET_CODE (operands[0]) != MEM)
7386 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7391 (define_insn "*addtf3_hq"
7392 [(set (match_operand:TF 0 "register_operand" "=e")
7393 (plus:TF (match_operand:TF 1 "register_operand" "e")
7394 (match_operand:TF 2 "register_operand" "e")))]
7395 "TARGET_FPU && TARGET_HARD_QUAD"
7396 "faddq\\t%1, %2, %0"
7397 [(set_attr "type" "fp")])
7399 (define_insn "adddf3"
7400 [(set (match_operand:DF 0 "register_operand" "=e")
7401 (plus:DF (match_operand:DF 1 "register_operand" "e")
7402 (match_operand:DF 2 "register_operand" "e")))]
7404 "faddd\\t%1, %2, %0"
7405 [(set_attr "type" "fp")
7406 (set_attr "fptype" "double")])
7408 (define_insn "addsf3"
7409 [(set (match_operand:SF 0 "register_operand" "=f")
7410 (plus:SF (match_operand:SF 1 "register_operand" "f")
7411 (match_operand:SF 2 "register_operand" "f")))]
7413 "fadds\\t%1, %2, %0"
7414 [(set_attr "type" "fp")])
7416 (define_expand "subtf3"
7417 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7418 (minus:TF (match_operand:TF 1 "general_operand" "")
7419 (match_operand:TF 2 "general_operand" "")))]
7420 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7423 if (! TARGET_HARD_QUAD)
7425 rtx slot0, slot1, slot2;
7427 if (GET_CODE (operands[0]) != MEM)
7428 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7430 slot0 = operands[0];
7431 if (GET_CODE (operands[1]) != MEM)
7433 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7434 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7437 slot1 = operands[1];
7438 if (GET_CODE (operands[2]) != MEM)
7440 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7441 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7444 slot2 = operands[2];
7446 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7448 XEXP (slot0, 0), Pmode,
7449 XEXP (slot1, 0), Pmode,
7450 XEXP (slot2, 0), Pmode);
7452 if (GET_CODE (operands[0]) != MEM)
7453 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7458 (define_insn "*subtf3_hq"
7459 [(set (match_operand:TF 0 "register_operand" "=e")
7460 (minus:TF (match_operand:TF 1 "register_operand" "e")
7461 (match_operand:TF 2 "register_operand" "e")))]
7462 "TARGET_FPU && TARGET_HARD_QUAD"
7463 "fsubq\\t%1, %2, %0"
7464 [(set_attr "type" "fp")])
7466 (define_insn "subdf3"
7467 [(set (match_operand:DF 0 "register_operand" "=e")
7468 (minus:DF (match_operand:DF 1 "register_operand" "e")
7469 (match_operand:DF 2 "register_operand" "e")))]
7471 "fsubd\\t%1, %2, %0"
7472 [(set_attr "type" "fp")
7473 (set_attr "fptype" "double")])
7475 (define_insn "subsf3"
7476 [(set (match_operand:SF 0 "register_operand" "=f")
7477 (minus:SF (match_operand:SF 1 "register_operand" "f")
7478 (match_operand:SF 2 "register_operand" "f")))]
7480 "fsubs\\t%1, %2, %0"
7481 [(set_attr "type" "fp")])
7483 (define_expand "multf3"
7484 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7485 (mult:TF (match_operand:TF 1 "general_operand" "")
7486 (match_operand:TF 2 "general_operand" "")))]
7487 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7490 if (! TARGET_HARD_QUAD)
7492 rtx slot0, slot1, slot2;
7494 if (GET_CODE (operands[0]) != MEM)
7495 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7497 slot0 = operands[0];
7498 if (GET_CODE (operands[1]) != MEM)
7500 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7501 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7504 slot1 = operands[1];
7505 if (GET_CODE (operands[2]) != MEM)
7507 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7508 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7511 slot2 = operands[2];
7513 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7515 XEXP (slot0, 0), Pmode,
7516 XEXP (slot1, 0), Pmode,
7517 XEXP (slot2, 0), Pmode);
7519 if (GET_CODE (operands[0]) != MEM)
7520 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7525 (define_insn "*multf3_hq"
7526 [(set (match_operand:TF 0 "register_operand" "=e")
7527 (mult:TF (match_operand:TF 1 "register_operand" "e")
7528 (match_operand:TF 2 "register_operand" "e")))]
7529 "TARGET_FPU && TARGET_HARD_QUAD"
7530 "fmulq\\t%1, %2, %0"
7531 [(set_attr "type" "fpmul")])
7533 (define_insn "muldf3"
7534 [(set (match_operand:DF 0 "register_operand" "=e")
7535 (mult:DF (match_operand:DF 1 "register_operand" "e")
7536 (match_operand:DF 2 "register_operand" "e")))]
7538 "fmuld\\t%1, %2, %0"
7539 [(set_attr "type" "fpmul")
7540 (set_attr "fptype" "double")])
7542 (define_insn "mulsf3"
7543 [(set (match_operand:SF 0 "register_operand" "=f")
7544 (mult:SF (match_operand:SF 1 "register_operand" "f")
7545 (match_operand:SF 2 "register_operand" "f")))]
7547 "fmuls\\t%1, %2, %0"
7548 [(set_attr "type" "fpmul")])
7550 (define_insn "*muldf3_extend"
7551 [(set (match_operand:DF 0 "register_operand" "=e")
7552 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7553 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7554 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7555 "fsmuld\\t%1, %2, %0"
7556 [(set_attr "type" "fpmul")
7557 (set_attr "fptype" "double")])
7559 (define_insn "*multf3_extend"
7560 [(set (match_operand:TF 0 "register_operand" "=e")
7561 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7562 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7563 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7564 "fdmulq\\t%1, %2, %0"
7565 [(set_attr "type" "fpmul")])
7567 (define_expand "divtf3"
7568 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7569 (div:TF (match_operand:TF 1 "general_operand" "")
7570 (match_operand:TF 2 "general_operand" "")))]
7571 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7574 if (! TARGET_HARD_QUAD)
7576 rtx slot0, slot1, slot2;
7578 if (GET_CODE (operands[0]) != MEM)
7579 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7581 slot0 = operands[0];
7582 if (GET_CODE (operands[1]) != MEM)
7584 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7585 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7588 slot1 = operands[1];
7589 if (GET_CODE (operands[2]) != MEM)
7591 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7592 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7595 slot2 = operands[2];
7597 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7599 XEXP (slot0, 0), Pmode,
7600 XEXP (slot1, 0), Pmode,
7601 XEXP (slot2, 0), Pmode);
7603 if (GET_CODE (operands[0]) != MEM)
7604 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7609 ;; don't have timing for quad-prec. divide.
7610 (define_insn "*divtf3_hq"
7611 [(set (match_operand:TF 0 "register_operand" "=e")
7612 (div:TF (match_operand:TF 1 "register_operand" "e")
7613 (match_operand:TF 2 "register_operand" "e")))]
7614 "TARGET_FPU && TARGET_HARD_QUAD"
7615 "fdivq\\t%1, %2, %0"
7616 [(set_attr "type" "fpdivd")])
7618 (define_insn "divdf3"
7619 [(set (match_operand:DF 0 "register_operand" "=e")
7620 (div:DF (match_operand:DF 1 "register_operand" "e")
7621 (match_operand:DF 2 "register_operand" "e")))]
7623 "fdivd\\t%1, %2, %0"
7624 [(set_attr "type" "fpdivd")
7625 (set_attr "fptype" "double")])
7627 (define_insn "divsf3"
7628 [(set (match_operand:SF 0 "register_operand" "=f")
7629 (div:SF (match_operand:SF 1 "register_operand" "f")
7630 (match_operand:SF 2 "register_operand" "f")))]
7632 "fdivs\\t%1, %2, %0"
7633 [(set_attr "type" "fpdivs")])
7635 (define_expand "negtf2"
7636 [(set (match_operand:TF 0 "register_operand" "=e,e")
7637 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7641 (define_insn "*negtf2_notv9"
7642 [(set (match_operand:TF 0 "register_operand" "=e,e")
7643 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7644 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7650 [(set_attr "type" "fpmove,*")
7651 (set_attr "length" "*,2")])
7654 [(set (match_operand:TF 0 "register_operand" "")
7655 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7659 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7660 [(set (match_dup 2) (neg:SF (match_dup 3)))
7661 (set (match_dup 4) (match_dup 5))
7662 (set (match_dup 6) (match_dup 7))]
7663 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7664 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7665 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7666 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7667 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7668 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7670 (define_insn "*negtf2_v9"
7671 [(set (match_operand:TF 0 "register_operand" "=e,e")
7672 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7673 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7674 "TARGET_FPU && TARGET_V9"
7678 [(set_attr "type" "fpmove,*")
7679 (set_attr "length" "*,2")
7680 (set_attr "fptype" "double")])
7683 [(set (match_operand:TF 0 "register_operand" "")
7684 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7688 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7689 [(set (match_dup 2) (neg:DF (match_dup 3)))
7690 (set (match_dup 4) (match_dup 5))]
7691 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7692 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7693 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7694 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7696 (define_expand "negdf2"
7697 [(set (match_operand:DF 0 "register_operand" "")
7698 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7702 (define_insn "*negdf2_notv9"
7703 [(set (match_operand:DF 0 "register_operand" "=e,e")
7704 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7705 "TARGET_FPU && ! TARGET_V9"
7709 [(set_attr "type" "fpmove,*")
7710 (set_attr "length" "*,2")])
7713 [(set (match_operand:DF 0 "register_operand" "")
7714 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7718 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7719 [(set (match_dup 2) (neg:SF (match_dup 3)))
7720 (set (match_dup 4) (match_dup 5))]
7721 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7722 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7723 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7724 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7726 (define_insn "*negdf2_v9"
7727 [(set (match_operand:DF 0 "register_operand" "=e")
7728 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7729 "TARGET_FPU && TARGET_V9"
7731 [(set_attr "type" "fpmove")
7732 (set_attr "fptype" "double")])
7734 (define_insn "negsf2"
7735 [(set (match_operand:SF 0 "register_operand" "=f")
7736 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7739 [(set_attr "type" "fpmove")])
7741 (define_expand "abstf2"
7742 [(set (match_operand:TF 0 "register_operand" "")
7743 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7747 (define_insn "*abstf2_notv9"
7748 [(set (match_operand:TF 0 "register_operand" "=e,e")
7749 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7750 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7751 "TARGET_FPU && ! TARGET_V9"
7755 [(set_attr "type" "fpmove,*")
7756 (set_attr "length" "*,2")])
7759 [(set (match_operand:TF 0 "register_operand" "")
7760 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7764 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7765 [(set (match_dup 2) (abs:SF (match_dup 3)))
7766 (set (match_dup 4) (match_dup 5))
7767 (set (match_dup 6) (match_dup 7))]
7768 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7769 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7770 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7771 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7772 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7773 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7775 (define_insn "*abstf2_hq_v9"
7776 [(set (match_operand:TF 0 "register_operand" "=e,e")
7777 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7778 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7782 [(set_attr "type" "fpmove")
7783 (set_attr "fptype" "double,*")])
7785 (define_insn "*abstf2_v9"
7786 [(set (match_operand:TF 0 "register_operand" "=e,e")
7787 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7788 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7792 [(set_attr "type" "fpmove,*")
7793 (set_attr "length" "*,2")
7794 (set_attr "fptype" "double,*")])
7797 [(set (match_operand:TF 0 "register_operand" "")
7798 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7802 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7803 [(set (match_dup 2) (abs:DF (match_dup 3)))
7804 (set (match_dup 4) (match_dup 5))]
7805 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7806 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7807 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7808 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7810 (define_expand "absdf2"
7811 [(set (match_operand:DF 0 "register_operand" "")
7812 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7816 (define_insn "*absdf2_notv9"
7817 [(set (match_operand:DF 0 "register_operand" "=e,e")
7818 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7819 "TARGET_FPU && ! TARGET_V9"
7823 [(set_attr "type" "fpmove,*")
7824 (set_attr "length" "*,2")])
7827 [(set (match_operand:DF 0 "register_operand" "")
7828 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7832 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7833 [(set (match_dup 2) (abs:SF (match_dup 3)))
7834 (set (match_dup 4) (match_dup 5))]
7835 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7836 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7837 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7838 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7840 (define_insn "*absdf2_v9"
7841 [(set (match_operand:DF 0 "register_operand" "=e")
7842 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7843 "TARGET_FPU && TARGET_V9"
7845 [(set_attr "type" "fpmove")
7846 (set_attr "fptype" "double")])
7848 (define_insn "abssf2"
7849 [(set (match_operand:SF 0 "register_operand" "=f")
7850 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7853 [(set_attr "type" "fpmove")])
7855 (define_expand "sqrttf2"
7856 [(set (match_operand:TF 0 "register_operand" "=e")
7857 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7858 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7861 if (! TARGET_HARD_QUAD)
7865 if (GET_CODE (operands[0]) != MEM)
7866 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7868 slot0 = operands[0];
7869 if (GET_CODE (operands[1]) != MEM)
7871 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7872 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7875 slot1 = operands[1];
7877 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7879 XEXP (slot0, 0), Pmode,
7880 XEXP (slot1, 0), Pmode);
7882 if (GET_CODE (operands[0]) != MEM)
7883 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7888 (define_insn "*sqrttf2_hq"
7889 [(set (match_operand:TF 0 "register_operand" "=e")
7890 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7891 "TARGET_FPU && TARGET_HARD_QUAD"
7893 [(set_attr "type" "fpsqrtd")])
7895 (define_insn "sqrtdf2"
7896 [(set (match_operand:DF 0 "register_operand" "=e")
7897 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7900 [(set_attr "type" "fpsqrtd")
7901 (set_attr "fptype" "double")])
7903 (define_insn "sqrtsf2"
7904 [(set (match_operand:SF 0 "register_operand" "=f")
7905 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7908 [(set_attr "type" "fpsqrts")])
7910 ;;- arithmetic shift instructions
7912 (define_insn "ashlsi3"
7913 [(set (match_operand:SI 0 "register_operand" "=r")
7914 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7915 (match_operand:SI 2 "arith_operand" "rI")))]
7919 if (GET_CODE (operands[2]) == CONST_INT
7920 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7921 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7923 return \"sll\\t%1, %2, %0\";
7925 [(set_attr "type" "shift")])
7927 ;; We special case multiplication by two, as add can be done
7928 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7929 (define_insn "*ashlsi3_const1"
7930 [(set (match_operand:SI 0 "register_operand" "=r")
7931 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7936 (define_expand "ashldi3"
7937 [(set (match_operand:DI 0 "register_operand" "=r")
7938 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7939 (match_operand:SI 2 "arith_operand" "rI")))]
7940 "TARGET_ARCH64 || TARGET_V8PLUS"
7943 if (! TARGET_ARCH64)
7945 if (GET_CODE (operands[2]) == CONST_INT)
7947 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7952 ;; We special case multiplication by two, as add can be done
7953 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7954 (define_insn "*ashldi3_const1"
7955 [(set (match_operand:DI 0 "register_operand" "=r")
7956 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7961 (define_insn "*ashldi3_sp64"
7962 [(set (match_operand:DI 0 "register_operand" "=r")
7963 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7964 (match_operand:SI 2 "arith_operand" "rI")))]
7968 if (GET_CODE (operands[2]) == CONST_INT
7969 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7970 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7972 return \"sllx\\t%1, %2, %0\";
7974 [(set_attr "type" "shift")])
7977 (define_insn "ashldi3_v8plus"
7978 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7979 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7980 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7981 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7983 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7984 [(set_attr "type" "multi")
7985 (set_attr "length" "5,5,6")])
7987 ;; Optimize (1LL<<x)-1
7988 ;; XXX this also needs to be fixed to handle equal subregs
7989 ;; XXX first before we could re-enable it.
7991 ; [(set (match_operand:DI 0 "register_operand" "=h")
7992 ; (plus:DI (ashift:DI (const_int 1)
7993 ; (match_operand:SI 1 "arith_operand" "rI"))
7995 ; "0 && TARGET_V8PLUS"
7998 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7999 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8000 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8002 ; [(set_attr "type" "multi")
8003 ; (set_attr "length" "4")])
8005 (define_insn "*cmp_cc_ashift_1"
8006 [(set (reg:CC_NOOV 100)
8007 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8011 "addcc\\t%0, %0, %%g0"
8012 [(set_attr "type" "compare")])
8014 (define_insn "*cmp_cc_set_ashift_1"
8015 [(set (reg:CC_NOOV 100)
8016 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8019 (set (match_operand:SI 0 "register_operand" "=r")
8020 (ashift:SI (match_dup 1) (const_int 1)))]
8022 "addcc\\t%1, %1, %0"
8023 [(set_attr "type" "compare")])
8025 (define_insn "ashrsi3"
8026 [(set (match_operand:SI 0 "register_operand" "=r")
8027 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8028 (match_operand:SI 2 "arith_operand" "rI")))]
8032 if (GET_CODE (operands[2]) == CONST_INT
8033 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8034 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8036 return \"sra\\t%1, %2, %0\";
8038 [(set_attr "type" "shift")])
8040 (define_insn "*ashrsi3_extend"
8041 [(set (match_operand:DI 0 "register_operand" "=r")
8042 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8043 (match_operand:SI 2 "arith_operand" "r"))))]
8046 [(set_attr "type" "shift")])
8048 ;; This handles the case as above, but with constant shift instead of
8049 ;; register. Combiner "simplifies" it for us a little bit though.
8050 (define_insn "*ashrsi3_extend2"
8051 [(set (match_operand:DI 0 "register_operand" "=r")
8052 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8054 (match_operand:SI 2 "small_int_or_double" "n")))]
8056 && ((GET_CODE (operands[2]) == CONST_INT
8057 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8058 || (GET_CODE (operands[2]) == CONST_DOUBLE
8059 && !CONST_DOUBLE_HIGH (operands[2])
8060 && CONST_DOUBLE_LOW (operands[2]) >= 32
8061 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8064 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8066 return \"sra\\t%1, %2, %0\";
8068 [(set_attr "type" "shift")])
8070 (define_expand "ashrdi3"
8071 [(set (match_operand:DI 0 "register_operand" "=r")
8072 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8073 (match_operand:SI 2 "arith_operand" "rI")))]
8074 "TARGET_ARCH64 || TARGET_V8PLUS"
8077 if (! TARGET_ARCH64)
8079 if (GET_CODE (operands[2]) == CONST_INT)
8080 FAIL; /* prefer generic code in this case */
8081 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8087 [(set (match_operand:DI 0 "register_operand" "=r")
8088 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8089 (match_operand:SI 2 "arith_operand" "rI")))]
8093 if (GET_CODE (operands[2]) == CONST_INT
8094 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8095 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8097 return \"srax\\t%1, %2, %0\";
8099 [(set_attr "type" "shift")])
8102 (define_insn "ashrdi3_v8plus"
8103 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8104 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8105 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8106 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8108 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8109 [(set_attr "type" "multi")
8110 (set_attr "length" "5,5,6")])
8112 (define_insn "lshrsi3"
8113 [(set (match_operand:SI 0 "register_operand" "=r")
8114 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8115 (match_operand:SI 2 "arith_operand" "rI")))]
8119 if (GET_CODE (operands[2]) == CONST_INT
8120 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8121 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8123 return \"srl\\t%1, %2, %0\";
8125 [(set_attr "type" "shift")])
8127 ;; This handles the case where
8128 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8129 ;; but combiner "simplifies" it for us.
8130 (define_insn "*lshrsi3_extend"
8131 [(set (match_operand:DI 0 "register_operand" "=r")
8132 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8133 (match_operand:SI 2 "arith_operand" "r")) 0)
8134 (match_operand 3 "" "")))]
8136 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8137 && CONST_DOUBLE_HIGH (operands[3]) == 0
8138 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8139 || (HOST_BITS_PER_WIDE_INT >= 64
8140 && GET_CODE (operands[3]) == CONST_INT
8141 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8143 [(set_attr "type" "shift")])
8145 ;; This handles the case where
8146 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8147 ;; but combiner "simplifies" it for us.
8148 (define_insn "*lshrsi3_extend2"
8149 [(set (match_operand:DI 0 "register_operand" "=r")
8150 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8151 (match_operand 2 "small_int_or_double" "n")
8154 && ((GET_CODE (operands[2]) == CONST_INT
8155 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8156 || (GET_CODE (operands[2]) == CONST_DOUBLE
8157 && CONST_DOUBLE_HIGH (operands[2]) == 0
8158 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8161 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8163 return \"srl\\t%1, %2, %0\";
8165 [(set_attr "type" "shift")])
8167 (define_expand "lshrdi3"
8168 [(set (match_operand:DI 0 "register_operand" "=r")
8169 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8170 (match_operand:SI 2 "arith_operand" "rI")))]
8171 "TARGET_ARCH64 || TARGET_V8PLUS"
8174 if (! TARGET_ARCH64)
8176 if (GET_CODE (operands[2]) == CONST_INT)
8178 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8184 [(set (match_operand:DI 0 "register_operand" "=r")
8185 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8186 (match_operand:SI 2 "arith_operand" "rI")))]
8190 if (GET_CODE (operands[2]) == CONST_INT
8191 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8192 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8194 return \"srlx\\t%1, %2, %0\";
8196 [(set_attr "type" "shift")])
8199 (define_insn "lshrdi3_v8plus"
8200 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8201 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8202 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8203 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8205 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8206 [(set_attr "type" "multi")
8207 (set_attr "length" "5,5,6")])
8210 [(set (match_operand:SI 0 "register_operand" "=r")
8211 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8213 (match_operand:SI 2 "small_int_or_double" "n")))]
8215 && ((GET_CODE (operands[2]) == CONST_INT
8216 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8217 || (GET_CODE (operands[2]) == CONST_DOUBLE
8218 && !CONST_DOUBLE_HIGH (operands[2])
8219 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8222 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8224 return \"srax\\t%1, %2, %0\";
8226 [(set_attr "type" "shift")])
8229 [(set (match_operand:SI 0 "register_operand" "=r")
8230 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8232 (match_operand:SI 2 "small_int_or_double" "n")))]
8234 && ((GET_CODE (operands[2]) == CONST_INT
8235 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8236 || (GET_CODE (operands[2]) == CONST_DOUBLE
8237 && !CONST_DOUBLE_HIGH (operands[2])
8238 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8241 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8243 return \"srlx\\t%1, %2, %0\";
8245 [(set_attr "type" "shift")])
8248 [(set (match_operand:SI 0 "register_operand" "=r")
8249 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8250 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8251 (match_operand:SI 3 "small_int_or_double" "n")))]
8253 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8254 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8255 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8256 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8259 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8261 return \"srax\\t%1, %2, %0\";
8263 [(set_attr "type" "shift")])
8266 [(set (match_operand:SI 0 "register_operand" "=r")
8267 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8268 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8269 (match_operand:SI 3 "small_int_or_double" "n")))]
8271 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8272 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8273 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8274 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8277 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8279 return \"srlx\\t%1, %2, %0\";
8281 [(set_attr "type" "shift")])
8283 ;; Unconditional and other jump instructions
8284 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8285 ;; following insn is never executed. This saves us a nop. Dbx does not
8286 ;; handle such branches though, so we only use them when optimizing.
8288 [(set (pc) (label_ref (match_operand 0 "" "")))]
8292 /* TurboSparc is reported to have problems with
8295 i.e. an empty loop with the annul bit set. The workaround is to use
8299 if (! TARGET_V9 && flag_delayed_branch
8300 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8301 == INSN_ADDRESSES (INSN_UID (insn))))
8302 return \"b\\t%l0%#\";
8304 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8306 [(set_attr "type" "uncond_branch")])
8308 (define_expand "tablejump"
8309 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8310 (use (label_ref (match_operand 1 "" "")))])]
8314 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8317 /* In pic mode, our address differences are against the base of the
8318 table. Add that base value back in; CSE ought to be able to combine
8319 the two address loads. */
8323 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8325 if (CASE_VECTOR_MODE != Pmode)
8326 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8327 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8328 operands[0] = memory_address (Pmode, tmp);
8332 (define_insn "*tablejump_sp32"
8333 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8334 (use (label_ref (match_operand 1 "" "")))]
8337 [(set_attr "type" "uncond_branch")])
8339 (define_insn "*tablejump_sp64"
8340 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8341 (use (label_ref (match_operand 1 "" "")))]
8344 [(set_attr "type" "uncond_branch")])
8346 ;; This pattern recognizes the "instruction" that appears in
8347 ;; a function call that wants a structure value,
8348 ;; to inform the called function if compiled with Sun CC.
8349 ;(define_insn "*unimp_insn"
8350 ; [(match_operand:SI 0 "immediate_operand" "")]
8351 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8353 ; [(set_attr "type" "marker")])
8355 ;;- jump to subroutine
8356 (define_expand "call"
8357 ;; Note that this expression is not used for generating RTL.
8358 ;; All the RTL is generated explicitly below.
8359 [(call (match_operand 0 "call_operand" "")
8360 (match_operand 3 "" "i"))]
8361 ;; operands[2] is next_arg_register
8362 ;; operands[3] is struct_value_size_rtx.
8366 rtx fn_rtx, nregs_rtx;
8368 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8371 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8373 /* This is really a PIC sequence. We want to represent
8374 it as a funny jump so its delay slots can be filled.
8376 ??? But if this really *is* a CALL, will not it clobber the
8377 call-clobbered registers? We lose this if it is a JUMP_INSN.
8378 Why cannot we have delay slots filled if it were a CALL? */
8380 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8385 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8387 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8393 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8394 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8398 fn_rtx = operands[0];
8400 /* Count the number of parameter registers being used by this call.
8401 if that argument is NULL, it means we are using them all, which
8402 means 6 on the sparc. */
8405 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8407 nregs_rtx = GEN_INT (6);
8409 nregs_rtx = const0_rtx;
8412 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8416 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8418 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8423 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8424 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8428 /* If this call wants a structure value,
8429 emit an unimp insn to let the called function know about this. */
8430 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8432 rtx insn = emit_insn (operands[3]);
8433 SCHED_GROUP_P (insn) = 1;
8440 ;; We can't use the same pattern for these two insns, because then registers
8441 ;; in the address may not be properly reloaded.
8443 (define_insn "*call_address_sp32"
8444 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8445 (match_operand 1 "" ""))
8446 (clobber (reg:SI 15))]
8447 ;;- Do not use operand 1 for most machines.
8450 [(set_attr "type" "call")])
8452 (define_insn "*call_symbolic_sp32"
8453 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8454 (match_operand 1 "" ""))
8455 (clobber (reg:SI 15))]
8456 ;;- Do not use operand 1 for most machines.
8459 [(set_attr "type" "call")])
8461 (define_insn "*call_address_sp64"
8462 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8463 (match_operand 1 "" ""))
8464 (clobber (reg:DI 15))]
8465 ;;- Do not use operand 1 for most machines.
8468 [(set_attr "type" "call")])
8470 (define_insn "*call_symbolic_sp64"
8471 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8472 (match_operand 1 "" ""))
8473 (clobber (reg:DI 15))]
8474 ;;- Do not use operand 1 for most machines.
8477 [(set_attr "type" "call")])
8479 ;; This is a call that wants a structure value.
8480 ;; There is no such critter for v9 (??? we may need one anyway).
8481 (define_insn "*call_address_struct_value_sp32"
8482 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8483 (match_operand 1 "" ""))
8484 (match_operand 2 "immediate_operand" "")
8485 (clobber (reg:SI 15))]
8486 ;;- Do not use operand 1 for most machines.
8487 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8488 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8489 [(set_attr "type" "call_no_delay_slot")
8490 (set_attr "length" "2")])
8492 ;; This is a call that wants a structure value.
8493 ;; There is no such critter for v9 (??? we may need one anyway).
8494 (define_insn "*call_symbolic_struct_value_sp32"
8495 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8496 (match_operand 1 "" ""))
8497 (match_operand 2 "immediate_operand" "")
8498 (clobber (reg:SI 15))]
8499 ;;- Do not use operand 1 for most machines.
8500 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8501 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8502 [(set_attr "type" "call_no_delay_slot")
8503 (set_attr "length" "2")])
8505 ;; This is a call that may want a structure value. This is used for
8507 (define_insn "*call_address_untyped_struct_value_sp32"
8508 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8509 (match_operand 1 "" ""))
8510 (match_operand 2 "immediate_operand" "")
8511 (clobber (reg:SI 15))]
8512 ;;- Do not use operand 1 for most machines.
8513 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8514 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8515 [(set_attr "type" "call_no_delay_slot")
8516 (set_attr "length" "2")])
8518 ;; This is a call that wants a structure value.
8519 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8520 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
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 (define_expand "call_value"
8531 ;; Note that this expression is not used for generating RTL.
8532 ;; All the RTL is generated explicitly below.
8533 [(set (match_operand 0 "register_operand" "=rf")
8534 (call (match_operand 1 "" "")
8535 (match_operand 4 "" "")))]
8536 ;; operand 2 is stack_size_rtx
8537 ;; operand 3 is next_arg_register
8541 rtx fn_rtx, nregs_rtx;
8544 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8547 fn_rtx = operands[1];
8551 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8553 nregs_rtx = GEN_INT (6);
8555 nregs_rtx = const0_rtx;
8559 gen_rtx_SET (VOIDmode, operands[0],
8560 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8561 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8563 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8568 (define_insn "*call_value_address_sp32"
8569 [(set (match_operand 0 "" "=rf")
8570 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8571 (match_operand 2 "" "")))
8572 (clobber (reg:SI 15))]
8573 ;;- Do not use operand 2 for most machines.
8576 [(set_attr "type" "call")])
8578 (define_insn "*call_value_symbolic_sp32"
8579 [(set (match_operand 0 "" "=rf")
8580 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8581 (match_operand 2 "" "")))
8582 (clobber (reg:SI 15))]
8583 ;;- Do not use operand 2 for most machines.
8586 [(set_attr "type" "call")])
8588 (define_insn "*call_value_address_sp64"
8589 [(set (match_operand 0 "" "")
8590 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8591 (match_operand 2 "" "")))
8592 (clobber (reg:DI 15))]
8593 ;;- Do not use operand 2 for most machines.
8596 [(set_attr "type" "call")])
8598 (define_insn "*call_value_symbolic_sp64"
8599 [(set (match_operand 0 "" "")
8600 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8601 (match_operand 2 "" "")))
8602 (clobber (reg:DI 15))]
8603 ;;- Do not use operand 2 for most machines.
8606 [(set_attr "type" "call")])
8608 (define_expand "untyped_call"
8609 [(parallel [(call (match_operand 0 "" "")
8611 (match_operand 1 "" "")
8612 (match_operand 2 "" "")])]
8618 /* Pass constm1 to indicate that it may expect a structure value, but
8619 we don't know what size it is. */
8620 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8622 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8624 rtx set = XVECEXP (operands[2], 0, i);
8625 emit_move_insn (SET_DEST (set), SET_SRC (set));
8628 /* The optimizer does not know that the call sets the function value
8629 registers we stored in the result block. We avoid problems by
8630 claiming that all hard registers are used and clobbered at this
8632 emit_insn (gen_blockage ());
8638 (define_expand "sibcall"
8639 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8644 (define_insn "*sibcall_symbolic_sp32"
8645 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8646 (match_operand 1 "" ""))
8649 "* return output_sibcall(insn, operands[0]);"
8650 [(set_attr "type" "sibcall")])
8652 (define_insn "*sibcall_symbolic_sp64"
8653 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8654 (match_operand 1 "" ""))
8657 "* return output_sibcall(insn, operands[0]);"
8658 [(set_attr "type" "sibcall")])
8660 (define_expand "sibcall_value"
8661 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8662 (call (match_operand 1 "" "") (const_int 0)))
8667 (define_insn "*sibcall_value_symbolic_sp32"
8668 [(set (match_operand 0 "" "=rf")
8669 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8670 (match_operand 2 "" "")))
8673 "* return output_sibcall(insn, operands[1]);"
8674 [(set_attr "type" "sibcall")])
8676 (define_insn "*sibcall_value_symbolic_sp64"
8677 [(set (match_operand 0 "" "")
8678 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8679 (match_operand 2 "" "")))
8682 "* return output_sibcall(insn, operands[1]);"
8683 [(set_attr "type" "sibcall")])
8685 (define_expand "sibcall_epilogue"
8690 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8691 ;; all of memory. This blocks insns from being moved across this point.
8693 (define_insn "blockage"
8694 [(unspec_volatile [(const_int 0)] 0)]
8697 [(set_attr "length" "0")])
8699 ;; Prepare to return any type including a structure value.
8701 (define_expand "untyped_return"
8702 [(match_operand:BLK 0 "memory_operand" "")
8703 (match_operand 1 "" "")]
8707 rtx valreg1 = gen_rtx_REG (DImode, 24);
8708 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8709 rtx result = operands[0];
8711 if (! TARGET_ARCH64)
8713 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8715 rtx value = gen_reg_rtx (SImode);
8717 /* Fetch the instruction where we will return to and see if it's an unimp
8718 instruction (the most significant 10 bits will be zero). If so,
8719 update the return address to skip the unimp instruction. */
8720 emit_move_insn (value,
8721 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8722 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8723 emit_insn (gen_update_return (rtnreg, value));
8726 /* Reload the function value registers. */
8727 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8728 emit_move_insn (valreg2,
8729 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8731 /* Put USE insns before the return. */
8732 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8733 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8735 /* Construct the return. */
8736 expand_null_return ();
8741 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8742 ;; and parts of the compiler don't want to believe that the add is needed.
8744 (define_insn "update_return"
8745 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8746 (match_operand:SI 1 "register_operand" "r")] 1)]
8748 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8749 [(set_attr "type" "multi")
8750 (set_attr "length" "3")])
8752 (define_insn "return"
8756 "* return output_return (operands);"
8757 [(set_attr "type" "return")])
8760 [(set (match_operand:SI 0 "register_operand" "=r")
8761 (match_operand:SI 1 "arith_operand" "rI"))
8763 (use (reg:SI 31))])]
8764 "sparc_return_peephole_ok (operands[0], operands[1])"
8765 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8772 (define_expand "indirect_jump"
8773 [(set (pc) (match_operand 0 "address_operand" "p"))]
8777 (define_insn "*branch_sp32"
8778 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8781 [(set_attr "type" "uncond_branch")])
8783 (define_insn "*branch_sp64"
8784 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8787 [(set_attr "type" "uncond_branch")])
8789 ;; ??? Doesn't work with -mflat.
8790 (define_expand "nonlocal_goto"
8791 [(match_operand:SI 0 "general_operand" "")
8792 (match_operand:SI 1 "general_operand" "")
8793 (match_operand:SI 2 "general_operand" "")
8794 (match_operand:SI 3 "" "")]
8799 rtx chain = operands[0];
8801 rtx lab = operands[1];
8802 rtx stack = operands[2];
8803 rtx fp = operands[3];
8806 /* Trap instruction to flush all the register windows. */
8807 emit_insn (gen_flush_register_windows ());
8809 /* Load the fp value for the containing fn into %fp. This is needed
8810 because STACK refers to %fp. Note that virtual register instantiation
8811 fails if the virtual %fp isn't set from a register. */
8812 if (GET_CODE (fp) != REG)
8813 fp = force_reg (Pmode, fp);
8814 emit_move_insn (virtual_stack_vars_rtx, fp);
8816 /* Find the containing function's current nonlocal goto handler,
8817 which will do any cleanups and then jump to the label. */
8818 labreg = gen_rtx_REG (Pmode, 8);
8819 emit_move_insn (labreg, lab);
8821 /* Restore %fp from stack pointer value for containing function.
8822 The restore insn that follows will move this to %sp,
8823 and reload the appropriate value into %fp. */
8824 emit_move_insn (hard_frame_pointer_rtx, stack);
8826 /* USE of frame_pointer_rtx added for consistency; not clear if
8828 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8829 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8832 /* Return, restoring reg window and jumping to goto handler. */
8833 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8834 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8836 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8842 /* Put in the static chain register the nonlocal label address. */
8843 emit_move_insn (static_chain_rtx, chain);
8846 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8847 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8852 ;; Special trap insn to flush register windows.
8853 (define_insn "flush_register_windows"
8854 [(unspec_volatile [(const_int 0)] 1)]
8856 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8857 [(set_attr "type" "misc")])
8859 (define_insn "goto_handler_and_restore"
8860 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8861 "GET_MODE (operands[0]) == Pmode"
8862 "jmp\\t%0+0\\n\\trestore"
8863 [(set_attr "type" "multi")
8864 (set_attr "length" "2")])
8866 ;;(define_insn "goto_handler_and_restore_v9"
8867 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8868 ;; (match_operand:SI 1 "register_operand" "=r,r")
8869 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8870 ;; "TARGET_V9 && ! TARGET_ARCH64"
8872 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8873 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8874 ;; [(set_attr "type" "multi")
8875 ;; (set_attr "length" "2,3")])
8877 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8878 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8879 ;; (match_operand:DI 1 "register_operand" "=r,r")
8880 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8881 ;; "TARGET_V9 && TARGET_ARCH64"
8883 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8884 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8885 ;; [(set_attr "type" "multi")
8886 ;; (set_attr "length" "2,3")])
8888 ;; For __builtin_setjmp we need to flush register windows iff the function
8889 ;; calls alloca as well, because otherwise the register window might be
8890 ;; saved after %sp adjustement and thus setjmp would crash
8891 (define_expand "builtin_setjmp_setup"
8892 [(match_operand 0 "register_operand" "r")]
8896 emit_insn (gen_do_builtin_setjmp_setup ());
8900 ;; ??? Should set length to zero when !current_function_calls_alloca,
8901 ;; ??? but there is no easy way to get at that definition. It would
8902 ;; ??? require including function.h into sparc-protos.h and that is
8903 ;; ??? likely not a good idea. -DaveM
8904 (define_insn "do_builtin_setjmp_setup"
8905 [(unspec_volatile [(const_int 0)] 5)]
8909 if (!current_function_calls_alloca)
8915 [(set_attr "type" "misc")])
8917 ;; Pattern for use after a setjmp to store FP and the return register
8918 ;; into the stack area.
8920 (define_expand "setjmp"
8926 emit_insn (gen_setjmp_64 ());
8928 emit_insn (gen_setjmp_32 ());
8932 (define_expand "setjmp_32"
8933 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8934 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8937 { operands[0] = frame_pointer_rtx; }")
8939 (define_expand "setjmp_64"
8940 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8941 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8944 { operands[0] = frame_pointer_rtx; }")
8946 ;; Special pattern for the FLUSH instruction.
8948 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8949 ; of the define_insn otherwise missing a mode. We make "flush", aka
8950 ; gen_flush, the default one since sparc_initialize_trampoline uses
8951 ; it on SImode mem values.
8953 (define_insn "flush"
8954 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8956 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8957 [(set_attr "type" "misc")])
8959 (define_insn "flushdi"
8960 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8962 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8963 [(set_attr "type" "misc")])
8968 ;; The scan instruction searches from the most significant bit while ffs
8969 ;; searches from the least significant bit. The bit index and treatment of
8970 ;; zero also differ. It takes at least 7 instructions to get the proper
8971 ;; result. Here is an obvious 8 instruction sequence.
8974 (define_insn "ffssi2"
8975 [(set (match_operand:SI 0 "register_operand" "=&r")
8976 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8977 (clobber (match_scratch:SI 2 "=&r"))]
8978 "TARGET_SPARCLITE || TARGET_SPARCLET"
8981 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\";
8983 [(set_attr "type" "multi")
8984 (set_attr "length" "8")])
8986 ;; ??? This should be a define expand, so that the extra instruction have
8987 ;; a chance of being optimized away.
8989 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8990 ;; does, but no one uses that and we don't have a switch for it.
8992 ;(define_insn "ffsdi2"
8993 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8994 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8995 ; (clobber (match_scratch:DI 2 "=&r"))]
8997 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8998 ; [(set_attr "type" "multi")
8999 ; (set_attr "length" "4")])
9003 ;; Peepholes go at the end.
9005 ;; Optimize consecutive loads or stores into ldd and std when possible.
9006 ;; The conditions in which we do this are very restricted and are
9007 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9010 [(set (match_operand:SI 0 "memory_operand" "")
9012 (set (match_operand:SI 1 "memory_operand" "")
9015 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
9018 "operands[0] = change_address (operands[0], DImode, NULL);")
9021 [(set (match_operand:SI 0 "memory_operand" "")
9023 (set (match_operand:SI 1 "memory_operand" "")
9026 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
9029 "operands[1] = change_address (operands[1], DImode, NULL);")
9032 [(set (match_operand:SI 0 "register_operand" "")
9033 (match_operand:SI 1 "memory_operand" ""))
9034 (set (match_operand:SI 2 "register_operand" "")
9035 (match_operand:SI 3 "memory_operand" ""))]
9036 "registers_ok_for_ldd_peep (operands[0], operands[2])
9037 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9040 "operands[1] = change_address (operands[1], DImode, NULL);
9041 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
9044 [(set (match_operand:SI 0 "memory_operand" "")
9045 (match_operand:SI 1 "register_operand" ""))
9046 (set (match_operand:SI 2 "memory_operand" "")
9047 (match_operand:SI 3 "register_operand" ""))]
9048 "registers_ok_for_ldd_peep (operands[1], operands[3])
9049 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9052 "operands[0] = change_address (operands[0], DImode, NULL);
9053 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
9056 [(set (match_operand:SF 0 "register_operand" "")
9057 (match_operand:SF 1 "memory_operand" ""))
9058 (set (match_operand:SF 2 "register_operand" "")
9059 (match_operand:SF 3 "memory_operand" ""))]
9060 "registers_ok_for_ldd_peep (operands[0], operands[2])
9061 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
9064 "operands[1] = change_address (operands[1], DFmode, NULL);
9065 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
9068 [(set (match_operand:SF 0 "memory_operand" "")
9069 (match_operand:SF 1 "register_operand" ""))
9070 (set (match_operand:SF 2 "memory_operand" "")
9071 (match_operand:SF 3 "register_operand" ""))]
9072 "registers_ok_for_ldd_peep (operands[1], operands[3])
9073 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
9076 "operands[0] = change_address (operands[0], DFmode, NULL);
9077 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
9080 [(set (match_operand:SI 0 "register_operand" "")
9081 (match_operand:SI 1 "memory_operand" ""))
9082 (set (match_operand:SI 2 "register_operand" "")
9083 (match_operand:SI 3 "memory_operand" ""))]
9084 "registers_ok_for_ldd_peep (operands[2], operands[0])
9085 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9088 "operands[3] = change_address (operands[3], DImode, NULL);
9089 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9092 [(set (match_operand:SI 0 "memory_operand" "")
9093 (match_operand:SI 1 "register_operand" ""))
9094 (set (match_operand:SI 2 "memory_operand" "")
9095 (match_operand:SI 3 "register_operand" ""))]
9096 "registers_ok_for_ldd_peep (operands[3], operands[1])
9097 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9100 "operands[2] = change_address (operands[2], DImode, NULL);
9101 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9105 [(set (match_operand:SF 0 "register_operand" "")
9106 (match_operand:SF 1 "memory_operand" ""))
9107 (set (match_operand:SF 2 "register_operand" "")
9108 (match_operand:SF 3 "memory_operand" ""))]
9109 "registers_ok_for_ldd_peep (operands[2], operands[0])
9110 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9113 "operands[3] = change_address (operands[3], DFmode, NULL);
9114 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9117 [(set (match_operand:SF 0 "memory_operand" "")
9118 (match_operand:SF 1 "register_operand" ""))
9119 (set (match_operand:SF 2 "memory_operand" "")
9120 (match_operand:SF 3 "register_operand" ""))]
9121 "registers_ok_for_ldd_peep (operands[3], operands[1])
9122 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9125 "operands[2] = change_address (operands[2], DFmode, NULL);
9126 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9128 ;; Optimize the case of following a reg-reg move with a test
9129 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9130 ;; This can result from a float to fix conversion.
9133 [(set (match_operand:SI 0 "register_operand" "")
9134 (match_operand:SI 1 "register_operand" ""))
9136 (compare:CC (match_operand:SI 2 "register_operand" "")
9138 "(rtx_equal_p (operands[2], operands[0])
9139 || rtx_equal_p (operands[2], operands[1]))
9140 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9141 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9142 [(parallel [(set (match_dup 0) (match_dup 1))
9144 (compare:CC (match_dup 1) (const_int 0)))])]
9148 [(set (match_operand:DI 0 "register_operand" "")
9149 (match_operand:DI 1 "register_operand" ""))
9151 (compare:CCX (match_operand:DI 2 "register_operand" "")
9154 && (rtx_equal_p (operands[2], operands[0])
9155 || rtx_equal_p (operands[2], operands[1]))
9156 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9157 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9158 [(parallel [(set (match_dup 0) (match_dup 1))
9160 (compare:CC (match_dup 1) (const_int 0)))])]
9163 ;; Return peepholes. First the "normal" ones.
9164 ;; These are necessary to catch insns ending up in the epilogue delay list.
9166 (define_insn "*return_qi"
9167 [(set (match_operand:QI 0 "restore_operand" "")
9168 (match_operand:QI 1 "arith_operand" "rI"))
9173 if (! TARGET_ARCH64 && current_function_returns_struct)
9174 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9175 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9176 || IN_OR_GLOBAL_P (operands[1])))
9177 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9179 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9181 [(set_attr "type" "multi")
9182 (set_attr "length" "2")])
9184 (define_insn "*return_hi"
9185 [(set (match_operand:HI 0 "restore_operand" "")
9186 (match_operand:HI 1 "arith_operand" "rI"))
9191 if (! TARGET_ARCH64 && current_function_returns_struct)
9192 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9193 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9194 || IN_OR_GLOBAL_P (operands[1])))
9195 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9197 return \"ret\;restore %%g0, %1, %Y0\";
9199 [(set_attr "type" "multi")
9200 (set_attr "length" "2")])
9202 (define_insn "*return_si"
9203 [(set (match_operand:SI 0 "restore_operand" "")
9204 (match_operand:SI 1 "arith_operand" "rI"))
9209 if (! TARGET_ARCH64 && current_function_returns_struct)
9210 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9211 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9212 || IN_OR_GLOBAL_P (operands[1])))
9213 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9215 return \"ret\;restore %%g0, %1, %Y0\";
9217 [(set_attr "type" "multi")
9218 (set_attr "length" "2")])
9220 ;; The following pattern is only generated by delayed-branch scheduling,
9221 ;; when the insn winds up in the epilogue. This can happen not only when
9222 ;; ! TARGET_FPU because we move complex types around by parts using
9224 (define_insn "*return_sf_no_fpu"
9225 [(set (match_operand:SF 0 "restore_operand" "=r")
9226 (match_operand:SF 1 "register_operand" "r"))
9231 if (! TARGET_ARCH64 && current_function_returns_struct)
9232 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9233 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9234 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9236 return \"ret\;restore %%g0, %1, %Y0\";
9238 [(set_attr "type" "multi")
9239 (set_attr "length" "2")])
9241 (define_insn "*return_df_no_fpu"
9242 [(set (match_operand:DF 0 "restore_operand" "=r")
9243 (match_operand:DF 1 "register_operand" "r"))
9245 "! TARGET_EPILOGUE && TARGET_ARCH64"
9248 if (IN_OR_GLOBAL_P (operands[1]))
9249 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9251 return \"ret\;restore %%g0, %1, %Y0\";
9253 [(set_attr "type" "multi")
9254 (set_attr "length" "2")])
9256 (define_insn "*return_addsi"
9257 [(set (match_operand:SI 0 "restore_operand" "")
9258 (plus:SI (match_operand:SI 1 "register_operand" "r")
9259 (match_operand:SI 2 "arith_operand" "rI")))
9264 if (! TARGET_ARCH64 && current_function_returns_struct)
9265 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9266 /* If operands are global or in registers, can use return */
9267 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9268 && (GET_CODE (operands[2]) == CONST_INT
9269 || IN_OR_GLOBAL_P (operands[2])))
9270 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9272 return \"ret\;restore %r1, %2, %Y0\";
9274 [(set_attr "type" "multi")
9275 (set_attr "length" "2")])
9277 (define_insn "*return_losum_si"
9278 [(set (match_operand:SI 0 "restore_operand" "")
9279 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9280 (match_operand:SI 2 "immediate_operand" "in")))
9282 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9285 if (! TARGET_ARCH64 && current_function_returns_struct)
9286 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9287 /* If operands are global or in registers, can use return */
9288 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9289 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9291 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9293 [(set_attr "type" "multi")
9294 (set_attr "length" "2")])
9296 (define_insn "*return_di"
9297 [(set (match_operand:DI 0 "restore_operand" "")
9298 (match_operand:DI 1 "arith_double_operand" "rHI"))
9300 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9301 "ret\;restore %%g0, %1, %Y0"
9302 [(set_attr "type" "multi")
9303 (set_attr "length" "2")])
9305 (define_insn "*return_adddi"
9306 [(set (match_operand:DI 0 "restore_operand" "")
9307 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9308 (match_operand:DI 2 "arith_double_operand" "rHI")))
9310 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9311 "ret\;restore %r1, %2, %Y0"
9312 [(set_attr "type" "multi")
9313 (set_attr "length" "2")])
9315 (define_insn "*return_losum_di"
9316 [(set (match_operand:DI 0 "restore_operand" "")
9317 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9318 (match_operand:DI 2 "immediate_operand" "in")))
9320 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9321 "ret\;restore %r1, %%lo(%a2), %Y0"
9322 [(set_attr "type" "multi")
9323 (set_attr "length" "2")])
9325 ;; The following pattern is only generated by delayed-branch scheduling,
9326 ;; when the insn winds up in the epilogue.
9327 (define_insn "*return_sf"
9329 (match_operand:SF 0 "register_operand" "f"))
9332 "ret\;fmovs\\t%0, %%f0"
9333 [(set_attr "type" "multi")
9334 (set_attr "length" "2")])
9336 ;; Now peepholes to do a call followed by a jump.
9339 [(parallel [(set (match_operand 0 "" "")
9340 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9341 (match_operand 2 "" "")))
9342 (clobber (reg:SI 15))])
9343 (set (pc) (label_ref (match_operand 3 "" "")))]
9344 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9345 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9346 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9349 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9350 (match_operand 1 "" ""))
9351 (clobber (reg:SI 15))])
9352 (set (pc) (label_ref (match_operand 2 "" "")))]
9353 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9354 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9355 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9358 [(parallel [(set (match_operand 0 "" "")
9359 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9360 (match_operand 2 "" "")))
9361 (clobber (reg:DI 15))])
9362 (set (pc) (label_ref (match_operand 3 "" "")))]
9364 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9365 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9366 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9369 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9370 (match_operand 1 "" ""))
9371 (clobber (reg:DI 15))])
9372 (set (pc) (label_ref (match_operand 2 "" "")))]
9374 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9375 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9376 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9378 (define_insn "prefetch"
9379 [(prefetch (match_operand:DI 0 "address_operand" "p")
9380 (match_operand:DI 1 "const_int_operand" "n")
9381 (match_operand:DI 2 "const_int_operand" "n"))]
9384 static const char * const prefetch_instr[2][4] = {
9386 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9387 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9388 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9389 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9392 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9393 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9394 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9395 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9398 int read_or_write = INTVAL (operands[1]);
9399 int locality = INTVAL (operands[2]);
9401 if (read_or_write != 0 && read_or_write != 1)
9403 if (locality < 0 || locality > 3)
9405 return prefetch_instr [read_or_write][locality];
9407 [(set_attr "type" "load")])
9409 (define_expand "prologue"
9411 "flag_pic && current_function_uses_pic_offset_table"
9414 load_pic_register ();
9418 ;; We need to reload %l7 for -mflat -fpic,
9419 ;; otherwise %l7 should be preserved simply
9420 ;; by loading the function's register window
9421 (define_expand "exception_receiver"
9423 "TARGET_FLAT && flag_pic"
9426 load_pic_register ();
9431 (define_expand "builtin_setjmp_receiver"
9432 [(label_ref (match_operand 0 "" ""))]
9433 "TARGET_FLAT && flag_pic"
9436 load_pic_register ();
9441 [(trap_if (const_int 1) (const_int 5))]
9444 [(set_attr "type" "misc")])
9446 (define_expand "conditional_trap"
9447 [(trap_if (match_operator 0 "noov_compare_op"
9448 [(match_dup 2) (match_dup 3)])
9449 (match_operand:SI 1 "arith_operand" ""))]
9451 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9452 sparc_compare_op0, sparc_compare_op1);
9453 operands[3] = const0_rtx;")
9456 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9457 (match_operand:SI 1 "arith_operand" "rM"))]
9460 [(set_attr "type" "misc")])
9463 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9464 (match_operand:SI 1 "arith_operand" "rM"))]
9467 [(set_attr "type" "misc")])