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], operands[2]);
2741 (define_expand "reload_outdi"
2742 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2743 (match_operand:DI 1 "immediate_operand" "")
2744 (match_operand:TI 2 "register_operand" "=&r")])]
2746 || TARGET_CM_EMBMEDANY)
2750 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2754 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2756 [(set (match_operand:DI 0 "register_operand" "")
2757 (match_operand:DI 1 "const_int_operand" ""))]
2758 "! TARGET_ARCH64 && reload_completed"
2759 [(clobber (const_int 0))]
2762 #if HOST_BITS_PER_WIDE_INT == 32
2763 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2764 (INTVAL (operands[1]) < 0) ?
2767 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2770 unsigned int low, high;
2772 low = INTVAL (operands[1]) & 0xffffffff;
2773 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2774 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2776 /* Slick... but this trick loses if this subreg constant part
2777 can be done in one insn. */
2778 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2779 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2780 gen_highpart (SImode, operands[0])));
2782 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2788 [(set (match_operand:DI 0 "register_operand" "")
2789 (match_operand:DI 1 "const_double_operand" ""))]
2790 "! TARGET_ARCH64 && reload_completed"
2791 [(clobber (const_int 0))]
2794 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2795 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2797 /* Slick... but this trick loses if this subreg constant part
2798 can be done in one insn. */
2799 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2800 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2801 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2803 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2804 gen_highpart (SImode, operands[0])));
2808 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2809 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2815 [(set (match_operand:DI 0 "register_operand" "")
2816 (match_operand:DI 1 "register_operand" ""))]
2817 "! TARGET_ARCH64 && reload_completed"
2818 [(clobber (const_int 0))]
2821 rtx set_dest = operands[0];
2822 rtx set_src = operands[1];
2826 dest1 = gen_highpart (SImode, set_dest);
2827 dest2 = gen_lowpart (SImode, set_dest);
2828 src1 = gen_highpart (SImode, set_src);
2829 src2 = gen_lowpart (SImode, set_src);
2831 /* Now emit using the real source and destination we found, swapping
2832 the order if we detect overlap. */
2833 if (reg_overlap_mentioned_p (dest1, src2))
2835 emit_insn (gen_movsi (dest2, src2));
2836 emit_insn (gen_movsi (dest1, src1));
2840 emit_insn (gen_movsi (dest1, src1));
2841 emit_insn (gen_movsi (dest2, src2));
2846 ;; Now handle the cases of memory moves from/to non-even
2847 ;; DI mode register pairs.
2849 [(set (match_operand:DI 0 "register_operand" "")
2850 (match_operand:DI 1 "memory_operand" ""))]
2853 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2854 [(clobber (const_int 0))]
2857 rtx word0 = adjust_address (operands[1], SImode, 0);
2858 rtx word1 = adjust_address (operands[1], SImode, 4);
2859 rtx high_part = gen_highpart (SImode, operands[0]);
2860 rtx low_part = gen_lowpart (SImode, operands[0]);
2862 if (reg_overlap_mentioned_p (high_part, word1))
2864 emit_insn (gen_movsi (low_part, word1));
2865 emit_insn (gen_movsi (high_part, word0));
2869 emit_insn (gen_movsi (high_part, word0));
2870 emit_insn (gen_movsi (low_part, word1));
2876 [(set (match_operand:DI 0 "memory_operand" "")
2877 (match_operand:DI 1 "register_operand" ""))]
2880 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2881 [(clobber (const_int 0))]
2884 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2885 gen_highpart (SImode, operands[1])));
2886 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2887 gen_lowpart (SImode, operands[1])));
2892 ;; Floating point move insns
2894 (define_insn "*movsf_insn_novis"
2895 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2896 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2897 "(TARGET_FPU && ! TARGET_VIS)
2898 && (register_operand (operands[0], SFmode)
2899 || register_operand (operands[1], SFmode)
2900 || fp_zero_operand (operands[1], SFmode))"
2903 if (GET_CODE (operands[1]) == CONST_DOUBLE
2904 && (which_alternative == 2
2905 || which_alternative == 3
2906 || which_alternative == 4))
2911 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2912 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2913 operands[1] = GEN_INT (i);
2916 switch (which_alternative)
2919 return \"fmovs\\t%1, %0\";
2921 return \"clr\\t%0\";
2923 return \"sethi\\t%%hi(%a1), %0\";
2925 return \"mov\\t%1, %0\";
2930 return \"ld\\t%1, %0\";
2933 return \"st\\t%r1, %0\";
2938 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2940 (define_insn "*movsf_insn_vis"
2941 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2942 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2943 "(TARGET_FPU && TARGET_VIS)
2944 && (register_operand (operands[0], SFmode)
2945 || register_operand (operands[1], SFmode)
2946 || fp_zero_operand (operands[1], SFmode))"
2949 if (GET_CODE (operands[1]) == CONST_DOUBLE
2950 && (which_alternative == 3
2951 || which_alternative == 4
2952 || which_alternative == 5))
2957 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2958 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2959 operands[1] = GEN_INT (i);
2962 switch (which_alternative)
2965 return \"fmovs\\t%1, %0\";
2967 return \"fzeros\\t%0\";
2969 return \"clr\\t%0\";
2971 return \"sethi\\t%%hi(%a1), %0\";
2973 return \"mov\\t%1, %0\";
2978 return \"ld\\t%1, %0\";
2981 return \"st\\t%r1, %0\";
2986 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2988 ;; Exactly the same as above, except that all `f' cases are deleted.
2989 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2992 (define_insn "*movsf_no_f_insn"
2993 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2994 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2996 && (register_operand (operands[0], SFmode)
2997 || register_operand (operands[1], SFmode)
2998 || fp_zero_operand (operands[1], SFmode))"
3001 if (GET_CODE (operands[1]) == CONST_DOUBLE
3002 && (which_alternative == 1
3003 || which_alternative == 2
3004 || which_alternative == 3))
3009 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3010 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3011 operands[1] = GEN_INT (i);
3014 switch (which_alternative)
3017 return \"clr\\t%0\";
3019 return \"sethi\\t%%hi(%a1), %0\";
3021 return \"mov\\t%1, %0\";
3025 return \"ld\\t%1, %0\";
3027 return \"st\\t%r1, %0\";
3032 [(set_attr "type" "*,*,*,*,load,store")])
3034 (define_insn "*movsf_lo_sum"
3035 [(set (match_operand:SF 0 "register_operand" "=r")
3036 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3037 (match_operand:SF 2 "const_double_operand" "S")))]
3038 "fp_high_losum_p (operands[2])"
3044 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3045 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3046 operands[2] = GEN_INT (i);
3047 return \"or\\t%1, %%lo(%a2), %0\";
3050 (define_insn "*movsf_high"
3051 [(set (match_operand:SF 0 "register_operand" "=r")
3052 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3053 "fp_high_losum_p (operands[1])"
3059 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3060 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3061 operands[1] = GEN_INT (i);
3062 return \"sethi\\t%%hi(%1), %0\";
3066 [(set (match_operand:SF 0 "register_operand" "")
3067 (match_operand:SF 1 "const_double_operand" ""))]
3068 "fp_high_losum_p (operands[1])
3069 && (GET_CODE (operands[0]) == REG
3070 && REGNO (operands[0]) < 32)"
3071 [(set (match_dup 0) (high:SF (match_dup 1)))
3072 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3074 (define_expand "movsf"
3075 [(set (match_operand:SF 0 "general_operand" "")
3076 (match_operand:SF 1 "general_operand" ""))]
3080 /* Force SFmode constants into memory. */
3081 if (GET_CODE (operands[0]) == REG
3082 && CONSTANT_P (operands[1]))
3084 /* emit_group_store will send such bogosity to us when it is
3085 not storing directly into memory. So fix this up to avoid
3086 crashes in output_constant_pool. */
3087 if (operands [1] == const0_rtx)
3088 operands[1] = CONST0_RTX (SFmode);
3090 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3093 /* We are able to build any SF constant in integer registers
3094 with at most 2 instructions. */
3095 if (REGNO (operands[0]) < 32)
3098 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3102 /* Handle sets of MEM first. */
3103 if (GET_CODE (operands[0]) == MEM)
3105 if (register_operand (operands[1], SFmode)
3106 || fp_zero_operand (operands[1], SFmode))
3109 if (! reload_in_progress)
3111 operands[0] = validize_mem (operands[0]);
3112 operands[1] = force_reg (SFmode, operands[1]);
3116 /* Fixup PIC cases. */
3119 if (CONSTANT_P (operands[1])
3120 && pic_address_needs_scratch (operands[1]))
3121 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3123 if (symbolic_operand (operands[1], SFmode))
3125 operands[1] = legitimize_pic_address (operands[1],
3127 (reload_in_progress ?
3137 (define_expand "movdf"
3138 [(set (match_operand:DF 0 "general_operand" "")
3139 (match_operand:DF 1 "general_operand" ""))]
3143 /* Force DFmode constants into memory. */
3144 if (GET_CODE (operands[0]) == REG
3145 && CONSTANT_P (operands[1]))
3147 /* emit_group_store will send such bogosity to us when it is
3148 not storing directly into memory. So fix this up to avoid
3149 crashes in output_constant_pool. */
3150 if (operands [1] == const0_rtx)
3151 operands[1] = CONST0_RTX (DFmode);
3153 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3154 && fp_zero_operand (operands[1], DFmode))
3157 /* We are able to build any DF constant in integer registers. */
3158 if (REGNO (operands[0]) < 32
3159 && (reload_completed || reload_in_progress))
3162 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3166 /* Handle MEM cases first. */
3167 if (GET_CODE (operands[0]) == MEM)
3169 if (register_operand (operands[1], DFmode)
3170 || fp_zero_operand (operands[1], DFmode))
3173 if (! reload_in_progress)
3175 operands[0] = validize_mem (operands[0]);
3176 operands[1] = force_reg (DFmode, operands[1]);
3180 /* Fixup PIC cases. */
3183 if (CONSTANT_P (operands[1])
3184 && pic_address_needs_scratch (operands[1]))
3185 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3187 if (symbolic_operand (operands[1], DFmode))
3189 operands[1] = legitimize_pic_address (operands[1],
3191 (reload_in_progress ?
3201 ;; Be careful, fmovd does not exist when !v9.
3202 (define_insn "*movdf_insn_sp32"
3203 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3204 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3207 && (register_operand (operands[0], DFmode)
3208 || register_operand (operands[1], DFmode)
3209 || fp_zero_operand (operands[1], DFmode))"
3221 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3222 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3224 (define_insn "*movdf_no_e_insn_sp32"
3225 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3226 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3230 && (register_operand (operands[0], DFmode)
3231 || register_operand (operands[1], DFmode)
3232 || fp_zero_operand (operands[1], DFmode))"
3239 [(set_attr "type" "load,store,*,*,*")
3240 (set_attr "length" "*,*,2,2,2")])
3242 (define_insn "*movdf_no_e_insn_v9_sp32"
3243 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3244 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3248 && (register_operand (operands[0], DFmode)
3249 || register_operand (operands[1], DFmode)
3250 || fp_zero_operand (operands[1], DFmode))"
3257 [(set_attr "type" "load,store,store,*,*")
3258 (set_attr "length" "*,*,*,2,2")])
3260 ;; We have available v9 double floats but not 64-bit
3261 ;; integer registers and no VIS.
3262 (define_insn "*movdf_insn_v9only_novis"
3263 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3264 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3269 && (register_operand (operands[0], DFmode)
3270 || register_operand (operands[1], DFmode)
3271 || fp_zero_operand (operands[1], DFmode))"
3282 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3283 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3284 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3286 ;; We have available v9 double floats but not 64-bit
3287 ;; integer registers but we have VIS.
3288 (define_insn "*movdf_insn_v9only_vis"
3289 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3290 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3294 && (register_operand (operands[0], DFmode)
3295 || register_operand (operands[1], DFmode)
3296 || fp_zero_operand (operands[1], DFmode))"
3308 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3309 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3310 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3312 ;; We have available both v9 double floats and 64-bit
3313 ;; integer registers. No VIS though.
3314 (define_insn "*movdf_insn_sp64_novis"
3315 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3316 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3320 && (register_operand (operands[0], DFmode)
3321 || register_operand (operands[1], DFmode)
3322 || fp_zero_operand (operands[1], DFmode))"
3331 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3332 (set_attr "length" "*,*,*,*,*,*,2")
3333 (set_attr "fptype" "double,*,*,*,*,*,*")])
3335 ;; We have available both v9 double floats and 64-bit
3336 ;; integer registers. And we have VIS.
3337 (define_insn "*movdf_insn_sp64_vis"
3338 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3339 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3343 && (register_operand (operands[0], DFmode)
3344 || register_operand (operands[1], DFmode)
3345 || fp_zero_operand (operands[1], DFmode))"
3355 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3356 (set_attr "length" "*,*,*,*,*,*,*,2")
3357 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3359 (define_insn "*movdf_no_e_insn_sp64"
3360 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3361 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3364 && (register_operand (operands[0], DFmode)
3365 || register_operand (operands[1], DFmode)
3366 || fp_zero_operand (operands[1], DFmode))"
3371 [(set_attr "type" "*,load,store")])
3374 [(set (match_operand:DF 0 "register_operand" "")
3375 (match_operand:DF 1 "const_double_operand" ""))]
3377 && (GET_CODE (operands[0]) == REG
3378 && REGNO (operands[0]) < 32)
3379 && ! fp_zero_operand(operands[1], DFmode)
3380 && reload_completed"
3381 [(clobber (const_int 0))]
3387 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3388 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3389 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3393 #if HOST_BITS_PER_WIDE_INT == 64
3396 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3397 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3398 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3400 emit_insn (gen_movdi (operands[0],
3401 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3406 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3409 /* Slick... but this trick loses if this subreg constant part
3410 can be done in one insn. */
3412 && !(SPARC_SETHI_P (l[0])
3413 || SPARC_SIMM13_P (l[0])))
3415 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3416 gen_highpart (SImode, operands[0])));
3420 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3427 ;; Ok, now the splits to handle all the multi insn and
3428 ;; mis-aligned memory address cases.
3429 ;; In these splits please take note that we must be
3430 ;; careful when V9 but not ARCH64 because the integer
3431 ;; register DFmode cases must be handled.
3433 [(set (match_operand:DF 0 "register_operand" "")
3434 (match_operand:DF 1 "register_operand" ""))]
3437 && ((GET_CODE (operands[0]) == REG
3438 && REGNO (operands[0]) < 32)
3439 || (GET_CODE (operands[0]) == SUBREG
3440 && GET_CODE (SUBREG_REG (operands[0])) == REG
3441 && REGNO (SUBREG_REG (operands[0])) < 32))))
3442 && reload_completed"
3443 [(clobber (const_int 0))]
3446 rtx set_dest = operands[0];
3447 rtx set_src = operands[1];
3451 dest1 = gen_highpart (SFmode, set_dest);
3452 dest2 = gen_lowpart (SFmode, set_dest);
3453 src1 = gen_highpart (SFmode, set_src);
3454 src2 = gen_lowpart (SFmode, set_src);
3456 /* Now emit using the real source and destination we found, swapping
3457 the order if we detect overlap. */
3458 if (reg_overlap_mentioned_p (dest1, src2))
3460 emit_insn (gen_movsf (dest2, src2));
3461 emit_insn (gen_movsf (dest1, src1));
3465 emit_insn (gen_movsf (dest1, src1));
3466 emit_insn (gen_movsf (dest2, src2));
3472 [(set (match_operand:DF 0 "register_operand" "")
3473 (match_operand:DF 1 "memory_operand" ""))]
3476 && (((REGNO (operands[0]) % 2) != 0)
3477 || ! mem_min_alignment (operands[1], 8))
3478 && offsettable_memref_p (operands[1])"
3479 [(clobber (const_int 0))]
3482 rtx word0 = adjust_address (operands[1], SFmode, 0);
3483 rtx word1 = adjust_address (operands[1], SFmode, 4);
3485 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3487 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3489 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3494 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3496 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3503 [(set (match_operand:DF 0 "memory_operand" "")
3504 (match_operand:DF 1 "register_operand" ""))]
3507 && (((REGNO (operands[1]) % 2) != 0)
3508 || ! mem_min_alignment (operands[0], 8))
3509 && offsettable_memref_p (operands[0])"
3510 [(clobber (const_int 0))]
3513 rtx word0 = adjust_address (operands[0], SFmode, 0);
3514 rtx word1 = adjust_address (operands[0], SFmode, 4);
3516 emit_insn (gen_movsf (word0,
3517 gen_highpart (SFmode, operands[1])));
3518 emit_insn (gen_movsf (word1,
3519 gen_lowpart (SFmode, operands[1])));
3524 [(set (match_operand:DF 0 "memory_operand" "")
3525 (match_operand:DF 1 "fp_zero_operand" ""))]
3529 && ! mem_min_alignment (operands[0], 8)))
3530 && offsettable_memref_p (operands[0])"
3531 [(clobber (const_int 0))]
3536 dest1 = adjust_address (operands[0], SFmode, 0);
3537 dest2 = adjust_address (operands[0], SFmode, 4);
3539 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3540 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3545 [(set (match_operand:DF 0 "register_operand" "")
3546 (match_operand:DF 1 "fp_zero_operand" ""))]
3549 && ((GET_CODE (operands[0]) == REG
3550 && REGNO (operands[0]) < 32)
3551 || (GET_CODE (operands[0]) == SUBREG
3552 && GET_CODE (SUBREG_REG (operands[0])) == REG
3553 && REGNO (SUBREG_REG (operands[0])) < 32))"
3554 [(clobber (const_int 0))]
3557 rtx set_dest = operands[0];
3560 dest1 = gen_highpart (SFmode, set_dest);
3561 dest2 = gen_lowpart (SFmode, set_dest);
3562 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3563 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3567 (define_expand "movtf"
3568 [(set (match_operand:TF 0 "general_operand" "")
3569 (match_operand:TF 1 "general_operand" ""))]
3573 /* Force TFmode constants into memory. */
3574 if (GET_CODE (operands[0]) == REG
3575 && CONSTANT_P (operands[1]))
3577 /* emit_group_store will send such bogosity to us when it is
3578 not storing directly into memory. So fix this up to avoid
3579 crashes in output_constant_pool. */
3580 if (operands [1] == const0_rtx)
3581 operands[1] = CONST0_RTX (TFmode);
3583 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3586 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3590 /* Handle MEM cases first, note that only v9 guarentees
3591 full 16-byte alignment for quads. */
3592 if (GET_CODE (operands[0]) == MEM)
3594 if (register_operand (operands[1], TFmode)
3595 || fp_zero_operand (operands[1], TFmode))
3598 if (! reload_in_progress)
3600 operands[0] = validize_mem (operands[0]);
3601 operands[1] = force_reg (TFmode, operands[1]);
3605 /* Fixup PIC cases. */
3608 if (CONSTANT_P (operands[1])
3609 && pic_address_needs_scratch (operands[1]))
3610 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3612 if (symbolic_operand (operands[1], TFmode))
3614 operands[1] = legitimize_pic_address (operands[1],
3616 (reload_in_progress ?
3626 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3627 ;; we must split them all. :-(
3628 (define_insn "*movtf_insn_sp32"
3629 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3630 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3634 && (register_operand (operands[0], TFmode)
3635 || register_operand (operands[1], TFmode)
3636 || fp_zero_operand (operands[1], TFmode))"
3638 [(set_attr "length" "4")])
3640 (define_insn "*movtf_insn_vis_sp32"
3641 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3642 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3646 && (register_operand (operands[0], TFmode)
3647 || register_operand (operands[1], TFmode)
3648 || fp_zero_operand (operands[1], TFmode))"
3650 [(set_attr "length" "4")])
3652 ;; Exactly the same as above, except that all `e' cases are deleted.
3653 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3656 (define_insn "*movtf_no_e_insn_sp32"
3657 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3658 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3661 && (register_operand (operands[0], TFmode)
3662 || register_operand (operands[1], TFmode)
3663 || fp_zero_operand (operands[1], TFmode))"
3665 [(set_attr "length" "4")])
3667 ;; Now handle the float reg cases directly when arch64,
3668 ;; hard_quad, and proper reg number alignment are all true.
3669 (define_insn "*movtf_insn_hq_sp64"
3670 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3671 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3676 && (register_operand (operands[0], TFmode)
3677 || register_operand (operands[1], TFmode)
3678 || fp_zero_operand (operands[1], TFmode))"
3685 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3686 (set_attr "length" "*,*,*,2,2")])
3688 (define_insn "*movtf_insn_hq_vis_sp64"
3689 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3690 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3695 && (register_operand (operands[0], TFmode)
3696 || register_operand (operands[1], TFmode)
3697 || fp_zero_operand (operands[1], TFmode))"
3705 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3706 (set_attr "length" "*,*,*,2,2,2")])
3708 ;; Now we allow the integer register cases even when
3709 ;; only arch64 is true.
3710 (define_insn "*movtf_insn_sp64"
3711 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3712 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3716 && ! TARGET_HARD_QUAD
3717 && (register_operand (operands[0], TFmode)
3718 || register_operand (operands[1], TFmode)
3719 || fp_zero_operand (operands[1], TFmode))"
3721 [(set_attr "length" "2")])
3723 (define_insn "*movtf_insn_vis_sp64"
3724 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3725 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3729 && ! TARGET_HARD_QUAD
3730 && (register_operand (operands[0], TFmode)
3731 || register_operand (operands[1], TFmode)
3732 || fp_zero_operand (operands[1], TFmode))"
3734 [(set_attr "length" "2")])
3736 (define_insn "*movtf_no_e_insn_sp64"
3737 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3738 (match_operand:TF 1 "input_operand" "orG,rG"))]
3741 && (register_operand (operands[0], TFmode)
3742 || register_operand (operands[1], TFmode)
3743 || fp_zero_operand (operands[1], TFmode))"
3745 [(set_attr "length" "2")])
3747 ;; Now all the splits to handle multi-insn TF mode moves.
3749 [(set (match_operand:TF 0 "register_operand" "")
3750 (match_operand:TF 1 "register_operand" ""))]
3754 && ! TARGET_HARD_QUAD))"
3755 [(clobber (const_int 0))]
3758 rtx set_dest = operands[0];
3759 rtx set_src = operands[1];
3763 dest1 = gen_df_reg (set_dest, 0);
3764 dest2 = gen_df_reg (set_dest, 1);
3765 src1 = gen_df_reg (set_src, 0);
3766 src2 = gen_df_reg (set_src, 1);
3768 /* Now emit using the real source and destination we found, swapping
3769 the order if we detect overlap. */
3770 if (reg_overlap_mentioned_p (dest1, src2))
3772 emit_insn (gen_movdf (dest2, src2));
3773 emit_insn (gen_movdf (dest1, src1));
3777 emit_insn (gen_movdf (dest1, src1));
3778 emit_insn (gen_movdf (dest2, src2));
3784 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3785 (match_operand:TF 1 "fp_zero_operand" ""))]
3787 [(clobber (const_int 0))]
3790 rtx set_dest = operands[0];
3793 switch (GET_CODE (set_dest))
3796 dest1 = gen_df_reg (set_dest, 0);
3797 dest2 = gen_df_reg (set_dest, 1);
3800 dest1 = adjust_address (set_dest, DFmode, 0);
3801 dest2 = adjust_address (set_dest, DFmode, 8);
3807 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3808 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3813 [(set (match_operand:TF 0 "register_operand" "")
3814 (match_operand:TF 1 "memory_operand" ""))]
3816 && offsettable_memref_p (operands[1]))"
3817 [(clobber (const_int 0))]
3820 rtx word0 = adjust_address (operands[1], DFmode, 0);
3821 rtx word1 = adjust_address (operands[1], DFmode, 8);
3822 rtx set_dest, dest1, dest2;
3824 set_dest = operands[0];
3826 dest1 = gen_df_reg (set_dest, 0);
3827 dest2 = gen_df_reg (set_dest, 1);
3829 /* Now output, ordering such that we don't clobber any registers
3830 mentioned in the address. */
3831 if (reg_overlap_mentioned_p (dest1, word1))
3834 emit_insn (gen_movdf (dest2, word1));
3835 emit_insn (gen_movdf (dest1, word0));
3839 emit_insn (gen_movdf (dest1, word0));
3840 emit_insn (gen_movdf (dest2, word1));
3846 [(set (match_operand:TF 0 "memory_operand" "")
3847 (match_operand:TF 1 "register_operand" ""))]
3849 && offsettable_memref_p (operands[0]))"
3850 [(clobber (const_int 0))]
3853 rtx set_src = operands[1];
3855 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3856 gen_df_reg (set_src, 0)));
3857 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3858 gen_df_reg (set_src, 1)));
3862 ;; Sparc V9 conditional move instructions.
3864 ;; We can handle larger constants here for some flavors, but for now we keep
3865 ;; it simple and only allow those constants supported by all flavours.
3866 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3867 ;; 3 contains the constant if one is present, but we handle either for
3868 ;; generality (sparc.c puts a constant in operand 2).
3870 (define_expand "movqicc"
3871 [(set (match_operand:QI 0 "register_operand" "")
3872 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3873 (match_operand:QI 2 "arith10_operand" "")
3874 (match_operand:QI 3 "arith10_operand" "")))]
3878 enum rtx_code code = GET_CODE (operands[1]);
3880 if (GET_MODE (sparc_compare_op0) == DImode
3884 if (sparc_compare_op1 == const0_rtx
3885 && GET_CODE (sparc_compare_op0) == REG
3886 && GET_MODE (sparc_compare_op0) == DImode
3887 && v9_regcmp_p (code))
3889 operands[1] = gen_rtx_fmt_ee (code, DImode,
3890 sparc_compare_op0, sparc_compare_op1);
3894 rtx cc_reg = gen_compare_reg (code,
3895 sparc_compare_op0, sparc_compare_op1);
3896 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3900 (define_expand "movhicc"
3901 [(set (match_operand:HI 0 "register_operand" "")
3902 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3903 (match_operand:HI 2 "arith10_operand" "")
3904 (match_operand:HI 3 "arith10_operand" "")))]
3908 enum rtx_code code = GET_CODE (operands[1]);
3910 if (GET_MODE (sparc_compare_op0) == DImode
3914 if (sparc_compare_op1 == const0_rtx
3915 && GET_CODE (sparc_compare_op0) == REG
3916 && GET_MODE (sparc_compare_op0) == DImode
3917 && v9_regcmp_p (code))
3919 operands[1] = gen_rtx_fmt_ee (code, DImode,
3920 sparc_compare_op0, sparc_compare_op1);
3924 rtx cc_reg = gen_compare_reg (code,
3925 sparc_compare_op0, sparc_compare_op1);
3926 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3930 (define_expand "movsicc"
3931 [(set (match_operand:SI 0 "register_operand" "")
3932 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3933 (match_operand:SI 2 "arith10_operand" "")
3934 (match_operand:SI 3 "arith10_operand" "")))]
3938 enum rtx_code code = GET_CODE (operands[1]);
3939 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3941 if (sparc_compare_op1 == const0_rtx
3942 && GET_CODE (sparc_compare_op0) == REG
3943 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3945 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3946 sparc_compare_op0, sparc_compare_op1);
3950 rtx cc_reg = gen_compare_reg (code,
3951 sparc_compare_op0, sparc_compare_op1);
3952 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3953 cc_reg, const0_rtx);
3957 (define_expand "movdicc"
3958 [(set (match_operand:DI 0 "register_operand" "")
3959 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3960 (match_operand:DI 2 "arith10_double_operand" "")
3961 (match_operand:DI 3 "arith10_double_operand" "")))]
3965 enum rtx_code code = GET_CODE (operands[1]);
3967 if (sparc_compare_op1 == const0_rtx
3968 && GET_CODE (sparc_compare_op0) == REG
3969 && GET_MODE (sparc_compare_op0) == DImode
3970 && v9_regcmp_p (code))
3972 operands[1] = gen_rtx_fmt_ee (code, DImode,
3973 sparc_compare_op0, sparc_compare_op1);
3977 rtx cc_reg = gen_compare_reg (code,
3978 sparc_compare_op0, sparc_compare_op1);
3979 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3980 cc_reg, const0_rtx);
3984 (define_expand "movsfcc"
3985 [(set (match_operand:SF 0 "register_operand" "")
3986 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3987 (match_operand:SF 2 "register_operand" "")
3988 (match_operand:SF 3 "register_operand" "")))]
3989 "TARGET_V9 && TARGET_FPU"
3992 enum rtx_code code = GET_CODE (operands[1]);
3994 if (GET_MODE (sparc_compare_op0) == DImode
3998 if (sparc_compare_op1 == const0_rtx
3999 && GET_CODE (sparc_compare_op0) == REG
4000 && GET_MODE (sparc_compare_op0) == DImode
4001 && v9_regcmp_p (code))
4003 operands[1] = gen_rtx_fmt_ee (code, DImode,
4004 sparc_compare_op0, sparc_compare_op1);
4008 rtx cc_reg = gen_compare_reg (code,
4009 sparc_compare_op0, sparc_compare_op1);
4010 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4014 (define_expand "movdfcc"
4015 [(set (match_operand:DF 0 "register_operand" "")
4016 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4017 (match_operand:DF 2 "register_operand" "")
4018 (match_operand:DF 3 "register_operand" "")))]
4019 "TARGET_V9 && TARGET_FPU"
4022 enum rtx_code code = GET_CODE (operands[1]);
4024 if (GET_MODE (sparc_compare_op0) == DImode
4028 if (sparc_compare_op1 == const0_rtx
4029 && GET_CODE (sparc_compare_op0) == REG
4030 && GET_MODE (sparc_compare_op0) == DImode
4031 && v9_regcmp_p (code))
4033 operands[1] = gen_rtx_fmt_ee (code, DImode,
4034 sparc_compare_op0, sparc_compare_op1);
4038 rtx cc_reg = gen_compare_reg (code,
4039 sparc_compare_op0, sparc_compare_op1);
4040 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4044 (define_expand "movtfcc"
4045 [(set (match_operand:TF 0 "register_operand" "")
4046 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4047 (match_operand:TF 2 "register_operand" "")
4048 (match_operand:TF 3 "register_operand" "")))]
4049 "TARGET_V9 && TARGET_FPU"
4052 enum rtx_code code = GET_CODE (operands[1]);
4054 if (GET_MODE (sparc_compare_op0) == DImode
4058 if (sparc_compare_op1 == const0_rtx
4059 && GET_CODE (sparc_compare_op0) == REG
4060 && GET_MODE (sparc_compare_op0) == DImode
4061 && v9_regcmp_p (code))
4063 operands[1] = gen_rtx_fmt_ee (code, DImode,
4064 sparc_compare_op0, sparc_compare_op1);
4068 rtx cc_reg = gen_compare_reg (code,
4069 sparc_compare_op0, sparc_compare_op1);
4070 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4074 ;; Conditional move define_insns.
4076 (define_insn "*movqi_cc_sp64"
4077 [(set (match_operand:QI 0 "register_operand" "=r,r")
4078 (if_then_else:QI (match_operator 1 "comparison_operator"
4079 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4081 (match_operand:QI 3 "arith11_operand" "rL,0")
4082 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4085 mov%C1\\t%x2, %3, %0
4086 mov%c1\\t%x2, %4, %0"
4087 [(set_attr "type" "cmove")])
4089 (define_insn "*movhi_cc_sp64"
4090 [(set (match_operand:HI 0 "register_operand" "=r,r")
4091 (if_then_else:HI (match_operator 1 "comparison_operator"
4092 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4094 (match_operand:HI 3 "arith11_operand" "rL,0")
4095 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4098 mov%C1\\t%x2, %3, %0
4099 mov%c1\\t%x2, %4, %0"
4100 [(set_attr "type" "cmove")])
4102 (define_insn "*movsi_cc_sp64"
4103 [(set (match_operand:SI 0 "register_operand" "=r,r")
4104 (if_then_else:SI (match_operator 1 "comparison_operator"
4105 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4107 (match_operand:SI 3 "arith11_operand" "rL,0")
4108 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4111 mov%C1\\t%x2, %3, %0
4112 mov%c1\\t%x2, %4, %0"
4113 [(set_attr "type" "cmove")])
4115 ;; ??? The constraints of operands 3,4 need work.
4116 (define_insn "*movdi_cc_sp64"
4117 [(set (match_operand:DI 0 "register_operand" "=r,r")
4118 (if_then_else:DI (match_operator 1 "comparison_operator"
4119 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4121 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4122 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4125 mov%C1\\t%x2, %3, %0
4126 mov%c1\\t%x2, %4, %0"
4127 [(set_attr "type" "cmove")])
4129 (define_insn "*movdi_cc_sp64_trunc"
4130 [(set (match_operand:SI 0 "register_operand" "=r,r")
4131 (if_then_else:SI (match_operator 1 "comparison_operator"
4132 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4134 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4135 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4138 mov%C1\\t%x2, %3, %0
4139 mov%c1\\t%x2, %4, %0"
4140 [(set_attr "type" "cmove")])
4142 (define_insn "*movsf_cc_sp64"
4143 [(set (match_operand:SF 0 "register_operand" "=f,f")
4144 (if_then_else:SF (match_operator 1 "comparison_operator"
4145 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4147 (match_operand:SF 3 "register_operand" "f,0")
4148 (match_operand:SF 4 "register_operand" "0,f")))]
4149 "TARGET_V9 && TARGET_FPU"
4151 fmovs%C1\\t%x2, %3, %0
4152 fmovs%c1\\t%x2, %4, %0"
4153 [(set_attr "type" "fpcmove")])
4155 (define_insn "movdf_cc_sp64"
4156 [(set (match_operand:DF 0 "register_operand" "=e,e")
4157 (if_then_else:DF (match_operator 1 "comparison_operator"
4158 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4160 (match_operand:DF 3 "register_operand" "e,0")
4161 (match_operand:DF 4 "register_operand" "0,e")))]
4162 "TARGET_V9 && TARGET_FPU"
4164 fmovd%C1\\t%x2, %3, %0
4165 fmovd%c1\\t%x2, %4, %0"
4166 [(set_attr "type" "fpcmove")
4167 (set_attr "fptype" "double")])
4169 (define_insn "*movtf_cc_hq_sp64"
4170 [(set (match_operand:TF 0 "register_operand" "=e,e")
4171 (if_then_else:TF (match_operator 1 "comparison_operator"
4172 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4174 (match_operand:TF 3 "register_operand" "e,0")
4175 (match_operand:TF 4 "register_operand" "0,e")))]
4176 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4178 fmovq%C1\\t%x2, %3, %0
4179 fmovq%c1\\t%x2, %4, %0"
4180 [(set_attr "type" "fpcmove")])
4182 (define_insn "*movtf_cc_sp64"
4183 [(set (match_operand:TF 0 "register_operand" "=e,e")
4184 (if_then_else:TF (match_operator 1 "comparison_operator"
4185 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4187 (match_operand:TF 3 "register_operand" "e,0")
4188 (match_operand:TF 4 "register_operand" "0,e")))]
4189 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4191 [(set_attr "length" "2")])
4194 [(set (match_operand:TF 0 "register_operand" "")
4195 (if_then_else:TF (match_operator 1 "comparison_operator"
4196 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4198 (match_operand:TF 3 "register_operand" "")
4199 (match_operand:TF 4 "register_operand" "")))]
4200 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4201 [(clobber (const_int 0))]
4204 rtx set_dest = operands[0];
4205 rtx set_srca = operands[3];
4206 rtx set_srcb = operands[4];
4207 int third = rtx_equal_p (set_dest, set_srca);
4209 rtx srca1, srca2, srcb1, srcb2;
4211 dest1 = gen_df_reg (set_dest, 0);
4212 dest2 = gen_df_reg (set_dest, 1);
4213 srca1 = gen_df_reg (set_srca, 0);
4214 srca2 = gen_df_reg (set_srca, 1);
4215 srcb1 = gen_df_reg (set_srcb, 0);
4216 srcb2 = gen_df_reg (set_srcb, 1);
4218 /* Now emit using the real source and destination we found, swapping
4219 the order if we detect overlap. */
4220 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4221 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4223 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4224 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4228 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4229 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4234 (define_insn "*movqi_cc_reg_sp64"
4235 [(set (match_operand:QI 0 "register_operand" "=r,r")
4236 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4237 [(match_operand:DI 2 "register_operand" "r,r")
4239 (match_operand:QI 3 "arith10_operand" "rM,0")
4240 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4243 movr%D1\\t%2, %r3, %0
4244 movr%d1\\t%2, %r4, %0"
4245 [(set_attr "type" "cmove")])
4247 (define_insn "*movhi_cc_reg_sp64"
4248 [(set (match_operand:HI 0 "register_operand" "=r,r")
4249 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4250 [(match_operand:DI 2 "register_operand" "r,r")
4252 (match_operand:HI 3 "arith10_operand" "rM,0")
4253 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4256 movr%D1\\t%2, %r3, %0
4257 movr%d1\\t%2, %r4, %0"
4258 [(set_attr "type" "cmove")])
4260 (define_insn "*movsi_cc_reg_sp64"
4261 [(set (match_operand:SI 0 "register_operand" "=r,r")
4262 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4263 [(match_operand:DI 2 "register_operand" "r,r")
4265 (match_operand:SI 3 "arith10_operand" "rM,0")
4266 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4269 movr%D1\\t%2, %r3, %0
4270 movr%d1\\t%2, %r4, %0"
4271 [(set_attr "type" "cmove")])
4273 ;; ??? The constraints of operands 3,4 need work.
4274 (define_insn "*movdi_cc_reg_sp64"
4275 [(set (match_operand:DI 0 "register_operand" "=r,r")
4276 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4277 [(match_operand:DI 2 "register_operand" "r,r")
4279 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4280 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4283 movr%D1\\t%2, %r3, %0
4284 movr%d1\\t%2, %r4, %0"
4285 [(set_attr "type" "cmove")])
4287 (define_insn "*movdi_cc_reg_sp64_trunc"
4288 [(set (match_operand:SI 0 "register_operand" "=r,r")
4289 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4290 [(match_operand:DI 2 "register_operand" "r,r")
4292 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4293 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4296 movr%D1\\t%2, %r3, %0
4297 movr%d1\\t%2, %r4, %0"
4298 [(set_attr "type" "cmove")])
4300 (define_insn "*movsf_cc_reg_sp64"
4301 [(set (match_operand:SF 0 "register_operand" "=f,f")
4302 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4303 [(match_operand:DI 2 "register_operand" "r,r")
4305 (match_operand:SF 3 "register_operand" "f,0")
4306 (match_operand:SF 4 "register_operand" "0,f")))]
4307 "TARGET_ARCH64 && TARGET_FPU"
4309 fmovrs%D1\\t%2, %3, %0
4310 fmovrs%d1\\t%2, %4, %0"
4311 [(set_attr "type" "fpcmove")])
4313 (define_insn "movdf_cc_reg_sp64"
4314 [(set (match_operand:DF 0 "register_operand" "=e,e")
4315 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4316 [(match_operand:DI 2 "register_operand" "r,r")
4318 (match_operand:DF 3 "register_operand" "e,0")
4319 (match_operand:DF 4 "register_operand" "0,e")))]
4320 "TARGET_ARCH64 && TARGET_FPU"
4322 fmovrd%D1\\t%2, %3, %0
4323 fmovrd%d1\\t%2, %4, %0"
4324 [(set_attr "type" "fpcmove")
4325 (set_attr "fptype" "double")])
4327 (define_insn "*movtf_cc_reg_hq_sp64"
4328 [(set (match_operand:TF 0 "register_operand" "=e,e")
4329 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4330 [(match_operand:DI 2 "register_operand" "r,r")
4332 (match_operand:TF 3 "register_operand" "e,0")
4333 (match_operand:TF 4 "register_operand" "0,e")))]
4334 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4336 fmovrq%D1\\t%2, %3, %0
4337 fmovrq%d1\\t%2, %4, %0"
4338 [(set_attr "type" "fpcmove")])
4340 (define_insn "*movtf_cc_reg_sp64"
4341 [(set (match_operand:TF 0 "register_operand" "=e,e")
4342 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4343 [(match_operand:DI 2 "register_operand" "r,r")
4345 (match_operand:TF 3 "register_operand" "e,0")
4346 (match_operand:TF 4 "register_operand" "0,e")))]
4347 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4349 [(set_attr "length" "2")])
4352 [(set (match_operand:TF 0 "register_operand" "")
4353 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4354 [(match_operand:DI 2 "register_operand" "")
4356 (match_operand:TF 3 "register_operand" "")
4357 (match_operand:TF 4 "register_operand" "")))]
4358 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4359 [(clobber (const_int 0))]
4362 rtx set_dest = operands[0];
4363 rtx set_srca = operands[3];
4364 rtx set_srcb = operands[4];
4365 int third = rtx_equal_p (set_dest, set_srca);
4367 rtx srca1, srca2, srcb1, srcb2;
4369 dest1 = gen_df_reg (set_dest, 0);
4370 dest2 = gen_df_reg (set_dest, 1);
4371 srca1 = gen_df_reg (set_srca, 0);
4372 srca2 = gen_df_reg (set_srca, 1);
4373 srcb1 = gen_df_reg (set_srcb, 0);
4374 srcb2 = gen_df_reg (set_srcb, 1);
4376 /* Now emit using the real source and destination we found, swapping
4377 the order if we detect overlap. */
4378 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4379 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4381 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4382 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4386 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4387 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4393 ;;- zero extension instructions
4395 ;; These patterns originally accepted general_operands, however, slightly
4396 ;; better code is generated by only accepting register_operands, and then
4397 ;; letting combine generate the ldu[hb] insns.
4399 (define_expand "zero_extendhisi2"
4400 [(set (match_operand:SI 0 "register_operand" "")
4401 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4405 rtx temp = gen_reg_rtx (SImode);
4406 rtx shift_16 = GEN_INT (16);
4407 int op1_subbyte = 0;
4409 if (GET_CODE (operand1) == SUBREG)
4411 op1_subbyte = SUBREG_BYTE (operand1);
4412 op1_subbyte /= GET_MODE_SIZE (SImode);
4413 op1_subbyte *= GET_MODE_SIZE (SImode);
4414 operand1 = XEXP (operand1, 0);
4417 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4419 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4423 (define_insn "*zero_extendhisi2_insn"
4424 [(set (match_operand:SI 0 "register_operand" "=r")
4425 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4428 [(set_attr "type" "load")])
4430 (define_expand "zero_extendqihi2"
4431 [(set (match_operand:HI 0 "register_operand" "")
4432 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4436 (define_insn "*zero_extendqihi2_insn"
4437 [(set (match_operand:HI 0 "register_operand" "=r,r")
4438 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4439 "GET_CODE (operands[1]) != CONST_INT"
4443 [(set_attr "type" "*,load")])
4445 (define_expand "zero_extendqisi2"
4446 [(set (match_operand:SI 0 "register_operand" "")
4447 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4451 (define_insn "*zero_extendqisi2_insn"
4452 [(set (match_operand:SI 0 "register_operand" "=r,r")
4453 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4454 "GET_CODE (operands[1]) != CONST_INT"
4458 [(set_attr "type" "*,load")])
4460 (define_expand "zero_extendqidi2"
4461 [(set (match_operand:DI 0 "register_operand" "")
4462 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4466 (define_insn "*zero_extendqidi2_insn"
4467 [(set (match_operand:DI 0 "register_operand" "=r,r")
4468 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4469 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4473 [(set_attr "type" "*,load")])
4475 (define_expand "zero_extendhidi2"
4476 [(set (match_operand:DI 0 "register_operand" "")
4477 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4481 rtx temp = gen_reg_rtx (DImode);
4482 rtx shift_48 = GEN_INT (48);
4483 int op1_subbyte = 0;
4485 if (GET_CODE (operand1) == SUBREG)
4487 op1_subbyte = SUBREG_BYTE (operand1);
4488 op1_subbyte /= GET_MODE_SIZE (DImode);
4489 op1_subbyte *= GET_MODE_SIZE (DImode);
4490 operand1 = XEXP (operand1, 0);
4493 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4495 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4499 (define_insn "*zero_extendhidi2_insn"
4500 [(set (match_operand:DI 0 "register_operand" "=r")
4501 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4504 [(set_attr "type" "load")])
4507 ;; ??? Write truncdisi pattern using sra?
4509 (define_expand "zero_extendsidi2"
4510 [(set (match_operand:DI 0 "register_operand" "")
4511 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4515 (define_insn "*zero_extendsidi2_insn_sp64"
4516 [(set (match_operand:DI 0 "register_operand" "=r,r")
4517 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4518 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4522 [(set_attr "type" "shift,load")])
4524 (define_insn "*zero_extendsidi2_insn_sp32"
4525 [(set (match_operand:DI 0 "register_operand" "=r")
4526 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4529 [(set_attr "length" "2")])
4532 [(set (match_operand:DI 0 "register_operand" "")
4533 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4534 "! TARGET_ARCH64 && reload_completed"
4535 [(set (match_dup 2) (match_dup 3))
4536 (set (match_dup 4) (match_dup 5))]
4541 dest1 = gen_highpart (SImode, operands[0]);
4542 dest2 = gen_lowpart (SImode, operands[0]);
4544 /* Swap the order in case of overlap. */
4545 if (REGNO (dest1) == REGNO (operands[1]))
4547 operands[2] = dest2;
4548 operands[3] = operands[1];
4549 operands[4] = dest1;
4550 operands[5] = const0_rtx;
4554 operands[2] = dest1;
4555 operands[3] = const0_rtx;
4556 operands[4] = dest2;
4557 operands[5] = operands[1];
4561 ;; Simplify comparisons of extended values.
4563 (define_insn "*cmp_zero_extendqisi2"
4565 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4568 "andcc\\t%0, 0xff, %%g0"
4569 [(set_attr "type" "compare")])
4571 (define_insn "*cmp_zero_qi"
4573 (compare:CC (match_operand:QI 0 "register_operand" "r")
4576 "andcc\\t%0, 0xff, %%g0"
4577 [(set_attr "type" "compare")])
4579 (define_insn "*cmp_zero_extendqisi2_set"
4581 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4583 (set (match_operand:SI 0 "register_operand" "=r")
4584 (zero_extend:SI (match_dup 1)))]
4586 "andcc\\t%1, 0xff, %0"
4587 [(set_attr "type" "compare")])
4589 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4591 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4594 (set (match_operand:SI 0 "register_operand" "=r")
4595 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4597 "andcc\\t%1, 0xff, %0"
4598 [(set_attr "type" "compare")])
4600 (define_insn "*cmp_zero_extendqidi2"
4602 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4605 "andcc\\t%0, 0xff, %%g0"
4606 [(set_attr "type" "compare")])
4608 (define_insn "*cmp_zero_qi_sp64"
4610 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4613 "andcc\\t%0, 0xff, %%g0"
4614 [(set_attr "type" "compare")])
4616 (define_insn "*cmp_zero_extendqidi2_set"
4618 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4620 (set (match_operand:DI 0 "register_operand" "=r")
4621 (zero_extend:DI (match_dup 1)))]
4623 "andcc\\t%1, 0xff, %0"
4624 [(set_attr "type" "compare")])
4626 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4628 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4631 (set (match_operand:DI 0 "register_operand" "=r")
4632 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4634 "andcc\\t%1, 0xff, %0"
4635 [(set_attr "type" "compare")])
4637 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4639 (define_insn "*cmp_siqi_trunc"
4641 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4644 "andcc\\t%0, 0xff, %%g0"
4645 [(set_attr "type" "compare")])
4647 (define_insn "*cmp_siqi_trunc_set"
4649 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4651 (set (match_operand:QI 0 "register_operand" "=r")
4652 (subreg:QI (match_dup 1) 3))]
4654 "andcc\\t%1, 0xff, %0"
4655 [(set_attr "type" "compare")])
4657 (define_insn "*cmp_diqi_trunc"
4659 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4662 "andcc\\t%0, 0xff, %%g0"
4663 [(set_attr "type" "compare")])
4665 (define_insn "*cmp_diqi_trunc_set"
4667 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4669 (set (match_operand:QI 0 "register_operand" "=r")
4670 (subreg:QI (match_dup 1) 7))]
4672 "andcc\\t%1, 0xff, %0"
4673 [(set_attr "type" "compare")])
4675 ;;- sign extension instructions
4677 ;; These patterns originally accepted general_operands, however, slightly
4678 ;; better code is generated by only accepting register_operands, and then
4679 ;; letting combine generate the lds[hb] insns.
4681 (define_expand "extendhisi2"
4682 [(set (match_operand:SI 0 "register_operand" "")
4683 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4687 rtx temp = gen_reg_rtx (SImode);
4688 rtx shift_16 = GEN_INT (16);
4689 int op1_subbyte = 0;
4691 if (GET_CODE (operand1) == SUBREG)
4693 op1_subbyte = SUBREG_BYTE (operand1);
4694 op1_subbyte /= GET_MODE_SIZE (SImode);
4695 op1_subbyte *= GET_MODE_SIZE (SImode);
4696 operand1 = XEXP (operand1, 0);
4699 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4701 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4705 (define_insn "*sign_extendhisi2_insn"
4706 [(set (match_operand:SI 0 "register_operand" "=r")
4707 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4710 [(set_attr "type" "sload")])
4712 (define_expand "extendqihi2"
4713 [(set (match_operand:HI 0 "register_operand" "")
4714 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4718 rtx temp = gen_reg_rtx (SImode);
4719 rtx shift_24 = GEN_INT (24);
4720 int op1_subbyte = 0;
4721 int op0_subbyte = 0;
4723 if (GET_CODE (operand1) == SUBREG)
4725 op1_subbyte = SUBREG_BYTE (operand1);
4726 op1_subbyte /= GET_MODE_SIZE (SImode);
4727 op1_subbyte *= GET_MODE_SIZE (SImode);
4728 operand1 = XEXP (operand1, 0);
4730 if (GET_CODE (operand0) == SUBREG)
4732 op0_subbyte = SUBREG_BYTE (operand0);
4733 op0_subbyte /= GET_MODE_SIZE (SImode);
4734 op0_subbyte *= GET_MODE_SIZE (SImode);
4735 operand0 = XEXP (operand0, 0);
4737 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4739 if (GET_MODE (operand0) != SImode)
4740 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4741 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4745 (define_insn "*sign_extendqihi2_insn"
4746 [(set (match_operand:HI 0 "register_operand" "=r")
4747 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4750 [(set_attr "type" "sload")])
4752 (define_expand "extendqisi2"
4753 [(set (match_operand:SI 0 "register_operand" "")
4754 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4758 rtx temp = gen_reg_rtx (SImode);
4759 rtx shift_24 = GEN_INT (24);
4760 int op1_subbyte = 0;
4762 if (GET_CODE (operand1) == SUBREG)
4764 op1_subbyte = SUBREG_BYTE (operand1);
4765 op1_subbyte /= GET_MODE_SIZE (SImode);
4766 op1_subbyte *= GET_MODE_SIZE (SImode);
4767 operand1 = XEXP (operand1, 0);
4770 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4772 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4776 (define_insn "*sign_extendqisi2_insn"
4777 [(set (match_operand:SI 0 "register_operand" "=r")
4778 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4781 [(set_attr "type" "sload")])
4783 (define_expand "extendqidi2"
4784 [(set (match_operand:DI 0 "register_operand" "")
4785 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4789 rtx temp = gen_reg_rtx (DImode);
4790 rtx shift_56 = GEN_INT (56);
4791 int op1_subbyte = 0;
4793 if (GET_CODE (operand1) == SUBREG)
4795 op1_subbyte = SUBREG_BYTE (operand1);
4796 op1_subbyte /= GET_MODE_SIZE (DImode);
4797 op1_subbyte *= GET_MODE_SIZE (DImode);
4798 operand1 = XEXP (operand1, 0);
4801 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4803 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4807 (define_insn "*sign_extendqidi2_insn"
4808 [(set (match_operand:DI 0 "register_operand" "=r")
4809 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4812 [(set_attr "type" "sload")])
4814 (define_expand "extendhidi2"
4815 [(set (match_operand:DI 0 "register_operand" "")
4816 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4820 rtx temp = gen_reg_rtx (DImode);
4821 rtx shift_48 = GEN_INT (48);
4822 int op1_subbyte = 0;
4824 if (GET_CODE (operand1) == SUBREG)
4826 op1_subbyte = SUBREG_BYTE (operand1);
4827 op1_subbyte /= GET_MODE_SIZE (DImode);
4828 op1_subbyte *= GET_MODE_SIZE (DImode);
4829 operand1 = XEXP (operand1, 0);
4832 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4834 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4838 (define_insn "*sign_extendhidi2_insn"
4839 [(set (match_operand:DI 0 "register_operand" "=r")
4840 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4843 [(set_attr "type" "sload")])
4845 (define_expand "extendsidi2"
4846 [(set (match_operand:DI 0 "register_operand" "")
4847 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4851 (define_insn "*sign_extendsidi2_insn"
4852 [(set (match_operand:DI 0 "register_operand" "=r,r")
4853 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4858 [(set_attr "type" "shift,sload")])
4860 ;; Special pattern for optimizing bit-field compares. This is needed
4861 ;; because combine uses this as a canonical form.
4863 (define_insn "*cmp_zero_extract"
4866 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4867 (match_operand:SI 1 "small_int_or_double" "n")
4868 (match_operand:SI 2 "small_int_or_double" "n"))
4870 "(GET_CODE (operands[2]) == CONST_INT
4871 && INTVAL (operands[2]) > 19)
4872 || (GET_CODE (operands[2]) == CONST_DOUBLE
4873 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4876 int len = (GET_CODE (operands[1]) == CONST_INT
4877 ? INTVAL (operands[1])
4878 : CONST_DOUBLE_LOW (operands[1]));
4880 (GET_CODE (operands[2]) == CONST_INT
4881 ? INTVAL (operands[2])
4882 : CONST_DOUBLE_LOW (operands[2])) - len;
4883 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4885 operands[1] = GEN_INT (mask);
4886 return \"andcc\\t%0, %1, %%g0\";
4888 [(set_attr "type" "compare")])
4890 (define_insn "*cmp_zero_extract_sp64"
4893 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4894 (match_operand:SI 1 "small_int_or_double" "n")
4895 (match_operand:SI 2 "small_int_or_double" "n"))
4898 && ((GET_CODE (operands[2]) == CONST_INT
4899 && INTVAL (operands[2]) > 51)
4900 || (GET_CODE (operands[2]) == CONST_DOUBLE
4901 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4904 int len = (GET_CODE (operands[1]) == CONST_INT
4905 ? INTVAL (operands[1])
4906 : CONST_DOUBLE_LOW (operands[1]));
4908 (GET_CODE (operands[2]) == CONST_INT
4909 ? INTVAL (operands[2])
4910 : CONST_DOUBLE_LOW (operands[2])) - len;
4911 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4913 operands[1] = GEN_INT (mask);
4914 return \"andcc\\t%0, %1, %%g0\";
4916 [(set_attr "type" "compare")])
4918 ;; Conversions between float, double and long double.
4920 (define_insn "extendsfdf2"
4921 [(set (match_operand:DF 0 "register_operand" "=e")
4923 (match_operand:SF 1 "register_operand" "f")))]
4926 [(set_attr "type" "fp")
4927 (set_attr "fptype" "double")])
4929 (define_expand "extendsftf2"
4930 [(set (match_operand:TF 0 "register_operand" "=e")
4932 (match_operand:SF 1 "register_operand" "f")))]
4933 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4936 if (! TARGET_HARD_QUAD)
4940 if (GET_CODE (operands[0]) != MEM)
4941 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4943 slot0 = operands[0];
4945 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4947 XEXP (slot0, 0), Pmode,
4948 operands[1], SFmode);
4950 if (GET_CODE (operands[0]) != MEM)
4951 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4956 (define_insn "*extendsftf2_hq"
4957 [(set (match_operand:TF 0 "register_operand" "=e")
4959 (match_operand:SF 1 "register_operand" "f")))]
4960 "TARGET_FPU && TARGET_HARD_QUAD"
4962 [(set_attr "type" "fp")])
4964 (define_expand "extenddftf2"
4965 [(set (match_operand:TF 0 "register_operand" "=e")
4967 (match_operand:DF 1 "register_operand" "e")))]
4968 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4971 if (! TARGET_HARD_QUAD)
4975 if (GET_CODE (operands[0]) != MEM)
4976 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4978 slot0 = operands[0];
4980 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
4982 XEXP (slot0, 0), Pmode,
4983 operands[1], DFmode);
4985 if (GET_CODE (operands[0]) != MEM)
4986 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4991 (define_insn "*extenddftf2_hq"
4992 [(set (match_operand:TF 0 "register_operand" "=e")
4994 (match_operand:DF 1 "register_operand" "e")))]
4995 "TARGET_FPU && TARGET_HARD_QUAD"
4997 [(set_attr "type" "fp")])
4999 (define_insn "truncdfsf2"
5000 [(set (match_operand:SF 0 "register_operand" "=f")
5002 (match_operand:DF 1 "register_operand" "e")))]
5005 [(set_attr "type" "fp")
5006 (set_attr "fptype" "double")])
5008 (define_expand "trunctfsf2"
5009 [(set (match_operand:SF 0 "register_operand" "=f")
5011 (match_operand:TF 1 "register_operand" "e")))]
5012 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5015 if (! TARGET_HARD_QUAD)
5019 if (GET_CODE (operands[1]) != MEM)
5021 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5022 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5025 slot0 = operands[1];
5027 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5028 operands[0], 0, SFmode, 1,
5029 XEXP (slot0, 0), Pmode);
5034 (define_insn "*trunctfsf2_hq"
5035 [(set (match_operand:SF 0 "register_operand" "=f")
5037 (match_operand:TF 1 "register_operand" "e")))]
5038 "TARGET_FPU && TARGET_HARD_QUAD"
5040 [(set_attr "type" "fp")])
5042 (define_expand "trunctfdf2"
5043 [(set (match_operand:DF 0 "register_operand" "=f")
5045 (match_operand:TF 1 "register_operand" "e")))]
5046 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5049 if (! TARGET_HARD_QUAD)
5053 if (GET_CODE (operands[1]) != MEM)
5055 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5056 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5059 slot0 = operands[1];
5061 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5062 operands[0], 0, DFmode, 1,
5063 XEXP (slot0, 0), Pmode);
5068 (define_insn "*trunctfdf2_hq"
5069 [(set (match_operand:DF 0 "register_operand" "=e")
5071 (match_operand:TF 1 "register_operand" "e")))]
5072 "TARGET_FPU && TARGET_HARD_QUAD"
5074 [(set_attr "type" "fp")])
5076 ;; Conversion between fixed point and floating point.
5078 (define_insn "floatsisf2"
5079 [(set (match_operand:SF 0 "register_operand" "=f")
5080 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5083 [(set_attr "type" "fp")
5084 (set_attr "fptype" "double")])
5086 (define_insn "floatsidf2"
5087 [(set (match_operand:DF 0 "register_operand" "=e")
5088 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5091 [(set_attr "type" "fp")
5092 (set_attr "fptype" "double")])
5094 (define_expand "floatsitf2"
5095 [(set (match_operand:TF 0 "register_operand" "=e")
5096 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5097 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5100 if (! TARGET_HARD_QUAD)
5104 if (GET_CODE (operands[1]) != MEM)
5105 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5107 slot0 = operands[1];
5109 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5111 XEXP (slot0, 0), Pmode,
5112 operands[1], SImode);
5114 if (GET_CODE (operands[0]) != MEM)
5115 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5120 (define_insn "*floatsitf2_hq"
5121 [(set (match_operand:TF 0 "register_operand" "=e")
5122 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5123 "TARGET_FPU && TARGET_HARD_QUAD"
5125 [(set_attr "type" "fp")])
5127 (define_expand "floatunssitf2"
5128 [(set (match_operand:TF 0 "register_operand" "=e")
5129 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5130 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5135 if (GET_CODE (operands[1]) != MEM)
5136 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5138 slot0 = operands[1];
5140 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5142 XEXP (slot0, 0), Pmode,
5143 operands[1], SImode);
5145 if (GET_CODE (operands[0]) != MEM)
5146 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5150 ;; Now the same for 64 bit sources.
5152 (define_insn "floatdisf2"
5153 [(set (match_operand:SF 0 "register_operand" "=f")
5154 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5155 "TARGET_V9 && TARGET_FPU"
5157 [(set_attr "type" "fp")
5158 (set_attr "fptype" "double")])
5160 (define_insn "floatdidf2"
5161 [(set (match_operand:DF 0 "register_operand" "=e")
5162 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5163 "TARGET_V9 && TARGET_FPU"
5165 [(set_attr "type" "fp")
5166 (set_attr "fptype" "double")])
5168 (define_expand "floatditf2"
5169 [(set (match_operand:TF 0 "register_operand" "=e")
5170 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5171 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5174 if (! TARGET_HARD_QUAD)
5178 if (GET_CODE (operands[1]) != MEM)
5179 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5181 slot0 = operands[1];
5183 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5185 XEXP (slot0, 0), Pmode,
5186 operands[1], DImode);
5188 if (GET_CODE (operands[0]) != MEM)
5189 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5194 (define_insn "*floatditf2_hq"
5195 [(set (match_operand:TF 0 "register_operand" "=e")
5196 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5197 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5199 [(set_attr "type" "fp")])
5201 (define_expand "floatunsditf2"
5202 [(set (match_operand:TF 0 "register_operand" "=e")
5203 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5204 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5209 if (GET_CODE (operands[1]) != MEM)
5210 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5212 slot0 = operands[1];
5214 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5216 XEXP (slot0, 0), Pmode,
5217 operands[1], DImode);
5219 if (GET_CODE (operands[0]) != MEM)
5220 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5224 ;; Convert a float to an actual integer.
5225 ;; Truncation is performed as part of the conversion.
5227 (define_insn "fix_truncsfsi2"
5228 [(set (match_operand:SI 0 "register_operand" "=f")
5229 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5232 [(set_attr "type" "fp")
5233 (set_attr "fptype" "double")])
5235 (define_insn "fix_truncdfsi2"
5236 [(set (match_operand:SI 0 "register_operand" "=f")
5237 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5240 [(set_attr "type" "fp")
5241 (set_attr "fptype" "double")])
5243 (define_expand "fix_trunctfsi2"
5244 [(set (match_operand:SI 0 "register_operand" "=f")
5245 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5246 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5249 if (! TARGET_HARD_QUAD)
5253 if (GET_CODE (operands[1]) != MEM)
5255 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5256 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5259 slot0 = operands[1];
5261 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5262 operands[0], 0, SImode, 1,
5263 XEXP (slot0, 0), Pmode);
5268 (define_insn "*fix_trunctfsi2_hq"
5269 [(set (match_operand:SI 0 "register_operand" "=f")
5270 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5271 "TARGET_FPU && TARGET_HARD_QUAD"
5273 [(set_attr "type" "fp")])
5275 (define_expand "fixuns_trunctfsi2"
5276 [(set (match_operand:SI 0 "register_operand" "=f")
5277 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5278 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5283 if (GET_CODE (operands[1]) != MEM)
5285 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5286 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5289 slot0 = operands[1];
5291 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5292 operands[0], 0, SImode, 1,
5293 XEXP (slot0, 0), Pmode);
5297 ;; Now the same, for V9 targets
5299 (define_insn "fix_truncsfdi2"
5300 [(set (match_operand:DI 0 "register_operand" "=e")
5301 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5302 "TARGET_V9 && TARGET_FPU"
5304 [(set_attr "type" "fp")
5305 (set_attr "fptype" "double")])
5307 (define_insn "fix_truncdfdi2"
5308 [(set (match_operand:DI 0 "register_operand" "=e")
5309 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5310 "TARGET_V9 && TARGET_FPU"
5312 [(set_attr "type" "fp")
5313 (set_attr "fptype" "double")])
5315 (define_expand "fix_trunctfdi2"
5316 [(set (match_operand:DI 0 "register_operand" "=e")
5317 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5318 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5321 if (! TARGET_HARD_QUAD)
5325 if (GET_CODE (operands[1]) != MEM)
5327 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5328 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5331 slot0 = operands[1];
5333 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5334 operands[0], 0, DImode, 1,
5335 XEXP (slot0, 0), Pmode);
5340 (define_insn "*fix_trunctfdi2_hq"
5341 [(set (match_operand:DI 0 "register_operand" "=e")
5342 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5343 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5345 [(set_attr "type" "fp")])
5347 (define_expand "fixuns_trunctfdi2"
5348 [(set (match_operand:DI 0 "register_operand" "=f")
5349 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5350 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5355 if (GET_CODE (operands[1]) != MEM)
5357 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5358 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5361 slot0 = operands[1];
5363 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5364 operands[0], 0, DImode, 1,
5365 XEXP (slot0, 0), Pmode);
5370 ;;- arithmetic instructions
5372 (define_expand "adddi3"
5373 [(set (match_operand:DI 0 "register_operand" "=r")
5374 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5375 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5381 if (! TARGET_ARCH64)
5383 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5384 gen_rtx_SET (VOIDmode, operands[0],
5385 gen_rtx_PLUS (DImode, operands[1],
5387 gen_rtx_CLOBBER (VOIDmode,
5388 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5391 if (arith_double_4096_operand(operands[2], DImode))
5393 switch (GET_CODE (operands[1]))
5395 case CONST_INT: i = INTVAL (operands[1]); break;
5396 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5398 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5399 gen_rtx_MINUS (DImode, operands[1],
5403 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5408 (define_insn "adddi3_insn_sp32"
5409 [(set (match_operand:DI 0 "register_operand" "=r")
5410 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5411 (match_operand:DI 2 "arith_double_operand" "rHI")))
5412 (clobber (reg:CC 100))]
5415 [(set_attr "length" "2")])
5418 [(set (match_operand:DI 0 "register_operand" "")
5419 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5420 (match_operand:DI 2 "arith_double_operand" "")))
5421 (clobber (reg:CC 100))]
5422 "! TARGET_ARCH64 && reload_completed"
5423 [(parallel [(set (reg:CC_NOOV 100)
5424 (compare:CC_NOOV (plus:SI (match_dup 4)
5428 (plus:SI (match_dup 4) (match_dup 5)))])
5430 (plus:SI (plus:SI (match_dup 7)
5432 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5435 operands[3] = gen_lowpart (SImode, operands[0]);
5436 operands[4] = gen_lowpart (SImode, operands[1]);
5437 operands[5] = gen_lowpart (SImode, operands[2]);
5438 operands[6] = gen_highpart (SImode, operands[0]);
5439 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5440 #if HOST_BITS_PER_WIDE_INT == 32
5441 if (GET_CODE (operands[2]) == CONST_INT)
5443 if (INTVAL (operands[2]) < 0)
5444 operands[8] = constm1_rtx;
5446 operands[8] = const0_rtx;
5450 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5454 [(set (match_operand:DI 0 "register_operand" "")
5455 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5456 (match_operand:DI 2 "arith_double_operand" "")))
5457 (clobber (reg:CC 100))]
5458 "! TARGET_ARCH64 && reload_completed"
5459 [(parallel [(set (reg:CC_NOOV 100)
5460 (compare:CC_NOOV (minus:SI (match_dup 4)
5464 (minus:SI (match_dup 4) (match_dup 5)))])
5466 (minus:SI (minus:SI (match_dup 7)
5468 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5471 operands[3] = gen_lowpart (SImode, operands[0]);
5472 operands[4] = gen_lowpart (SImode, operands[1]);
5473 operands[5] = gen_lowpart (SImode, operands[2]);
5474 operands[6] = gen_highpart (SImode, operands[0]);
5475 operands[7] = gen_highpart (SImode, operands[1]);
5476 #if HOST_BITS_PER_WIDE_INT == 32
5477 if (GET_CODE (operands[2]) == CONST_INT)
5479 if (INTVAL (operands[2]) < 0)
5480 operands[8] = constm1_rtx;
5482 operands[8] = const0_rtx;
5486 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5489 ;; LTU here means "carry set"
5491 [(set (match_operand:SI 0 "register_operand" "=r")
5492 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5493 (match_operand:SI 2 "arith_operand" "rI"))
5494 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5497 [(set_attr "type" "misc")])
5499 (define_insn "*addx_extend_sp32"
5500 [(set (match_operand:DI 0 "register_operand" "=r")
5501 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5502 (match_operand:SI 2 "arith_operand" "rI"))
5503 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5506 [(set_attr "length" "2")])
5509 [(set (match_operand:DI 0 "register_operand" "")
5510 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5511 (match_operand:SI 2 "arith_operand" ""))
5512 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5513 "! TARGET_ARCH64 && reload_completed"
5514 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5515 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5516 (set (match_dup 4) (const_int 0))]
5517 "operands[3] = gen_lowpart (SImode, operands[0]);
5518 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5520 (define_insn "*addx_extend_sp64"
5521 [(set (match_operand:DI 0 "register_operand" "=r")
5522 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5523 (match_operand:SI 2 "arith_operand" "rI"))
5524 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5526 "addx\\t%r1, %2, %0"
5527 [(set_attr "type" "misc")])
5530 [(set (match_operand:SI 0 "register_operand" "=r")
5531 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5532 (match_operand:SI 2 "arith_operand" "rI"))
5533 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5535 "subx\\t%r1, %2, %0"
5536 [(set_attr "type" "misc")])
5538 (define_insn "*subx_extend_sp64"
5539 [(set (match_operand:DI 0 "register_operand" "=r")
5540 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5541 (match_operand:SI 2 "arith_operand" "rI"))
5542 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5544 "subx\\t%r1, %2, %0"
5545 [(set_attr "type" "misc")])
5547 (define_insn "*subx_extend"
5548 [(set (match_operand:DI 0 "register_operand" "=r")
5549 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5550 (match_operand:SI 2 "arith_operand" "rI"))
5551 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5554 [(set_attr "length" "2")])
5557 [(set (match_operand:DI 0 "register_operand" "")
5558 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5559 (match_operand:SI 2 "arith_operand" ""))
5560 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5561 "! TARGET_ARCH64 && reload_completed"
5562 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5563 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5564 (set (match_dup 4) (const_int 0))]
5565 "operands[3] = gen_lowpart (SImode, operands[0]);
5566 operands[4] = gen_highpart (SImode, operands[0]);")
5569 [(set (match_operand:DI 0 "register_operand" "=r")
5570 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5571 (match_operand:DI 2 "register_operand" "r")))
5572 (clobber (reg:CC 100))]
5575 [(set_attr "length" "2")])
5578 [(set (match_operand:DI 0 "register_operand" "")
5579 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5580 (match_operand:DI 2 "register_operand" "")))
5581 (clobber (reg:CC 100))]
5582 "! TARGET_ARCH64 && reload_completed"
5583 [(parallel [(set (reg:CC_NOOV 100)
5584 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5586 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5588 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5589 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5590 "operands[3] = gen_lowpart (SImode, operands[2]);
5591 operands[4] = gen_highpart (SImode, operands[2]);
5592 operands[5] = gen_lowpart (SImode, operands[0]);
5593 operands[6] = gen_highpart (SImode, operands[0]);")
5595 (define_insn "*adddi3_sp64"
5596 [(set (match_operand:DI 0 "register_operand" "=r")
5597 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5598 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5602 (define_expand "addsi3"
5603 [(set (match_operand:SI 0 "register_operand" "=r,d")
5604 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5605 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5609 if (arith_4096_operand(operands[2], SImode))
5611 if (GET_CODE (operands[1]) == CONST_INT)
5612 emit_insn (gen_movsi (operands[0],
5613 GEN_INT (INTVAL (operands[1]) + 4096)));
5615 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5616 gen_rtx_MINUS (SImode, operands[1],
5622 (define_insn "*addsi3"
5623 [(set (match_operand:SI 0 "register_operand" "=r,d")
5624 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5625 (match_operand:SI 2 "arith_operand" "rI,d")))]
5629 fpadd32s\\t%1, %2, %0"
5630 [(set_attr "type" "*,fp")])
5632 (define_insn "*cmp_cc_plus"
5633 [(set (reg:CC_NOOV 100)
5634 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5635 (match_operand:SI 1 "arith_operand" "rI"))
5638 "addcc\\t%0, %1, %%g0"
5639 [(set_attr "type" "compare")])
5641 (define_insn "*cmp_ccx_plus"
5642 [(set (reg:CCX_NOOV 100)
5643 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5644 (match_operand:DI 1 "arith_double_operand" "rHI"))
5647 "addcc\\t%0, %1, %%g0"
5648 [(set_attr "type" "compare")])
5650 (define_insn "*cmp_cc_plus_set"
5651 [(set (reg:CC_NOOV 100)
5652 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5653 (match_operand:SI 2 "arith_operand" "rI"))
5655 (set (match_operand:SI 0 "register_operand" "=r")
5656 (plus:SI (match_dup 1) (match_dup 2)))]
5658 "addcc\\t%1, %2, %0"
5659 [(set_attr "type" "compare")])
5661 (define_insn "*cmp_ccx_plus_set"
5662 [(set (reg:CCX_NOOV 100)
5663 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5664 (match_operand:DI 2 "arith_double_operand" "rHI"))
5666 (set (match_operand:DI 0 "register_operand" "=r")
5667 (plus:DI (match_dup 1) (match_dup 2)))]
5669 "addcc\\t%1, %2, %0"
5670 [(set_attr "type" "compare")])
5672 (define_expand "subdi3"
5673 [(set (match_operand:DI 0 "register_operand" "=r")
5674 (minus:DI (match_operand:DI 1 "register_operand" "r")
5675 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5679 if (! TARGET_ARCH64)
5681 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5682 gen_rtx_SET (VOIDmode, operands[0],
5683 gen_rtx_MINUS (DImode, operands[1],
5685 gen_rtx_CLOBBER (VOIDmode,
5686 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5689 if (arith_double_4096_operand(operands[2], DImode))
5691 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5692 gen_rtx_PLUS (DImode, operands[1],
5698 (define_insn "*subdi3_sp32"
5699 [(set (match_operand:DI 0 "register_operand" "=r")
5700 (minus:DI (match_operand:DI 1 "register_operand" "r")
5701 (match_operand:DI 2 "arith_double_operand" "rHI")))
5702 (clobber (reg:CC 100))]
5705 [(set_attr "length" "2")])
5708 [(set (match_operand:DI 0 "register_operand" "")
5709 (minus:DI (match_operand:DI 1 "register_operand" "")
5710 (match_operand:DI 2 "arith_double_operand" "")))
5711 (clobber (reg:CC 100))]
5714 && (GET_CODE (operands[2]) == CONST_INT
5715 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5716 [(clobber (const_int 0))]
5721 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5722 lowp = gen_lowpart (SImode, operands[2]);
5723 if ((lowp == const0_rtx)
5724 && (operands[0] == operands[1]))
5726 emit_insn (gen_rtx_SET (VOIDmode,
5727 gen_highpart (SImode, operands[0]),
5728 gen_rtx_MINUS (SImode,
5729 gen_highpart_mode (SImode, DImode,
5735 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5736 gen_lowpart (SImode, operands[1]),
5738 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5739 gen_highpart_mode (SImode, DImode, operands[1]),
5746 [(set (match_operand:DI 0 "register_operand" "")
5747 (minus:DI (match_operand:DI 1 "register_operand" "")
5748 (match_operand:DI 2 "register_operand" "")))
5749 (clobber (reg:CC 100))]
5751 && reload_completed"
5752 [(clobber (const_int 0))]
5755 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5756 gen_lowpart (SImode, operands[1]),
5757 gen_lowpart (SImode, operands[2])));
5758 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5759 gen_highpart (SImode, operands[1]),
5760 gen_highpart (SImode, operands[2])));
5765 [(set (match_operand:DI 0 "register_operand" "=r")
5766 (minus:DI (match_operand:DI 1 "register_operand" "r")
5767 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5768 (clobber (reg:CC 100))]
5771 [(set_attr "length" "2")])
5774 [(set (match_operand:DI 0 "register_operand" "")
5775 (minus:DI (match_operand:DI 1 "register_operand" "")
5776 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5777 (clobber (reg:CC 100))]
5778 "! TARGET_ARCH64 && reload_completed"
5779 [(parallel [(set (reg:CC_NOOV 100)
5780 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5782 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5784 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5785 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5786 "operands[3] = gen_lowpart (SImode, operands[1]);
5787 operands[4] = gen_highpart (SImode, operands[1]);
5788 operands[5] = gen_lowpart (SImode, operands[0]);
5789 operands[6] = gen_highpart (SImode, operands[0]);")
5791 (define_insn "*subdi3_sp64"
5792 [(set (match_operand:DI 0 "register_operand" "=r")
5793 (minus:DI (match_operand:DI 1 "register_operand" "r")
5794 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5798 (define_expand "subsi3"
5799 [(set (match_operand:SI 0 "register_operand" "=r,d")
5800 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5801 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5805 if (arith_4096_operand(operands[2], SImode))
5807 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5808 gen_rtx_PLUS (SImode, operands[1],
5814 (define_insn "*subsi3"
5815 [(set (match_operand:SI 0 "register_operand" "=r,d")
5816 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5817 (match_operand:SI 2 "arith_operand" "rI,d")))]
5821 fpsub32s\\t%1, %2, %0"
5822 [(set_attr "type" "*,fp")])
5824 (define_insn "*cmp_minus_cc"
5825 [(set (reg:CC_NOOV 100)
5826 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5827 (match_operand:SI 1 "arith_operand" "rI"))
5830 "subcc\\t%r0, %1, %%g0"
5831 [(set_attr "type" "compare")])
5833 (define_insn "*cmp_minus_ccx"
5834 [(set (reg:CCX_NOOV 100)
5835 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5836 (match_operand:DI 1 "arith_double_operand" "rHI"))
5839 "subcc\\t%0, %1, %%g0"
5840 [(set_attr "type" "compare")])
5842 (define_insn "cmp_minus_cc_set"
5843 [(set (reg:CC_NOOV 100)
5844 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5845 (match_operand:SI 2 "arith_operand" "rI"))
5847 (set (match_operand:SI 0 "register_operand" "=r")
5848 (minus:SI (match_dup 1) (match_dup 2)))]
5850 "subcc\\t%r1, %2, %0"
5851 [(set_attr "type" "compare")])
5853 (define_insn "*cmp_minus_ccx_set"
5854 [(set (reg:CCX_NOOV 100)
5855 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5856 (match_operand:DI 2 "arith_double_operand" "rHI"))
5858 (set (match_operand:DI 0 "register_operand" "=r")
5859 (minus:DI (match_dup 1) (match_dup 2)))]
5861 "subcc\\t%1, %2, %0"
5862 [(set_attr "type" "compare")])
5864 ;; Integer Multiply/Divide.
5866 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5867 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5869 (define_insn "mulsi3"
5870 [(set (match_operand:SI 0 "register_operand" "=r")
5871 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5872 (match_operand:SI 2 "arith_operand" "rI")))]
5875 [(set_attr "type" "imul")])
5877 (define_expand "muldi3"
5878 [(set (match_operand:DI 0 "register_operand" "=r")
5879 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5880 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5881 "TARGET_ARCH64 || TARGET_V8PLUS"
5886 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5891 (define_insn "*muldi3_sp64"
5892 [(set (match_operand:DI 0 "register_operand" "=r")
5893 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5894 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5897 [(set_attr "type" "imul")])
5899 ;; V8plus wide multiply.
5901 (define_insn "muldi3_v8plus"
5902 [(set (match_operand:DI 0 "register_operand" "=r,h")
5903 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5904 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5905 (clobber (match_scratch:SI 3 "=&h,X"))
5906 (clobber (match_scratch:SI 4 "=&h,X"))]
5910 if (sparc_check_64 (operands[1], insn) <= 0)
5911 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5912 if (which_alternative == 1)
5913 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5914 if (GET_CODE (operands[2]) == CONST_INT)
5916 if (which_alternative == 1)
5917 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5919 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\";
5921 if (sparc_check_64 (operands[2], insn) <= 0)
5922 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5923 if (which_alternative == 1)
5924 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\";
5926 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\";
5928 [(set_attr "type" "multi")
5929 (set_attr "length" "9,8")])
5931 (define_insn "*cmp_mul_set"
5933 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5934 (match_operand:SI 2 "arith_operand" "rI"))
5936 (set (match_operand:SI 0 "register_operand" "=r")
5937 (mult:SI (match_dup 1) (match_dup 2)))]
5938 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5939 "smulcc\\t%1, %2, %0"
5940 [(set_attr "type" "imul")])
5942 (define_expand "mulsidi3"
5943 [(set (match_operand:DI 0 "register_operand" "")
5944 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5945 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5949 if (CONSTANT_P (operands[2]))
5952 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5955 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5961 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5966 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5967 ;; registers can hold 64 bit values in the V8plus environment.
5969 (define_insn "mulsidi3_v8plus"
5970 [(set (match_operand:DI 0 "register_operand" "=h,r")
5971 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5972 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5973 (clobber (match_scratch:SI 3 "=X,&h"))]
5976 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5977 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5978 [(set_attr "type" "multi")
5979 (set_attr "length" "2,3")])
5982 (define_insn "const_mulsidi3_v8plus"
5983 [(set (match_operand:DI 0 "register_operand" "=h,r")
5984 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5985 (match_operand:SI 2 "small_int" "I,I")))
5986 (clobber (match_scratch:SI 3 "=X,&h"))]
5989 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5990 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5991 [(set_attr "type" "multi")
5992 (set_attr "length" "2,3")])
5995 (define_insn "*mulsidi3_sp32"
5996 [(set (match_operand:DI 0 "register_operand" "=r")
5997 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5998 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6002 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6005 (if_then_else (eq_attr "isa" "sparclet")
6006 (const_string "imul") (const_string "multi")))
6007 (set (attr "length")
6008 (if_then_else (eq_attr "isa" "sparclet")
6009 (const_int 1) (const_int 2)))])
6011 (define_insn "*mulsidi3_sp64"
6012 [(set (match_operand:DI 0 "register_operand" "=r")
6013 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6014 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6015 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6017 [(set_attr "type" "imul")])
6019 ;; Extra pattern, because sign_extend of a constant isn't valid.
6022 (define_insn "const_mulsidi3_sp32"
6023 [(set (match_operand:DI 0 "register_operand" "=r")
6024 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6025 (match_operand:SI 2 "small_int" "I")))]
6029 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6032 (if_then_else (eq_attr "isa" "sparclet")
6033 (const_string "imul") (const_string "multi")))
6034 (set (attr "length")
6035 (if_then_else (eq_attr "isa" "sparclet")
6036 (const_int 1) (const_int 2)))])
6038 (define_insn "const_mulsidi3_sp64"
6039 [(set (match_operand:DI 0 "register_operand" "=r")
6040 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6041 (match_operand:SI 2 "small_int" "I")))]
6042 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6044 [(set_attr "type" "imul")])
6046 (define_expand "smulsi3_highpart"
6047 [(set (match_operand:SI 0 "register_operand" "")
6049 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6050 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6052 "TARGET_HARD_MUL && TARGET_ARCH32"
6055 if (CONSTANT_P (operands[2]))
6059 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6065 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6070 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6071 operands[2], GEN_INT (32)));
6077 (define_insn "smulsi3_highpart_v8plus"
6078 [(set (match_operand:SI 0 "register_operand" "=h,r")
6080 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6081 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6082 (match_operand:SI 3 "const_int_operand" "i,i"))))
6083 (clobber (match_scratch:SI 4 "=X,&h"))]
6086 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6087 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6088 [(set_attr "type" "multi")
6089 (set_attr "length" "2")])
6091 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6094 [(set (match_operand:SI 0 "register_operand" "=h,r")
6097 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6098 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6099 (match_operand:SI 3 "const_int_operand" "i,i"))
6101 (clobber (match_scratch:SI 4 "=X,&h"))]
6104 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6105 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6106 [(set_attr "type" "multi")
6107 (set_attr "length" "2")])
6110 (define_insn "const_smulsi3_highpart_v8plus"
6111 [(set (match_operand:SI 0 "register_operand" "=h,r")
6113 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6114 (match_operand 2 "small_int" "i,i"))
6115 (match_operand:SI 3 "const_int_operand" "i,i"))))
6116 (clobber (match_scratch:SI 4 "=X,&h"))]
6119 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6120 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6121 [(set_attr "type" "multi")
6122 (set_attr "length" "2")])
6125 (define_insn "*smulsi3_highpart_sp32"
6126 [(set (match_operand:SI 0 "register_operand" "=r")
6128 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6129 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6132 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6133 [(set_attr "type" "multi")
6134 (set_attr "length" "2")])
6137 (define_insn "const_smulsi3_highpart"
6138 [(set (match_operand:SI 0 "register_operand" "=r")
6140 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6141 (match_operand:SI 2 "register_operand" "r"))
6144 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6145 [(set_attr "type" "multi")
6146 (set_attr "length" "2")])
6148 (define_expand "umulsidi3"
6149 [(set (match_operand:DI 0 "register_operand" "")
6150 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6151 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6155 if (CONSTANT_P (operands[2]))
6158 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6161 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6167 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6173 (define_insn "umulsidi3_v8plus"
6174 [(set (match_operand:DI 0 "register_operand" "=h,r")
6175 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6176 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6177 (clobber (match_scratch:SI 3 "=X,&h"))]
6180 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6181 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6182 [(set_attr "type" "multi")
6183 (set_attr "length" "2,3")])
6186 (define_insn "*umulsidi3_sp32"
6187 [(set (match_operand:DI 0 "register_operand" "=r")
6188 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6189 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6193 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6196 (if_then_else (eq_attr "isa" "sparclet")
6197 (const_string "imul") (const_string "multi")))
6198 (set (attr "length")
6199 (if_then_else (eq_attr "isa" "sparclet")
6200 (const_int 1) (const_int 2)))])
6202 (define_insn "*umulsidi3_sp64"
6203 [(set (match_operand:DI 0 "register_operand" "=r")
6204 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6205 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6206 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6208 [(set_attr "type" "imul")])
6210 ;; Extra pattern, because sign_extend of a constant isn't valid.
6213 (define_insn "const_umulsidi3_sp32"
6214 [(set (match_operand:DI 0 "register_operand" "=r")
6215 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6216 (match_operand:SI 2 "uns_small_int" "")))]
6220 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6223 (if_then_else (eq_attr "isa" "sparclet")
6224 (const_string "imul") (const_string "multi")))
6225 (set (attr "length")
6226 (if_then_else (eq_attr "isa" "sparclet")
6227 (const_int 1) (const_int 2)))])
6229 (define_insn "const_umulsidi3_sp64"
6230 [(set (match_operand:DI 0 "register_operand" "=r")
6231 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6232 (match_operand:SI 2 "uns_small_int" "")))]
6233 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6235 [(set_attr "type" "imul")])
6238 (define_insn "const_umulsidi3_v8plus"
6239 [(set (match_operand:DI 0 "register_operand" "=h,r")
6240 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6241 (match_operand:SI 2 "uns_small_int" "")))
6242 (clobber (match_scratch:SI 3 "=X,h"))]
6245 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6246 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6247 [(set_attr "type" "multi")
6248 (set_attr "length" "2,3")])
6250 (define_expand "umulsi3_highpart"
6251 [(set (match_operand:SI 0 "register_operand" "")
6253 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6254 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6256 "TARGET_HARD_MUL && TARGET_ARCH32"
6259 if (CONSTANT_P (operands[2]))
6263 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6269 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6274 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6275 operands[2], GEN_INT (32)));
6281 (define_insn "umulsi3_highpart_v8plus"
6282 [(set (match_operand:SI 0 "register_operand" "=h,r")
6284 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6285 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6286 (match_operand:SI 3 "const_int_operand" "i,i"))))
6287 (clobber (match_scratch:SI 4 "=X,h"))]
6290 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6291 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6292 [(set_attr "type" "multi")
6293 (set_attr "length" "2")])
6296 (define_insn "const_umulsi3_highpart_v8plus"
6297 [(set (match_operand:SI 0 "register_operand" "=h,r")
6299 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6300 (match_operand:SI 2 "uns_small_int" ""))
6301 (match_operand:SI 3 "const_int_operand" "i,i"))))
6302 (clobber (match_scratch:SI 4 "=X,h"))]
6305 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6306 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6307 [(set_attr "type" "multi")
6308 (set_attr "length" "2")])
6311 (define_insn "*umulsi3_highpart_sp32"
6312 [(set (match_operand:SI 0 "register_operand" "=r")
6314 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6315 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6318 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6319 [(set_attr "type" "multi")
6320 (set_attr "length" "2")])
6323 (define_insn "const_umulsi3_highpart"
6324 [(set (match_operand:SI 0 "register_operand" "=r")
6326 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6327 (match_operand:SI 2 "uns_small_int" ""))
6330 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6331 [(set_attr "type" "multi")
6332 (set_attr "length" "2")])
6334 ;; The v8 architecture specifies that there must be 3 instructions between
6335 ;; a y register write and a use of it for correct results.
6337 (define_expand "divsi3"
6338 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6339 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6340 (match_operand:SI 2 "input_operand" "rI,m")))
6341 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6342 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6347 operands[3] = gen_reg_rtx(SImode);
6348 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6349 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6355 (define_insn "divsi3_sp32"
6356 [(set (match_operand:SI 0 "register_operand" "=r,r")
6357 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6358 (match_operand:SI 2 "input_operand" "rI,m")))
6359 (clobber (match_scratch:SI 3 "=&r,&r"))]
6360 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6364 if (which_alternative == 0)
6366 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6368 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6371 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6373 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\";
6375 [(set_attr "type" "multi")
6376 (set (attr "length")
6377 (if_then_else (eq_attr "isa" "v9")
6378 (const_int 4) (const_int 7)))])
6380 (define_insn "divsi3_sp64"
6381 [(set (match_operand:SI 0 "register_operand" "=r")
6382 (div:SI (match_operand:SI 1 "register_operand" "r")
6383 (match_operand:SI 2 "input_operand" "rI")))
6384 (use (match_operand:SI 3 "register_operand" "r"))]
6385 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6386 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6387 [(set_attr "type" "multi")
6388 (set_attr "length" "2")])
6390 (define_insn "divdi3"
6391 [(set (match_operand:DI 0 "register_operand" "=r")
6392 (div:DI (match_operand:DI 1 "register_operand" "r")
6393 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6395 "sdivx\\t%1, %2, %0"
6396 [(set_attr "type" "idiv")])
6398 (define_insn "*cmp_sdiv_cc_set"
6400 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6401 (match_operand:SI 2 "arith_operand" "rI"))
6403 (set (match_operand:SI 0 "register_operand" "=r")
6404 (div:SI (match_dup 1) (match_dup 2)))
6405 (clobber (match_scratch:SI 3 "=&r"))]
6406 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6410 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6412 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6414 [(set_attr "type" "multi")
6415 (set (attr "length")
6416 (if_then_else (eq_attr "isa" "v9")
6417 (const_int 3) (const_int 6)))])
6420 (define_expand "udivsi3"
6421 [(set (match_operand:SI 0 "register_operand" "")
6422 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6423 (match_operand:SI 2 "input_operand" "")))]
6424 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6427 (define_insn "udivsi3_sp32"
6428 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6429 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6430 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6432 || TARGET_DEPRECATED_V8_INSNS)
6436 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6437 switch (which_alternative)
6440 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6442 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6444 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6447 [(set_attr "type" "multi")
6448 (set_attr "length" "5")])
6450 (define_insn "udivsi3_sp64"
6451 [(set (match_operand:SI 0 "register_operand" "=r")
6452 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6453 (match_operand:SI 2 "input_operand" "rI")))]
6454 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6455 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6456 [(set_attr "type" "multi")
6457 (set_attr "length" "2")])
6459 (define_insn "udivdi3"
6460 [(set (match_operand:DI 0 "register_operand" "=r")
6461 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6462 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6464 "udivx\\t%1, %2, %0"
6465 [(set_attr "type" "idiv")])
6467 (define_insn "*cmp_udiv_cc_set"
6469 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6470 (match_operand:SI 2 "arith_operand" "rI"))
6472 (set (match_operand:SI 0 "register_operand" "=r")
6473 (udiv:SI (match_dup 1) (match_dup 2)))]
6475 || TARGET_DEPRECATED_V8_INSNS"
6479 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6481 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6483 [(set_attr "type" "multi")
6484 (set (attr "length")
6485 (if_then_else (eq_attr "isa" "v9")
6486 (const_int 2) (const_int 5)))])
6488 ; sparclet multiply/accumulate insns
6490 (define_insn "*smacsi"
6491 [(set (match_operand:SI 0 "register_operand" "=r")
6492 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6493 (match_operand:SI 2 "arith_operand" "rI"))
6494 (match_operand:SI 3 "register_operand" "0")))]
6497 [(set_attr "type" "imul")])
6499 (define_insn "*smacdi"
6500 [(set (match_operand:DI 0 "register_operand" "=r")
6501 (plus:DI (mult:DI (sign_extend:DI
6502 (match_operand:SI 1 "register_operand" "%r"))
6504 (match_operand:SI 2 "register_operand" "r")))
6505 (match_operand:DI 3 "register_operand" "0")))]
6507 "smacd\\t%1, %2, %L0"
6508 [(set_attr "type" "imul")])
6510 (define_insn "*umacdi"
6511 [(set (match_operand:DI 0 "register_operand" "=r")
6512 (plus:DI (mult:DI (zero_extend:DI
6513 (match_operand:SI 1 "register_operand" "%r"))
6515 (match_operand:SI 2 "register_operand" "r")))
6516 (match_operand:DI 3 "register_operand" "0")))]
6518 "umacd\\t%1, %2, %L0"
6519 [(set_attr "type" "imul")])
6521 ;;- Boolean instructions
6522 ;; We define DImode `and' so with DImode `not' we can get
6523 ;; DImode `andn'. Other combinations are possible.
6525 (define_expand "anddi3"
6526 [(set (match_operand:DI 0 "register_operand" "")
6527 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6528 (match_operand:DI 2 "arith_double_operand" "")))]
6532 (define_insn "*anddi3_sp32"
6533 [(set (match_operand:DI 0 "register_operand" "=r,b")
6534 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6535 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6540 [(set_attr "type" "*,fp")
6541 (set_attr "length" "2,*")
6542 (set_attr "fptype" "double")])
6544 (define_insn "*anddi3_sp64"
6545 [(set (match_operand:DI 0 "register_operand" "=r,b")
6546 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6547 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6552 [(set_attr "type" "*,fp")
6553 (set_attr "fptype" "double")])
6555 (define_insn "andsi3"
6556 [(set (match_operand:SI 0 "register_operand" "=r,d")
6557 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6558 (match_operand:SI 2 "arith_operand" "rI,d")))]
6563 [(set_attr "type" "*,fp")])
6566 [(set (match_operand:SI 0 "register_operand" "")
6567 (and:SI (match_operand:SI 1 "register_operand" "")
6568 (match_operand:SI 2 "" "")))
6569 (clobber (match_operand:SI 3 "register_operand" ""))]
6570 "GET_CODE (operands[2]) == CONST_INT
6571 && !SMALL_INT32 (operands[2])
6572 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6573 [(set (match_dup 3) (match_dup 4))
6574 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6577 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6580 ;; Split DImode logical operations requiring two instructions.
6582 [(set (match_operand:DI 0 "register_operand" "")
6583 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6584 [(match_operand:DI 2 "register_operand" "")
6585 (match_operand:DI 3 "arith_double_operand" "")]))]
6588 && ((GET_CODE (operands[0]) == REG
6589 && REGNO (operands[0]) < 32)
6590 || (GET_CODE (operands[0]) == SUBREG
6591 && GET_CODE (SUBREG_REG (operands[0])) == REG
6592 && REGNO (SUBREG_REG (operands[0])) < 32))"
6593 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6594 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6597 operands[4] = gen_highpart (SImode, operands[0]);
6598 operands[5] = gen_lowpart (SImode, operands[0]);
6599 operands[6] = gen_highpart (SImode, operands[2]);
6600 operands[7] = gen_lowpart (SImode, operands[2]);
6601 #if HOST_BITS_PER_WIDE_INT == 32
6602 if (GET_CODE (operands[3]) == CONST_INT)
6604 if (INTVAL (operands[3]) < 0)
6605 operands[8] = constm1_rtx;
6607 operands[8] = const0_rtx;
6611 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6612 operands[9] = gen_lowpart (SImode, operands[3]);
6615 (define_insn "*and_not_di_sp32"
6616 [(set (match_operand:DI 0 "register_operand" "=r,b")
6617 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6618 (match_operand:DI 2 "register_operand" "r,b")))]
6622 fandnot1\\t%1, %2, %0"
6623 [(set_attr "type" "*,fp")
6624 (set_attr "length" "2,*")
6625 (set_attr "fptype" "double")])
6628 [(set (match_operand:DI 0 "register_operand" "")
6629 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6630 (match_operand:DI 2 "register_operand" "")))]
6633 && ((GET_CODE (operands[0]) == REG
6634 && REGNO (operands[0]) < 32)
6635 || (GET_CODE (operands[0]) == SUBREG
6636 && GET_CODE (SUBREG_REG (operands[0])) == REG
6637 && REGNO (SUBREG_REG (operands[0])) < 32))"
6638 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6639 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6640 "operands[3] = gen_highpart (SImode, operands[0]);
6641 operands[4] = gen_highpart (SImode, operands[1]);
6642 operands[5] = gen_highpart (SImode, operands[2]);
6643 operands[6] = gen_lowpart (SImode, operands[0]);
6644 operands[7] = gen_lowpart (SImode, operands[1]);
6645 operands[8] = gen_lowpart (SImode, operands[2]);")
6647 (define_insn "*and_not_di_sp64"
6648 [(set (match_operand:DI 0 "register_operand" "=r,b")
6649 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6650 (match_operand:DI 2 "register_operand" "r,b")))]
6654 fandnot1\\t%1, %2, %0"
6655 [(set_attr "type" "*,fp")
6656 (set_attr "fptype" "double")])
6658 (define_insn "*and_not_si"
6659 [(set (match_operand:SI 0 "register_operand" "=r,d")
6660 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6661 (match_operand:SI 2 "register_operand" "r,d")))]
6665 fandnot1s\\t%1, %2, %0"
6666 [(set_attr "type" "*,fp")])
6668 (define_expand "iordi3"
6669 [(set (match_operand:DI 0 "register_operand" "")
6670 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6671 (match_operand:DI 2 "arith_double_operand" "")))]
6675 (define_insn "*iordi3_sp32"
6676 [(set (match_operand:DI 0 "register_operand" "=r,b")
6677 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6678 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6683 [(set_attr "type" "*,fp")
6684 (set_attr "length" "2,*")
6685 (set_attr "fptype" "double")])
6687 (define_insn "*iordi3_sp64"
6688 [(set (match_operand:DI 0 "register_operand" "=r,b")
6689 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6690 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6695 [(set_attr "type" "*,fp")
6696 (set_attr "fptype" "double")])
6698 (define_insn "iorsi3"
6699 [(set (match_operand:SI 0 "register_operand" "=r,d")
6700 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6701 (match_operand:SI 2 "arith_operand" "rI,d")))]
6706 [(set_attr "type" "*,fp")])
6709 [(set (match_operand:SI 0 "register_operand" "")
6710 (ior:SI (match_operand:SI 1 "register_operand" "")
6711 (match_operand:SI 2 "" "")))
6712 (clobber (match_operand:SI 3 "register_operand" ""))]
6713 "GET_CODE (operands[2]) == CONST_INT
6714 && !SMALL_INT32 (operands[2])
6715 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6716 [(set (match_dup 3) (match_dup 4))
6717 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6720 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6723 (define_insn "*or_not_di_sp32"
6724 [(set (match_operand:DI 0 "register_operand" "=r,b")
6725 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6726 (match_operand:DI 2 "register_operand" "r,b")))]
6730 fornot1\\t%1, %2, %0"
6731 [(set_attr "type" "*,fp")
6732 (set_attr "length" "2,*")
6733 (set_attr "fptype" "double")])
6736 [(set (match_operand:DI 0 "register_operand" "")
6737 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6738 (match_operand:DI 2 "register_operand" "")))]
6741 && ((GET_CODE (operands[0]) == REG
6742 && REGNO (operands[0]) < 32)
6743 || (GET_CODE (operands[0]) == SUBREG
6744 && GET_CODE (SUBREG_REG (operands[0])) == REG
6745 && REGNO (SUBREG_REG (operands[0])) < 32))"
6746 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6747 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6748 "operands[3] = gen_highpart (SImode, operands[0]);
6749 operands[4] = gen_highpart (SImode, operands[1]);
6750 operands[5] = gen_highpart (SImode, operands[2]);
6751 operands[6] = gen_lowpart (SImode, operands[0]);
6752 operands[7] = gen_lowpart (SImode, operands[1]);
6753 operands[8] = gen_lowpart (SImode, operands[2]);")
6755 (define_insn "*or_not_di_sp64"
6756 [(set (match_operand:DI 0 "register_operand" "=r,b")
6757 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6758 (match_operand:DI 2 "register_operand" "r,b")))]
6762 fornot1\\t%1, %2, %0"
6763 [(set_attr "type" "*,fp")
6764 (set_attr "fptype" "double")])
6766 (define_insn "*or_not_si"
6767 [(set (match_operand:SI 0 "register_operand" "=r,d")
6768 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6769 (match_operand:SI 2 "register_operand" "r,d")))]
6773 fornot1s\\t%1, %2, %0"
6774 [(set_attr "type" "*,fp")])
6776 (define_expand "xordi3"
6777 [(set (match_operand:DI 0 "register_operand" "")
6778 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6779 (match_operand:DI 2 "arith_double_operand" "")))]
6783 (define_insn "*xordi3_sp32"
6784 [(set (match_operand:DI 0 "register_operand" "=r,b")
6785 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6786 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6791 [(set_attr "type" "*,fp")
6792 (set_attr "length" "2,*")
6793 (set_attr "fptype" "double")])
6795 (define_insn "*xordi3_sp64"
6796 [(set (match_operand:DI 0 "register_operand" "=r,b")
6797 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6798 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6803 [(set_attr "type" "*,fp")
6804 (set_attr "fptype" "double")])
6806 (define_insn "*xordi3_sp64_dbl"
6807 [(set (match_operand:DI 0 "register_operand" "=r")
6808 (xor:DI (match_operand:DI 1 "register_operand" "r")
6809 (match_operand:DI 2 "const64_operand" "")))]
6811 && HOST_BITS_PER_WIDE_INT != 64)"
6814 (define_insn "xorsi3"
6815 [(set (match_operand:SI 0 "register_operand" "=r,d")
6816 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6817 (match_operand:SI 2 "arith_operand" "rI,d")))]
6822 [(set_attr "type" "*,fp")])
6825 [(set (match_operand:SI 0 "register_operand" "")
6826 (xor:SI (match_operand:SI 1 "register_operand" "")
6827 (match_operand:SI 2 "" "")))
6828 (clobber (match_operand:SI 3 "register_operand" ""))]
6829 "GET_CODE (operands[2]) == CONST_INT
6830 && !SMALL_INT32 (operands[2])
6831 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6832 [(set (match_dup 3) (match_dup 4))
6833 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6836 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6840 [(set (match_operand:SI 0 "register_operand" "")
6841 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6842 (match_operand:SI 2 "" ""))))
6843 (clobber (match_operand:SI 3 "register_operand" ""))]
6844 "GET_CODE (operands[2]) == CONST_INT
6845 && !SMALL_INT32 (operands[2])
6846 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6847 [(set (match_dup 3) (match_dup 4))
6848 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6851 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6854 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6855 ;; Combine now canonicalizes to the rightmost expression.
6856 (define_insn "*xor_not_di_sp32"
6857 [(set (match_operand:DI 0 "register_operand" "=r,b")
6858 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6859 (match_operand:DI 2 "register_operand" "r,b"))))]
6864 [(set_attr "type" "*,fp")
6865 (set_attr "length" "2,*")
6866 (set_attr "fptype" "double")])
6869 [(set (match_operand:DI 0 "register_operand" "")
6870 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6871 (match_operand:DI 2 "register_operand" ""))))]
6874 && ((GET_CODE (operands[0]) == REG
6875 && REGNO (operands[0]) < 32)
6876 || (GET_CODE (operands[0]) == SUBREG
6877 && GET_CODE (SUBREG_REG (operands[0])) == REG
6878 && REGNO (SUBREG_REG (operands[0])) < 32))"
6879 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6880 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6881 "operands[3] = gen_highpart (SImode, operands[0]);
6882 operands[4] = gen_highpart (SImode, operands[1]);
6883 operands[5] = gen_highpart (SImode, operands[2]);
6884 operands[6] = gen_lowpart (SImode, operands[0]);
6885 operands[7] = gen_lowpart (SImode, operands[1]);
6886 operands[8] = gen_lowpart (SImode, operands[2]);")
6888 (define_insn "*xor_not_di_sp64"
6889 [(set (match_operand:DI 0 "register_operand" "=r,b")
6890 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6891 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6896 [(set_attr "type" "*,fp")
6897 (set_attr "fptype" "double")])
6899 (define_insn "*xor_not_si"
6900 [(set (match_operand:SI 0 "register_operand" "=r,d")
6901 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6902 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6906 fxnors\\t%1, %2, %0"
6907 [(set_attr "type" "*,fp")])
6909 ;; These correspond to the above in the case where we also (or only)
6910 ;; want to set the condition code.
6912 (define_insn "*cmp_cc_arith_op"
6915 (match_operator:SI 2 "cc_arithop"
6916 [(match_operand:SI 0 "arith_operand" "%r")
6917 (match_operand:SI 1 "arith_operand" "rI")])
6920 "%A2cc\\t%0, %1, %%g0"
6921 [(set_attr "type" "compare")])
6923 (define_insn "*cmp_ccx_arith_op"
6926 (match_operator:DI 2 "cc_arithop"
6927 [(match_operand:DI 0 "arith_double_operand" "%r")
6928 (match_operand:DI 1 "arith_double_operand" "rHI")])
6931 "%A2cc\\t%0, %1, %%g0"
6932 [(set_attr "type" "compare")])
6934 (define_insn "*cmp_cc_arith_op_set"
6937 (match_operator:SI 3 "cc_arithop"
6938 [(match_operand:SI 1 "arith_operand" "%r")
6939 (match_operand:SI 2 "arith_operand" "rI")])
6941 (set (match_operand:SI 0 "register_operand" "=r")
6942 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6943 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6944 "%A3cc\\t%1, %2, %0"
6945 [(set_attr "type" "compare")])
6947 (define_insn "*cmp_ccx_arith_op_set"
6950 (match_operator:DI 3 "cc_arithop"
6951 [(match_operand:DI 1 "arith_double_operand" "%r")
6952 (match_operand:DI 2 "arith_double_operand" "rHI")])
6954 (set (match_operand:DI 0 "register_operand" "=r")
6955 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6956 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6957 "%A3cc\\t%1, %2, %0"
6958 [(set_attr "type" "compare")])
6960 (define_insn "*cmp_cc_xor_not"
6963 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6964 (match_operand:SI 1 "arith_operand" "rI")))
6967 "xnorcc\\t%r0, %1, %%g0"
6968 [(set_attr "type" "compare")])
6970 (define_insn "*cmp_ccx_xor_not"
6973 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6974 (match_operand:DI 1 "arith_double_operand" "rHI")))
6977 "xnorcc\\t%r0, %1, %%g0"
6978 [(set_attr "type" "compare")])
6980 (define_insn "*cmp_cc_xor_not_set"
6983 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6984 (match_operand:SI 2 "arith_operand" "rI")))
6986 (set (match_operand:SI 0 "register_operand" "=r")
6987 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6989 "xnorcc\\t%r1, %2, %0"
6990 [(set_attr "type" "compare")])
6992 (define_insn "*cmp_ccx_xor_not_set"
6995 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6996 (match_operand:DI 2 "arith_double_operand" "rHI")))
6998 (set (match_operand:DI 0 "register_operand" "=r")
6999 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7001 "xnorcc\\t%r1, %2, %0"
7002 [(set_attr "type" "compare")])
7004 (define_insn "*cmp_cc_arith_op_not"
7007 (match_operator:SI 2 "cc_arithopn"
7008 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7009 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7012 "%B2cc\\t%r1, %0, %%g0"
7013 [(set_attr "type" "compare")])
7015 (define_insn "*cmp_ccx_arith_op_not"
7018 (match_operator:DI 2 "cc_arithopn"
7019 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7020 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7023 "%B2cc\\t%r1, %0, %%g0"
7024 [(set_attr "type" "compare")])
7026 (define_insn "*cmp_cc_arith_op_not_set"
7029 (match_operator:SI 3 "cc_arithopn"
7030 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7031 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7033 (set (match_operand:SI 0 "register_operand" "=r")
7034 (match_operator:SI 4 "cc_arithopn"
7035 [(not:SI (match_dup 1)) (match_dup 2)]))]
7036 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7037 "%B3cc\\t%r2, %1, %0"
7038 [(set_attr "type" "compare")])
7040 (define_insn "*cmp_ccx_arith_op_not_set"
7043 (match_operator:DI 3 "cc_arithopn"
7044 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7045 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7047 (set (match_operand:DI 0 "register_operand" "=r")
7048 (match_operator:DI 4 "cc_arithopn"
7049 [(not:DI (match_dup 1)) (match_dup 2)]))]
7050 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7051 "%B3cc\\t%r2, %1, %0"
7052 [(set_attr "type" "compare")])
7054 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7055 ;; does not know how to make it work for constants.
7057 (define_expand "negdi2"
7058 [(set (match_operand:DI 0 "register_operand" "=r")
7059 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7063 if (! TARGET_ARCH64)
7065 emit_insn (gen_rtx_PARALLEL
7068 gen_rtx_SET (VOIDmode, operand0,
7069 gen_rtx_NEG (DImode, operand1)),
7070 gen_rtx_CLOBBER (VOIDmode,
7071 gen_rtx_REG (CCmode,
7077 (define_insn "*negdi2_sp32"
7078 [(set (match_operand:DI 0 "register_operand" "=r")
7079 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7080 (clobber (reg:CC 100))]
7083 [(set_attr "length" "2")])
7086 [(set (match_operand:DI 0 "register_operand" "")
7087 (neg:DI (match_operand:DI 1 "register_operand" "")))
7088 (clobber (reg:CC 100))]
7090 && reload_completed"
7091 [(parallel [(set (reg:CC_NOOV 100)
7092 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7094 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7095 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7096 (ltu:SI (reg:CC 100) (const_int 0))))]
7097 "operands[2] = gen_highpart (SImode, operands[0]);
7098 operands[3] = gen_highpart (SImode, operands[1]);
7099 operands[4] = gen_lowpart (SImode, operands[0]);
7100 operands[5] = gen_lowpart (SImode, operands[1]);")
7102 (define_insn "*negdi2_sp64"
7103 [(set (match_operand:DI 0 "register_operand" "=r")
7104 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7106 "sub\\t%%g0, %1, %0")
7108 (define_insn "negsi2"
7109 [(set (match_operand:SI 0 "register_operand" "=r")
7110 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7112 "sub\\t%%g0, %1, %0")
7114 (define_insn "*cmp_cc_neg"
7115 [(set (reg:CC_NOOV 100)
7116 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7119 "subcc\\t%%g0, %0, %%g0"
7120 [(set_attr "type" "compare")])
7122 (define_insn "*cmp_ccx_neg"
7123 [(set (reg:CCX_NOOV 100)
7124 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7127 "subcc\\t%%g0, %0, %%g0"
7128 [(set_attr "type" "compare")])
7130 (define_insn "*cmp_cc_set_neg"
7131 [(set (reg:CC_NOOV 100)
7132 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7134 (set (match_operand:SI 0 "register_operand" "=r")
7135 (neg:SI (match_dup 1)))]
7137 "subcc\\t%%g0, %1, %0"
7138 [(set_attr "type" "compare")])
7140 (define_insn "*cmp_ccx_set_neg"
7141 [(set (reg:CCX_NOOV 100)
7142 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7144 (set (match_operand:DI 0 "register_operand" "=r")
7145 (neg:DI (match_dup 1)))]
7147 "subcc\\t%%g0, %1, %0"
7148 [(set_attr "type" "compare")])
7150 ;; We cannot use the "not" pseudo insn because the Sun assembler
7151 ;; does not know how to make it work for constants.
7152 (define_expand "one_cmpldi2"
7153 [(set (match_operand:DI 0 "register_operand" "")
7154 (not:DI (match_operand:DI 1 "register_operand" "")))]
7158 (define_insn "*one_cmpldi2_sp32"
7159 [(set (match_operand:DI 0 "register_operand" "=r,b")
7160 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7165 [(set_attr "type" "*,fp")
7166 (set_attr "length" "2,*")
7167 (set_attr "fptype" "double")])
7170 [(set (match_operand:DI 0 "register_operand" "")
7171 (not:DI (match_operand:DI 1 "register_operand" "")))]
7174 && ((GET_CODE (operands[0]) == REG
7175 && REGNO (operands[0]) < 32)
7176 || (GET_CODE (operands[0]) == SUBREG
7177 && GET_CODE (SUBREG_REG (operands[0])) == REG
7178 && REGNO (SUBREG_REG (operands[0])) < 32))"
7179 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7180 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7181 "operands[2] = gen_highpart (SImode, operands[0]);
7182 operands[3] = gen_highpart (SImode, operands[1]);
7183 operands[4] = gen_lowpart (SImode, operands[0]);
7184 operands[5] = gen_lowpart (SImode, operands[1]);")
7186 (define_insn "*one_cmpldi2_sp64"
7187 [(set (match_operand:DI 0 "register_operand" "=r,b")
7188 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7193 [(set_attr "type" "*,fp")
7194 (set_attr "fptype" "double")])
7196 (define_insn "one_cmplsi2"
7197 [(set (match_operand:SI 0 "register_operand" "=r,d")
7198 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7203 [(set_attr "type" "*,fp")])
7205 (define_insn "*cmp_cc_not"
7207 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7210 "xnorcc\\t%%g0, %0, %%g0"
7211 [(set_attr "type" "compare")])
7213 (define_insn "*cmp_ccx_not"
7215 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7218 "xnorcc\\t%%g0, %0, %%g0"
7219 [(set_attr "type" "compare")])
7221 (define_insn "*cmp_cc_set_not"
7223 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7225 (set (match_operand:SI 0 "register_operand" "=r")
7226 (not:SI (match_dup 1)))]
7228 "xnorcc\\t%%g0, %1, %0"
7229 [(set_attr "type" "compare")])
7231 (define_insn "*cmp_ccx_set_not"
7233 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7235 (set (match_operand:DI 0 "register_operand" "=r")
7236 (not:DI (match_dup 1)))]
7238 "xnorcc\\t%%g0, %1, %0"
7239 [(set_attr "type" "compare")])
7241 (define_insn "*cmp_cc_set"
7242 [(set (match_operand:SI 0 "register_operand" "=r")
7243 (match_operand:SI 1 "register_operand" "r"))
7245 (compare:CC (match_dup 1)
7249 [(set_attr "type" "compare")])
7251 (define_insn "*cmp_ccx_set64"
7252 [(set (match_operand:DI 0 "register_operand" "=r")
7253 (match_operand:DI 1 "register_operand" "r"))
7255 (compare:CCX (match_dup 1)
7259 [(set_attr "type" "compare")])
7261 ;; Floating point arithmetic instructions.
7263 (define_expand "addtf3"
7264 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7265 (plus:TF (match_operand:TF 1 "general_operand" "")
7266 (match_operand:TF 2 "general_operand" "")))]
7267 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7270 if (! TARGET_HARD_QUAD)
7272 rtx slot0, slot1, slot2;
7274 if (GET_CODE (operands[0]) != MEM)
7275 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7277 slot0 = operands[0];
7278 if (GET_CODE (operands[1]) != MEM)
7280 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7281 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7284 slot1 = operands[1];
7285 if (GET_CODE (operands[2]) != MEM)
7287 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7288 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7291 slot2 = operands[2];
7293 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7295 XEXP (slot0, 0), Pmode,
7296 XEXP (slot1, 0), Pmode,
7297 XEXP (slot2, 0), Pmode);
7299 if (GET_CODE (operands[0]) != MEM)
7300 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7305 (define_insn "*addtf3_hq"
7306 [(set (match_operand:TF 0 "register_operand" "=e")
7307 (plus:TF (match_operand:TF 1 "register_operand" "e")
7308 (match_operand:TF 2 "register_operand" "e")))]
7309 "TARGET_FPU && TARGET_HARD_QUAD"
7310 "faddq\\t%1, %2, %0"
7311 [(set_attr "type" "fp")])
7313 (define_insn "adddf3"
7314 [(set (match_operand:DF 0 "register_operand" "=e")
7315 (plus:DF (match_operand:DF 1 "register_operand" "e")
7316 (match_operand:DF 2 "register_operand" "e")))]
7318 "faddd\\t%1, %2, %0"
7319 [(set_attr "type" "fp")
7320 (set_attr "fptype" "double")])
7322 (define_insn "addsf3"
7323 [(set (match_operand:SF 0 "register_operand" "=f")
7324 (plus:SF (match_operand:SF 1 "register_operand" "f")
7325 (match_operand:SF 2 "register_operand" "f")))]
7327 "fadds\\t%1, %2, %0"
7328 [(set_attr "type" "fp")])
7330 (define_expand "subtf3"
7331 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7332 (minus:TF (match_operand:TF 1 "general_operand" "")
7333 (match_operand:TF 2 "general_operand" "")))]
7334 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7337 if (! TARGET_HARD_QUAD)
7339 rtx slot0, slot1, slot2;
7341 if (GET_CODE (operands[0]) != MEM)
7342 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7344 slot0 = operands[0];
7345 if (GET_CODE (operands[1]) != MEM)
7347 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7348 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7351 slot1 = operands[1];
7352 if (GET_CODE (operands[2]) != MEM)
7354 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7355 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7358 slot2 = operands[2];
7360 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7362 XEXP (slot0, 0), Pmode,
7363 XEXP (slot1, 0), Pmode,
7364 XEXP (slot2, 0), Pmode);
7366 if (GET_CODE (operands[0]) != MEM)
7367 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7372 (define_insn "*subtf3_hq"
7373 [(set (match_operand:TF 0 "register_operand" "=e")
7374 (minus:TF (match_operand:TF 1 "register_operand" "e")
7375 (match_operand:TF 2 "register_operand" "e")))]
7376 "TARGET_FPU && TARGET_HARD_QUAD"
7377 "fsubq\\t%1, %2, %0"
7378 [(set_attr "type" "fp")])
7380 (define_insn "subdf3"
7381 [(set (match_operand:DF 0 "register_operand" "=e")
7382 (minus:DF (match_operand:DF 1 "register_operand" "e")
7383 (match_operand:DF 2 "register_operand" "e")))]
7385 "fsubd\\t%1, %2, %0"
7386 [(set_attr "type" "fp")
7387 (set_attr "fptype" "double")])
7389 (define_insn "subsf3"
7390 [(set (match_operand:SF 0 "register_operand" "=f")
7391 (minus:SF (match_operand:SF 1 "register_operand" "f")
7392 (match_operand:SF 2 "register_operand" "f")))]
7394 "fsubs\\t%1, %2, %0"
7395 [(set_attr "type" "fp")])
7397 (define_expand "multf3"
7398 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7399 (mult:TF (match_operand:TF 1 "general_operand" "")
7400 (match_operand:TF 2 "general_operand" "")))]
7401 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7404 if (! TARGET_HARD_QUAD)
7406 rtx slot0, slot1, slot2;
7408 if (GET_CODE (operands[0]) != MEM)
7409 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7411 slot0 = operands[0];
7412 if (GET_CODE (operands[1]) != MEM)
7414 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7415 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7418 slot1 = operands[1];
7419 if (GET_CODE (operands[2]) != MEM)
7421 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7422 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7425 slot2 = operands[2];
7427 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7429 XEXP (slot0, 0), Pmode,
7430 XEXP (slot1, 0), Pmode,
7431 XEXP (slot2, 0), Pmode);
7433 if (GET_CODE (operands[0]) != MEM)
7434 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7439 (define_insn "*multf3_hq"
7440 [(set (match_operand:TF 0 "register_operand" "=e")
7441 (mult:TF (match_operand:TF 1 "register_operand" "e")
7442 (match_operand:TF 2 "register_operand" "e")))]
7443 "TARGET_FPU && TARGET_HARD_QUAD"
7444 "fmulq\\t%1, %2, %0"
7445 [(set_attr "type" "fpmul")])
7447 (define_insn "muldf3"
7448 [(set (match_operand:DF 0 "register_operand" "=e")
7449 (mult:DF (match_operand:DF 1 "register_operand" "e")
7450 (match_operand:DF 2 "register_operand" "e")))]
7452 "fmuld\\t%1, %2, %0"
7453 [(set_attr "type" "fpmul")
7454 (set_attr "fptype" "double")])
7456 (define_insn "mulsf3"
7457 [(set (match_operand:SF 0 "register_operand" "=f")
7458 (mult:SF (match_operand:SF 1 "register_operand" "f")
7459 (match_operand:SF 2 "register_operand" "f")))]
7461 "fmuls\\t%1, %2, %0"
7462 [(set_attr "type" "fpmul")])
7464 (define_insn "*muldf3_extend"
7465 [(set (match_operand:DF 0 "register_operand" "=e")
7466 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7467 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7468 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7469 "fsmuld\\t%1, %2, %0"
7470 [(set_attr "type" "fpmul")
7471 (set_attr "fptype" "double")])
7473 (define_insn "*multf3_extend"
7474 [(set (match_operand:TF 0 "register_operand" "=e")
7475 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7476 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7477 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7478 "fdmulq\\t%1, %2, %0"
7479 [(set_attr "type" "fpmul")])
7481 (define_expand "divtf3"
7482 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7483 (div:TF (match_operand:TF 1 "general_operand" "")
7484 (match_operand:TF 2 "general_operand" "")))]
7485 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7488 if (! TARGET_HARD_QUAD)
7490 rtx slot0, slot1, slot2;
7492 if (GET_CODE (operands[0]) != MEM)
7493 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7495 slot0 = operands[0];
7496 if (GET_CODE (operands[1]) != MEM)
7498 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7499 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7502 slot1 = operands[1];
7503 if (GET_CODE (operands[2]) != MEM)
7505 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7506 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7509 slot2 = operands[2];
7511 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7513 XEXP (slot0, 0), Pmode,
7514 XEXP (slot1, 0), Pmode,
7515 XEXP (slot2, 0), Pmode);
7517 if (GET_CODE (operands[0]) != MEM)
7518 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7523 ;; don't have timing for quad-prec. divide.
7524 (define_insn "*divtf3_hq"
7525 [(set (match_operand:TF 0 "register_operand" "=e")
7526 (div:TF (match_operand:TF 1 "register_operand" "e")
7527 (match_operand:TF 2 "register_operand" "e")))]
7528 "TARGET_FPU && TARGET_HARD_QUAD"
7529 "fdivq\\t%1, %2, %0"
7530 [(set_attr "type" "fpdivd")])
7532 (define_insn "divdf3"
7533 [(set (match_operand:DF 0 "register_operand" "=e")
7534 (div:DF (match_operand:DF 1 "register_operand" "e")
7535 (match_operand:DF 2 "register_operand" "e")))]
7537 "fdivd\\t%1, %2, %0"
7538 [(set_attr "type" "fpdivd")
7539 (set_attr "fptype" "double")])
7541 (define_insn "divsf3"
7542 [(set (match_operand:SF 0 "register_operand" "=f")
7543 (div:SF (match_operand:SF 1 "register_operand" "f")
7544 (match_operand:SF 2 "register_operand" "f")))]
7546 "fdivs\\t%1, %2, %0"
7547 [(set_attr "type" "fpdivs")])
7549 (define_expand "negtf2"
7550 [(set (match_operand:TF 0 "register_operand" "=e,e")
7551 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7555 (define_insn "*negtf2_notv9"
7556 [(set (match_operand:TF 0 "register_operand" "=e,e")
7557 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7558 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7564 [(set_attr "type" "fpmove,*")
7565 (set_attr "length" "*,2")])
7568 [(set (match_operand:TF 0 "register_operand" "")
7569 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7573 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7574 [(set (match_dup 2) (neg:SF (match_dup 3)))
7575 (set (match_dup 4) (match_dup 5))
7576 (set (match_dup 6) (match_dup 7))]
7577 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7578 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7579 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7580 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7581 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7582 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7584 (define_insn "*negtf2_v9"
7585 [(set (match_operand:TF 0 "register_operand" "=e,e")
7586 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7587 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7588 "TARGET_FPU && TARGET_V9"
7592 [(set_attr "type" "fpmove,*")
7593 (set_attr "length" "*,2")
7594 (set_attr "fptype" "double")])
7597 [(set (match_operand:TF 0 "register_operand" "")
7598 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7602 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7603 [(set (match_dup 2) (neg:DF (match_dup 3)))
7604 (set (match_dup 4) (match_dup 5))]
7605 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7606 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7607 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7608 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7610 (define_expand "negdf2"
7611 [(set (match_operand:DF 0 "register_operand" "")
7612 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7616 (define_insn "*negdf2_notv9"
7617 [(set (match_operand:DF 0 "register_operand" "=e,e")
7618 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7619 "TARGET_FPU && ! TARGET_V9"
7623 [(set_attr "type" "fpmove,*")
7624 (set_attr "length" "*,2")])
7627 [(set (match_operand:DF 0 "register_operand" "")
7628 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7632 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7633 [(set (match_dup 2) (neg:SF (match_dup 3)))
7634 (set (match_dup 4) (match_dup 5))]
7635 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7636 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7637 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7638 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7640 (define_insn "*negdf2_v9"
7641 [(set (match_operand:DF 0 "register_operand" "=e")
7642 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7643 "TARGET_FPU && TARGET_V9"
7645 [(set_attr "type" "fpmove")
7646 (set_attr "fptype" "double")])
7648 (define_insn "negsf2"
7649 [(set (match_operand:SF 0 "register_operand" "=f")
7650 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7653 [(set_attr "type" "fpmove")])
7655 (define_expand "abstf2"
7656 [(set (match_operand:TF 0 "register_operand" "")
7657 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7661 (define_insn "*abstf2_notv9"
7662 [(set (match_operand:TF 0 "register_operand" "=e,e")
7663 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7664 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7665 "TARGET_FPU && ! TARGET_V9"
7669 [(set_attr "type" "fpmove,*")
7670 (set_attr "length" "*,2")])
7673 [(set (match_operand:TF 0 "register_operand" "")
7674 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7678 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7679 [(set (match_dup 2) (abs:SF (match_dup 3)))
7680 (set (match_dup 4) (match_dup 5))
7681 (set (match_dup 6) (match_dup 7))]
7682 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7683 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7684 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7685 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7686 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7687 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7689 (define_insn "*abstf2_hq_v9"
7690 [(set (match_operand:TF 0 "register_operand" "=e,e")
7691 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7692 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7696 [(set_attr "type" "fpmove")
7697 (set_attr "fptype" "double,*")])
7699 (define_insn "*abstf2_v9"
7700 [(set (match_operand:TF 0 "register_operand" "=e,e")
7701 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7702 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7706 [(set_attr "type" "fpmove,*")
7707 (set_attr "length" "*,2")
7708 (set_attr "fptype" "double,*")])
7711 [(set (match_operand:TF 0 "register_operand" "")
7712 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7716 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7717 [(set (match_dup 2) (abs:DF (match_dup 3)))
7718 (set (match_dup 4) (match_dup 5))]
7719 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7720 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7721 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7722 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7724 (define_expand "absdf2"
7725 [(set (match_operand:DF 0 "register_operand" "")
7726 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7730 (define_insn "*absdf2_notv9"
7731 [(set (match_operand:DF 0 "register_operand" "=e,e")
7732 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7733 "TARGET_FPU && ! TARGET_V9"
7737 [(set_attr "type" "fpmove,*")
7738 (set_attr "length" "*,2")])
7741 [(set (match_operand:DF 0 "register_operand" "")
7742 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7746 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7747 [(set (match_dup 2) (abs:SF (match_dup 3)))
7748 (set (match_dup 4) (match_dup 5))]
7749 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7750 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7751 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7752 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7754 (define_insn "*absdf2_v9"
7755 [(set (match_operand:DF 0 "register_operand" "=e")
7756 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7757 "TARGET_FPU && TARGET_V9"
7759 [(set_attr "type" "fpmove")
7760 (set_attr "fptype" "double")])
7762 (define_insn "abssf2"
7763 [(set (match_operand:SF 0 "register_operand" "=f")
7764 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7767 [(set_attr "type" "fpmove")])
7769 (define_expand "sqrttf2"
7770 [(set (match_operand:TF 0 "register_operand" "=e")
7771 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7772 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7775 if (! TARGET_HARD_QUAD)
7779 if (GET_CODE (operands[0]) != MEM)
7780 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7782 slot0 = operands[0];
7783 if (GET_CODE (operands[1]) != MEM)
7785 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7786 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7789 slot1 = operands[1];
7791 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7793 XEXP (slot0, 0), Pmode,
7794 XEXP (slot1, 0), Pmode);
7796 if (GET_CODE (operands[0]) != MEM)
7797 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7802 (define_insn "*sqrttf2_hq"
7803 [(set (match_operand:TF 0 "register_operand" "=e")
7804 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7805 "TARGET_FPU && TARGET_HARD_QUAD"
7807 [(set_attr "type" "fpsqrtd")])
7809 (define_insn "sqrtdf2"
7810 [(set (match_operand:DF 0 "register_operand" "=e")
7811 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7814 [(set_attr "type" "fpsqrtd")
7815 (set_attr "fptype" "double")])
7817 (define_insn "sqrtsf2"
7818 [(set (match_operand:SF 0 "register_operand" "=f")
7819 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7822 [(set_attr "type" "fpsqrts")])
7824 ;;- arithmetic shift instructions
7826 (define_insn "ashlsi3"
7827 [(set (match_operand:SI 0 "register_operand" "=r")
7828 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7829 (match_operand:SI 2 "arith_operand" "rI")))]
7833 if (GET_CODE (operands[2]) == CONST_INT
7834 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7835 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7837 return \"sll\\t%1, %2, %0\";
7839 [(set_attr "type" "shift")])
7841 ;; We special case multiplication by two, as add can be done
7842 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7843 (define_insn "*ashlsi3_const1"
7844 [(set (match_operand:SI 0 "register_operand" "=r")
7845 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7850 (define_expand "ashldi3"
7851 [(set (match_operand:DI 0 "register_operand" "=r")
7852 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7853 (match_operand:SI 2 "arith_operand" "rI")))]
7854 "TARGET_ARCH64 || TARGET_V8PLUS"
7857 if (! TARGET_ARCH64)
7859 if (GET_CODE (operands[2]) == CONST_INT)
7861 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7866 ;; We special case multiplication by two, as add can be done
7867 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7868 (define_insn "*ashldi3_const1"
7869 [(set (match_operand:DI 0 "register_operand" "=r")
7870 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7875 (define_insn "*ashldi3_sp64"
7876 [(set (match_operand:DI 0 "register_operand" "=r")
7877 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7878 (match_operand:SI 2 "arith_operand" "rI")))]
7882 if (GET_CODE (operands[2]) == CONST_INT
7883 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7884 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7886 return \"sllx\\t%1, %2, %0\";
7888 [(set_attr "type" "shift")])
7891 (define_insn "ashldi3_v8plus"
7892 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7893 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7894 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7895 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7897 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7898 [(set_attr "type" "multi")
7899 (set_attr "length" "5,5,6")])
7901 ;; Optimize (1LL<<x)-1
7902 ;; XXX this also needs to be fixed to handle equal subregs
7903 ;; XXX first before we could re-enable it.
7905 ; [(set (match_operand:DI 0 "register_operand" "=h")
7906 ; (plus:DI (ashift:DI (const_int 1)
7907 ; (match_operand:SI 1 "arith_operand" "rI"))
7909 ; "0 && TARGET_V8PLUS"
7912 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7913 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7914 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7916 ; [(set_attr "type" "multi")
7917 ; (set_attr "length" "4")])
7919 (define_insn "*cmp_cc_ashift_1"
7920 [(set (reg:CC_NOOV 100)
7921 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7925 "addcc\\t%0, %0, %%g0"
7926 [(set_attr "type" "compare")])
7928 (define_insn "*cmp_cc_set_ashift_1"
7929 [(set (reg:CC_NOOV 100)
7930 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7933 (set (match_operand:SI 0 "register_operand" "=r")
7934 (ashift:SI (match_dup 1) (const_int 1)))]
7936 "addcc\\t%1, %1, %0"
7937 [(set_attr "type" "compare")])
7939 (define_insn "ashrsi3"
7940 [(set (match_operand:SI 0 "register_operand" "=r")
7941 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7942 (match_operand:SI 2 "arith_operand" "rI")))]
7946 if (GET_CODE (operands[2]) == CONST_INT
7947 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7948 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7950 return \"sra\\t%1, %2, %0\";
7952 [(set_attr "type" "shift")])
7954 (define_insn "*ashrsi3_extend"
7955 [(set (match_operand:DI 0 "register_operand" "=r")
7956 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7957 (match_operand:SI 2 "arith_operand" "r"))))]
7960 [(set_attr "type" "shift")])
7962 ;; This handles the case as above, but with constant shift instead of
7963 ;; register. Combiner "simplifies" it for us a little bit though.
7964 (define_insn "*ashrsi3_extend2"
7965 [(set (match_operand:DI 0 "register_operand" "=r")
7966 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7968 (match_operand:SI 2 "small_int_or_double" "n")))]
7970 && ((GET_CODE (operands[2]) == CONST_INT
7971 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7972 || (GET_CODE (operands[2]) == CONST_DOUBLE
7973 && !CONST_DOUBLE_HIGH (operands[2])
7974 && CONST_DOUBLE_LOW (operands[2]) >= 32
7975 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7978 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7980 return \"sra\\t%1, %2, %0\";
7982 [(set_attr "type" "shift")])
7984 (define_expand "ashrdi3"
7985 [(set (match_operand:DI 0 "register_operand" "=r")
7986 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7987 (match_operand:SI 2 "arith_operand" "rI")))]
7988 "TARGET_ARCH64 || TARGET_V8PLUS"
7991 if (! TARGET_ARCH64)
7993 if (GET_CODE (operands[2]) == CONST_INT)
7994 FAIL; /* prefer generic code in this case */
7995 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8001 [(set (match_operand:DI 0 "register_operand" "=r")
8002 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8003 (match_operand:SI 2 "arith_operand" "rI")))]
8007 if (GET_CODE (operands[2]) == CONST_INT
8008 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8009 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8011 return \"srax\\t%1, %2, %0\";
8013 [(set_attr "type" "shift")])
8016 (define_insn "ashrdi3_v8plus"
8017 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8018 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8019 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8020 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8022 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8023 [(set_attr "type" "multi")
8024 (set_attr "length" "5,5,6")])
8026 (define_insn "lshrsi3"
8027 [(set (match_operand:SI 0 "register_operand" "=r")
8028 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8029 (match_operand:SI 2 "arith_operand" "rI")))]
8033 if (GET_CODE (operands[2]) == CONST_INT
8034 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8035 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8037 return \"srl\\t%1, %2, %0\";
8039 [(set_attr "type" "shift")])
8041 ;; This handles the case where
8042 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8043 ;; but combiner "simplifies" it for us.
8044 (define_insn "*lshrsi3_extend"
8045 [(set (match_operand:DI 0 "register_operand" "=r")
8046 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8047 (match_operand:SI 2 "arith_operand" "r")) 0)
8048 (match_operand 3 "" "")))]
8050 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8051 && CONST_DOUBLE_HIGH (operands[3]) == 0
8052 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8053 || (HOST_BITS_PER_WIDE_INT >= 64
8054 && GET_CODE (operands[3]) == CONST_INT
8055 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8057 [(set_attr "type" "shift")])
8059 ;; This handles the case where
8060 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8061 ;; but combiner "simplifies" it for us.
8062 (define_insn "*lshrsi3_extend2"
8063 [(set (match_operand:DI 0 "register_operand" "=r")
8064 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8065 (match_operand 2 "small_int_or_double" "n")
8068 && ((GET_CODE (operands[2]) == CONST_INT
8069 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8070 || (GET_CODE (operands[2]) == CONST_DOUBLE
8071 && CONST_DOUBLE_HIGH (operands[2]) == 0
8072 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8075 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8077 return \"srl\\t%1, %2, %0\";
8079 [(set_attr "type" "shift")])
8081 (define_expand "lshrdi3"
8082 [(set (match_operand:DI 0 "register_operand" "=r")
8083 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8084 (match_operand:SI 2 "arith_operand" "rI")))]
8085 "TARGET_ARCH64 || TARGET_V8PLUS"
8088 if (! TARGET_ARCH64)
8090 if (GET_CODE (operands[2]) == CONST_INT)
8092 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8098 [(set (match_operand:DI 0 "register_operand" "=r")
8099 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8100 (match_operand:SI 2 "arith_operand" "rI")))]
8104 if (GET_CODE (operands[2]) == CONST_INT
8105 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8106 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8108 return \"srlx\\t%1, %2, %0\";
8110 [(set_attr "type" "shift")])
8113 (define_insn "lshrdi3_v8plus"
8114 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8115 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8116 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8117 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8119 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8120 [(set_attr "type" "multi")
8121 (set_attr "length" "5,5,6")])
8124 [(set (match_operand:SI 0 "register_operand" "=r")
8125 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8127 (match_operand:SI 2 "small_int_or_double" "n")))]
8129 && ((GET_CODE (operands[2]) == CONST_INT
8130 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8131 || (GET_CODE (operands[2]) == CONST_DOUBLE
8132 && !CONST_DOUBLE_HIGH (operands[2])
8133 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8136 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8138 return \"srax\\t%1, %2, %0\";
8140 [(set_attr "type" "shift")])
8143 [(set (match_operand:SI 0 "register_operand" "=r")
8144 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8146 (match_operand:SI 2 "small_int_or_double" "n")))]
8148 && ((GET_CODE (operands[2]) == CONST_INT
8149 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8150 || (GET_CODE (operands[2]) == CONST_DOUBLE
8151 && !CONST_DOUBLE_HIGH (operands[2])
8152 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8155 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8157 return \"srlx\\t%1, %2, %0\";
8159 [(set_attr "type" "shift")])
8162 [(set (match_operand:SI 0 "register_operand" "=r")
8163 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8164 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8165 (match_operand:SI 3 "small_int_or_double" "n")))]
8167 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8168 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8169 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8170 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8173 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8175 return \"srax\\t%1, %2, %0\";
8177 [(set_attr "type" "shift")])
8180 [(set (match_operand:SI 0 "register_operand" "=r")
8181 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8182 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8183 (match_operand:SI 3 "small_int_or_double" "n")))]
8185 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8186 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8187 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8188 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8191 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8193 return \"srlx\\t%1, %2, %0\";
8195 [(set_attr "type" "shift")])
8197 ;; Unconditional and other jump instructions
8198 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8199 ;; following insn is never executed. This saves us a nop. Dbx does not
8200 ;; handle such branches though, so we only use them when optimizing.
8202 [(set (pc) (label_ref (match_operand 0 "" "")))]
8206 /* TurboSparc is reported to have problems with
8209 i.e. an empty loop with the annul bit set. The workaround is to use
8213 if (! TARGET_V9 && flag_delayed_branch
8214 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8215 == INSN_ADDRESSES (INSN_UID (insn))))
8216 return \"b\\t%l0%#\";
8218 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8220 [(set_attr "type" "uncond_branch")])
8222 (define_expand "tablejump"
8223 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8224 (use (label_ref (match_operand 1 "" "")))])]
8228 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8231 /* In pic mode, our address differences are against the base of the
8232 table. Add that base value back in; CSE ought to be able to combine
8233 the two address loads. */
8237 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8239 if (CASE_VECTOR_MODE != Pmode)
8240 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8241 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8242 operands[0] = memory_address (Pmode, tmp);
8246 (define_insn "*tablejump_sp32"
8247 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8248 (use (label_ref (match_operand 1 "" "")))]
8251 [(set_attr "type" "uncond_branch")])
8253 (define_insn "*tablejump_sp64"
8254 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8255 (use (label_ref (match_operand 1 "" "")))]
8258 [(set_attr "type" "uncond_branch")])
8260 ;; This pattern recognizes the "instruction" that appears in
8261 ;; a function call that wants a structure value,
8262 ;; to inform the called function if compiled with Sun CC.
8263 ;(define_insn "*unimp_insn"
8264 ; [(match_operand:SI 0 "immediate_operand" "")]
8265 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8267 ; [(set_attr "type" "marker")])
8269 ;;- jump to subroutine
8270 (define_expand "call"
8271 ;; Note that this expression is not used for generating RTL.
8272 ;; All the RTL is generated explicitly below.
8273 [(call (match_operand 0 "call_operand" "")
8274 (match_operand 3 "" "i"))]
8275 ;; operands[2] is next_arg_register
8276 ;; operands[3] is struct_value_size_rtx.
8280 rtx fn_rtx, nregs_rtx;
8282 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8285 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8287 /* This is really a PIC sequence. We want to represent
8288 it as a funny jump so its delay slots can be filled.
8290 ??? But if this really *is* a CALL, will not it clobber the
8291 call-clobbered registers? We lose this if it is a JUMP_INSN.
8292 Why cannot we have delay slots filled if it were a CALL? */
8294 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8299 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8301 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8307 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8308 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8312 fn_rtx = operands[0];
8314 /* Count the number of parameter registers being used by this call.
8315 if that argument is NULL, it means we are using them all, which
8316 means 6 on the sparc. */
8319 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8321 nregs_rtx = GEN_INT (6);
8323 nregs_rtx = const0_rtx;
8326 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8330 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8332 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8337 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8338 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8342 /* If this call wants a structure value,
8343 emit an unimp insn to let the called function know about this. */
8344 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8346 rtx insn = emit_insn (operands[3]);
8347 SCHED_GROUP_P (insn) = 1;
8354 ;; We can't use the same pattern for these two insns, because then registers
8355 ;; in the address may not be properly reloaded.
8357 (define_insn "*call_address_sp32"
8358 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8359 (match_operand 1 "" ""))
8360 (clobber (reg:SI 15))]
8361 ;;- Do not use operand 1 for most machines.
8364 [(set_attr "type" "call")])
8366 (define_insn "*call_symbolic_sp32"
8367 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8368 (match_operand 1 "" ""))
8369 (clobber (reg:SI 15))]
8370 ;;- Do not use operand 1 for most machines.
8373 [(set_attr "type" "call")])
8375 (define_insn "*call_address_sp64"
8376 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8377 (match_operand 1 "" ""))
8378 (clobber (reg:DI 15))]
8379 ;;- Do not use operand 1 for most machines.
8382 [(set_attr "type" "call")])
8384 (define_insn "*call_symbolic_sp64"
8385 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8386 (match_operand 1 "" ""))
8387 (clobber (reg:DI 15))]
8388 ;;- Do not use operand 1 for most machines.
8391 [(set_attr "type" "call")])
8393 ;; This is a call that wants a structure value.
8394 ;; There is no such critter for v9 (??? we may need one anyway).
8395 (define_insn "*call_address_struct_value_sp32"
8396 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8397 (match_operand 1 "" ""))
8398 (match_operand 2 "immediate_operand" "")
8399 (clobber (reg:SI 15))]
8400 ;;- Do not use operand 1 for most machines.
8401 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8402 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8403 [(set_attr "type" "call_no_delay_slot")
8404 (set_attr "length" "2")])
8406 ;; This is a call that wants a structure value.
8407 ;; There is no such critter for v9 (??? we may need one anyway).
8408 (define_insn "*call_symbolic_struct_value_sp32"
8409 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8410 (match_operand 1 "" ""))
8411 (match_operand 2 "immediate_operand" "")
8412 (clobber (reg:SI 15))]
8413 ;;- Do not use operand 1 for most machines.
8414 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8415 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8416 [(set_attr "type" "call_no_delay_slot")
8417 (set_attr "length" "2")])
8419 ;; This is a call that may want a structure value. This is used for
8421 (define_insn "*call_address_untyped_struct_value_sp32"
8422 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8423 (match_operand 1 "" ""))
8424 (match_operand 2 "immediate_operand" "")
8425 (clobber (reg:SI 15))]
8426 ;;- Do not use operand 1 for most machines.
8427 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8428 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8429 [(set_attr "type" "call_no_delay_slot")
8430 (set_attr "length" "2")])
8432 ;; This is a call that wants a structure value.
8433 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8434 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8435 (match_operand 1 "" ""))
8436 (match_operand 2 "immediate_operand" "")
8437 (clobber (reg:SI 15))]
8438 ;;- Do not use operand 1 for most machines.
8439 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8440 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8441 [(set_attr "type" "call_no_delay_slot")
8442 (set_attr "length" "2")])
8444 (define_expand "call_value"
8445 ;; Note that this expression is not used for generating RTL.
8446 ;; All the RTL is generated explicitly below.
8447 [(set (match_operand 0 "register_operand" "=rf")
8448 (call (match_operand 1 "" "")
8449 (match_operand 4 "" "")))]
8450 ;; operand 2 is stack_size_rtx
8451 ;; operand 3 is next_arg_register
8455 rtx fn_rtx, nregs_rtx;
8458 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8461 fn_rtx = operands[1];
8465 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8467 nregs_rtx = GEN_INT (6);
8469 nregs_rtx = const0_rtx;
8473 gen_rtx_SET (VOIDmode, operands[0],
8474 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8475 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8477 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8482 (define_insn "*call_value_address_sp32"
8483 [(set (match_operand 0 "" "=rf")
8484 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8485 (match_operand 2 "" "")))
8486 (clobber (reg:SI 15))]
8487 ;;- Do not use operand 2 for most machines.
8490 [(set_attr "type" "call")])
8492 (define_insn "*call_value_symbolic_sp32"
8493 [(set (match_operand 0 "" "=rf")
8494 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8495 (match_operand 2 "" "")))
8496 (clobber (reg:SI 15))]
8497 ;;- Do not use operand 2 for most machines.
8500 [(set_attr "type" "call")])
8502 (define_insn "*call_value_address_sp64"
8503 [(set (match_operand 0 "" "")
8504 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8505 (match_operand 2 "" "")))
8506 (clobber (reg:DI 15))]
8507 ;;- Do not use operand 2 for most machines.
8510 [(set_attr "type" "call")])
8512 (define_insn "*call_value_symbolic_sp64"
8513 [(set (match_operand 0 "" "")
8514 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8515 (match_operand 2 "" "")))
8516 (clobber (reg:DI 15))]
8517 ;;- Do not use operand 2 for most machines.
8520 [(set_attr "type" "call")])
8522 (define_expand "untyped_call"
8523 [(parallel [(call (match_operand 0 "" "")
8525 (match_operand 1 "" "")
8526 (match_operand 2 "" "")])]
8532 /* Pass constm1 to indicate that it may expect a structure value, but
8533 we don't know what size it is. */
8534 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8536 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8538 rtx set = XVECEXP (operands[2], 0, i);
8539 emit_move_insn (SET_DEST (set), SET_SRC (set));
8542 /* The optimizer does not know that the call sets the function value
8543 registers we stored in the result block. We avoid problems by
8544 claiming that all hard registers are used and clobbered at this
8546 emit_insn (gen_blockage ());
8552 (define_expand "sibcall"
8553 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8558 (define_insn "*sibcall_symbolic_sp32"
8559 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8560 (match_operand 1 "" ""))
8563 "* return output_sibcall(insn, operands[0]);"
8564 [(set_attr "type" "sibcall")])
8566 (define_insn "*sibcall_symbolic_sp64"
8567 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8568 (match_operand 1 "" ""))
8571 "* return output_sibcall(insn, operands[0]);"
8572 [(set_attr "type" "sibcall")])
8574 (define_expand "sibcall_value"
8575 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8576 (call (match_operand 1 "" "") (const_int 0)))
8581 (define_insn "*sibcall_value_symbolic_sp32"
8582 [(set (match_operand 0 "" "=rf")
8583 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8584 (match_operand 2 "" "")))
8587 "* return output_sibcall(insn, operands[1]);"
8588 [(set_attr "type" "sibcall")])
8590 (define_insn "*sibcall_value_symbolic_sp64"
8591 [(set (match_operand 0 "" "")
8592 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8593 (match_operand 2 "" "")))
8596 "* return output_sibcall(insn, operands[1]);"
8597 [(set_attr "type" "sibcall")])
8599 (define_expand "sibcall_epilogue"
8604 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8605 ;; all of memory. This blocks insns from being moved across this point.
8607 (define_insn "blockage"
8608 [(unspec_volatile [(const_int 0)] 0)]
8611 [(set_attr "length" "0")])
8613 ;; Prepare to return any type including a structure value.
8615 (define_expand "untyped_return"
8616 [(match_operand:BLK 0 "memory_operand" "")
8617 (match_operand 1 "" "")]
8621 rtx valreg1 = gen_rtx_REG (DImode, 24);
8622 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8623 rtx result = operands[0];
8625 if (! TARGET_ARCH64)
8627 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8629 rtx value = gen_reg_rtx (SImode);
8631 /* Fetch the instruction where we will return to and see if it's an unimp
8632 instruction (the most significant 10 bits will be zero). If so,
8633 update the return address to skip the unimp instruction. */
8634 emit_move_insn (value,
8635 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8636 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8637 emit_insn (gen_update_return (rtnreg, value));
8640 /* Reload the function value registers. */
8641 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8642 emit_move_insn (valreg2,
8643 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8645 /* Put USE insns before the return. */
8646 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8647 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8649 /* Construct the return. */
8650 expand_null_return ();
8655 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8656 ;; and parts of the compiler don't want to believe that the add is needed.
8658 (define_insn "update_return"
8659 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8660 (match_operand:SI 1 "register_operand" "r")] 1)]
8662 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8663 [(set_attr "type" "multi")
8664 (set_attr "length" "3")])
8666 (define_insn "return"
8670 "* return output_return (operands);"
8671 [(set_attr "type" "return")])
8674 [(set (match_operand:SI 0 "register_operand" "=r")
8675 (match_operand:SI 1 "arith_operand" "rI"))
8677 (use (reg:SI 31))])]
8678 "sparc_return_peephole_ok (operands[0], operands[1])"
8679 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8686 (define_expand "indirect_jump"
8687 [(set (pc) (match_operand 0 "address_operand" "p"))]
8691 (define_insn "*branch_sp32"
8692 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8695 [(set_attr "type" "uncond_branch")])
8697 (define_insn "*branch_sp64"
8698 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8701 [(set_attr "type" "uncond_branch")])
8703 ;; ??? Doesn't work with -mflat.
8704 (define_expand "nonlocal_goto"
8705 [(match_operand:SI 0 "general_operand" "")
8706 (match_operand:SI 1 "general_operand" "")
8707 (match_operand:SI 2 "general_operand" "")
8708 (match_operand:SI 3 "" "")]
8713 rtx chain = operands[0];
8715 rtx lab = operands[1];
8716 rtx stack = operands[2];
8717 rtx fp = operands[3];
8720 /* Trap instruction to flush all the register windows. */
8721 emit_insn (gen_flush_register_windows ());
8723 /* Load the fp value for the containing fn into %fp. This is needed
8724 because STACK refers to %fp. Note that virtual register instantiation
8725 fails if the virtual %fp isn't set from a register. */
8726 if (GET_CODE (fp) != REG)
8727 fp = force_reg (Pmode, fp);
8728 emit_move_insn (virtual_stack_vars_rtx, fp);
8730 /* Find the containing function's current nonlocal goto handler,
8731 which will do any cleanups and then jump to the label. */
8732 labreg = gen_rtx_REG (Pmode, 8);
8733 emit_move_insn (labreg, lab);
8735 /* Restore %fp from stack pointer value for containing function.
8736 The restore insn that follows will move this to %sp,
8737 and reload the appropriate value into %fp. */
8738 emit_move_insn (frame_pointer_rtx, stack);
8740 /* USE of frame_pointer_rtx added for consistency; not clear if
8742 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8743 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8746 /* Return, restoring reg window and jumping to goto handler. */
8747 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8748 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8750 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8756 /* Put in the static chain register the nonlocal label address. */
8757 emit_move_insn (static_chain_rtx, chain);
8760 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8761 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8766 ;; Special trap insn to flush register windows.
8767 (define_insn "flush_register_windows"
8768 [(unspec_volatile [(const_int 0)] 1)]
8770 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8771 [(set_attr "type" "misc")])
8773 (define_insn "goto_handler_and_restore"
8774 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8775 "GET_MODE (operands[0]) == Pmode"
8776 "jmp\\t%0+0\\n\\trestore"
8777 [(set_attr "type" "multi")
8778 (set_attr "length" "2")])
8780 ;;(define_insn "goto_handler_and_restore_v9"
8781 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8782 ;; (match_operand:SI 1 "register_operand" "=r,r")
8783 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8784 ;; "TARGET_V9 && ! TARGET_ARCH64"
8786 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8787 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8788 ;; [(set_attr "type" "multi")
8789 ;; (set_attr "length" "2,3")])
8791 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8792 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8793 ;; (match_operand:DI 1 "register_operand" "=r,r")
8794 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8795 ;; "TARGET_V9 && TARGET_ARCH64"
8797 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8798 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8799 ;; [(set_attr "type" "multi")
8800 ;; (set_attr "length" "2,3")])
8802 ;; For __builtin_setjmp we need to flush register windows iff the function
8803 ;; calls alloca as well, because otherwise the register window might be
8804 ;; saved after %sp adjustement and thus setjmp would crash
8805 (define_expand "builtin_setjmp_setup"
8806 [(match_operand 0 "register_operand" "r")]
8810 emit_insn (gen_do_builtin_setjmp_setup ());
8814 ;; ??? Should set length to zero when !current_function_calls_alloca,
8815 ;; ??? but there is no easy way to get at that definition. It would
8816 ;; ??? require including function.h into sparc-protos.h and that is
8817 ;; ??? likely not a good idea. -DaveM
8818 (define_insn "do_builtin_setjmp_setup"
8819 [(unspec_volatile [(const_int 0)] 5)]
8823 if (!current_function_calls_alloca)
8829 [(set_attr "type" "misc")])
8831 ;; Pattern for use after a setjmp to store FP and the return register
8832 ;; into the stack area.
8834 (define_expand "setjmp"
8840 emit_insn (gen_setjmp_64 ());
8842 emit_insn (gen_setjmp_32 ());
8846 (define_expand "setjmp_32"
8847 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8848 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8851 { operands[0] = frame_pointer_rtx; }")
8853 (define_expand "setjmp_64"
8854 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8855 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8858 { operands[0] = frame_pointer_rtx; }")
8860 ;; Special pattern for the FLUSH instruction.
8862 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8863 ; of the define_insn otherwise missing a mode. We make "flush", aka
8864 ; gen_flush, the default one since sparc_initialize_trampoline uses
8865 ; it on SImode mem values.
8867 (define_insn "flush"
8868 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8870 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8871 [(set_attr "type" "misc")])
8873 (define_insn "flushdi"
8874 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8876 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8877 [(set_attr "type" "misc")])
8882 ;; The scan instruction searches from the most significant bit while ffs
8883 ;; searches from the least significant bit. The bit index and treatment of
8884 ;; zero also differ. It takes at least 7 instructions to get the proper
8885 ;; result. Here is an obvious 8 instruction sequence.
8888 (define_insn "ffssi2"
8889 [(set (match_operand:SI 0 "register_operand" "=&r")
8890 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8891 (clobber (match_scratch:SI 2 "=&r"))]
8892 "TARGET_SPARCLITE || TARGET_SPARCLET"
8895 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\";
8897 [(set_attr "type" "multi")
8898 (set_attr "length" "8")])
8900 ;; ??? This should be a define expand, so that the extra instruction have
8901 ;; a chance of being optimized away.
8903 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8904 ;; does, but no one uses that and we don't have a switch for it.
8906 ;(define_insn "ffsdi2"
8907 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8908 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8909 ; (clobber (match_scratch:DI 2 "=&r"))]
8911 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8912 ; [(set_attr "type" "multi")
8913 ; (set_attr "length" "4")])
8917 ;; Peepholes go at the end.
8919 ;; Optimize consecutive loads or stores into ldd and std when possible.
8920 ;; The conditions in which we do this are very restricted and are
8921 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8924 [(set (match_operand:SI 0 "memory_operand" "")
8926 (set (match_operand:SI 1 "memory_operand" "")
8929 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8932 "operands[0] = change_address (operands[0], DImode, NULL);")
8935 [(set (match_operand:SI 0 "memory_operand" "")
8937 (set (match_operand:SI 1 "memory_operand" "")
8940 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8943 "operands[1] = change_address (operands[1], DImode, NULL);")
8946 [(set (match_operand:SI 0 "register_operand" "")
8947 (match_operand:SI 1 "memory_operand" ""))
8948 (set (match_operand:SI 2 "register_operand" "")
8949 (match_operand:SI 3 "memory_operand" ""))]
8950 "registers_ok_for_ldd_peep (operands[0], operands[2])
8951 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8954 "operands[1] = change_address (operands[1], DImode, NULL);
8955 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8958 [(set (match_operand:SI 0 "memory_operand" "")
8959 (match_operand:SI 1 "register_operand" ""))
8960 (set (match_operand:SI 2 "memory_operand" "")
8961 (match_operand:SI 3 "register_operand" ""))]
8962 "registers_ok_for_ldd_peep (operands[1], operands[3])
8963 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8966 "operands[0] = change_address (operands[0], DImode, NULL);
8967 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8970 [(set (match_operand:SF 0 "register_operand" "")
8971 (match_operand:SF 1 "memory_operand" ""))
8972 (set (match_operand:SF 2 "register_operand" "")
8973 (match_operand:SF 3 "memory_operand" ""))]
8974 "registers_ok_for_ldd_peep (operands[0], operands[2])
8975 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8978 "operands[1] = change_address (operands[1], DFmode, NULL);
8979 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8982 [(set (match_operand:SF 0 "memory_operand" "")
8983 (match_operand:SF 1 "register_operand" ""))
8984 (set (match_operand:SF 2 "memory_operand" "")
8985 (match_operand:SF 3 "register_operand" ""))]
8986 "registers_ok_for_ldd_peep (operands[1], operands[3])
8987 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8990 "operands[0] = change_address (operands[0], DFmode, NULL);
8991 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8994 [(set (match_operand:SI 0 "register_operand" "")
8995 (match_operand:SI 1 "memory_operand" ""))
8996 (set (match_operand:SI 2 "register_operand" "")
8997 (match_operand:SI 3 "memory_operand" ""))]
8998 "registers_ok_for_ldd_peep (operands[2], operands[0])
8999 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9002 "operands[3] = change_address (operands[3], DImode, NULL);
9003 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9006 [(set (match_operand:SI 0 "memory_operand" "")
9007 (match_operand:SI 1 "register_operand" ""))
9008 (set (match_operand:SI 2 "memory_operand" "")
9009 (match_operand:SI 3 "register_operand" ""))]
9010 "registers_ok_for_ldd_peep (operands[3], operands[1])
9011 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9014 "operands[2] = change_address (operands[2], DImode, NULL);
9015 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9019 [(set (match_operand:SF 0 "register_operand" "")
9020 (match_operand:SF 1 "memory_operand" ""))
9021 (set (match_operand:SF 2 "register_operand" "")
9022 (match_operand:SF 3 "memory_operand" ""))]
9023 "registers_ok_for_ldd_peep (operands[2], operands[0])
9024 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9027 "operands[3] = change_address (operands[3], DFmode, NULL);
9028 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9031 [(set (match_operand:SF 0 "memory_operand" "")
9032 (match_operand:SF 1 "register_operand" ""))
9033 (set (match_operand:SF 2 "memory_operand" "")
9034 (match_operand:SF 3 "register_operand" ""))]
9035 "registers_ok_for_ldd_peep (operands[3], operands[1])
9036 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9039 "operands[2] = change_address (operands[2], DFmode, NULL);
9040 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9042 ;; Optimize the case of following a reg-reg move with a test
9043 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9044 ;; This can result from a float to fix conversion.
9047 [(set (match_operand:SI 0 "register_operand" "")
9048 (match_operand:SI 1 "register_operand" ""))
9050 (compare:CC (match_operand:SI 2 "register_operand" "")
9052 "(rtx_equal_p (operands[2], operands[0])
9053 || rtx_equal_p (operands[2], operands[1]))
9054 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9055 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9056 [(parallel [(set (match_dup 0) (match_dup 1))
9058 (compare:CC (match_dup 1) (const_int 0)))])]
9062 [(set (match_operand:DI 0 "register_operand" "")
9063 (match_operand:DI 1 "register_operand" ""))
9065 (compare:CCX (match_operand:DI 2 "register_operand" "")
9068 && (rtx_equal_p (operands[2], operands[0])
9069 || rtx_equal_p (operands[2], operands[1]))
9070 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9071 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9072 [(parallel [(set (match_dup 0) (match_dup 1))
9074 (compare:CC (match_dup 1) (const_int 0)))])]
9077 ;; Return peepholes. First the "normal" ones.
9078 ;; These are necessary to catch insns ending up in the epilogue delay list.
9080 (define_insn "*return_qi"
9081 [(set (match_operand:QI 0 "restore_operand" "")
9082 (match_operand:QI 1 "arith_operand" "rI"))
9087 if (! TARGET_ARCH64 && current_function_returns_struct)
9088 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9089 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9090 || IN_OR_GLOBAL_P (operands[1])))
9091 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9093 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9095 [(set_attr "type" "multi")
9096 (set_attr "length" "2")])
9098 (define_insn "*return_hi"
9099 [(set (match_operand:HI 0 "restore_operand" "")
9100 (match_operand:HI 1 "arith_operand" "rI"))
9105 if (! TARGET_ARCH64 && current_function_returns_struct)
9106 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9107 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9108 || IN_OR_GLOBAL_P (operands[1])))
9109 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9111 return \"ret\;restore %%g0, %1, %Y0\";
9113 [(set_attr "type" "multi")
9114 (set_attr "length" "2")])
9116 (define_insn "*return_si"
9117 [(set (match_operand:SI 0 "restore_operand" "")
9118 (match_operand:SI 1 "arith_operand" "rI"))
9123 if (! TARGET_ARCH64 && current_function_returns_struct)
9124 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9125 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9126 || IN_OR_GLOBAL_P (operands[1])))
9127 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9129 return \"ret\;restore %%g0, %1, %Y0\";
9131 [(set_attr "type" "multi")
9132 (set_attr "length" "2")])
9134 ;; The following pattern is only generated by delayed-branch scheduling,
9135 ;; when the insn winds up in the epilogue. This can happen not only when
9136 ;; ! TARGET_FPU because we move complex types around by parts using
9138 (define_insn "*return_sf_no_fpu"
9139 [(set (match_operand:SF 0 "restore_operand" "=r")
9140 (match_operand:SF 1 "register_operand" "r"))
9145 if (! TARGET_ARCH64 && current_function_returns_struct)
9146 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9147 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9148 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9150 return \"ret\;restore %%g0, %1, %Y0\";
9152 [(set_attr "type" "multi")
9153 (set_attr "length" "2")])
9155 (define_insn "*return_df_no_fpu"
9156 [(set (match_operand:DF 0 "restore_operand" "=r")
9157 (match_operand:DF 1 "register_operand" "r"))
9159 "! TARGET_EPILOGUE && TARGET_ARCH64"
9162 if (IN_OR_GLOBAL_P (operands[1]))
9163 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9165 return \"ret\;restore %%g0, %1, %Y0\";
9167 [(set_attr "type" "multi")
9168 (set_attr "length" "2")])
9170 (define_insn "*return_addsi"
9171 [(set (match_operand:SI 0 "restore_operand" "")
9172 (plus:SI (match_operand:SI 1 "register_operand" "r")
9173 (match_operand:SI 2 "arith_operand" "rI")))
9178 if (! TARGET_ARCH64 && current_function_returns_struct)
9179 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9180 /* If operands are global or in registers, can use return */
9181 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9182 && (GET_CODE (operands[2]) == CONST_INT
9183 || IN_OR_GLOBAL_P (operands[2])))
9184 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9186 return \"ret\;restore %r1, %2, %Y0\";
9188 [(set_attr "type" "multi")
9189 (set_attr "length" "2")])
9191 (define_insn "*return_losum_si"
9192 [(set (match_operand:SI 0 "restore_operand" "")
9193 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9194 (match_operand:SI 2 "immediate_operand" "in")))
9196 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9199 if (! TARGET_ARCH64 && current_function_returns_struct)
9200 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9201 /* If operands are global or in registers, can use return */
9202 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9203 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9205 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9207 [(set_attr "type" "multi")
9208 (set_attr "length" "2")])
9210 (define_insn "*return_di"
9211 [(set (match_operand:DI 0 "restore_operand" "")
9212 (match_operand:DI 1 "arith_double_operand" "rHI"))
9214 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9215 "ret\;restore %%g0, %1, %Y0"
9216 [(set_attr "type" "multi")
9217 (set_attr "length" "2")])
9219 (define_insn "*return_adddi"
9220 [(set (match_operand:DI 0 "restore_operand" "")
9221 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9222 (match_operand:DI 2 "arith_double_operand" "rHI")))
9224 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9225 "ret\;restore %r1, %2, %Y0"
9226 [(set_attr "type" "multi")
9227 (set_attr "length" "2")])
9229 (define_insn "*return_losum_di"
9230 [(set (match_operand:DI 0 "restore_operand" "")
9231 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9232 (match_operand:DI 2 "immediate_operand" "in")))
9234 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9235 "ret\;restore %r1, %%lo(%a2), %Y0"
9236 [(set_attr "type" "multi")
9237 (set_attr "length" "2")])
9239 ;; The following pattern is only generated by delayed-branch scheduling,
9240 ;; when the insn winds up in the epilogue.
9241 (define_insn "*return_sf"
9243 (match_operand:SF 0 "register_operand" "f"))
9246 "ret\;fmovs\\t%0, %%f0"
9247 [(set_attr "type" "multi")
9248 (set_attr "length" "2")])
9250 ;; Now peepholes to do a call followed by a jump.
9253 [(parallel [(set (match_operand 0 "" "")
9254 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9255 (match_operand 2 "" "")))
9256 (clobber (reg:SI 15))])
9257 (set (pc) (label_ref (match_operand 3 "" "")))]
9258 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9259 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9260 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9263 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9264 (match_operand 1 "" ""))
9265 (clobber (reg:SI 15))])
9266 (set (pc) (label_ref (match_operand 2 "" "")))]
9267 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9268 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9269 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9272 [(parallel [(set (match_operand 0 "" "")
9273 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9274 (match_operand 2 "" "")))
9275 (clobber (reg:DI 15))])
9276 (set (pc) (label_ref (match_operand 3 "" "")))]
9278 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9279 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9280 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9283 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9284 (match_operand 1 "" ""))
9285 (clobber (reg:DI 15))])
9286 (set (pc) (label_ref (match_operand 2 "" "")))]
9288 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9289 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9290 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9292 (define_insn "prefetch"
9293 [(prefetch (match_operand:DI 0 "address_operand" "p")
9294 (match_operand:DI 1 "const_int_operand" "n")
9295 (match_operand:DI 2 "const_int_operand" "n"))]
9298 static const char * const prefetch_instr[2][4] = {
9300 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9301 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9302 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9303 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9306 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9307 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9308 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9309 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9312 int read_or_write = INTVAL (operands[1]);
9313 int locality = INTVAL (operands[2]);
9315 if (read_or_write != 0 && read_or_write != 1)
9317 if (locality < 0 || locality > 3)
9319 return prefetch_instr [read_or_write][locality];
9321 [(set_attr "type" "load")])
9323 (define_expand "prologue"
9325 "flag_pic && current_function_uses_pic_offset_table"
9328 load_pic_register ();
9332 ;; We need to reload %l7 for -mflat -fpic,
9333 ;; otherwise %l7 should be preserved simply
9334 ;; by loading the function's register window
9335 (define_expand "exception_receiver"
9337 "TARGET_FLAT && flag_pic"
9340 load_pic_register ();
9345 (define_expand "builtin_setjmp_receiver"
9346 [(label_ref (match_operand 0 "" ""))]
9347 "TARGET_FLAT && flag_pic"
9350 load_pic_register ();
9355 [(trap_if (const_int 1) (const_int 5))]
9358 [(set_attr "type" "misc")])
9360 (define_expand "conditional_trap"
9361 [(trap_if (match_operator 0 "noov_compare_op"
9362 [(match_dup 2) (match_dup 3)])
9363 (match_operand:SI 1 "arith_operand" ""))]
9365 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9366 sparc_compare_op0, sparc_compare_op1);
9367 operands[3] = const0_rtx;")
9370 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9371 (match_operand:SI 1 "arith_operand" "rM"))]
9374 [(set_attr "type" "misc")])
9377 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9378 (match_operand:SI 1 "arith_operand" "rM"))]
9381 [(set_attr "type" "misc")])