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 (trunc_int_for_mode
2057 (CONST_DOUBLE_LOW (operands[1]), QImode));
2060 /* Handle sets of MEM first. */
2061 if (GET_CODE (operands[0]) == MEM)
2063 if (reg_or_0_operand (operands[1], QImode))
2066 if (! reload_in_progress)
2068 operands[0] = validize_mem (operands[0]);
2069 operands[1] = force_reg (QImode, operands[1]);
2073 /* Fixup PIC cases. */
2076 if (CONSTANT_P (operands[1])
2077 && pic_address_needs_scratch (operands[1]))
2078 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2080 if (symbolic_operand (operands[1], QImode))
2082 operands[1] = legitimize_pic_address (operands[1],
2084 (reload_in_progress ?
2091 /* All QI constants require only one insn, so proceed. */
2097 (define_insn "*movqi_insn"
2098 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2099 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2100 "(register_operand (operands[0], QImode)
2101 || reg_or_0_operand (operands[1], QImode))"
2106 [(set_attr "type" "*,load,store")])
2108 (define_expand "movhi"
2109 [(set (match_operand:HI 0 "general_operand" "")
2110 (match_operand:HI 1 "general_operand" ""))]
2114 /* Working with CONST_INTs is easier, so convert
2115 a double if needed. */
2116 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2117 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2119 /* Handle sets of MEM first. */
2120 if (GET_CODE (operands[0]) == MEM)
2122 if (reg_or_0_operand (operands[1], HImode))
2125 if (! reload_in_progress)
2127 operands[0] = validize_mem (operands[0]);
2128 operands[1] = force_reg (HImode, operands[1]);
2132 /* Fixup PIC cases. */
2135 if (CONSTANT_P (operands[1])
2136 && pic_address_needs_scratch (operands[1]))
2137 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2139 if (symbolic_operand (operands[1], HImode))
2141 operands[1] = legitimize_pic_address (operands[1],
2143 (reload_in_progress ?
2150 /* This makes sure we will not get rematched due to splittage. */
2151 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2153 else if (CONSTANT_P (operands[1])
2154 && GET_CODE (operands[1]) != HIGH
2155 && GET_CODE (operands[1]) != LO_SUM)
2157 sparc_emit_set_const32 (operands[0], operands[1]);
2164 (define_insn "*movhi_const64_special"
2165 [(set (match_operand:HI 0 "register_operand" "=r")
2166 (match_operand:HI 1 "const64_high_operand" ""))]
2168 "sethi\\t%%hi(%a1), %0")
2170 (define_insn "*movhi_insn"
2171 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2172 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2173 "(register_operand (operands[0], HImode)
2174 || reg_or_0_operand (operands[1], HImode))"
2177 sethi\\t%%hi(%a1), %0
2180 [(set_attr "type" "*,*,load,store")])
2182 ;; We always work with constants here.
2183 (define_insn "*movhi_lo_sum"
2184 [(set (match_operand:HI 0 "register_operand" "=r")
2185 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2186 (match_operand:HI 2 "arith_operand" "I")))]
2190 (define_expand "movsi"
2191 [(set (match_operand:SI 0 "general_operand" "")
2192 (match_operand:SI 1 "general_operand" ""))]
2196 /* Working with CONST_INTs is easier, so convert
2197 a double if needed. */
2198 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2199 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2201 /* Handle sets of MEM first. */
2202 if (GET_CODE (operands[0]) == MEM)
2204 if (reg_or_0_operand (operands[1], SImode))
2207 if (! reload_in_progress)
2209 operands[0] = validize_mem (operands[0]);
2210 operands[1] = force_reg (SImode, operands[1]);
2214 /* Fixup PIC cases. */
2217 if (CONSTANT_P (operands[1])
2218 && pic_address_needs_scratch (operands[1]))
2219 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2221 if (GET_CODE (operands[1]) == LABEL_REF)
2224 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2228 if (symbolic_operand (operands[1], SImode))
2230 operands[1] = legitimize_pic_address (operands[1],
2232 (reload_in_progress ?
2239 /* If we are trying to toss an integer constant into the
2240 FPU registers, force it into memory. */
2241 if (GET_CODE (operands[0]) == REG
2242 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2243 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2244 && CONSTANT_P (operands[1]))
2245 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2248 /* This makes sure we will not get rematched due to splittage. */
2249 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2251 else if (CONSTANT_P (operands[1])
2252 && GET_CODE (operands[1]) != HIGH
2253 && GET_CODE (operands[1]) != LO_SUM)
2255 sparc_emit_set_const32 (operands[0], operands[1]);
2262 ;; This is needed to show CSE exactly which bits are set
2263 ;; in a 64-bit register by sethi instructions.
2264 (define_insn "*movsi_const64_special"
2265 [(set (match_operand:SI 0 "register_operand" "=r")
2266 (match_operand:SI 1 "const64_high_operand" ""))]
2268 "sethi\\t%%hi(%a1), %0")
2270 (define_insn "*movsi_insn"
2271 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2272 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2273 "(register_operand (operands[0], SImode)
2274 || reg_or_0_operand (operands[1], SImode))"
2278 sethi\\t%%hi(%a1), %0
2285 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
2287 (define_insn "*movsi_lo_sum"
2288 [(set (match_operand:SI 0 "register_operand" "=r")
2289 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2290 (match_operand:SI 2 "immediate_operand" "in")))]
2292 "or\\t%1, %%lo(%a2), %0")
2294 (define_insn "*movsi_high"
2295 [(set (match_operand:SI 0 "register_operand" "=r")
2296 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2298 "sethi\\t%%hi(%a1), %0")
2300 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2301 ;; so that CSE won't optimize the address computation away.
2302 (define_insn "movsi_lo_sum_pic"
2303 [(set (match_operand:SI 0 "register_operand" "=r")
2304 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2305 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2307 "or\\t%1, %%lo(%a2), %0")
2309 (define_insn "movsi_high_pic"
2310 [(set (match_operand:SI 0 "register_operand" "=r")
2311 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2312 "flag_pic && check_pic (1)"
2313 "sethi\\t%%hi(%a1), %0")
2315 (define_expand "movsi_pic_label_ref"
2316 [(set (match_dup 3) (high:SI
2317 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2319 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2320 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2321 (set (match_operand:SI 0 "register_operand" "=r")
2322 (minus:SI (match_dup 5) (match_dup 4)))]
2326 current_function_uses_pic_offset_table = 1;
2327 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2330 operands[3] = operands[0];
2331 operands[4] = operands[0];
2335 operands[3] = gen_reg_rtx (SImode);
2336 operands[4] = gen_reg_rtx (SImode);
2338 operands[5] = pic_offset_table_rtx;
2341 (define_insn "*movsi_high_pic_label_ref"
2342 [(set (match_operand:SI 0 "register_operand" "=r")
2344 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2345 (match_operand:SI 2 "" "")] 5)))]
2347 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2349 (define_insn "*movsi_lo_sum_pic_label_ref"
2350 [(set (match_operand:SI 0 "register_operand" "=r")
2351 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2352 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2353 (match_operand:SI 3 "" "")] 5)))]
2355 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2357 (define_expand "movdi"
2358 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2359 (match_operand:DI 1 "general_operand" ""))]
2363 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2364 if (GET_CODE (operands[1]) == CONST_DOUBLE
2365 #if HOST_BITS_PER_WIDE_INT == 32
2366 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2367 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2368 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2369 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2372 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2374 /* Handle MEM cases first. */
2375 if (GET_CODE (operands[0]) == MEM)
2377 /* If it's a REG, we can always do it.
2378 The const zero case is more complex, on v9
2379 we can always perform it. */
2380 if (register_operand (operands[1], DImode)
2382 && (operands[1] == const0_rtx)))
2385 if (! reload_in_progress)
2387 operands[0] = validize_mem (operands[0]);
2388 operands[1] = force_reg (DImode, operands[1]);
2394 if (CONSTANT_P (operands[1])
2395 && pic_address_needs_scratch (operands[1]))
2396 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2398 if (GET_CODE (operands[1]) == LABEL_REF)
2400 if (! TARGET_ARCH64)
2402 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2406 if (symbolic_operand (operands[1], DImode))
2408 operands[1] = legitimize_pic_address (operands[1],
2410 (reload_in_progress ?
2417 /* If we are trying to toss an integer constant into the
2418 FPU registers, force it into memory. */
2419 if (GET_CODE (operands[0]) == REG
2420 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2421 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2422 && CONSTANT_P (operands[1]))
2423 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2426 /* This makes sure we will not get rematched due to splittage. */
2427 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2429 else if (TARGET_ARCH64
2430 && CONSTANT_P (operands[1])
2431 && GET_CODE (operands[1]) != HIGH
2432 && GET_CODE (operands[1]) != LO_SUM)
2434 sparc_emit_set_const64 (operands[0], operands[1]);
2442 ;; Be careful, fmovd does not exist when !arch64.
2443 ;; We match MEM moves directly when we have correct even
2444 ;; numbered registers, but fall into splits otherwise.
2445 ;; The constraint ordering here is really important to
2446 ;; avoid insane problems in reload, especially for patterns
2449 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2450 ;; (const_int -5016)))
2454 (define_insn "*movdi_insn_sp32_v9"
2455 [(set (match_operand:DI 0 "nonimmediate_operand"
2456 "=m,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2457 (match_operand:DI 1 "input_operand"
2458 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2459 "! TARGET_ARCH64 && TARGET_V9
2460 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2474 [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2475 (set_attr "length" "*,*,*,2,2,2,2,*,*,2,2,2")])
2477 (define_insn "*movdi_insn_sp32"
2478 [(set (match_operand:DI 0 "nonimmediate_operand"
2479 "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2480 (match_operand:DI 1 "input_operand"
2481 " U,T,r,o,i,r, f, T, o, f, f"))]
2483 && (register_operand (operands[0], DImode)
2484 || register_operand (operands[1], DImode))"
2497 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2498 (set_attr "length" "*,*,2,2,2,2,*,*,2,2,2")])
2500 ;; The following are generated by sparc_emit_set_const64
2501 (define_insn "*movdi_sp64_dbl"
2502 [(set (match_operand:DI 0 "register_operand" "=r")
2503 (match_operand:DI 1 "const64_operand" ""))]
2505 && HOST_BITS_PER_WIDE_INT != 64)"
2508 ;; This is needed to show CSE exactly which bits are set
2509 ;; in a 64-bit register by sethi instructions.
2510 (define_insn "*movdi_const64_special"
2511 [(set (match_operand:DI 0 "register_operand" "=r")
2512 (match_operand:DI 1 "const64_high_operand" ""))]
2514 "sethi\\t%%hi(%a1), %0")
2516 (define_insn "*movdi_insn_sp64_novis"
2517 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2518 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e"))]
2519 "TARGET_ARCH64 && ! TARGET_VIS
2520 && (register_operand (operands[0], DImode)
2521 || reg_or_0_operand (operands[1], DImode))"
2524 sethi\\t%%hi(%a1), %0
2531 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2532 (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2534 (define_insn "*movdi_insn_sp64_vis"
2535 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2536 (match_operand:DI 1 "input_operand" "rI,N,J,m,rJ,e,m,e,J"))]
2537 "TARGET_ARCH64 && TARGET_VIS &&
2538 (register_operand (operands[0], DImode)
2539 || reg_or_0_operand (operands[1], DImode))"
2542 sethi\\t%%hi(%a1), %0
2550 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2551 (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2553 (define_expand "movdi_pic_label_ref"
2554 [(set (match_dup 3) (high:DI
2555 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2557 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2558 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2559 (set (match_operand:DI 0 "register_operand" "=r")
2560 (minus:DI (match_dup 5) (match_dup 4)))]
2561 "TARGET_ARCH64 && flag_pic"
2564 current_function_uses_pic_offset_table = 1;
2565 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2568 operands[3] = operands[0];
2569 operands[4] = operands[0];
2573 operands[3] = gen_reg_rtx (DImode);
2574 operands[4] = gen_reg_rtx (DImode);
2576 operands[5] = pic_offset_table_rtx;
2579 (define_insn "*movdi_high_pic_label_ref"
2580 [(set (match_operand:DI 0 "register_operand" "=r")
2582 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2583 (match_operand:DI 2 "" "")] 5)))]
2584 "TARGET_ARCH64 && flag_pic"
2585 "sethi\\t%%hi(%a2-(%a1-.)), %0")
2587 (define_insn "*movdi_lo_sum_pic_label_ref"
2588 [(set (match_operand:DI 0 "register_operand" "=r")
2589 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2590 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2591 (match_operand:DI 3 "" "")] 5)))]
2592 "TARGET_ARCH64 && flag_pic"
2593 "or\\t%1, %%lo(%a3-(%a2-.)), %0")
2595 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2596 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2598 (define_insn "movdi_lo_sum_pic"
2599 [(set (match_operand:DI 0 "register_operand" "=r")
2600 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2601 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2602 "TARGET_ARCH64 && flag_pic"
2603 "or\\t%1, %%lo(%a2), %0")
2605 (define_insn "movdi_high_pic"
2606 [(set (match_operand:DI 0 "register_operand" "=r")
2607 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2608 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2609 "sethi\\t%%hi(%a1), %0")
2611 (define_insn "*sethi_di_medlow_embmedany_pic"
2612 [(set (match_operand:DI 0 "register_operand" "=r")
2613 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2614 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2615 "sethi\\t%%hi(%a1), %0")
2617 (define_insn "*sethi_di_medlow"
2618 [(set (match_operand:DI 0 "register_operand" "=r")
2619 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2620 "TARGET_CM_MEDLOW && check_pic (1)"
2621 "sethi\\t%%hi(%a1), %0")
2623 (define_insn "*losum_di_medlow"
2624 [(set (match_operand:DI 0 "register_operand" "=r")
2625 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2626 (match_operand:DI 2 "symbolic_operand" "")))]
2628 "or\\t%1, %%lo(%a2), %0")
2630 (define_insn "seth44"
2631 [(set (match_operand:DI 0 "register_operand" "=r")
2632 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2634 "sethi\\t%%h44(%a1), %0")
2636 (define_insn "setm44"
2637 [(set (match_operand:DI 0 "register_operand" "=r")
2638 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2639 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2641 "or\\t%1, %%m44(%a2), %0")
2643 (define_insn "setl44"
2644 [(set (match_operand:DI 0 "register_operand" "=r")
2645 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2646 (match_operand:DI 2 "symbolic_operand" "")))]
2648 "or\\t%1, %%l44(%a2), %0")
2650 (define_insn "sethh"
2651 [(set (match_operand:DI 0 "register_operand" "=r")
2652 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2654 "sethi\\t%%hh(%a1), %0")
2656 (define_insn "setlm"
2657 [(set (match_operand:DI 0 "register_operand" "=r")
2658 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2660 "sethi\\t%%lm(%a1), %0")
2662 (define_insn "sethm"
2663 [(set (match_operand:DI 0 "register_operand" "=r")
2664 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2665 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2667 "or\\t%1, %%hm(%a2), %0")
2669 (define_insn "setlo"
2670 [(set (match_operand:DI 0 "register_operand" "=r")
2671 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2672 (match_operand:DI 2 "symbolic_operand" "")))]
2674 "or\\t%1, %%lo(%a2), %0")
2676 (define_insn "embmedany_sethi"
2677 [(set (match_operand:DI 0 "register_operand" "=r")
2678 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2679 "TARGET_CM_EMBMEDANY && check_pic (1)"
2680 "sethi\\t%%hi(%a1), %0")
2682 (define_insn "embmedany_losum"
2683 [(set (match_operand:DI 0 "register_operand" "=r")
2684 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2685 (match_operand:DI 2 "data_segment_operand" "")))]
2686 "TARGET_CM_EMBMEDANY"
2687 "add\\t%1, %%lo(%a2), %0")
2689 (define_insn "embmedany_brsum"
2690 [(set (match_operand:DI 0 "register_operand" "=r")
2691 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2692 "TARGET_CM_EMBMEDANY"
2695 (define_insn "embmedany_textuhi"
2696 [(set (match_operand:DI 0 "register_operand" "=r")
2697 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2698 "TARGET_CM_EMBMEDANY && check_pic (1)"
2699 "sethi\\t%%uhi(%a1), %0")
2701 (define_insn "embmedany_texthi"
2702 [(set (match_operand:DI 0 "register_operand" "=r")
2703 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2704 "TARGET_CM_EMBMEDANY && check_pic (1)"
2705 "sethi\\t%%hi(%a1), %0")
2707 (define_insn "embmedany_textulo"
2708 [(set (match_operand:DI 0 "register_operand" "=r")
2709 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2710 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2711 "TARGET_CM_EMBMEDANY"
2712 "or\\t%1, %%ulo(%a2), %0")
2714 (define_insn "embmedany_textlo"
2715 [(set (match_operand:DI 0 "register_operand" "=r")
2716 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2717 (match_operand:DI 2 "text_segment_operand" "")))]
2718 "TARGET_CM_EMBMEDANY"
2719 "or\\t%1, %%lo(%a2), %0")
2721 ;; Now some patterns to help reload out a bit.
2722 (define_expand "reload_indi"
2723 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2724 (match_operand:DI 1 "immediate_operand" "")
2725 (match_operand:TI 2 "register_operand" "=&r")])]
2727 || TARGET_CM_EMBMEDANY)
2731 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2735 (define_expand "reload_outdi"
2736 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2737 (match_operand:DI 1 "immediate_operand" "")
2738 (match_operand:TI 2 "register_operand" "=&r")])]
2740 || TARGET_CM_EMBMEDANY)
2744 sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2748 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2750 [(set (match_operand:DI 0 "register_operand" "")
2751 (match_operand:DI 1 "const_int_operand" ""))]
2752 "! TARGET_ARCH64 && reload_completed"
2753 [(clobber (const_int 0))]
2756 #if HOST_BITS_PER_WIDE_INT == 32
2757 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2758 (INTVAL (operands[1]) < 0) ?
2761 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2764 unsigned int low, high;
2766 low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2767 high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2768 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2770 /* Slick... but this trick loses if this subreg constant part
2771 can be done in one insn. */
2772 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2773 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2774 gen_highpart (SImode, operands[0])));
2776 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2782 [(set (match_operand:DI 0 "register_operand" "")
2783 (match_operand:DI 1 "const_double_operand" ""))]
2784 "! TARGET_ARCH64 && reload_completed"
2785 [(clobber (const_int 0))]
2788 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2789 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2791 /* Slick... but this trick loses if this subreg constant part
2792 can be done in one insn. */
2793 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2794 && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2795 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2797 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2798 gen_highpart (SImode, operands[0])));
2802 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2803 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2809 [(set (match_operand:DI 0 "register_operand" "")
2810 (match_operand:DI 1 "register_operand" ""))]
2811 "! TARGET_ARCH64 && reload_completed"
2812 [(clobber (const_int 0))]
2815 rtx set_dest = operands[0];
2816 rtx set_src = operands[1];
2820 dest1 = gen_highpart (SImode, set_dest);
2821 dest2 = gen_lowpart (SImode, set_dest);
2822 src1 = gen_highpart (SImode, set_src);
2823 src2 = gen_lowpart (SImode, set_src);
2825 /* Now emit using the real source and destination we found, swapping
2826 the order if we detect overlap. */
2827 if (reg_overlap_mentioned_p (dest1, src2))
2829 emit_insn (gen_movsi (dest2, src2));
2830 emit_insn (gen_movsi (dest1, src1));
2834 emit_insn (gen_movsi (dest1, src1));
2835 emit_insn (gen_movsi (dest2, src2));
2840 ;; Now handle the cases of memory moves from/to non-even
2841 ;; DI mode register pairs.
2843 [(set (match_operand:DI 0 "register_operand" "")
2844 (match_operand:DI 1 "memory_operand" ""))]
2847 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2848 [(clobber (const_int 0))]
2851 rtx word0 = adjust_address (operands[1], SImode, 0);
2852 rtx word1 = adjust_address (operands[1], SImode, 4);
2853 rtx high_part = gen_highpart (SImode, operands[0]);
2854 rtx low_part = gen_lowpart (SImode, operands[0]);
2856 if (reg_overlap_mentioned_p (high_part, word1))
2858 emit_insn (gen_movsi (low_part, word1));
2859 emit_insn (gen_movsi (high_part, word0));
2863 emit_insn (gen_movsi (high_part, word0));
2864 emit_insn (gen_movsi (low_part, word1));
2870 [(set (match_operand:DI 0 "memory_operand" "")
2871 (match_operand:DI 1 "register_operand" ""))]
2874 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2875 [(clobber (const_int 0))]
2878 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2879 gen_highpart (SImode, operands[1])));
2880 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2881 gen_lowpart (SImode, operands[1])));
2886 ;; Floating point move insns
2888 (define_insn "*movsf_insn_novis"
2889 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2890 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2891 "(TARGET_FPU && ! TARGET_VIS)
2892 && (register_operand (operands[0], SFmode)
2893 || register_operand (operands[1], SFmode)
2894 || fp_zero_operand (operands[1], SFmode))"
2897 if (GET_CODE (operands[1]) == CONST_DOUBLE
2898 && (which_alternative == 2
2899 || which_alternative == 3
2900 || which_alternative == 4))
2905 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2906 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2907 operands[1] = GEN_INT (i);
2910 switch (which_alternative)
2913 return \"fmovs\\t%1, %0\";
2915 return \"clr\\t%0\";
2917 return \"sethi\\t%%hi(%a1), %0\";
2919 return \"mov\\t%1, %0\";
2924 return \"ld\\t%1, %0\";
2927 return \"st\\t%r1, %0\";
2932 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2934 (define_insn "*movsf_insn_vis"
2935 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2936 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2937 "(TARGET_FPU && TARGET_VIS)
2938 && (register_operand (operands[0], SFmode)
2939 || register_operand (operands[1], SFmode)
2940 || fp_zero_operand (operands[1], SFmode))"
2943 if (GET_CODE (operands[1]) == CONST_DOUBLE
2944 && (which_alternative == 3
2945 || which_alternative == 4
2946 || which_alternative == 5))
2951 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2952 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2953 operands[1] = GEN_INT (i);
2956 switch (which_alternative)
2959 return \"fmovs\\t%1, %0\";
2961 return \"fzeros\\t%0\";
2963 return \"clr\\t%0\";
2965 return \"sethi\\t%%hi(%a1), %0\";
2967 return \"mov\\t%1, %0\";
2972 return \"ld\\t%1, %0\";
2975 return \"st\\t%r1, %0\";
2980 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
2982 ;; Exactly the same as above, except that all `f' cases are deleted.
2983 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2986 (define_insn "*movsf_no_f_insn"
2987 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2988 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
2990 && (register_operand (operands[0], SFmode)
2991 || register_operand (operands[1], SFmode)
2992 || fp_zero_operand (operands[1], SFmode))"
2995 if (GET_CODE (operands[1]) == CONST_DOUBLE
2996 && (which_alternative == 1
2997 || which_alternative == 2
2998 || which_alternative == 3))
3003 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3004 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3005 operands[1] = GEN_INT (i);
3008 switch (which_alternative)
3011 return \"clr\\t%0\";
3013 return \"sethi\\t%%hi(%a1), %0\";
3015 return \"mov\\t%1, %0\";
3019 return \"ld\\t%1, %0\";
3021 return \"st\\t%r1, %0\";
3026 [(set_attr "type" "*,*,*,*,load,store")])
3028 (define_insn "*movsf_lo_sum"
3029 [(set (match_operand:SF 0 "register_operand" "=r")
3030 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3031 (match_operand:SF 2 "const_double_operand" "S")))]
3032 "fp_high_losum_p (operands[2])"
3038 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3039 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3040 operands[2] = GEN_INT (i);
3041 return \"or\\t%1, %%lo(%a2), %0\";
3044 (define_insn "*movsf_high"
3045 [(set (match_operand:SF 0 "register_operand" "=r")
3046 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3047 "fp_high_losum_p (operands[1])"
3053 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3054 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3055 operands[1] = GEN_INT (i);
3056 return \"sethi\\t%%hi(%1), %0\";
3060 [(set (match_operand:SF 0 "register_operand" "")
3061 (match_operand:SF 1 "const_double_operand" ""))]
3062 "fp_high_losum_p (operands[1])
3063 && (GET_CODE (operands[0]) == REG
3064 && REGNO (operands[0]) < 32)"
3065 [(set (match_dup 0) (high:SF (match_dup 1)))
3066 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3068 (define_expand "movsf"
3069 [(set (match_operand:SF 0 "general_operand" "")
3070 (match_operand:SF 1 "general_operand" ""))]
3074 /* Force SFmode constants into memory. */
3075 if (GET_CODE (operands[0]) == REG
3076 && CONSTANT_P (operands[1]))
3078 /* emit_group_store will send such bogosity to us when it is
3079 not storing directly into memory. So fix this up to avoid
3080 crashes in output_constant_pool. */
3081 if (operands [1] == const0_rtx)
3082 operands[1] = CONST0_RTX (SFmode);
3084 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3087 /* We are able to build any SF constant in integer registers
3088 with at most 2 instructions. */
3089 if (REGNO (operands[0]) < 32)
3092 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3096 /* Handle sets of MEM first. */
3097 if (GET_CODE (operands[0]) == MEM)
3099 if (register_operand (operands[1], SFmode)
3100 || fp_zero_operand (operands[1], SFmode))
3103 if (! reload_in_progress)
3105 operands[0] = validize_mem (operands[0]);
3106 operands[1] = force_reg (SFmode, operands[1]);
3110 /* Fixup PIC cases. */
3113 if (CONSTANT_P (operands[1])
3114 && pic_address_needs_scratch (operands[1]))
3115 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3117 if (symbolic_operand (operands[1], SFmode))
3119 operands[1] = legitimize_pic_address (operands[1],
3121 (reload_in_progress ?
3131 (define_expand "movdf"
3132 [(set (match_operand:DF 0 "general_operand" "")
3133 (match_operand:DF 1 "general_operand" ""))]
3137 /* Force DFmode constants into memory. */
3138 if (GET_CODE (operands[0]) == REG
3139 && CONSTANT_P (operands[1]))
3141 /* emit_group_store will send such bogosity to us when it is
3142 not storing directly into memory. So fix this up to avoid
3143 crashes in output_constant_pool. */
3144 if (operands [1] == const0_rtx)
3145 operands[1] = CONST0_RTX (DFmode);
3147 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3148 && fp_zero_operand (operands[1], DFmode))
3151 /* We are able to build any DF constant in integer registers. */
3152 if (REGNO (operands[0]) < 32
3153 && (reload_completed || reload_in_progress))
3156 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3160 /* Handle MEM cases first. */
3161 if (GET_CODE (operands[0]) == MEM)
3163 if (register_operand (operands[1], DFmode)
3164 || fp_zero_operand (operands[1], DFmode))
3167 if (! reload_in_progress)
3169 operands[0] = validize_mem (operands[0]);
3170 operands[1] = force_reg (DFmode, operands[1]);
3174 /* Fixup PIC cases. */
3177 if (CONSTANT_P (operands[1])
3178 && pic_address_needs_scratch (operands[1]))
3179 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3181 if (symbolic_operand (operands[1], DFmode))
3183 operands[1] = legitimize_pic_address (operands[1],
3185 (reload_in_progress ?
3195 ;; Be careful, fmovd does not exist when !v9.
3196 (define_insn "*movdf_insn_sp32"
3197 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3198 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3201 && (register_operand (operands[0], DFmode)
3202 || register_operand (operands[1], DFmode)
3203 || fp_zero_operand (operands[1], DFmode))"
3215 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3216 (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
3218 (define_insn "*movdf_no_e_insn_sp32"
3219 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3220 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3224 && (register_operand (operands[0], DFmode)
3225 || register_operand (operands[1], DFmode)
3226 || fp_zero_operand (operands[1], DFmode))"
3233 [(set_attr "type" "load,store,*,*,*")
3234 (set_attr "length" "*,*,2,2,2")])
3236 (define_insn "*movdf_no_e_insn_v9_sp32"
3237 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3238 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3242 && (register_operand (operands[0], DFmode)
3243 || register_operand (operands[1], DFmode)
3244 || fp_zero_operand (operands[1], DFmode))"
3251 [(set_attr "type" "load,store,store,*,*")
3252 (set_attr "length" "*,*,*,2,2")])
3254 ;; We have available v9 double floats but not 64-bit
3255 ;; integer registers and no VIS.
3256 (define_insn "*movdf_insn_v9only_novis"
3257 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3258 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3263 && (register_operand (operands[0], DFmode)
3264 || register_operand (operands[1], DFmode)
3265 || fp_zero_operand (operands[1], DFmode))"
3276 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3277 (set_attr "length" "*,*,*,*,*,*,2,2,2")
3278 (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
3280 ;; We have available v9 double floats but not 64-bit
3281 ;; integer registers but we have VIS.
3282 (define_insn "*movdf_insn_v9only_vis"
3283 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3284 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3288 && (register_operand (operands[0], DFmode)
3289 || register_operand (operands[1], DFmode)
3290 || fp_zero_operand (operands[1], DFmode))"
3302 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3303 (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3304 (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3306 ;; We have available both v9 double floats and 64-bit
3307 ;; integer registers. No VIS though.
3308 (define_insn "*movdf_insn_sp64_novis"
3309 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3310 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3314 && (register_operand (operands[0], DFmode)
3315 || register_operand (operands[1], DFmode)
3316 || fp_zero_operand (operands[1], DFmode))"
3325 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3326 (set_attr "length" "*,*,*,*,*,*,2")
3327 (set_attr "fptype" "double,*,*,*,*,*,*")])
3329 ;; We have available both v9 double floats and 64-bit
3330 ;; integer registers. And we have VIS.
3331 (define_insn "*movdf_insn_sp64_vis"
3332 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3333 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3337 && (register_operand (operands[0], DFmode)
3338 || register_operand (operands[1], DFmode)
3339 || fp_zero_operand (operands[1], DFmode))"
3349 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3350 (set_attr "length" "*,*,*,*,*,*,*,2")
3351 (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3353 (define_insn "*movdf_no_e_insn_sp64"
3354 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3355 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3358 && (register_operand (operands[0], DFmode)
3359 || register_operand (operands[1], DFmode)
3360 || fp_zero_operand (operands[1], DFmode))"
3365 [(set_attr "type" "*,load,store")])
3368 [(set (match_operand:DF 0 "register_operand" "")
3369 (match_operand:DF 1 "const_double_operand" ""))]
3371 && (GET_CODE (operands[0]) == REG
3372 && REGNO (operands[0]) < 32)
3373 && ! fp_zero_operand(operands[1], DFmode)
3374 && reload_completed"
3375 [(clobber (const_int 0))]
3381 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3382 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3383 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3387 #if HOST_BITS_PER_WIDE_INT == 64
3390 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3391 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3392 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3394 emit_insn (gen_movdi (operands[0],
3395 gen_rtx_CONST_DOUBLE (VOIDmode, l[1], l[0])));
3400 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3403 /* Slick... but this trick loses if this subreg constant part
3404 can be done in one insn. */
3406 && !(SPARC_SETHI32_P (l[0])
3407 || SPARC_SIMM13_P (l[0])))
3409 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3410 gen_highpart (SImode, operands[0])));
3414 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3421 ;; Ok, now the splits to handle all the multi insn and
3422 ;; mis-aligned memory address cases.
3423 ;; In these splits please take note that we must be
3424 ;; careful when V9 but not ARCH64 because the integer
3425 ;; register DFmode cases must be handled.
3427 [(set (match_operand:DF 0 "register_operand" "")
3428 (match_operand:DF 1 "register_operand" ""))]
3431 && ((GET_CODE (operands[0]) == REG
3432 && REGNO (operands[0]) < 32)
3433 || (GET_CODE (operands[0]) == SUBREG
3434 && GET_CODE (SUBREG_REG (operands[0])) == REG
3435 && REGNO (SUBREG_REG (operands[0])) < 32))))
3436 && reload_completed"
3437 [(clobber (const_int 0))]
3440 rtx set_dest = operands[0];
3441 rtx set_src = operands[1];
3445 dest1 = gen_highpart (SFmode, set_dest);
3446 dest2 = gen_lowpart (SFmode, set_dest);
3447 src1 = gen_highpart (SFmode, set_src);
3448 src2 = gen_lowpart (SFmode, set_src);
3450 /* Now emit using the real source and destination we found, swapping
3451 the order if we detect overlap. */
3452 if (reg_overlap_mentioned_p (dest1, src2))
3454 emit_insn (gen_movsf (dest2, src2));
3455 emit_insn (gen_movsf (dest1, src1));
3459 emit_insn (gen_movsf (dest1, src1));
3460 emit_insn (gen_movsf (dest2, src2));
3466 [(set (match_operand:DF 0 "register_operand" "")
3467 (match_operand:DF 1 "memory_operand" ""))]
3470 && (((REGNO (operands[0]) % 2) != 0)
3471 || ! mem_min_alignment (operands[1], 8))
3472 && offsettable_memref_p (operands[1])"
3473 [(clobber (const_int 0))]
3476 rtx word0 = adjust_address (operands[1], SFmode, 0);
3477 rtx word1 = adjust_address (operands[1], SFmode, 4);
3479 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3481 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3483 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3488 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3490 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3497 [(set (match_operand:DF 0 "memory_operand" "")
3498 (match_operand:DF 1 "register_operand" ""))]
3501 && (((REGNO (operands[1]) % 2) != 0)
3502 || ! mem_min_alignment (operands[0], 8))
3503 && offsettable_memref_p (operands[0])"
3504 [(clobber (const_int 0))]
3507 rtx word0 = adjust_address (operands[0], SFmode, 0);
3508 rtx word1 = adjust_address (operands[0], SFmode, 4);
3510 emit_insn (gen_movsf (word0,
3511 gen_highpart (SFmode, operands[1])));
3512 emit_insn (gen_movsf (word1,
3513 gen_lowpart (SFmode, operands[1])));
3518 [(set (match_operand:DF 0 "memory_operand" "")
3519 (match_operand:DF 1 "fp_zero_operand" ""))]
3523 && ! mem_min_alignment (operands[0], 8)))
3524 && offsettable_memref_p (operands[0])"
3525 [(clobber (const_int 0))]
3530 dest1 = adjust_address (operands[0], SFmode, 0);
3531 dest2 = adjust_address (operands[0], SFmode, 4);
3533 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3534 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3539 [(set (match_operand:DF 0 "register_operand" "")
3540 (match_operand:DF 1 "fp_zero_operand" ""))]
3543 && ((GET_CODE (operands[0]) == REG
3544 && REGNO (operands[0]) < 32)
3545 || (GET_CODE (operands[0]) == SUBREG
3546 && GET_CODE (SUBREG_REG (operands[0])) == REG
3547 && REGNO (SUBREG_REG (operands[0])) < 32))"
3548 [(clobber (const_int 0))]
3551 rtx set_dest = operands[0];
3554 dest1 = gen_highpart (SFmode, set_dest);
3555 dest2 = gen_lowpart (SFmode, set_dest);
3556 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3557 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3561 (define_expand "movtf"
3562 [(set (match_operand:TF 0 "general_operand" "")
3563 (match_operand:TF 1 "general_operand" ""))]
3567 /* Force TFmode constants into memory. */
3568 if (GET_CODE (operands[0]) == REG
3569 && CONSTANT_P (operands[1]))
3571 /* emit_group_store will send such bogosity to us when it is
3572 not storing directly into memory. So fix this up to avoid
3573 crashes in output_constant_pool. */
3574 if (operands [1] == const0_rtx)
3575 operands[1] = CONST0_RTX (TFmode);
3577 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3580 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3584 /* Handle MEM cases first, note that only v9 guarentees
3585 full 16-byte alignment for quads. */
3586 if (GET_CODE (operands[0]) == MEM)
3588 if (register_operand (operands[1], TFmode)
3589 || fp_zero_operand (operands[1], TFmode))
3592 if (! reload_in_progress)
3594 operands[0] = validize_mem (operands[0]);
3595 operands[1] = force_reg (TFmode, operands[1]);
3599 /* Fixup PIC cases. */
3602 if (CONSTANT_P (operands[1])
3603 && pic_address_needs_scratch (operands[1]))
3604 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3606 if (symbolic_operand (operands[1], TFmode))
3608 operands[1] = legitimize_pic_address (operands[1],
3610 (reload_in_progress ?
3620 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3621 ;; we must split them all. :-(
3622 (define_insn "*movtf_insn_sp32"
3623 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3624 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3628 && (register_operand (operands[0], TFmode)
3629 || register_operand (operands[1], TFmode)
3630 || fp_zero_operand (operands[1], TFmode))"
3632 [(set_attr "length" "4")])
3634 (define_insn "*movtf_insn_vis_sp32"
3635 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3636 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3640 && (register_operand (operands[0], TFmode)
3641 || register_operand (operands[1], TFmode)
3642 || fp_zero_operand (operands[1], TFmode))"
3644 [(set_attr "length" "4")])
3646 ;; Exactly the same as above, except that all `e' cases are deleted.
3647 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3650 (define_insn "*movtf_no_e_insn_sp32"
3651 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3652 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3655 && (register_operand (operands[0], TFmode)
3656 || register_operand (operands[1], TFmode)
3657 || fp_zero_operand (operands[1], TFmode))"
3659 [(set_attr "length" "4")])
3661 ;; Now handle the float reg cases directly when arch64,
3662 ;; hard_quad, and proper reg number alignment are all true.
3663 (define_insn "*movtf_insn_hq_sp64"
3664 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3665 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3670 && (register_operand (operands[0], TFmode)
3671 || register_operand (operands[1], TFmode)
3672 || fp_zero_operand (operands[1], TFmode))"
3679 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3680 (set_attr "length" "*,*,*,2,2")])
3682 (define_insn "*movtf_insn_hq_vis_sp64"
3683 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3684 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3689 && (register_operand (operands[0], TFmode)
3690 || register_operand (operands[1], TFmode)
3691 || fp_zero_operand (operands[1], TFmode))"
3699 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3700 (set_attr "length" "*,*,*,2,2,2")])
3702 ;; Now we allow the integer register cases even when
3703 ;; only arch64 is true.
3704 (define_insn "*movtf_insn_sp64"
3705 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3706 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3710 && ! TARGET_HARD_QUAD
3711 && (register_operand (operands[0], TFmode)
3712 || register_operand (operands[1], TFmode)
3713 || fp_zero_operand (operands[1], TFmode))"
3715 [(set_attr "length" "2")])
3717 (define_insn "*movtf_insn_vis_sp64"
3718 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3719 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3723 && ! TARGET_HARD_QUAD
3724 && (register_operand (operands[0], TFmode)
3725 || register_operand (operands[1], TFmode)
3726 || fp_zero_operand (operands[1], TFmode))"
3728 [(set_attr "length" "2")])
3730 (define_insn "*movtf_no_e_insn_sp64"
3731 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3732 (match_operand:TF 1 "input_operand" "orG,rG"))]
3735 && (register_operand (operands[0], TFmode)
3736 || register_operand (operands[1], TFmode)
3737 || fp_zero_operand (operands[1], TFmode))"
3739 [(set_attr "length" "2")])
3741 ;; Now all the splits to handle multi-insn TF mode moves.
3743 [(set (match_operand:TF 0 "register_operand" "")
3744 (match_operand:TF 1 "register_operand" ""))]
3748 && ! TARGET_HARD_QUAD))"
3749 [(clobber (const_int 0))]
3752 rtx set_dest = operands[0];
3753 rtx set_src = operands[1];
3757 dest1 = gen_df_reg (set_dest, 0);
3758 dest2 = gen_df_reg (set_dest, 1);
3759 src1 = gen_df_reg (set_src, 0);
3760 src2 = gen_df_reg (set_src, 1);
3762 /* Now emit using the real source and destination we found, swapping
3763 the order if we detect overlap. */
3764 if (reg_overlap_mentioned_p (dest1, src2))
3766 emit_insn (gen_movdf (dest2, src2));
3767 emit_insn (gen_movdf (dest1, src1));
3771 emit_insn (gen_movdf (dest1, src1));
3772 emit_insn (gen_movdf (dest2, src2));
3778 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3779 (match_operand:TF 1 "fp_zero_operand" ""))]
3781 [(clobber (const_int 0))]
3784 rtx set_dest = operands[0];
3787 switch (GET_CODE (set_dest))
3790 dest1 = gen_df_reg (set_dest, 0);
3791 dest2 = gen_df_reg (set_dest, 1);
3794 dest1 = adjust_address (set_dest, DFmode, 0);
3795 dest2 = adjust_address (set_dest, DFmode, 8);
3801 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3802 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3807 [(set (match_operand:TF 0 "register_operand" "")
3808 (match_operand:TF 1 "memory_operand" ""))]
3810 && offsettable_memref_p (operands[1]))"
3811 [(clobber (const_int 0))]
3814 rtx word0 = adjust_address (operands[1], DFmode, 0);
3815 rtx word1 = adjust_address (operands[1], DFmode, 8);
3816 rtx set_dest, dest1, dest2;
3818 set_dest = operands[0];
3820 dest1 = gen_df_reg (set_dest, 0);
3821 dest2 = gen_df_reg (set_dest, 1);
3823 /* Now output, ordering such that we don't clobber any registers
3824 mentioned in the address. */
3825 if (reg_overlap_mentioned_p (dest1, word1))
3828 emit_insn (gen_movdf (dest2, word1));
3829 emit_insn (gen_movdf (dest1, word0));
3833 emit_insn (gen_movdf (dest1, word0));
3834 emit_insn (gen_movdf (dest2, word1));
3840 [(set (match_operand:TF 0 "memory_operand" "")
3841 (match_operand:TF 1 "register_operand" ""))]
3843 && offsettable_memref_p (operands[0]))"
3844 [(clobber (const_int 0))]
3847 rtx set_src = operands[1];
3849 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3850 gen_df_reg (set_src, 0)));
3851 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3852 gen_df_reg (set_src, 1)));
3856 ;; Sparc V9 conditional move instructions.
3858 ;; We can handle larger constants here for some flavors, but for now we keep
3859 ;; it simple and only allow those constants supported by all flavours.
3860 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3861 ;; 3 contains the constant if one is present, but we handle either for
3862 ;; generality (sparc.c puts a constant in operand 2).
3864 (define_expand "movqicc"
3865 [(set (match_operand:QI 0 "register_operand" "")
3866 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3867 (match_operand:QI 2 "arith10_operand" "")
3868 (match_operand:QI 3 "arith10_operand" "")))]
3872 enum rtx_code code = GET_CODE (operands[1]);
3874 if (GET_MODE (sparc_compare_op0) == DImode
3878 if (sparc_compare_op1 == const0_rtx
3879 && GET_CODE (sparc_compare_op0) == REG
3880 && GET_MODE (sparc_compare_op0) == DImode
3881 && v9_regcmp_p (code))
3883 operands[1] = gen_rtx_fmt_ee (code, DImode,
3884 sparc_compare_op0, sparc_compare_op1);
3888 rtx cc_reg = gen_compare_reg (code,
3889 sparc_compare_op0, sparc_compare_op1);
3890 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3894 (define_expand "movhicc"
3895 [(set (match_operand:HI 0 "register_operand" "")
3896 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3897 (match_operand:HI 2 "arith10_operand" "")
3898 (match_operand:HI 3 "arith10_operand" "")))]
3902 enum rtx_code code = GET_CODE (operands[1]);
3904 if (GET_MODE (sparc_compare_op0) == DImode
3908 if (sparc_compare_op1 == const0_rtx
3909 && GET_CODE (sparc_compare_op0) == REG
3910 && GET_MODE (sparc_compare_op0) == DImode
3911 && v9_regcmp_p (code))
3913 operands[1] = gen_rtx_fmt_ee (code, DImode,
3914 sparc_compare_op0, sparc_compare_op1);
3918 rtx cc_reg = gen_compare_reg (code,
3919 sparc_compare_op0, sparc_compare_op1);
3920 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3924 (define_expand "movsicc"
3925 [(set (match_operand:SI 0 "register_operand" "")
3926 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3927 (match_operand:SI 2 "arith10_operand" "")
3928 (match_operand:SI 3 "arith10_operand" "")))]
3932 enum rtx_code code = GET_CODE (operands[1]);
3933 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3935 if (sparc_compare_op1 == const0_rtx
3936 && GET_CODE (sparc_compare_op0) == REG
3937 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3939 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3940 sparc_compare_op0, sparc_compare_op1);
3944 rtx cc_reg = gen_compare_reg (code,
3945 sparc_compare_op0, sparc_compare_op1);
3946 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3947 cc_reg, const0_rtx);
3951 (define_expand "movdicc"
3952 [(set (match_operand:DI 0 "register_operand" "")
3953 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3954 (match_operand:DI 2 "arith10_double_operand" "")
3955 (match_operand:DI 3 "arith10_double_operand" "")))]
3959 enum rtx_code code = GET_CODE (operands[1]);
3961 if (sparc_compare_op1 == const0_rtx
3962 && GET_CODE (sparc_compare_op0) == REG
3963 && GET_MODE (sparc_compare_op0) == DImode
3964 && v9_regcmp_p (code))
3966 operands[1] = gen_rtx_fmt_ee (code, DImode,
3967 sparc_compare_op0, sparc_compare_op1);
3971 rtx cc_reg = gen_compare_reg (code,
3972 sparc_compare_op0, sparc_compare_op1);
3973 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3974 cc_reg, const0_rtx);
3978 (define_expand "movsfcc"
3979 [(set (match_operand:SF 0 "register_operand" "")
3980 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3981 (match_operand:SF 2 "register_operand" "")
3982 (match_operand:SF 3 "register_operand" "")))]
3983 "TARGET_V9 && TARGET_FPU"
3986 enum rtx_code code = GET_CODE (operands[1]);
3988 if (GET_MODE (sparc_compare_op0) == DImode
3992 if (sparc_compare_op1 == const0_rtx
3993 && GET_CODE (sparc_compare_op0) == REG
3994 && GET_MODE (sparc_compare_op0) == DImode
3995 && v9_regcmp_p (code))
3997 operands[1] = gen_rtx_fmt_ee (code, DImode,
3998 sparc_compare_op0, sparc_compare_op1);
4002 rtx cc_reg = gen_compare_reg (code,
4003 sparc_compare_op0, sparc_compare_op1);
4004 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4008 (define_expand "movdfcc"
4009 [(set (match_operand:DF 0 "register_operand" "")
4010 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4011 (match_operand:DF 2 "register_operand" "")
4012 (match_operand:DF 3 "register_operand" "")))]
4013 "TARGET_V9 && TARGET_FPU"
4016 enum rtx_code code = GET_CODE (operands[1]);
4018 if (GET_MODE (sparc_compare_op0) == DImode
4022 if (sparc_compare_op1 == const0_rtx
4023 && GET_CODE (sparc_compare_op0) == REG
4024 && GET_MODE (sparc_compare_op0) == DImode
4025 && v9_regcmp_p (code))
4027 operands[1] = gen_rtx_fmt_ee (code, DImode,
4028 sparc_compare_op0, sparc_compare_op1);
4032 rtx cc_reg = gen_compare_reg (code,
4033 sparc_compare_op0, sparc_compare_op1);
4034 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4038 (define_expand "movtfcc"
4039 [(set (match_operand:TF 0 "register_operand" "")
4040 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4041 (match_operand:TF 2 "register_operand" "")
4042 (match_operand:TF 3 "register_operand" "")))]
4043 "TARGET_V9 && TARGET_FPU"
4046 enum rtx_code code = GET_CODE (operands[1]);
4048 if (GET_MODE (sparc_compare_op0) == DImode
4052 if (sparc_compare_op1 == const0_rtx
4053 && GET_CODE (sparc_compare_op0) == REG
4054 && GET_MODE (sparc_compare_op0) == DImode
4055 && v9_regcmp_p (code))
4057 operands[1] = gen_rtx_fmt_ee (code, DImode,
4058 sparc_compare_op0, sparc_compare_op1);
4062 rtx cc_reg = gen_compare_reg (code,
4063 sparc_compare_op0, sparc_compare_op1);
4064 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4068 ;; Conditional move define_insns.
4070 (define_insn "*movqi_cc_sp64"
4071 [(set (match_operand:QI 0 "register_operand" "=r,r")
4072 (if_then_else:QI (match_operator 1 "comparison_operator"
4073 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4075 (match_operand:QI 3 "arith11_operand" "rL,0")
4076 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4079 mov%C1\\t%x2, %3, %0
4080 mov%c1\\t%x2, %4, %0"
4081 [(set_attr "type" "cmove")])
4083 (define_insn "*movhi_cc_sp64"
4084 [(set (match_operand:HI 0 "register_operand" "=r,r")
4085 (if_then_else:HI (match_operator 1 "comparison_operator"
4086 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4088 (match_operand:HI 3 "arith11_operand" "rL,0")
4089 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4092 mov%C1\\t%x2, %3, %0
4093 mov%c1\\t%x2, %4, %0"
4094 [(set_attr "type" "cmove")])
4096 (define_insn "*movsi_cc_sp64"
4097 [(set (match_operand:SI 0 "register_operand" "=r,r")
4098 (if_then_else:SI (match_operator 1 "comparison_operator"
4099 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4101 (match_operand:SI 3 "arith11_operand" "rL,0")
4102 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4105 mov%C1\\t%x2, %3, %0
4106 mov%c1\\t%x2, %4, %0"
4107 [(set_attr "type" "cmove")])
4109 ;; ??? The constraints of operands 3,4 need work.
4110 (define_insn "*movdi_cc_sp64"
4111 [(set (match_operand:DI 0 "register_operand" "=r,r")
4112 (if_then_else:DI (match_operator 1 "comparison_operator"
4113 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4115 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4116 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4119 mov%C1\\t%x2, %3, %0
4120 mov%c1\\t%x2, %4, %0"
4121 [(set_attr "type" "cmove")])
4123 (define_insn "*movdi_cc_sp64_trunc"
4124 [(set (match_operand:SI 0 "register_operand" "=r,r")
4125 (if_then_else:SI (match_operator 1 "comparison_operator"
4126 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4128 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4129 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4132 mov%C1\\t%x2, %3, %0
4133 mov%c1\\t%x2, %4, %0"
4134 [(set_attr "type" "cmove")])
4136 (define_insn "*movsf_cc_sp64"
4137 [(set (match_operand:SF 0 "register_operand" "=f,f")
4138 (if_then_else:SF (match_operator 1 "comparison_operator"
4139 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4141 (match_operand:SF 3 "register_operand" "f,0")
4142 (match_operand:SF 4 "register_operand" "0,f")))]
4143 "TARGET_V9 && TARGET_FPU"
4145 fmovs%C1\\t%x2, %3, %0
4146 fmovs%c1\\t%x2, %4, %0"
4147 [(set_attr "type" "fpcmove")])
4149 (define_insn "movdf_cc_sp64"
4150 [(set (match_operand:DF 0 "register_operand" "=e,e")
4151 (if_then_else:DF (match_operator 1 "comparison_operator"
4152 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4154 (match_operand:DF 3 "register_operand" "e,0")
4155 (match_operand:DF 4 "register_operand" "0,e")))]
4156 "TARGET_V9 && TARGET_FPU"
4158 fmovd%C1\\t%x2, %3, %0
4159 fmovd%c1\\t%x2, %4, %0"
4160 [(set_attr "type" "fpcmove")
4161 (set_attr "fptype" "double")])
4163 (define_insn "*movtf_cc_hq_sp64"
4164 [(set (match_operand:TF 0 "register_operand" "=e,e")
4165 (if_then_else:TF (match_operator 1 "comparison_operator"
4166 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4168 (match_operand:TF 3 "register_operand" "e,0")
4169 (match_operand:TF 4 "register_operand" "0,e")))]
4170 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4172 fmovq%C1\\t%x2, %3, %0
4173 fmovq%c1\\t%x2, %4, %0"
4174 [(set_attr "type" "fpcmove")])
4176 (define_insn "*movtf_cc_sp64"
4177 [(set (match_operand:TF 0 "register_operand" "=e,e")
4178 (if_then_else:TF (match_operator 1 "comparison_operator"
4179 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4181 (match_operand:TF 3 "register_operand" "e,0")
4182 (match_operand:TF 4 "register_operand" "0,e")))]
4183 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4185 [(set_attr "length" "2")])
4188 [(set (match_operand:TF 0 "register_operand" "")
4189 (if_then_else:TF (match_operator 1 "comparison_operator"
4190 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4192 (match_operand:TF 3 "register_operand" "")
4193 (match_operand:TF 4 "register_operand" "")))]
4194 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4195 [(clobber (const_int 0))]
4198 rtx set_dest = operands[0];
4199 rtx set_srca = operands[3];
4200 rtx set_srcb = operands[4];
4201 int third = rtx_equal_p (set_dest, set_srca);
4203 rtx srca1, srca2, srcb1, srcb2;
4205 dest1 = gen_df_reg (set_dest, 0);
4206 dest2 = gen_df_reg (set_dest, 1);
4207 srca1 = gen_df_reg (set_srca, 0);
4208 srca2 = gen_df_reg (set_srca, 1);
4209 srcb1 = gen_df_reg (set_srcb, 0);
4210 srcb2 = gen_df_reg (set_srcb, 1);
4212 /* Now emit using the real source and destination we found, swapping
4213 the order if we detect overlap. */
4214 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4215 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4217 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4218 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4222 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4223 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4228 (define_insn "*movqi_cc_reg_sp64"
4229 [(set (match_operand:QI 0 "register_operand" "=r,r")
4230 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4231 [(match_operand:DI 2 "register_operand" "r,r")
4233 (match_operand:QI 3 "arith10_operand" "rM,0")
4234 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4237 movr%D1\\t%2, %r3, %0
4238 movr%d1\\t%2, %r4, %0"
4239 [(set_attr "type" "cmove")])
4241 (define_insn "*movhi_cc_reg_sp64"
4242 [(set (match_operand:HI 0 "register_operand" "=r,r")
4243 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4244 [(match_operand:DI 2 "register_operand" "r,r")
4246 (match_operand:HI 3 "arith10_operand" "rM,0")
4247 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4250 movr%D1\\t%2, %r3, %0
4251 movr%d1\\t%2, %r4, %0"
4252 [(set_attr "type" "cmove")])
4254 (define_insn "*movsi_cc_reg_sp64"
4255 [(set (match_operand:SI 0 "register_operand" "=r,r")
4256 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4257 [(match_operand:DI 2 "register_operand" "r,r")
4259 (match_operand:SI 3 "arith10_operand" "rM,0")
4260 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4263 movr%D1\\t%2, %r3, %0
4264 movr%d1\\t%2, %r4, %0"
4265 [(set_attr "type" "cmove")])
4267 ;; ??? The constraints of operands 3,4 need work.
4268 (define_insn "*movdi_cc_reg_sp64"
4269 [(set (match_operand:DI 0 "register_operand" "=r,r")
4270 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4271 [(match_operand:DI 2 "register_operand" "r,r")
4273 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4274 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4277 movr%D1\\t%2, %r3, %0
4278 movr%d1\\t%2, %r4, %0"
4279 [(set_attr "type" "cmove")])
4281 (define_insn "*movdi_cc_reg_sp64_trunc"
4282 [(set (match_operand:SI 0 "register_operand" "=r,r")
4283 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4284 [(match_operand:DI 2 "register_operand" "r,r")
4286 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4287 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4290 movr%D1\\t%2, %r3, %0
4291 movr%d1\\t%2, %r4, %0"
4292 [(set_attr "type" "cmove")])
4294 (define_insn "*movsf_cc_reg_sp64"
4295 [(set (match_operand:SF 0 "register_operand" "=f,f")
4296 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4297 [(match_operand:DI 2 "register_operand" "r,r")
4299 (match_operand:SF 3 "register_operand" "f,0")
4300 (match_operand:SF 4 "register_operand" "0,f")))]
4301 "TARGET_ARCH64 && TARGET_FPU"
4303 fmovrs%D1\\t%2, %3, %0
4304 fmovrs%d1\\t%2, %4, %0"
4305 [(set_attr "type" "fpcmove")])
4307 (define_insn "movdf_cc_reg_sp64"
4308 [(set (match_operand:DF 0 "register_operand" "=e,e")
4309 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4310 [(match_operand:DI 2 "register_operand" "r,r")
4312 (match_operand:DF 3 "register_operand" "e,0")
4313 (match_operand:DF 4 "register_operand" "0,e")))]
4314 "TARGET_ARCH64 && TARGET_FPU"
4316 fmovrd%D1\\t%2, %3, %0
4317 fmovrd%d1\\t%2, %4, %0"
4318 [(set_attr "type" "fpcmove")
4319 (set_attr "fptype" "double")])
4321 (define_insn "*movtf_cc_reg_hq_sp64"
4322 [(set (match_operand:TF 0 "register_operand" "=e,e")
4323 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4324 [(match_operand:DI 2 "register_operand" "r,r")
4326 (match_operand:TF 3 "register_operand" "e,0")
4327 (match_operand:TF 4 "register_operand" "0,e")))]
4328 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4330 fmovrq%D1\\t%2, %3, %0
4331 fmovrq%d1\\t%2, %4, %0"
4332 [(set_attr "type" "fpcmove")])
4334 (define_insn "*movtf_cc_reg_sp64"
4335 [(set (match_operand:TF 0 "register_operand" "=e,e")
4336 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4337 [(match_operand:DI 2 "register_operand" "r,r")
4339 (match_operand:TF 3 "register_operand" "e,0")
4340 (match_operand:TF 4 "register_operand" "0,e")))]
4341 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4343 [(set_attr "length" "2")])
4346 [(set (match_operand:TF 0 "register_operand" "")
4347 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4348 [(match_operand:DI 2 "register_operand" "")
4350 (match_operand:TF 3 "register_operand" "")
4351 (match_operand:TF 4 "register_operand" "")))]
4352 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4353 [(clobber (const_int 0))]
4356 rtx set_dest = operands[0];
4357 rtx set_srca = operands[3];
4358 rtx set_srcb = operands[4];
4359 int third = rtx_equal_p (set_dest, set_srca);
4361 rtx srca1, srca2, srcb1, srcb2;
4363 dest1 = gen_df_reg (set_dest, 0);
4364 dest2 = gen_df_reg (set_dest, 1);
4365 srca1 = gen_df_reg (set_srca, 0);
4366 srca2 = gen_df_reg (set_srca, 1);
4367 srcb1 = gen_df_reg (set_srcb, 0);
4368 srcb2 = gen_df_reg (set_srcb, 1);
4370 /* Now emit using the real source and destination we found, swapping
4371 the order if we detect overlap. */
4372 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4373 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4375 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4376 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4380 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4381 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4387 ;;- zero extension instructions
4389 ;; These patterns originally accepted general_operands, however, slightly
4390 ;; better code is generated by only accepting register_operands, and then
4391 ;; letting combine generate the ldu[hb] insns.
4393 (define_expand "zero_extendhisi2"
4394 [(set (match_operand:SI 0 "register_operand" "")
4395 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4399 rtx temp = gen_reg_rtx (SImode);
4400 rtx shift_16 = GEN_INT (16);
4401 int op1_subbyte = 0;
4403 if (GET_CODE (operand1) == SUBREG)
4405 op1_subbyte = SUBREG_BYTE (operand1);
4406 op1_subbyte /= GET_MODE_SIZE (SImode);
4407 op1_subbyte *= GET_MODE_SIZE (SImode);
4408 operand1 = XEXP (operand1, 0);
4411 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4413 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4417 (define_insn "*zero_extendhisi2_insn"
4418 [(set (match_operand:SI 0 "register_operand" "=r")
4419 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4422 [(set_attr "type" "load")])
4424 (define_expand "zero_extendqihi2"
4425 [(set (match_operand:HI 0 "register_operand" "")
4426 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4430 (define_insn "*zero_extendqihi2_insn"
4431 [(set (match_operand:HI 0 "register_operand" "=r,r")
4432 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4433 "GET_CODE (operands[1]) != CONST_INT"
4437 [(set_attr "type" "*,load")])
4439 (define_expand "zero_extendqisi2"
4440 [(set (match_operand:SI 0 "register_operand" "")
4441 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4445 (define_insn "*zero_extendqisi2_insn"
4446 [(set (match_operand:SI 0 "register_operand" "=r,r")
4447 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4448 "GET_CODE (operands[1]) != CONST_INT"
4452 [(set_attr "type" "*,load")])
4454 (define_expand "zero_extendqidi2"
4455 [(set (match_operand:DI 0 "register_operand" "")
4456 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4460 (define_insn "*zero_extendqidi2_insn"
4461 [(set (match_operand:DI 0 "register_operand" "=r,r")
4462 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4463 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4467 [(set_attr "type" "*,load")])
4469 (define_expand "zero_extendhidi2"
4470 [(set (match_operand:DI 0 "register_operand" "")
4471 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4475 rtx temp = gen_reg_rtx (DImode);
4476 rtx shift_48 = GEN_INT (48);
4477 int op1_subbyte = 0;
4479 if (GET_CODE (operand1) == SUBREG)
4481 op1_subbyte = SUBREG_BYTE (operand1);
4482 op1_subbyte /= GET_MODE_SIZE (DImode);
4483 op1_subbyte *= GET_MODE_SIZE (DImode);
4484 operand1 = XEXP (operand1, 0);
4487 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4489 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4493 (define_insn "*zero_extendhidi2_insn"
4494 [(set (match_operand:DI 0 "register_operand" "=r")
4495 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4498 [(set_attr "type" "load")])
4501 ;; ??? Write truncdisi pattern using sra?
4503 (define_expand "zero_extendsidi2"
4504 [(set (match_operand:DI 0 "register_operand" "")
4505 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4509 (define_insn "*zero_extendsidi2_insn_sp64"
4510 [(set (match_operand:DI 0 "register_operand" "=r,r")
4511 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4512 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4516 [(set_attr "type" "shift,load")])
4518 (define_insn "*zero_extendsidi2_insn_sp32"
4519 [(set (match_operand:DI 0 "register_operand" "=r")
4520 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4523 [(set_attr "length" "2")])
4526 [(set (match_operand:DI 0 "register_operand" "")
4527 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4528 "! TARGET_ARCH64 && reload_completed"
4529 [(set (match_dup 2) (match_dup 3))
4530 (set (match_dup 4) (match_dup 5))]
4535 dest1 = gen_highpart (SImode, operands[0]);
4536 dest2 = gen_lowpart (SImode, operands[0]);
4538 /* Swap the order in case of overlap. */
4539 if (REGNO (dest1) == REGNO (operands[1]))
4541 operands[2] = dest2;
4542 operands[3] = operands[1];
4543 operands[4] = dest1;
4544 operands[5] = const0_rtx;
4548 operands[2] = dest1;
4549 operands[3] = const0_rtx;
4550 operands[4] = dest2;
4551 operands[5] = operands[1];
4555 ;; Simplify comparisons of extended values.
4557 (define_insn "*cmp_zero_extendqisi2"
4559 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4562 "andcc\\t%0, 0xff, %%g0"
4563 [(set_attr "type" "compare")])
4565 (define_insn "*cmp_zero_qi"
4567 (compare:CC (match_operand:QI 0 "register_operand" "r")
4570 "andcc\\t%0, 0xff, %%g0"
4571 [(set_attr "type" "compare")])
4573 (define_insn "*cmp_zero_extendqisi2_set"
4575 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4577 (set (match_operand:SI 0 "register_operand" "=r")
4578 (zero_extend:SI (match_dup 1)))]
4580 "andcc\\t%1, 0xff, %0"
4581 [(set_attr "type" "compare")])
4583 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4585 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4588 (set (match_operand:SI 0 "register_operand" "=r")
4589 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4591 "andcc\\t%1, 0xff, %0"
4592 [(set_attr "type" "compare")])
4594 (define_insn "*cmp_zero_extendqidi2"
4596 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4599 "andcc\\t%0, 0xff, %%g0"
4600 [(set_attr "type" "compare")])
4602 (define_insn "*cmp_zero_qi_sp64"
4604 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4607 "andcc\\t%0, 0xff, %%g0"
4608 [(set_attr "type" "compare")])
4610 (define_insn "*cmp_zero_extendqidi2_set"
4612 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4614 (set (match_operand:DI 0 "register_operand" "=r")
4615 (zero_extend:DI (match_dup 1)))]
4617 "andcc\\t%1, 0xff, %0"
4618 [(set_attr "type" "compare")])
4620 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4622 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4625 (set (match_operand:DI 0 "register_operand" "=r")
4626 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4628 "andcc\\t%1, 0xff, %0"
4629 [(set_attr "type" "compare")])
4631 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4633 (define_insn "*cmp_siqi_trunc"
4635 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4638 "andcc\\t%0, 0xff, %%g0"
4639 [(set_attr "type" "compare")])
4641 (define_insn "*cmp_siqi_trunc_set"
4643 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4645 (set (match_operand:QI 0 "register_operand" "=r")
4646 (subreg:QI (match_dup 1) 3))]
4648 "andcc\\t%1, 0xff, %0"
4649 [(set_attr "type" "compare")])
4651 (define_insn "*cmp_diqi_trunc"
4653 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4656 "andcc\\t%0, 0xff, %%g0"
4657 [(set_attr "type" "compare")])
4659 (define_insn "*cmp_diqi_trunc_set"
4661 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4663 (set (match_operand:QI 0 "register_operand" "=r")
4664 (subreg:QI (match_dup 1) 7))]
4666 "andcc\\t%1, 0xff, %0"
4667 [(set_attr "type" "compare")])
4669 ;;- sign extension instructions
4671 ;; These patterns originally accepted general_operands, however, slightly
4672 ;; better code is generated by only accepting register_operands, and then
4673 ;; letting combine generate the lds[hb] insns.
4675 (define_expand "extendhisi2"
4676 [(set (match_operand:SI 0 "register_operand" "")
4677 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4681 rtx temp = gen_reg_rtx (SImode);
4682 rtx shift_16 = GEN_INT (16);
4683 int op1_subbyte = 0;
4685 if (GET_CODE (operand1) == SUBREG)
4687 op1_subbyte = SUBREG_BYTE (operand1);
4688 op1_subbyte /= GET_MODE_SIZE (SImode);
4689 op1_subbyte *= GET_MODE_SIZE (SImode);
4690 operand1 = XEXP (operand1, 0);
4693 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4695 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4699 (define_insn "*sign_extendhisi2_insn"
4700 [(set (match_operand:SI 0 "register_operand" "=r")
4701 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4704 [(set_attr "type" "sload")])
4706 (define_expand "extendqihi2"
4707 [(set (match_operand:HI 0 "register_operand" "")
4708 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4712 rtx temp = gen_reg_rtx (SImode);
4713 rtx shift_24 = GEN_INT (24);
4714 int op1_subbyte = 0;
4715 int op0_subbyte = 0;
4717 if (GET_CODE (operand1) == SUBREG)
4719 op1_subbyte = SUBREG_BYTE (operand1);
4720 op1_subbyte /= GET_MODE_SIZE (SImode);
4721 op1_subbyte *= GET_MODE_SIZE (SImode);
4722 operand1 = XEXP (operand1, 0);
4724 if (GET_CODE (operand0) == SUBREG)
4726 op0_subbyte = SUBREG_BYTE (operand0);
4727 op0_subbyte /= GET_MODE_SIZE (SImode);
4728 op0_subbyte *= GET_MODE_SIZE (SImode);
4729 operand0 = XEXP (operand0, 0);
4731 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4733 if (GET_MODE (operand0) != SImode)
4734 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4735 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4739 (define_insn "*sign_extendqihi2_insn"
4740 [(set (match_operand:HI 0 "register_operand" "=r")
4741 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4744 [(set_attr "type" "sload")])
4746 (define_expand "extendqisi2"
4747 [(set (match_operand:SI 0 "register_operand" "")
4748 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4752 rtx temp = gen_reg_rtx (SImode);
4753 rtx shift_24 = GEN_INT (24);
4754 int op1_subbyte = 0;
4756 if (GET_CODE (operand1) == SUBREG)
4758 op1_subbyte = SUBREG_BYTE (operand1);
4759 op1_subbyte /= GET_MODE_SIZE (SImode);
4760 op1_subbyte *= GET_MODE_SIZE (SImode);
4761 operand1 = XEXP (operand1, 0);
4764 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4766 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4770 (define_insn "*sign_extendqisi2_insn"
4771 [(set (match_operand:SI 0 "register_operand" "=r")
4772 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4775 [(set_attr "type" "sload")])
4777 (define_expand "extendqidi2"
4778 [(set (match_operand:DI 0 "register_operand" "")
4779 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4783 rtx temp = gen_reg_rtx (DImode);
4784 rtx shift_56 = GEN_INT (56);
4785 int op1_subbyte = 0;
4787 if (GET_CODE (operand1) == SUBREG)
4789 op1_subbyte = SUBREG_BYTE (operand1);
4790 op1_subbyte /= GET_MODE_SIZE (DImode);
4791 op1_subbyte *= GET_MODE_SIZE (DImode);
4792 operand1 = XEXP (operand1, 0);
4795 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4797 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4801 (define_insn "*sign_extendqidi2_insn"
4802 [(set (match_operand:DI 0 "register_operand" "=r")
4803 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4806 [(set_attr "type" "sload")])
4808 (define_expand "extendhidi2"
4809 [(set (match_operand:DI 0 "register_operand" "")
4810 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4814 rtx temp = gen_reg_rtx (DImode);
4815 rtx shift_48 = GEN_INT (48);
4816 int op1_subbyte = 0;
4818 if (GET_CODE (operand1) == SUBREG)
4820 op1_subbyte = SUBREG_BYTE (operand1);
4821 op1_subbyte /= GET_MODE_SIZE (DImode);
4822 op1_subbyte *= GET_MODE_SIZE (DImode);
4823 operand1 = XEXP (operand1, 0);
4826 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4828 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4832 (define_insn "*sign_extendhidi2_insn"
4833 [(set (match_operand:DI 0 "register_operand" "=r")
4834 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4837 [(set_attr "type" "sload")])
4839 (define_expand "extendsidi2"
4840 [(set (match_operand:DI 0 "register_operand" "")
4841 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4845 (define_insn "*sign_extendsidi2_insn"
4846 [(set (match_operand:DI 0 "register_operand" "=r,r")
4847 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4852 [(set_attr "type" "shift,sload")])
4854 ;; Special pattern for optimizing bit-field compares. This is needed
4855 ;; because combine uses this as a canonical form.
4857 (define_insn "*cmp_zero_extract"
4860 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4861 (match_operand:SI 1 "small_int_or_double" "n")
4862 (match_operand:SI 2 "small_int_or_double" "n"))
4864 "(GET_CODE (operands[2]) == CONST_INT
4865 && INTVAL (operands[2]) > 19)
4866 || (GET_CODE (operands[2]) == CONST_DOUBLE
4867 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4870 int len = (GET_CODE (operands[1]) == CONST_INT
4871 ? INTVAL (operands[1])
4872 : CONST_DOUBLE_LOW (operands[1]));
4874 (GET_CODE (operands[2]) == CONST_INT
4875 ? INTVAL (operands[2])
4876 : CONST_DOUBLE_LOW (operands[2])) - len;
4877 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4879 operands[1] = GEN_INT (mask);
4880 return \"andcc\\t%0, %1, %%g0\";
4882 [(set_attr "type" "compare")])
4884 (define_insn "*cmp_zero_extract_sp64"
4887 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4888 (match_operand:SI 1 "small_int_or_double" "n")
4889 (match_operand:SI 2 "small_int_or_double" "n"))
4892 && ((GET_CODE (operands[2]) == CONST_INT
4893 && INTVAL (operands[2]) > 51)
4894 || (GET_CODE (operands[2]) == CONST_DOUBLE
4895 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4898 int len = (GET_CODE (operands[1]) == CONST_INT
4899 ? INTVAL (operands[1])
4900 : CONST_DOUBLE_LOW (operands[1]));
4902 (GET_CODE (operands[2]) == CONST_INT
4903 ? INTVAL (operands[2])
4904 : CONST_DOUBLE_LOW (operands[2])) - len;
4905 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4907 operands[1] = GEN_INT (mask);
4908 return \"andcc\\t%0, %1, %%g0\";
4910 [(set_attr "type" "compare")])
4912 ;; Conversions between float, double and long double.
4914 (define_insn "extendsfdf2"
4915 [(set (match_operand:DF 0 "register_operand" "=e")
4917 (match_operand:SF 1 "register_operand" "f")))]
4920 [(set_attr "type" "fp")
4921 (set_attr "fptype" "double")])
4923 (define_expand "extendsftf2"
4924 [(set (match_operand:TF 0 "register_operand" "=e")
4926 (match_operand:SF 1 "register_operand" "f")))]
4927 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4930 if (! TARGET_HARD_QUAD)
4934 if (GET_CODE (operands[0]) != MEM)
4935 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4937 slot0 = operands[0];
4939 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4941 XEXP (slot0, 0), Pmode,
4942 operands[1], SFmode);
4944 if (GET_CODE (operands[0]) != MEM)
4945 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4950 (define_insn "*extendsftf2_hq"
4951 [(set (match_operand:TF 0 "register_operand" "=e")
4953 (match_operand:SF 1 "register_operand" "f")))]
4954 "TARGET_FPU && TARGET_HARD_QUAD"
4956 [(set_attr "type" "fp")])
4958 (define_expand "extenddftf2"
4959 [(set (match_operand:TF 0 "register_operand" "=e")
4961 (match_operand:DF 1 "register_operand" "e")))]
4962 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4965 if (! TARGET_HARD_QUAD)
4969 if (GET_CODE (operands[0]) != MEM)
4970 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4972 slot0 = operands[0];
4974 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
4976 XEXP (slot0, 0), Pmode,
4977 operands[1], DFmode);
4979 if (GET_CODE (operands[0]) != MEM)
4980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4985 (define_insn "*extenddftf2_hq"
4986 [(set (match_operand:TF 0 "register_operand" "=e")
4988 (match_operand:DF 1 "register_operand" "e")))]
4989 "TARGET_FPU && TARGET_HARD_QUAD"
4991 [(set_attr "type" "fp")])
4993 (define_insn "truncdfsf2"
4994 [(set (match_operand:SF 0 "register_operand" "=f")
4996 (match_operand:DF 1 "register_operand" "e")))]
4999 [(set_attr "type" "fp")
5000 (set_attr "fptype" "double")])
5002 (define_expand "trunctfsf2"
5003 [(set (match_operand:SF 0 "register_operand" "=f")
5005 (match_operand:TF 1 "register_operand" "e")))]
5006 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5009 if (! TARGET_HARD_QUAD)
5013 if (GET_CODE (operands[1]) != MEM)
5015 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5016 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5019 slot0 = operands[1];
5021 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5022 operands[0], 0, SFmode, 1,
5023 XEXP (slot0, 0), Pmode);
5028 (define_insn "*trunctfsf2_hq"
5029 [(set (match_operand:SF 0 "register_operand" "=f")
5031 (match_operand:TF 1 "register_operand" "e")))]
5032 "TARGET_FPU && TARGET_HARD_QUAD"
5034 [(set_attr "type" "fp")])
5036 (define_expand "trunctfdf2"
5037 [(set (match_operand:DF 0 "register_operand" "=f")
5039 (match_operand:TF 1 "register_operand" "e")))]
5040 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5043 if (! TARGET_HARD_QUAD)
5047 if (GET_CODE (operands[1]) != MEM)
5049 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5050 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5053 slot0 = operands[1];
5055 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5056 operands[0], 0, DFmode, 1,
5057 XEXP (slot0, 0), Pmode);
5062 (define_insn "*trunctfdf2_hq"
5063 [(set (match_operand:DF 0 "register_operand" "=e")
5065 (match_operand:TF 1 "register_operand" "e")))]
5066 "TARGET_FPU && TARGET_HARD_QUAD"
5068 [(set_attr "type" "fp")])
5070 ;; Conversion between fixed point and floating point.
5072 (define_insn "floatsisf2"
5073 [(set (match_operand:SF 0 "register_operand" "=f")
5074 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5077 [(set_attr "type" "fp")
5078 (set_attr "fptype" "double")])
5080 (define_insn "floatsidf2"
5081 [(set (match_operand:DF 0 "register_operand" "=e")
5082 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5085 [(set_attr "type" "fp")
5086 (set_attr "fptype" "double")])
5088 (define_expand "floatsitf2"
5089 [(set (match_operand:TF 0 "register_operand" "=e")
5090 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5091 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5094 if (! TARGET_HARD_QUAD)
5098 if (GET_CODE (operands[1]) != MEM)
5099 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5101 slot0 = operands[1];
5103 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5105 XEXP (slot0, 0), Pmode,
5106 operands[1], SImode);
5108 if (GET_CODE (operands[0]) != MEM)
5109 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5114 (define_insn "*floatsitf2_hq"
5115 [(set (match_operand:TF 0 "register_operand" "=e")
5116 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5117 "TARGET_FPU && TARGET_HARD_QUAD"
5119 [(set_attr "type" "fp")])
5121 (define_expand "floatunssitf2"
5122 [(set (match_operand:TF 0 "register_operand" "=e")
5123 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5124 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5129 if (GET_CODE (operands[1]) != MEM)
5130 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5132 slot0 = operands[1];
5134 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5136 XEXP (slot0, 0), Pmode,
5137 operands[1], SImode);
5139 if (GET_CODE (operands[0]) != MEM)
5140 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5144 ;; Now the same for 64 bit sources.
5146 (define_insn "floatdisf2"
5147 [(set (match_operand:SF 0 "register_operand" "=f")
5148 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5149 "TARGET_V9 && TARGET_FPU"
5151 [(set_attr "type" "fp")
5152 (set_attr "fptype" "double")])
5154 (define_insn "floatdidf2"
5155 [(set (match_operand:DF 0 "register_operand" "=e")
5156 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5157 "TARGET_V9 && TARGET_FPU"
5159 [(set_attr "type" "fp")
5160 (set_attr "fptype" "double")])
5162 (define_expand "floatditf2"
5163 [(set (match_operand:TF 0 "register_operand" "=e")
5164 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5165 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5168 if (! TARGET_HARD_QUAD)
5172 if (GET_CODE (operands[1]) != MEM)
5173 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5175 slot0 = operands[1];
5177 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5179 XEXP (slot0, 0), Pmode,
5180 operands[1], DImode);
5182 if (GET_CODE (operands[0]) != MEM)
5183 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5188 (define_insn "*floatditf2_hq"
5189 [(set (match_operand:TF 0 "register_operand" "=e")
5190 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5191 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5193 [(set_attr "type" "fp")])
5195 (define_expand "floatunsditf2"
5196 [(set (match_operand:TF 0 "register_operand" "=e")
5197 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5198 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5203 if (GET_CODE (operands[1]) != MEM)
5204 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5206 slot0 = operands[1];
5208 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5210 XEXP (slot0, 0), Pmode,
5211 operands[1], DImode);
5213 if (GET_CODE (operands[0]) != MEM)
5214 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5218 ;; Convert a float to an actual integer.
5219 ;; Truncation is performed as part of the conversion.
5221 (define_insn "fix_truncsfsi2"
5222 [(set (match_operand:SI 0 "register_operand" "=f")
5223 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5226 [(set_attr "type" "fp")
5227 (set_attr "fptype" "double")])
5229 (define_insn "fix_truncdfsi2"
5230 [(set (match_operand:SI 0 "register_operand" "=f")
5231 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5234 [(set_attr "type" "fp")
5235 (set_attr "fptype" "double")])
5237 (define_expand "fix_trunctfsi2"
5238 [(set (match_operand:SI 0 "register_operand" "=f")
5239 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5240 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5243 if (! TARGET_HARD_QUAD)
5247 if (GET_CODE (operands[1]) != MEM)
5249 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5250 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5253 slot0 = operands[1];
5255 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5256 operands[0], 0, SImode, 1,
5257 XEXP (slot0, 0), Pmode);
5262 (define_insn "*fix_trunctfsi2_hq"
5263 [(set (match_operand:SI 0 "register_operand" "=f")
5264 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5265 "TARGET_FPU && TARGET_HARD_QUAD"
5267 [(set_attr "type" "fp")])
5269 (define_expand "fixuns_trunctfsi2"
5270 [(set (match_operand:SI 0 "register_operand" "=f")
5271 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5272 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5277 if (GET_CODE (operands[1]) != MEM)
5279 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5280 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5283 slot0 = operands[1];
5285 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5286 operands[0], 0, SImode, 1,
5287 XEXP (slot0, 0), Pmode);
5291 ;; Now the same, for V9 targets
5293 (define_insn "fix_truncsfdi2"
5294 [(set (match_operand:DI 0 "register_operand" "=e")
5295 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5296 "TARGET_V9 && TARGET_FPU"
5298 [(set_attr "type" "fp")
5299 (set_attr "fptype" "double")])
5301 (define_insn "fix_truncdfdi2"
5302 [(set (match_operand:DI 0 "register_operand" "=e")
5303 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5304 "TARGET_V9 && TARGET_FPU"
5306 [(set_attr "type" "fp")
5307 (set_attr "fptype" "double")])
5309 (define_expand "fix_trunctfdi2"
5310 [(set (match_operand:DI 0 "register_operand" "=e")
5311 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5312 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5315 if (! TARGET_HARD_QUAD)
5319 if (GET_CODE (operands[1]) != MEM)
5321 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5322 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5325 slot0 = operands[1];
5327 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5328 operands[0], 0, DImode, 1,
5329 XEXP (slot0, 0), Pmode);
5334 (define_insn "*fix_trunctfdi2_hq"
5335 [(set (match_operand:DI 0 "register_operand" "=e")
5336 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5337 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5339 [(set_attr "type" "fp")])
5341 (define_expand "fixuns_trunctfdi2"
5342 [(set (match_operand:DI 0 "register_operand" "=f")
5343 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5344 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5349 if (GET_CODE (operands[1]) != MEM)
5351 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5352 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5355 slot0 = operands[1];
5357 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5358 operands[0], 0, DImode, 1,
5359 XEXP (slot0, 0), Pmode);
5364 ;;- arithmetic instructions
5366 (define_expand "adddi3"
5367 [(set (match_operand:DI 0 "register_operand" "=r")
5368 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5369 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5375 if (! TARGET_ARCH64)
5377 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5378 gen_rtx_SET (VOIDmode, operands[0],
5379 gen_rtx_PLUS (DImode, operands[1],
5381 gen_rtx_CLOBBER (VOIDmode,
5382 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5385 if (arith_double_4096_operand(operands[2], DImode))
5387 switch (GET_CODE (operands[1]))
5389 case CONST_INT: i = INTVAL (operands[1]); break;
5390 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5392 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5393 gen_rtx_MINUS (DImode, operands[1],
5397 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5402 (define_insn "adddi3_insn_sp32"
5403 [(set (match_operand:DI 0 "register_operand" "=r")
5404 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5405 (match_operand:DI 2 "arith_double_operand" "rHI")))
5406 (clobber (reg:CC 100))]
5409 [(set_attr "length" "2")])
5412 [(set (match_operand:DI 0 "register_operand" "")
5413 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5414 (match_operand:DI 2 "arith_double_operand" "")))
5415 (clobber (reg:CC 100))]
5416 "! TARGET_ARCH64 && reload_completed"
5417 [(parallel [(set (reg:CC_NOOV 100)
5418 (compare:CC_NOOV (plus:SI (match_dup 4)
5422 (plus:SI (match_dup 4) (match_dup 5)))])
5424 (plus:SI (plus:SI (match_dup 7)
5426 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5429 operands[3] = gen_lowpart (SImode, operands[0]);
5430 operands[4] = gen_lowpart (SImode, operands[1]);
5431 operands[5] = gen_lowpart (SImode, operands[2]);
5432 operands[6] = gen_highpart (SImode, operands[0]);
5433 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5434 #if HOST_BITS_PER_WIDE_INT == 32
5435 if (GET_CODE (operands[2]) == CONST_INT)
5437 if (INTVAL (operands[2]) < 0)
5438 operands[8] = constm1_rtx;
5440 operands[8] = const0_rtx;
5444 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5448 [(set (match_operand:DI 0 "register_operand" "")
5449 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5450 (match_operand:DI 2 "arith_double_operand" "")))
5451 (clobber (reg:CC 100))]
5452 "! TARGET_ARCH64 && reload_completed"
5453 [(parallel [(set (reg:CC_NOOV 100)
5454 (compare:CC_NOOV (minus:SI (match_dup 4)
5458 (minus:SI (match_dup 4) (match_dup 5)))])
5460 (minus:SI (minus:SI (match_dup 7)
5462 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5465 operands[3] = gen_lowpart (SImode, operands[0]);
5466 operands[4] = gen_lowpart (SImode, operands[1]);
5467 operands[5] = gen_lowpart (SImode, operands[2]);
5468 operands[6] = gen_highpart (SImode, operands[0]);
5469 operands[7] = gen_highpart (SImode, operands[1]);
5470 #if HOST_BITS_PER_WIDE_INT == 32
5471 if (GET_CODE (operands[2]) == CONST_INT)
5473 if (INTVAL (operands[2]) < 0)
5474 operands[8] = constm1_rtx;
5476 operands[8] = const0_rtx;
5480 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5483 ;; LTU here means "carry set"
5485 [(set (match_operand:SI 0 "register_operand" "=r")
5486 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5487 (match_operand:SI 2 "arith_operand" "rI"))
5488 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5491 [(set_attr "type" "misc")])
5493 (define_insn "*addx_extend_sp32"
5494 [(set (match_operand:DI 0 "register_operand" "=r")
5495 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5496 (match_operand:SI 2 "arith_operand" "rI"))
5497 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5500 [(set_attr "length" "2")])
5503 [(set (match_operand:DI 0 "register_operand" "")
5504 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5505 (match_operand:SI 2 "arith_operand" ""))
5506 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5507 "! TARGET_ARCH64 && reload_completed"
5508 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5509 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5510 (set (match_dup 4) (const_int 0))]
5511 "operands[3] = gen_lowpart (SImode, operands[0]);
5512 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5514 (define_insn "*addx_extend_sp64"
5515 [(set (match_operand:DI 0 "register_operand" "=r")
5516 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5517 (match_operand:SI 2 "arith_operand" "rI"))
5518 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5520 "addx\\t%r1, %2, %0"
5521 [(set_attr "type" "misc")])
5524 [(set (match_operand:SI 0 "register_operand" "=r")
5525 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5526 (match_operand:SI 2 "arith_operand" "rI"))
5527 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5529 "subx\\t%r1, %2, %0"
5530 [(set_attr "type" "misc")])
5532 (define_insn "*subx_extend_sp64"
5533 [(set (match_operand:DI 0 "register_operand" "=r")
5534 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5535 (match_operand:SI 2 "arith_operand" "rI"))
5536 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5538 "subx\\t%r1, %2, %0"
5539 [(set_attr "type" "misc")])
5541 (define_insn "*subx_extend"
5542 [(set (match_operand:DI 0 "register_operand" "=r")
5543 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5544 (match_operand:SI 2 "arith_operand" "rI"))
5545 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5548 [(set_attr "length" "2")])
5551 [(set (match_operand:DI 0 "register_operand" "")
5552 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5553 (match_operand:SI 2 "arith_operand" ""))
5554 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5555 "! TARGET_ARCH64 && reload_completed"
5556 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5557 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5558 (set (match_dup 4) (const_int 0))]
5559 "operands[3] = gen_lowpart (SImode, operands[0]);
5560 operands[4] = gen_highpart (SImode, operands[0]);")
5563 [(set (match_operand:DI 0 "register_operand" "=r")
5564 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5565 (match_operand:DI 2 "register_operand" "r")))
5566 (clobber (reg:CC 100))]
5569 [(set_attr "length" "2")])
5572 [(set (match_operand:DI 0 "register_operand" "")
5573 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5574 (match_operand:DI 2 "register_operand" "")))
5575 (clobber (reg:CC 100))]
5576 "! TARGET_ARCH64 && reload_completed"
5577 [(parallel [(set (reg:CC_NOOV 100)
5578 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5580 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5582 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5583 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5584 "operands[3] = gen_lowpart (SImode, operands[2]);
5585 operands[4] = gen_highpart (SImode, operands[2]);
5586 operands[5] = gen_lowpart (SImode, operands[0]);
5587 operands[6] = gen_highpart (SImode, operands[0]);")
5589 (define_insn "*adddi3_sp64"
5590 [(set (match_operand:DI 0 "register_operand" "=r")
5591 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5592 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5596 (define_expand "addsi3"
5597 [(set (match_operand:SI 0 "register_operand" "=r,d")
5598 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5599 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5603 if (arith_4096_operand(operands[2], SImode))
5605 if (GET_CODE (operands[1]) == CONST_INT)
5606 emit_insn (gen_movsi (operands[0],
5607 GEN_INT (INTVAL (operands[1]) + 4096)));
5609 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5610 gen_rtx_MINUS (SImode, operands[1],
5616 (define_insn "*addsi3"
5617 [(set (match_operand:SI 0 "register_operand" "=r,d")
5618 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5619 (match_operand:SI 2 "arith_operand" "rI,d")))]
5623 fpadd32s\\t%1, %2, %0"
5624 [(set_attr "type" "*,fp")])
5626 (define_insn "*cmp_cc_plus"
5627 [(set (reg:CC_NOOV 100)
5628 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5629 (match_operand:SI 1 "arith_operand" "rI"))
5632 "addcc\\t%0, %1, %%g0"
5633 [(set_attr "type" "compare")])
5635 (define_insn "*cmp_ccx_plus"
5636 [(set (reg:CCX_NOOV 100)
5637 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5638 (match_operand:DI 1 "arith_double_operand" "rHI"))
5641 "addcc\\t%0, %1, %%g0"
5642 [(set_attr "type" "compare")])
5644 (define_insn "*cmp_cc_plus_set"
5645 [(set (reg:CC_NOOV 100)
5646 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5647 (match_operand:SI 2 "arith_operand" "rI"))
5649 (set (match_operand:SI 0 "register_operand" "=r")
5650 (plus:SI (match_dup 1) (match_dup 2)))]
5652 "addcc\\t%1, %2, %0"
5653 [(set_attr "type" "compare")])
5655 (define_insn "*cmp_ccx_plus_set"
5656 [(set (reg:CCX_NOOV 100)
5657 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5658 (match_operand:DI 2 "arith_double_operand" "rHI"))
5660 (set (match_operand:DI 0 "register_operand" "=r")
5661 (plus:DI (match_dup 1) (match_dup 2)))]
5663 "addcc\\t%1, %2, %0"
5664 [(set_attr "type" "compare")])
5666 (define_expand "subdi3"
5667 [(set (match_operand:DI 0 "register_operand" "=r")
5668 (minus:DI (match_operand:DI 1 "register_operand" "r")
5669 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5673 if (! TARGET_ARCH64)
5675 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5676 gen_rtx_SET (VOIDmode, operands[0],
5677 gen_rtx_MINUS (DImode, operands[1],
5679 gen_rtx_CLOBBER (VOIDmode,
5680 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5683 if (arith_double_4096_operand(operands[2], DImode))
5685 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5686 gen_rtx_PLUS (DImode, operands[1],
5692 (define_insn "*subdi3_sp32"
5693 [(set (match_operand:DI 0 "register_operand" "=r")
5694 (minus:DI (match_operand:DI 1 "register_operand" "r")
5695 (match_operand:DI 2 "arith_double_operand" "rHI")))
5696 (clobber (reg:CC 100))]
5699 [(set_attr "length" "2")])
5702 [(set (match_operand:DI 0 "register_operand" "")
5703 (minus:DI (match_operand:DI 1 "register_operand" "")
5704 (match_operand:DI 2 "arith_double_operand" "")))
5705 (clobber (reg:CC 100))]
5708 && (GET_CODE (operands[2]) == CONST_INT
5709 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5710 [(clobber (const_int 0))]
5715 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5716 lowp = gen_lowpart (SImode, operands[2]);
5717 if ((lowp == const0_rtx)
5718 && (operands[0] == operands[1]))
5720 emit_insn (gen_rtx_SET (VOIDmode,
5721 gen_highpart (SImode, operands[0]),
5722 gen_rtx_MINUS (SImode,
5723 gen_highpart_mode (SImode, DImode,
5729 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5730 gen_lowpart (SImode, operands[1]),
5732 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5733 gen_highpart_mode (SImode, DImode, operands[1]),
5740 [(set (match_operand:DI 0 "register_operand" "")
5741 (minus:DI (match_operand:DI 1 "register_operand" "")
5742 (match_operand:DI 2 "register_operand" "")))
5743 (clobber (reg:CC 100))]
5745 && reload_completed"
5746 [(clobber (const_int 0))]
5749 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5750 gen_lowpart (SImode, operands[1]),
5751 gen_lowpart (SImode, operands[2])));
5752 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5753 gen_highpart (SImode, operands[1]),
5754 gen_highpart (SImode, operands[2])));
5759 [(set (match_operand:DI 0 "register_operand" "=r")
5760 (minus:DI (match_operand:DI 1 "register_operand" "r")
5761 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5762 (clobber (reg:CC 100))]
5765 [(set_attr "length" "2")])
5768 [(set (match_operand:DI 0 "register_operand" "")
5769 (minus:DI (match_operand:DI 1 "register_operand" "")
5770 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5771 (clobber (reg:CC 100))]
5772 "! TARGET_ARCH64 && reload_completed"
5773 [(parallel [(set (reg:CC_NOOV 100)
5774 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5776 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5778 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5779 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5780 "operands[3] = gen_lowpart (SImode, operands[1]);
5781 operands[4] = gen_highpart (SImode, operands[1]);
5782 operands[5] = gen_lowpart (SImode, operands[0]);
5783 operands[6] = gen_highpart (SImode, operands[0]);")
5785 (define_insn "*subdi3_sp64"
5786 [(set (match_operand:DI 0 "register_operand" "=r")
5787 (minus:DI (match_operand:DI 1 "register_operand" "r")
5788 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5792 (define_expand "subsi3"
5793 [(set (match_operand:SI 0 "register_operand" "=r,d")
5794 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5795 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5799 if (arith_4096_operand(operands[2], SImode))
5801 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5802 gen_rtx_PLUS (SImode, operands[1],
5808 (define_insn "*subsi3"
5809 [(set (match_operand:SI 0 "register_operand" "=r,d")
5810 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5811 (match_operand:SI 2 "arith_operand" "rI,d")))]
5815 fpsub32s\\t%1, %2, %0"
5816 [(set_attr "type" "*,fp")])
5818 (define_insn "*cmp_minus_cc"
5819 [(set (reg:CC_NOOV 100)
5820 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5821 (match_operand:SI 1 "arith_operand" "rI"))
5824 "subcc\\t%r0, %1, %%g0"
5825 [(set_attr "type" "compare")])
5827 (define_insn "*cmp_minus_ccx"
5828 [(set (reg:CCX_NOOV 100)
5829 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5830 (match_operand:DI 1 "arith_double_operand" "rHI"))
5833 "subcc\\t%0, %1, %%g0"
5834 [(set_attr "type" "compare")])
5836 (define_insn "cmp_minus_cc_set"
5837 [(set (reg:CC_NOOV 100)
5838 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5839 (match_operand:SI 2 "arith_operand" "rI"))
5841 (set (match_operand:SI 0 "register_operand" "=r")
5842 (minus:SI (match_dup 1) (match_dup 2)))]
5844 "subcc\\t%r1, %2, %0"
5845 [(set_attr "type" "compare")])
5847 (define_insn "*cmp_minus_ccx_set"
5848 [(set (reg:CCX_NOOV 100)
5849 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5850 (match_operand:DI 2 "arith_double_operand" "rHI"))
5852 (set (match_operand:DI 0 "register_operand" "=r")
5853 (minus:DI (match_dup 1) (match_dup 2)))]
5855 "subcc\\t%1, %2, %0"
5856 [(set_attr "type" "compare")])
5858 ;; Integer Multiply/Divide.
5860 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5861 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5863 (define_insn "mulsi3"
5864 [(set (match_operand:SI 0 "register_operand" "=r")
5865 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5866 (match_operand:SI 2 "arith_operand" "rI")))]
5869 [(set_attr "type" "imul")])
5871 (define_expand "muldi3"
5872 [(set (match_operand:DI 0 "register_operand" "=r")
5873 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5874 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5875 "TARGET_ARCH64 || TARGET_V8PLUS"
5880 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5885 (define_insn "*muldi3_sp64"
5886 [(set (match_operand:DI 0 "register_operand" "=r")
5887 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5888 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5891 [(set_attr "type" "imul")])
5893 ;; V8plus wide multiply.
5895 (define_insn "muldi3_v8plus"
5896 [(set (match_operand:DI 0 "register_operand" "=r,h")
5897 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5898 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5899 (clobber (match_scratch:SI 3 "=&h,X"))
5900 (clobber (match_scratch:SI 4 "=&h,X"))]
5904 if (sparc_check_64 (operands[1], insn) <= 0)
5905 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5906 if (which_alternative == 1)
5907 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5908 if (GET_CODE (operands[2]) == CONST_INT)
5910 if (which_alternative == 1)
5911 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
5913 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\";
5915 if (sparc_check_64 (operands[2], insn) <= 0)
5916 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5917 if (which_alternative == 1)
5918 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\";
5920 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\";
5922 [(set_attr "type" "multi")
5923 (set_attr "length" "9,8")])
5925 (define_insn "*cmp_mul_set"
5927 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5928 (match_operand:SI 2 "arith_operand" "rI"))
5930 (set (match_operand:SI 0 "register_operand" "=r")
5931 (mult:SI (match_dup 1) (match_dup 2)))]
5932 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5933 "smulcc\\t%1, %2, %0"
5934 [(set_attr "type" "imul")])
5936 (define_expand "mulsidi3"
5937 [(set (match_operand:DI 0 "register_operand" "")
5938 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5939 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5943 if (CONSTANT_P (operands[2]))
5946 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5949 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5955 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5960 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5961 ;; registers can hold 64 bit values in the V8plus environment.
5963 (define_insn "mulsidi3_v8plus"
5964 [(set (match_operand:DI 0 "register_operand" "=h,r")
5965 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5966 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5967 (clobber (match_scratch:SI 3 "=X,&h"))]
5970 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5971 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5972 [(set_attr "type" "multi")
5973 (set_attr "length" "2,3")])
5976 (define_insn "const_mulsidi3_v8plus"
5977 [(set (match_operand:DI 0 "register_operand" "=h,r")
5978 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5979 (match_operand:SI 2 "small_int" "I,I")))
5980 (clobber (match_scratch:SI 3 "=X,&h"))]
5983 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5984 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5985 [(set_attr "type" "multi")
5986 (set_attr "length" "2,3")])
5989 (define_insn "*mulsidi3_sp32"
5990 [(set (match_operand:DI 0 "register_operand" "=r")
5991 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5992 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5996 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5999 (if_then_else (eq_attr "isa" "sparclet")
6000 (const_string "imul") (const_string "multi")))
6001 (set (attr "length")
6002 (if_then_else (eq_attr "isa" "sparclet")
6003 (const_int 1) (const_int 2)))])
6005 (define_insn "*mulsidi3_sp64"
6006 [(set (match_operand:DI 0 "register_operand" "=r")
6007 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6008 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6009 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6011 [(set_attr "type" "imul")])
6013 ;; Extra pattern, because sign_extend of a constant isn't valid.
6016 (define_insn "const_mulsidi3_sp32"
6017 [(set (match_operand:DI 0 "register_operand" "=r")
6018 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6019 (match_operand:SI 2 "small_int" "I")))]
6023 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6026 (if_then_else (eq_attr "isa" "sparclet")
6027 (const_string "imul") (const_string "multi")))
6028 (set (attr "length")
6029 (if_then_else (eq_attr "isa" "sparclet")
6030 (const_int 1) (const_int 2)))])
6032 (define_insn "const_mulsidi3_sp64"
6033 [(set (match_operand:DI 0 "register_operand" "=r")
6034 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6035 (match_operand:SI 2 "small_int" "I")))]
6036 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6038 [(set_attr "type" "imul")])
6040 (define_expand "smulsi3_highpart"
6041 [(set (match_operand:SI 0 "register_operand" "")
6043 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6044 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6046 "TARGET_HARD_MUL && TARGET_ARCH32"
6049 if (CONSTANT_P (operands[2]))
6053 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6059 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6064 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6065 operands[2], GEN_INT (32)));
6071 (define_insn "smulsi3_highpart_v8plus"
6072 [(set (match_operand:SI 0 "register_operand" "=h,r")
6074 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6075 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6076 (match_operand:SI 3 "const_int_operand" "i,i"))))
6077 (clobber (match_scratch:SI 4 "=X,&h"))]
6080 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6081 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6082 [(set_attr "type" "multi")
6083 (set_attr "length" "2")])
6085 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6088 [(set (match_operand:SI 0 "register_operand" "=h,r")
6091 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6092 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6093 (match_operand:SI 3 "const_int_operand" "i,i"))
6095 (clobber (match_scratch:SI 4 "=X,&h"))]
6098 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6099 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6100 [(set_attr "type" "multi")
6101 (set_attr "length" "2")])
6104 (define_insn "const_smulsi3_highpart_v8plus"
6105 [(set (match_operand:SI 0 "register_operand" "=h,r")
6107 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6108 (match_operand 2 "small_int" "i,i"))
6109 (match_operand:SI 3 "const_int_operand" "i,i"))))
6110 (clobber (match_scratch:SI 4 "=X,&h"))]
6113 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6114 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6115 [(set_attr "type" "multi")
6116 (set_attr "length" "2")])
6119 (define_insn "*smulsi3_highpart_sp32"
6120 [(set (match_operand:SI 0 "register_operand" "=r")
6122 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6123 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6126 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6127 [(set_attr "type" "multi")
6128 (set_attr "length" "2")])
6131 (define_insn "const_smulsi3_highpart"
6132 [(set (match_operand:SI 0 "register_operand" "=r")
6134 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6135 (match_operand:SI 2 "register_operand" "r"))
6138 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6139 [(set_attr "type" "multi")
6140 (set_attr "length" "2")])
6142 (define_expand "umulsidi3"
6143 [(set (match_operand:DI 0 "register_operand" "")
6144 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6145 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6149 if (CONSTANT_P (operands[2]))
6152 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6155 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6161 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6167 (define_insn "umulsidi3_v8plus"
6168 [(set (match_operand:DI 0 "register_operand" "=h,r")
6169 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6170 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6171 (clobber (match_scratch:SI 3 "=X,&h"))]
6174 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6175 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6176 [(set_attr "type" "multi")
6177 (set_attr "length" "2,3")])
6180 (define_insn "*umulsidi3_sp32"
6181 [(set (match_operand:DI 0 "register_operand" "=r")
6182 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6183 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6187 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6190 (if_then_else (eq_attr "isa" "sparclet")
6191 (const_string "imul") (const_string "multi")))
6192 (set (attr "length")
6193 (if_then_else (eq_attr "isa" "sparclet")
6194 (const_int 1) (const_int 2)))])
6196 (define_insn "*umulsidi3_sp64"
6197 [(set (match_operand:DI 0 "register_operand" "=r")
6198 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6199 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6200 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6202 [(set_attr "type" "imul")])
6204 ;; Extra pattern, because sign_extend of a constant isn't valid.
6207 (define_insn "const_umulsidi3_sp32"
6208 [(set (match_operand:DI 0 "register_operand" "=r")
6209 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6210 (match_operand:SI 2 "uns_small_int" "")))]
6214 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6217 (if_then_else (eq_attr "isa" "sparclet")
6218 (const_string "imul") (const_string "multi")))
6219 (set (attr "length")
6220 (if_then_else (eq_attr "isa" "sparclet")
6221 (const_int 1) (const_int 2)))])
6223 (define_insn "const_umulsidi3_sp64"
6224 [(set (match_operand:DI 0 "register_operand" "=r")
6225 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6226 (match_operand:SI 2 "uns_small_int" "")))]
6227 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6229 [(set_attr "type" "imul")])
6232 (define_insn "const_umulsidi3_v8plus"
6233 [(set (match_operand:DI 0 "register_operand" "=h,r")
6234 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6235 (match_operand:SI 2 "uns_small_int" "")))
6236 (clobber (match_scratch:SI 3 "=X,h"))]
6239 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6240 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6241 [(set_attr "type" "multi")
6242 (set_attr "length" "2,3")])
6244 (define_expand "umulsi3_highpart"
6245 [(set (match_operand:SI 0 "register_operand" "")
6247 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6248 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6250 "TARGET_HARD_MUL && TARGET_ARCH32"
6253 if (CONSTANT_P (operands[2]))
6257 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6263 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6268 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6269 operands[2], GEN_INT (32)));
6275 (define_insn "umulsi3_highpart_v8plus"
6276 [(set (match_operand:SI 0 "register_operand" "=h,r")
6278 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6279 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6280 (match_operand:SI 3 "const_int_operand" "i,i"))))
6281 (clobber (match_scratch:SI 4 "=X,h"))]
6284 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6285 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6286 [(set_attr "type" "multi")
6287 (set_attr "length" "2")])
6290 (define_insn "const_umulsi3_highpart_v8plus"
6291 [(set (match_operand:SI 0 "register_operand" "=h,r")
6293 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6294 (match_operand:SI 2 "uns_small_int" ""))
6295 (match_operand:SI 3 "const_int_operand" "i,i"))))
6296 (clobber (match_scratch:SI 4 "=X,h"))]
6299 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6300 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6301 [(set_attr "type" "multi")
6302 (set_attr "length" "2")])
6305 (define_insn "*umulsi3_highpart_sp32"
6306 [(set (match_operand:SI 0 "register_operand" "=r")
6308 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6309 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6312 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6313 [(set_attr "type" "multi")
6314 (set_attr "length" "2")])
6317 (define_insn "const_umulsi3_highpart"
6318 [(set (match_operand:SI 0 "register_operand" "=r")
6320 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6321 (match_operand:SI 2 "uns_small_int" ""))
6324 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6325 [(set_attr "type" "multi")
6326 (set_attr "length" "2")])
6328 ;; The v8 architecture specifies that there must be 3 instructions between
6329 ;; a y register write and a use of it for correct results.
6331 (define_expand "divsi3"
6332 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6333 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6334 (match_operand:SI 2 "input_operand" "rI,m")))
6335 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6336 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6341 operands[3] = gen_reg_rtx(SImode);
6342 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6343 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6349 (define_insn "divsi3_sp32"
6350 [(set (match_operand:SI 0 "register_operand" "=r,r")
6351 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6352 (match_operand:SI 2 "input_operand" "rI,m")))
6353 (clobber (match_scratch:SI 3 "=&r,&r"))]
6354 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6358 if (which_alternative == 0)
6360 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6362 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6365 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6367 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\";
6369 [(set_attr "type" "multi")
6370 (set (attr "length")
6371 (if_then_else (eq_attr "isa" "v9")
6372 (const_int 4) (const_int 7)))])
6374 (define_insn "divsi3_sp64"
6375 [(set (match_operand:SI 0 "register_operand" "=r")
6376 (div:SI (match_operand:SI 1 "register_operand" "r")
6377 (match_operand:SI 2 "input_operand" "rI")))
6378 (use (match_operand:SI 3 "register_operand" "r"))]
6379 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6380 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6381 [(set_attr "type" "multi")
6382 (set_attr "length" "2")])
6384 (define_insn "divdi3"
6385 [(set (match_operand:DI 0 "register_operand" "=r")
6386 (div:DI (match_operand:DI 1 "register_operand" "r")
6387 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6389 "sdivx\\t%1, %2, %0"
6390 [(set_attr "type" "idiv")])
6392 (define_insn "*cmp_sdiv_cc_set"
6394 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6395 (match_operand:SI 2 "arith_operand" "rI"))
6397 (set (match_operand:SI 0 "register_operand" "=r")
6398 (div:SI (match_dup 1) (match_dup 2)))
6399 (clobber (match_scratch:SI 3 "=&r"))]
6400 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6404 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6406 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6408 [(set_attr "type" "multi")
6409 (set (attr "length")
6410 (if_then_else (eq_attr "isa" "v9")
6411 (const_int 3) (const_int 6)))])
6414 (define_expand "udivsi3"
6415 [(set (match_operand:SI 0 "register_operand" "")
6416 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6417 (match_operand:SI 2 "input_operand" "")))]
6418 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6421 (define_insn "udivsi3_sp32"
6422 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6423 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6424 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6426 || TARGET_DEPRECATED_V8_INSNS)
6430 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6431 switch (which_alternative)
6434 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6436 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6438 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6441 [(set_attr "type" "multi")
6442 (set_attr "length" "5")])
6444 (define_insn "udivsi3_sp64"
6445 [(set (match_operand:SI 0 "register_operand" "=r")
6446 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6447 (match_operand:SI 2 "input_operand" "rI")))]
6448 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6449 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6450 [(set_attr "type" "multi")
6451 (set_attr "length" "2")])
6453 (define_insn "udivdi3"
6454 [(set (match_operand:DI 0 "register_operand" "=r")
6455 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6456 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6458 "udivx\\t%1, %2, %0"
6459 [(set_attr "type" "idiv")])
6461 (define_insn "*cmp_udiv_cc_set"
6463 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6464 (match_operand:SI 2 "arith_operand" "rI"))
6466 (set (match_operand:SI 0 "register_operand" "=r")
6467 (udiv:SI (match_dup 1) (match_dup 2)))]
6469 || TARGET_DEPRECATED_V8_INSNS"
6473 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6475 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6477 [(set_attr "type" "multi")
6478 (set (attr "length")
6479 (if_then_else (eq_attr "isa" "v9")
6480 (const_int 2) (const_int 5)))])
6482 ; sparclet multiply/accumulate insns
6484 (define_insn "*smacsi"
6485 [(set (match_operand:SI 0 "register_operand" "=r")
6486 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6487 (match_operand:SI 2 "arith_operand" "rI"))
6488 (match_operand:SI 3 "register_operand" "0")))]
6491 [(set_attr "type" "imul")])
6493 (define_insn "*smacdi"
6494 [(set (match_operand:DI 0 "register_operand" "=r")
6495 (plus:DI (mult:DI (sign_extend:DI
6496 (match_operand:SI 1 "register_operand" "%r"))
6498 (match_operand:SI 2 "register_operand" "r")))
6499 (match_operand:DI 3 "register_operand" "0")))]
6501 "smacd\\t%1, %2, %L0"
6502 [(set_attr "type" "imul")])
6504 (define_insn "*umacdi"
6505 [(set (match_operand:DI 0 "register_operand" "=r")
6506 (plus:DI (mult:DI (zero_extend:DI
6507 (match_operand:SI 1 "register_operand" "%r"))
6509 (match_operand:SI 2 "register_operand" "r")))
6510 (match_operand:DI 3 "register_operand" "0")))]
6512 "umacd\\t%1, %2, %L0"
6513 [(set_attr "type" "imul")])
6515 ;;- Boolean instructions
6516 ;; We define DImode `and' so with DImode `not' we can get
6517 ;; DImode `andn'. Other combinations are possible.
6519 (define_expand "anddi3"
6520 [(set (match_operand:DI 0 "register_operand" "")
6521 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6522 (match_operand:DI 2 "arith_double_operand" "")))]
6526 (define_insn "*anddi3_sp32"
6527 [(set (match_operand:DI 0 "register_operand" "=r,b")
6528 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6529 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6534 [(set_attr "type" "*,fp")
6535 (set_attr "length" "2,*")
6536 (set_attr "fptype" "double")])
6538 (define_insn "*anddi3_sp64"
6539 [(set (match_operand:DI 0 "register_operand" "=r,b")
6540 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6541 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6546 [(set_attr "type" "*,fp")
6547 (set_attr "fptype" "double")])
6549 (define_insn "andsi3"
6550 [(set (match_operand:SI 0 "register_operand" "=r,d")
6551 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6552 (match_operand:SI 2 "arith_operand" "rI,d")))]
6557 [(set_attr "type" "*,fp")])
6560 [(set (match_operand:SI 0 "register_operand" "")
6561 (and:SI (match_operand:SI 1 "register_operand" "")
6562 (match_operand:SI 2 "" "")))
6563 (clobber (match_operand:SI 3 "register_operand" ""))]
6564 "GET_CODE (operands[2]) == CONST_INT
6565 && !SMALL_INT32 (operands[2])
6566 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6567 [(set (match_dup 3) (match_dup 4))
6568 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6571 operands[4] = GEN_INT (~INTVAL (operands[2]));
6574 ;; Split DImode logical operations requiring two instructions.
6576 [(set (match_operand:DI 0 "register_operand" "")
6577 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6578 [(match_operand:DI 2 "register_operand" "")
6579 (match_operand:DI 3 "arith_double_operand" "")]))]
6582 && ((GET_CODE (operands[0]) == REG
6583 && REGNO (operands[0]) < 32)
6584 || (GET_CODE (operands[0]) == SUBREG
6585 && GET_CODE (SUBREG_REG (operands[0])) == REG
6586 && REGNO (SUBREG_REG (operands[0])) < 32))"
6587 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6588 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6591 operands[4] = gen_highpart (SImode, operands[0]);
6592 operands[5] = gen_lowpart (SImode, operands[0]);
6593 operands[6] = gen_highpart (SImode, operands[2]);
6594 operands[7] = gen_lowpart (SImode, operands[2]);
6595 #if HOST_BITS_PER_WIDE_INT == 32
6596 if (GET_CODE (operands[3]) == CONST_INT)
6598 if (INTVAL (operands[3]) < 0)
6599 operands[8] = constm1_rtx;
6601 operands[8] = const0_rtx;
6605 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6606 operands[9] = gen_lowpart (SImode, operands[3]);
6609 (define_insn "*and_not_di_sp32"
6610 [(set (match_operand:DI 0 "register_operand" "=r,b")
6611 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6612 (match_operand:DI 2 "register_operand" "r,b")))]
6616 fandnot1\\t%1, %2, %0"
6617 [(set_attr "type" "*,fp")
6618 (set_attr "length" "2,*")
6619 (set_attr "fptype" "double")])
6622 [(set (match_operand:DI 0 "register_operand" "")
6623 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6624 (match_operand:DI 2 "register_operand" "")))]
6627 && ((GET_CODE (operands[0]) == REG
6628 && REGNO (operands[0]) < 32)
6629 || (GET_CODE (operands[0]) == SUBREG
6630 && GET_CODE (SUBREG_REG (operands[0])) == REG
6631 && REGNO (SUBREG_REG (operands[0])) < 32))"
6632 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6633 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6634 "operands[3] = gen_highpart (SImode, operands[0]);
6635 operands[4] = gen_highpart (SImode, operands[1]);
6636 operands[5] = gen_highpart (SImode, operands[2]);
6637 operands[6] = gen_lowpart (SImode, operands[0]);
6638 operands[7] = gen_lowpart (SImode, operands[1]);
6639 operands[8] = gen_lowpart (SImode, operands[2]);")
6641 (define_insn "*and_not_di_sp64"
6642 [(set (match_operand:DI 0 "register_operand" "=r,b")
6643 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6644 (match_operand:DI 2 "register_operand" "r,b")))]
6648 fandnot1\\t%1, %2, %0"
6649 [(set_attr "type" "*,fp")
6650 (set_attr "fptype" "double")])
6652 (define_insn "*and_not_si"
6653 [(set (match_operand:SI 0 "register_operand" "=r,d")
6654 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6655 (match_operand:SI 2 "register_operand" "r,d")))]
6659 fandnot1s\\t%1, %2, %0"
6660 [(set_attr "type" "*,fp")])
6662 (define_expand "iordi3"
6663 [(set (match_operand:DI 0 "register_operand" "")
6664 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6665 (match_operand:DI 2 "arith_double_operand" "")))]
6669 (define_insn "*iordi3_sp32"
6670 [(set (match_operand:DI 0 "register_operand" "=r,b")
6671 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6672 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6677 [(set_attr "type" "*,fp")
6678 (set_attr "length" "2,*")
6679 (set_attr "fptype" "double")])
6681 (define_insn "*iordi3_sp64"
6682 [(set (match_operand:DI 0 "register_operand" "=r,b")
6683 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6684 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6689 [(set_attr "type" "*,fp")
6690 (set_attr "fptype" "double")])
6692 (define_insn "iorsi3"
6693 [(set (match_operand:SI 0 "register_operand" "=r,d")
6694 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6695 (match_operand:SI 2 "arith_operand" "rI,d")))]
6700 [(set_attr "type" "*,fp")])
6703 [(set (match_operand:SI 0 "register_operand" "")
6704 (ior:SI (match_operand:SI 1 "register_operand" "")
6705 (match_operand:SI 2 "" "")))
6706 (clobber (match_operand:SI 3 "register_operand" ""))]
6707 "GET_CODE (operands[2]) == CONST_INT
6708 && !SMALL_INT32 (operands[2])
6709 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6710 [(set (match_dup 3) (match_dup 4))
6711 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6714 operands[4] = GEN_INT (~INTVAL (operands[2]));
6717 (define_insn "*or_not_di_sp32"
6718 [(set (match_operand:DI 0 "register_operand" "=r,b")
6719 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6720 (match_operand:DI 2 "register_operand" "r,b")))]
6724 fornot1\\t%1, %2, %0"
6725 [(set_attr "type" "*,fp")
6726 (set_attr "length" "2,*")
6727 (set_attr "fptype" "double")])
6730 [(set (match_operand:DI 0 "register_operand" "")
6731 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6732 (match_operand:DI 2 "register_operand" "")))]
6735 && ((GET_CODE (operands[0]) == REG
6736 && REGNO (operands[0]) < 32)
6737 || (GET_CODE (operands[0]) == SUBREG
6738 && GET_CODE (SUBREG_REG (operands[0])) == REG
6739 && REGNO (SUBREG_REG (operands[0])) < 32))"
6740 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6741 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6742 "operands[3] = gen_highpart (SImode, operands[0]);
6743 operands[4] = gen_highpart (SImode, operands[1]);
6744 operands[5] = gen_highpart (SImode, operands[2]);
6745 operands[6] = gen_lowpart (SImode, operands[0]);
6746 operands[7] = gen_lowpart (SImode, operands[1]);
6747 operands[8] = gen_lowpart (SImode, operands[2]);")
6749 (define_insn "*or_not_di_sp64"
6750 [(set (match_operand:DI 0 "register_operand" "=r,b")
6751 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6752 (match_operand:DI 2 "register_operand" "r,b")))]
6756 fornot1\\t%1, %2, %0"
6757 [(set_attr "type" "*,fp")
6758 (set_attr "fptype" "double")])
6760 (define_insn "*or_not_si"
6761 [(set (match_operand:SI 0 "register_operand" "=r,d")
6762 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6763 (match_operand:SI 2 "register_operand" "r,d")))]
6767 fornot1s\\t%1, %2, %0"
6768 [(set_attr "type" "*,fp")])
6770 (define_expand "xordi3"
6771 [(set (match_operand:DI 0 "register_operand" "")
6772 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6773 (match_operand:DI 2 "arith_double_operand" "")))]
6777 (define_insn "*xordi3_sp32"
6778 [(set (match_operand:DI 0 "register_operand" "=r,b")
6779 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6780 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6785 [(set_attr "type" "*,fp")
6786 (set_attr "length" "2,*")
6787 (set_attr "fptype" "double")])
6789 (define_insn "*xordi3_sp64"
6790 [(set (match_operand:DI 0 "register_operand" "=r,b")
6791 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6792 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6797 [(set_attr "type" "*,fp")
6798 (set_attr "fptype" "double")])
6800 (define_insn "*xordi3_sp64_dbl"
6801 [(set (match_operand:DI 0 "register_operand" "=r")
6802 (xor:DI (match_operand:DI 1 "register_operand" "r")
6803 (match_operand:DI 2 "const64_operand" "")))]
6805 && HOST_BITS_PER_WIDE_INT != 64)"
6808 (define_insn "xorsi3"
6809 [(set (match_operand:SI 0 "register_operand" "=r,d")
6810 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6811 (match_operand:SI 2 "arith_operand" "rI,d")))]
6816 [(set_attr "type" "*,fp")])
6819 [(set (match_operand:SI 0 "register_operand" "")
6820 (xor:SI (match_operand:SI 1 "register_operand" "")
6821 (match_operand:SI 2 "" "")))
6822 (clobber (match_operand:SI 3 "register_operand" ""))]
6823 "GET_CODE (operands[2]) == CONST_INT
6824 && !SMALL_INT32 (operands[2])
6825 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6826 [(set (match_dup 3) (match_dup 4))
6827 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6830 operands[4] = GEN_INT (~INTVAL (operands[2]));
6834 [(set (match_operand:SI 0 "register_operand" "")
6835 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6836 (match_operand:SI 2 "" ""))))
6837 (clobber (match_operand:SI 3 "register_operand" ""))]
6838 "GET_CODE (operands[2]) == CONST_INT
6839 && !SMALL_INT32 (operands[2])
6840 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6841 [(set (match_dup 3) (match_dup 4))
6842 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6845 operands[4] = GEN_INT (~INTVAL (operands[2]));
6848 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6849 ;; Combine now canonicalizes to the rightmost expression.
6850 (define_insn "*xor_not_di_sp32"
6851 [(set (match_operand:DI 0 "register_operand" "=r,b")
6852 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6853 (match_operand:DI 2 "register_operand" "r,b"))))]
6858 [(set_attr "type" "*,fp")
6859 (set_attr "length" "2,*")
6860 (set_attr "fptype" "double")])
6863 [(set (match_operand:DI 0 "register_operand" "")
6864 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6865 (match_operand:DI 2 "register_operand" ""))))]
6868 && ((GET_CODE (operands[0]) == REG
6869 && REGNO (operands[0]) < 32)
6870 || (GET_CODE (operands[0]) == SUBREG
6871 && GET_CODE (SUBREG_REG (operands[0])) == REG
6872 && REGNO (SUBREG_REG (operands[0])) < 32))"
6873 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6874 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6875 "operands[3] = gen_highpart (SImode, operands[0]);
6876 operands[4] = gen_highpart (SImode, operands[1]);
6877 operands[5] = gen_highpart (SImode, operands[2]);
6878 operands[6] = gen_lowpart (SImode, operands[0]);
6879 operands[7] = gen_lowpart (SImode, operands[1]);
6880 operands[8] = gen_lowpart (SImode, operands[2]);")
6882 (define_insn "*xor_not_di_sp64"
6883 [(set (match_operand:DI 0 "register_operand" "=r,b")
6884 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6885 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6890 [(set_attr "type" "*,fp")
6891 (set_attr "fptype" "double")])
6893 (define_insn "*xor_not_si"
6894 [(set (match_operand:SI 0 "register_operand" "=r,d")
6895 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6896 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6900 fxnors\\t%1, %2, %0"
6901 [(set_attr "type" "*,fp")])
6903 ;; These correspond to the above in the case where we also (or only)
6904 ;; want to set the condition code.
6906 (define_insn "*cmp_cc_arith_op"
6909 (match_operator:SI 2 "cc_arithop"
6910 [(match_operand:SI 0 "arith_operand" "%r")
6911 (match_operand:SI 1 "arith_operand" "rI")])
6914 "%A2cc\\t%0, %1, %%g0"
6915 [(set_attr "type" "compare")])
6917 (define_insn "*cmp_ccx_arith_op"
6920 (match_operator:DI 2 "cc_arithop"
6921 [(match_operand:DI 0 "arith_double_operand" "%r")
6922 (match_operand:DI 1 "arith_double_operand" "rHI")])
6925 "%A2cc\\t%0, %1, %%g0"
6926 [(set_attr "type" "compare")])
6928 (define_insn "*cmp_cc_arith_op_set"
6931 (match_operator:SI 3 "cc_arithop"
6932 [(match_operand:SI 1 "arith_operand" "%r")
6933 (match_operand:SI 2 "arith_operand" "rI")])
6935 (set (match_operand:SI 0 "register_operand" "=r")
6936 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6937 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6938 "%A3cc\\t%1, %2, %0"
6939 [(set_attr "type" "compare")])
6941 (define_insn "*cmp_ccx_arith_op_set"
6944 (match_operator:DI 3 "cc_arithop"
6945 [(match_operand:DI 1 "arith_double_operand" "%r")
6946 (match_operand:DI 2 "arith_double_operand" "rHI")])
6948 (set (match_operand:DI 0 "register_operand" "=r")
6949 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6950 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6951 "%A3cc\\t%1, %2, %0"
6952 [(set_attr "type" "compare")])
6954 (define_insn "*cmp_cc_xor_not"
6957 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6958 (match_operand:SI 1 "arith_operand" "rI")))
6961 "xnorcc\\t%r0, %1, %%g0"
6962 [(set_attr "type" "compare")])
6964 (define_insn "*cmp_ccx_xor_not"
6967 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6968 (match_operand:DI 1 "arith_double_operand" "rHI")))
6971 "xnorcc\\t%r0, %1, %%g0"
6972 [(set_attr "type" "compare")])
6974 (define_insn "*cmp_cc_xor_not_set"
6977 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6978 (match_operand:SI 2 "arith_operand" "rI")))
6980 (set (match_operand:SI 0 "register_operand" "=r")
6981 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6983 "xnorcc\\t%r1, %2, %0"
6984 [(set_attr "type" "compare")])
6986 (define_insn "*cmp_ccx_xor_not_set"
6989 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6990 (match_operand:DI 2 "arith_double_operand" "rHI")))
6992 (set (match_operand:DI 0 "register_operand" "=r")
6993 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6995 "xnorcc\\t%r1, %2, %0"
6996 [(set_attr "type" "compare")])
6998 (define_insn "*cmp_cc_arith_op_not"
7001 (match_operator:SI 2 "cc_arithopn"
7002 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7003 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7006 "%B2cc\\t%r1, %0, %%g0"
7007 [(set_attr "type" "compare")])
7009 (define_insn "*cmp_ccx_arith_op_not"
7012 (match_operator:DI 2 "cc_arithopn"
7013 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7014 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7017 "%B2cc\\t%r1, %0, %%g0"
7018 [(set_attr "type" "compare")])
7020 (define_insn "*cmp_cc_arith_op_not_set"
7023 (match_operator:SI 3 "cc_arithopn"
7024 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7025 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7027 (set (match_operand:SI 0 "register_operand" "=r")
7028 (match_operator:SI 4 "cc_arithopn"
7029 [(not:SI (match_dup 1)) (match_dup 2)]))]
7030 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7031 "%B3cc\\t%r2, %1, %0"
7032 [(set_attr "type" "compare")])
7034 (define_insn "*cmp_ccx_arith_op_not_set"
7037 (match_operator:DI 3 "cc_arithopn"
7038 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7039 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7041 (set (match_operand:DI 0 "register_operand" "=r")
7042 (match_operator:DI 4 "cc_arithopn"
7043 [(not:DI (match_dup 1)) (match_dup 2)]))]
7044 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7045 "%B3cc\\t%r2, %1, %0"
7046 [(set_attr "type" "compare")])
7048 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7049 ;; does not know how to make it work for constants.
7051 (define_expand "negdi2"
7052 [(set (match_operand:DI 0 "register_operand" "=r")
7053 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7057 if (! TARGET_ARCH64)
7059 emit_insn (gen_rtx_PARALLEL
7062 gen_rtx_SET (VOIDmode, operand0,
7063 gen_rtx_NEG (DImode, operand1)),
7064 gen_rtx_CLOBBER (VOIDmode,
7065 gen_rtx_REG (CCmode,
7071 (define_insn "*negdi2_sp32"
7072 [(set (match_operand:DI 0 "register_operand" "=r")
7073 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7074 (clobber (reg:CC 100))]
7077 [(set_attr "length" "2")])
7080 [(set (match_operand:DI 0 "register_operand" "")
7081 (neg:DI (match_operand:DI 1 "register_operand" "")))
7082 (clobber (reg:CC 100))]
7084 && reload_completed"
7085 [(parallel [(set (reg:CC_NOOV 100)
7086 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7088 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7089 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7090 (ltu:SI (reg:CC 100) (const_int 0))))]
7091 "operands[2] = gen_highpart (SImode, operands[0]);
7092 operands[3] = gen_highpart (SImode, operands[1]);
7093 operands[4] = gen_lowpart (SImode, operands[0]);
7094 operands[5] = gen_lowpart (SImode, operands[1]);")
7096 (define_insn "*negdi2_sp64"
7097 [(set (match_operand:DI 0 "register_operand" "=r")
7098 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7100 "sub\\t%%g0, %1, %0")
7102 (define_insn "negsi2"
7103 [(set (match_operand:SI 0 "register_operand" "=r")
7104 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7106 "sub\\t%%g0, %1, %0")
7108 (define_insn "*cmp_cc_neg"
7109 [(set (reg:CC_NOOV 100)
7110 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7113 "subcc\\t%%g0, %0, %%g0"
7114 [(set_attr "type" "compare")])
7116 (define_insn "*cmp_ccx_neg"
7117 [(set (reg:CCX_NOOV 100)
7118 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7121 "subcc\\t%%g0, %0, %%g0"
7122 [(set_attr "type" "compare")])
7124 (define_insn "*cmp_cc_set_neg"
7125 [(set (reg:CC_NOOV 100)
7126 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7128 (set (match_operand:SI 0 "register_operand" "=r")
7129 (neg:SI (match_dup 1)))]
7131 "subcc\\t%%g0, %1, %0"
7132 [(set_attr "type" "compare")])
7134 (define_insn "*cmp_ccx_set_neg"
7135 [(set (reg:CCX_NOOV 100)
7136 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7138 (set (match_operand:DI 0 "register_operand" "=r")
7139 (neg:DI (match_dup 1)))]
7141 "subcc\\t%%g0, %1, %0"
7142 [(set_attr "type" "compare")])
7144 ;; We cannot use the "not" pseudo insn because the Sun assembler
7145 ;; does not know how to make it work for constants.
7146 (define_expand "one_cmpldi2"
7147 [(set (match_operand:DI 0 "register_operand" "")
7148 (not:DI (match_operand:DI 1 "register_operand" "")))]
7152 (define_insn "*one_cmpldi2_sp32"
7153 [(set (match_operand:DI 0 "register_operand" "=r,b")
7154 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7159 [(set_attr "type" "*,fp")
7160 (set_attr "length" "2,*")
7161 (set_attr "fptype" "double")])
7164 [(set (match_operand:DI 0 "register_operand" "")
7165 (not:DI (match_operand:DI 1 "register_operand" "")))]
7168 && ((GET_CODE (operands[0]) == REG
7169 && REGNO (operands[0]) < 32)
7170 || (GET_CODE (operands[0]) == SUBREG
7171 && GET_CODE (SUBREG_REG (operands[0])) == REG
7172 && REGNO (SUBREG_REG (operands[0])) < 32))"
7173 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7174 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7175 "operands[2] = gen_highpart (SImode, operands[0]);
7176 operands[3] = gen_highpart (SImode, operands[1]);
7177 operands[4] = gen_lowpart (SImode, operands[0]);
7178 operands[5] = gen_lowpart (SImode, operands[1]);")
7180 (define_insn "*one_cmpldi2_sp64"
7181 [(set (match_operand:DI 0 "register_operand" "=r,b")
7182 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7187 [(set_attr "type" "*,fp")
7188 (set_attr "fptype" "double")])
7190 (define_insn "one_cmplsi2"
7191 [(set (match_operand:SI 0 "register_operand" "=r,d")
7192 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7197 [(set_attr "type" "*,fp")])
7199 (define_insn "*cmp_cc_not"
7201 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7204 "xnorcc\\t%%g0, %0, %%g0"
7205 [(set_attr "type" "compare")])
7207 (define_insn "*cmp_ccx_not"
7209 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7212 "xnorcc\\t%%g0, %0, %%g0"
7213 [(set_attr "type" "compare")])
7215 (define_insn "*cmp_cc_set_not"
7217 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7219 (set (match_operand:SI 0 "register_operand" "=r")
7220 (not:SI (match_dup 1)))]
7222 "xnorcc\\t%%g0, %1, %0"
7223 [(set_attr "type" "compare")])
7225 (define_insn "*cmp_ccx_set_not"
7227 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7229 (set (match_operand:DI 0 "register_operand" "=r")
7230 (not:DI (match_dup 1)))]
7232 "xnorcc\\t%%g0, %1, %0"
7233 [(set_attr "type" "compare")])
7235 (define_insn "*cmp_cc_set"
7236 [(set (match_operand:SI 0 "register_operand" "=r")
7237 (match_operand:SI 1 "register_operand" "r"))
7239 (compare:CC (match_dup 1)
7243 [(set_attr "type" "compare")])
7245 (define_insn "*cmp_ccx_set64"
7246 [(set (match_operand:DI 0 "register_operand" "=r")
7247 (match_operand:DI 1 "register_operand" "r"))
7249 (compare:CCX (match_dup 1)
7253 [(set_attr "type" "compare")])
7255 ;; Floating point arithmetic instructions.
7257 (define_expand "addtf3"
7258 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7259 (plus:TF (match_operand:TF 1 "general_operand" "")
7260 (match_operand:TF 2 "general_operand" "")))]
7261 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7264 if (! TARGET_HARD_QUAD)
7266 rtx slot0, slot1, slot2;
7268 if (GET_CODE (operands[0]) != MEM)
7269 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7271 slot0 = operands[0];
7272 if (GET_CODE (operands[1]) != MEM)
7274 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7275 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7278 slot1 = operands[1];
7279 if (GET_CODE (operands[2]) != MEM)
7281 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7282 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7285 slot2 = operands[2];
7287 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7289 XEXP (slot0, 0), Pmode,
7290 XEXP (slot1, 0), Pmode,
7291 XEXP (slot2, 0), Pmode);
7293 if (GET_CODE (operands[0]) != MEM)
7294 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7299 (define_insn "*addtf3_hq"
7300 [(set (match_operand:TF 0 "register_operand" "=e")
7301 (plus:TF (match_operand:TF 1 "register_operand" "e")
7302 (match_operand:TF 2 "register_operand" "e")))]
7303 "TARGET_FPU && TARGET_HARD_QUAD"
7304 "faddq\\t%1, %2, %0"
7305 [(set_attr "type" "fp")])
7307 (define_insn "adddf3"
7308 [(set (match_operand:DF 0 "register_operand" "=e")
7309 (plus:DF (match_operand:DF 1 "register_operand" "e")
7310 (match_operand:DF 2 "register_operand" "e")))]
7312 "faddd\\t%1, %2, %0"
7313 [(set_attr "type" "fp")
7314 (set_attr "fptype" "double")])
7316 (define_insn "addsf3"
7317 [(set (match_operand:SF 0 "register_operand" "=f")
7318 (plus:SF (match_operand:SF 1 "register_operand" "f")
7319 (match_operand:SF 2 "register_operand" "f")))]
7321 "fadds\\t%1, %2, %0"
7322 [(set_attr "type" "fp")])
7324 (define_expand "subtf3"
7325 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7326 (minus:TF (match_operand:TF 1 "general_operand" "")
7327 (match_operand:TF 2 "general_operand" "")))]
7328 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7331 if (! TARGET_HARD_QUAD)
7333 rtx slot0, slot1, slot2;
7335 if (GET_CODE (operands[0]) != MEM)
7336 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7338 slot0 = operands[0];
7339 if (GET_CODE (operands[1]) != MEM)
7341 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7342 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7345 slot1 = operands[1];
7346 if (GET_CODE (operands[2]) != MEM)
7348 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7349 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7352 slot2 = operands[2];
7354 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7356 XEXP (slot0, 0), Pmode,
7357 XEXP (slot1, 0), Pmode,
7358 XEXP (slot2, 0), Pmode);
7360 if (GET_CODE (operands[0]) != MEM)
7361 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7366 (define_insn "*subtf3_hq"
7367 [(set (match_operand:TF 0 "register_operand" "=e")
7368 (minus:TF (match_operand:TF 1 "register_operand" "e")
7369 (match_operand:TF 2 "register_operand" "e")))]
7370 "TARGET_FPU && TARGET_HARD_QUAD"
7371 "fsubq\\t%1, %2, %0"
7372 [(set_attr "type" "fp")])
7374 (define_insn "subdf3"
7375 [(set (match_operand:DF 0 "register_operand" "=e")
7376 (minus:DF (match_operand:DF 1 "register_operand" "e")
7377 (match_operand:DF 2 "register_operand" "e")))]
7379 "fsubd\\t%1, %2, %0"
7380 [(set_attr "type" "fp")
7381 (set_attr "fptype" "double")])
7383 (define_insn "subsf3"
7384 [(set (match_operand:SF 0 "register_operand" "=f")
7385 (minus:SF (match_operand:SF 1 "register_operand" "f")
7386 (match_operand:SF 2 "register_operand" "f")))]
7388 "fsubs\\t%1, %2, %0"
7389 [(set_attr "type" "fp")])
7391 (define_expand "multf3"
7392 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7393 (mult:TF (match_operand:TF 1 "general_operand" "")
7394 (match_operand:TF 2 "general_operand" "")))]
7395 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7398 if (! TARGET_HARD_QUAD)
7400 rtx slot0, slot1, slot2;
7402 if (GET_CODE (operands[0]) != MEM)
7403 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7405 slot0 = operands[0];
7406 if (GET_CODE (operands[1]) != MEM)
7408 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7409 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7412 slot1 = operands[1];
7413 if (GET_CODE (operands[2]) != MEM)
7415 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7416 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7419 slot2 = operands[2];
7421 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7423 XEXP (slot0, 0), Pmode,
7424 XEXP (slot1, 0), Pmode,
7425 XEXP (slot2, 0), Pmode);
7427 if (GET_CODE (operands[0]) != MEM)
7428 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7433 (define_insn "*multf3_hq"
7434 [(set (match_operand:TF 0 "register_operand" "=e")
7435 (mult:TF (match_operand:TF 1 "register_operand" "e")
7436 (match_operand:TF 2 "register_operand" "e")))]
7437 "TARGET_FPU && TARGET_HARD_QUAD"
7438 "fmulq\\t%1, %2, %0"
7439 [(set_attr "type" "fpmul")])
7441 (define_insn "muldf3"
7442 [(set (match_operand:DF 0 "register_operand" "=e")
7443 (mult:DF (match_operand:DF 1 "register_operand" "e")
7444 (match_operand:DF 2 "register_operand" "e")))]
7446 "fmuld\\t%1, %2, %0"
7447 [(set_attr "type" "fpmul")
7448 (set_attr "fptype" "double")])
7450 (define_insn "mulsf3"
7451 [(set (match_operand:SF 0 "register_operand" "=f")
7452 (mult:SF (match_operand:SF 1 "register_operand" "f")
7453 (match_operand:SF 2 "register_operand" "f")))]
7455 "fmuls\\t%1, %2, %0"
7456 [(set_attr "type" "fpmul")])
7458 (define_insn "*muldf3_extend"
7459 [(set (match_operand:DF 0 "register_operand" "=e")
7460 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7461 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7462 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7463 "fsmuld\\t%1, %2, %0"
7464 [(set_attr "type" "fpmul")
7465 (set_attr "fptype" "double")])
7467 (define_insn "*multf3_extend"
7468 [(set (match_operand:TF 0 "register_operand" "=e")
7469 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7470 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7471 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7472 "fdmulq\\t%1, %2, %0"
7473 [(set_attr "type" "fpmul")])
7475 (define_expand "divtf3"
7476 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7477 (div:TF (match_operand:TF 1 "general_operand" "")
7478 (match_operand:TF 2 "general_operand" "")))]
7479 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7482 if (! TARGET_HARD_QUAD)
7484 rtx slot0, slot1, slot2;
7486 if (GET_CODE (operands[0]) != MEM)
7487 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7489 slot0 = operands[0];
7490 if (GET_CODE (operands[1]) != MEM)
7492 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7493 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7496 slot1 = operands[1];
7497 if (GET_CODE (operands[2]) != MEM)
7499 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7500 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7503 slot2 = operands[2];
7505 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7507 XEXP (slot0, 0), Pmode,
7508 XEXP (slot1, 0), Pmode,
7509 XEXP (slot2, 0), Pmode);
7511 if (GET_CODE (operands[0]) != MEM)
7512 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7517 ;; don't have timing for quad-prec. divide.
7518 (define_insn "*divtf3_hq"
7519 [(set (match_operand:TF 0 "register_operand" "=e")
7520 (div:TF (match_operand:TF 1 "register_operand" "e")
7521 (match_operand:TF 2 "register_operand" "e")))]
7522 "TARGET_FPU && TARGET_HARD_QUAD"
7523 "fdivq\\t%1, %2, %0"
7524 [(set_attr "type" "fpdivd")])
7526 (define_insn "divdf3"
7527 [(set (match_operand:DF 0 "register_operand" "=e")
7528 (div:DF (match_operand:DF 1 "register_operand" "e")
7529 (match_operand:DF 2 "register_operand" "e")))]
7531 "fdivd\\t%1, %2, %0"
7532 [(set_attr "type" "fpdivd")
7533 (set_attr "fptype" "double")])
7535 (define_insn "divsf3"
7536 [(set (match_operand:SF 0 "register_operand" "=f")
7537 (div:SF (match_operand:SF 1 "register_operand" "f")
7538 (match_operand:SF 2 "register_operand" "f")))]
7540 "fdivs\\t%1, %2, %0"
7541 [(set_attr "type" "fpdivs")])
7543 (define_expand "negtf2"
7544 [(set (match_operand:TF 0 "register_operand" "=e,e")
7545 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7549 (define_insn "*negtf2_notv9"
7550 [(set (match_operand:TF 0 "register_operand" "=e,e")
7551 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7552 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7558 [(set_attr "type" "fpmove,*")
7559 (set_attr "length" "*,2")])
7562 [(set (match_operand:TF 0 "register_operand" "")
7563 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7567 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7568 [(set (match_dup 2) (neg:SF (match_dup 3)))
7569 (set (match_dup 4) (match_dup 5))
7570 (set (match_dup 6) (match_dup 7))]
7571 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7572 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7573 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7574 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7575 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7576 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7578 (define_insn "*negtf2_v9"
7579 [(set (match_operand:TF 0 "register_operand" "=e,e")
7580 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7581 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7582 "TARGET_FPU && TARGET_V9"
7586 [(set_attr "type" "fpmove,*")
7587 (set_attr "length" "*,2")
7588 (set_attr "fptype" "double")])
7591 [(set (match_operand:TF 0 "register_operand" "")
7592 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7596 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7597 [(set (match_dup 2) (neg:DF (match_dup 3)))
7598 (set (match_dup 4) (match_dup 5))]
7599 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7600 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7601 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7602 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7604 (define_expand "negdf2"
7605 [(set (match_operand:DF 0 "register_operand" "")
7606 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7610 (define_insn "*negdf2_notv9"
7611 [(set (match_operand:DF 0 "register_operand" "=e,e")
7612 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7613 "TARGET_FPU && ! TARGET_V9"
7617 [(set_attr "type" "fpmove,*")
7618 (set_attr "length" "*,2")])
7621 [(set (match_operand:DF 0 "register_operand" "")
7622 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7626 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7627 [(set (match_dup 2) (neg:SF (match_dup 3)))
7628 (set (match_dup 4) (match_dup 5))]
7629 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7630 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7631 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7632 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7634 (define_insn "*negdf2_v9"
7635 [(set (match_operand:DF 0 "register_operand" "=e")
7636 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7637 "TARGET_FPU && TARGET_V9"
7639 [(set_attr "type" "fpmove")
7640 (set_attr "fptype" "double")])
7642 (define_insn "negsf2"
7643 [(set (match_operand:SF 0 "register_operand" "=f")
7644 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7647 [(set_attr "type" "fpmove")])
7649 (define_expand "abstf2"
7650 [(set (match_operand:TF 0 "register_operand" "")
7651 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7655 (define_insn "*abstf2_notv9"
7656 [(set (match_operand:TF 0 "register_operand" "=e,e")
7657 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7658 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7659 "TARGET_FPU && ! TARGET_V9"
7663 [(set_attr "type" "fpmove,*")
7664 (set_attr "length" "*,2")])
7667 [(set (match_operand:TF 0 "register_operand" "")
7668 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7672 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7673 [(set (match_dup 2) (abs:SF (match_dup 3)))
7674 (set (match_dup 4) (match_dup 5))
7675 (set (match_dup 6) (match_dup 7))]
7676 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7677 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7678 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7679 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7680 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7681 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7683 (define_insn "*abstf2_hq_v9"
7684 [(set (match_operand:TF 0 "register_operand" "=e,e")
7685 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7686 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7690 [(set_attr "type" "fpmove")
7691 (set_attr "fptype" "double,*")])
7693 (define_insn "*abstf2_v9"
7694 [(set (match_operand:TF 0 "register_operand" "=e,e")
7695 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7696 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7700 [(set_attr "type" "fpmove,*")
7701 (set_attr "length" "*,2")
7702 (set_attr "fptype" "double,*")])
7705 [(set (match_operand:TF 0 "register_operand" "")
7706 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7710 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7711 [(set (match_dup 2) (abs:DF (match_dup 3)))
7712 (set (match_dup 4) (match_dup 5))]
7713 "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7714 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7715 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7716 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7718 (define_expand "absdf2"
7719 [(set (match_operand:DF 0 "register_operand" "")
7720 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7724 (define_insn "*absdf2_notv9"
7725 [(set (match_operand:DF 0 "register_operand" "=e,e")
7726 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7727 "TARGET_FPU && ! TARGET_V9"
7731 [(set_attr "type" "fpmove,*")
7732 (set_attr "length" "*,2")])
7735 [(set (match_operand:DF 0 "register_operand" "")
7736 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7740 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7741 [(set (match_dup 2) (abs:SF (match_dup 3)))
7742 (set (match_dup 4) (match_dup 5))]
7743 "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7744 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7745 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7746 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7748 (define_insn "*absdf2_v9"
7749 [(set (match_operand:DF 0 "register_operand" "=e")
7750 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7751 "TARGET_FPU && TARGET_V9"
7753 [(set_attr "type" "fpmove")
7754 (set_attr "fptype" "double")])
7756 (define_insn "abssf2"
7757 [(set (match_operand:SF 0 "register_operand" "=f")
7758 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7761 [(set_attr "type" "fpmove")])
7763 (define_expand "sqrttf2"
7764 [(set (match_operand:TF 0 "register_operand" "=e")
7765 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7766 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7769 if (! TARGET_HARD_QUAD)
7773 if (GET_CODE (operands[0]) != MEM)
7774 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7776 slot0 = operands[0];
7777 if (GET_CODE (operands[1]) != MEM)
7779 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7780 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7783 slot1 = operands[1];
7785 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7787 XEXP (slot0, 0), Pmode,
7788 XEXP (slot1, 0), Pmode);
7790 if (GET_CODE (operands[0]) != MEM)
7791 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7796 (define_insn "*sqrttf2_hq"
7797 [(set (match_operand:TF 0 "register_operand" "=e")
7798 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7799 "TARGET_FPU && TARGET_HARD_QUAD"
7801 [(set_attr "type" "fpsqrtd")])
7803 (define_insn "sqrtdf2"
7804 [(set (match_operand:DF 0 "register_operand" "=e")
7805 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7808 [(set_attr "type" "fpsqrtd")
7809 (set_attr "fptype" "double")])
7811 (define_insn "sqrtsf2"
7812 [(set (match_operand:SF 0 "register_operand" "=f")
7813 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7816 [(set_attr "type" "fpsqrts")])
7818 ;;- arithmetic shift instructions
7820 (define_insn "ashlsi3"
7821 [(set (match_operand:SI 0 "register_operand" "=r")
7822 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7823 (match_operand:SI 2 "arith_operand" "rI")))]
7827 if (GET_CODE (operands[2]) == CONST_INT
7828 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7829 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7831 return \"sll\\t%1, %2, %0\";
7833 [(set_attr "type" "shift")])
7835 ;; We special case multiplication by two, as add can be done
7836 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7837 (define_insn "*ashlsi3_const1"
7838 [(set (match_operand:SI 0 "register_operand" "=r")
7839 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7844 (define_expand "ashldi3"
7845 [(set (match_operand:DI 0 "register_operand" "=r")
7846 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7847 (match_operand:SI 2 "arith_operand" "rI")))]
7848 "TARGET_ARCH64 || TARGET_V8PLUS"
7851 if (! TARGET_ARCH64)
7853 if (GET_CODE (operands[2]) == CONST_INT)
7855 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7860 ;; We special case multiplication by two, as add can be done
7861 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7862 (define_insn "*ashldi3_const1"
7863 [(set (match_operand:DI 0 "register_operand" "=r")
7864 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7869 (define_insn "*ashldi3_sp64"
7870 [(set (match_operand:DI 0 "register_operand" "=r")
7871 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7872 (match_operand:SI 2 "arith_operand" "rI")))]
7876 if (GET_CODE (operands[2]) == CONST_INT
7877 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7878 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7880 return \"sllx\\t%1, %2, %0\";
7882 [(set_attr "type" "shift")])
7885 (define_insn "ashldi3_v8plus"
7886 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7887 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7888 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7889 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7891 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7892 [(set_attr "type" "multi")
7893 (set_attr "length" "5,5,6")])
7895 ;; Optimize (1LL<<x)-1
7896 ;; XXX this also needs to be fixed to handle equal subregs
7897 ;; XXX first before we could re-enable it.
7899 ; [(set (match_operand:DI 0 "register_operand" "=h")
7900 ; (plus:DI (ashift:DI (const_int 1)
7901 ; (match_operand:SI 1 "arith_operand" "rI"))
7903 ; "0 && TARGET_V8PLUS"
7906 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7907 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7908 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
7910 ; [(set_attr "type" "multi")
7911 ; (set_attr "length" "4")])
7913 (define_insn "*cmp_cc_ashift_1"
7914 [(set (reg:CC_NOOV 100)
7915 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7919 "addcc\\t%0, %0, %%g0"
7920 [(set_attr "type" "compare")])
7922 (define_insn "*cmp_cc_set_ashift_1"
7923 [(set (reg:CC_NOOV 100)
7924 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7927 (set (match_operand:SI 0 "register_operand" "=r")
7928 (ashift:SI (match_dup 1) (const_int 1)))]
7930 "addcc\\t%1, %1, %0"
7931 [(set_attr "type" "compare")])
7933 (define_insn "ashrsi3"
7934 [(set (match_operand:SI 0 "register_operand" "=r")
7935 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7936 (match_operand:SI 2 "arith_operand" "rI")))]
7940 if (GET_CODE (operands[2]) == CONST_INT
7941 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7942 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7944 return \"sra\\t%1, %2, %0\";
7946 [(set_attr "type" "shift")])
7948 (define_insn "*ashrsi3_extend"
7949 [(set (match_operand:DI 0 "register_operand" "=r")
7950 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7951 (match_operand:SI 2 "arith_operand" "r"))))]
7954 [(set_attr "type" "shift")])
7956 ;; This handles the case as above, but with constant shift instead of
7957 ;; register. Combiner "simplifies" it for us a little bit though.
7958 (define_insn "*ashrsi3_extend2"
7959 [(set (match_operand:DI 0 "register_operand" "=r")
7960 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7962 (match_operand:SI 2 "small_int_or_double" "n")))]
7964 && ((GET_CODE (operands[2]) == CONST_INT
7965 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7966 || (GET_CODE (operands[2]) == CONST_DOUBLE
7967 && !CONST_DOUBLE_HIGH (operands[2])
7968 && CONST_DOUBLE_LOW (operands[2]) >= 32
7969 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7972 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7974 return \"sra\\t%1, %2, %0\";
7976 [(set_attr "type" "shift")])
7978 (define_expand "ashrdi3"
7979 [(set (match_operand:DI 0 "register_operand" "=r")
7980 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7981 (match_operand:SI 2 "arith_operand" "rI")))]
7982 "TARGET_ARCH64 || TARGET_V8PLUS"
7985 if (! TARGET_ARCH64)
7987 if (GET_CODE (operands[2]) == CONST_INT)
7988 FAIL; /* prefer generic code in this case */
7989 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7995 [(set (match_operand:DI 0 "register_operand" "=r")
7996 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7997 (match_operand:SI 2 "arith_operand" "rI")))]
8001 if (GET_CODE (operands[2]) == CONST_INT
8002 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8003 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8005 return \"srax\\t%1, %2, %0\";
8007 [(set_attr "type" "shift")])
8010 (define_insn "ashrdi3_v8plus"
8011 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8012 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8013 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8014 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8016 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8017 [(set_attr "type" "multi")
8018 (set_attr "length" "5,5,6")])
8020 (define_insn "lshrsi3"
8021 [(set (match_operand:SI 0 "register_operand" "=r")
8022 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8023 (match_operand:SI 2 "arith_operand" "rI")))]
8027 if (GET_CODE (operands[2]) == CONST_INT
8028 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8029 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8031 return \"srl\\t%1, %2, %0\";
8033 [(set_attr "type" "shift")])
8035 ;; This handles the case where
8036 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8037 ;; but combiner "simplifies" it for us.
8038 (define_insn "*lshrsi3_extend"
8039 [(set (match_operand:DI 0 "register_operand" "=r")
8040 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8041 (match_operand:SI 2 "arith_operand" "r")) 0)
8042 (match_operand 3 "" "")))]
8044 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8045 && CONST_DOUBLE_HIGH (operands[3]) == 0
8046 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8047 || (HOST_BITS_PER_WIDE_INT >= 64
8048 && GET_CODE (operands[3]) == CONST_INT
8049 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8051 [(set_attr "type" "shift")])
8053 ;; This handles the case where
8054 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8055 ;; but combiner "simplifies" it for us.
8056 (define_insn "*lshrsi3_extend2"
8057 [(set (match_operand:DI 0 "register_operand" "=r")
8058 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8059 (match_operand 2 "small_int_or_double" "n")
8062 && ((GET_CODE (operands[2]) == CONST_INT
8063 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8064 || (GET_CODE (operands[2]) == CONST_DOUBLE
8065 && CONST_DOUBLE_HIGH (operands[2]) == 0
8066 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8069 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8071 return \"srl\\t%1, %2, %0\";
8073 [(set_attr "type" "shift")])
8075 (define_expand "lshrdi3"
8076 [(set (match_operand:DI 0 "register_operand" "=r")
8077 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8078 (match_operand:SI 2 "arith_operand" "rI")))]
8079 "TARGET_ARCH64 || TARGET_V8PLUS"
8082 if (! TARGET_ARCH64)
8084 if (GET_CODE (operands[2]) == CONST_INT)
8086 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8092 [(set (match_operand:DI 0 "register_operand" "=r")
8093 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8094 (match_operand:SI 2 "arith_operand" "rI")))]
8098 if (GET_CODE (operands[2]) == CONST_INT
8099 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8100 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8102 return \"srlx\\t%1, %2, %0\";
8104 [(set_attr "type" "shift")])
8107 (define_insn "lshrdi3_v8plus"
8108 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8109 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8110 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8111 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8113 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8114 [(set_attr "type" "multi")
8115 (set_attr "length" "5,5,6")])
8118 [(set (match_operand:SI 0 "register_operand" "=r")
8119 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8121 (match_operand:SI 2 "small_int_or_double" "n")))]
8123 && ((GET_CODE (operands[2]) == CONST_INT
8124 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8125 || (GET_CODE (operands[2]) == CONST_DOUBLE
8126 && !CONST_DOUBLE_HIGH (operands[2])
8127 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8130 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8132 return \"srax\\t%1, %2, %0\";
8134 [(set_attr "type" "shift")])
8137 [(set (match_operand:SI 0 "register_operand" "=r")
8138 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8140 (match_operand:SI 2 "small_int_or_double" "n")))]
8142 && ((GET_CODE (operands[2]) == CONST_INT
8143 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8144 || (GET_CODE (operands[2]) == CONST_DOUBLE
8145 && !CONST_DOUBLE_HIGH (operands[2])
8146 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8149 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8151 return \"srlx\\t%1, %2, %0\";
8153 [(set_attr "type" "shift")])
8156 [(set (match_operand:SI 0 "register_operand" "=r")
8157 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8158 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8159 (match_operand:SI 3 "small_int_or_double" "n")))]
8161 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8162 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8163 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8164 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8167 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8169 return \"srax\\t%1, %2, %0\";
8171 [(set_attr "type" "shift")])
8174 [(set (match_operand:SI 0 "register_operand" "=r")
8175 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8176 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8177 (match_operand:SI 3 "small_int_or_double" "n")))]
8179 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8180 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8181 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8182 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8185 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8187 return \"srlx\\t%1, %2, %0\";
8189 [(set_attr "type" "shift")])
8191 ;; Unconditional and other jump instructions
8192 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8193 ;; following insn is never executed. This saves us a nop. Dbx does not
8194 ;; handle such branches though, so we only use them when optimizing.
8196 [(set (pc) (label_ref (match_operand 0 "" "")))]
8200 /* TurboSparc is reported to have problems with
8203 i.e. an empty loop with the annul bit set. The workaround is to use
8207 if (! TARGET_V9 && flag_delayed_branch
8208 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8209 == INSN_ADDRESSES (INSN_UID (insn))))
8210 return \"b\\t%l0%#\";
8212 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8214 [(set_attr "type" "uncond_branch")])
8216 (define_expand "tablejump"
8217 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8218 (use (label_ref (match_operand 1 "" "")))])]
8222 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8225 /* In pic mode, our address differences are against the base of the
8226 table. Add that base value back in; CSE ought to be able to combine
8227 the two address loads. */
8231 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8233 if (CASE_VECTOR_MODE != Pmode)
8234 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8235 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8236 operands[0] = memory_address (Pmode, tmp);
8240 (define_insn "*tablejump_sp32"
8241 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8242 (use (label_ref (match_operand 1 "" "")))]
8245 [(set_attr "type" "uncond_branch")])
8247 (define_insn "*tablejump_sp64"
8248 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8249 (use (label_ref (match_operand 1 "" "")))]
8252 [(set_attr "type" "uncond_branch")])
8254 ;; This pattern recognizes the "instruction" that appears in
8255 ;; a function call that wants a structure value,
8256 ;; to inform the called function if compiled with Sun CC.
8257 ;(define_insn "*unimp_insn"
8258 ; [(match_operand:SI 0 "immediate_operand" "")]
8259 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8261 ; [(set_attr "type" "marker")])
8263 ;;- jump to subroutine
8264 (define_expand "call"
8265 ;; Note that this expression is not used for generating RTL.
8266 ;; All the RTL is generated explicitly below.
8267 [(call (match_operand 0 "call_operand" "")
8268 (match_operand 3 "" "i"))]
8269 ;; operands[2] is next_arg_register
8270 ;; operands[3] is struct_value_size_rtx.
8274 rtx fn_rtx, nregs_rtx;
8276 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8279 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8281 /* This is really a PIC sequence. We want to represent
8282 it as a funny jump so its delay slots can be filled.
8284 ??? But if this really *is* a CALL, will not it clobber the
8285 call-clobbered registers? We lose this if it is a JUMP_INSN.
8286 Why cannot we have delay slots filled if it were a CALL? */
8288 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8293 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8295 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8301 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8302 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8306 fn_rtx = operands[0];
8308 /* Count the number of parameter registers being used by this call.
8309 if that argument is NULL, it means we are using them all, which
8310 means 6 on the sparc. */
8313 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8315 nregs_rtx = GEN_INT (6);
8317 nregs_rtx = const0_rtx;
8320 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8324 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8326 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8331 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8332 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8336 /* If this call wants a structure value,
8337 emit an unimp insn to let the called function know about this. */
8338 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8340 rtx insn = emit_insn (operands[3]);
8341 SCHED_GROUP_P (insn) = 1;
8348 ;; We can't use the same pattern for these two insns, because then registers
8349 ;; in the address may not be properly reloaded.
8351 (define_insn "*call_address_sp32"
8352 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8353 (match_operand 1 "" ""))
8354 (clobber (reg:SI 15))]
8355 ;;- Do not use operand 1 for most machines.
8358 [(set_attr "type" "call")])
8360 (define_insn "*call_symbolic_sp32"
8361 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8362 (match_operand 1 "" ""))
8363 (clobber (reg:SI 15))]
8364 ;;- Do not use operand 1 for most machines.
8367 [(set_attr "type" "call")])
8369 (define_insn "*call_address_sp64"
8370 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8371 (match_operand 1 "" ""))
8372 (clobber (reg:DI 15))]
8373 ;;- Do not use operand 1 for most machines.
8376 [(set_attr "type" "call")])
8378 (define_insn "*call_symbolic_sp64"
8379 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8380 (match_operand 1 "" ""))
8381 (clobber (reg:DI 15))]
8382 ;;- Do not use operand 1 for most machines.
8385 [(set_attr "type" "call")])
8387 ;; This is a call that wants a structure value.
8388 ;; There is no such critter for v9 (??? we may need one anyway).
8389 (define_insn "*call_address_struct_value_sp32"
8390 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8391 (match_operand 1 "" ""))
8392 (match_operand 2 "immediate_operand" "")
8393 (clobber (reg:SI 15))]
8394 ;;- Do not use operand 1 for most machines.
8395 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8396 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8397 [(set_attr "type" "call_no_delay_slot")
8398 (set_attr "length" "2")])
8400 ;; This is a call that wants a structure value.
8401 ;; There is no such critter for v9 (??? we may need one anyway).
8402 (define_insn "*call_symbolic_struct_value_sp32"
8403 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8404 (match_operand 1 "" ""))
8405 (match_operand 2 "immediate_operand" "")
8406 (clobber (reg:SI 15))]
8407 ;;- Do not use operand 1 for most machines.
8408 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8409 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8410 [(set_attr "type" "call_no_delay_slot")
8411 (set_attr "length" "2")])
8413 ;; This is a call that may want a structure value. This is used for
8415 (define_insn "*call_address_untyped_struct_value_sp32"
8416 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8417 (match_operand 1 "" ""))
8418 (match_operand 2 "immediate_operand" "")
8419 (clobber (reg:SI 15))]
8420 ;;- Do not use operand 1 for most machines.
8421 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8422 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8423 [(set_attr "type" "call_no_delay_slot")
8424 (set_attr "length" "2")])
8426 ;; This is a call that wants a structure value.
8427 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8428 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8429 (match_operand 1 "" ""))
8430 (match_operand 2 "immediate_operand" "")
8431 (clobber (reg:SI 15))]
8432 ;;- Do not use operand 1 for most machines.
8433 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8434 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8435 [(set_attr "type" "call_no_delay_slot")
8436 (set_attr "length" "2")])
8438 (define_expand "call_value"
8439 ;; Note that this expression is not used for generating RTL.
8440 ;; All the RTL is generated explicitly below.
8441 [(set (match_operand 0 "register_operand" "=rf")
8442 (call (match_operand 1 "" "")
8443 (match_operand 4 "" "")))]
8444 ;; operand 2 is stack_size_rtx
8445 ;; operand 3 is next_arg_register
8449 rtx fn_rtx, nregs_rtx;
8452 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8455 fn_rtx = operands[1];
8459 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8461 nregs_rtx = GEN_INT (6);
8463 nregs_rtx = const0_rtx;
8467 gen_rtx_SET (VOIDmode, operands[0],
8468 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8469 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8471 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8476 (define_insn "*call_value_address_sp32"
8477 [(set (match_operand 0 "" "=rf")
8478 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8479 (match_operand 2 "" "")))
8480 (clobber (reg:SI 15))]
8481 ;;- Do not use operand 2 for most machines.
8484 [(set_attr "type" "call")])
8486 (define_insn "*call_value_symbolic_sp32"
8487 [(set (match_operand 0 "" "=rf")
8488 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8489 (match_operand 2 "" "")))
8490 (clobber (reg:SI 15))]
8491 ;;- Do not use operand 2 for most machines.
8494 [(set_attr "type" "call")])
8496 (define_insn "*call_value_address_sp64"
8497 [(set (match_operand 0 "" "")
8498 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8499 (match_operand 2 "" "")))
8500 (clobber (reg:DI 15))]
8501 ;;- Do not use operand 2 for most machines.
8504 [(set_attr "type" "call")])
8506 (define_insn "*call_value_symbolic_sp64"
8507 [(set (match_operand 0 "" "")
8508 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8509 (match_operand 2 "" "")))
8510 (clobber (reg:DI 15))]
8511 ;;- Do not use operand 2 for most machines.
8514 [(set_attr "type" "call")])
8516 (define_expand "untyped_call"
8517 [(parallel [(call (match_operand 0 "" "")
8519 (match_operand 1 "" "")
8520 (match_operand 2 "" "")])]
8526 /* Pass constm1 to indicate that it may expect a structure value, but
8527 we don't know what size it is. */
8528 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8530 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8532 rtx set = XVECEXP (operands[2], 0, i);
8533 emit_move_insn (SET_DEST (set), SET_SRC (set));
8536 /* The optimizer does not know that the call sets the function value
8537 registers we stored in the result block. We avoid problems by
8538 claiming that all hard registers are used and clobbered at this
8540 emit_insn (gen_blockage ());
8546 (define_expand "sibcall"
8547 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8552 (define_insn "*sibcall_symbolic_sp32"
8553 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8554 (match_operand 1 "" ""))
8557 "* return output_sibcall(insn, operands[0]);"
8558 [(set_attr "type" "sibcall")])
8560 (define_insn "*sibcall_symbolic_sp64"
8561 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8562 (match_operand 1 "" ""))
8565 "* return output_sibcall(insn, operands[0]);"
8566 [(set_attr "type" "sibcall")])
8568 (define_expand "sibcall_value"
8569 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8570 (call (match_operand 1 "" "") (const_int 0)))
8575 (define_insn "*sibcall_value_symbolic_sp32"
8576 [(set (match_operand 0 "" "=rf")
8577 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8578 (match_operand 2 "" "")))
8581 "* return output_sibcall(insn, operands[1]);"
8582 [(set_attr "type" "sibcall")])
8584 (define_insn "*sibcall_value_symbolic_sp64"
8585 [(set (match_operand 0 "" "")
8586 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8587 (match_operand 2 "" "")))
8590 "* return output_sibcall(insn, operands[1]);"
8591 [(set_attr "type" "sibcall")])
8593 (define_expand "sibcall_epilogue"
8598 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8599 ;; all of memory. This blocks insns from being moved across this point.
8601 (define_insn "blockage"
8602 [(unspec_volatile [(const_int 0)] 0)]
8605 [(set_attr "length" "0")])
8607 ;; Prepare to return any type including a structure value.
8609 (define_expand "untyped_return"
8610 [(match_operand:BLK 0 "memory_operand" "")
8611 (match_operand 1 "" "")]
8615 rtx valreg1 = gen_rtx_REG (DImode, 24);
8616 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8617 rtx result = operands[0];
8619 if (! TARGET_ARCH64)
8621 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8623 rtx value = gen_reg_rtx (SImode);
8625 /* Fetch the instruction where we will return to and see if it's an unimp
8626 instruction (the most significant 10 bits will be zero). If so,
8627 update the return address to skip the unimp instruction. */
8628 emit_move_insn (value,
8629 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8630 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8631 emit_insn (gen_update_return (rtnreg, value));
8634 /* Reload the function value registers. */
8635 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8636 emit_move_insn (valreg2,
8637 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8639 /* Put USE insns before the return. */
8640 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8641 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8643 /* Construct the return. */
8644 expand_null_return ();
8649 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8650 ;; and parts of the compiler don't want to believe that the add is needed.
8652 (define_insn "update_return"
8653 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8654 (match_operand:SI 1 "register_operand" "r")] 1)]
8656 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8657 [(set_attr "type" "multi")
8658 (set_attr "length" "3")])
8660 (define_insn "return"
8664 "* return output_return (operands);"
8665 [(set_attr "type" "return")])
8668 [(set (match_operand:SI 0 "register_operand" "=r")
8669 (match_operand:SI 1 "arith_operand" "rI"))
8671 (use (reg:SI 31))])]
8672 "sparc_return_peephole_ok (operands[0], operands[1])"
8673 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8680 (define_expand "indirect_jump"
8681 [(set (pc) (match_operand 0 "address_operand" "p"))]
8685 (define_insn "*branch_sp32"
8686 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8689 [(set_attr "type" "uncond_branch")])
8691 (define_insn "*branch_sp64"
8692 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8695 [(set_attr "type" "uncond_branch")])
8697 ;; ??? Doesn't work with -mflat.
8698 (define_expand "nonlocal_goto"
8699 [(match_operand:SI 0 "general_operand" "")
8700 (match_operand:SI 1 "general_operand" "")
8701 (match_operand:SI 2 "general_operand" "")
8702 (match_operand:SI 3 "" "")]
8707 rtx chain = operands[0];
8709 rtx lab = operands[1];
8710 rtx stack = operands[2];
8711 rtx fp = operands[3];
8714 /* Trap instruction to flush all the register windows. */
8715 emit_insn (gen_flush_register_windows ());
8717 /* Load the fp value for the containing fn into %fp. This is needed
8718 because STACK refers to %fp. Note that virtual register instantiation
8719 fails if the virtual %fp isn't set from a register. */
8720 if (GET_CODE (fp) != REG)
8721 fp = force_reg (Pmode, fp);
8722 emit_move_insn (virtual_stack_vars_rtx, fp);
8724 /* Find the containing function's current nonlocal goto handler,
8725 which will do any cleanups and then jump to the label. */
8726 labreg = gen_rtx_REG (Pmode, 8);
8727 emit_move_insn (labreg, lab);
8729 /* Restore %fp from stack pointer value for containing function.
8730 The restore insn that follows will move this to %sp,
8731 and reload the appropriate value into %fp. */
8732 emit_move_insn (hard_frame_pointer_rtx, stack);
8734 /* USE of frame_pointer_rtx added for consistency; not clear if
8736 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8737 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8740 /* Return, restoring reg window and jumping to goto handler. */
8741 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8742 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8744 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8750 /* Put in the static chain register the nonlocal label address. */
8751 emit_move_insn (static_chain_rtx, chain);
8754 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8755 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8760 ;; Special trap insn to flush register windows.
8761 (define_insn "flush_register_windows"
8762 [(unspec_volatile [(const_int 0)] 1)]
8764 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8765 [(set_attr "type" "misc")])
8767 (define_insn "goto_handler_and_restore"
8768 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8769 "GET_MODE (operands[0]) == Pmode"
8770 "jmp\\t%0+0\\n\\trestore"
8771 [(set_attr "type" "multi")
8772 (set_attr "length" "2")])
8774 ;;(define_insn "goto_handler_and_restore_v9"
8775 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8776 ;; (match_operand:SI 1 "register_operand" "=r,r")
8777 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8778 ;; "TARGET_V9 && ! TARGET_ARCH64"
8780 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8781 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8782 ;; [(set_attr "type" "multi")
8783 ;; (set_attr "length" "2,3")])
8785 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8786 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8787 ;; (match_operand:DI 1 "register_operand" "=r,r")
8788 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8789 ;; "TARGET_V9 && TARGET_ARCH64"
8791 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8792 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8793 ;; [(set_attr "type" "multi")
8794 ;; (set_attr "length" "2,3")])
8796 ;; For __builtin_setjmp we need to flush register windows iff the function
8797 ;; calls alloca as well, because otherwise the register window might be
8798 ;; saved after %sp adjustement and thus setjmp would crash
8799 (define_expand "builtin_setjmp_setup"
8800 [(match_operand 0 "register_operand" "r")]
8804 emit_insn (gen_do_builtin_setjmp_setup ());
8808 ;; ??? Should set length to zero when !current_function_calls_alloca,
8809 ;; ??? but there is no easy way to get at that definition. It would
8810 ;; ??? require including function.h into sparc-protos.h and that is
8811 ;; ??? likely not a good idea. -DaveM
8812 (define_insn "do_builtin_setjmp_setup"
8813 [(unspec_volatile [(const_int 0)] 5)]
8817 if (!current_function_calls_alloca)
8823 [(set_attr "type" "misc")])
8825 ;; Pattern for use after a setjmp to store FP and the return register
8826 ;; into the stack area.
8828 (define_expand "setjmp"
8834 emit_insn (gen_setjmp_64 ());
8836 emit_insn (gen_setjmp_32 ());
8840 (define_expand "setjmp_32"
8841 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8842 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8845 { operands[0] = frame_pointer_rtx; }")
8847 (define_expand "setjmp_64"
8848 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8849 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8852 { operands[0] = frame_pointer_rtx; }")
8854 ;; Special pattern for the FLUSH instruction.
8856 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8857 ; of the define_insn otherwise missing a mode. We make "flush", aka
8858 ; gen_flush, the default one since sparc_initialize_trampoline uses
8859 ; it on SImode mem values.
8861 (define_insn "flush"
8862 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8864 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8865 [(set_attr "type" "misc")])
8867 (define_insn "flushdi"
8868 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8870 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
8871 [(set_attr "type" "misc")])
8876 ;; The scan instruction searches from the most significant bit while ffs
8877 ;; searches from the least significant bit. The bit index and treatment of
8878 ;; zero also differ. It takes at least 7 instructions to get the proper
8879 ;; result. Here is an obvious 8 instruction sequence.
8882 (define_insn "ffssi2"
8883 [(set (match_operand:SI 0 "register_operand" "=&r")
8884 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8885 (clobber (match_scratch:SI 2 "=&r"))]
8886 "TARGET_SPARCLITE || TARGET_SPARCLET"
8889 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\";
8891 [(set_attr "type" "multi")
8892 (set_attr "length" "8")])
8894 ;; ??? This should be a define expand, so that the extra instruction have
8895 ;; a chance of being optimized away.
8897 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8898 ;; does, but no one uses that and we don't have a switch for it.
8900 ;(define_insn "ffsdi2"
8901 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8902 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8903 ; (clobber (match_scratch:DI 2 "=&r"))]
8905 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
8906 ; [(set_attr "type" "multi")
8907 ; (set_attr "length" "4")])
8911 ;; Peepholes go at the end.
8913 ;; Optimize consecutive loads or stores into ldd and std when possible.
8914 ;; The conditions in which we do this are very restricted and are
8915 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8918 [(set (match_operand:SI 0 "memory_operand" "")
8920 (set (match_operand:SI 1 "memory_operand" "")
8923 && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8926 "operands[0] = change_address (operands[0], DImode, NULL);")
8929 [(set (match_operand:SI 0 "memory_operand" "")
8931 (set (match_operand:SI 1 "memory_operand" "")
8934 && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8937 "operands[1] = change_address (operands[1], DImode, NULL);")
8940 [(set (match_operand:SI 0 "register_operand" "")
8941 (match_operand:SI 1 "memory_operand" ""))
8942 (set (match_operand:SI 2 "register_operand" "")
8943 (match_operand:SI 3 "memory_operand" ""))]
8944 "registers_ok_for_ldd_peep (operands[0], operands[2])
8945 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8948 "operands[1] = change_address (operands[1], DImode, NULL);
8949 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8952 [(set (match_operand:SI 0 "memory_operand" "")
8953 (match_operand:SI 1 "register_operand" ""))
8954 (set (match_operand:SI 2 "memory_operand" "")
8955 (match_operand:SI 3 "register_operand" ""))]
8956 "registers_ok_for_ldd_peep (operands[1], operands[3])
8957 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8960 "operands[0] = change_address (operands[0], DImode, NULL);
8961 operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8964 [(set (match_operand:SF 0 "register_operand" "")
8965 (match_operand:SF 1 "memory_operand" ""))
8966 (set (match_operand:SF 2 "register_operand" "")
8967 (match_operand:SF 3 "memory_operand" ""))]
8968 "registers_ok_for_ldd_peep (operands[0], operands[2])
8969 && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8972 "operands[1] = change_address (operands[1], DFmode, NULL);
8973 operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8976 [(set (match_operand:SF 0 "memory_operand" "")
8977 (match_operand:SF 1 "register_operand" ""))
8978 (set (match_operand:SF 2 "memory_operand" "")
8979 (match_operand:SF 3 "register_operand" ""))]
8980 "registers_ok_for_ldd_peep (operands[1], operands[3])
8981 && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8984 "operands[0] = change_address (operands[0], DFmode, NULL);
8985 operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8988 [(set (match_operand:SI 0 "register_operand" "")
8989 (match_operand:SI 1 "memory_operand" ""))
8990 (set (match_operand:SI 2 "register_operand" "")
8991 (match_operand:SI 3 "memory_operand" ""))]
8992 "registers_ok_for_ldd_peep (operands[2], operands[0])
8993 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
8996 "operands[3] = change_address (operands[3], DImode, NULL);
8997 operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
9000 [(set (match_operand:SI 0 "memory_operand" "")
9001 (match_operand:SI 1 "register_operand" ""))
9002 (set (match_operand:SI 2 "memory_operand" "")
9003 (match_operand:SI 3 "register_operand" ""))]
9004 "registers_ok_for_ldd_peep (operands[3], operands[1])
9005 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9008 "operands[2] = change_address (operands[2], DImode, NULL);
9009 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
9013 [(set (match_operand:SF 0 "register_operand" "")
9014 (match_operand:SF 1 "memory_operand" ""))
9015 (set (match_operand:SF 2 "register_operand" "")
9016 (match_operand:SF 3 "memory_operand" ""))]
9017 "registers_ok_for_ldd_peep (operands[2], operands[0])
9018 && mems_ok_for_ldd_peep (operands[3], operands[1], operands[2])"
9021 "operands[3] = change_address (operands[3], DFmode, NULL);
9022 operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
9025 [(set (match_operand:SF 0 "memory_operand" "")
9026 (match_operand:SF 1 "register_operand" ""))
9027 (set (match_operand:SF 2 "memory_operand" "")
9028 (match_operand:SF 3 "register_operand" ""))]
9029 "registers_ok_for_ldd_peep (operands[3], operands[1])
9030 && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
9033 "operands[2] = change_address (operands[2], DFmode, NULL);
9034 operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
9036 ;; Optimize the case of following a reg-reg move with a test
9037 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9038 ;; This can result from a float to fix conversion.
9041 [(set (match_operand:SI 0 "register_operand" "")
9042 (match_operand:SI 1 "register_operand" ""))
9044 (compare:CC (match_operand:SI 2 "register_operand" "")
9046 "(rtx_equal_p (operands[2], operands[0])
9047 || rtx_equal_p (operands[2], operands[1]))
9048 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9049 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9050 [(parallel [(set (match_dup 0) (match_dup 1))
9052 (compare:CC (match_dup 1) (const_int 0)))])]
9056 [(set (match_operand:DI 0 "register_operand" "")
9057 (match_operand:DI 1 "register_operand" ""))
9059 (compare:CCX (match_operand:DI 2 "register_operand" "")
9062 && (rtx_equal_p (operands[2], operands[0])
9063 || rtx_equal_p (operands[2], operands[1]))
9064 && ! SPARC_FP_REG_P (REGNO (operands[0]))
9065 && ! SPARC_FP_REG_P (REGNO (operands[1]))"
9066 [(parallel [(set (match_dup 0) (match_dup 1))
9068 (compare:CC (match_dup 1) (const_int 0)))])]
9071 ;; Return peepholes. First the "normal" ones.
9072 ;; These are necessary to catch insns ending up in the epilogue delay list.
9074 (define_insn "*return_qi"
9075 [(set (match_operand:QI 0 "restore_operand" "")
9076 (match_operand:QI 1 "arith_operand" "rI"))
9081 if (! TARGET_ARCH64 && current_function_returns_struct)
9082 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9083 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9084 || IN_OR_GLOBAL_P (operands[1])))
9085 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9087 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9089 [(set_attr "type" "multi")
9090 (set_attr "length" "2")])
9092 (define_insn "*return_hi"
9093 [(set (match_operand:HI 0 "restore_operand" "")
9094 (match_operand:HI 1 "arith_operand" "rI"))
9099 if (! TARGET_ARCH64 && current_function_returns_struct)
9100 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9101 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9102 || IN_OR_GLOBAL_P (operands[1])))
9103 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9105 return \"ret\;restore %%g0, %1, %Y0\";
9107 [(set_attr "type" "multi")
9108 (set_attr "length" "2")])
9110 (define_insn "*return_si"
9111 [(set (match_operand:SI 0 "restore_operand" "")
9112 (match_operand:SI 1 "arith_operand" "rI"))
9117 if (! TARGET_ARCH64 && current_function_returns_struct)
9118 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9119 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9120 || IN_OR_GLOBAL_P (operands[1])))
9121 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9123 return \"ret\;restore %%g0, %1, %Y0\";
9125 [(set_attr "type" "multi")
9126 (set_attr "length" "2")])
9128 ;; The following pattern is only generated by delayed-branch scheduling,
9129 ;; when the insn winds up in the epilogue. This can happen not only when
9130 ;; ! TARGET_FPU because we move complex types around by parts using
9132 (define_insn "*return_sf_no_fpu"
9133 [(set (match_operand:SF 0 "restore_operand" "=r")
9134 (match_operand:SF 1 "register_operand" "r"))
9139 if (! TARGET_ARCH64 && current_function_returns_struct)
9140 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9141 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9142 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9144 return \"ret\;restore %%g0, %1, %Y0\";
9146 [(set_attr "type" "multi")
9147 (set_attr "length" "2")])
9149 (define_insn "*return_df_no_fpu"
9150 [(set (match_operand:DF 0 "restore_operand" "=r")
9151 (match_operand:DF 1 "register_operand" "r"))
9153 "! TARGET_EPILOGUE && TARGET_ARCH64"
9156 if (IN_OR_GLOBAL_P (operands[1]))
9157 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9159 return \"ret\;restore %%g0, %1, %Y0\";
9161 [(set_attr "type" "multi")
9162 (set_attr "length" "2")])
9164 (define_insn "*return_addsi"
9165 [(set (match_operand:SI 0 "restore_operand" "")
9166 (plus:SI (match_operand:SI 1 "register_operand" "r")
9167 (match_operand:SI 2 "arith_operand" "rI")))
9172 if (! TARGET_ARCH64 && current_function_returns_struct)
9173 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9174 /* If operands are global or in registers, can use return */
9175 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9176 && (GET_CODE (operands[2]) == CONST_INT
9177 || IN_OR_GLOBAL_P (operands[2])))
9178 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9180 return \"ret\;restore %r1, %2, %Y0\";
9182 [(set_attr "type" "multi")
9183 (set_attr "length" "2")])
9185 (define_insn "*return_losum_si"
9186 [(set (match_operand:SI 0 "restore_operand" "")
9187 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9188 (match_operand:SI 2 "immediate_operand" "in")))
9190 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9193 if (! TARGET_ARCH64 && current_function_returns_struct)
9194 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9195 /* If operands are global or in registers, can use return */
9196 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9197 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9199 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9201 [(set_attr "type" "multi")
9202 (set_attr "length" "2")])
9204 (define_insn "*return_di"
9205 [(set (match_operand:DI 0 "restore_operand" "")
9206 (match_operand:DI 1 "arith_double_operand" "rHI"))
9208 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9209 "ret\;restore %%g0, %1, %Y0"
9210 [(set_attr "type" "multi")
9211 (set_attr "length" "2")])
9213 (define_insn "*return_adddi"
9214 [(set (match_operand:DI 0 "restore_operand" "")
9215 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9216 (match_operand:DI 2 "arith_double_operand" "rHI")))
9218 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9219 "ret\;restore %r1, %2, %Y0"
9220 [(set_attr "type" "multi")
9221 (set_attr "length" "2")])
9223 (define_insn "*return_losum_di"
9224 [(set (match_operand:DI 0 "restore_operand" "")
9225 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9226 (match_operand:DI 2 "immediate_operand" "in")))
9228 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9229 "ret\;restore %r1, %%lo(%a2), %Y0"
9230 [(set_attr "type" "multi")
9231 (set_attr "length" "2")])
9233 ;; The following pattern is only generated by delayed-branch scheduling,
9234 ;; when the insn winds up in the epilogue.
9235 (define_insn "*return_sf"
9237 (match_operand:SF 0 "register_operand" "f"))
9240 "ret\;fmovs\\t%0, %%f0"
9241 [(set_attr "type" "multi")
9242 (set_attr "length" "2")])
9244 ;; Now peepholes to do a call followed by a jump.
9247 [(parallel [(set (match_operand 0 "" "")
9248 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9249 (match_operand 2 "" "")))
9250 (clobber (reg:SI 15))])
9251 (set (pc) (label_ref (match_operand 3 "" "")))]
9252 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9253 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9254 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9257 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9258 (match_operand 1 "" ""))
9259 (clobber (reg:SI 15))])
9260 (set (pc) (label_ref (match_operand 2 "" "")))]
9261 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9262 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9263 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9266 [(parallel [(set (match_operand 0 "" "")
9267 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9268 (match_operand 2 "" "")))
9269 (clobber (reg:DI 15))])
9270 (set (pc) (label_ref (match_operand 3 "" "")))]
9272 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9273 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9274 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9277 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9278 (match_operand 1 "" ""))
9279 (clobber (reg:DI 15))])
9280 (set (pc) (label_ref (match_operand 2 "" "")))]
9282 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9283 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))"
9284 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9286 (define_insn "prefetch"
9287 [(prefetch (match_operand:DI 0 "address_operand" "p")
9288 (match_operand:DI 1 "const_int_operand" "n")
9289 (match_operand:DI 2 "const_int_operand" "n"))]
9292 static const char * const prefetch_instr[2][4] = {
9294 "prefetch\\t[%a0], 1", /* no locality: prefetch for one read */
9295 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9296 "prefetch\\t[%a0], 0", /* medium locality: prefetch for several reads */
9297 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9300 "prefetch\\t[%a0], 3", /* no locality: prefetch for one write */
9301 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9302 "prefetch\\t[%a0], 2", /* medium locality: prefetch for several writes */
9303 "prefetch\\t[%a0], 4", /* high locality: prefetch page */
9306 int read_or_write = INTVAL (operands[1]);
9307 int locality = INTVAL (operands[2]);
9309 if (read_or_write != 0 && read_or_write != 1)
9311 if (locality < 0 || locality > 3)
9313 return prefetch_instr [read_or_write][locality];
9315 [(set_attr "type" "load")])
9317 (define_expand "prologue"
9319 "flag_pic && current_function_uses_pic_offset_table"
9322 load_pic_register ();
9326 ;; We need to reload %l7 for -mflat -fpic,
9327 ;; otherwise %l7 should be preserved simply
9328 ;; by loading the function's register window
9329 (define_expand "exception_receiver"
9331 "TARGET_FLAT && flag_pic"
9334 load_pic_register ();
9339 (define_expand "builtin_setjmp_receiver"
9340 [(label_ref (match_operand 0 "" ""))]
9341 "TARGET_FLAT && flag_pic"
9344 load_pic_register ();
9349 [(trap_if (const_int 1) (const_int 5))]
9352 [(set_attr "type" "misc")])
9354 (define_expand "conditional_trap"
9355 [(trap_if (match_operator 0 "noov_compare_op"
9356 [(match_dup 2) (match_dup 3)])
9357 (match_operand:SI 1 "arith_operand" ""))]
9359 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9360 sparc_compare_op0, sparc_compare_op1);
9361 operands[3] = const0_rtx;")
9364 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9365 (match_operand:SI 1 "arith_operand" "rM"))]
9368 [(set_attr "type" "misc")])
9371 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9372 (match_operand:SI 1 "arith_operand" "rM"))]
9375 [(set_attr "type" "misc")])