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], 1, 0,
1897 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1898 ! final_sequence, insn);
1900 [(set_attr "type" "branch")])
1902 ;; XXX fpcmp nop braindamage
1903 (define_insn "*inverted_branch"
1905 (if_then_else (match_operator 0 "noov_compare_op"
1906 [(reg 100) (const_int 0)])
1908 (label_ref (match_operand 1 "" ""))))]
1912 return output_cbranch (operands[0], 1, 1,
1913 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1914 ! final_sequence, insn);
1916 [(set_attr "type" "branch")])
1918 ;; XXX fpcmp nop braindamage
1919 (define_insn "*normal_fp_branch"
1921 (if_then_else (match_operator 1 "comparison_operator"
1922 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1924 (label_ref (match_operand 2 "" ""))
1929 return output_cbranch (operands[1], 2, 0,
1930 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1931 ! final_sequence, insn);
1933 [(set_attr "type" "branch")])
1935 ;; XXX fpcmp nop braindamage
1936 (define_insn "*inverted_fp_branch"
1938 (if_then_else (match_operator 1 "comparison_operator"
1939 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1942 (label_ref (match_operand 2 "" ""))))]
1946 return output_cbranch (operands[1], 2, 1,
1947 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1948 ! final_sequence, insn);
1950 [(set_attr "type" "branch")])
1952 ;; XXX fpcmp nop braindamage
1953 (define_insn "*normal_fpe_branch"
1955 (if_then_else (match_operator 1 "comparison_operator"
1956 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1958 (label_ref (match_operand 2 "" ""))
1963 return output_cbranch (operands[1], 2, 0,
1964 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1965 ! final_sequence, insn);
1967 [(set_attr "type" "branch")])
1969 ;; XXX fpcmp nop braindamage
1970 (define_insn "*inverted_fpe_branch"
1972 (if_then_else (match_operator 1 "comparison_operator"
1973 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1976 (label_ref (match_operand 2 "" ""))))]
1980 return output_cbranch (operands[1], 2, 1,
1981 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1982 ! final_sequence, insn);
1984 [(set_attr "type" "branch")])
1986 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1987 ;; in the architecture.
1989 ;; There are no 32 bit brreg insns.
1992 (define_insn "*normal_int_branch_sp64"
1994 (if_then_else (match_operator 0 "v9_regcmp_op"
1995 [(match_operand:DI 1 "register_operand" "r")
1997 (label_ref (match_operand 2 "" ""))
2002 return output_v9branch (operands[0], 1, 2, 0,
2003 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2004 ! final_sequence, insn);
2006 [(set_attr "type" "branch")])
2009 (define_insn "*inverted_int_branch_sp64"
2011 (if_then_else (match_operator 0 "v9_regcmp_op"
2012 [(match_operand:DI 1 "register_operand" "r")
2015 (label_ref (match_operand 2 "" ""))))]
2019 return output_v9branch (operands[0], 1, 2, 1,
2020 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2021 ! final_sequence, insn);
2023 [(set_attr "type" "branch")])
2025 ;; Load program counter insns.
2027 (define_insn "get_pc"
2028 [(clobber (reg:SI 15))
2029 (set (match_operand 0 "register_operand" "=r")
2030 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2031 "flag_pic && REGNO (operands[0]) == 23"
2032 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2033 [(set_attr "type" "multi")
2034 (set_attr "length" "3")])
2036 ;; Currently unused...
2037 ;; (define_insn "get_pc_via_rdpc"
2038 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2041 ;; [(set_attr "type" "misc")])
2044 ;; Move instructions
2046 (define_expand "movqi"
2047 [(set (match_operand:QI 0 "general_operand" "")
2048 (match_operand:QI 1 "general_operand" ""))]
2052 /* Working with CONST_INTs is easier, so convert
2053 a double if needed. */
2054 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2056 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2058 else if (GET_CODE (operands[1]) == CONST_INT)
2060 /* And further, we know for all QI cases that only the
2061 low byte is significant, which we can always process
2062 in a single insn. So mask it now. */
2063 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2066 /* Handle sets of MEM first. */
2067 if (GET_CODE (operands[0]) == MEM)
2069 if (reg_or_0_operand (operands[1], QImode))
2072 if (! reload_in_progress)
2074 operands[0] = validize_mem (operands[0]);
2075 operands[1] = force_reg (QImode, operands[1]);
2079 /* Fixup PIC cases. */
2082 if (CONSTANT_P (operands[1])
2083 && pic_address_needs_scratch (operands[1]))
2084 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2086 if (symbolic_operand (operands[1], QImode))
2088 operands[1] = legitimize_pic_address (operands[1],
2090 (reload_in_progress ?
2097 /* All QI constants require only one insn, so proceed. */
2103 (define_insn "*movqi_insn"
2104 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2105 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2106 "(register_operand (operands[0], QImode)
2107 || reg_or_0_operand (operands[1], QImode))"
2112 [(set_attr "type" "*,load,store")])
2114 (define_expand "movhi"
2115 [(set (match_operand:HI 0 "general_operand" "")
2116 (match_operand:HI 1 "general_operand" ""))]
2120 /* Working with CONST_INTs is easier, so convert
2121 a double if needed. */
2122 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2123 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2125 /* Handle sets of MEM first. */
2126 if (GET_CODE (operands[0]) == MEM)
2128 if (reg_or_0_operand (operands[1], HImode))
2131 if (! reload_in_progress)
2133 operands[0] = validize_mem (operands[0]);
2134 operands[1] = force_reg (HImode, operands[1]);
2138 /* Fixup PIC cases. */
2141 if (CONSTANT_P (operands[1])
2142 && pic_address_needs_scratch (operands[1]))
2143 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2145 if (symbolic_operand (operands[1], HImode))
2147 operands[1] = legitimize_pic_address (operands[1],
2149 (reload_in_progress ?
2156 /* This makes sure we will not get rematched due to splittage. */
2157 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2159 else if (CONSTANT_P (operands[1])
2160 && GET_CODE (operands[1]) != HIGH
2161 && GET_CODE (operands[1]) != LO_SUM)
2163 sparc_emit_set_const32 (operands[0], operands[1]);
2170 (define_insn "*movhi_const64_special"
2171 [(set (match_operand:HI 0 "register_operand" "=r")
2172 (match_operand:HI 1 "const64_high_operand" ""))]
2174 "sethi\\t%%hi(%a1), %0")
2176 (define_insn "*movhi_insn"
2177 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2178 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2179 "(register_operand (operands[0], HImode)
2180 || reg_or_0_operand (operands[1], HImode))"
2183 sethi\\t%%hi(%a1), %0
2186 [(set_attr "type" "*,*,load,store")])
2188 ;; We always work with constants here.
2189 (define_insn "*movhi_lo_sum"
2190 [(set (match_operand:HI 0 "register_operand" "=r")
2191 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2192 (match_operand:HI 2 "arith_operand" "I")))]
2196 (define_expand "movsi"
2197 [(set (match_operand:SI 0 "general_operand" "")
2198 (match_operand:SI 1 "general_operand" ""))]
2202 /* Working with CONST_INTs is easier, so convert
2203 a double if needed. */
2204 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2205 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2207 /* Handle sets of MEM first. */
2208 if (GET_CODE (operands[0]) == MEM)
2210 if (reg_or_0_operand (operands[1], SImode))
2213 if (! reload_in_progress)
2215 operands[0] = validize_mem (operands[0]);
2216 operands[1] = force_reg (SImode, operands[1]);
2220 /* Fixup PIC cases. */
2223 if (CONSTANT_P (operands[1])
2224 && pic_address_needs_scratch (operands[1]))
2225 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2227 if (GET_CODE (operands[1]) == LABEL_REF)
2230 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2234 if (symbolic_operand (operands[1], SImode))
2236 operands[1] = legitimize_pic_address (operands[1],
2238 (reload_in_progress ?
2245 /* If we are trying to toss an integer constant into the
2246 FPU registers, force it into memory. */
2247 if (GET_CODE (operands[0]) == REG
2248 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2249 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2250 && CONSTANT_P (operands[1]))
2251 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2254 /* This makes sure we will not get rematched due to splittage. */
2255 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2257 else if (CONSTANT_P (operands[1])
2258 && GET_CODE (operands[1]) != HIGH
2259 && GET_CODE (operands[1]) != LO_SUM)
2261 sparc_emit_set_const32 (operands[0], operands[1]);
2268 ;; This is needed to show CSE exactly which bits are set
2269 ;; in a 64-bit register by sethi instructions.
2270 (define_insn "*movsi_const64_special"
2271 [(set (match_operand:SI 0 "register_operand" "=r")
2272 (match_operand:SI 1 "const64_high_operand" ""))]
2274 "sethi\\t%%hi(%a1), %0")
2276 (define_insn "*movsi_insn"
2277 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2278 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2279 "(register_operand (operands[0], SImode)
2280 || reg_or_0_operand (operands[1], SImode))"
2284 sethi\\t%%hi(%a1), %0
2291 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2293 (define_insn "*movsi_lo_sum"
2294 [(set (match_operand:SI 0 "register_operand" "=r")
2295 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2296 (match_operand:SI 2 "immediate_operand" "in")))]
2298 "or\\t%1, %%lo(%a2), %0")
2300 (define_insn "*movsi_high"
2301 [(set (match_operand:SI 0 "register_operand" "=r")
2302 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2304 "sethi\\t%%hi(%a1), %0")
2306 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2307 ;; so that CSE won't optimize the address computation away.
2308 (define_insn "movsi_lo_sum_pic"
2309 [(set (match_operand:SI 0 "register_operand" "=r")
2310 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2311 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2313 "or\\t%1, %%lo(%a2), %0")
2315 (define_insn "movsi_high_pic"
2316 [(set (match_operand:SI 0 "register_operand" "=r")
2317 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2318 "flag_pic && check_pic (1)"
2319 "sethi\\t%%hi(%a1), %0")
2321 (define_expand "movsi_pic_label_ref"
2322 [(set (match_dup 3) (high:SI
2323 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2325 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2326 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2327 (set (match_operand:SI 0 "register_operand" "=r")
2328 (minus:SI (match_dup 5) (match_dup 4)))]
2332 current_function_uses_pic_offset_table = 1;
2333 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2336 operands[3] = operands[0];
2337 operands[4] = operands[0];
2341 operands[3] = gen_reg_rtx (SImode);
2342 operands[4] = gen_reg_rtx (SImode);
2344 operands[5] = pic_offset_table_rtx;
2347 (define_insn "*movsi_high_pic_label_ref"
2348 [(set (match_operand:SI 0 "register_operand" "=r")
2350 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2351 (match_operand:SI 2 "" "")] 5)))]
2353 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2355 (define_insn "*movsi_lo_sum_pic_label_ref"
2356 [(set (match_operand:SI 0 "register_operand" "=r")
2357 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2358 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2359 (match_operand:SI 3 "" "")] 5)))]
2361 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2363 (define_expand "movdi"
2364 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2365 (match_operand:DI 1 "general_operand" ""))]
2369 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2370 if (GET_CODE (operands[1]) == CONST_DOUBLE
2371 #if HOST_BITS_PER_WIDE_INT == 32
2372 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2373 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2374 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2375 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2378 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2380 /* Handle MEM cases first. */
2381 if (GET_CODE (operands[0]) == MEM)
2383 /* If it's a REG, we can always do it.
2384 The const zero case is more complex, on v9
2385 we can always perform it. */
2386 if (register_operand (operands[1], DImode)
2388 && (operands[1] == const0_rtx)))
2391 if (! reload_in_progress)
2393 operands[0] = validize_mem (operands[0]);
2394 operands[1] = force_reg (DImode, operands[1]);
2400 if (CONSTANT_P (operands[1])
2401 && pic_address_needs_scratch (operands[1]))
2402 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2404 if (GET_CODE (operands[1]) == LABEL_REF)
2406 if (! TARGET_ARCH64)
2408 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2412 if (symbolic_operand (operands[1], DImode))
2414 operands[1] = legitimize_pic_address (operands[1],
2416 (reload_in_progress ?
2423 /* If we are trying to toss an integer constant into the
2424 FPU registers, force it into memory. */
2425 if (GET_CODE (operands[0]) == REG
2426 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2427 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2428 && CONSTANT_P (operands[1]))
2429 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2432 /* This makes sure we will not get rematched due to splittage. */
2433 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2435 else if (TARGET_ARCH64
2436 && CONSTANT_P (operands[1])
2437 && GET_CODE (operands[1]) != HIGH
2438 && GET_CODE (operands[1]) != LO_SUM)
2440 sparc_emit_set_const64 (operands[0], operands[1]);
2448 ;; Be careful, fmovd does not exist when !arch64.
2449 ;; We match MEM moves directly when we have correct even
2450 ;; numbered registers, but fall into splits otherwise.
2451 ;; The constraint ordering here is really important to
2452 ;; avoid insane problems in reload, especially for patterns
2455 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2456 ;; (const_int -5016)))
2460 (define_insn "*movdi_insn_sp32_v9"
2461 [(set (match_operand:DI 0 "nonimmediate_operand"
2462 "=m,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2463 (match_operand:DI 1 "input_operand"
2464 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2465 "! TARGET_ARCH64 && TARGET_V9
2466 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2480 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2481 (set_attr "length" "*,*,*,2,2,2,2,*,*,2,2,2")])
2483 (define_insn "*movdi_insn_sp32"
2484 [(set (match_operand:DI 0 "nonimmediate_operand"
2485 "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2486 (match_operand:DI 1 "input_operand"
2487 " U,T,r,o,i,r, f, T, o, f, f"))]
2489 && (register_operand (operands[0], DImode)
2490 || register_operand (operands[1], DImode))"
2503 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2504 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2506 ;; The following are generated by sparc_emit_set_const64
2507 (define_insn "*movdi_sp64_dbl"
2508 [(set (match_operand:DI 0 "register_operand" "=r")
2509 (match_operand:DI 1 "const64_operand" ""))]
2511 && HOST_BITS_PER_WIDE_INT != 64)"
2514 ;; This is needed to show CSE exactly which bits are set
2515 ;; in a 64-bit register by sethi instructions.
2516 (define_insn "*movdi_const64_special"
2517 [(set (match_operand:DI 0 "register_operand" "=r")
2518 (match_operand:DI 1 "const64_high_operand" ""))]
2520 "sethi\\t%%hi(%a1), %0")
2522 (define_insn "*movdi_insn_sp64_novis"
2523 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2524 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2525 "TARGET_ARCH64 && ! TARGET_VIS
2526 && (register_operand (operands[0], DImode)
2527 || reg_or_0_operand (operands[1], DImode))"
2530 sethi\\t%%hi(%a1), %0
2537 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2538 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2540 (define_insn "*movdi_insn_sp64_vis"
2541 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2542 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2543 "TARGET_ARCH64 && TARGET_VIS &&
2544 (register_operand (operands[0], DImode)
2545 || reg_or_0_operand (operands[1], DImode))"
2548 sethi\\t%%hi(%a1), %0
2556 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2557 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2559 (define_expand "movdi_pic_label_ref"
2560 [(set (match_dup 3) (high:DI
2561 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2563 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2564 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2565 (set (match_operand:DI 0 "register_operand" "=r")
2566 (minus:DI (match_dup 5) (match_dup 4)))]
2567 "TARGET_ARCH64 && flag_pic"
2570 current_function_uses_pic_offset_table = 1;
2571 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2574 operands[3] = operands[0];
2575 operands[4] = operands[0];
2579 operands[3] = gen_reg_rtx (DImode);
2580 operands[4] = gen_reg_rtx (DImode);
2582 operands[5] = pic_offset_table_rtx;
2585 (define_insn "*movdi_high_pic_label_ref"
2586 [(set (match_operand:DI 0 "register_operand" "=r")
2588 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2589 (match_operand:DI 2 "" "")] 5)))]
2590 "TARGET_ARCH64 && flag_pic"
2591 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2593 (define_insn "*movdi_lo_sum_pic_label_ref"
2594 [(set (match_operand:DI 0 "register_operand" "=r")
2595 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2596 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2597 (match_operand:DI 3 "" "")] 5)))]
2598 "TARGET_ARCH64 && flag_pic"
2599 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2601 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2602 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2604 (define_insn "movdi_lo_sum_pic"
2605 [(set (match_operand:DI 0 "register_operand" "=r")
2606 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2607 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2608 "TARGET_ARCH64 && flag_pic"
2609 "or\\t%1, %%lo(%a2), %0")
2611 (define_insn "movdi_high_pic"
2612 [(set (match_operand:DI 0 "register_operand" "=r")
2613 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2614 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2615 "sethi\\t%%hi(%a1), %0")
2617 (define_insn "*sethi_di_medlow_embmedany_pic"
2618 [(set (match_operand:DI 0 "register_operand" "=r")
2619 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2620 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2621 "sethi\\t%%hi(%a1), %0")
2623 (define_insn "*sethi_di_medlow"
2624 [(set (match_operand:DI 0 "register_operand" "=r")
2625 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2626 "TARGET_CM_MEDLOW && check_pic (1)"
2627 "sethi\\t%%hi(%a1), %0")
2629 (define_insn "*losum_di_medlow"
2630 [(set (match_operand:DI 0 "register_operand" "=r")
2631 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2632 (match_operand:DI 2 "symbolic_operand" "")))]
2634 "or\\t%1, %%lo(%a2), %0")
2636 (define_insn "seth44"
2637 [(set (match_operand:DI 0 "register_operand" "=r")
2638 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2640 "sethi\\t%%h44(%a1), %0")
2642 (define_insn "setm44"
2643 [(set (match_operand:DI 0 "register_operand" "=r")
2644 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2645 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2647 "or\\t%1, %%m44(%a2), %0")
2649 (define_insn "setl44"
2650 [(set (match_operand:DI 0 "register_operand" "=r")
2651 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2652 (match_operand:DI 2 "symbolic_operand" "")))]
2654 "or\\t%1, %%l44(%a2), %0")
2656 (define_insn "sethh"
2657 [(set (match_operand:DI 0 "register_operand" "=r")
2658 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2660 "sethi\\t%%hh(%a1), %0")
2662 (define_insn "setlm"
2663 [(set (match_operand:DI 0 "register_operand" "=r")
2664 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2666 "sethi\\t%%lm(%a1), %0")
2668 (define_insn "sethm"
2669 [(set (match_operand:DI 0 "register_operand" "=r")
2670 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2671 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2673 "or\\t%1, %%hm(%a2), %0")
2675 (define_insn "setlo"
2676 [(set (match_operand:DI 0 "register_operand" "=r")
2677 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2678 (match_operand:DI 2 "symbolic_operand" "")))]
2680 "or\\t%1, %%lo(%a2), %0")
2682 (define_insn "embmedany_sethi"
2683 [(set (match_operand:DI 0 "register_operand" "=r")
2684 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2685 "TARGET_CM_EMBMEDANY && check_pic (1)"
2686 "sethi\\t%%hi(%a1), %0")
2688 (define_insn "embmedany_losum"
2689 [(set (match_operand:DI 0 "register_operand" "=r")
2690 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2691 (match_operand:DI 2 "data_segment_operand" "")))]
2692 "TARGET_CM_EMBMEDANY"
2693 "add\\t%1, %%lo(%a2), %0")
2695 (define_insn "embmedany_brsum"
2696 [(set (match_operand:DI 0 "register_operand" "=r")
2697 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2698 "TARGET_CM_EMBMEDANY"
2701 (define_insn "embmedany_textuhi"
2702 [(set (match_operand:DI 0 "register_operand" "=r")
2703 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2704 "TARGET_CM_EMBMEDANY && check_pic (1)"
2705 "sethi\\t%%uhi(%a1), %0")
2707 (define_insn "embmedany_texthi"
2708 [(set (match_operand:DI 0 "register_operand" "=r")
2709 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2710 "TARGET_CM_EMBMEDANY && check_pic (1)"
2711 "sethi\\t%%hi(%a1), %0")
2713 (define_insn "embmedany_textulo"
2714 [(set (match_operand:DI 0 "register_operand" "=r")
2715 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2716 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2717 "TARGET_CM_EMBMEDANY"
2718 "or\\t%1, %%ulo(%a2), %0")
2720 (define_insn "embmedany_textlo"
2721 [(set (match_operand:DI 0 "register_operand" "=r")
2722 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2723 (match_operand:DI 2 "text_segment_operand" "")))]
2724 "TARGET_CM_EMBMEDANY"
2725 "or\\t%1, %%lo(%a2), %0")
2727 ;; Now some patterns to help reload out a bit.
2728 (define_expand "reload_indi"
2729 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2730 (match_operand:DI 1 "immediate_operand" "")
2731 (match_operand:TI 2 "register_operand" "=&r")])]
2733 || TARGET_CM_EMBMEDANY)
2737 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2738 gen_rtx_REG (DImode, REGNO (operands[2])));
2742 (define_expand "reload_outdi"
2743 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2744 (match_operand:DI 1 "immediate_operand" "")
2745 (match_operand:TI 2 "register_operand" "=&r")])]
2747 || TARGET_CM_EMBMEDANY)
2751 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2752 gen_rtx_REG (DImode, REGNO (operands[2])));
2756 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2758 [(set (match_operand:DI 0 "register_operand" "")
2759 (match_operand:DI 1 "const_int_operand" ""))]
2760 "! TARGET_ARCH64 && reload_completed"
2761 [(clobber (const_int 0))]
2764 #if HOST_BITS_PER_WIDE_INT == 32
2765 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2766 (INTVAL (operands[1]) < 0) ?
2769 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2772 unsigned int low, high;
2774 low = INTVAL (operands[1]) & 0xffffffff;
2775 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2776 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2778 /* Slick... but this trick loses if this subreg constant part
2779 can be done in one insn. */
2780 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2781 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2782 gen_highpart (SImode, operands[0])));
2784 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2790 [(set (match_operand:DI 0 "register_operand" "")
2791 (match_operand:DI 1 "const_double_operand" ""))]
2792 "! TARGET_ARCH64 && reload_completed"
2793 [(clobber (const_int 0))]
2796 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2797 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2799 /* Slick... but this trick loses if this subreg constant part
2800 can be done in one insn. */
2801 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2802 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2803 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2805 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2806 gen_highpart (SImode, operands[0])));
2810 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2811 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2817 [(set (match_operand:DI 0 "register_operand" "")
2818 (match_operand:DI 1 "register_operand" ""))]
2819 "! TARGET_ARCH64 && reload_completed"
2820 [(clobber (const_int 0))]
2823 rtx set_dest = operands[0];
2824 rtx set_src = operands[1];
2828 dest1 = gen_highpart (SImode, set_dest);
2829 dest2 = gen_lowpart (SImode, set_dest);
2830 src1 = gen_highpart (SImode, set_src);
2831 src2 = gen_lowpart (SImode, set_src);
2833 /* Now emit using the real source and destination we found, swapping
2834 the order if we detect overlap. */
2835 if (reg_overlap_mentioned_p (dest1, src2))
2837 emit_insn (gen_movsi (dest2, src2));
2838 emit_insn (gen_movsi (dest1, src1));
2842 emit_insn (gen_movsi (dest1, src1));
2843 emit_insn (gen_movsi (dest2, src2));
2848 ;; Now handle the cases of memory moves from/to non-even
2849 ;; DI mode register pairs.
2851 [(set (match_operand:DI 0 "register_operand" "")
2852 (match_operand:DI 1 "memory_operand" ""))]
2855 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2856 [(clobber (const_int 0))]
2859 rtx word0 = adjust_address (operands[1], SImode, 0);
2860 rtx word1 = adjust_address (operands[1], SImode, 4);
2861 rtx high_part = gen_highpart (SImode, operands[0]);
2862 rtx low_part = gen_lowpart (SImode, operands[0]);
2864 if (reg_overlap_mentioned_p (high_part, word1))
2866 emit_insn (gen_movsi (low_part, word1));
2867 emit_insn (gen_movsi (high_part, word0));
2871 emit_insn (gen_movsi (high_part, word0));
2872 emit_insn (gen_movsi (low_part, word1));
2878 [(set (match_operand:DI 0 "memory_operand" "")
2879 (match_operand:DI 1 "register_operand" ""))]
2882 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2883 [(clobber (const_int 0))]
2886 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2887 gen_highpart (SImode, operands[1])));
2888 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2889 gen_lowpart (SImode, operands[1])));
2894 ;; Floating point move insns
2896 (define_insn "*movsf_insn_novis"
2897 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2898 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2899 "(TARGET_FPU && ! TARGET_VIS)
2900 && (register_operand (operands[0], SFmode)
2901 || register_operand (operands[1], SFmode)
2902 || fp_zero_operand (operands[1], SFmode))"
2905 if (GET_CODE (operands[1]) == CONST_DOUBLE
2906 && (which_alternative == 2
2907 || which_alternative == 3
2908 || which_alternative == 4))
2913 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2914 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2915 operands[1] = GEN_INT (i);
2918 switch (which_alternative)
2921 return \"fmovs\\t%1, %0\";
2923 return \"clr\\t%0\";
2925 return \"sethi\\t%%hi(%a1), %0\";
2927 return \"mov\\t%1, %0\";
2932 return \"ld\\t%1, %0\";
2935 return \"st\\t%r1, %0\";
2940 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2942 (define_insn "*movsf_insn_vis"
2943 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2944 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2945 "(TARGET_FPU && TARGET_VIS)
2946 && (register_operand (operands[0], SFmode)
2947 || register_operand (operands[1], SFmode)
2948 || fp_zero_operand (operands[1], SFmode))"
2951 if (GET_CODE (operands[1]) == CONST_DOUBLE
2952 && (which_alternative == 3
2953 || which_alternative == 4
2954 || which_alternative == 5))
2959 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2960 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2961 operands[1] = GEN_INT (i);
2964 switch (which_alternative)
2967 return \"fmovs\\t%1, %0\";
2969 return \"fzeros\\t%0\";
2971 return \"clr\\t%0\";
2973 return \"sethi\\t%%hi(%a1), %0\";
2975 return \"mov\\t%1, %0\";
2980 return \"ld\\t%1, %0\";
2983 return \"st\\t%r1, %0\";
2988 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2990 ;; Exactly the same as above, except that all `f' cases are deleted.
2991 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2994 (define_insn "*movsf_no_f_insn"
2995 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2996 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2998 && (register_operand (operands[0], SFmode)
2999 || register_operand (operands[1], SFmode)
3000 || fp_zero_operand (operands[1], SFmode))"
3003 if (GET_CODE (operands[1]) == CONST_DOUBLE
3004 && (which_alternative == 1
3005 || which_alternative == 2
3006 || which_alternative == 3))
3011 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3012 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3013 operands[1] = GEN_INT (i);
3016 switch (which_alternative)
3019 return \"clr\\t%0\";
3021 return \"sethi\\t%%hi(%a1), %0\";
3023 return \"mov\\t%1, %0\";
3027 return \"ld\\t%1, %0\";
3029 return \"st\\t%r1, %0\";
3034 [(set_attr "type" "*,*,*,*,load,store")])
3036 (define_insn "*movsf_lo_sum"
3037 [(set (match_operand:SF 0 "register_operand" "=r")
3038 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3039 (match_operand:SF 2 "const_double_operand" "S")))]
3040 "fp_high_losum_p (operands[2])"
3046 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3047 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3048 operands[2] = GEN_INT (i);
3049 return \"or\\t%1, %%lo(%a2), %0\";
3052 (define_insn "*movsf_high"
3053 [(set (match_operand:SF 0 "register_operand" "=r")
3054 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3055 "fp_high_losum_p (operands[1])"
3061 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3062 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3063 operands[1] = GEN_INT (i);
3064 return \"sethi\\t%%hi(%1), %0\";
3068 [(set (match_operand:SF 0 "register_operand" "")
3069 (match_operand:SF 1 "const_double_operand" ""))]
3070 "fp_high_losum_p (operands[1])
3071 && (GET_CODE (operands[0]) == REG
3072 && REGNO (operands[0]) < 32)"
3073 [(set (match_dup 0) (high:SF (match_dup 1)))
3074 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3076 (define_expand "movsf"
3077 [(set (match_operand:SF 0 "general_operand" "")
3078 (match_operand:SF 1 "general_operand" ""))]
3082 /* Force SFmode constants into memory. */
3083 if (GET_CODE (operands[0]) == REG
3084 && CONSTANT_P (operands[1]))
3086 /* emit_group_store will send such bogosity to us when it is
3087 not storing directly into memory. So fix this up to avoid
3088 crashes in output_constant_pool. */
3089 if (operands [1] == const0_rtx)
3090 operands[1] = CONST0_RTX (SFmode);
3092 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3095 /* We are able to build any SF constant in integer registers
3096 with at most 2 instructions. */
3097 if (REGNO (operands[0]) < 32)
3100 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3104 /* Handle sets of MEM first. */
3105 if (GET_CODE (operands[0]) == MEM)
3107 if (register_operand (operands[1], SFmode)
3108 || fp_zero_operand (operands[1], SFmode))
3111 if (! reload_in_progress)
3113 operands[0] = validize_mem (operands[0]);
3114 operands[1] = force_reg (SFmode, operands[1]);
3118 /* Fixup PIC cases. */
3121 if (CONSTANT_P (operands[1])
3122 && pic_address_needs_scratch (operands[1]))
3123 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3125 if (symbolic_operand (operands[1], SFmode))
3127 operands[1] = legitimize_pic_address (operands[1],
3129 (reload_in_progress ?
3139 (define_expand "movdf"
3140 [(set (match_operand:DF 0 "general_operand" "")
3141 (match_operand:DF 1 "general_operand" ""))]
3145 /* Force DFmode constants into memory. */
3146 if (GET_CODE (operands[0]) == REG
3147 && CONSTANT_P (operands[1]))
3149 /* emit_group_store will send such bogosity to us when it is
3150 not storing directly into memory. So fix this up to avoid
3151 crashes in output_constant_pool. */
3152 if (operands [1] == const0_rtx)
3153 operands[1] = CONST0_RTX (DFmode);
3155 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3156 && fp_zero_operand (operands[1], DFmode))
3159 /* We are able to build any DF constant in integer registers. */
3160 if (REGNO (operands[0]) < 32
3161 && (reload_completed || reload_in_progress))
3164 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3168 /* Handle MEM cases first. */
3169 if (GET_CODE (operands[0]) == MEM)
3171 if (register_operand (operands[1], DFmode)
3172 || fp_zero_operand (operands[1], DFmode))
3175 if (! reload_in_progress)
3177 operands[0] = validize_mem (operands[0]);
3178 operands[1] = force_reg (DFmode, operands[1]);
3182 /* Fixup PIC cases. */
3185 if (CONSTANT_P (operands[1])
3186 && pic_address_needs_scratch (operands[1]))
3187 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3189 if (symbolic_operand (operands[1], DFmode))
3191 operands[1] = legitimize_pic_address (operands[1],
3193 (reload_in_progress ?
3203 ;; Be careful, fmovd does not exist when !v9.
3204 (define_insn "*movdf_insn_sp32"
3205 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3206 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3209 && (register_operand (operands[0], DFmode)
3210 || register_operand (operands[1], DFmode)
3211 || fp_zero_operand (operands[1], DFmode))"
3223 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3224 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3226 (define_insn "*movdf_no_e_insn_sp32"
3227 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3228 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3232 && (register_operand (operands[0], DFmode)
3233 || register_operand (operands[1], DFmode)
3234 || fp_zero_operand (operands[1], DFmode))"
3241 [(set_attr "type" "load,store,*,*,*")
3242 (set_attr "length" "*,*,2,2,2")])
3244 (define_insn "*movdf_no_e_insn_v9_sp32"
3245 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3246 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3250 && (register_operand (operands[0], DFmode)
3251 || register_operand (operands[1], DFmode)
3252 || fp_zero_operand (operands[1], DFmode))"
3259 [(set_attr "type" "load,store,store,*,*")
3260 (set_attr "length" "*,*,*,2,2")])
3262 ;; We have available v9 double floats but not 64-bit
3263 ;; integer registers and no VIS.
3264 (define_insn "*movdf_insn_v9only_novis"
3265 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3266 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3271 && (register_operand (operands[0], DFmode)
3272 || register_operand (operands[1], DFmode)
3273 || fp_zero_operand (operands[1], DFmode))"
3284 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3285 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3286 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3288 ;; We have available v9 double floats but not 64-bit
3289 ;; integer registers but we have VIS.
3290 (define_insn "*movdf_insn_v9only_vis"
3291 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3292 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3296 && (register_operand (operands[0], DFmode)
3297 || register_operand (operands[1], DFmode)
3298 || fp_zero_operand (operands[1], DFmode))"
3310 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3311 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3312 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3314 ;; We have available both v9 double floats and 64-bit
3315 ;; integer registers. No VIS though.
3316 (define_insn "*movdf_insn_sp64_novis"
3317 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3318 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3322 && (register_operand (operands[0], DFmode)
3323 || register_operand (operands[1], DFmode)
3324 || fp_zero_operand (operands[1], DFmode))"
3333 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3334 (set_attr "length" "*,*,*,*,*,*,2")
3335 (set_attr "fptype" "double,*,*,*,*,*,*")])
3337 ;; We have available both v9 double floats and 64-bit
3338 ;; integer registers. And we have VIS.
3339 (define_insn "*movdf_insn_sp64_vis"
3340 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3341 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3345 && (register_operand (operands[0], DFmode)
3346 || register_operand (operands[1], DFmode)
3347 || fp_zero_operand (operands[1], DFmode))"
3357 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3358 (set_attr "length" "*,*,*,*,*,*,*,2")
3359 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3361 (define_insn "*movdf_no_e_insn_sp64"
3362 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3363 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3366 && (register_operand (operands[0], DFmode)
3367 || register_operand (operands[1], DFmode)
3368 || fp_zero_operand (operands[1], DFmode))"
3373 [(set_attr "type" "*,load,store")])
3376 [(set (match_operand:DF 0 "register_operand" "")
3377 (match_operand:DF 1 "const_double_operand" ""))]
3379 && (GET_CODE (operands[0]) == REG
3380 && REGNO (operands[0]) < 32)
3381 && ! fp_zero_operand(operands[1], DFmode)
3382 && reload_completed"
3383 [(clobber (const_int 0))]
3389 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3390 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3391 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3395 #if HOST_BITS_PER_WIDE_INT == 64
3398 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3399 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3400 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3402 emit_insn (gen_movdi (operands[0],
3403 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3408 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3411 /* Slick... but this trick loses if this subreg constant part
3412 can be done in one insn. */
3414 && !(SPARC_SETHI_P (l[0])
3415 || SPARC_SIMM13_P (l[0])))
3417 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3418 gen_highpart (SImode, operands[0])));
3422 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3429 ;; Ok, now the splits to handle all the multi insn and
3430 ;; mis-aligned memory address cases.
3431 ;; In these splits please take note that we must be
3432 ;; careful when V9 but not ARCH64 because the integer
3433 ;; register DFmode cases must be handled.
3435 [(set (match_operand:DF 0 "register_operand" "")
3436 (match_operand:DF 1 "register_operand" ""))]
3439 && ((GET_CODE (operands[0]) == REG
3440 && REGNO (operands[0]) < 32)
3441 || (GET_CODE (operands[0]) == SUBREG
3442 && GET_CODE (SUBREG_REG (operands[0])) == REG
3443 && REGNO (SUBREG_REG (operands[0])) < 32))))
3444 && reload_completed"
3445 [(clobber (const_int 0))]
3448 rtx set_dest = operands[0];
3449 rtx set_src = operands[1];
3453 dest1 = gen_highpart (SFmode, set_dest);
3454 dest2 = gen_lowpart (SFmode, set_dest);
3455 src1 = gen_highpart (SFmode, set_src);
3456 src2 = gen_lowpart (SFmode, set_src);
3458 /* Now emit using the real source and destination we found, swapping
3459 the order if we detect overlap. */
3460 if (reg_overlap_mentioned_p (dest1, src2))
3462 emit_insn (gen_movsf (dest2, src2));
3463 emit_insn (gen_movsf (dest1, src1));
3467 emit_insn (gen_movsf (dest1, src1));
3468 emit_insn (gen_movsf (dest2, src2));
3474 [(set (match_operand:DF 0 "register_operand" "")
3475 (match_operand:DF 1 "memory_operand" ""))]
3478 && (((REGNO (operands[0]) % 2) != 0)
3479 || ! mem_min_alignment (operands[1], 8))
3480 && offsettable_memref_p (operands[1])"
3481 [(clobber (const_int 0))]
3484 rtx word0 = adjust_address (operands[1], SFmode, 0);
3485 rtx word1 = adjust_address (operands[1], SFmode, 4);
3487 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3489 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3491 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3496 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3498 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3505 [(set (match_operand:DF 0 "memory_operand" "")
3506 (match_operand:DF 1 "register_operand" ""))]
3509 && (((REGNO (operands[1]) % 2) != 0)
3510 || ! mem_min_alignment (operands[0], 8))
3511 && offsettable_memref_p (operands[0])"
3512 [(clobber (const_int 0))]
3515 rtx word0 = adjust_address (operands[0], SFmode, 0);
3516 rtx word1 = adjust_address (operands[0], SFmode, 4);
3518 emit_insn (gen_movsf (word0,
3519 gen_highpart (SFmode, operands[1])));
3520 emit_insn (gen_movsf (word1,
3521 gen_lowpart (SFmode, operands[1])));
3526 [(set (match_operand:DF 0 "memory_operand" "")
3527 (match_operand:DF 1 "fp_zero_operand" ""))]
3531 && ! mem_min_alignment (operands[0], 8)))
3532 && offsettable_memref_p (operands[0])"
3533 [(clobber (const_int 0))]
3538 dest1 = adjust_address (operands[0], SFmode, 0);
3539 dest2 = adjust_address (operands[0], SFmode, 4);
3541 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3542 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3547 [(set (match_operand:DF 0 "register_operand" "")
3548 (match_operand:DF 1 "fp_zero_operand" ""))]
3551 && ((GET_CODE (operands[0]) == REG
3552 && REGNO (operands[0]) < 32)
3553 || (GET_CODE (operands[0]) == SUBREG
3554 && GET_CODE (SUBREG_REG (operands[0])) == REG
3555 && REGNO (SUBREG_REG (operands[0])) < 32))"
3556 [(clobber (const_int 0))]
3559 rtx set_dest = operands[0];
3562 dest1 = gen_highpart (SFmode, set_dest);
3563 dest2 = gen_lowpart (SFmode, set_dest);
3564 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3565 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3569 (define_expand "movtf"
3570 [(set (match_operand:TF 0 "general_operand" "")
3571 (match_operand:TF 1 "general_operand" ""))]
3575 /* Force TFmode constants into memory. */
3576 if (GET_CODE (operands[0]) == REG
3577 && CONSTANT_P (operands[1]))
3579 /* emit_group_store will send such bogosity to us when it is
3580 not storing directly into memory. So fix this up to avoid
3581 crashes in output_constant_pool. */
3582 if (operands [1] == const0_rtx)
3583 operands[1] = CONST0_RTX (TFmode);
3585 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3588 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3592 /* Handle MEM cases first, note that only v9 guarentees
3593 full 16-byte alignment for quads. */
3594 if (GET_CODE (operands[0]) == MEM)
3596 if (register_operand (operands[1], TFmode)
3597 || fp_zero_operand (operands[1], TFmode))
3600 if (! reload_in_progress)
3602 operands[0] = validize_mem (operands[0]);
3603 operands[1] = force_reg (TFmode, operands[1]);
3607 /* Fixup PIC cases. */
3610 if (CONSTANT_P (operands[1])
3611 && pic_address_needs_scratch (operands[1]))
3612 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3614 if (symbolic_operand (operands[1], TFmode))
3616 operands[1] = legitimize_pic_address (operands[1],
3618 (reload_in_progress ?
3628 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3629 ;; we must split them all. :-(
3630 (define_insn "*movtf_insn_sp32"
3631 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3632 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3636 && (register_operand (operands[0], TFmode)
3637 || register_operand (operands[1], TFmode)
3638 || fp_zero_operand (operands[1], TFmode))"
3640 [(set_attr "length" "4")])
3642 (define_insn "*movtf_insn_vis_sp32"
3643 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3644 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3648 && (register_operand (operands[0], TFmode)
3649 || register_operand (operands[1], TFmode)
3650 || fp_zero_operand (operands[1], TFmode))"
3652 [(set_attr "length" "4")])
3654 ;; Exactly the same as above, except that all `e' cases are deleted.
3655 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3658 (define_insn "*movtf_no_e_insn_sp32"
3659 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3660 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3663 && (register_operand (operands[0], TFmode)
3664 || register_operand (operands[1], TFmode)
3665 || fp_zero_operand (operands[1], TFmode))"
3667 [(set_attr "length" "4")])
3669 ;; Now handle the float reg cases directly when arch64,
3670 ;; hard_quad, and proper reg number alignment are all true.
3671 (define_insn "*movtf_insn_hq_sp64"
3672 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3673 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3678 && (register_operand (operands[0], TFmode)
3679 || register_operand (operands[1], TFmode)
3680 || fp_zero_operand (operands[1], TFmode))"
3687 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3688 (set_attr "length" "*,*,*,2,2")])
3690 (define_insn "*movtf_insn_hq_vis_sp64"
3691 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3692 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3697 && (register_operand (operands[0], TFmode)
3698 || register_operand (operands[1], TFmode)
3699 || fp_zero_operand (operands[1], TFmode))"
3707 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3708 (set_attr "length" "*,*,*,2,2,2")])
3710 ;; Now we allow the integer register cases even when
3711 ;; only arch64 is true.
3712 (define_insn "*movtf_insn_sp64"
3713 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3714 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3718 && ! TARGET_HARD_QUAD
3719 && (register_operand (operands[0], TFmode)
3720 || register_operand (operands[1], TFmode)
3721 || fp_zero_operand (operands[1], TFmode))"
3723 [(set_attr "length" "2")])
3725 (define_insn "*movtf_insn_vis_sp64"
3726 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3727 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3731 && ! TARGET_HARD_QUAD
3732 && (register_operand (operands[0], TFmode)
3733 || register_operand (operands[1], TFmode)
3734 || fp_zero_operand (operands[1], TFmode))"
3736 [(set_attr "length" "2")])
3738 (define_insn "*movtf_no_e_insn_sp64"
3739 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3740 (match_operand:TF 1 "input_operand" "orG,rG"))]
3743 && (register_operand (operands[0], TFmode)
3744 || register_operand (operands[1], TFmode)
3745 || fp_zero_operand (operands[1], TFmode))"
3747 [(set_attr "length" "2")])
3749 ;; Now all the splits to handle multi-insn TF mode moves.
3751 [(set (match_operand:TF 0 "register_operand" "")
3752 (match_operand:TF 1 "register_operand" ""))]
3756 && ! TARGET_HARD_QUAD))"
3757 [(clobber (const_int 0))]
3760 rtx set_dest = operands[0];
3761 rtx set_src = operands[1];
3765 dest1 = gen_df_reg (set_dest, 0);
3766 dest2 = gen_df_reg (set_dest, 1);
3767 src1 = gen_df_reg (set_src, 0);
3768 src2 = gen_df_reg (set_src, 1);
3770 /* Now emit using the real source and destination we found, swapping
3771 the order if we detect overlap. */
3772 if (reg_overlap_mentioned_p (dest1, src2))
3774 emit_insn (gen_movdf (dest2, src2));
3775 emit_insn (gen_movdf (dest1, src1));
3779 emit_insn (gen_movdf (dest1, src1));
3780 emit_insn (gen_movdf (dest2, src2));
3786 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3787 (match_operand:TF 1 "fp_zero_operand" ""))]
3789 [(clobber (const_int 0))]
3792 rtx set_dest = operands[0];
3795 switch (GET_CODE (set_dest))
3798 dest1 = gen_df_reg (set_dest, 0);
3799 dest2 = gen_df_reg (set_dest, 1);
3802 dest1 = adjust_address (set_dest, DFmode, 0);
3803 dest2 = adjust_address (set_dest, DFmode, 8);
3809 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3810 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3815 [(set (match_operand:TF 0 "register_operand" "")
3816 (match_operand:TF 1 "memory_operand" ""))]
3818 && offsettable_memref_p (operands[1]))"
3819 [(clobber (const_int 0))]
3822 rtx word0 = adjust_address (operands[1], DFmode, 0);
3823 rtx word1 = adjust_address (operands[1], DFmode, 8);
3824 rtx set_dest, dest1, dest2;
3826 set_dest = operands[0];
3828 dest1 = gen_df_reg (set_dest, 0);
3829 dest2 = gen_df_reg (set_dest, 1);
3831 /* Now output, ordering such that we don't clobber any registers
3832 mentioned in the address. */
3833 if (reg_overlap_mentioned_p (dest1, word1))
3836 emit_insn (gen_movdf (dest2, word1));
3837 emit_insn (gen_movdf (dest1, word0));
3841 emit_insn (gen_movdf (dest1, word0));
3842 emit_insn (gen_movdf (dest2, word1));
3848 [(set (match_operand:TF 0 "memory_operand" "")
3849 (match_operand:TF 1 "register_operand" ""))]
3851 && offsettable_memref_p (operands[0]))"
3852 [(clobber (const_int 0))]
3855 rtx set_src = operands[1];
3857 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3858 gen_df_reg (set_src, 0)));
3859 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3860 gen_df_reg (set_src, 1)));
3864 ;; Sparc V9 conditional move instructions.
3866 ;; We can handle larger constants here for some flavors, but for now we keep
3867 ;; it simple and only allow those constants supported by all flavours.
3868 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3869 ;; 3 contains the constant if one is present, but we handle either for
3870 ;; generality (sparc.c puts a constant in operand 2).
3872 (define_expand "movqicc"
3873 [(set (match_operand:QI 0 "register_operand" "")
3874 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3875 (match_operand:QI 2 "arith10_operand" "")
3876 (match_operand:QI 3 "arith10_operand" "")))]
3880 enum rtx_code code = GET_CODE (operands[1]);
3882 if (GET_MODE (sparc_compare_op0) == DImode
3886 if (sparc_compare_op1 == const0_rtx
3887 && GET_CODE (sparc_compare_op0) == REG
3888 && GET_MODE (sparc_compare_op0) == DImode
3889 && v9_regcmp_p (code))
3891 operands[1] = gen_rtx_fmt_ee (code, DImode,
3892 sparc_compare_op0, sparc_compare_op1);
3896 rtx cc_reg = gen_compare_reg (code,
3897 sparc_compare_op0, sparc_compare_op1);
3898 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3902 (define_expand "movhicc"
3903 [(set (match_operand:HI 0 "register_operand" "")
3904 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3905 (match_operand:HI 2 "arith10_operand" "")
3906 (match_operand:HI 3 "arith10_operand" "")))]
3910 enum rtx_code code = GET_CODE (operands[1]);
3912 if (GET_MODE (sparc_compare_op0) == DImode
3916 if (sparc_compare_op1 == const0_rtx
3917 && GET_CODE (sparc_compare_op0) == REG
3918 && GET_MODE (sparc_compare_op0) == DImode
3919 && v9_regcmp_p (code))
3921 operands[1] = gen_rtx_fmt_ee (code, DImode,
3922 sparc_compare_op0, sparc_compare_op1);
3926 rtx cc_reg = gen_compare_reg (code,
3927 sparc_compare_op0, sparc_compare_op1);
3928 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3932 (define_expand "movsicc"
3933 [(set (match_operand:SI 0 "register_operand" "")
3934 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3935 (match_operand:SI 2 "arith10_operand" "")
3936 (match_operand:SI 3 "arith10_operand" "")))]
3940 enum rtx_code code = GET_CODE (operands[1]);
3941 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3943 if (sparc_compare_op1 == const0_rtx
3944 && GET_CODE (sparc_compare_op0) == REG
3945 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3947 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3948 sparc_compare_op0, sparc_compare_op1);
3952 rtx cc_reg = gen_compare_reg (code,
3953 sparc_compare_op0, sparc_compare_op1);
3954 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3955 cc_reg, const0_rtx);
3959 (define_expand "movdicc"
3960 [(set (match_operand:DI 0 "register_operand" "")
3961 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3962 (match_operand:DI 2 "arith10_double_operand" "")
3963 (match_operand:DI 3 "arith10_double_operand" "")))]
3967 enum rtx_code code = GET_CODE (operands[1]);
3969 if (sparc_compare_op1 == const0_rtx
3970 && GET_CODE (sparc_compare_op0) == REG
3971 && GET_MODE (sparc_compare_op0) == DImode
3972 && v9_regcmp_p (code))
3974 operands[1] = gen_rtx_fmt_ee (code, DImode,
3975 sparc_compare_op0, sparc_compare_op1);
3979 rtx cc_reg = gen_compare_reg (code,
3980 sparc_compare_op0, sparc_compare_op1);
3981 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3982 cc_reg, const0_rtx);
3986 (define_expand "movsfcc"
3987 [(set (match_operand:SF 0 "register_operand" "")
3988 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3989 (match_operand:SF 2 "register_operand" "")
3990 (match_operand:SF 3 "register_operand" "")))]
3991 "TARGET_V9 && TARGET_FPU"
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 "movdfcc"
4017 [(set (match_operand:DF 0 "register_operand" "")
4018 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4019 (match_operand:DF 2 "register_operand" "")
4020 (match_operand:DF 3 "register_operand" "")))]
4021 "TARGET_V9 && TARGET_FPU"
4024 enum rtx_code code = GET_CODE (operands[1]);
4026 if (GET_MODE (sparc_compare_op0) == DImode
4030 if (sparc_compare_op1 == const0_rtx
4031 && GET_CODE (sparc_compare_op0) == REG
4032 && GET_MODE (sparc_compare_op0) == DImode
4033 && v9_regcmp_p (code))
4035 operands[1] = gen_rtx_fmt_ee (code, DImode,
4036 sparc_compare_op0, sparc_compare_op1);
4040 rtx cc_reg = gen_compare_reg (code,
4041 sparc_compare_op0, sparc_compare_op1);
4042 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4046 (define_expand "movtfcc"
4047 [(set (match_operand:TF 0 "register_operand" "")
4048 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4049 (match_operand:TF 2 "register_operand" "")
4050 (match_operand:TF 3 "register_operand" "")))]
4051 "TARGET_V9 && TARGET_FPU"
4054 enum rtx_code code = GET_CODE (operands[1]);
4056 if (GET_MODE (sparc_compare_op0) == DImode
4060 if (sparc_compare_op1 == const0_rtx
4061 && GET_CODE (sparc_compare_op0) == REG
4062 && GET_MODE (sparc_compare_op0) == DImode
4063 && v9_regcmp_p (code))
4065 operands[1] = gen_rtx_fmt_ee (code, DImode,
4066 sparc_compare_op0, sparc_compare_op1);
4070 rtx cc_reg = gen_compare_reg (code,
4071 sparc_compare_op0, sparc_compare_op1);
4072 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4076 ;; Conditional move define_insns.
4078 (define_insn "*movqi_cc_sp64"
4079 [(set (match_operand:QI 0 "register_operand" "=r,r")
4080 (if_then_else:QI (match_operator 1 "comparison_operator"
4081 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4083 (match_operand:QI 3 "arith11_operand" "rL,0")
4084 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4087 mov%C1\\t%x2, %3, %0
4088 mov%c1\\t%x2, %4, %0"
4089 [(set_attr "type" "cmove")])
4091 (define_insn "*movhi_cc_sp64"
4092 [(set (match_operand:HI 0 "register_operand" "=r,r")
4093 (if_then_else:HI (match_operator 1 "comparison_operator"
4094 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4096 (match_operand:HI 3 "arith11_operand" "rL,0")
4097 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4100 mov%C1\\t%x2, %3, %0
4101 mov%c1\\t%x2, %4, %0"
4102 [(set_attr "type" "cmove")])
4104 (define_insn "*movsi_cc_sp64"
4105 [(set (match_operand:SI 0 "register_operand" "=r,r")
4106 (if_then_else:SI (match_operator 1 "comparison_operator"
4107 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4109 (match_operand:SI 3 "arith11_operand" "rL,0")
4110 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4113 mov%C1\\t%x2, %3, %0
4114 mov%c1\\t%x2, %4, %0"
4115 [(set_attr "type" "cmove")])
4117 ;; ??? The constraints of operands 3,4 need work.
4118 (define_insn "*movdi_cc_sp64"
4119 [(set (match_operand:DI 0 "register_operand" "=r,r")
4120 (if_then_else:DI (match_operator 1 "comparison_operator"
4121 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4123 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4124 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4127 mov%C1\\t%x2, %3, %0
4128 mov%c1\\t%x2, %4, %0"
4129 [(set_attr "type" "cmove")])
4131 (define_insn "*movdi_cc_sp64_trunc"
4132 [(set (match_operand:SI 0 "register_operand" "=r,r")
4133 (if_then_else:SI (match_operator 1 "comparison_operator"
4134 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4136 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4137 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4140 mov%C1\\t%x2, %3, %0
4141 mov%c1\\t%x2, %4, %0"
4142 [(set_attr "type" "cmove")])
4144 (define_insn "*movsf_cc_sp64"
4145 [(set (match_operand:SF 0 "register_operand" "=f,f")
4146 (if_then_else:SF (match_operator 1 "comparison_operator"
4147 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4149 (match_operand:SF 3 "register_operand" "f,0")
4150 (match_operand:SF 4 "register_operand" "0,f")))]
4151 "TARGET_V9 && TARGET_FPU"
4153 fmovs%C1\\t%x2, %3, %0
4154 fmovs%c1\\t%x2, %4, %0"
4155 [(set_attr "type" "fpcmove")])
4157 (define_insn "movdf_cc_sp64"
4158 [(set (match_operand:DF 0 "register_operand" "=e,e")
4159 (if_then_else:DF (match_operator 1 "comparison_operator"
4160 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4162 (match_operand:DF 3 "register_operand" "e,0")
4163 (match_operand:DF 4 "register_operand" "0,e")))]
4164 "TARGET_V9 && TARGET_FPU"
4166 fmovd%C1\\t%x2, %3, %0
4167 fmovd%c1\\t%x2, %4, %0"
4168 [(set_attr "type" "fpcmove")
4169 (set_attr "fptype" "double")])
4171 (define_insn "*movtf_cc_hq_sp64"
4172 [(set (match_operand:TF 0 "register_operand" "=e,e")
4173 (if_then_else:TF (match_operator 1 "comparison_operator"
4174 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4176 (match_operand:TF 3 "register_operand" "e,0")
4177 (match_operand:TF 4 "register_operand" "0,e")))]
4178 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4180 fmovq%C1\\t%x2, %3, %0
4181 fmovq%c1\\t%x2, %4, %0"
4182 [(set_attr "type" "fpcmove")])
4184 (define_insn "*movtf_cc_sp64"
4185 [(set (match_operand:TF 0 "register_operand" "=e,e")
4186 (if_then_else:TF (match_operator 1 "comparison_operator"
4187 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4189 (match_operand:TF 3 "register_operand" "e,0")
4190 (match_operand:TF 4 "register_operand" "0,e")))]
4191 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4193 [(set_attr "length" "2")])
4196 [(set (match_operand:TF 0 "register_operand" "")
4197 (if_then_else:TF (match_operator 1 "comparison_operator"
4198 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4200 (match_operand:TF 3 "register_operand" "")
4201 (match_operand:TF 4 "register_operand" "")))]
4202 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4203 [(clobber (const_int 0))]
4206 rtx set_dest = operands[0];
4207 rtx set_srca = operands[3];
4208 rtx set_srcb = operands[4];
4209 int third = rtx_equal_p (set_dest, set_srca);
4211 rtx srca1, srca2, srcb1, srcb2;
4213 dest1 = gen_df_reg (set_dest, 0);
4214 dest2 = gen_df_reg (set_dest, 1);
4215 srca1 = gen_df_reg (set_srca, 0);
4216 srca2 = gen_df_reg (set_srca, 1);
4217 srcb1 = gen_df_reg (set_srcb, 0);
4218 srcb2 = gen_df_reg (set_srcb, 1);
4220 /* Now emit using the real source and destination we found, swapping
4221 the order if we detect overlap. */
4222 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4223 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4225 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4226 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4230 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4231 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4236 (define_insn "*movqi_cc_reg_sp64"
4237 [(set (match_operand:QI 0 "register_operand" "=r,r")
4238 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4239 [(match_operand:DI 2 "register_operand" "r,r")
4241 (match_operand:QI 3 "arith10_operand" "rM,0")
4242 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4245 movr%D1\\t%2, %r3, %0
4246 movr%d1\\t%2, %r4, %0"
4247 [(set_attr "type" "cmove")])
4249 (define_insn "*movhi_cc_reg_sp64"
4250 [(set (match_operand:HI 0 "register_operand" "=r,r")
4251 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4252 [(match_operand:DI 2 "register_operand" "r,r")
4254 (match_operand:HI 3 "arith10_operand" "rM,0")
4255 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4258 movr%D1\\t%2, %r3, %0
4259 movr%d1\\t%2, %r4, %0"
4260 [(set_attr "type" "cmove")])
4262 (define_insn "*movsi_cc_reg_sp64"
4263 [(set (match_operand:SI 0 "register_operand" "=r,r")
4264 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4265 [(match_operand:DI 2 "register_operand" "r,r")
4267 (match_operand:SI 3 "arith10_operand" "rM,0")
4268 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4271 movr%D1\\t%2, %r3, %0
4272 movr%d1\\t%2, %r4, %0"
4273 [(set_attr "type" "cmove")])
4275 ;; ??? The constraints of operands 3,4 need work.
4276 (define_insn "*movdi_cc_reg_sp64"
4277 [(set (match_operand:DI 0 "register_operand" "=r,r")
4278 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4279 [(match_operand:DI 2 "register_operand" "r,r")
4281 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4282 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4285 movr%D1\\t%2, %r3, %0
4286 movr%d1\\t%2, %r4, %0"
4287 [(set_attr "type" "cmove")])
4289 (define_insn "*movdi_cc_reg_sp64_trunc"
4290 [(set (match_operand:SI 0 "register_operand" "=r,r")
4291 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4292 [(match_operand:DI 2 "register_operand" "r,r")
4294 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4295 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4298 movr%D1\\t%2, %r3, %0
4299 movr%d1\\t%2, %r4, %0"
4300 [(set_attr "type" "cmove")])
4302 (define_insn "*movsf_cc_reg_sp64"
4303 [(set (match_operand:SF 0 "register_operand" "=f,f")
4304 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4305 [(match_operand:DI 2 "register_operand" "r,r")
4307 (match_operand:SF 3 "register_operand" "f,0")
4308 (match_operand:SF 4 "register_operand" "0,f")))]
4309 "TARGET_ARCH64 && TARGET_FPU"
4311 fmovrs%D1\\t%2, %3, %0
4312 fmovrs%d1\\t%2, %4, %0"
4313 [(set_attr "type" "fpcmove")])
4315 (define_insn "movdf_cc_reg_sp64"
4316 [(set (match_operand:DF 0 "register_operand" "=e,e")
4317 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4318 [(match_operand:DI 2 "register_operand" "r,r")
4320 (match_operand:DF 3 "register_operand" "e,0")
4321 (match_operand:DF 4 "register_operand" "0,e")))]
4322 "TARGET_ARCH64 && TARGET_FPU"
4324 fmovrd%D1\\t%2, %3, %0
4325 fmovrd%d1\\t%2, %4, %0"
4326 [(set_attr "type" "fpcmove")
4327 (set_attr "fptype" "double")])
4329 (define_insn "*movtf_cc_reg_hq_sp64"
4330 [(set (match_operand:TF 0 "register_operand" "=e,e")
4331 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4332 [(match_operand:DI 2 "register_operand" "r,r")
4334 (match_operand:TF 3 "register_operand" "e,0")
4335 (match_operand:TF 4 "register_operand" "0,e")))]
4336 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4338 fmovrq%D1\\t%2, %3, %0
4339 fmovrq%d1\\t%2, %4, %0"
4340 [(set_attr "type" "fpcmove")])
4342 (define_insn "*movtf_cc_reg_sp64"
4343 [(set (match_operand:TF 0 "register_operand" "=e,e")
4344 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4345 [(match_operand:DI 2 "register_operand" "r,r")
4347 (match_operand:TF 3 "register_operand" "e,0")
4348 (match_operand:TF 4 "register_operand" "0,e")))]
4349 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4351 [(set_attr "length" "2")])
4354 [(set (match_operand:TF 0 "register_operand" "")
4355 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4356 [(match_operand:DI 2 "register_operand" "")
4358 (match_operand:TF 3 "register_operand" "")
4359 (match_operand:TF 4 "register_operand" "")))]
4360 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4361 [(clobber (const_int 0))]
4364 rtx set_dest = operands[0];
4365 rtx set_srca = operands[3];
4366 rtx set_srcb = operands[4];
4367 int third = rtx_equal_p (set_dest, set_srca);
4369 rtx srca1, srca2, srcb1, srcb2;
4371 dest1 = gen_df_reg (set_dest, 0);
4372 dest2 = gen_df_reg (set_dest, 1);
4373 srca1 = gen_df_reg (set_srca, 0);
4374 srca2 = gen_df_reg (set_srca, 1);
4375 srcb1 = gen_df_reg (set_srcb, 0);
4376 srcb2 = gen_df_reg (set_srcb, 1);
4378 /* Now emit using the real source and destination we found, swapping
4379 the order if we detect overlap. */
4380 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4381 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4383 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4384 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4388 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4389 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4395 ;;- zero extension instructions
4397 ;; These patterns originally accepted general_operands, however, slightly
4398 ;; better code is generated by only accepting register_operands, and then
4399 ;; letting combine generate the ldu[hb] insns.
4401 (define_expand "zero_extendhisi2"
4402 [(set (match_operand:SI 0 "register_operand" "")
4403 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4407 rtx temp = gen_reg_rtx (SImode);
4408 rtx shift_16 = GEN_INT (16);
4409 int op1_subbyte = 0;
4411 if (GET_CODE (operand1) == SUBREG)
4413 op1_subbyte = SUBREG_BYTE (operand1);
4414 op1_subbyte /= GET_MODE_SIZE (SImode);
4415 op1_subbyte *= GET_MODE_SIZE (SImode);
4416 operand1 = XEXP (operand1, 0);
4419 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4421 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4425 (define_insn "*zero_extendhisi2_insn"
4426 [(set (match_operand:SI 0 "register_operand" "=r")
4427 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4430 [(set_attr "type" "load")])
4432 (define_expand "zero_extendqihi2"
4433 [(set (match_operand:HI 0 "register_operand" "")
4434 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4438 (define_insn "*zero_extendqihi2_insn"
4439 [(set (match_operand:HI 0 "register_operand" "=r,r")
4440 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4441 "GET_CODE (operands[1]) != CONST_INT"
4445 [(set_attr "type" "*,load")])
4447 (define_expand "zero_extendqisi2"
4448 [(set (match_operand:SI 0 "register_operand" "")
4449 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4453 (define_insn "*zero_extendqisi2_insn"
4454 [(set (match_operand:SI 0 "register_operand" "=r,r")
4455 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4456 "GET_CODE (operands[1]) != CONST_INT"
4460 [(set_attr "type" "*,load")])
4462 (define_expand "zero_extendqidi2"
4463 [(set (match_operand:DI 0 "register_operand" "")
4464 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4468 (define_insn "*zero_extendqidi2_insn"
4469 [(set (match_operand:DI 0 "register_operand" "=r,r")
4470 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4471 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4475 [(set_attr "type" "*,load")])
4477 (define_expand "zero_extendhidi2"
4478 [(set (match_operand:DI 0 "register_operand" "")
4479 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4483 rtx temp = gen_reg_rtx (DImode);
4484 rtx shift_48 = GEN_INT (48);
4485 int op1_subbyte = 0;
4487 if (GET_CODE (operand1) == SUBREG)
4489 op1_subbyte = SUBREG_BYTE (operand1);
4490 op1_subbyte /= GET_MODE_SIZE (DImode);
4491 op1_subbyte *= GET_MODE_SIZE (DImode);
4492 operand1 = XEXP (operand1, 0);
4495 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4497 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4501 (define_insn "*zero_extendhidi2_insn"
4502 [(set (match_operand:DI 0 "register_operand" "=r")
4503 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4506 [(set_attr "type" "load")])
4509 ;; ??? Write truncdisi pattern using sra?
4511 (define_expand "zero_extendsidi2"
4512 [(set (match_operand:DI 0 "register_operand" "")
4513 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4517 (define_insn "*zero_extendsidi2_insn_sp64"
4518 [(set (match_operand:DI 0 "register_operand" "=r,r")
4519 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4520 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4524 [(set_attr "type" "shift,load")])
4526 (define_insn "*zero_extendsidi2_insn_sp32"
4527 [(set (match_operand:DI 0 "register_operand" "=r")
4528 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4531 [(set_attr "length" "2")])
4534 [(set (match_operand:DI 0 "register_operand" "")
4535 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4536 "! TARGET_ARCH64 && reload_completed"
4537 [(set (match_dup 2) (match_dup 3))
4538 (set (match_dup 4) (match_dup 5))]
4543 dest1 = gen_highpart (SImode, operands[0]);
4544 dest2 = gen_lowpart (SImode, operands[0]);
4546 /* Swap the order in case of overlap. */
4547 if (REGNO (dest1) == REGNO (operands[1]))
4549 operands[2] = dest2;
4550 operands[3] = operands[1];
4551 operands[4] = dest1;
4552 operands[5] = const0_rtx;
4556 operands[2] = dest1;
4557 operands[3] = const0_rtx;
4558 operands[4] = dest2;
4559 operands[5] = operands[1];
4563 ;; Simplify comparisons of extended values.
4565 (define_insn "*cmp_zero_extendqisi2"
4567 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4570 "andcc\\t%0, 0xff, %%g0"
4571 [(set_attr "type" "compare")])
4573 (define_insn "*cmp_zero_qi"
4575 (compare:CC (match_operand:QI 0 "register_operand" "r")
4578 "andcc\\t%0, 0xff, %%g0"
4579 [(set_attr "type" "compare")])
4581 (define_insn "*cmp_zero_extendqisi2_set"
4583 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4585 (set (match_operand:SI 0 "register_operand" "=r")
4586 (zero_extend:SI (match_dup 1)))]
4588 "andcc\\t%1, 0xff, %0"
4589 [(set_attr "type" "compare")])
4591 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4593 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4596 (set (match_operand:SI 0 "register_operand" "=r")
4597 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4599 "andcc\\t%1, 0xff, %0"
4600 [(set_attr "type" "compare")])
4602 (define_insn "*cmp_zero_extendqidi2"
4604 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4607 "andcc\\t%0, 0xff, %%g0"
4608 [(set_attr "type" "compare")])
4610 (define_insn "*cmp_zero_qi_sp64"
4612 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4615 "andcc\\t%0, 0xff, %%g0"
4616 [(set_attr "type" "compare")])
4618 (define_insn "*cmp_zero_extendqidi2_set"
4620 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4622 (set (match_operand:DI 0 "register_operand" "=r")
4623 (zero_extend:DI (match_dup 1)))]
4625 "andcc\\t%1, 0xff, %0"
4626 [(set_attr "type" "compare")])
4628 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4630 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4633 (set (match_operand:DI 0 "register_operand" "=r")
4634 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4636 "andcc\\t%1, 0xff, %0"
4637 [(set_attr "type" "compare")])
4639 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4641 (define_insn "*cmp_siqi_trunc"
4643 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4646 "andcc\\t%0, 0xff, %%g0"
4647 [(set_attr "type" "compare")])
4649 (define_insn "*cmp_siqi_trunc_set"
4651 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4653 (set (match_operand:QI 0 "register_operand" "=r")
4654 (subreg:QI (match_dup 1) 3))]
4656 "andcc\\t%1, 0xff, %0"
4657 [(set_attr "type" "compare")])
4659 (define_insn "*cmp_diqi_trunc"
4661 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4664 "andcc\\t%0, 0xff, %%g0"
4665 [(set_attr "type" "compare")])
4667 (define_insn "*cmp_diqi_trunc_set"
4669 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4671 (set (match_operand:QI 0 "register_operand" "=r")
4672 (subreg:QI (match_dup 1) 7))]
4674 "andcc\\t%1, 0xff, %0"
4675 [(set_attr "type" "compare")])
4677 ;;- sign extension instructions
4679 ;; These patterns originally accepted general_operands, however, slightly
4680 ;; better code is generated by only accepting register_operands, and then
4681 ;; letting combine generate the lds[hb] insns.
4683 (define_expand "extendhisi2"
4684 [(set (match_operand:SI 0 "register_operand" "")
4685 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4689 rtx temp = gen_reg_rtx (SImode);
4690 rtx shift_16 = GEN_INT (16);
4691 int op1_subbyte = 0;
4693 if (GET_CODE (operand1) == SUBREG)
4695 op1_subbyte = SUBREG_BYTE (operand1);
4696 op1_subbyte /= GET_MODE_SIZE (SImode);
4697 op1_subbyte *= GET_MODE_SIZE (SImode);
4698 operand1 = XEXP (operand1, 0);
4701 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4703 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4707 (define_insn "*sign_extendhisi2_insn"
4708 [(set (match_operand:SI 0 "register_operand" "=r")
4709 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4712 [(set_attr "type" "sload")])
4714 (define_expand "extendqihi2"
4715 [(set (match_operand:HI 0 "register_operand" "")
4716 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4720 rtx temp = gen_reg_rtx (SImode);
4721 rtx shift_24 = GEN_INT (24);
4722 int op1_subbyte = 0;
4723 int op0_subbyte = 0;
4725 if (GET_CODE (operand1) == SUBREG)
4727 op1_subbyte = SUBREG_BYTE (operand1);
4728 op1_subbyte /= GET_MODE_SIZE (SImode);
4729 op1_subbyte *= GET_MODE_SIZE (SImode);
4730 operand1 = XEXP (operand1, 0);
4732 if (GET_CODE (operand0) == SUBREG)
4734 op0_subbyte = SUBREG_BYTE (operand0);
4735 op0_subbyte /= GET_MODE_SIZE (SImode);
4736 op0_subbyte *= GET_MODE_SIZE (SImode);
4737 operand0 = XEXP (operand0, 0);
4739 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4741 if (GET_MODE (operand0) != SImode)
4742 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4743 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4747 (define_insn "*sign_extendqihi2_insn"
4748 [(set (match_operand:HI 0 "register_operand" "=r")
4749 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4752 [(set_attr "type" "sload")])
4754 (define_expand "extendqisi2"
4755 [(set (match_operand:SI 0 "register_operand" "")
4756 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4760 rtx temp = gen_reg_rtx (SImode);
4761 rtx shift_24 = GEN_INT (24);
4762 int op1_subbyte = 0;
4764 if (GET_CODE (operand1) == SUBREG)
4766 op1_subbyte = SUBREG_BYTE (operand1);
4767 op1_subbyte /= GET_MODE_SIZE (SImode);
4768 op1_subbyte *= GET_MODE_SIZE (SImode);
4769 operand1 = XEXP (operand1, 0);
4772 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4774 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4778 (define_insn "*sign_extendqisi2_insn"
4779 [(set (match_operand:SI 0 "register_operand" "=r")
4780 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4783 [(set_attr "type" "sload")])
4785 (define_expand "extendqidi2"
4786 [(set (match_operand:DI 0 "register_operand" "")
4787 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4791 rtx temp = gen_reg_rtx (DImode);
4792 rtx shift_56 = GEN_INT (56);
4793 int op1_subbyte = 0;
4795 if (GET_CODE (operand1) == SUBREG)
4797 op1_subbyte = SUBREG_BYTE (operand1);
4798 op1_subbyte /= GET_MODE_SIZE (DImode);
4799 op1_subbyte *= GET_MODE_SIZE (DImode);
4800 operand1 = XEXP (operand1, 0);
4803 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4805 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4809 (define_insn "*sign_extendqidi2_insn"
4810 [(set (match_operand:DI 0 "register_operand" "=r")
4811 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4814 [(set_attr "type" "sload")])
4816 (define_expand "extendhidi2"
4817 [(set (match_operand:DI 0 "register_operand" "")
4818 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4822 rtx temp = gen_reg_rtx (DImode);
4823 rtx shift_48 = GEN_INT (48);
4824 int op1_subbyte = 0;
4826 if (GET_CODE (operand1) == SUBREG)
4828 op1_subbyte = SUBREG_BYTE (operand1);
4829 op1_subbyte /= GET_MODE_SIZE (DImode);
4830 op1_subbyte *= GET_MODE_SIZE (DImode);
4831 operand1 = XEXP (operand1, 0);
4834 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4836 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4840 (define_insn "*sign_extendhidi2_insn"
4841 [(set (match_operand:DI 0 "register_operand" "=r")
4842 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4845 [(set_attr "type" "sload")])
4847 (define_expand "extendsidi2"
4848 [(set (match_operand:DI 0 "register_operand" "")
4849 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4853 (define_insn "*sign_extendsidi2_insn"
4854 [(set (match_operand:DI 0 "register_operand" "=r,r")
4855 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4860 [(set_attr "type" "shift,sload")])
4862 ;; Special pattern for optimizing bit-field compares. This is needed
4863 ;; because combine uses this as a canonical form.
4865 (define_insn "*cmp_zero_extract"
4868 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4869 (match_operand:SI 1 "small_int_or_double" "n")
4870 (match_operand:SI 2 "small_int_or_double" "n"))
4872 "(GET_CODE (operands[2]) == CONST_INT
4873 && INTVAL (operands[2]) > 19)
4874 || (GET_CODE (operands[2]) == CONST_DOUBLE
4875 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4878 int len = (GET_CODE (operands[1]) == CONST_INT
4879 ? INTVAL (operands[1])
4880 : CONST_DOUBLE_LOW (operands[1]));
4882 (GET_CODE (operands[2]) == CONST_INT
4883 ? INTVAL (operands[2])
4884 : CONST_DOUBLE_LOW (operands[2])) - len;
4885 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4887 operands[1] = GEN_INT (mask);
4888 return \"andcc\\t%0, %1, %%g0\";
4890 [(set_attr "type" "compare")])
4892 (define_insn "*cmp_zero_extract_sp64"
4895 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4896 (match_operand:SI 1 "small_int_or_double" "n")
4897 (match_operand:SI 2 "small_int_or_double" "n"))
4900 && ((GET_CODE (operands[2]) == CONST_INT
4901 && INTVAL (operands[2]) > 51)
4902 || (GET_CODE (operands[2]) == CONST_DOUBLE
4903 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4906 int len = (GET_CODE (operands[1]) == CONST_INT
4907 ? INTVAL (operands[1])
4908 : CONST_DOUBLE_LOW (operands[1]));
4910 (GET_CODE (operands[2]) == CONST_INT
4911 ? INTVAL (operands[2])
4912 : CONST_DOUBLE_LOW (operands[2])) - len;
4913 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4915 operands[1] = GEN_INT (mask);
4916 return \"andcc\\t%0, %1, %%g0\";
4918 [(set_attr "type" "compare")])
4920 ;; Conversions between float, double and long double.
4922 (define_insn "extendsfdf2"
4923 [(set (match_operand:DF 0 "register_operand" "=e")
4925 (match_operand:SF 1 "register_operand" "f")))]
4928 [(set_attr "type" "fp")
4929 (set_attr "fptype" "double")])
4931 (define_expand "extendsftf2"
4932 [(set (match_operand:TF 0 "register_operand" "=e")
4934 (match_operand:SF 1 "register_operand" "f")))]
4935 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4938 if (! TARGET_HARD_QUAD)
4942 if (GET_CODE (operands[0]) != MEM)
4943 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4945 slot0 = operands[0];
4947 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4949 XEXP (slot0, 0), Pmode,
4950 operands[1], SFmode);
4952 if (GET_CODE (operands[0]) != MEM)
4953 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4958 (define_insn "*extendsftf2_hq"
4959 [(set (match_operand:TF 0 "register_operand" "=e")
4961 (match_operand:SF 1 "register_operand" "f")))]
4962 "TARGET_FPU && TARGET_HARD_QUAD"
4964 [(set_attr "type" "fp")])
4966 (define_expand "extenddftf2"
4967 [(set (match_operand:TF 0 "register_operand" "=e")
4969 (match_operand:DF 1 "register_operand" "e")))]
4970 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4973 if (! TARGET_HARD_QUAD)
4977 if (GET_CODE (operands[0]) != MEM)
4978 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4980 slot0 = operands[0];
4982 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
4984 XEXP (slot0, 0), Pmode,
4985 operands[1], DFmode);
4987 if (GET_CODE (operands[0]) != MEM)
4988 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4993 (define_insn "*extenddftf2_hq"
4994 [(set (match_operand:TF 0 "register_operand" "=e")
4996 (match_operand:DF 1 "register_operand" "e")))]
4997 "TARGET_FPU && TARGET_HARD_QUAD"
4999 [(set_attr "type" "fp")])
5001 (define_insn "truncdfsf2"
5002 [(set (match_operand:SF 0 "register_operand" "=f")
5004 (match_operand:DF 1 "register_operand" "e")))]
5007 [(set_attr "type" "fp")
5008 (set_attr "fptype" "double")])
5010 (define_expand "trunctfsf2"
5011 [(set (match_operand:SF 0 "register_operand" "=f")
5013 (match_operand:TF 1 "register_operand" "e")))]
5014 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5017 if (! TARGET_HARD_QUAD)
5021 if (GET_CODE (operands[1]) != MEM)
5023 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5024 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5027 slot0 = operands[1];
5029 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5030 operands[0], 0, SFmode, 1,
5031 XEXP (slot0, 0), Pmode);
5036 (define_insn "*trunctfsf2_hq"
5037 [(set (match_operand:SF 0 "register_operand" "=f")
5039 (match_operand:TF 1 "register_operand" "e")))]
5040 "TARGET_FPU && TARGET_HARD_QUAD"
5042 [(set_attr "type" "fp")])
5044 (define_expand "trunctfdf2"
5045 [(set (match_operand:DF 0 "register_operand" "=f")
5047 (match_operand:TF 1 "register_operand" "e")))]
5048 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5051 if (! TARGET_HARD_QUAD)
5055 if (GET_CODE (operands[1]) != MEM)
5057 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5058 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5061 slot0 = operands[1];
5063 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5064 operands[0], 0, DFmode, 1,
5065 XEXP (slot0, 0), Pmode);
5070 (define_insn "*trunctfdf2_hq"
5071 [(set (match_operand:DF 0 "register_operand" "=e")
5073 (match_operand:TF 1 "register_operand" "e")))]
5074 "TARGET_FPU && TARGET_HARD_QUAD"
5076 [(set_attr "type" "fp")])
5078 ;; Conversion between fixed point and floating point.
5080 (define_insn "floatsisf2"
5081 [(set (match_operand:SF 0 "register_operand" "=f")
5082 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5085 [(set_attr "type" "fp")
5086 (set_attr "fptype" "double")])
5088 (define_insn "floatsidf2"
5089 [(set (match_operand:DF 0 "register_operand" "=e")
5090 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5093 [(set_attr "type" "fp")
5094 (set_attr "fptype" "double")])
5096 (define_expand "floatsitf2"
5097 [(set (match_operand:TF 0 "register_operand" "=e")
5098 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5099 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5102 if (! TARGET_HARD_QUAD)
5106 if (GET_CODE (operands[1]) != MEM)
5107 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5109 slot0 = operands[1];
5111 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5113 XEXP (slot0, 0), Pmode,
5114 operands[1], SImode);
5116 if (GET_CODE (operands[0]) != MEM)
5117 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5122 (define_insn "*floatsitf2_hq"
5123 [(set (match_operand:TF 0 "register_operand" "=e")
5124 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5125 "TARGET_FPU && TARGET_HARD_QUAD"
5127 [(set_attr "type" "fp")])
5129 (define_expand "floatunssitf2"
5130 [(set (match_operand:TF 0 "register_operand" "=e")
5131 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5132 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5137 if (GET_CODE (operands[1]) != MEM)
5138 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5140 slot0 = operands[1];
5142 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5144 XEXP (slot0, 0), Pmode,
5145 operands[1], SImode);
5147 if (GET_CODE (operands[0]) != MEM)
5148 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5152 ;; Now the same for 64 bit sources.
5154 (define_insn "floatdisf2"
5155 [(set (match_operand:SF 0 "register_operand" "=f")
5156 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5157 "TARGET_V9 && TARGET_FPU"
5159 [(set_attr "type" "fp")
5160 (set_attr "fptype" "double")])
5162 (define_insn "floatdidf2"
5163 [(set (match_operand:DF 0 "register_operand" "=e")
5164 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5165 "TARGET_V9 && TARGET_FPU"
5167 [(set_attr "type" "fp")
5168 (set_attr "fptype" "double")])
5170 (define_expand "floatditf2"
5171 [(set (match_operand:TF 0 "register_operand" "=e")
5172 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5173 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5176 if (! TARGET_HARD_QUAD)
5180 if (GET_CODE (operands[1]) != MEM)
5181 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5183 slot0 = operands[1];
5185 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5187 XEXP (slot0, 0), Pmode,
5188 operands[1], DImode);
5190 if (GET_CODE (operands[0]) != MEM)
5191 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5196 (define_insn "*floatditf2_hq"
5197 [(set (match_operand:TF 0 "register_operand" "=e")
5198 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5199 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5201 [(set_attr "type" "fp")])
5203 (define_expand "floatunsditf2"
5204 [(set (match_operand:TF 0 "register_operand" "=e")
5205 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5206 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5211 if (GET_CODE (operands[1]) != MEM)
5212 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5214 slot0 = operands[1];
5216 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5218 XEXP (slot0, 0), Pmode,
5219 operands[1], DImode);
5221 if (GET_CODE (operands[0]) != MEM)
5222 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5226 ;; Convert a float to an actual integer.
5227 ;; Truncation is performed as part of the conversion.
5229 (define_insn "fix_truncsfsi2"
5230 [(set (match_operand:SI 0 "register_operand" "=f")
5231 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5234 [(set_attr "type" "fp")
5235 (set_attr "fptype" "double")])
5237 (define_insn "fix_truncdfsi2"
5238 [(set (match_operand:SI 0 "register_operand" "=f")
5239 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5242 [(set_attr "type" "fp")
5243 (set_attr "fptype" "double")])
5245 (define_expand "fix_trunctfsi2"
5246 [(set (match_operand:SI 0 "register_operand" "=f")
5247 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5248 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5251 if (! TARGET_HARD_QUAD)
5255 if (GET_CODE (operands[1]) != MEM)
5257 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5258 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5261 slot0 = operands[1];
5263 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5264 operands[0], 0, SImode, 1,
5265 XEXP (slot0, 0), Pmode);
5270 (define_insn "*fix_trunctfsi2_hq"
5271 [(set (match_operand:SI 0 "register_operand" "=f")
5272 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5273 "TARGET_FPU && TARGET_HARD_QUAD"
5275 [(set_attr "type" "fp")])
5277 (define_expand "fixuns_trunctfsi2"
5278 [(set (match_operand:SI 0 "register_operand" "=f")
5279 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5280 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5285 if (GET_CODE (operands[1]) != MEM)
5287 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5288 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5291 slot0 = operands[1];
5293 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5294 operands[0], 0, SImode, 1,
5295 XEXP (slot0, 0), Pmode);
5299 ;; Now the same, for V9 targets
5301 (define_insn "fix_truncsfdi2"
5302 [(set (match_operand:DI 0 "register_operand" "=e")
5303 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5304 "TARGET_V9 && TARGET_FPU"
5306 [(set_attr "type" "fp")
5307 (set_attr "fptype" "double")])
5309 (define_insn "fix_truncdfdi2"
5310 [(set (match_operand:DI 0 "register_operand" "=e")
5311 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5312 "TARGET_V9 && TARGET_FPU"
5314 [(set_attr "type" "fp")
5315 (set_attr "fptype" "double")])
5317 (define_expand "fix_trunctfdi2"
5318 [(set (match_operand:DI 0 "register_operand" "=e")
5319 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5320 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5323 if (! TARGET_HARD_QUAD)
5327 if (GET_CODE (operands[1]) != MEM)
5329 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5330 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5333 slot0 = operands[1];
5335 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5336 operands[0], 0, DImode, 1,
5337 XEXP (slot0, 0), Pmode);
5342 (define_insn "*fix_trunctfdi2_hq"
5343 [(set (match_operand:DI 0 "register_operand" "=e")
5344 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5345 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5347 [(set_attr "type" "fp")])
5349 (define_expand "fixuns_trunctfdi2"
5350 [(set (match_operand:DI 0 "register_operand" "=f")
5351 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5352 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5357 if (GET_CODE (operands[1]) != MEM)
5359 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5360 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5363 slot0 = operands[1];
5365 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5366 operands[0], 0, DImode, 1,
5367 XEXP (slot0, 0), Pmode);
5372 ;;- arithmetic instructions
5374 (define_expand "adddi3"
5375 [(set (match_operand:DI 0 "register_operand" "=r")
5376 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5377 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5383 if (! TARGET_ARCH64)
5385 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5386 gen_rtx_SET (VOIDmode, operands[0],
5387 gen_rtx_PLUS (DImode, operands[1],
5389 gen_rtx_CLOBBER (VOIDmode,
5390 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5393 if (arith_double_4096_operand(operands[2], DImode))
5395 switch (GET_CODE (operands[1]))
5397 case CONST_INT: i = INTVAL (operands[1]); break;
5398 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5400 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5401 gen_rtx_MINUS (DImode, operands[1],
5405 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5410 (define_insn "adddi3_insn_sp32"
5411 [(set (match_operand:DI 0 "register_operand" "=r")
5412 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5413 (match_operand:DI 2 "arith_double_operand" "rHI")))
5414 (clobber (reg:CC 100))]
5417 [(set_attr "length" "2")])
5420 [(set (match_operand:DI 0 "register_operand" "")
5421 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5422 (match_operand:DI 2 "arith_double_operand" "")))
5423 (clobber (reg:CC 100))]
5424 "! TARGET_ARCH64 && reload_completed"
5425 [(parallel [(set (reg:CC_NOOV 100)
5426 (compare:CC_NOOV (plus:SI (match_dup 4)
5430 (plus:SI (match_dup 4) (match_dup 5)))])
5432 (plus:SI (plus:SI (match_dup 7)
5434 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5437 operands[3] = gen_lowpart (SImode, operands[0]);
5438 operands[4] = gen_lowpart (SImode, operands[1]);
5439 operands[5] = gen_lowpart (SImode, operands[2]);
5440 operands[6] = gen_highpart (SImode, operands[0]);
5441 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5442 #if HOST_BITS_PER_WIDE_INT == 32
5443 if (GET_CODE (operands[2]) == CONST_INT)
5445 if (INTVAL (operands[2]) < 0)
5446 operands[8] = constm1_rtx;
5448 operands[8] = const0_rtx;
5452 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5456 [(set (match_operand:DI 0 "register_operand" "")
5457 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5458 (match_operand:DI 2 "arith_double_operand" "")))
5459 (clobber (reg:CC 100))]
5460 "! TARGET_ARCH64 && reload_completed"
5461 [(parallel [(set (reg:CC_NOOV 100)
5462 (compare:CC_NOOV (minus:SI (match_dup 4)
5466 (minus:SI (match_dup 4) (match_dup 5)))])
5468 (minus:SI (minus:SI (match_dup 7)
5470 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5473 operands[3] = gen_lowpart (SImode, operands[0]);
5474 operands[4] = gen_lowpart (SImode, operands[1]);
5475 operands[5] = gen_lowpart (SImode, operands[2]);
5476 operands[6] = gen_highpart (SImode, operands[0]);
5477 operands[7] = gen_highpart (SImode, operands[1]);
5478 #if HOST_BITS_PER_WIDE_INT == 32
5479 if (GET_CODE (operands[2]) == CONST_INT)
5481 if (INTVAL (operands[2]) < 0)
5482 operands[8] = constm1_rtx;
5484 operands[8] = const0_rtx;
5488 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5491 ;; LTU here means "carry set"
5493 [(set (match_operand:SI 0 "register_operand" "=r")
5494 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5495 (match_operand:SI 2 "arith_operand" "rI"))
5496 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5499 [(set_attr "type" "misc")])
5501 (define_insn "*addx_extend_sp32"
5502 [(set (match_operand:DI 0 "register_operand" "=r")
5503 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5504 (match_operand:SI 2 "arith_operand" "rI"))
5505 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5508 [(set_attr "length" "2")])
5511 [(set (match_operand:DI 0 "register_operand" "")
5512 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5513 (match_operand:SI 2 "arith_operand" ""))
5514 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5515 "! TARGET_ARCH64 && reload_completed"
5516 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5517 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5518 (set (match_dup 4) (const_int 0))]
5519 "operands[3] = gen_lowpart (SImode, operands[0]);
5520 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5522 (define_insn "*addx_extend_sp64"
5523 [(set (match_operand:DI 0 "register_operand" "=r")
5524 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5525 (match_operand:SI 2 "arith_operand" "rI"))
5526 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5528 "addx\\t%r1, %2, %0"
5529 [(set_attr "type" "misc")])
5532 [(set (match_operand:SI 0 "register_operand" "=r")
5533 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5534 (match_operand:SI 2 "arith_operand" "rI"))
5535 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5537 "subx\\t%r1, %2, %0"
5538 [(set_attr "type" "misc")])
5540 (define_insn "*subx_extend_sp64"
5541 [(set (match_operand:DI 0 "register_operand" "=r")
5542 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5543 (match_operand:SI 2 "arith_operand" "rI"))
5544 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5546 "subx\\t%r1, %2, %0"
5547 [(set_attr "type" "misc")])
5549 (define_insn "*subx_extend"
5550 [(set (match_operand:DI 0 "register_operand" "=r")
5551 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5552 (match_operand:SI 2 "arith_operand" "rI"))
5553 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5556 [(set_attr "length" "2")])
5559 [(set (match_operand:DI 0 "register_operand" "")
5560 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5561 (match_operand:SI 2 "arith_operand" ""))
5562 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5563 "! TARGET_ARCH64 && reload_completed"
5564 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5565 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5566 (set (match_dup 4) (const_int 0))]
5567 "operands[3] = gen_lowpart (SImode, operands[0]);
5568 operands[4] = gen_highpart (SImode, operands[0]);")
5571 [(set (match_operand:DI 0 "register_operand" "=r")
5572 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5573 (match_operand:DI 2 "register_operand" "r")))
5574 (clobber (reg:CC 100))]
5577 [(set_attr "length" "2")])
5580 [(set (match_operand:DI 0 "register_operand" "")
5581 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5582 (match_operand:DI 2 "register_operand" "")))
5583 (clobber (reg:CC 100))]
5584 "! TARGET_ARCH64 && reload_completed"
5585 [(parallel [(set (reg:CC_NOOV 100)
5586 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5588 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5590 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5591 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5592 "operands[3] = gen_lowpart (SImode, operands[2]);
5593 operands[4] = gen_highpart (SImode, operands[2]);
5594 operands[5] = gen_lowpart (SImode, operands[0]);
5595 operands[6] = gen_highpart (SImode, operands[0]);")
5597 (define_insn "*adddi3_sp64"
5598 [(set (match_operand:DI 0 "register_operand" "=r")
5599 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5600 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5604 (define_expand "addsi3"
5605 [(set (match_operand:SI 0 "register_operand" "=r,d")
5606 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5607 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5611 if (arith_4096_operand(operands[2], SImode))
5613 if (GET_CODE (operands[1]) == CONST_INT)
5614 emit_insn (gen_movsi (operands[0],
5615 GEN_INT (INTVAL (operands[1]) + 4096)));
5617 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5618 gen_rtx_MINUS (SImode, operands[1],
5624 (define_insn "*addsi3"
5625 [(set (match_operand:SI 0 "register_operand" "=r,d")
5626 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5627 (match_operand:SI 2 "arith_operand" "rI,d")))]
5631 fpadd32s\\t%1, %2, %0"
5632 [(set_attr "type" "*,fp")])
5634 (define_insn "*cmp_cc_plus"
5635 [(set (reg:CC_NOOV 100)
5636 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5637 (match_operand:SI 1 "arith_operand" "rI"))
5640 "addcc\\t%0, %1, %%g0"
5641 [(set_attr "type" "compare")])
5643 (define_insn "*cmp_ccx_plus"
5644 [(set (reg:CCX_NOOV 100)
5645 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5646 (match_operand:DI 1 "arith_double_operand" "rHI"))
5649 "addcc\\t%0, %1, %%g0"
5650 [(set_attr "type" "compare")])
5652 (define_insn "*cmp_cc_plus_set"
5653 [(set (reg:CC_NOOV 100)
5654 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5655 (match_operand:SI 2 "arith_operand" "rI"))
5657 (set (match_operand:SI 0 "register_operand" "=r")
5658 (plus:SI (match_dup 1) (match_dup 2)))]
5660 "addcc\\t%1, %2, %0"
5661 [(set_attr "type" "compare")])
5663 (define_insn "*cmp_ccx_plus_set"
5664 [(set (reg:CCX_NOOV 100)
5665 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5666 (match_operand:DI 2 "arith_double_operand" "rHI"))
5668 (set (match_operand:DI 0 "register_operand" "=r")
5669 (plus:DI (match_dup 1) (match_dup 2)))]
5671 "addcc\\t%1, %2, %0"
5672 [(set_attr "type" "compare")])
5674 (define_expand "subdi3"
5675 [(set (match_operand:DI 0 "register_operand" "=r")
5676 (minus:DI (match_operand:DI 1 "register_operand" "r")
5677 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5681 if (! TARGET_ARCH64)
5683 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5684 gen_rtx_SET (VOIDmode, operands[0],
5685 gen_rtx_MINUS (DImode, operands[1],
5687 gen_rtx_CLOBBER (VOIDmode,
5688 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5691 if (arith_double_4096_operand(operands[2], DImode))
5693 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5694 gen_rtx_PLUS (DImode, operands[1],
5700 (define_insn "*subdi3_sp32"
5701 [(set (match_operand:DI 0 "register_operand" "=r")
5702 (minus:DI (match_operand:DI 1 "register_operand" "r")
5703 (match_operand:DI 2 "arith_double_operand" "rHI")))
5704 (clobber (reg:CC 100))]
5707 [(set_attr "length" "2")])
5710 [(set (match_operand:DI 0 "register_operand" "")
5711 (minus:DI (match_operand:DI 1 "register_operand" "")
5712 (match_operand:DI 2 "arith_double_operand" "")))
5713 (clobber (reg:CC 100))]
5716 && (GET_CODE (operands[2]) == CONST_INT
5717 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5718 [(clobber (const_int 0))]
5723 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5724 lowp = gen_lowpart (SImode, operands[2]);
5725 if ((lowp == const0_rtx)
5726 && (operands[0] == operands[1]))
5728 emit_insn (gen_rtx_SET (VOIDmode,
5729 gen_highpart (SImode, operands[0]),
5730 gen_rtx_MINUS (SImode,
5731 gen_highpart_mode (SImode, DImode,
5737 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5738 gen_lowpart (SImode, operands[1]),
5740 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5741 gen_highpart_mode (SImode, DImode, operands[1]),
5748 [(set (match_operand:DI 0 "register_operand" "")
5749 (minus:DI (match_operand:DI 1 "register_operand" "")
5750 (match_operand:DI 2 "register_operand" "")))
5751 (clobber (reg:CC 100))]
5753 && reload_completed"
5754 [(clobber (const_int 0))]
5757 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5758 gen_lowpart (SImode, operands[1]),
5759 gen_lowpart (SImode, operands[2])));
5760 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5761 gen_highpart (SImode, operands[1]),
5762 gen_highpart (SImode, operands[2])));
5767 [(set (match_operand:DI 0 "register_operand" "=r")
5768 (minus:DI (match_operand:DI 1 "register_operand" "r")
5769 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5770 (clobber (reg:CC 100))]
5773 [(set_attr "length" "2")])
5776 [(set (match_operand:DI 0 "register_operand" "")
5777 (minus:DI (match_operand:DI 1 "register_operand" "")
5778 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5779 (clobber (reg:CC 100))]
5780 "! TARGET_ARCH64 && reload_completed"
5781 [(parallel [(set (reg:CC_NOOV 100)
5782 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5784 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5786 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5787 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5788 "operands[3] = gen_lowpart (SImode, operands[1]);
5789 operands[4] = gen_highpart (SImode, operands[1]);
5790 operands[5] = gen_lowpart (SImode, operands[0]);
5791 operands[6] = gen_highpart (SImode, operands[0]);")
5793 (define_insn "*subdi3_sp64"
5794 [(set (match_operand:DI 0 "register_operand" "=r")
5795 (minus:DI (match_operand:DI 1 "register_operand" "r")
5796 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5800 (define_expand "subsi3"
5801 [(set (match_operand:SI 0 "register_operand" "=r,d")
5802 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5803 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5807 if (arith_4096_operand(operands[2], SImode))
5809 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5810 gen_rtx_PLUS (SImode, operands[1],
5816 (define_insn "*subsi3"
5817 [(set (match_operand:SI 0 "register_operand" "=r,d")
5818 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5819 (match_operand:SI 2 "arith_operand" "rI,d")))]
5823 fpsub32s\\t%1, %2, %0"
5824 [(set_attr "type" "*,fp")])
5826 (define_insn "*cmp_minus_cc"
5827 [(set (reg:CC_NOOV 100)
5828 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5829 (match_operand:SI 1 "arith_operand" "rI"))
5832 "subcc\\t%r0, %1, %%g0"
5833 [(set_attr "type" "compare")])
5835 (define_insn "*cmp_minus_ccx"
5836 [(set (reg:CCX_NOOV 100)
5837 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5838 (match_operand:DI 1 "arith_double_operand" "rHI"))
5841 "subcc\\t%0, %1, %%g0"
5842 [(set_attr "type" "compare")])
5844 (define_insn "cmp_minus_cc_set"
5845 [(set (reg:CC_NOOV 100)
5846 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5847 (match_operand:SI 2 "arith_operand" "rI"))
5849 (set (match_operand:SI 0 "register_operand" "=r")
5850 (minus:SI (match_dup 1) (match_dup 2)))]
5852 "subcc\\t%r1, %2, %0"
5853 [(set_attr "type" "compare")])
5855 (define_insn "*cmp_minus_ccx_set"
5856 [(set (reg:CCX_NOOV 100)
5857 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5858 (match_operand:DI 2 "arith_double_operand" "rHI"))
5860 (set (match_operand:DI 0 "register_operand" "=r")
5861 (minus:DI (match_dup 1) (match_dup 2)))]
5863 "subcc\\t%1, %2, %0"
5864 [(set_attr "type" "compare")])
5866 ;; Integer Multiply/Divide.
5868 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5869 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5871 (define_insn "mulsi3"
5872 [(set (match_operand:SI 0 "register_operand" "=r")
5873 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5874 (match_operand:SI 2 "arith_operand" "rI")))]
5877 [(set_attr "type" "imul")])
5879 (define_expand "muldi3"
5880 [(set (match_operand:DI 0 "register_operand" "=r")
5881 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5882 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5883 "TARGET_ARCH64 || TARGET_V8PLUS"
5888 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5893 (define_insn "*muldi3_sp64"
5894 [(set (match_operand:DI 0 "register_operand" "=r")
5895 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5896 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5899 [(set_attr "type" "imul")])
5901 ;; V8plus wide multiply.
5903 (define_insn "muldi3_v8plus"
5904 [(set (match_operand:DI 0 "register_operand" "=r,h")
5905 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5906 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5907 (clobber (match_scratch:SI 3 "=&h,X"))
5908 (clobber (match_scratch:SI 4 "=&h,X"))]
5912 if (sparc_check_64 (operands[1], insn) <= 0)
5913 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5914 if (which_alternative == 1)
5915 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5916 if (GET_CODE (operands[2]) == CONST_INT)
5918 if (which_alternative == 1)
5919 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5921 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\";
5923 if (sparc_check_64 (operands[2], insn) <= 0)
5924 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5925 if (which_alternative == 1)
5926 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\";
5928 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\";
5930 [(set_attr "type" "multi")
5931 (set_attr "length" "9,8")])
5933 (define_insn "*cmp_mul_set"
5935 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5936 (match_operand:SI 2 "arith_operand" "rI"))
5938 (set (match_operand:SI 0 "register_operand" "=r")
5939 (mult:SI (match_dup 1) (match_dup 2)))]
5940 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5941 "smulcc\\t%1, %2, %0"
5942 [(set_attr "type" "imul")])
5944 (define_expand "mulsidi3"
5945 [(set (match_operand:DI 0 "register_operand" "")
5946 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5947 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5951 if (CONSTANT_P (operands[2]))
5954 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5957 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5963 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5968 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5969 ;; registers can hold 64 bit values in the V8plus environment.
5971 (define_insn "mulsidi3_v8plus"
5972 [(set (match_operand:DI 0 "register_operand" "=h,r")
5973 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5974 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5975 (clobber (match_scratch:SI 3 "=X,&h"))]
5978 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5979 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5980 [(set_attr "type" "multi")
5981 (set_attr "length" "2,3")])
5984 (define_insn "const_mulsidi3_v8plus"
5985 [(set (match_operand:DI 0 "register_operand" "=h,r")
5986 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5987 (match_operand:SI 2 "small_int" "I,I")))
5988 (clobber (match_scratch:SI 3 "=X,&h"))]
5991 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5992 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5993 [(set_attr "type" "multi")
5994 (set_attr "length" "2,3")])
5997 (define_insn "*mulsidi3_sp32"
5998 [(set (match_operand:DI 0 "register_operand" "=r")
5999 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6000 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6004 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6007 (if_then_else (eq_attr "isa" "sparclet")
6008 (const_string "imul") (const_string "multi")))
6009 (set (attr "length")
6010 (if_then_else (eq_attr "isa" "sparclet")
6011 (const_int 1) (const_int 2)))])
6013 (define_insn "*mulsidi3_sp64"
6014 [(set (match_operand:DI 0 "register_operand" "=r")
6015 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6016 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6017 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6019 [(set_attr "type" "imul")])
6021 ;; Extra pattern, because sign_extend of a constant isn't valid.
6024 (define_insn "const_mulsidi3_sp32"
6025 [(set (match_operand:DI 0 "register_operand" "=r")
6026 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6027 (match_operand:SI 2 "small_int" "I")))]
6031 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6034 (if_then_else (eq_attr "isa" "sparclet")
6035 (const_string "imul") (const_string "multi")))
6036 (set (attr "length")
6037 (if_then_else (eq_attr "isa" "sparclet")
6038 (const_int 1) (const_int 2)))])
6040 (define_insn "const_mulsidi3_sp64"
6041 [(set (match_operand:DI 0 "register_operand" "=r")
6042 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6043 (match_operand:SI 2 "small_int" "I")))]
6044 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6046 [(set_attr "type" "imul")])
6048 (define_expand "smulsi3_highpart"
6049 [(set (match_operand:SI 0 "register_operand" "")
6051 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6052 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6054 "TARGET_HARD_MUL && TARGET_ARCH32"
6057 if (CONSTANT_P (operands[2]))
6061 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6067 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6072 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6073 operands[2], GEN_INT (32)));
6079 (define_insn "smulsi3_highpart_v8plus"
6080 [(set (match_operand:SI 0 "register_operand" "=h,r")
6082 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6083 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6084 (match_operand:SI 3 "const_int_operand" "i,i"))))
6085 (clobber (match_scratch:SI 4 "=X,&h"))]
6088 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6089 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6090 [(set_attr "type" "multi")
6091 (set_attr "length" "2")])
6093 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6096 [(set (match_operand:SI 0 "register_operand" "=h,r")
6099 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6100 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6101 (match_operand:SI 3 "const_int_operand" "i,i"))
6103 (clobber (match_scratch:SI 4 "=X,&h"))]
6106 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6107 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6108 [(set_attr "type" "multi")
6109 (set_attr "length" "2")])
6112 (define_insn "const_smulsi3_highpart_v8plus"
6113 [(set (match_operand:SI 0 "register_operand" "=h,r")
6115 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6116 (match_operand 2 "small_int" "i,i"))
6117 (match_operand:SI 3 "const_int_operand" "i,i"))))
6118 (clobber (match_scratch:SI 4 "=X,&h"))]
6121 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6122 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6123 [(set_attr "type" "multi")
6124 (set_attr "length" "2")])
6127 (define_insn "*smulsi3_highpart_sp32"
6128 [(set (match_operand:SI 0 "register_operand" "=r")
6130 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6131 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6134 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6135 [(set_attr "type" "multi")
6136 (set_attr "length" "2")])
6139 (define_insn "const_smulsi3_highpart"
6140 [(set (match_operand:SI 0 "register_operand" "=r")
6142 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6143 (match_operand:SI 2 "register_operand" "r"))
6146 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6147 [(set_attr "type" "multi")
6148 (set_attr "length" "2")])
6150 (define_expand "umulsidi3"
6151 [(set (match_operand:DI 0 "register_operand" "")
6152 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6153 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6157 if (CONSTANT_P (operands[2]))
6160 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6163 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6169 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6175 (define_insn "umulsidi3_v8plus"
6176 [(set (match_operand:DI 0 "register_operand" "=h,r")
6177 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6178 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6179 (clobber (match_scratch:SI 3 "=X,&h"))]
6182 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6183 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6184 [(set_attr "type" "multi")
6185 (set_attr "length" "2,3")])
6188 (define_insn "*umulsidi3_sp32"
6189 [(set (match_operand:DI 0 "register_operand" "=r")
6190 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6191 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6195 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6198 (if_then_else (eq_attr "isa" "sparclet")
6199 (const_string "imul") (const_string "multi")))
6200 (set (attr "length")
6201 (if_then_else (eq_attr "isa" "sparclet")
6202 (const_int 1) (const_int 2)))])
6204 (define_insn "*umulsidi3_sp64"
6205 [(set (match_operand:DI 0 "register_operand" "=r")
6206 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6207 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6208 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6210 [(set_attr "type" "imul")])
6212 ;; Extra pattern, because sign_extend of a constant isn't valid.
6215 (define_insn "const_umulsidi3_sp32"
6216 [(set (match_operand:DI 0 "register_operand" "=r")
6217 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6218 (match_operand:SI 2 "uns_small_int" "")))]
6222 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6225 (if_then_else (eq_attr "isa" "sparclet")
6226 (const_string "imul") (const_string "multi")))
6227 (set (attr "length")
6228 (if_then_else (eq_attr "isa" "sparclet")
6229 (const_int 1) (const_int 2)))])
6231 (define_insn "const_umulsidi3_sp64"
6232 [(set (match_operand:DI 0 "register_operand" "=r")
6233 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6234 (match_operand:SI 2 "uns_small_int" "")))]
6235 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6237 [(set_attr "type" "imul")])
6240 (define_insn "const_umulsidi3_v8plus"
6241 [(set (match_operand:DI 0 "register_operand" "=h,r")
6242 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6243 (match_operand:SI 2 "uns_small_int" "")))
6244 (clobber (match_scratch:SI 3 "=X,h"))]
6247 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6248 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6249 [(set_attr "type" "multi")
6250 (set_attr "length" "2,3")])
6252 (define_expand "umulsi3_highpart"
6253 [(set (match_operand:SI 0 "register_operand" "")
6255 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6256 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6258 "TARGET_HARD_MUL && TARGET_ARCH32"
6261 if (CONSTANT_P (operands[2]))
6265 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6271 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6276 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6277 operands[2], GEN_INT (32)));
6283 (define_insn "umulsi3_highpart_v8plus"
6284 [(set (match_operand:SI 0 "register_operand" "=h,r")
6286 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6287 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6288 (match_operand:SI 3 "const_int_operand" "i,i"))))
6289 (clobber (match_scratch:SI 4 "=X,h"))]
6292 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6293 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6294 [(set_attr "type" "multi")
6295 (set_attr "length" "2")])
6298 (define_insn "const_umulsi3_highpart_v8plus"
6299 [(set (match_operand:SI 0 "register_operand" "=h,r")
6301 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6302 (match_operand:SI 2 "uns_small_int" ""))
6303 (match_operand:SI 3 "const_int_operand" "i,i"))))
6304 (clobber (match_scratch:SI 4 "=X,h"))]
6307 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6308 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6309 [(set_attr "type" "multi")
6310 (set_attr "length" "2")])
6313 (define_insn "*umulsi3_highpart_sp32"
6314 [(set (match_operand:SI 0 "register_operand" "=r")
6316 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6317 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6320 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6321 [(set_attr "type" "multi")
6322 (set_attr "length" "2")])
6325 (define_insn "const_umulsi3_highpart"
6326 [(set (match_operand:SI 0 "register_operand" "=r")
6328 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6329 (match_operand:SI 2 "uns_small_int" ""))
6332 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6333 [(set_attr "type" "multi")
6334 (set_attr "length" "2")])
6336 ;; The v8 architecture specifies that there must be 3 instructions between
6337 ;; a y register write and a use of it for correct results.
6339 (define_expand "divsi3"
6340 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6341 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6342 (match_operand:SI 2 "input_operand" "rI,m")))
6343 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6344 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6349 operands[3] = gen_reg_rtx(SImode);
6350 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6351 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6357 (define_insn "divsi3_sp32"
6358 [(set (match_operand:SI 0 "register_operand" "=r,r")
6359 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6360 (match_operand:SI 2 "input_operand" "rI,m")))
6361 (clobber (match_scratch:SI 3 "=&r,&r"))]
6362 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6366 if (which_alternative == 0)
6368 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6370 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6373 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6375 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\";
6377 [(set_attr "type" "multi")
6378 (set (attr "length")
6379 (if_then_else (eq_attr "isa" "v9")
6380 (const_int 4) (const_int 7)))])
6382 (define_insn "divsi3_sp64"
6383 [(set (match_operand:SI 0 "register_operand" "=r")
6384 (div:SI (match_operand:SI 1 "register_operand" "r")
6385 (match_operand:SI 2 "input_operand" "rI")))
6386 (use (match_operand:SI 3 "register_operand" "r"))]
6387 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6388 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6389 [(set_attr "type" "multi")
6390 (set_attr "length" "2")])
6392 (define_insn "divdi3"
6393 [(set (match_operand:DI 0 "register_operand" "=r")
6394 (div:DI (match_operand:DI 1 "register_operand" "r")
6395 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6397 "sdivx\\t%1, %2, %0"
6398 [(set_attr "type" "idiv")])
6400 (define_insn "*cmp_sdiv_cc_set"
6402 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6403 (match_operand:SI 2 "arith_operand" "rI"))
6405 (set (match_operand:SI 0 "register_operand" "=r")
6406 (div:SI (match_dup 1) (match_dup 2)))
6407 (clobber (match_scratch:SI 3 "=&r"))]
6408 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6412 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6414 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6416 [(set_attr "type" "multi")
6417 (set (attr "length")
6418 (if_then_else (eq_attr "isa" "v9")
6419 (const_int 3) (const_int 6)))])
6422 (define_expand "udivsi3"
6423 [(set (match_operand:SI 0 "register_operand" "")
6424 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6425 (match_operand:SI 2 "input_operand" "")))]
6426 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6429 (define_insn "udivsi3_sp32"
6430 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6431 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6432 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6434 || TARGET_DEPRECATED_V8_INSNS)
6438 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6439 switch (which_alternative)
6442 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6444 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6446 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6449 [(set_attr "type" "multi")
6450 (set_attr "length" "5")])
6452 (define_insn "udivsi3_sp64"
6453 [(set (match_operand:SI 0 "register_operand" "=r")
6454 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6455 (match_operand:SI 2 "input_operand" "rI")))]
6456 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6457 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6458 [(set_attr "type" "multi")
6459 (set_attr "length" "2")])
6461 (define_insn "udivdi3"
6462 [(set (match_operand:DI 0 "register_operand" "=r")
6463 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6464 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6466 "udivx\\t%1, %2, %0"
6467 [(set_attr "type" "idiv")])
6469 (define_insn "*cmp_udiv_cc_set"
6471 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6472 (match_operand:SI 2 "arith_operand" "rI"))
6474 (set (match_operand:SI 0 "register_operand" "=r")
6475 (udiv:SI (match_dup 1) (match_dup 2)))]
6477 || TARGET_DEPRECATED_V8_INSNS"
6481 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6483 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6485 [(set_attr "type" "multi")
6486 (set (attr "length")
6487 (if_then_else (eq_attr "isa" "v9")
6488 (const_int 2) (const_int 5)))])
6490 ; sparclet multiply/accumulate insns
6492 (define_insn "*smacsi"
6493 [(set (match_operand:SI 0 "register_operand" "=r")
6494 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6495 (match_operand:SI 2 "arith_operand" "rI"))
6496 (match_operand:SI 3 "register_operand" "0")))]
6499 [(set_attr "type" "imul")])
6501 (define_insn "*smacdi"
6502 [(set (match_operand:DI 0 "register_operand" "=r")
6503 (plus:DI (mult:DI (sign_extend:DI
6504 (match_operand:SI 1 "register_operand" "%r"))
6506 (match_operand:SI 2 "register_operand" "r")))
6507 (match_operand:DI 3 "register_operand" "0")))]
6509 "smacd\\t%1, %2, %L0"
6510 [(set_attr "type" "imul")])
6512 (define_insn "*umacdi"
6513 [(set (match_operand:DI 0 "register_operand" "=r")
6514 (plus:DI (mult:DI (zero_extend:DI
6515 (match_operand:SI 1 "register_operand" "%r"))
6517 (match_operand:SI 2 "register_operand" "r")))
6518 (match_operand:DI 3 "register_operand" "0")))]
6520 "umacd\\t%1, %2, %L0"
6521 [(set_attr "type" "imul")])
6523 ;;- Boolean instructions
6524 ;; We define DImode `and' so with DImode `not' we can get
6525 ;; DImode `andn'. Other combinations are possible.
6527 (define_expand "anddi3"
6528 [(set (match_operand:DI 0 "register_operand" "")
6529 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6530 (match_operand:DI 2 "arith_double_operand" "")))]
6534 (define_insn "*anddi3_sp32"
6535 [(set (match_operand:DI 0 "register_operand" "=r,b")
6536 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6537 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6542 [(set_attr "type" "*,fp")
6543 (set_attr "length" "2,*")
6544 (set_attr "fptype" "double")])
6546 (define_insn "*anddi3_sp64"
6547 [(set (match_operand:DI 0 "register_operand" "=r,b")
6548 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6549 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6554 [(set_attr "type" "*,fp")
6555 (set_attr "fptype" "double")])
6557 (define_insn "andsi3"
6558 [(set (match_operand:SI 0 "register_operand" "=r,d")
6559 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6560 (match_operand:SI 2 "arith_operand" "rI,d")))]
6565 [(set_attr "type" "*,fp")])
6568 [(set (match_operand:SI 0 "register_operand" "")
6569 (and:SI (match_operand:SI 1 "register_operand" "")
6570 (match_operand:SI 2 "" "")))
6571 (clobber (match_operand:SI 3 "register_operand" ""))]
6572 "GET_CODE (operands[2]) == CONST_INT
6573 && !SMALL_INT32 (operands[2])
6574 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6575 [(set (match_dup 3) (match_dup 4))
6576 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6579 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6582 ;; Split DImode logical operations requiring two instructions.
6584 [(set (match_operand:DI 0 "register_operand" "")
6585 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6586 [(match_operand:DI 2 "register_operand" "")
6587 (match_operand:DI 3 "arith_double_operand" "")]))]
6590 && ((GET_CODE (operands[0]) == REG
6591 && REGNO (operands[0]) < 32)
6592 || (GET_CODE (operands[0]) == SUBREG
6593 && GET_CODE (SUBREG_REG (operands[0])) == REG
6594 && REGNO (SUBREG_REG (operands[0])) < 32))"
6595 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6596 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6599 operands[4] = gen_highpart (SImode, operands[0]);
6600 operands[5] = gen_lowpart (SImode, operands[0]);
6601 operands[6] = gen_highpart (SImode, operands[2]);
6602 operands[7] = gen_lowpart (SImode, operands[2]);
6603 #if HOST_BITS_PER_WIDE_INT == 32
6604 if (GET_CODE (operands[3]) == CONST_INT)
6606 if (INTVAL (operands[3]) < 0)
6607 operands[8] = constm1_rtx;
6609 operands[8] = const0_rtx;
6613 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6614 operands[9] = gen_lowpart (SImode, operands[3]);
6617 (define_insn "*and_not_di_sp32"
6618 [(set (match_operand:DI 0 "register_operand" "=r,b")
6619 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6620 (match_operand:DI 2 "register_operand" "r,b")))]
6624 fandnot1\\t%1, %2, %0"
6625 [(set_attr "type" "*,fp")
6626 (set_attr "length" "2,*")
6627 (set_attr "fptype" "double")])
6630 [(set (match_operand:DI 0 "register_operand" "")
6631 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6632 (match_operand:DI 2 "register_operand" "")))]
6635 && ((GET_CODE (operands[0]) == REG
6636 && REGNO (operands[0]) < 32)
6637 || (GET_CODE (operands[0]) == SUBREG
6638 && GET_CODE (SUBREG_REG (operands[0])) == REG
6639 && REGNO (SUBREG_REG (operands[0])) < 32))"
6640 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6641 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6642 "operands[3] = gen_highpart (SImode, operands[0]);
6643 operands[4] = gen_highpart (SImode, operands[1]);
6644 operands[5] = gen_highpart (SImode, operands[2]);
6645 operands[6] = gen_lowpart (SImode, operands[0]);
6646 operands[7] = gen_lowpart (SImode, operands[1]);
6647 operands[8] = gen_lowpart (SImode, operands[2]);")
6649 (define_insn "*and_not_di_sp64"
6650 [(set (match_operand:DI 0 "register_operand" "=r,b")
6651 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6652 (match_operand:DI 2 "register_operand" "r,b")))]
6656 fandnot1\\t%1, %2, %0"
6657 [(set_attr "type" "*,fp")
6658 (set_attr "fptype" "double")])
6660 (define_insn "*and_not_si"
6661 [(set (match_operand:SI 0 "register_operand" "=r,d")
6662 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6663 (match_operand:SI 2 "register_operand" "r,d")))]
6667 fandnot1s\\t%1, %2, %0"
6668 [(set_attr "type" "*,fp")])
6670 (define_expand "iordi3"
6671 [(set (match_operand:DI 0 "register_operand" "")
6672 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6673 (match_operand:DI 2 "arith_double_operand" "")))]
6677 (define_insn "*iordi3_sp32"
6678 [(set (match_operand:DI 0 "register_operand" "=r,b")
6679 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6680 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6685 [(set_attr "type" "*,fp")
6686 (set_attr "length" "2,*")
6687 (set_attr "fptype" "double")])
6689 (define_insn "*iordi3_sp64"
6690 [(set (match_operand:DI 0 "register_operand" "=r,b")
6691 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6692 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6697 [(set_attr "type" "*,fp")
6698 (set_attr "fptype" "double")])
6700 (define_insn "iorsi3"
6701 [(set (match_operand:SI 0 "register_operand" "=r,d")
6702 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6703 (match_operand:SI 2 "arith_operand" "rI,d")))]
6708 [(set_attr "type" "*,fp")])
6711 [(set (match_operand:SI 0 "register_operand" "")
6712 (ior:SI (match_operand:SI 1 "register_operand" "")
6713 (match_operand:SI 2 "" "")))
6714 (clobber (match_operand:SI 3 "register_operand" ""))]
6715 "GET_CODE (operands[2]) == CONST_INT
6716 && !SMALL_INT32 (operands[2])
6717 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6718 [(set (match_dup 3) (match_dup 4))
6719 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6722 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6725 (define_insn "*or_not_di_sp32"
6726 [(set (match_operand:DI 0 "register_operand" "=r,b")
6727 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6728 (match_operand:DI 2 "register_operand" "r,b")))]
6732 fornot1\\t%1, %2, %0"
6733 [(set_attr "type" "*,fp")
6734 (set_attr "length" "2,*")
6735 (set_attr "fptype" "double")])
6738 [(set (match_operand:DI 0 "register_operand" "")
6739 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6740 (match_operand:DI 2 "register_operand" "")))]
6743 && ((GET_CODE (operands[0]) == REG
6744 && REGNO (operands[0]) < 32)
6745 || (GET_CODE (operands[0]) == SUBREG
6746 && GET_CODE (SUBREG_REG (operands[0])) == REG
6747 && REGNO (SUBREG_REG (operands[0])) < 32))"
6748 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6749 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6750 "operands[3] = gen_highpart (SImode, operands[0]);
6751 operands[4] = gen_highpart (SImode, operands[1]);
6752 operands[5] = gen_highpart (SImode, operands[2]);
6753 operands[6] = gen_lowpart (SImode, operands[0]);
6754 operands[7] = gen_lowpart (SImode, operands[1]);
6755 operands[8] = gen_lowpart (SImode, operands[2]);")
6757 (define_insn "*or_not_di_sp64"
6758 [(set (match_operand:DI 0 "register_operand" "=r,b")
6759 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6760 (match_operand:DI 2 "register_operand" "r,b")))]
6764 fornot1\\t%1, %2, %0"
6765 [(set_attr "type" "*,fp")
6766 (set_attr "fptype" "double")])
6768 (define_insn "*or_not_si"
6769 [(set (match_operand:SI 0 "register_operand" "=r,d")
6770 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6771 (match_operand:SI 2 "register_operand" "r,d")))]
6775 fornot1s\\t%1, %2, %0"
6776 [(set_attr "type" "*,fp")])
6778 (define_expand "xordi3"
6779 [(set (match_operand:DI 0 "register_operand" "")
6780 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6781 (match_operand:DI 2 "arith_double_operand" "")))]
6785 (define_insn "*xordi3_sp32"
6786 [(set (match_operand:DI 0 "register_operand" "=r,b")
6787 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6788 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6793 [(set_attr "type" "*,fp")
6794 (set_attr "length" "2,*")
6795 (set_attr "fptype" "double")])
6797 (define_insn "*xordi3_sp64"
6798 [(set (match_operand:DI 0 "register_operand" "=r,b")
6799 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6800 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6805 [(set_attr "type" "*,fp")
6806 (set_attr "fptype" "double")])
6808 (define_insn "*xordi3_sp64_dbl"
6809 [(set (match_operand:DI 0 "register_operand" "=r")
6810 (xor:DI (match_operand:DI 1 "register_operand" "r")
6811 (match_operand:DI 2 "const64_operand" "")))]
6813 && HOST_BITS_PER_WIDE_INT != 64)"
6816 (define_insn "xorsi3"
6817 [(set (match_operand:SI 0 "register_operand" "=r,d")
6818 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6819 (match_operand:SI 2 "arith_operand" "rI,d")))]
6824 [(set_attr "type" "*,fp")])
6827 [(set (match_operand:SI 0 "register_operand" "")
6828 (xor:SI (match_operand:SI 1 "register_operand" "")
6829 (match_operand:SI 2 "" "")))
6830 (clobber (match_operand:SI 3 "register_operand" ""))]
6831 "GET_CODE (operands[2]) == CONST_INT
6832 && !SMALL_INT32 (operands[2])
6833 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6834 [(set (match_dup 3) (match_dup 4))
6835 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6838 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6842 [(set (match_operand:SI 0 "register_operand" "")
6843 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6844 (match_operand:SI 2 "" ""))))
6845 (clobber (match_operand:SI 3 "register_operand" ""))]
6846 "GET_CODE (operands[2]) == CONST_INT
6847 && !SMALL_INT32 (operands[2])
6848 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6849 [(set (match_dup 3) (match_dup 4))
6850 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6853 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6856 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6857 ;; Combine now canonicalizes to the rightmost expression.
6858 (define_insn "*xor_not_di_sp32"
6859 [(set (match_operand:DI 0 "register_operand" "=r,b")
6860 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6861 (match_operand:DI 2 "register_operand" "r,b"))))]
6866 [(set_attr "type" "*,fp")
6867 (set_attr "length" "2,*")
6868 (set_attr "fptype" "double")])
6871 [(set (match_operand:DI 0 "register_operand" "")
6872 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6873 (match_operand:DI 2 "register_operand" ""))))]
6876 && ((GET_CODE (operands[0]) == REG
6877 && REGNO (operands[0]) < 32)
6878 || (GET_CODE (operands[0]) == SUBREG
6879 && GET_CODE (SUBREG_REG (operands[0])) == REG
6880 && REGNO (SUBREG_REG (operands[0])) < 32))"
6881 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6882 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6883 "operands[3] = gen_highpart (SImode, operands[0]);
6884 operands[4] = gen_highpart (SImode, operands[1]);
6885 operands[5] = gen_highpart (SImode, operands[2]);
6886 operands[6] = gen_lowpart (SImode, operands[0]);
6887 operands[7] = gen_lowpart (SImode, operands[1]);
6888 operands[8] = gen_lowpart (SImode, operands[2]);")
6890 (define_insn "*xor_not_di_sp64"
6891 [(set (match_operand:DI 0 "register_operand" "=r,b")
6892 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6893 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6898 [(set_attr "type" "*,fp")
6899 (set_attr "fptype" "double")])
6901 (define_insn "*xor_not_si"
6902 [(set (match_operand:SI 0 "register_operand" "=r,d")
6903 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6904 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6908 fxnors\\t%1, %2, %0"
6909 [(set_attr "type" "*,fp")])
6911 ;; These correspond to the above in the case where we also (or only)
6912 ;; want to set the condition code.
6914 (define_insn "*cmp_cc_arith_op"
6917 (match_operator:SI 2 "cc_arithop"
6918 [(match_operand:SI 0 "arith_operand" "%r")
6919 (match_operand:SI 1 "arith_operand" "rI")])
6922 "%A2cc\\t%0, %1, %%g0"
6923 [(set_attr "type" "compare")])
6925 (define_insn "*cmp_ccx_arith_op"
6928 (match_operator:DI 2 "cc_arithop"
6929 [(match_operand:DI 0 "arith_double_operand" "%r")
6930 (match_operand:DI 1 "arith_double_operand" "rHI")])
6933 "%A2cc\\t%0, %1, %%g0"
6934 [(set_attr "type" "compare")])
6936 (define_insn "*cmp_cc_arith_op_set"
6939 (match_operator:SI 3 "cc_arithop"
6940 [(match_operand:SI 1 "arith_operand" "%r")
6941 (match_operand:SI 2 "arith_operand" "rI")])
6943 (set (match_operand:SI 0 "register_operand" "=r")
6944 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6945 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6946 "%A3cc\\t%1, %2, %0"
6947 [(set_attr "type" "compare")])
6949 (define_insn "*cmp_ccx_arith_op_set"
6952 (match_operator:DI 3 "cc_arithop"
6953 [(match_operand:DI 1 "arith_double_operand" "%r")
6954 (match_operand:DI 2 "arith_double_operand" "rHI")])
6956 (set (match_operand:DI 0 "register_operand" "=r")
6957 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6958 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6959 "%A3cc\\t%1, %2, %0"
6960 [(set_attr "type" "compare")])
6962 (define_insn "*cmp_cc_xor_not"
6965 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6966 (match_operand:SI 1 "arith_operand" "rI")))
6969 "xnorcc\\t%r0, %1, %%g0"
6970 [(set_attr "type" "compare")])
6972 (define_insn "*cmp_ccx_xor_not"
6975 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6976 (match_operand:DI 1 "arith_double_operand" "rHI")))
6979 "xnorcc\\t%r0, %1, %%g0"
6980 [(set_attr "type" "compare")])
6982 (define_insn "*cmp_cc_xor_not_set"
6985 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6986 (match_operand:SI 2 "arith_operand" "rI")))
6988 (set (match_operand:SI 0 "register_operand" "=r")
6989 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6991 "xnorcc\\t%r1, %2, %0"
6992 [(set_attr "type" "compare")])
6994 (define_insn "*cmp_ccx_xor_not_set"
6997 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6998 (match_operand:DI 2 "arith_double_operand" "rHI")))
7000 (set (match_operand:DI 0 "register_operand" "=r")
7001 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7003 "xnorcc\\t%r1, %2, %0"
7004 [(set_attr "type" "compare")])
7006 (define_insn "*cmp_cc_arith_op_not"
7009 (match_operator:SI 2 "cc_arithopn"
7010 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7011 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7014 "%B2cc\\t%r1, %0, %%g0"
7015 [(set_attr "type" "compare")])
7017 (define_insn "*cmp_ccx_arith_op_not"
7020 (match_operator:DI 2 "cc_arithopn"
7021 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7022 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7025 "%B2cc\\t%r1, %0, %%g0"
7026 [(set_attr "type" "compare")])
7028 (define_insn "*cmp_cc_arith_op_not_set"
7031 (match_operator:SI 3 "cc_arithopn"
7032 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7033 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7035 (set (match_operand:SI 0 "register_operand" "=r")
7036 (match_operator:SI 4 "cc_arithopn"
7037 [(not:SI (match_dup 1)) (match_dup 2)]))]
7038 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7039 "%B3cc\\t%r2, %1, %0"
7040 [(set_attr "type" "compare")])
7042 (define_insn "*cmp_ccx_arith_op_not_set"
7045 (match_operator:DI 3 "cc_arithopn"
7046 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7047 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7049 (set (match_operand:DI 0 "register_operand" "=r")
7050 (match_operator:DI 4 "cc_arithopn"
7051 [(not:DI (match_dup 1)) (match_dup 2)]))]
7052 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7053 "%B3cc\\t%r2, %1, %0"
7054 [(set_attr "type" "compare")])
7056 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7057 ;; does not know how to make it work for constants.
7059 (define_expand "negdi2"
7060 [(set (match_operand:DI 0 "register_operand" "=r")
7061 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7065 if (! TARGET_ARCH64)
7067 emit_insn (gen_rtx_PARALLEL
7070 gen_rtx_SET (VOIDmode, operand0,
7071 gen_rtx_NEG (DImode, operand1)),
7072 gen_rtx_CLOBBER (VOIDmode,
7073 gen_rtx_REG (CCmode,
7079 (define_insn "*negdi2_sp32"
7080 [(set (match_operand:DI 0 "register_operand" "=r")
7081 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7082 (clobber (reg:CC 100))]
7085 [(set_attr "length" "2")])
7088 [(set (match_operand:DI 0 "register_operand" "")
7089 (neg:DI (match_operand:DI 1 "register_operand" "")))
7090 (clobber (reg:CC 100))]
7092 && reload_completed"
7093 [(parallel [(set (reg:CC_NOOV 100)
7094 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7096 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7097 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7098 (ltu:SI (reg:CC 100) (const_int 0))))]
7099 "operands[2] = gen_highpart (SImode, operands[0]);
7100 operands[3] = gen_highpart (SImode, operands[1]);
7101 operands[4] = gen_lowpart (SImode, operands[0]);
7102 operands[5] = gen_lowpart (SImode, operands[1]);")
7104 (define_insn "*negdi2_sp64"
7105 [(set (match_operand:DI 0 "register_operand" "=r")
7106 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7108 "sub\\t%%g0, %1, %0")
7110 (define_insn "negsi2"
7111 [(set (match_operand:SI 0 "register_operand" "=r")
7112 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7114 "sub\\t%%g0, %1, %0")
7116 (define_insn "*cmp_cc_neg"
7117 [(set (reg:CC_NOOV 100)
7118 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7121 "subcc\\t%%g0, %0, %%g0"
7122 [(set_attr "type" "compare")])
7124 (define_insn "*cmp_ccx_neg"
7125 [(set (reg:CCX_NOOV 100)
7126 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7129 "subcc\\t%%g0, %0, %%g0"
7130 [(set_attr "type" "compare")])
7132 (define_insn "*cmp_cc_set_neg"
7133 [(set (reg:CC_NOOV 100)
7134 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7136 (set (match_operand:SI 0 "register_operand" "=r")
7137 (neg:SI (match_dup 1)))]
7139 "subcc\\t%%g0, %1, %0"
7140 [(set_attr "type" "compare")])
7142 (define_insn "*cmp_ccx_set_neg"
7143 [(set (reg:CCX_NOOV 100)
7144 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7146 (set (match_operand:DI 0 "register_operand" "=r")
7147 (neg:DI (match_dup 1)))]
7149 "subcc\\t%%g0, %1, %0"
7150 [(set_attr "type" "compare")])
7152 ;; We cannot use the "not" pseudo insn because the Sun assembler
7153 ;; does not know how to make it work for constants.
7154 (define_expand "one_cmpldi2"
7155 [(set (match_operand:DI 0 "register_operand" "")
7156 (not:DI (match_operand:DI 1 "register_operand" "")))]
7160 (define_insn "*one_cmpldi2_sp32"
7161 [(set (match_operand:DI 0 "register_operand" "=r,b")
7162 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7167 [(set_attr "type" "*,fp")
7168 (set_attr "length" "2,*")
7169 (set_attr "fptype" "double")])
7172 [(set (match_operand:DI 0 "register_operand" "")
7173 (not:DI (match_operand:DI 1 "register_operand" "")))]
7176 && ((GET_CODE (operands[0]) == REG
7177 && REGNO (operands[0]) < 32)
7178 || (GET_CODE (operands[0]) == SUBREG
7179 && GET_CODE (SUBREG_REG (operands[0])) == REG
7180 && REGNO (SUBREG_REG (operands[0])) < 32))"
7181 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7182 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (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 "*one_cmpldi2_sp64"
7189 [(set (match_operand:DI 0 "register_operand" "=r,b")
7190 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7195 [(set_attr "type" "*,fp")
7196 (set_attr "fptype" "double")])
7198 (define_insn "one_cmplsi2"
7199 [(set (match_operand:SI 0 "register_operand" "=r,d")
7200 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7205 [(set_attr "type" "*,fp")])
7207 (define_insn "*cmp_cc_not"
7209 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7212 "xnorcc\\t%%g0, %0, %%g0"
7213 [(set_attr "type" "compare")])
7215 (define_insn "*cmp_ccx_not"
7217 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7220 "xnorcc\\t%%g0, %0, %%g0"
7221 [(set_attr "type" "compare")])
7223 (define_insn "*cmp_cc_set_not"
7225 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7227 (set (match_operand:SI 0 "register_operand" "=r")
7228 (not:SI (match_dup 1)))]
7230 "xnorcc\\t%%g0, %1, %0"
7231 [(set_attr "type" "compare")])
7233 (define_insn "*cmp_ccx_set_not"
7235 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7237 (set (match_operand:DI 0 "register_operand" "=r")
7238 (not:DI (match_dup 1)))]
7240 "xnorcc\\t%%g0, %1, %0"
7241 [(set_attr "type" "compare")])
7243 (define_insn "*cmp_cc_set"
7244 [(set (match_operand:SI 0 "register_operand" "=r")
7245 (match_operand:SI 1 "register_operand" "r"))
7247 (compare:CC (match_dup 1)
7251 [(set_attr "type" "compare")])
7253 (define_insn "*cmp_ccx_set64"
7254 [(set (match_operand:DI 0 "register_operand" "=r")
7255 (match_operand:DI 1 "register_operand" "r"))
7257 (compare:CCX (match_dup 1)
7261 [(set_attr "type" "compare")])
7263 ;; Floating point arithmetic instructions.
7265 (define_expand "addtf3"
7266 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7267 (plus:TF (match_operand:TF 1 "general_operand" "")
7268 (match_operand:TF 2 "general_operand" "")))]
7269 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7272 if (! TARGET_HARD_QUAD)
7274 rtx slot0, slot1, slot2;
7276 if (GET_CODE (operands[0]) != MEM)
7277 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7279 slot0 = operands[0];
7280 if (GET_CODE (operands[1]) != MEM)
7282 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7283 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7286 slot1 = operands[1];
7287 if (GET_CODE (operands[2]) != MEM)
7289 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7290 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7293 slot2 = operands[2];
7295 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7297 XEXP (slot0, 0), Pmode,
7298 XEXP (slot1, 0), Pmode,
7299 XEXP (slot2, 0), Pmode);
7301 if (GET_CODE (operands[0]) != MEM)
7302 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7307 (define_insn "*addtf3_hq"
7308 [(set (match_operand:TF 0 "register_operand" "=e")
7309 (plus:TF (match_operand:TF 1 "register_operand" "e")
7310 (match_operand:TF 2 "register_operand" "e")))]
7311 "TARGET_FPU && TARGET_HARD_QUAD"
7312 "faddq\\t%1, %2, %0"
7313 [(set_attr "type" "fp")])
7315 (define_insn "adddf3"
7316 [(set (match_operand:DF 0 "register_operand" "=e")
7317 (plus:DF (match_operand:DF 1 "register_operand" "e")
7318 (match_operand:DF 2 "register_operand" "e")))]
7320 "faddd\\t%1, %2, %0"
7321 [(set_attr "type" "fp")
7322 (set_attr "fptype" "double")])
7324 (define_insn "addsf3"
7325 [(set (match_operand:SF 0 "register_operand" "=f")
7326 (plus:SF (match_operand:SF 1 "register_operand" "f")
7327 (match_operand:SF 2 "register_operand" "f")))]
7329 "fadds\\t%1, %2, %0"
7330 [(set_attr "type" "fp")])
7332 (define_expand "subtf3"
7333 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7334 (minus:TF (match_operand:TF 1 "general_operand" "")
7335 (match_operand:TF 2 "general_operand" "")))]
7336 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7339 if (! TARGET_HARD_QUAD)
7341 rtx slot0, slot1, slot2;
7343 if (GET_CODE (operands[0]) != MEM)
7344 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7346 slot0 = operands[0];
7347 if (GET_CODE (operands[1]) != MEM)
7349 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7350 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7353 slot1 = operands[1];
7354 if (GET_CODE (operands[2]) != MEM)
7356 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7357 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7360 slot2 = operands[2];
7362 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7364 XEXP (slot0, 0), Pmode,
7365 XEXP (slot1, 0), Pmode,
7366 XEXP (slot2, 0), Pmode);
7368 if (GET_CODE (operands[0]) != MEM)
7369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7374 (define_insn "*subtf3_hq"
7375 [(set (match_operand:TF 0 "register_operand" "=e")
7376 (minus:TF (match_operand:TF 1 "register_operand" "e")
7377 (match_operand:TF 2 "register_operand" "e")))]
7378 "TARGET_FPU && TARGET_HARD_QUAD"
7379 "fsubq\\t%1, %2, %0"
7380 [(set_attr "type" "fp")])
7382 (define_insn "subdf3"
7383 [(set (match_operand:DF 0 "register_operand" "=e")
7384 (minus:DF (match_operand:DF 1 "register_operand" "e")
7385 (match_operand:DF 2 "register_operand" "e")))]
7387 "fsubd\\t%1, %2, %0"
7388 [(set_attr "type" "fp")
7389 (set_attr "fptype" "double")])
7391 (define_insn "subsf3"
7392 [(set (match_operand:SF 0 "register_operand" "=f")
7393 (minus:SF (match_operand:SF 1 "register_operand" "f")
7394 (match_operand:SF 2 "register_operand" "f")))]
7396 "fsubs\\t%1, %2, %0"
7397 [(set_attr "type" "fp")])
7399 (define_expand "multf3"
7400 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7401 (mult:TF (match_operand:TF 1 "general_operand" "")
7402 (match_operand:TF 2 "general_operand" "")))]
7403 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7406 if (! TARGET_HARD_QUAD)
7408 rtx slot0, slot1, slot2;
7410 if (GET_CODE (operands[0]) != MEM)
7411 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7413 slot0 = operands[0];
7414 if (GET_CODE (operands[1]) != MEM)
7416 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7417 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7420 slot1 = operands[1];
7421 if (GET_CODE (operands[2]) != MEM)
7423 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7424 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7427 slot2 = operands[2];
7429 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7431 XEXP (slot0, 0), Pmode,
7432 XEXP (slot1, 0), Pmode,
7433 XEXP (slot2, 0), Pmode);
7435 if (GET_CODE (operands[0]) != MEM)
7436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7441 (define_insn "*multf3_hq"
7442 [(set (match_operand:TF 0 "register_operand" "=e")
7443 (mult:TF (match_operand:TF 1 "register_operand" "e")
7444 (match_operand:TF 2 "register_operand" "e")))]
7445 "TARGET_FPU && TARGET_HARD_QUAD"
7446 "fmulq\\t%1, %2, %0"
7447 [(set_attr "type" "fpmul")])
7449 (define_insn "muldf3"
7450 [(set (match_operand:DF 0 "register_operand" "=e")
7451 (mult:DF (match_operand:DF 1 "register_operand" "e")
7452 (match_operand:DF 2 "register_operand" "e")))]
7454 "fmuld\\t%1, %2, %0"
7455 [(set_attr "type" "fpmul")
7456 (set_attr "fptype" "double")])
7458 (define_insn "mulsf3"
7459 [(set (match_operand:SF 0 "register_operand" "=f")
7460 (mult:SF (match_operand:SF 1 "register_operand" "f")
7461 (match_operand:SF 2 "register_operand" "f")))]
7463 "fmuls\\t%1, %2, %0"
7464 [(set_attr "type" "fpmul")])
7466 (define_insn "*muldf3_extend"
7467 [(set (match_operand:DF 0 "register_operand" "=e")
7468 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7469 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7470 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7471 "fsmuld\\t%1, %2, %0"
7472 [(set_attr "type" "fpmul")
7473 (set_attr "fptype" "double")])
7475 (define_insn "*multf3_extend"
7476 [(set (match_operand:TF 0 "register_operand" "=e")
7477 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7478 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7479 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7480 "fdmulq\\t%1, %2, %0"
7481 [(set_attr "type" "fpmul")])
7483 (define_expand "divtf3"
7484 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7485 (div: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_div\"), 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 ;; don't have timing for quad-prec. divide.
7526 (define_insn "*divtf3_hq"
7527 [(set (match_operand:TF 0 "register_operand" "=e")
7528 (div:TF (match_operand:TF 1 "register_operand" "e")
7529 (match_operand:TF 2 "register_operand" "e")))]
7530 "TARGET_FPU && TARGET_HARD_QUAD"
7531 "fdivq\\t%1, %2, %0"
7532 [(set_attr "type" "fpdivd")])
7534 (define_insn "divdf3"
7535 [(set (match_operand:DF 0 "register_operand" "=e")
7536 (div:DF (match_operand:DF 1 "register_operand" "e")
7537 (match_operand:DF 2 "register_operand" "e")))]
7539 "fdivd\\t%1, %2, %0"
7540 [(set_attr "type" "fpdivd")
7541 (set_attr "fptype" "double")])
7543 (define_insn "divsf3"
7544 [(set (match_operand:SF 0 "register_operand" "=f")
7545 (div:SF (match_operand:SF 1 "register_operand" "f")
7546 (match_operand:SF 2 "register_operand" "f")))]
7548 "fdivs\\t%1, %2, %0"
7549 [(set_attr "type" "fpdivs")])
7551 (define_expand "negtf2"
7552 [(set (match_operand:TF 0 "register_operand" "=e,e")
7553 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7557 (define_insn "*negtf2_notv9"
7558 [(set (match_operand:TF 0 "register_operand" "=e,e")
7559 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7560 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7566 [(set_attr "type" "fpmove,*")
7567 (set_attr "length" "*,2")])
7570 [(set (match_operand:TF 0 "register_operand" "")
7571 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7575 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7576 [(set (match_dup 2) (neg:SF (match_dup 3)))
7577 (set (match_dup 4) (match_dup 5))
7578 (set (match_dup 6) (match_dup 7))]
7579 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7580 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7581 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7582 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7583 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7584 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7586 (define_insn "*negtf2_v9"
7587 [(set (match_operand:TF 0 "register_operand" "=e,e")
7588 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7589 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7590 "TARGET_FPU && TARGET_V9"
7594 [(set_attr "type" "fpmove,*")
7595 (set_attr "length" "*,2")
7596 (set_attr "fptype" "double")])
7599 [(set (match_operand:TF 0 "register_operand" "")
7600 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7604 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7605 [(set (match_dup 2) (neg:DF (match_dup 3)))
7606 (set (match_dup 4) (match_dup 5))]
7607 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7608 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7609 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7610 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7612 (define_expand "negdf2"
7613 [(set (match_operand:DF 0 "register_operand" "")
7614 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7618 (define_insn "*negdf2_notv9"
7619 [(set (match_operand:DF 0 "register_operand" "=e,e")
7620 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7621 "TARGET_FPU && ! TARGET_V9"
7625 [(set_attr "type" "fpmove,*")
7626 (set_attr "length" "*,2")])
7629 [(set (match_operand:DF 0 "register_operand" "")
7630 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7634 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7635 [(set (match_dup 2) (neg:SF (match_dup 3)))
7636 (set (match_dup 4) (match_dup 5))]
7637 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7638 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7639 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7640 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7642 (define_insn "*negdf2_v9"
7643 [(set (match_operand:DF 0 "register_operand" "=e")
7644 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7645 "TARGET_FPU && TARGET_V9"
7647 [(set_attr "type" "fpmove")
7648 (set_attr "fptype" "double")])
7650 (define_insn "negsf2"
7651 [(set (match_operand:SF 0 "register_operand" "=f")
7652 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7655 [(set_attr "type" "fpmove")])
7657 (define_expand "abstf2"
7658 [(set (match_operand:TF 0 "register_operand" "")
7659 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7663 (define_insn "*abstf2_notv9"
7664 [(set (match_operand:TF 0 "register_operand" "=e,e")
7665 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7666 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7667 "TARGET_FPU && ! TARGET_V9"
7671 [(set_attr "type" "fpmove,*")
7672 (set_attr "length" "*,2")])
7675 [(set (match_operand:TF 0 "register_operand" "")
7676 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7680 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7681 [(set (match_dup 2) (abs:SF (match_dup 3)))
7682 (set (match_dup 4) (match_dup 5))
7683 (set (match_dup 6) (match_dup 7))]
7684 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7685 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7686 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7687 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7688 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7689 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7691 (define_insn "*abstf2_hq_v9"
7692 [(set (match_operand:TF 0 "register_operand" "=e,e")
7693 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7694 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7698 [(set_attr "type" "fpmove")
7699 (set_attr "fptype" "double,*")])
7701 (define_insn "*abstf2_v9"
7702 [(set (match_operand:TF 0 "register_operand" "=e,e")
7703 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7704 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7708 [(set_attr "type" "fpmove,*")
7709 (set_attr "length" "*,2")
7710 (set_attr "fptype" "double,*")])
7713 [(set (match_operand:TF 0 "register_operand" "")
7714 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7718 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7719 [(set (match_dup 2) (abs:DF (match_dup 3)))
7720 (set (match_dup 4) (match_dup 5))]
7721 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7722 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7723 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7724 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7726 (define_expand "absdf2"
7727 [(set (match_operand:DF 0 "register_operand" "")
7728 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7732 (define_insn "*absdf2_notv9"
7733 [(set (match_operand:DF 0 "register_operand" "=e,e")
7734 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7735 "TARGET_FPU && ! TARGET_V9"
7739 [(set_attr "type" "fpmove,*")
7740 (set_attr "length" "*,2")])
7743 [(set (match_operand:DF 0 "register_operand" "")
7744 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7748 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7749 [(set (match_dup 2) (abs:SF (match_dup 3)))
7750 (set (match_dup 4) (match_dup 5))]
7751 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7752 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7753 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7754 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7756 (define_insn "*absdf2_v9"
7757 [(set (match_operand:DF 0 "register_operand" "=e")
7758 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7759 "TARGET_FPU && TARGET_V9"
7761 [(set_attr "type" "fpmove")
7762 (set_attr "fptype" "double")])
7764 (define_insn "abssf2"
7765 [(set (match_operand:SF 0 "register_operand" "=f")
7766 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7769 [(set_attr "type" "fpmove")])
7771 (define_expand "sqrttf2"
7772 [(set (match_operand:TF 0 "register_operand" "=e")
7773 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7774 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7777 if (! TARGET_HARD_QUAD)
7781 if (GET_CODE (operands[0]) != MEM)
7782 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7784 slot0 = operands[0];
7785 if (GET_CODE (operands[1]) != MEM)
7787 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7788 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7791 slot1 = operands[1];
7793 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7795 XEXP (slot0, 0), Pmode,
7796 XEXP (slot1, 0), Pmode);
7798 if (GET_CODE (operands[0]) != MEM)
7799 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7804 (define_insn "*sqrttf2_hq"
7805 [(set (match_operand:TF 0 "register_operand" "=e")
7806 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7807 "TARGET_FPU && TARGET_HARD_QUAD"
7809 [(set_attr "type" "fpsqrtd")])
7811 (define_insn "sqrtdf2"
7812 [(set (match_operand:DF 0 "register_operand" "=e")
7813 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7816 [(set_attr "type" "fpsqrtd")
7817 (set_attr "fptype" "double")])
7819 (define_insn "sqrtsf2"
7820 [(set (match_operand:SF 0 "register_operand" "=f")
7821 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7824 [(set_attr "type" "fpsqrts")])
7826 ;;- arithmetic shift instructions
7828 (define_insn "ashlsi3"
7829 [(set (match_operand:SI 0 "register_operand" "=r")
7830 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7831 (match_operand:SI 2 "arith_operand" "rI")))]
7835 if (GET_CODE (operands[2]) == CONST_INT
7836 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7837 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7839 return \"sll\\t%1, %2, %0\";
7841 [(set_attr "type" "shift")])
7843 ;; We special case multiplication by two, as add can be done
7844 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7845 (define_insn "*ashlsi3_const1"
7846 [(set (match_operand:SI 0 "register_operand" "=r")
7847 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7852 (define_expand "ashldi3"
7853 [(set (match_operand:DI 0 "register_operand" "=r")
7854 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7855 (match_operand:SI 2 "arith_operand" "rI")))]
7856 "TARGET_ARCH64 || TARGET_V8PLUS"
7859 if (! TARGET_ARCH64)
7861 if (GET_CODE (operands[2]) == CONST_INT)
7863 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7868 ;; We special case multiplication by two, as add can be done
7869 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7870 (define_insn "*ashldi3_const1"
7871 [(set (match_operand:DI 0 "register_operand" "=r")
7872 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7877 (define_insn "*ashldi3_sp64"
7878 [(set (match_operand:DI 0 "register_operand" "=r")
7879 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7880 (match_operand:SI 2 "arith_operand" "rI")))]
7884 if (GET_CODE (operands[2]) == CONST_INT
7885 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7886 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7888 return \"sllx\\t%1, %2, %0\";
7890 [(set_attr "type" "shift")])
7893 (define_insn "ashldi3_v8plus"
7894 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7895 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7896 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7897 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7899 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7900 [(set_attr "type" "multi")
7901 (set_attr "length" "5,5,6")])
7903 ;; Optimize (1LL<<x)-1
7904 ;; XXX this also needs to be fixed to handle equal subregs
7905 ;; XXX first before we could re-enable it.
7907 ; [(set (match_operand:DI 0 "register_operand" "=h")
7908 ; (plus:DI (ashift:DI (const_int 1)
7909 ; (match_operand:SI 1 "arith_operand" "rI"))
7911 ; "0 && TARGET_V8PLUS"
7914 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7915 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7916 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7918 ; [(set_attr "type" "multi")
7919 ; (set_attr "length" "4")])
7921 (define_insn "*cmp_cc_ashift_1"
7922 [(set (reg:CC_NOOV 100)
7923 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7927 "addcc\\t%0, %0, %%g0"
7928 [(set_attr "type" "compare")])
7930 (define_insn "*cmp_cc_set_ashift_1"
7931 [(set (reg:CC_NOOV 100)
7932 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7935 (set (match_operand:SI 0 "register_operand" "=r")
7936 (ashift:SI (match_dup 1) (const_int 1)))]
7938 "addcc\\t%1, %1, %0"
7939 [(set_attr "type" "compare")])
7941 (define_insn "ashrsi3"
7942 [(set (match_operand:SI 0 "register_operand" "=r")
7943 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7944 (match_operand:SI 2 "arith_operand" "rI")))]
7948 if (GET_CODE (operands[2]) == CONST_INT
7949 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7950 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7952 return \"sra\\t%1, %2, %0\";
7954 [(set_attr "type" "shift")])
7956 (define_insn "*ashrsi3_extend"
7957 [(set (match_operand:DI 0 "register_operand" "=r")
7958 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7959 (match_operand:SI 2 "arith_operand" "r"))))]
7962 [(set_attr "type" "shift")])
7964 ;; This handles the case as above, but with constant shift instead of
7965 ;; register. Combiner "simplifies" it for us a little bit though.
7966 (define_insn "*ashrsi3_extend2"
7967 [(set (match_operand:DI 0 "register_operand" "=r")
7968 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7970 (match_operand:SI 2 "small_int_or_double" "n")))]
7972 && ((GET_CODE (operands[2]) == CONST_INT
7973 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7974 || (GET_CODE (operands[2]) == CONST_DOUBLE
7975 && !CONST_DOUBLE_HIGH (operands[2])
7976 && CONST_DOUBLE_LOW (operands[2]) >= 32
7977 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7980 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7982 return \"sra\\t%1, %2, %0\";
7984 [(set_attr "type" "shift")])
7986 (define_expand "ashrdi3"
7987 [(set (match_operand:DI 0 "register_operand" "=r")
7988 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7989 (match_operand:SI 2 "arith_operand" "rI")))]
7990 "TARGET_ARCH64 || TARGET_V8PLUS"
7993 if (! TARGET_ARCH64)
7995 if (GET_CODE (operands[2]) == CONST_INT)
7996 FAIL; /* prefer generic code in this case */
7997 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8003 [(set (match_operand:DI 0 "register_operand" "=r")
8004 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8005 (match_operand:SI 2 "arith_operand" "rI")))]
8009 if (GET_CODE (operands[2]) == CONST_INT
8010 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8011 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8013 return \"srax\\t%1, %2, %0\";
8015 [(set_attr "type" "shift")])
8018 (define_insn "ashrdi3_v8plus"
8019 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8020 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8021 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8022 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8024 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8025 [(set_attr "type" "multi")
8026 (set_attr "length" "5,5,6")])
8028 (define_insn "lshrsi3"
8029 [(set (match_operand:SI 0 "register_operand" "=r")
8030 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8031 (match_operand:SI 2 "arith_operand" "rI")))]
8035 if (GET_CODE (operands[2]) == CONST_INT
8036 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8037 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8039 return \"srl\\t%1, %2, %0\";
8041 [(set_attr "type" "shift")])
8043 ;; This handles the case where
8044 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8045 ;; but combiner "simplifies" it for us.
8046 (define_insn "*lshrsi3_extend"
8047 [(set (match_operand:DI 0 "register_operand" "=r")
8048 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8049 (match_operand:SI 2 "arith_operand" "r")) 0)
8050 (match_operand 3 "" "")))]
8052 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8053 && CONST_DOUBLE_HIGH (operands[3]) == 0
8054 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8055 || (HOST_BITS_PER_WIDE_INT >= 64
8056 && GET_CODE (operands[3]) == CONST_INT
8057 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8059 [(set_attr "type" "shift")])
8061 ;; This handles the case where
8062 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8063 ;; but combiner "simplifies" it for us.
8064 (define_insn "*lshrsi3_extend2"
8065 [(set (match_operand:DI 0 "register_operand" "=r")
8066 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8067 (match_operand 2 "small_int_or_double" "n")
8070 && ((GET_CODE (operands[2]) == CONST_INT
8071 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8072 || (GET_CODE (operands[2]) == CONST_DOUBLE
8073 && CONST_DOUBLE_HIGH (operands[2]) == 0
8074 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8077 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8079 return \"srl\\t%1, %2, %0\";
8081 [(set_attr "type" "shift")])
8083 (define_expand "lshrdi3"
8084 [(set (match_operand:DI 0 "register_operand" "=r")
8085 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8086 (match_operand:SI 2 "arith_operand" "rI")))]
8087 "TARGET_ARCH64 || TARGET_V8PLUS"
8090 if (! TARGET_ARCH64)
8092 if (GET_CODE (operands[2]) == CONST_INT)
8094 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8100 [(set (match_operand:DI 0 "register_operand" "=r")
8101 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8102 (match_operand:SI 2 "arith_operand" "rI")))]
8106 if (GET_CODE (operands[2]) == CONST_INT
8107 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8108 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8110 return \"srlx\\t%1, %2, %0\";
8112 [(set_attr "type" "shift")])
8115 (define_insn "lshrdi3_v8plus"
8116 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8117 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8118 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8119 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8121 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8122 [(set_attr "type" "multi")
8123 (set_attr "length" "5,5,6")])
8126 [(set (match_operand:SI 0 "register_operand" "=r")
8127 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8129 (match_operand:SI 2 "small_int_or_double" "n")))]
8131 && ((GET_CODE (operands[2]) == CONST_INT
8132 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8133 || (GET_CODE (operands[2]) == CONST_DOUBLE
8134 && !CONST_DOUBLE_HIGH (operands[2])
8135 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8138 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8140 return \"srax\\t%1, %2, %0\";
8142 [(set_attr "type" "shift")])
8145 [(set (match_operand:SI 0 "register_operand" "=r")
8146 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8148 (match_operand:SI 2 "small_int_or_double" "n")))]
8150 && ((GET_CODE (operands[2]) == CONST_INT
8151 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8152 || (GET_CODE (operands[2]) == CONST_DOUBLE
8153 && !CONST_DOUBLE_HIGH (operands[2])
8154 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8157 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8159 return \"srlx\\t%1, %2, %0\";
8161 [(set_attr "type" "shift")])
8164 [(set (match_operand:SI 0 "register_operand" "=r")
8165 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8166 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8167 (match_operand:SI 3 "small_int_or_double" "n")))]
8169 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8170 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8171 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8172 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8175 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8177 return \"srax\\t%1, %2, %0\";
8179 [(set_attr "type" "shift")])
8182 [(set (match_operand:SI 0 "register_operand" "=r")
8183 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8184 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8185 (match_operand:SI 3 "small_int_or_double" "n")))]
8187 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8188 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8189 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8190 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8193 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8195 return \"srlx\\t%1, %2, %0\";
8197 [(set_attr "type" "shift")])
8199 ;; Unconditional and other jump instructions
8200 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8201 ;; following insn is never executed. This saves us a nop. Dbx does not
8202 ;; handle such branches though, so we only use them when optimizing.
8204 [(set (pc) (label_ref (match_operand 0 "" "")))]
8208 /* TurboSparc is reported to have problems with
8211 i.e. an empty loop with the annul bit set. The workaround is to use
8215 if (! TARGET_V9 && flag_delayed_branch
8216 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8217 == INSN_ADDRESSES (INSN_UID (insn))))
8218 return \"b\\t%l0%#\";
8220 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8222 [(set_attr "type" "uncond_branch")])
8224 (define_expand "tablejump"
8225 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8226 (use (label_ref (match_operand 1 "" "")))])]
8230 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8233 /* In pic mode, our address differences are against the base of the
8234 table. Add that base value back in; CSE ought to be able to combine
8235 the two address loads. */
8239 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8241 if (CASE_VECTOR_MODE != Pmode)
8242 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8243 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8244 operands[0] = memory_address (Pmode, tmp);
8248 (define_insn "*tablejump_sp32"
8249 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8250 (use (label_ref (match_operand 1 "" "")))]
8253 [(set_attr "type" "uncond_branch")])
8255 (define_insn "*tablejump_sp64"
8256 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8257 (use (label_ref (match_operand 1 "" "")))]
8260 [(set_attr "type" "uncond_branch")])
8262 ;; This pattern recognizes the "instruction" that appears in
8263 ;; a function call that wants a structure value,
8264 ;; to inform the called function if compiled with Sun CC.
8265 ;(define_insn "*unimp_insn"
8266 ; [(match_operand:SI 0 "immediate_operand" "")]
8267 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8269 ; [(set_attr "type" "marker")])
8271 ;;- jump to subroutine
8272 (define_expand "call"
8273 ;; Note that this expression is not used for generating RTL.
8274 ;; All the RTL is generated explicitly below.
8275 [(call (match_operand 0 "call_operand" "")
8276 (match_operand 3 "" "i"))]
8277 ;; operands[2] is next_arg_register
8278 ;; operands[3] is struct_value_size_rtx.
8282 rtx fn_rtx, nregs_rtx;
8284 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8287 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8289 /* This is really a PIC sequence. We want to represent
8290 it as a funny jump so its delay slots can be filled.
8292 ??? But if this really *is* a CALL, will not it clobber the
8293 call-clobbered registers? We lose this if it is a JUMP_INSN.
8294 Why cannot we have delay slots filled if it were a CALL? */
8296 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8301 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8303 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8309 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8310 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8314 fn_rtx = operands[0];
8316 /* Count the number of parameter registers being used by this call.
8317 if that argument is NULL, it means we are using them all, which
8318 means 6 on the sparc. */
8321 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8323 nregs_rtx = GEN_INT (6);
8325 nregs_rtx = const0_rtx;
8328 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8332 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8334 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8339 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8340 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8344 /* If this call wants a structure value,
8345 emit an unimp insn to let the called function know about this. */
8346 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8348 rtx insn = emit_insn (operands[3]);
8349 SCHED_GROUP_P (insn) = 1;
8356 ;; We can't use the same pattern for these two insns, because then registers
8357 ;; in the address may not be properly reloaded.
8359 (define_insn "*call_address_sp32"
8360 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8361 (match_operand 1 "" ""))
8362 (clobber (reg:SI 15))]
8363 ;;- Do not use operand 1 for most machines.
8366 [(set_attr "type" "call")])
8368 (define_insn "*call_symbolic_sp32"
8369 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8370 (match_operand 1 "" ""))
8371 (clobber (reg:SI 15))]
8372 ;;- Do not use operand 1 for most machines.
8375 [(set_attr "type" "call")])
8377 (define_insn "*call_address_sp64"
8378 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8379 (match_operand 1 "" ""))
8380 (clobber (reg:DI 15))]
8381 ;;- Do not use operand 1 for most machines.
8384 [(set_attr "type" "call")])
8386 (define_insn "*call_symbolic_sp64"
8387 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8388 (match_operand 1 "" ""))
8389 (clobber (reg:DI 15))]
8390 ;;- Do not use operand 1 for most machines.
8393 [(set_attr "type" "call")])
8395 ;; This is a call that wants a structure value.
8396 ;; There is no such critter for v9 (??? we may need one anyway).
8397 (define_insn "*call_address_struct_value_sp32"
8398 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8399 (match_operand 1 "" ""))
8400 (match_operand 2 "immediate_operand" "")
8401 (clobber (reg:SI 15))]
8402 ;;- Do not use operand 1 for most machines.
8403 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8404 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8405 [(set_attr "type" "call_no_delay_slot")
8406 (set_attr "length" "2")])
8408 ;; This is a call that wants a structure value.
8409 ;; There is no such critter for v9 (??? we may need one anyway).
8410 (define_insn "*call_symbolic_struct_value_sp32"
8411 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8412 (match_operand 1 "" ""))
8413 (match_operand 2 "immediate_operand" "")
8414 (clobber (reg:SI 15))]
8415 ;;- Do not use operand 1 for most machines.
8416 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8417 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8418 [(set_attr "type" "call_no_delay_slot")
8419 (set_attr "length" "2")])
8421 ;; This is a call that may want a structure value. This is used for
8423 (define_insn "*call_address_untyped_struct_value_sp32"
8424 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8425 (match_operand 1 "" ""))
8426 (match_operand 2 "immediate_operand" "")
8427 (clobber (reg:SI 15))]
8428 ;;- Do not use operand 1 for most machines.
8429 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8430 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8431 [(set_attr "type" "call_no_delay_slot")
8432 (set_attr "length" "2")])
8434 ;; This is a call that wants a structure value.
8435 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8436 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8437 (match_operand 1 "" ""))
8438 (match_operand 2 "immediate_operand" "")
8439 (clobber (reg:SI 15))]
8440 ;;- Do not use operand 1 for most machines.
8441 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8442 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8443 [(set_attr "type" "call_no_delay_slot")
8444 (set_attr "length" "2")])
8446 (define_expand "call_value"
8447 ;; Note that this expression is not used for generating RTL.
8448 ;; All the RTL is generated explicitly below.
8449 [(set (match_operand 0 "register_operand" "=rf")
8450 (call (match_operand 1 "" "")
8451 (match_operand 4 "" "")))]
8452 ;; operand 2 is stack_size_rtx
8453 ;; operand 3 is next_arg_register
8457 rtx fn_rtx, nregs_rtx;
8460 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8463 fn_rtx = operands[1];
8467 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8469 nregs_rtx = GEN_INT (6);
8471 nregs_rtx = const0_rtx;
8475 gen_rtx_SET (VOIDmode, operands[0],
8476 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8477 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8479 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8484 (define_insn "*call_value_address_sp32"
8485 [(set (match_operand 0 "" "=rf")
8486 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8487 (match_operand 2 "" "")))
8488 (clobber (reg:SI 15))]
8489 ;;- Do not use operand 2 for most machines.
8492 [(set_attr "type" "call")])
8494 (define_insn "*call_value_symbolic_sp32"
8495 [(set (match_operand 0 "" "=rf")
8496 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8497 (match_operand 2 "" "")))
8498 (clobber (reg:SI 15))]
8499 ;;- Do not use operand 2 for most machines.
8502 [(set_attr "type" "call")])
8504 (define_insn "*call_value_address_sp64"
8505 [(set (match_operand 0 "" "")
8506 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8507 (match_operand 2 "" "")))
8508 (clobber (reg:DI 15))]
8509 ;;- Do not use operand 2 for most machines.
8512 [(set_attr "type" "call")])
8514 (define_insn "*call_value_symbolic_sp64"
8515 [(set (match_operand 0 "" "")
8516 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8517 (match_operand 2 "" "")))
8518 (clobber (reg:DI 15))]
8519 ;;- Do not use operand 2 for most machines.
8522 [(set_attr "type" "call")])
8524 (define_expand "untyped_call"
8525 [(parallel [(call (match_operand 0 "" "")
8527 (match_operand 1 "" "")
8528 (match_operand 2 "" "")])]
8534 /* Pass constm1 to indicate that it may expect a structure value, but
8535 we don't know what size it is. */
8536 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8538 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8540 rtx set = XVECEXP (operands[2], 0, i);
8541 emit_move_insn (SET_DEST (set), SET_SRC (set));
8544 /* The optimizer does not know that the call sets the function value
8545 registers we stored in the result block. We avoid problems by
8546 claiming that all hard registers are used and clobbered at this
8548 emit_insn (gen_blockage ());
8554 (define_expand "sibcall"
8555 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8560 (define_insn "*sibcall_symbolic_sp32"
8561 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8562 (match_operand 1 "" ""))
8565 "* return output_sibcall(insn, operands[0]);"
8566 [(set_attr "type" "sibcall")])
8568 (define_insn "*sibcall_symbolic_sp64"
8569 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8570 (match_operand 1 "" ""))
8573 "* return output_sibcall(insn, operands[0]);"
8574 [(set_attr "type" "sibcall")])
8576 (define_expand "sibcall_value"
8577 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8578 (call (match_operand 1 "" "") (const_int 0)))
8583 (define_insn "*sibcall_value_symbolic_sp32"
8584 [(set (match_operand 0 "" "=rf")
8585 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8586 (match_operand 2 "" "")))
8589 "* return output_sibcall(insn, operands[1]);"
8590 [(set_attr "type" "sibcall")])
8592 (define_insn "*sibcall_value_symbolic_sp64"
8593 [(set (match_operand 0 "" "")
8594 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8595 (match_operand 2 "" "")))
8598 "* return output_sibcall(insn, operands[1]);"
8599 [(set_attr "type" "sibcall")])
8601 (define_expand "sibcall_epilogue"
8606 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8607 ;; all of memory. This blocks insns from being moved across this point.
8609 (define_insn "blockage"
8610 [(unspec_volatile [(const_int 0)] 0)]
8613 [(set_attr "length" "0")])
8615 ;; Prepare to return any type including a structure value.
8617 (define_expand "untyped_return"
8618 [(match_operand:BLK 0 "memory_operand" "")
8619 (match_operand 1 "" "")]
8623 rtx valreg1 = gen_rtx_REG (DImode, 24);
8624 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8625 rtx result = operands[0];
8627 if (! TARGET_ARCH64)
8629 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8631 rtx value = gen_reg_rtx (SImode);
8633 /* Fetch the instruction where we will return to and see if it's an unimp
8634 instruction (the most significant 10 bits will be zero). If so,
8635 update the return address to skip the unimp instruction. */
8636 emit_move_insn (value,
8637 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8638 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8639 emit_insn (gen_update_return (rtnreg, value));
8642 /* Reload the function value registers. */
8643 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8644 emit_move_insn (valreg2,
8645 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8647 /* Put USE insns before the return. */
8648 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8649 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8651 /* Construct the return. */
8652 expand_null_return ();
8657 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8658 ;; and parts of the compiler don't want to believe that the add is needed.
8660 (define_insn "update_return"
8661 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8662 (match_operand:SI 1 "register_operand" "r")] 1)]
8664 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8665 [(set_attr "type" "multi")
8666 (set_attr "length" "3")])
8668 (define_insn "return"
8672 "* return output_return (operands);"
8673 [(set_attr "type" "return")])
8676 [(set (match_operand:SI 0 "register_operand" "=r")
8677 (match_operand:SI 1 "arith_operand" "rI"))
8679 (use (reg:SI 31))])]
8680 "sparc_return_peephole_ok (operands[0], operands[1])"
8681 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8688 (define_expand "indirect_jump"
8689 [(set (pc) (match_operand 0 "address_operand" "p"))]
8693 (define_insn "*branch_sp32"
8694 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8697 [(set_attr "type" "uncond_branch")])
8699 (define_insn "*branch_sp64"
8700 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8703 [(set_attr "type" "uncond_branch")])
8705 ;; ??? Doesn't work with -mflat.
8706 (define_expand "nonlocal_goto"
8707 [(match_operand:SI 0 "general_operand" "")
8708 (match_operand:SI 1 "general_operand" "")
8709 (match_operand:SI 2 "general_operand" "")
8710 (match_operand:SI 3 "" "")]
8715 rtx chain = operands[0];
8717 rtx lab = operands[1];
8718 rtx stack = operands[2];
8719 rtx fp = operands[3];
8722 /* Trap instruction to flush all the register windows. */
8723 emit_insn (gen_flush_register_windows ());
8725 /* Load the fp value for the containing fn into %fp. This is needed
8726 because STACK refers to %fp. Note that virtual register instantiation
8727 fails if the virtual %fp isn't set from a register. */
8728 if (GET_CODE (fp) != REG)
8729 fp = force_reg (Pmode, fp);
8730 emit_move_insn (virtual_stack_vars_rtx, fp);
8732 /* Find the containing function's current nonlocal goto handler,
8733 which will do any cleanups and then jump to the label. */
8734 labreg = gen_rtx_REG (Pmode, 8);
8735 emit_move_insn (labreg, lab);
8737 /* Restore %fp from stack pointer value for containing function.
8738 The restore insn that follows will move this to %sp,
8739 and reload the appropriate value into %fp. */
8740 emit_move_insn (frame_pointer_rtx, stack);
8742 /* USE of frame_pointer_rtx added for consistency; not clear if
8744 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8745 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8748 /* Return, restoring reg window and jumping to goto handler. */
8749 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8750 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8752 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8758 /* Put in the static chain register the nonlocal label address. */
8759 emit_move_insn (static_chain_rtx, chain);
8762 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8763 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8768 ;; Special trap insn to flush register windows.
8769 (define_insn "flush_register_windows"
8770 [(unspec_volatile [(const_int 0)] 1)]
8772 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8773 [(set_attr "type" "misc")])
8775 (define_insn "goto_handler_and_restore"
8776 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8777 "GET_MODE (operands[0]) == Pmode"
8778 "jmp\\t%0+0\\n\\trestore"
8779 [(set_attr "type" "multi")
8780 (set_attr "length" "2")])
8782 ;;(define_insn "goto_handler_and_restore_v9"
8783 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8784 ;; (match_operand:SI 1 "register_operand" "=r,r")
8785 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8786 ;; "TARGET_V9 && ! TARGET_ARCH64"
8788 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8789 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8790 ;; [(set_attr "type" "multi")
8791 ;; (set_attr "length" "2,3")])
8793 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8794 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8795 ;; (match_operand:DI 1 "register_operand" "=r,r")
8796 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8797 ;; "TARGET_V9 && TARGET_ARCH64"
8799 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8800 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8801 ;; [(set_attr "type" "multi")
8802 ;; (set_attr "length" "2,3")])
8804 ;; For __builtin_setjmp we need to flush register windows iff the function
8805 ;; calls alloca as well, because otherwise the register window might be
8806 ;; saved after %sp adjustement and thus setjmp would crash
8807 (define_expand "builtin_setjmp_setup"
8808 [(match_operand 0 "register_operand" "r")]
8812 emit_insn (gen_do_builtin_setjmp_setup ());
8816 ;; ??? Should set length to zero when !current_function_calls_alloca,
8817 ;; ??? but there is no easy way to get at that definition. It would
8818 ;; ??? require including function.h into sparc-protos.h and that is
8819 ;; ??? likely not a good idea. -DaveM
8820 (define_insn "do_builtin_setjmp_setup"
8821 [(unspec_volatile [(const_int 0)] 5)]
8825 if (!current_function_calls_alloca)
8831 [(set_attr "type" "misc")])
8833 ;; Pattern for use after a setjmp to store FP and the return register
8834 ;; into the stack area.
8836 (define_expand "setjmp"
8842 emit_insn (gen_setjmp_64 ());
8844 emit_insn (gen_setjmp_32 ());
8848 (define_expand "setjmp_32"
8849 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8850 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8853 { operands[0] = frame_pointer_rtx; }")
8855 (define_expand "setjmp_64"
8856 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8857 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8860 { operands[0] = frame_pointer_rtx; }")
8862 ;; Special pattern for the FLUSH instruction.
8864 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8865 ; of the define_insn otherwise missing a mode. We make "flush", aka
8866 ; gen_flush, the default one since sparc_initialize_trampoline uses
8867 ; it on SImode mem values.
8869 (define_insn "flush"
8870 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8872 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8873 [(set_attr "type" "misc")])
8875 (define_insn "flushdi"
8876 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8878 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8879 [(set_attr "type" "misc")])
8884 ;; The scan instruction searches from the most significant bit while ffs
8885 ;; searches from the least significant bit. The bit index and treatment of
8886 ;; zero also differ. It takes at least 7 instructions to get the proper
8887 ;; result. Here is an obvious 8 instruction sequence.
8890 (define_insn "ffssi2"
8891 [(set (match_operand:SI 0 "register_operand" "=&r")
8892 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8893 (clobber (match_scratch:SI 2 "=&r"))]
8894 "TARGET_SPARCLITE || TARGET_SPARCLET"
8897 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\";
8899 [(set_attr "type" "multi")
8900 (set_attr "length" "8")])
8902 ;; ??? This should be a define expand, so that the extra instruction have
8903 ;; a chance of being optimized away.
8905 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8906 ;; does, but no one uses that and we don't have a switch for it.
8908 ;(define_insn "ffsdi2"
8909 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8910 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8911 ; (clobber (match_scratch:DI 2 "=&r"))]
8913 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8914 ; [(set_attr "type" "multi")
8915 ; (set_attr "length" "4")])
8919 ;; Peepholes go at the end.
8921 ;; Optimize consecutive loads or stores into ldd and std when possible.
8922 ;; The conditions in which we do this are very restricted and are
8923 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8926 [(set (match_operand:SI 0 "memory_operand" "")
8928 (set (match_operand:SI 1 "memory_operand" "")
8931 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8934 "operands[0] = change_address (operands[0], DImode, NULL);")
8937 [(set (match_operand:SI 0 "memory_operand" "")
8939 (set (match_operand:SI 1 "memory_operand" "")
8942 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8945 "operands[1] = change_address (operands[1], DImode, NULL);")
8948 [(set (match_operand:SI 0 "register_operand" "")
8949 (match_operand:SI 1 "memory_operand" ""))
8950 (set (match_operand:SI 2 "register_operand" "")
8951 (match_operand:SI 3 "memory_operand" ""))]
8952 "registers_ok_for_ldd_peep (operands[0], operands[2])
8953 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8956 "operands[1] = change_address (operands[1], DImode, NULL);
8957 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8960 [(set (match_operand:SI 0 "memory_operand" "")
8961 (match_operand:SI 1 "register_operand" ""))
8962 (set (match_operand:SI 2 "memory_operand" "")
8963 (match_operand:SI 3 "register_operand" ""))]
8964 "registers_ok_for_ldd_peep (operands[1], operands[3])
8965 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8968 "operands[0] = change_address (operands[0], DImode, NULL);
8969 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8972 [(set (match_operand:SF 0 "register_operand" "")
8973 (match_operand:SF 1 "memory_operand" ""))
8974 (set (match_operand:SF 2 "register_operand" "")
8975 (match_operand:SF 3 "memory_operand" ""))]
8976 "registers_ok_for_ldd_peep (operands[0], operands[2])
8977 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8980 "operands[1] = change_address (operands[1], DFmode, NULL);
8981 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8984 [(set (match_operand:SF 0 "memory_operand" "")
8985 (match_operand:SF 1 "register_operand" ""))
8986 (set (match_operand:SF 2 "memory_operand" "")
8987 (match_operand:SF 3 "register_operand" ""))]
8988 "registers_ok_for_ldd_peep (operands[1], operands[3])
8989 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8992 "operands[0] = change_address (operands[0], DFmode, NULL);
8993 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8996 [(set (match_operand:SI 0 "register_operand" "")
8997 (match_operand:SI 1 "memory_operand" ""))
8998 (set (match_operand:SI 2 "register_operand" "")
8999 (match_operand:SI 3 "memory_operand" ""))]
9000 "registers_ok_for_ldd_peep (operands[2], operands[0])
9001 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9004 "operands[3] = change_address (operands[3], DImode, NULL);
9005 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9008 [(set (match_operand:SI 0 "memory_operand" "")
9009 (match_operand:SI 1 "register_operand" ""))
9010 (set (match_operand:SI 2 "memory_operand" "")
9011 (match_operand:SI 3 "register_operand" ""))]
9012 "registers_ok_for_ldd_peep (operands[3], operands[1])
9013 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9016 "operands[2] = change_address (operands[2], DImode, NULL);
9017 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9021 [(set (match_operand:SF 0 "register_operand" "")
9022 (match_operand:SF 1 "memory_operand" ""))
9023 (set (match_operand:SF 2 "register_operand" "")
9024 (match_operand:SF 3 "memory_operand" ""))]
9025 "registers_ok_for_ldd_peep (operands[2], operands[0])
9026 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9029 "operands[3] = change_address (operands[3], DFmode, NULL);
9030 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9033 [(set (match_operand:SF 0 "memory_operand" "")
9034 (match_operand:SF 1 "register_operand" ""))
9035 (set (match_operand:SF 2 "memory_operand" "")
9036 (match_operand:SF 3 "register_operand" ""))]
9037 "registers_ok_for_ldd_peep (operands[3], operands[1])
9038 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9041 "operands[2] = change_address (operands[2], DFmode, NULL);
9042 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9044 ;; Optimize the case of following a reg-reg move with a test
9045 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9046 ;; This can result from a float to fix conversion.
9049 [(set (match_operand:SI 0 "register_operand" "")
9050 (match_operand:SI 1 "register_operand" ""))
9052 (compare:CC (match_operand:SI 2 "register_operand" "")
9054 "(rtx_equal_p (operands[2], operands[0])
9055 || rtx_equal_p (operands[2], operands[1]))
9056 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9057 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9058 [(parallel [(set (match_dup 0) (match_dup 1))
9060 (compare:CC (match_dup 1) (const_int 0)))])]
9064 [(set (match_operand:DI 0 "register_operand" "")
9065 (match_operand:DI 1 "register_operand" ""))
9067 (compare:CCX (match_operand:DI 2 "register_operand" "")
9070 && (rtx_equal_p (operands[2], operands[0])
9071 || rtx_equal_p (operands[2], operands[1]))
9072 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9073 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9074 [(parallel [(set (match_dup 0) (match_dup 1))
9076 (compare:CC (match_dup 1) (const_int 0)))])]
9079 ;; Return peepholes. First the "normal" ones.
9080 ;; These are necessary to catch insns ending up in the epilogue delay list.
9082 (define_insn "*return_qi"
9083 [(set (match_operand:QI 0 "restore_operand" "")
9084 (match_operand:QI 1 "arith_operand" "rI"))
9089 if (! TARGET_ARCH64 && current_function_returns_struct)
9090 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9091 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9092 || IN_OR_GLOBAL_P (operands[1])))
9093 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9095 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9097 [(set_attr "type" "multi")
9098 (set_attr "length" "2")])
9100 (define_insn "*return_hi"
9101 [(set (match_operand:HI 0 "restore_operand" "")
9102 (match_operand:HI 1 "arith_operand" "rI"))
9107 if (! TARGET_ARCH64 && current_function_returns_struct)
9108 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9109 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9110 || IN_OR_GLOBAL_P (operands[1])))
9111 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9113 return \"ret\;restore %%g0, %1, %Y0\";
9115 [(set_attr "type" "multi")
9116 (set_attr "length" "2")])
9118 (define_insn "*return_si"
9119 [(set (match_operand:SI 0 "restore_operand" "")
9120 (match_operand:SI 1 "arith_operand" "rI"))
9125 if (! TARGET_ARCH64 && current_function_returns_struct)
9126 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9127 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9128 || IN_OR_GLOBAL_P (operands[1])))
9129 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9131 return \"ret\;restore %%g0, %1, %Y0\";
9133 [(set_attr "type" "multi")
9134 (set_attr "length" "2")])
9136 ;; The following pattern is only generated by delayed-branch scheduling,
9137 ;; when the insn winds up in the epilogue. This can happen not only when
9138 ;; ! TARGET_FPU because we move complex types around by parts using
9140 (define_insn "*return_sf_no_fpu"
9141 [(set (match_operand:SF 0 "restore_operand" "=r")
9142 (match_operand:SF 1 "register_operand" "r"))
9147 if (! TARGET_ARCH64 && current_function_returns_struct)
9148 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9149 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9150 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9152 return \"ret\;restore %%g0, %1, %Y0\";
9154 [(set_attr "type" "multi")
9155 (set_attr "length" "2")])
9157 (define_insn "*return_df_no_fpu"
9158 [(set (match_operand:DF 0 "restore_operand" "=r")
9159 (match_operand:DF 1 "register_operand" "r"))
9161 "! TARGET_EPILOGUE && TARGET_ARCH64"
9164 if (IN_OR_GLOBAL_P (operands[1]))
9165 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9167 return \"ret\;restore %%g0, %1, %Y0\";
9169 [(set_attr "type" "multi")
9170 (set_attr "length" "2")])
9172 (define_insn "*return_addsi"
9173 [(set (match_operand:SI 0 "restore_operand" "")
9174 (plus:SI (match_operand:SI 1 "register_operand" "r")
9175 (match_operand:SI 2 "arith_operand" "rI")))
9180 if (! TARGET_ARCH64 && current_function_returns_struct)
9181 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9182 /* If operands are global or in registers, can use return */
9183 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9184 && (GET_CODE (operands[2]) == CONST_INT
9185 || IN_OR_GLOBAL_P (operands[2])))
9186 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9188 return \"ret\;restore %r1, %2, %Y0\";
9190 [(set_attr "type" "multi")
9191 (set_attr "length" "2")])
9193 (define_insn "*return_losum_si"
9194 [(set (match_operand:SI 0 "restore_operand" "")
9195 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9196 (match_operand:SI 2 "immediate_operand" "in")))
9198 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9201 if (! TARGET_ARCH64 && current_function_returns_struct)
9202 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9203 /* If operands are global or in registers, can use return */
9204 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9205 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9207 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9209 [(set_attr "type" "multi")
9210 (set_attr "length" "2")])
9212 (define_insn "*return_di"
9213 [(set (match_operand:DI 0 "restore_operand" "")
9214 (match_operand:DI 1 "arith_double_operand" "rHI"))
9216 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9217 "ret\;restore %%g0, %1, %Y0"
9218 [(set_attr "type" "multi")
9219 (set_attr "length" "2")])
9221 (define_insn "*return_adddi"
9222 [(set (match_operand:DI 0 "restore_operand" "")
9223 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9224 (match_operand:DI 2 "arith_double_operand" "rHI")))
9226 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9227 "ret\;restore %r1, %2, %Y0"
9228 [(set_attr "type" "multi")
9229 (set_attr "length" "2")])
9231 (define_insn "*return_losum_di"
9232 [(set (match_operand:DI 0 "restore_operand" "")
9233 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9234 (match_operand:DI 2 "immediate_operand" "in")))
9236 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9237 "ret\;restore %r1, %%lo(%a2), %Y0"
9238 [(set_attr "type" "multi")
9239 (set_attr "length" "2")])
9241 ;; The following pattern is only generated by delayed-branch scheduling,
9242 ;; when the insn winds up in the epilogue.
9243 (define_insn "*return_sf"
9245 (match_operand:SF 0 "register_operand" "f"))
9248 "ret\;fmovs\\t%0, %%f0"
9249 [(set_attr "type" "multi")
9250 (set_attr "length" "2")])
9252 ;; Now peepholes to do a call followed by a jump.
9255 [(parallel [(set (match_operand 0 "" "")
9256 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9257 (match_operand 2 "" "")))
9258 (clobber (reg:SI 15))])
9259 (set (pc) (label_ref (match_operand 3 "" "")))]
9260 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9261 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9262 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9265 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9266 (match_operand 1 "" ""))
9267 (clobber (reg:SI 15))])
9268 (set (pc) (label_ref (match_operand 2 "" "")))]
9269 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9270 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9271 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9274 [(parallel [(set (match_operand 0 "" "")
9275 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9276 (match_operand 2 "" "")))
9277 (clobber (reg:DI 15))])
9278 (set (pc) (label_ref (match_operand 3 "" "")))]
9280 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9281 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9282 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9285 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9286 (match_operand 1 "" ""))
9287 (clobber (reg:DI 15))])
9288 (set (pc) (label_ref (match_operand 2 "" "")))]
9290 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9291 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9292 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9294 (define_insn "prefetch"
9295 [(prefetch (match_operand:DI 0 "address_operand" "p")
9296 (match_operand:DI 1 "const_int_operand" "n")
9297 (match_operand:DI 2 "const_int_operand" "n"))]
9300 static const char * const prefetch_instr[2][4] = {
9302 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9303 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9304 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9305 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9308 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9309 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9310 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9311 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9314 int read_or_write = INTVAL (operands[1]);
9315 int locality = INTVAL (operands[2]);
9317 if (read_or_write != 0 && read_or_write != 1)
9319 if (locality < 0 || locality > 3)
9321 return prefetch_instr [read_or_write][locality];
9323 [(set_attr "type" "load")])
9325 (define_expand "prologue"
9327 "flag_pic && current_function_uses_pic_offset_table"
9330 load_pic_register ();
9334 ;; We need to reload %l7 for -mflat -fpic,
9335 ;; otherwise %l7 should be preserved simply
9336 ;; by loading the function's register window
9337 (define_expand "exception_receiver"
9339 "TARGET_FLAT && flag_pic"
9342 load_pic_register ();
9347 (define_expand "builtin_setjmp_receiver"
9348 [(label_ref (match_operand 0 "" ""))]
9349 "TARGET_FLAT && flag_pic"
9352 load_pic_register ();
9357 [(trap_if (const_int 1) (const_int 5))]
9360 [(set_attr "type" "misc")])
9362 (define_expand "conditional_trap"
9363 [(trap_if (match_operator 0 "noov_compare_op"
9364 [(match_dup 2) (match_dup 3)])
9365 (match_operand:SI 1 "arith_operand" ""))]
9367 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9368 sparc_compare_op0, sparc_compare_op1);
9369 operands[3] = const0_rtx;")
9372 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9373 (match_operand:SI 1 "arith_operand" "rM"))]
9376 [(set_attr "type" "misc")])
9379 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9380 (match_operand:SI 1 "arith_operand" "rM"))]
9383 [(set_attr "type" "misc")])