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 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"))))
86 "ialu,compare,shift,load,sload,store,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
87 (const_string "ialu"))
89 ;; Length (in # of insns).
90 (define_attr "length" ""
91 (cond [(eq_attr "type" "load,sload,fpload")
92 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
93 (const_int 2) (const_int 1))
95 (eq_attr "type" "store,fpstore")
96 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
97 (const_int 2) (const_int 1))
99 (eq_attr "type" "ialu")
100 (if_then_else (ior (match_operand 2 "arith_operand" "")
101 (match_operand 2 "arith_double_operand" ""))
102 (const_int 1) (const_int 3))
104 (eq_attr "type" "multi") (const_int 2)
106 (eq_attr "type" "ialu")
107 (if_then_else (ior (match_operand 1 "arith_operand" "")
108 (match_operand 1 "arith_double_operand" ""))
109 (const_int 1) (const_int 2))]
113 (define_asm_attributes
114 [(set_attr "length" "1")
115 (set_attr "type" "multi")])
117 ;; Attributes for instruction and branch scheduling
119 (define_attr "in_call_delay" "false,true"
120 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
121 (const_string "false")
122 (eq_attr "type" "load,fpload,store,fpstore")
123 (if_then_else (eq_attr "length" "1")
124 (const_string "true")
125 (const_string "false"))]
126 (if_then_else (eq_attr "length" "1")
127 (const_string "true")
128 (const_string "false"))))
130 (define_delay (eq_attr "type" "call")
131 [(eq_attr "in_call_delay" "true") (nil) (nil)])
133 (define_attr "eligible_for_sibcall_delay" "false,true"
134 (symbol_ref "eligible_for_sibcall_delay (insn)"))
136 (define_delay (eq_attr "type" "sibcall")
137 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
139 (define_attr "leaf_function" "false,true"
140 (const (symbol_ref "current_function_uses_only_leaf_regs")))
142 (define_attr "eligible_for_return_delay" "false,true"
143 (symbol_ref "eligible_for_return_delay (insn)"))
145 (define_attr "in_return_delay" "false,true"
146 (if_then_else (and (and (and (eq_attr "type" "ialu,load,sload,store")
147 (eq_attr "length" "1"))
148 (eq_attr "leaf_function" "false"))
149 (eq_attr "eligible_for_return_delay" "false"))
150 (const_string "true")
151 (const_string "false")))
153 (define_delay (and (eq_attr "type" "return")
154 (eq_attr "isa" "v9"))
155 [(eq_attr "in_return_delay" "true") (nil) (nil)])
157 ;; ??? Should implement the notion of predelay slots for floating point
158 ;; branches. This would allow us to remove the nop always inserted before
159 ;; a floating point branch.
161 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
162 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
163 ;; This is because doing so will add several pipeline stalls to the path
164 ;; that the load/store did not come from. Unfortunately, there is no way
165 ;; to prevent fill_eager_delay_slots from using load/store without completely
166 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
167 ;; because it prevents us from moving back the final store of inner loops.
169 (define_attr "in_branch_delay" "false,true"
170 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
171 (eq_attr "length" "1"))
172 (const_string "true")
173 (const_string "false")))
175 (define_attr "in_uncond_branch_delay" "false,true"
176 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
177 (eq_attr "length" "1"))
178 (const_string "true")
179 (const_string "false")))
181 (define_attr "in_annul_branch_delay" "false,true"
182 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
183 (eq_attr "length" "1"))
184 (const_string "true")
185 (const_string "false")))
187 (define_delay (eq_attr "type" "branch")
188 [(eq_attr "in_branch_delay" "true")
189 (nil) (eq_attr "in_annul_branch_delay" "true")])
191 (define_delay (eq_attr "type" "uncond_branch")
192 [(eq_attr "in_uncond_branch_delay" "true")
195 ;; Function units of the SPARC
197 ;; (define_function_unit {name} {num-units} {n-users} {test}
198 ;; {ready-delay} {issue-delay} [{conflict-list}])
201 ;; (Noted only for documentation; units that take one cycle do not need to
204 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
207 ;; ---- cypress CY7C602 scheduling:
208 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
210 (define_function_unit "memory" 1 0
211 (and (eq_attr "cpu" "cypress")
212 (eq_attr "type" "load,sload,fpload"))
215 ;; SPARC has two floating-point units: the FP ALU,
216 ;; and the FP MUL/DIV/SQRT unit.
217 ;; Instruction timings on the CY7C602 are as follows
231 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
232 ;; More insns cause the chip to stall.
234 (define_function_unit "fp_alu" 1 0
235 (and (eq_attr "cpu" "cypress")
236 (eq_attr "type" "fp,fpmove"))
239 (define_function_unit "fp_mds" 1 0
240 (and (eq_attr "cpu" "cypress")
241 (eq_attr "type" "fpmul"))
244 (define_function_unit "fp_mds" 1 0
245 (and (eq_attr "cpu" "cypress")
246 (eq_attr "type" "fpdivs,fpdivd"))
249 (define_function_unit "fp_mds" 1 0
250 (and (eq_attr "cpu" "cypress")
251 (eq_attr "type" "fpsqrts,fpsqrtd"))
254 ;; ----- The TMS390Z55 scheduling
255 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
256 ;; one ld/st, one fp.
257 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
259 (define_function_unit "memory" 1 0
260 (and (eq_attr "cpu" "supersparc")
261 (eq_attr "type" "load,sload"))
264 (define_function_unit "memory" 1 0
265 (and (eq_attr "cpu" "supersparc")
266 (eq_attr "type" "fpload"))
269 (define_function_unit "memory" 1 0
270 (and (eq_attr "cpu" "supersparc")
271 (eq_attr "type" "store,fpstore"))
274 (define_function_unit "shift" 1 0
275 (and (eq_attr "cpu" "supersparc")
276 (eq_attr "type" "shift"))
279 ;; There are only two write ports to the integer register file
280 ;; A store also uses a write port
282 (define_function_unit "iwport" 2 0
283 (and (eq_attr "cpu" "supersparc")
284 (eq_attr "type" "load,sload,store,shift,ialu"))
287 ;; Timings; throughput/latency
288 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
296 (define_function_unit "fp_alu" 1 0
297 (and (eq_attr "cpu" "supersparc")
298 (eq_attr "type" "fp,fpmove,fpcmp"))
301 (define_function_unit "fp_mds" 1 0
302 (and (eq_attr "cpu" "supersparc")
303 (eq_attr "type" "fpmul"))
306 (define_function_unit "fp_mds" 1 0
307 (and (eq_attr "cpu" "supersparc")
308 (eq_attr "type" "fpdivs"))
311 (define_function_unit "fp_mds" 1 0
312 (and (eq_attr "cpu" "supersparc")
313 (eq_attr "type" "fpdivd"))
316 (define_function_unit "fp_mds" 1 0
317 (and (eq_attr "cpu" "supersparc")
318 (eq_attr "type" "fpsqrts,fpsqrtd"))
321 (define_function_unit "fp_mds" 1 0
322 (and (eq_attr "cpu" "supersparc")
323 (eq_attr "type" "imul"))
326 ;; ----- hypersparc/sparclite86x scheduling
327 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
328 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
329 ;; II/FF case is only when loading a 32 bit hi/lo constant
330 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
331 ;; Memory delivers its result in one cycle to IU
333 (define_function_unit "memory" 1 0
334 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
335 (eq_attr "type" "load,sload,fpload"))
338 (define_function_unit "memory" 1 0
339 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
340 (eq_attr "type" "store,fpstore"))
343 (define_function_unit "sparclite86x_branch" 1 0
344 (and (eq_attr "cpu" "sparclite86x")
345 (eq_attr "type" "branch"))
348 ;; integer multiply insns
349 (define_function_unit "sparclite86x_shift" 1 0
350 (and (eq_attr "cpu" "sparclite86x")
351 (eq_attr "type" "shift"))
354 (define_function_unit "fp_alu" 1 0
355 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
356 (eq_attr "type" "fp,fpmove,fpcmp"))
359 (define_function_unit "fp_mds" 1 0
360 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
361 (eq_attr "type" "fpmul"))
364 (define_function_unit "fp_mds" 1 0
365 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
366 (eq_attr "type" "fpdivs"))
369 (define_function_unit "fp_mds" 1 0
370 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
371 (eq_attr "type" "fpdivd"))
374 (define_function_unit "fp_mds" 1 0
375 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
376 (eq_attr "type" "fpsqrts,fpsqrtd"))
379 (define_function_unit "fp_mds" 1 0
380 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
381 (eq_attr "type" "imul"))
384 ;; ----- sparclet tsc701 scheduling
385 ;; The tsc701 issues 1 insn per cycle.
386 ;; Results may be written back out of order.
388 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
390 (define_function_unit "tsc701_load" 4 1
391 (and (eq_attr "cpu" "tsc701")
392 (eq_attr "type" "load,sload"))
395 ;; Stores take 2(?) extra cycles to complete.
396 ;; It is desirable to not have any memory operation in the following 2 cycles.
397 ;; (??? or 2 memory ops in the case of std).
399 (define_function_unit "tsc701_store" 1 0
400 (and (eq_attr "cpu" "tsc701")
401 (eq_attr "type" "store"))
403 [(eq_attr "type" "load,sload,store")])
405 ;; The multiply unit has a latency of 5.
406 (define_function_unit "tsc701_mul" 1 0
407 (and (eq_attr "cpu" "tsc701")
408 (eq_attr "type" "imul"))
411 ;; ----- The UltraSPARC-1 scheduling
412 ;; UltraSPARC has two integer units. Shift instructions can only execute
413 ;; on IE0. Condition code setting instructions, call, and jmpl (including
414 ;; the ret and retl pseudo-instructions) can only execute on IE1.
415 ;; Branch on register uses IE1, but branch on condition code does not.
416 ;; Conditional moves take 2 cycles. No other instruction can issue in the
417 ;; same cycle as a conditional move.
418 ;; Multiply and divide take many cycles during which no other instructions
420 ;; Memory delivers its result in two cycles (except for signed loads,
421 ;; which take one cycle more). One memory instruction can be issued per
424 (define_function_unit "memory" 1 0
425 (and (eq_attr "cpu" "ultrasparc")
426 (eq_attr "type" "load,fpload"))
429 (define_function_unit "memory" 1 0
430 (and (eq_attr "cpu" "ultrasparc")
431 (eq_attr "type" "sload"))
434 (define_function_unit "memory" 1 0
435 (and (eq_attr "cpu" "ultrasparc")
436 (eq_attr "type" "store,fpstore"))
439 (define_function_unit "ieuN" 2 0
440 (and (eq_attr "cpu" "ultrasparc")
441 (eq_attr "type" "ialu,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
444 (define_function_unit "ieu0" 1 0
445 (and (eq_attr "cpu" "ultrasparc")
446 (eq_attr "type" "shift"))
449 (define_function_unit "ieu0" 1 0
450 (and (eq_attr "cpu" "ultrasparc")
451 (eq_attr "type" "cmove"))
454 (define_function_unit "ieu1" 1 0
455 (and (eq_attr "cpu" "ultrasparc")
456 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
459 (define_function_unit "cti" 1 0
460 (and (eq_attr "cpu" "ultrasparc")
461 (eq_attr "type" "branch"))
464 ;; Timings; throughput/latency
465 ;; FMOV 1/1 fmov, fabs, fneg
467 ;; FADD 1/3 add/sub, format conv, compar
473 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
475 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
476 ;; use the FPM multiplier for final rounding 3 cycles before the
477 ;; end of their latency and we have no real way to model that.
479 ;; ??? This is really bogus because the timings really depend upon
480 ;; who uses the result. We should record who the user is with
481 ;; more descriptive 'type' attribute names and account for these
482 ;; issues in ultrasparc_adjust_cost.
484 (define_function_unit "fadd" 1 0
485 (and (eq_attr "cpu" "ultrasparc")
486 (eq_attr "type" "fpmove"))
489 (define_function_unit "fadd" 1 0
490 (and (eq_attr "cpu" "ultrasparc")
491 (eq_attr "type" "fpcmove"))
494 (define_function_unit "fadd" 1 0
495 (and (eq_attr "cpu" "ultrasparc")
496 (eq_attr "type" "fp"))
499 (define_function_unit "fadd" 1 0
500 (and (eq_attr "cpu" "ultrasparc")
501 (eq_attr "type" "fpcmp"))
504 (define_function_unit "fmul" 1 0
505 (and (eq_attr "cpu" "ultrasparc")
506 (eq_attr "type" "fpmul"))
509 (define_function_unit "fadd" 1 0
510 (and (eq_attr "cpu" "ultrasparc")
511 (eq_attr "type" "fpcmove"))
514 (define_function_unit "fdiv" 1 0
515 (and (eq_attr "cpu" "ultrasparc")
516 (eq_attr "type" "fpdivs"))
519 (define_function_unit "fdiv" 1 0
520 (and (eq_attr "cpu" "ultrasparc")
521 (eq_attr "type" "fpdivd"))
524 (define_function_unit "fdiv" 1 0
525 (and (eq_attr "cpu" "ultrasparc")
526 (eq_attr "type" "fpsqrts"))
529 (define_function_unit "fdiv" 1 0
530 (and (eq_attr "cpu" "ultrasparc")
531 (eq_attr "type" "fpsqrtd"))
534 ;; Compare instructions.
535 ;; This controls RTL generation and register allocation.
537 ;; We generate RTL for comparisons and branches by having the cmpxx
538 ;; patterns store away the operands. Then, the scc and bcc patterns
539 ;; emit RTL for both the compare and the branch.
541 ;; We do this because we want to generate different code for an sne and
542 ;; seq insn. In those cases, if the second operand of the compare is not
543 ;; const0_rtx, we want to compute the xor of the two operands and test
546 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
547 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
548 ;; insns that actually require more than one machine instruction.
550 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
552 (define_expand "cmpsi"
554 (compare:CC (match_operand:SI 0 "register_operand" "")
555 (match_operand:SI 1 "arith_operand" "")))]
559 sparc_compare_op0 = operands[0];
560 sparc_compare_op1 = operands[1];
564 (define_expand "cmpdi"
566 (compare:CCX (match_operand:DI 0 "register_operand" "")
567 (match_operand:DI 1 "arith_double_operand" "")))]
571 sparc_compare_op0 = operands[0];
572 sparc_compare_op1 = operands[1];
576 (define_expand "cmpsf"
577 ;; The 96 here isn't ever used by anyone.
579 (compare:CCFP (match_operand:SF 0 "register_operand" "")
580 (match_operand:SF 1 "register_operand" "")))]
584 sparc_compare_op0 = operands[0];
585 sparc_compare_op1 = operands[1];
589 (define_expand "cmpdf"
590 ;; The 96 here isn't ever used by anyone.
592 (compare:CCFP (match_operand:DF 0 "register_operand" "")
593 (match_operand:DF 1 "register_operand" "")))]
597 sparc_compare_op0 = operands[0];
598 sparc_compare_op1 = operands[1];
602 (define_expand "cmptf"
603 ;; The 96 here isn't ever used by anyone.
605 (compare:CCFP (match_operand:TF 0 "register_operand" "")
606 (match_operand:TF 1 "register_operand" "")))]
610 sparc_compare_op0 = operands[0];
611 sparc_compare_op1 = operands[1];
615 ;; Now the compare DEFINE_INSNs.
617 (define_insn "*cmpsi_insn"
619 (compare:CC (match_operand:SI 0 "register_operand" "r")
620 (match_operand:SI 1 "arith_operand" "rI")))]
623 [(set_attr "type" "compare")])
625 (define_insn "*cmpdi_sp64"
627 (compare:CCX (match_operand:DI 0 "register_operand" "r")
628 (match_operand:DI 1 "arith_double_operand" "rHI")))]
631 [(set_attr "type" "compare")])
633 (define_insn "*cmpsf_fpe"
634 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
635 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
636 (match_operand:SF 2 "register_operand" "f")))]
641 return \"fcmpes\\t%0, %1, %2\";
642 return \"fcmpes\\t%1, %2\";
644 [(set_attr "type" "fpcmp")])
646 (define_insn "*cmpdf_fpe"
647 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
648 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
649 (match_operand:DF 2 "register_operand" "e")))]
654 return \"fcmped\\t%0, %1, %2\";
655 return \"fcmped\\t%1, %2\";
657 [(set_attr "type" "fpcmp")])
659 (define_insn "*cmptf_fpe"
660 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
661 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
662 (match_operand:TF 2 "register_operand" "e")))]
663 "TARGET_FPU && TARGET_HARD_QUAD"
667 return \"fcmpeq\\t%0, %1, %2\";
668 return \"fcmpeq\\t%1, %2\";
670 [(set_attr "type" "fpcmp")])
672 (define_insn "*cmpsf_fp"
673 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
674 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
675 (match_operand:SF 2 "register_operand" "f")))]
680 return \"fcmps\\t%0, %1, %2\";
681 return \"fcmps\\t%1, %2\";
683 [(set_attr "type" "fpcmp")])
685 (define_insn "*cmpdf_fp"
686 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
687 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
688 (match_operand:DF 2 "register_operand" "e")))]
693 return \"fcmpd\\t%0, %1, %2\";
694 return \"fcmpd\\t%1, %2\";
696 [(set_attr "type" "fpcmp")])
698 (define_insn "*cmptf_fp"
699 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
700 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
701 (match_operand:TF 2 "register_operand" "e")))]
702 "TARGET_FPU && TARGET_HARD_QUAD"
706 return \"fcmpq\\t%0, %1, %2\";
707 return \"fcmpq\\t%1, %2\";
709 [(set_attr "type" "fpcmp")])
711 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
712 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
713 ;; the same code as v8 (the addx/subx method has more applications). The
714 ;; exception to this is "reg != 0" which can be done in one instruction on v9
715 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
718 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
719 ;; generate addcc/subcc instructions.
721 (define_expand "seqsi_special"
723 (xor:SI (match_operand:SI 1 "register_operand" "")
724 (match_operand:SI 2 "register_operand" "")))
725 (parallel [(set (match_operand:SI 0 "register_operand" "")
726 (eq:SI (match_dup 3) (const_int 0)))
727 (clobber (reg:CC 100))])]
729 "{ operands[3] = gen_reg_rtx (SImode); }")
731 (define_expand "seqdi_special"
733 (xor:DI (match_operand:DI 1 "register_operand" "")
734 (match_operand:DI 2 "register_operand" "")))
735 (set (match_operand:DI 0 "register_operand" "")
736 (eq:DI (match_dup 3) (const_int 0)))]
738 "{ operands[3] = gen_reg_rtx (DImode); }")
740 (define_expand "snesi_special"
742 (xor:SI (match_operand:SI 1 "register_operand" "")
743 (match_operand:SI 2 "register_operand" "")))
744 (parallel [(set (match_operand:SI 0 "register_operand" "")
745 (ne:SI (match_dup 3) (const_int 0)))
746 (clobber (reg:CC 100))])]
748 "{ operands[3] = gen_reg_rtx (SImode); }")
750 (define_expand "snedi_special"
752 (xor:DI (match_operand:DI 1 "register_operand" "")
753 (match_operand:DI 2 "register_operand" "")))
754 (set (match_operand:DI 0 "register_operand" "")
755 (ne:DI (match_dup 3) (const_int 0)))]
757 "{ operands[3] = gen_reg_rtx (DImode); }")
759 (define_expand "seqdi_special_trunc"
761 (xor:DI (match_operand:DI 1 "register_operand" "")
762 (match_operand:DI 2 "register_operand" "")))
763 (set (match_operand:SI 0 "register_operand" "")
764 (eq:SI (match_dup 3) (const_int 0)))]
766 "{ operands[3] = gen_reg_rtx (DImode); }")
768 (define_expand "snedi_special_trunc"
770 (xor:DI (match_operand:DI 1 "register_operand" "")
771 (match_operand:DI 2 "register_operand" "")))
772 (set (match_operand:SI 0 "register_operand" "")
773 (ne:SI (match_dup 3) (const_int 0)))]
775 "{ operands[3] = gen_reg_rtx (DImode); }")
777 (define_expand "seqsi_special_extend"
779 (xor:SI (match_operand:SI 1 "register_operand" "")
780 (match_operand:SI 2 "register_operand" "")))
781 (parallel [(set (match_operand:DI 0 "register_operand" "")
782 (eq:DI (match_dup 3) (const_int 0)))
783 (clobber (reg:CC 100))])]
785 "{ operands[3] = gen_reg_rtx (SImode); }")
787 (define_expand "snesi_special_extend"
789 (xor:SI (match_operand:SI 1 "register_operand" "")
790 (match_operand:SI 2 "register_operand" "")))
791 (parallel [(set (match_operand:DI 0 "register_operand" "")
792 (ne:DI (match_dup 3) (const_int 0)))
793 (clobber (reg:CC 100))])]
795 "{ operands[3] = gen_reg_rtx (SImode); }")
797 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
798 ;; However, the code handles both SImode and DImode.
800 [(set (match_operand:SI 0 "intreg_operand" "")
801 (eq:SI (match_dup 1) (const_int 0)))]
805 if (GET_MODE (sparc_compare_op0) == SImode)
809 if (GET_MODE (operands[0]) == SImode)
810 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
812 else if (! TARGET_ARCH64)
815 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
820 else if (GET_MODE (sparc_compare_op0) == DImode)
826 else if (GET_MODE (operands[0]) == SImode)
827 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
830 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
835 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
837 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
838 emit_jump_insn (gen_sne (operands[0]));
843 if (gen_v9_scc (EQ, operands))
850 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
851 ;; However, the code handles both SImode and DImode.
853 [(set (match_operand:SI 0 "intreg_operand" "")
854 (ne:SI (match_dup 1) (const_int 0)))]
858 if (GET_MODE (sparc_compare_op0) == SImode)
862 if (GET_MODE (operands[0]) == SImode)
863 pat = gen_snesi_special (operands[0], sparc_compare_op0,
865 else if (! TARGET_ARCH64)
868 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
873 else if (GET_MODE (sparc_compare_op0) == DImode)
879 else if (GET_MODE (operands[0]) == SImode)
880 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
883 pat = gen_snedi_special (operands[0], sparc_compare_op0,
888 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
890 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
891 emit_jump_insn (gen_sne (operands[0]));
896 if (gen_v9_scc (NE, operands))
904 [(set (match_operand:SI 0 "intreg_operand" "")
905 (gt:SI (match_dup 1) (const_int 0)))]
909 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
911 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
912 emit_jump_insn (gen_sne (operands[0]));
917 if (gen_v9_scc (GT, operands))
925 [(set (match_operand:SI 0 "intreg_operand" "")
926 (lt:SI (match_dup 1) (const_int 0)))]
930 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
932 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
933 emit_jump_insn (gen_sne (operands[0]));
938 if (gen_v9_scc (LT, operands))
946 [(set (match_operand:SI 0 "intreg_operand" "")
947 (ge:SI (match_dup 1) (const_int 0)))]
951 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
953 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
954 emit_jump_insn (gen_sne (operands[0]));
959 if (gen_v9_scc (GE, operands))
967 [(set (match_operand:SI 0 "intreg_operand" "")
968 (le:SI (match_dup 1) (const_int 0)))]
972 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
974 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
975 emit_jump_insn (gen_sne (operands[0]));
980 if (gen_v9_scc (LE, operands))
987 (define_expand "sgtu"
988 [(set (match_operand:SI 0 "intreg_operand" "")
989 (gtu:SI (match_dup 1) (const_int 0)))]
997 /* We can do ltu easily, so if both operands are registers, swap them and
999 if ((GET_CODE (sparc_compare_op0) == REG
1000 || GET_CODE (sparc_compare_op0) == SUBREG)
1001 && (GET_CODE (sparc_compare_op1) == REG
1002 || GET_CODE (sparc_compare_op1) == SUBREG))
1004 tem = sparc_compare_op0;
1005 sparc_compare_op0 = sparc_compare_op1;
1006 sparc_compare_op1 = tem;
1007 pat = gen_sltu (operands[0]);
1008 if (pat == NULL_RTX)
1016 if (gen_v9_scc (GTU, operands))
1022 (define_expand "sltu"
1023 [(set (match_operand:SI 0 "intreg_operand" "")
1024 (ltu:SI (match_dup 1) (const_int 0)))]
1030 if (gen_v9_scc (LTU, operands))
1033 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1036 (define_expand "sgeu"
1037 [(set (match_operand:SI 0 "intreg_operand" "")
1038 (geu:SI (match_dup 1) (const_int 0)))]
1044 if (gen_v9_scc (GEU, operands))
1047 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1050 (define_expand "sleu"
1051 [(set (match_operand:SI 0 "intreg_operand" "")
1052 (leu:SI (match_dup 1) (const_int 0)))]
1060 /* We can do geu easily, so if both operands are registers, swap them and
1062 if ((GET_CODE (sparc_compare_op0) == REG
1063 || GET_CODE (sparc_compare_op0) == SUBREG)
1064 && (GET_CODE (sparc_compare_op1) == REG
1065 || GET_CODE (sparc_compare_op1) == SUBREG))
1067 tem = sparc_compare_op0;
1068 sparc_compare_op0 = sparc_compare_op1;
1069 sparc_compare_op1 = tem;
1070 pat = gen_sgeu (operands[0]);
1071 if (pat == NULL_RTX)
1079 if (gen_v9_scc (LEU, operands))
1085 ;; Now the DEFINE_INSNs for the scc cases.
1087 ;; The SEQ and SNE patterns are special because they can be done
1088 ;; without any branching and do not involve a COMPARE. We want
1089 ;; them to always use the splitz below so the results can be
1092 (define_insn "*snesi_zero"
1093 [(set (match_operand:SI 0 "register_operand" "=r")
1094 (ne:SI (match_operand:SI 1 "register_operand" "r")
1096 (clobber (reg:CC 100))]
1099 [(set_attr "length" "2")])
1102 [(set (match_operand:SI 0 "register_operand" "")
1103 (ne:SI (match_operand:SI 1 "register_operand" "")
1105 (clobber (reg:CC 100))]
1107 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1109 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1112 (define_insn "*neg_snesi_zero"
1113 [(set (match_operand:SI 0 "register_operand" "=r")
1114 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1116 (clobber (reg:CC 100))]
1119 [(set_attr "length" "2")])
1122 [(set (match_operand:SI 0 "register_operand" "")
1123 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1125 (clobber (reg:CC 100))]
1127 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1129 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1132 (define_insn "*snesi_zero_extend"
1133 [(set (match_operand:DI 0 "register_operand" "=r")
1134 (ne:DI (match_operand:SI 1 "register_operand" "r")
1136 (clobber (reg:CC 100))]
1139 [(set_attr "length" "2")])
1142 [(set (match_operand:DI 0 "register_operand" "")
1143 (ne:DI (match_operand:SI 1 "register_operand" "")
1145 (clobber (reg:CC 100))]
1147 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1149 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1151 (ltu:SI (reg:CC_NOOV 100)
1155 (define_insn "*snedi_zero"
1156 [(set (match_operand:DI 0 "register_operand" "=&r")
1157 (ne:DI (match_operand:DI 1 "register_operand" "r")
1161 [(set_attr "type" "cmove")
1162 (set_attr "length" "2")])
1165 [(set (match_operand:DI 0 "register_operand" "")
1166 (ne:DI (match_operand:DI 1 "register_operand" "")
1169 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1170 [(set (match_dup 0) (const_int 0))
1171 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1177 (define_insn "*neg_snedi_zero"
1178 [(set (match_operand:DI 0 "register_operand" "=&r")
1179 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1183 [(set_attr "type" "cmove")
1184 (set_attr "length" "2")])
1187 [(set (match_operand:DI 0 "register_operand" "")
1188 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1191 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1192 [(set (match_dup 0) (const_int 0))
1193 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1199 (define_insn "*snedi_zero_trunc"
1200 [(set (match_operand:SI 0 "register_operand" "=&r")
1201 (ne:SI (match_operand:DI 1 "register_operand" "r")
1205 [(set_attr "type" "cmove")
1206 (set_attr "length" "2")])
1209 [(set (match_operand:SI 0 "register_operand" "")
1210 (ne:SI (match_operand:DI 1 "register_operand" "")
1213 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1214 [(set (match_dup 0) (const_int 0))
1215 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1221 (define_insn "*seqsi_zero"
1222 [(set (match_operand:SI 0 "register_operand" "=r")
1223 (eq:SI (match_operand:SI 1 "register_operand" "r")
1225 (clobber (reg:CC 100))]
1228 [(set_attr "length" "2")])
1231 [(set (match_operand:SI 0 "register_operand" "")
1232 (eq:SI (match_operand:SI 1 "register_operand" "")
1234 (clobber (reg:CC 100))]
1236 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1238 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1241 (define_insn "*neg_seqsi_zero"
1242 [(set (match_operand:SI 0 "register_operand" "=r")
1243 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1245 (clobber (reg:CC 100))]
1248 [(set_attr "length" "2")])
1251 [(set (match_operand:SI 0 "register_operand" "")
1252 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1254 (clobber (reg:CC 100))]
1256 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1258 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1261 (define_insn "*seqsi_zero_extend"
1262 [(set (match_operand:DI 0 "register_operand" "=r")
1263 (eq:DI (match_operand:SI 1 "register_operand" "r")
1265 (clobber (reg:CC 100))]
1268 [(set_attr "length" "2")])
1271 [(set (match_operand:DI 0 "register_operand" "")
1272 (eq:DI (match_operand:SI 1 "register_operand" "")
1274 (clobber (reg:CC 100))]
1276 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1278 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1280 (ltu:SI (reg:CC_NOOV 100)
1284 (define_insn "*seqdi_zero"
1285 [(set (match_operand:DI 0 "register_operand" "=&r")
1286 (eq:DI (match_operand:DI 1 "register_operand" "r")
1290 [(set_attr "type" "cmove")
1291 (set_attr "length" "2")])
1294 [(set (match_operand:DI 0 "register_operand" "")
1295 (eq:DI (match_operand:DI 1 "register_operand" "")
1298 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1299 [(set (match_dup 0) (const_int 0))
1300 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1306 (define_insn "*neg_seqdi_zero"
1307 [(set (match_operand:DI 0 "register_operand" "=&r")
1308 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1312 [(set_attr "type" "cmove")
1313 (set_attr "length" "2")])
1316 [(set (match_operand:DI 0 "register_operand" "")
1317 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1320 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1321 [(set (match_dup 0) (const_int 0))
1322 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1328 (define_insn "*seqdi_zero_trunc"
1329 [(set (match_operand:SI 0 "register_operand" "=&r")
1330 (eq:SI (match_operand:DI 1 "register_operand" "r")
1334 [(set_attr "type" "cmove")
1335 (set_attr "length" "2")])
1338 [(set (match_operand:SI 0 "register_operand" "")
1339 (eq:SI (match_operand:DI 1 "register_operand" "")
1342 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1343 [(set (match_dup 0) (const_int 0))
1344 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1350 ;; We can also do (x + (i == 0)) and related, so put them in.
1351 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1354 (define_insn "*x_plus_i_ne_0"
1355 [(set (match_operand:SI 0 "register_operand" "=r")
1356 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1358 (match_operand:SI 2 "register_operand" "r")))
1359 (clobber (reg:CC 100))]
1362 [(set_attr "length" "2")])
1365 [(set (match_operand:SI 0 "register_operand" "")
1366 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1368 (match_operand:SI 2 "register_operand" "")))
1369 (clobber (reg:CC 100))]
1371 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1373 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1377 (define_insn "*x_minus_i_ne_0"
1378 [(set (match_operand:SI 0 "register_operand" "=r")
1379 (minus:SI (match_operand:SI 2 "register_operand" "r")
1380 (ne:SI (match_operand:SI 1 "register_operand" "r")
1382 (clobber (reg:CC 100))]
1385 [(set_attr "length" "2")])
1388 [(set (match_operand:SI 0 "register_operand" "")
1389 (minus:SI (match_operand:SI 2 "register_operand" "")
1390 (ne:SI (match_operand:SI 1 "register_operand" "")
1392 (clobber (reg:CC 100))]
1394 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1396 (set (match_dup 0) (minus:SI (match_dup 2)
1397 (ltu:SI (reg:CC 100) (const_int 0))))]
1400 (define_insn "*x_plus_i_eq_0"
1401 [(set (match_operand:SI 0 "register_operand" "=r")
1402 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1404 (match_operand:SI 2 "register_operand" "r")))
1405 (clobber (reg:CC 100))]
1408 [(set_attr "length" "2")])
1411 [(set (match_operand:SI 0 "register_operand" "")
1412 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1414 (match_operand:SI 2 "register_operand" "")))
1415 (clobber (reg:CC 100))]
1417 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1419 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1423 (define_insn "*x_minus_i_eq_0"
1424 [(set (match_operand:SI 0 "register_operand" "=r")
1425 (minus:SI (match_operand:SI 2 "register_operand" "r")
1426 (eq:SI (match_operand:SI 1 "register_operand" "r")
1428 (clobber (reg:CC 100))]
1431 [(set_attr "length" "2")])
1434 [(set (match_operand:SI 0 "register_operand" "")
1435 (minus:SI (match_operand:SI 2 "register_operand" "")
1436 (eq:SI (match_operand:SI 1 "register_operand" "")
1438 (clobber (reg:CC 100))]
1440 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1442 (set (match_dup 0) (minus:SI (match_dup 2)
1443 (geu:SI (reg:CC 100) (const_int 0))))]
1446 ;; We can also do GEU and LTU directly, but these operate after a compare.
1447 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1450 (define_insn "*sltu_insn"
1451 [(set (match_operand:SI 0 "register_operand" "=r")
1452 (ltu:SI (reg:CC 100) (const_int 0)))]
1454 "addx\\t%%g0, 0, %0"
1455 [(set_attr "type" "misc")
1456 (set_attr "length" "1")])
1458 (define_insn "*neg_sltu_insn"
1459 [(set (match_operand:SI 0 "register_operand" "=r")
1460 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1462 "subx\\t%%g0, 0, %0"
1463 [(set_attr "type" "misc")
1464 (set_attr "length" "1")])
1466 ;; ??? Combine should canonicalize these next two to the same pattern.
1467 (define_insn "*neg_sltu_minus_x"
1468 [(set (match_operand:SI 0 "register_operand" "=r")
1469 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1470 (match_operand:SI 1 "arith_operand" "rI")))]
1472 "subx\\t%%g0, %1, %0"
1473 [(set_attr "type" "misc")
1474 (set_attr "length" "1")])
1476 (define_insn "*neg_sltu_plus_x"
1477 [(set (match_operand:SI 0 "register_operand" "=r")
1478 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1479 (match_operand:SI 1 "arith_operand" "rI"))))]
1481 "subx\\t%%g0, %1, %0"
1482 [(set_attr "type" "misc")
1483 (set_attr "length" "1")])
1485 (define_insn "*sgeu_insn"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (geu:SI (reg:CC 100) (const_int 0)))]
1489 "subx\\t%%g0, -1, %0"
1490 [(set_attr "type" "misc")
1491 (set_attr "length" "1")])
1493 (define_insn "*neg_sgeu_insn"
1494 [(set (match_operand:SI 0 "register_operand" "=r")
1495 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1497 "addx\\t%%g0, -1, %0"
1498 [(set_attr "type" "misc")
1499 (set_attr "length" "1")])
1501 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1502 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1505 (define_insn "*sltu_plus_x"
1506 [(set (match_operand:SI 0 "register_operand" "=r")
1507 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1508 (match_operand:SI 1 "arith_operand" "rI")))]
1510 "addx\\t%%g0, %1, %0"
1511 [(set_attr "type" "misc")
1512 (set_attr "length" "1")])
1514 (define_insn "*sltu_plus_x_plus_y"
1515 [(set (match_operand:SI 0 "register_operand" "=r")
1516 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1517 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1518 (match_operand:SI 2 "arith_operand" "rI"))))]
1521 [(set_attr "type" "misc")
1522 (set_attr "length" "1")])
1524 (define_insn "*x_minus_sltu"
1525 [(set (match_operand:SI 0 "register_operand" "=r")
1526 (minus:SI (match_operand:SI 1 "register_operand" "r")
1527 (ltu:SI (reg:CC 100) (const_int 0))))]
1530 [(set_attr "type" "misc")
1531 (set_attr "length" "1")])
1533 ;; ??? Combine should canonicalize these next two to the same pattern.
1534 (define_insn "*x_minus_y_minus_sltu"
1535 [(set (match_operand:SI 0 "register_operand" "=r")
1536 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1537 (match_operand:SI 2 "arith_operand" "rI"))
1538 (ltu:SI (reg:CC 100) (const_int 0))))]
1540 "subx\\t%r1, %2, %0"
1541 [(set_attr "type" "misc")
1542 (set_attr "length" "1")])
1544 (define_insn "*x_minus_sltu_plus_y"
1545 [(set (match_operand:SI 0 "register_operand" "=r")
1546 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1547 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1548 (match_operand:SI 2 "arith_operand" "rI"))))]
1550 "subx\\t%r1, %2, %0"
1551 [(set_attr "type" "misc")
1552 (set_attr "length" "1")])
1554 (define_insn "*sgeu_plus_x"
1555 [(set (match_operand:SI 0 "register_operand" "=r")
1556 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1557 (match_operand:SI 1 "register_operand" "r")))]
1560 [(set_attr "type" "misc")
1561 (set_attr "length" "1")])
1563 (define_insn "*x_minus_sgeu"
1564 [(set (match_operand:SI 0 "register_operand" "=r")
1565 (minus:SI (match_operand:SI 1 "register_operand" "r")
1566 (geu:SI (reg:CC 100) (const_int 0))))]
1569 [(set_attr "type" "misc")
1570 (set_attr "length" "1")])
1573 [(set (match_operand:SI 0 "register_operand" "")
1574 (match_operator:SI 2 "noov_compare_op"
1575 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1577 ;; 32 bit LTU/GEU are better implemented using addx/subx
1578 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1579 && (GET_MODE (operands[1]) == CCXmode
1580 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1581 [(set (match_dup 0) (const_int 0))
1583 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1589 ;; These control RTL generation for conditional jump insns
1591 ;; The quad-word fp compare library routines all return nonzero to indicate
1592 ;; true, which is different from the equivalent libgcc routines, so we must
1593 ;; handle them specially here.
1595 (define_expand "beq"
1597 (if_then_else (eq (match_dup 1) (const_int 0))
1598 (label_ref (match_operand 0 "" ""))
1603 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1604 && GET_CODE (sparc_compare_op0) == REG
1605 && GET_MODE (sparc_compare_op0) == DImode)
1607 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1610 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1612 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1613 emit_jump_insn (gen_bne (operands[0]));
1616 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1619 (define_expand "bne"
1621 (if_then_else (ne (match_dup 1) (const_int 0))
1622 (label_ref (match_operand 0 "" ""))
1627 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1628 && GET_CODE (sparc_compare_op0) == REG
1629 && GET_MODE (sparc_compare_op0) == DImode)
1631 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1634 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1636 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1637 emit_jump_insn (gen_bne (operands[0]));
1640 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1643 (define_expand "bgt"
1645 (if_then_else (gt (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 (GT, 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, GT);
1661 emit_jump_insn (gen_bne (operands[0]));
1664 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1667 (define_expand "bgtu"
1669 (if_then_else (gtu (match_dup 1) (const_int 0))
1670 (label_ref (match_operand 0 "" ""))
1674 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1677 (define_expand "blt"
1679 (if_then_else (lt (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 (LT, 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, LT);
1695 emit_jump_insn (gen_bne (operands[0]));
1698 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1701 (define_expand "bltu"
1703 (if_then_else (ltu (match_dup 1) (const_int 0))
1704 (label_ref (match_operand 0 "" ""))
1708 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1711 (define_expand "bge"
1713 (if_then_else (ge (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 (GE, 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, GE);
1729 emit_jump_insn (gen_bne (operands[0]));
1732 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1735 (define_expand "bgeu"
1737 (if_then_else (geu (match_dup 1) (const_int 0))
1738 (label_ref (match_operand 0 "" ""))
1742 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1745 (define_expand "ble"
1747 (if_then_else (le (match_dup 1) (const_int 0))
1748 (label_ref (match_operand 0 "" ""))
1753 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1754 && GET_CODE (sparc_compare_op0) == REG
1755 && GET_MODE (sparc_compare_op0) == DImode)
1757 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1760 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1762 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1763 emit_jump_insn (gen_bne (operands[0]));
1766 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1769 (define_expand "bleu"
1771 (if_then_else (leu (match_dup 1) (const_int 0))
1772 (label_ref (match_operand 0 "" ""))
1776 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1779 (define_expand "bunordered"
1781 (if_then_else (unordered (match_dup 1) (const_int 0))
1782 (label_ref (match_operand 0 "" ""))
1787 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1789 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1791 emit_jump_insn (gen_beq (operands[0]));
1794 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1798 (define_expand "bordered"
1800 (if_then_else (ordered (match_dup 1) (const_int 0))
1801 (label_ref (match_operand 0 "" ""))
1806 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1808 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1809 emit_jump_insn (gen_bne (operands[0]));
1812 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1816 (define_expand "bungt"
1818 (if_then_else (ungt (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, UNGT);
1827 emit_jump_insn (gen_bgt (operands[0]));
1830 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1833 (define_expand "bunlt"
1835 (if_then_else (unlt (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, UNLT);
1844 emit_jump_insn (gen_bne (operands[0]));
1847 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1850 (define_expand "buneq"
1852 (if_then_else (uneq (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, UNEQ);
1861 emit_jump_insn (gen_beq (operands[0]));
1864 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1867 (define_expand "bunge"
1869 (if_then_else (unge (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, UNGE);
1878 emit_jump_insn (gen_bne (operands[0]));
1881 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1884 (define_expand "bunle"
1886 (if_then_else (unle (match_dup 1) (const_int 0))
1887 (label_ref (match_operand 0 "" ""))
1892 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1894 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1895 emit_jump_insn (gen_bne (operands[0]));
1898 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1901 (define_expand "bltgt"
1903 (if_then_else (ltgt (match_dup 1) (const_int 0))
1904 (label_ref (match_operand 0 "" ""))
1909 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1911 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1912 emit_jump_insn (gen_bne (operands[0]));
1915 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1918 ;; Now match both normal and inverted jump.
1920 ;; XXX fpcmp nop braindamage
1921 (define_insn "*normal_branch"
1923 (if_then_else (match_operator 0 "noov_compare_op"
1924 [(reg 100) (const_int 0)])
1925 (label_ref (match_operand 1 "" ""))
1930 return output_cbranch (operands[0], 1, 0,
1931 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1932 ! final_sequence, insn);
1934 [(set_attr "type" "branch")])
1936 ;; XXX fpcmp nop braindamage
1937 (define_insn "*inverted_branch"
1939 (if_then_else (match_operator 0 "noov_compare_op"
1940 [(reg 100) (const_int 0)])
1942 (label_ref (match_operand 1 "" ""))))]
1946 return output_cbranch (operands[0], 1, 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_fp_branch"
1955 (if_then_else (match_operator 1 "comparison_operator"
1956 [(match_operand:CCFP 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_fp_branch"
1972 (if_then_else (match_operator 1 "comparison_operator"
1973 [(match_operand:CCFP 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 ;; XXX fpcmp nop braindamage
1987 (define_insn "*normal_fpe_branch"
1989 (if_then_else (match_operator 1 "comparison_operator"
1990 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1992 (label_ref (match_operand 2 "" ""))
1997 return output_cbranch (operands[1], 2, 0,
1998 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1999 ! final_sequence, insn);
2001 [(set_attr "type" "branch")])
2003 ;; XXX fpcmp nop braindamage
2004 (define_insn "*inverted_fpe_branch"
2006 (if_then_else (match_operator 1 "comparison_operator"
2007 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2010 (label_ref (match_operand 2 "" ""))))]
2014 return output_cbranch (operands[1], 2, 1,
2015 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2016 ! final_sequence, insn);
2018 [(set_attr "type" "branch")])
2020 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2021 ;; in the architecture.
2023 ;; There are no 32 bit brreg insns.
2026 (define_insn "*normal_int_branch_sp64"
2028 (if_then_else (match_operator 0 "v9_regcmp_op"
2029 [(match_operand:DI 1 "register_operand" "r")
2031 (label_ref (match_operand 2 "" ""))
2036 return output_v9branch (operands[0], 1, 2, 0,
2037 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2038 ! final_sequence, insn);
2040 [(set_attr "type" "branch")])
2043 (define_insn "*inverted_int_branch_sp64"
2045 (if_then_else (match_operator 0 "v9_regcmp_op"
2046 [(match_operand:DI 1 "register_operand" "r")
2049 (label_ref (match_operand 2 "" ""))))]
2053 return output_v9branch (operands[0], 1, 2, 1,
2054 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2055 ! final_sequence, insn);
2057 [(set_attr "type" "branch")])
2059 ;; Load program counter insns.
2061 (define_insn "get_pc"
2062 [(clobber (reg:SI 15))
2063 (set (match_operand 0 "register_operand" "=r")
2064 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2065 "flag_pic && REGNO (operands[0]) == 23"
2066 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2067 [(set_attr "length" "3")])
2069 ;; Currently unused...
2070 ;; (define_insn "get_pc_via_rdpc"
2071 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2074 ;; [(set_attr "type" "misc")])
2077 ;; Move instructions
2079 (define_expand "movqi"
2080 [(set (match_operand:QI 0 "general_operand" "")
2081 (match_operand:QI 1 "general_operand" ""))]
2085 /* Working with CONST_INTs is easier, so convert
2086 a double if needed. */
2087 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2089 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2091 else if (GET_CODE (operands[1]) == CONST_INT)
2093 /* And further, we know for all QI cases that only the
2094 low byte is significant, which we can always process
2095 in a single insn. So mask it now. */
2096 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2099 /* Handle sets of MEM first. */
2100 if (GET_CODE (operands[0]) == MEM)
2102 if (reg_or_0_operand (operands[1], QImode))
2105 if (! reload_in_progress)
2107 operands[0] = validize_mem (operands[0]);
2108 operands[1] = force_reg (QImode, operands[1]);
2112 /* Fixup PIC cases. */
2115 if (CONSTANT_P (operands[1])
2116 && pic_address_needs_scratch (operands[1]))
2117 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2119 if (symbolic_operand (operands[1], QImode))
2121 operands[1] = legitimize_pic_address (operands[1],
2123 (reload_in_progress ?
2130 /* All QI constants require only one insn, so proceed. */
2136 (define_insn "*movqi_insn"
2137 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2138 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2139 "(register_operand (operands[0], QImode)
2140 || reg_or_0_operand (operands[1], QImode))"
2145 [(set_attr "type" "*,load,store")
2146 (set_attr "length" "1")])
2148 (define_expand "movhi"
2149 [(set (match_operand:HI 0 "general_operand" "")
2150 (match_operand:HI 1 "general_operand" ""))]
2154 /* Working with CONST_INTs is easier, so convert
2155 a double if needed. */
2156 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2157 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2159 /* Handle sets of MEM first. */
2160 if (GET_CODE (operands[0]) == MEM)
2162 if (reg_or_0_operand (operands[1], HImode))
2165 if (! reload_in_progress)
2167 operands[0] = validize_mem (operands[0]);
2168 operands[1] = force_reg (HImode, operands[1]);
2172 /* Fixup PIC cases. */
2175 if (CONSTANT_P (operands[1])
2176 && pic_address_needs_scratch (operands[1]))
2177 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2179 if (symbolic_operand (operands[1], HImode))
2181 operands[1] = legitimize_pic_address (operands[1],
2183 (reload_in_progress ?
2190 /* This makes sure we will not get rematched due to splittage. */
2191 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2193 else if (CONSTANT_P (operands[1])
2194 && GET_CODE (operands[1]) != HIGH
2195 && GET_CODE (operands[1]) != LO_SUM)
2197 sparc_emit_set_const32 (operands[0], operands[1]);
2204 (define_insn "*movhi_const64_special"
2205 [(set (match_operand:HI 0 "register_operand" "=r")
2206 (match_operand:HI 1 "const64_high_operand" ""))]
2208 "sethi\\t%%hi(%a1), %0"
2209 [(set_attr "length" "1")])
2211 (define_insn "*movhi_insn"
2212 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2213 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2214 "(register_operand (operands[0], HImode)
2215 || reg_or_0_operand (operands[1], HImode))"
2218 sethi\\t%%hi(%a1), %0
2221 [(set_attr "type" "*,*,load,store")
2222 (set_attr "length" "1")])
2224 ;; We always work with constants here.
2225 (define_insn "*movhi_lo_sum"
2226 [(set (match_operand:HI 0 "register_operand" "=r")
2227 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2228 (match_operand:HI 2 "arith_operand" "I")))]
2231 [(set_attr "type" "ialu")
2232 (set_attr "length" "1")])
2234 (define_expand "movsi"
2235 [(set (match_operand:SI 0 "general_operand" "")
2236 (match_operand:SI 1 "general_operand" ""))]
2240 /* Working with CONST_INTs is easier, so convert
2241 a double if needed. */
2242 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2243 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2245 /* Handle sets of MEM first. */
2246 if (GET_CODE (operands[0]) == MEM)
2248 if (reg_or_0_operand (operands[1], SImode))
2251 if (! reload_in_progress)
2253 operands[0] = validize_mem (operands[0]);
2254 operands[1] = force_reg (SImode, operands[1]);
2258 /* Fixup PIC cases. */
2261 if (CONSTANT_P (operands[1])
2262 && pic_address_needs_scratch (operands[1]))
2263 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2265 if (GET_CODE (operands[1]) == LABEL_REF)
2268 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2272 if (symbolic_operand (operands[1], SImode))
2274 operands[1] = legitimize_pic_address (operands[1],
2276 (reload_in_progress ?
2283 /* If we are trying to toss an integer constant into the
2284 FPU registers, force it into memory. */
2285 if (GET_CODE (operands[0]) == REG
2286 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2287 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2288 && CONSTANT_P (operands[1]))
2289 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2292 /* This makes sure we will not get rematched due to splittage. */
2293 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2295 else if (CONSTANT_P (operands[1])
2296 && GET_CODE (operands[1]) != HIGH
2297 && GET_CODE (operands[1]) != LO_SUM)
2299 sparc_emit_set_const32 (operands[0], operands[1]);
2306 ;; This is needed to show CSE exactly which bits are set
2307 ;; in a 64-bit register by sethi instructions.
2308 (define_insn "*movsi_const64_special"
2309 [(set (match_operand:SI 0 "register_operand" "=r")
2310 (match_operand:SI 1 "const64_high_operand" ""))]
2312 "sethi\\t%%hi(%a1), %0"
2313 [(set_attr "length" "1")])
2315 (define_insn "*movsi_insn"
2316 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2317 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2318 "(register_operand (operands[0], SImode)
2319 || reg_or_0_operand (operands[1], SImode))"
2323 sethi\\t%%hi(%a1), %0
2330 [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")
2331 (set_attr "length" "1")])
2333 (define_insn "*movsi_lo_sum"
2334 [(set (match_operand:SI 0 "register_operand" "=r")
2335 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2336 (match_operand:SI 2 "immediate_operand" "in")))]
2338 "or\\t%1, %%lo(%a2), %0"
2339 [(set_attr "type" "ialu")
2340 (set_attr "length" "1")])
2342 (define_insn "*movsi_high"
2343 [(set (match_operand:SI 0 "register_operand" "=r")
2344 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2346 "sethi\\t%%hi(%a1), %0"
2347 [(set_attr "length" "1")])
2349 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2350 ;; so that CSE won't optimize the address computation away.
2351 (define_insn "movsi_lo_sum_pic"
2352 [(set (match_operand:SI 0 "register_operand" "=r")
2353 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2354 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2356 "or\\t%1, %%lo(%a2), %0"
2357 [(set_attr "type" "ialu")
2358 (set_attr "length" "1")])
2360 (define_insn "movsi_high_pic"
2361 [(set (match_operand:SI 0 "register_operand" "=r")
2362 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2363 "flag_pic && check_pic (1)"
2364 "sethi\\t%%hi(%a1), %0"
2365 [(set_attr "length" "1")])
2367 (define_expand "movsi_pic_label_ref"
2368 [(set (match_dup 3) (high:SI
2369 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2371 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2372 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2373 (set (match_operand:SI 0 "register_operand" "=r")
2374 (minus:SI (match_dup 5) (match_dup 4)))]
2378 current_function_uses_pic_offset_table = 1;
2379 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2382 operands[3] = operands[0];
2383 operands[4] = operands[0];
2387 operands[3] = gen_reg_rtx (SImode);
2388 operands[4] = gen_reg_rtx (SImode);
2390 operands[5] = pic_offset_table_rtx;
2393 (define_insn "*movsi_high_pic_label_ref"
2394 [(set (match_operand:SI 0 "register_operand" "=r")
2396 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2397 (match_operand:SI 2 "" "")] 5)))]
2399 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2400 [(set_attr "length" "1")])
2402 (define_insn "*movsi_lo_sum_pic_label_ref"
2403 [(set (match_operand:SI 0 "register_operand" "=r")
2404 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2405 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2406 (match_operand:SI 3 "" "")] 5)))]
2408 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2409 [(set_attr "type" "ialu")
2410 (set_attr "length" "1")])
2412 (define_expand "movdi"
2413 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2414 (match_operand:DI 1 "general_operand" ""))]
2418 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2419 if (GET_CODE (operands[1]) == CONST_DOUBLE
2420 #if HOST_BITS_PER_WIDE_INT == 32
2421 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2422 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2423 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2424 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2427 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2429 /* Handle MEM cases first. */
2430 if (GET_CODE (operands[0]) == MEM)
2432 /* If it's a REG, we can always do it.
2433 The const zero case is more complex, on v9
2434 we can always perform it. */
2435 if (register_operand (operands[1], DImode)
2437 && (operands[1] == const0_rtx)))
2440 if (! reload_in_progress)
2442 operands[0] = validize_mem (operands[0]);
2443 operands[1] = force_reg (DImode, operands[1]);
2449 if (CONSTANT_P (operands[1])
2450 && pic_address_needs_scratch (operands[1]))
2451 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2453 if (GET_CODE (operands[1]) == LABEL_REF)
2455 if (! TARGET_ARCH64)
2457 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2461 if (symbolic_operand (operands[1], DImode))
2463 operands[1] = legitimize_pic_address (operands[1],
2465 (reload_in_progress ?
2472 /* If we are trying to toss an integer constant into the
2473 FPU registers, force it into memory. */
2474 if (GET_CODE (operands[0]) == REG
2475 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2476 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2477 && CONSTANT_P (operands[1]))
2478 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2481 /* This makes sure we will not get rematched due to splittage. */
2482 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2484 else if (TARGET_ARCH64
2485 && CONSTANT_P (operands[1])
2486 && GET_CODE (operands[1]) != HIGH
2487 && GET_CODE (operands[1]) != LO_SUM)
2489 sparc_emit_set_const64 (operands[0], operands[1]);
2497 ;; Be careful, fmovd does not exist when !arch64.
2498 ;; We match MEM moves directly when we have correct even
2499 ;; numbered registers, but fall into splits otherwise.
2500 ;; The constraint ordering here is really important to
2501 ;; avoid insane problems in reload, especially for patterns
2504 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2505 ;; (const_int -5016)))
2508 (define_insn "*movdi_insn_sp32"
2509 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2510 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2512 (register_operand (operands[0], DImode)
2513 || register_operand (operands[1], DImode))"
2526 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2527 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2529 ;; The following are generated by sparc_emit_set_const64
2530 (define_insn "*movdi_sp64_dbl"
2531 [(set (match_operand:DI 0 "register_operand" "=r")
2532 (match_operand:DI 1 "const64_operand" ""))]
2534 && HOST_BITS_PER_WIDE_INT != 64)"
2536 [(set_attr "length" "1")])
2538 ;; This is needed to show CSE exactly which bits are set
2539 ;; in a 64-bit register by sethi instructions.
2540 (define_insn "*movdi_const64_special"
2541 [(set (match_operand:DI 0 "register_operand" "=r")
2542 (match_operand:DI 1 "const64_high_operand" ""))]
2544 "sethi\\t%%hi(%a1), %0"
2545 [(set_attr "length" "1")])
2547 (define_insn "*movdi_insn_sp64_novis"
2548 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2549 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2550 "TARGET_ARCH64 && ! TARGET_VIS
2551 && (register_operand (operands[0], DImode)
2552 || reg_or_0_operand (operands[1], DImode))"
2555 sethi\\t%%hi(%a1), %0
2562 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2563 (set_attr "length" "1")])
2565 (define_insn "*movdi_insn_sp64_vis"
2566 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2567 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2568 "TARGET_ARCH64 && TARGET_VIS &&
2569 (register_operand (operands[0], DImode)
2570 || reg_or_0_operand (operands[1], DImode))"
2573 sethi\\t%%hi(%a1), %0
2581 [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
2582 (set_attr "length" "1")])
2584 (define_expand "movdi_pic_label_ref"
2585 [(set (match_dup 3) (high:DI
2586 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2588 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2589 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2590 (set (match_operand:DI 0 "register_operand" "=r")
2591 (minus:DI (match_dup 5) (match_dup 4)))]
2592 "TARGET_ARCH64 && flag_pic"
2595 current_function_uses_pic_offset_table = 1;
2596 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2599 operands[3] = operands[0];
2600 operands[4] = operands[0];
2604 operands[3] = gen_reg_rtx (DImode);
2605 operands[4] = gen_reg_rtx (DImode);
2607 operands[5] = pic_offset_table_rtx;
2610 (define_insn "*movdi_high_pic_label_ref"
2611 [(set (match_operand:DI 0 "register_operand" "=r")
2613 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2614 (match_operand:DI 2 "" "")] 5)))]
2615 "TARGET_ARCH64 && flag_pic"
2616 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2617 [(set_attr "length" "1")])
2619 (define_insn "*movdi_lo_sum_pic_label_ref"
2620 [(set (match_operand:DI 0 "register_operand" "=r")
2621 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2622 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2623 (match_operand:DI 3 "" "")] 5)))]
2624 "TARGET_ARCH64 && flag_pic"
2625 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2626 [(set_attr "type" "ialu")
2627 (set_attr "length" "1")])
2629 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2630 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2632 (define_insn "movdi_lo_sum_pic"
2633 [(set (match_operand:DI 0 "register_operand" "=r")
2634 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2635 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2636 "TARGET_ARCH64 && flag_pic"
2637 "or\\t%1, %%lo(%a2), %0"
2638 [(set_attr "type" "ialu")
2639 (set_attr "length" "1")])
2641 (define_insn "movdi_high_pic"
2642 [(set (match_operand:DI 0 "register_operand" "=r")
2643 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2644 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2645 "sethi\\t%%hi(%a1), %0"
2646 [(set_attr "length" "1")])
2648 (define_insn "*sethi_di_medlow_embmedany_pic"
2649 [(set (match_operand:DI 0 "register_operand" "=r")
2650 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2651 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2652 "sethi\\t%%hi(%a1), %0"
2653 [(set_attr "length" "1")])
2655 (define_insn "*sethi_di_medlow"
2656 [(set (match_operand:DI 0 "register_operand" "=r")
2657 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2658 "TARGET_CM_MEDLOW && check_pic (1)"
2659 "sethi\\t%%hi(%a1), %0"
2660 [(set_attr "length" "1")])
2662 (define_insn "*losum_di_medlow"
2663 [(set (match_operand:DI 0 "register_operand" "=r")
2664 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2665 (match_operand:DI 2 "symbolic_operand" "")))]
2667 "or\\t%1, %%lo(%a2), %0"
2668 [(set_attr "type" "ialu")
2669 (set_attr "length" "1")])
2671 (define_insn "seth44"
2672 [(set (match_operand:DI 0 "register_operand" "=r")
2673 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2675 "sethi\\t%%h44(%a1), %0"
2676 [(set_attr "length" "1")])
2678 (define_insn "setm44"
2679 [(set (match_operand:DI 0 "register_operand" "=r")
2680 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2681 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2683 "or\\t%1, %%m44(%a2), %0"
2684 [(set_attr "length" "1")])
2686 (define_insn "setl44"
2687 [(set (match_operand:DI 0 "register_operand" "=r")
2688 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2689 (match_operand:DI 2 "symbolic_operand" "")))]
2691 "or\\t%1, %%l44(%a2), %0"
2692 [(set_attr "type" "ialu")
2693 (set_attr "length" "1")])
2695 (define_insn "sethh"
2696 [(set (match_operand:DI 0 "register_operand" "=r")
2697 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2699 "sethi\\t%%hh(%a1), %0"
2700 [(set_attr "length" "1")])
2702 (define_insn "setlm"
2703 [(set (match_operand:DI 0 "register_operand" "=r")
2704 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2706 "sethi\\t%%lm(%a1), %0"
2707 [(set_attr "length" "1")])
2709 (define_insn "sethm"
2710 [(set (match_operand:DI 0 "register_operand" "=r")
2711 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2712 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2714 "or\\t%1, %%hm(%a2), %0"
2715 [(set_attr "type" "ialu")
2716 (set_attr "length" "1")])
2718 (define_insn "setlo"
2719 [(set (match_operand:DI 0 "register_operand" "=r")
2720 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2721 (match_operand:DI 2 "symbolic_operand" "")))]
2723 "or\\t%1, %%lo(%a2), %0"
2724 [(set_attr "type" "ialu")
2725 (set_attr "length" "1")])
2727 (define_insn "embmedany_sethi"
2728 [(set (match_operand:DI 0 "register_operand" "=r")
2729 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2730 "TARGET_CM_EMBMEDANY && check_pic (1)"
2731 "sethi\\t%%hi(%a1), %0"
2732 [(set_attr "length" "1")])
2734 (define_insn "embmedany_losum"
2735 [(set (match_operand:DI 0 "register_operand" "=r")
2736 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2737 (match_operand:DI 2 "data_segment_operand" "")))]
2738 "TARGET_CM_EMBMEDANY"
2739 "add\\t%1, %%lo(%a2), %0"
2740 [(set_attr "type" "ialu")
2741 (set_attr "length" "1")])
2743 (define_insn "embmedany_brsum"
2744 [(set (match_operand:DI 0 "register_operand" "=r")
2745 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2746 "TARGET_CM_EMBMEDANY"
2748 [(set_attr "length" "1")])
2750 (define_insn "embmedany_textuhi"
2751 [(set (match_operand:DI 0 "register_operand" "=r")
2752 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2753 "TARGET_CM_EMBMEDANY && check_pic (1)"
2754 "sethi\\t%%uhi(%a1), %0"
2755 [(set_attr "length" "1")])
2757 (define_insn "embmedany_texthi"
2758 [(set (match_operand:DI 0 "register_operand" "=r")
2759 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2760 "TARGET_CM_EMBMEDANY && check_pic (1)"
2761 "sethi\\t%%hi(%a1), %0"
2762 [(set_attr "length" "1")])
2764 (define_insn "embmedany_textulo"
2765 [(set (match_operand:DI 0 "register_operand" "=r")
2766 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2767 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2768 "TARGET_CM_EMBMEDANY"
2769 "or\\t%1, %%ulo(%a2), %0"
2770 [(set_attr "type" "ialu")
2771 (set_attr "length" "1")])
2773 (define_insn "embmedany_textlo"
2774 [(set (match_operand:DI 0 "register_operand" "=r")
2775 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2776 (match_operand:DI 2 "text_segment_operand" "")))]
2777 "TARGET_CM_EMBMEDANY"
2778 "or\\t%1, %%lo(%a2), %0"
2779 [(set_attr "type" "ialu")
2780 (set_attr "length" "1")])
2782 ;; Now some patterns to help reload out a bit.
2783 (define_expand "reload_indi"
2784 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2785 (match_operand:DI 1 "immediate_operand" "")
2786 (match_operand:TI 2 "register_operand" "=&r")])]
2788 || TARGET_CM_EMBMEDANY)
2792 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2793 gen_rtx_REG (DImode, REGNO (operands[2])));
2797 (define_expand "reload_outdi"
2798 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2799 (match_operand:DI 1 "immediate_operand" "")
2800 (match_operand:TI 2 "register_operand" "=&r")])]
2802 || TARGET_CM_EMBMEDANY)
2806 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2807 gen_rtx_REG (DImode, REGNO (operands[2])));
2811 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2813 [(set (match_operand:DI 0 "register_operand" "")
2814 (match_operand:DI 1 "const_int_operand" ""))]
2815 "! TARGET_ARCH64 && reload_completed"
2816 [(clobber (const_int 0))]
2819 #if HOST_BITS_PER_WIDE_INT == 32
2820 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2821 (INTVAL (operands[1]) < 0) ?
2824 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2827 unsigned int low, high;
2829 low = INTVAL (operands[1]) & 0xffffffff;
2830 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2831 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2833 /* Slick... but this trick loses if this subreg constant part
2834 can be done in one insn. */
2835 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2836 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2837 gen_highpart (SImode, operands[0])));
2839 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2845 [(set (match_operand:DI 0 "register_operand" "")
2846 (match_operand:DI 1 "const_double_operand" ""))]
2847 "! TARGET_ARCH64 && reload_completed"
2848 [(clobber (const_int 0))]
2851 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2852 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2854 /* Slick... but this trick loses if this subreg constant part
2855 can be done in one insn. */
2856 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2857 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2858 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2860 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2861 gen_highpart (SImode, operands[0])));
2865 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2866 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2872 [(set (match_operand:DI 0 "register_operand" "")
2873 (match_operand:DI 1 "register_operand" ""))]
2874 "! TARGET_ARCH64 && reload_completed"
2875 [(clobber (const_int 0))]
2878 rtx set_dest = operands[0];
2879 rtx set_src = operands[1];
2883 if (GET_CODE (set_dest) == SUBREG)
2884 set_dest = alter_subreg (set_dest);
2885 if (GET_CODE (set_src) == SUBREG)
2886 set_src = alter_subreg (set_src);
2888 dest1 = gen_highpart (SImode, set_dest);
2889 dest2 = gen_lowpart (SImode, set_dest);
2890 src1 = gen_highpart (SImode, set_src);
2891 src2 = gen_lowpart (SImode, set_src);
2893 /* Now emit using the real source and destination we found, swapping
2894 the order if we detect overlap. */
2895 if (reg_overlap_mentioned_p (dest1, src2))
2897 emit_insn (gen_movsi (dest2, src2));
2898 emit_insn (gen_movsi (dest1, src1));
2902 emit_insn (gen_movsi (dest1, src1));
2903 emit_insn (gen_movsi (dest2, src2));
2908 ;; Now handle the cases of memory moves from/to non-even
2909 ;; DI mode register pairs.
2911 [(set (match_operand:DI 0 "register_operand" "")
2912 (match_operand:DI 1 "memory_operand" ""))]
2915 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2916 [(clobber (const_int 0))]
2919 rtx word0 = adjust_address (operands[1], SImode, 0);
2920 rtx word1 = adjust_address (operands[1], SImode, 4);
2921 rtx high_part = gen_highpart (SImode, operands[0]);
2922 rtx low_part = gen_lowpart (SImode, operands[0]);
2924 if (reg_overlap_mentioned_p (high_part, word1))
2926 emit_insn (gen_movsi (low_part, word1));
2927 emit_insn (gen_movsi (high_part, word0));
2931 emit_insn (gen_movsi (high_part, word0));
2932 emit_insn (gen_movsi (low_part, word1));
2938 [(set (match_operand:DI 0 "memory_operand" "")
2939 (match_operand:DI 1 "register_operand" ""))]
2942 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2943 [(clobber (const_int 0))]
2946 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2947 gen_highpart (SImode, operands[1])));
2948 emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2949 gen_lowpart (SImode, operands[1])));
2954 ;; Floating point move insns
2956 (define_insn "*movsf_insn_novis"
2957 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2958 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2959 "(TARGET_FPU && ! TARGET_VIS)
2960 && (register_operand (operands[0], SFmode)
2961 || register_operand (operands[1], SFmode)
2962 || fp_zero_operand (operands[1], SFmode))"
2965 if (GET_CODE (operands[1]) == CONST_DOUBLE
2966 && (which_alternative == 2
2967 || which_alternative == 3
2968 || which_alternative == 4))
2973 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2974 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2975 operands[1] = GEN_INT (i);
2978 switch (which_alternative)
2981 return \"fmovs\\t%1, %0\";
2983 return \"clr\\t%0\";
2985 return \"sethi\\t%%hi(%a1), %0\";
2987 return \"mov\\t%1, %0\";
2992 return \"ld\\t%1, %0\";
2995 return \"st\\t%r1, %0\";
3000 [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")
3001 (set_attr "length" "1")])
3003 (define_insn "*movsf_insn_vis"
3004 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3005 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3006 "(TARGET_FPU && TARGET_VIS)
3007 && (register_operand (operands[0], SFmode)
3008 || register_operand (operands[1], SFmode)
3009 || fp_zero_operand (operands[1], SFmode))"
3012 if (GET_CODE (operands[1]) == CONST_DOUBLE
3013 && (which_alternative == 3
3014 || which_alternative == 4
3015 || which_alternative == 5))
3020 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3021 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3022 operands[1] = GEN_INT (i);
3025 switch (which_alternative)
3028 return \"fmovs\\t%1, %0\";
3030 return \"fzeros\\t%0\";
3032 return \"clr\\t%0\";
3034 return \"sethi\\t%%hi(%a1), %0\";
3036 return \"mov\\t%1, %0\";
3041 return \"ld\\t%1, %0\";
3044 return \"st\\t%r1, %0\";
3049 [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")
3050 (set_attr "length" "1")])
3052 ;; Exactly the same as above, except that all `f' cases are deleted.
3053 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3056 (define_insn "*movsf_no_f_insn"
3057 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
3058 (match_operand:SF 1 "input_operand" "G,Q,rR,S,m,rG"))]
3060 && (register_operand (operands[0], SFmode)
3061 || register_operand (operands[1], SFmode)
3062 || fp_zero_operand (operands[1], SFmode))"
3065 if (GET_CODE (operands[1]) == CONST_DOUBLE
3066 && (which_alternative == 1
3067 || which_alternative == 2
3068 || which_alternative == 3))
3073 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3074 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3075 operands[1] = GEN_INT (i);
3078 switch (which_alternative)
3081 return \"clr\\t%0\";
3083 return \"sethi\\t%%hi(%a1), %0\";
3085 return \"mov\\t%1, %0\";
3089 return \"ld\\t%1, %0\";
3091 return \"st\\t%r1, %0\";
3096 [(set_attr "type" "*,*,*,*,load,store")
3097 (set_attr "length" "1")])
3099 (define_insn "*movsf_lo_sum"
3100 [(set (match_operand:SF 0 "register_operand" "=r")
3101 (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
3102 (match_operand:SF 2 "const_double_operand" "S")))]
3103 "fp_high_losum_p (operands[2])"
3109 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3110 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3111 operands[2] = GEN_INT (i);
3112 return \"or\\t%1, %%lo(%a2), %0\";
3114 [(set_attr "type" "ialu")
3115 (set_attr "length" "1")])
3117 (define_insn "*movsf_high"
3118 [(set (match_operand:SF 0 "register_operand" "=r")
3119 (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
3120 "fp_high_losum_p (operands[1])"
3126 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3127 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3128 operands[1] = GEN_INT (i);
3129 return \"sethi\\t%%hi(%1), %0\";
3131 [(set_attr "length" "1")])
3134 [(set (match_operand:SF 0 "register_operand" "")
3135 (match_operand:SF 1 "const_double_operand" ""))]
3136 "fp_high_losum_p (operands[1])
3137 && (GET_CODE (operands[0]) == REG
3138 && REGNO (operands[0]) < 32)"
3139 [(set (match_dup 0) (high:SF (match_dup 1)))
3140 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3142 (define_expand "movsf"
3143 [(set (match_operand:SF 0 "general_operand" "")
3144 (match_operand:SF 1 "general_operand" ""))]
3148 /* Force SFmode constants into memory. */
3149 if (GET_CODE (operands[0]) == REG
3150 && CONSTANT_P (operands[1]))
3152 /* emit_group_store will send such bogosity to us when it is
3153 not storing directly into memory. So fix this up to avoid
3154 crashes in output_constant_pool. */
3155 if (operands [1] == const0_rtx)
3156 operands[1] = CONST0_RTX (SFmode);
3158 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3161 /* We are able to build any SF constant in integer registers
3162 with at most 2 instructions. */
3163 if (REGNO (operands[0]) < 32)
3166 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3170 /* Handle sets of MEM first. */
3171 if (GET_CODE (operands[0]) == MEM)
3173 if (register_operand (operands[1], SFmode)
3174 || fp_zero_operand (operands[1], SFmode))
3177 if (! reload_in_progress)
3179 operands[0] = validize_mem (operands[0]);
3180 operands[1] = force_reg (SFmode, operands[1]);
3184 /* Fixup PIC cases. */
3187 if (CONSTANT_P (operands[1])
3188 && pic_address_needs_scratch (operands[1]))
3189 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3191 if (symbolic_operand (operands[1], SFmode))
3193 operands[1] = legitimize_pic_address (operands[1],
3195 (reload_in_progress ?
3205 (define_expand "movdf"
3206 [(set (match_operand:DF 0 "general_operand" "")
3207 (match_operand:DF 1 "general_operand" ""))]
3211 /* Force DFmode constants into memory. */
3212 if (GET_CODE (operands[0]) == REG
3213 && CONSTANT_P (operands[1]))
3215 /* emit_group_store will send such bogosity to us when it is
3216 not storing directly into memory. So fix this up to avoid
3217 crashes in output_constant_pool. */
3218 if (operands [1] == const0_rtx)
3219 operands[1] = CONST0_RTX (DFmode);
3221 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3222 && fp_zero_operand (operands[1], DFmode))
3225 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3229 /* Handle MEM cases first. */
3230 if (GET_CODE (operands[0]) == MEM)
3232 if (register_operand (operands[1], DFmode)
3233 || fp_zero_operand (operands[1], DFmode))
3236 if (! reload_in_progress)
3238 operands[0] = validize_mem (operands[0]);
3239 operands[1] = force_reg (DFmode, operands[1]);
3243 /* Fixup PIC cases. */
3246 if (CONSTANT_P (operands[1])
3247 && pic_address_needs_scratch (operands[1]))
3248 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3250 if (symbolic_operand (operands[1], DFmode))
3252 operands[1] = legitimize_pic_address (operands[1],
3254 (reload_in_progress ?
3264 ;; Be careful, fmovd does not exist when !v9.
3265 (define_insn "*movdf_insn_sp32"
3266 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3267 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3270 && (register_operand (operands[0], DFmode)
3271 || register_operand (operands[1], DFmode)
3272 || fp_zero_operand (operands[1], DFmode))"
3284 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3285 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3287 (define_insn "*movdf_no_e_insn_sp32"
3288 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3289 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3293 && (register_operand (operands[0], DFmode)
3294 || register_operand (operands[1], DFmode)
3295 || fp_zero_operand (operands[1], DFmode))"
3302 [(set_attr "type" "load,store,*,*,*")
3303 (set_attr "length" "1,1,2,2,2")])
3305 (define_insn "*movdf_no_e_insn_v9_sp32"
3306 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3307 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3311 && (register_operand (operands[0], DFmode)
3312 || register_operand (operands[1], DFmode)
3313 || fp_zero_operand (operands[1], DFmode))"
3320 [(set_attr "type" "load,store,store,*,*")
3321 (set_attr "length" "1,1,1,2,2")])
3323 ;; We have available v9 double floats but not 64-bit
3324 ;; integer registers and no VIS.
3325 (define_insn "*movdf_insn_v9only_novis"
3326 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3327 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3332 && (register_operand (operands[0], DFmode)
3333 || register_operand (operands[1], DFmode)
3334 || fp_zero_operand (operands[1], DFmode))"
3345 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3346 (set_attr "length" "1,1,1,1,1,1,2,2,2")])
3348 ;; We have available v9 double floats but not 64-bit
3349 ;; integer registers but we have VIS.
3350 (define_insn "*movdf_insn_v9only_vis"
3351 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3352 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3356 && (register_operand (operands[0], DFmode)
3357 || register_operand (operands[1], DFmode)
3358 || fp_zero_operand (operands[1], DFmode))"
3370 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3371 (set_attr "length" "1,1,1,1,1,1,1,2,2,2")])
3373 ;; We have available both v9 double floats and 64-bit
3374 ;; integer registers. No VIS though.
3375 (define_insn "*movdf_insn_sp64_novis"
3376 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3377 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3381 && (register_operand (operands[0], DFmode)
3382 || register_operand (operands[1], DFmode)
3383 || fp_zero_operand (operands[1], DFmode))"
3392 [(set_attr "type" "fpmove,load,store,*,load,store,*")
3393 (set_attr "length" "1,1,1,1,1,1,2")])
3395 ;; We have available both v9 double floats and 64-bit
3396 ;; integer registers. And we have VIS.
3397 (define_insn "*movdf_insn_sp64_vis"
3398 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3399 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3403 && (register_operand (operands[0], DFmode)
3404 || register_operand (operands[1], DFmode)
3405 || fp_zero_operand (operands[1], DFmode))"
3415 [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
3416 (set_attr "length" "1,1,1,1,1,1,1,2")])
3418 (define_insn "*movdf_no_e_insn_sp64"
3419 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3420 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3423 && (register_operand (operands[0], DFmode)
3424 || register_operand (operands[1], DFmode)
3425 || fp_zero_operand (operands[1], DFmode))"
3430 [(set_attr "type" "*,load,store")
3431 (set_attr "length" "1")])
3434 [(set (match_operand:DF 0 "register_operand" "")
3435 (match_operand:DF 1 "const_double_operand" ""))]
3437 && (GET_CODE (operands[0]) == REG
3438 && REGNO (operands[0]) < 32)
3439 && ! fp_zero_operand(operands[1], DFmode)
3440 && reload_completed"
3441 [(clobber (const_int 0))]
3447 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3448 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3449 if (GET_CODE (operands[0]) == SUBREG)
3450 operands[0] = alter_subreg (operands[0]);
3451 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3455 #if HOST_BITS_PER_WIDE_INT == 64
3458 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3459 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3460 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3462 emit_insn (gen_movdi (operands[0],
3463 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3469 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3472 /* Slick... but this trick loses if this subreg constant part
3473 can be done in one insn. */
3475 && !(SPARC_SETHI_P (l[0])
3476 || SPARC_SIMM13_P (l[0])))
3478 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3479 gen_highpart (SImode, operands[0])));
3483 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3490 ;; Ok, now the splits to handle all the multi insn and
3491 ;; mis-aligned memory address cases.
3492 ;; In these splits please take note that we must be
3493 ;; careful when V9 but not ARCH64 because the integer
3494 ;; register DFmode cases must be handled.
3496 [(set (match_operand:DF 0 "register_operand" "")
3497 (match_operand:DF 1 "register_operand" ""))]
3500 && ((GET_CODE (operands[0]) == REG
3501 && REGNO (operands[0]) < 32)
3502 || (GET_CODE (operands[0]) == SUBREG
3503 && GET_CODE (SUBREG_REG (operands[0])) == REG
3504 && REGNO (SUBREG_REG (operands[0])) < 32))))
3505 && reload_completed"
3506 [(clobber (const_int 0))]
3509 rtx set_dest = operands[0];
3510 rtx set_src = operands[1];
3514 if (GET_CODE (set_dest) == SUBREG)
3515 set_dest = alter_subreg (set_dest);
3516 if (GET_CODE (set_src) == SUBREG)
3517 set_src = alter_subreg (set_src);
3519 dest1 = gen_highpart (SFmode, set_dest);
3520 dest2 = gen_lowpart (SFmode, set_dest);
3521 src1 = gen_highpart (SFmode, set_src);
3522 src2 = gen_lowpart (SFmode, set_src);
3524 /* Now emit using the real source and destination we found, swapping
3525 the order if we detect overlap. */
3526 if (reg_overlap_mentioned_p (dest1, src2))
3528 emit_insn (gen_movsf (dest2, src2));
3529 emit_insn (gen_movsf (dest1, src1));
3533 emit_insn (gen_movsf (dest1, src1));
3534 emit_insn (gen_movsf (dest2, src2));
3540 [(set (match_operand:DF 0 "register_operand" "")
3541 (match_operand:DF 1 "memory_operand" ""))]
3544 && (((REGNO (operands[0]) % 2) != 0)
3545 || ! mem_min_alignment (operands[1], 8))
3546 && offsettable_memref_p (operands[1])"
3547 [(clobber (const_int 0))]
3550 rtx word0 = adjust_address (operands[1], SFmode, 0);
3551 rtx word1 = adjust_address (operands[1], SFmode, 4);
3553 if (GET_CODE (operands[0]) == SUBREG)
3554 operands[0] = alter_subreg (operands[0]);
3556 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3558 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3560 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3565 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3567 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3574 [(set (match_operand:DF 0 "memory_operand" "")
3575 (match_operand:DF 1 "register_operand" ""))]
3578 && (((REGNO (operands[1]) % 2) != 0)
3579 || ! mem_min_alignment (operands[0], 8))
3580 && offsettable_memref_p (operands[0])"
3581 [(clobber (const_int 0))]
3584 rtx word0 = adjust_address (operands[0], SFmode, 0);
3585 rtx word1 = adjust_address (operands[0], SFmode, 4);
3587 if (GET_CODE (operands[1]) == SUBREG)
3588 operands[1] = alter_subreg (operands[1]);
3589 emit_insn (gen_movsf (word0,
3590 gen_highpart (SFmode, operands[1])));
3591 emit_insn (gen_movsf (word1,
3592 gen_lowpart (SFmode, operands[1])));
3597 [(set (match_operand:DF 0 "memory_operand" "")
3598 (match_operand:DF 1 "fp_zero_operand" ""))]
3602 && ! mem_min_alignment (operands[0], 8)))
3603 && offsettable_memref_p (operands[0])"
3604 [(clobber (const_int 0))]
3609 dest1 = adjust_address (operands[0], SFmode, 0);
3610 dest2 = adjust_address (operands[0], SFmode, 4);
3612 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3613 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3618 [(set (match_operand:DF 0 "register_operand" "")
3619 (match_operand:DF 1 "fp_zero_operand" ""))]
3622 && ((GET_CODE (operands[0]) == REG
3623 && REGNO (operands[0]) < 32)
3624 || (GET_CODE (operands[0]) == SUBREG
3625 && GET_CODE (SUBREG_REG (operands[0])) == REG
3626 && REGNO (SUBREG_REG (operands[0])) < 32))"
3627 [(clobber (const_int 0))]
3630 rtx set_dest = operands[0];
3633 if (GET_CODE (set_dest) == SUBREG)
3634 set_dest = alter_subreg (set_dest);
3635 dest1 = gen_highpart (SFmode, set_dest);
3636 dest2 = gen_lowpart (SFmode, set_dest);
3637 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3638 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3642 (define_expand "movtf"
3643 [(set (match_operand:TF 0 "general_operand" "")
3644 (match_operand:TF 1 "general_operand" ""))]
3648 /* Force TFmode constants into memory. */
3649 if (GET_CODE (operands[0]) == REG
3650 && CONSTANT_P (operands[1]))
3652 /* emit_group_store will send such bogosity to us when it is
3653 not storing directly into memory. So fix this up to avoid
3654 crashes in output_constant_pool. */
3655 if (operands [1] == const0_rtx)
3656 operands[1] = CONST0_RTX (TFmode);
3658 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3661 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3665 /* Handle MEM cases first, note that only v9 guarentees
3666 full 16-byte alignment for quads. */
3667 if (GET_CODE (operands[0]) == MEM)
3669 if (register_operand (operands[1], TFmode)
3670 || fp_zero_operand (operands[1], TFmode))
3673 if (! reload_in_progress)
3675 operands[0] = validize_mem (operands[0]);
3676 operands[1] = force_reg (TFmode, operands[1]);
3680 /* Fixup PIC cases. */
3683 if (CONSTANT_P (operands[1])
3684 && pic_address_needs_scratch (operands[1]))
3685 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3687 if (symbolic_operand (operands[1], TFmode))
3689 operands[1] = legitimize_pic_address (operands[1],
3691 (reload_in_progress ?
3701 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3702 ;; we must split them all. :-(
3703 (define_insn "*movtf_insn_sp32"
3704 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3705 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3709 && (register_operand (operands[0], TFmode)
3710 || register_operand (operands[1], TFmode)
3711 || fp_zero_operand (operands[1], TFmode))"
3713 [(set_attr "length" "4")])
3715 (define_insn "*movtf_insn_vis_sp32"
3716 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3717 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3721 && (register_operand (operands[0], TFmode)
3722 || register_operand (operands[1], TFmode)
3723 || fp_zero_operand (operands[1], TFmode))"
3725 [(set_attr "length" "4")])
3727 ;; Exactly the same as above, except that all `e' cases are deleted.
3728 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3731 (define_insn "*movtf_no_e_insn_sp32"
3732 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3733 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3736 && (register_operand (operands[0], TFmode)
3737 || register_operand (operands[1], TFmode)
3738 || fp_zero_operand (operands[1], TFmode))"
3740 [(set_attr "length" "4")])
3742 ;; Now handle the float reg cases directly when arch64,
3743 ;; hard_quad, and proper reg number alignment are all true.
3744 (define_insn "*movtf_insn_hq_sp64"
3745 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3746 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3751 && (register_operand (operands[0], TFmode)
3752 || register_operand (operands[1], TFmode)
3753 || fp_zero_operand (operands[1], TFmode))"
3760 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3761 (set_attr "length" "1,1,1,2,2")])
3763 (define_insn "*movtf_insn_hq_vis_sp64"
3764 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3765 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3770 && (register_operand (operands[0], TFmode)
3771 || register_operand (operands[1], TFmode)
3772 || fp_zero_operand (operands[1], TFmode))"
3780 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3781 (set_attr "length" "1,1,1,2,2,2")])
3783 ;; Now we allow the integer register cases even when
3784 ;; only arch64 is true.
3785 (define_insn "*movtf_insn_sp64"
3786 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3787 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3791 && ! TARGET_HARD_QUAD
3792 && (register_operand (operands[0], TFmode)
3793 || register_operand (operands[1], TFmode)
3794 || fp_zero_operand (operands[1], TFmode))"
3796 [(set_attr "length" "2")])
3798 (define_insn "*movtf_insn_vis_sp64"
3799 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3800 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3804 && ! TARGET_HARD_QUAD
3805 && (register_operand (operands[0], TFmode)
3806 || register_operand (operands[1], TFmode)
3807 || fp_zero_operand (operands[1], TFmode))"
3809 [(set_attr "length" "2")])
3811 (define_insn "*movtf_no_e_insn_sp64"
3812 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3813 (match_operand:TF 1 "input_operand" "orG,rG"))]
3816 && (register_operand (operands[0], TFmode)
3817 || register_operand (operands[1], TFmode)
3818 || fp_zero_operand (operands[1], TFmode))"
3820 [(set_attr "length" "2")])
3822 ;; Now all the splits to handle multi-insn TF mode moves.
3824 [(set (match_operand:TF 0 "register_operand" "")
3825 (match_operand:TF 1 "register_operand" ""))]
3829 && ! TARGET_HARD_QUAD))"
3830 [(clobber (const_int 0))]
3833 rtx set_dest = operands[0];
3834 rtx set_src = operands[1];
3838 if (GET_CODE (set_dest) == SUBREG)
3839 set_dest = alter_subreg (set_dest);
3840 if (GET_CODE (set_src) == SUBREG)
3841 set_src = alter_subreg (set_src);
3843 dest1 = gen_df_reg (set_dest, 0);
3844 dest2 = gen_df_reg (set_dest, 1);
3845 src1 = gen_df_reg (set_src, 0);
3846 src2 = gen_df_reg (set_src, 1);
3848 /* Now emit using the real source and destination we found, swapping
3849 the order if we detect overlap. */
3850 if (reg_overlap_mentioned_p (dest1, src2))
3852 emit_insn (gen_movdf (dest2, src2));
3853 emit_insn (gen_movdf (dest1, src1));
3857 emit_insn (gen_movdf (dest1, src1));
3858 emit_insn (gen_movdf (dest2, src2));
3864 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3865 (match_operand:TF 1 "fp_zero_operand" ""))]
3867 [(clobber (const_int 0))]
3870 rtx set_dest = operands[0];
3873 switch (GET_CODE (set_dest))
3876 set_dest = alter_subreg (set_dest);
3879 dest1 = gen_df_reg (set_dest, 0);
3880 dest2 = gen_df_reg (set_dest, 1);
3883 dest1 = adjust_address (set_dest, DFmode, 0);
3884 dest2 = adjust_address (set_dest, DFmode, 8);
3890 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3891 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3896 [(set (match_operand:TF 0 "register_operand" "")
3897 (match_operand:TF 1 "memory_operand" ""))]
3899 && offsettable_memref_p (operands[1]))"
3900 [(clobber (const_int 0))]
3903 rtx word0 = adjust_address (operands[1], DFmode, 0);
3904 rtx word1 = adjust_address (operands[1], DFmode, 8);
3905 rtx set_dest, dest1, dest2;
3907 set_dest = operands[0];
3908 if (GET_CODE (set_dest) == SUBREG)
3909 set_dest = alter_subreg (set_dest);
3911 dest1 = gen_df_reg (set_dest, 0);
3912 dest2 = gen_df_reg (set_dest, 1);
3914 /* Now output, ordering such that we don't clobber any registers
3915 mentioned in the address. */
3916 if (reg_overlap_mentioned_p (dest1, word1))
3919 emit_insn (gen_movdf (dest2, word1));
3920 emit_insn (gen_movdf (dest1, word0));
3924 emit_insn (gen_movdf (dest1, word0));
3925 emit_insn (gen_movdf (dest2, word1));
3931 [(set (match_operand:TF 0 "memory_operand" "")
3932 (match_operand:TF 1 "register_operand" ""))]
3934 && offsettable_memref_p (operands[0]))"
3935 [(clobber (const_int 0))]
3938 rtx set_src = operands[1];
3939 if (GET_CODE (set_src) == SUBREG)
3940 set_src = alter_subreg (set_src);
3942 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3943 gen_df_reg (set_src, 0)));
3944 emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3945 gen_df_reg (set_src, 1)));
3949 ;; Sparc V9 conditional move instructions.
3951 ;; We can handle larger constants here for some flavors, but for now we keep
3952 ;; it simple and only allow those constants supported by all flavours.
3953 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3954 ;; 3 contains the constant if one is present, but we handle either for
3955 ;; generality (sparc.c puts a constant in operand 2).
3957 (define_expand "movqicc"
3958 [(set (match_operand:QI 0 "register_operand" "")
3959 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3960 (match_operand:QI 2 "arith10_operand" "")
3961 (match_operand:QI 3 "arith10_operand" "")))]
3965 enum rtx_code code = GET_CODE (operands[1]);
3967 if (GET_MODE (sparc_compare_op0) == DImode
3971 if (sparc_compare_op1 == const0_rtx
3972 && GET_CODE (sparc_compare_op0) == REG
3973 && GET_MODE (sparc_compare_op0) == DImode
3974 && v9_regcmp_p (code))
3976 operands[1] = gen_rtx_fmt_ee (code, DImode,
3977 sparc_compare_op0, sparc_compare_op1);
3981 rtx cc_reg = gen_compare_reg (code,
3982 sparc_compare_op0, sparc_compare_op1);
3983 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3987 (define_expand "movhicc"
3988 [(set (match_operand:HI 0 "register_operand" "")
3989 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3990 (match_operand:HI 2 "arith10_operand" "")
3991 (match_operand:HI 3 "arith10_operand" "")))]
3995 enum rtx_code code = GET_CODE (operands[1]);
3997 if (GET_MODE (sparc_compare_op0) == DImode
4001 if (sparc_compare_op1 == const0_rtx
4002 && GET_CODE (sparc_compare_op0) == REG
4003 && GET_MODE (sparc_compare_op0) == DImode
4004 && v9_regcmp_p (code))
4006 operands[1] = gen_rtx_fmt_ee (code, DImode,
4007 sparc_compare_op0, sparc_compare_op1);
4011 rtx cc_reg = gen_compare_reg (code,
4012 sparc_compare_op0, sparc_compare_op1);
4013 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4017 (define_expand "movsicc"
4018 [(set (match_operand:SI 0 "register_operand" "")
4019 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4020 (match_operand:SI 2 "arith10_operand" "")
4021 (match_operand:SI 3 "arith10_operand" "")))]
4025 enum rtx_code code = GET_CODE (operands[1]);
4026 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4028 if (sparc_compare_op1 == const0_rtx
4029 && GET_CODE (sparc_compare_op0) == REG
4030 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4032 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4033 sparc_compare_op0, sparc_compare_op1);
4037 rtx cc_reg = gen_compare_reg (code,
4038 sparc_compare_op0, sparc_compare_op1);
4039 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4040 cc_reg, const0_rtx);
4044 (define_expand "movdicc"
4045 [(set (match_operand:DI 0 "register_operand" "")
4046 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4047 (match_operand:DI 2 "arith10_double_operand" "")
4048 (match_operand:DI 3 "arith10_double_operand" "")))]
4052 enum rtx_code code = GET_CODE (operands[1]);
4054 if (sparc_compare_op1 == const0_rtx
4055 && GET_CODE (sparc_compare_op0) == REG
4056 && GET_MODE (sparc_compare_op0) == DImode
4057 && v9_regcmp_p (code))
4059 operands[1] = gen_rtx_fmt_ee (code, DImode,
4060 sparc_compare_op0, sparc_compare_op1);
4064 rtx cc_reg = gen_compare_reg (code,
4065 sparc_compare_op0, sparc_compare_op1);
4066 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4067 cc_reg, const0_rtx);
4071 (define_expand "movsfcc"
4072 [(set (match_operand:SF 0 "register_operand" "")
4073 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4074 (match_operand:SF 2 "register_operand" "")
4075 (match_operand:SF 3 "register_operand" "")))]
4076 "TARGET_V9 && TARGET_FPU"
4079 enum rtx_code code = GET_CODE (operands[1]);
4081 if (GET_MODE (sparc_compare_op0) == DImode
4085 if (sparc_compare_op1 == const0_rtx
4086 && GET_CODE (sparc_compare_op0) == REG
4087 && GET_MODE (sparc_compare_op0) == DImode
4088 && v9_regcmp_p (code))
4090 operands[1] = gen_rtx_fmt_ee (code, DImode,
4091 sparc_compare_op0, sparc_compare_op1);
4095 rtx cc_reg = gen_compare_reg (code,
4096 sparc_compare_op0, sparc_compare_op1);
4097 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4101 (define_expand "movdfcc"
4102 [(set (match_operand:DF 0 "register_operand" "")
4103 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4104 (match_operand:DF 2 "register_operand" "")
4105 (match_operand:DF 3 "register_operand" "")))]
4106 "TARGET_V9 && TARGET_FPU"
4109 enum rtx_code code = GET_CODE (operands[1]);
4111 if (GET_MODE (sparc_compare_op0) == DImode
4115 if (sparc_compare_op1 == const0_rtx
4116 && GET_CODE (sparc_compare_op0) == REG
4117 && GET_MODE (sparc_compare_op0) == DImode
4118 && v9_regcmp_p (code))
4120 operands[1] = gen_rtx_fmt_ee (code, DImode,
4121 sparc_compare_op0, sparc_compare_op1);
4125 rtx cc_reg = gen_compare_reg (code,
4126 sparc_compare_op0, sparc_compare_op1);
4127 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4131 (define_expand "movtfcc"
4132 [(set (match_operand:TF 0 "register_operand" "")
4133 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4134 (match_operand:TF 2 "register_operand" "")
4135 (match_operand:TF 3 "register_operand" "")))]
4136 "TARGET_V9 && TARGET_FPU"
4139 enum rtx_code code = GET_CODE (operands[1]);
4141 if (GET_MODE (sparc_compare_op0) == DImode
4145 if (sparc_compare_op1 == const0_rtx
4146 && GET_CODE (sparc_compare_op0) == REG
4147 && GET_MODE (sparc_compare_op0) == DImode
4148 && v9_regcmp_p (code))
4150 operands[1] = gen_rtx_fmt_ee (code, DImode,
4151 sparc_compare_op0, sparc_compare_op1);
4155 rtx cc_reg = gen_compare_reg (code,
4156 sparc_compare_op0, sparc_compare_op1);
4157 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4161 ;; Conditional move define_insns.
4163 (define_insn "*movqi_cc_sp64"
4164 [(set (match_operand:QI 0 "register_operand" "=r,r")
4165 (if_then_else:QI (match_operator 1 "comparison_operator"
4166 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4168 (match_operand:QI 3 "arith11_operand" "rL,0")
4169 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4172 mov%C1\\t%x2, %3, %0
4173 mov%c1\\t%x2, %4, %0"
4174 [(set_attr "type" "cmove")
4175 (set_attr "length" "1")])
4177 (define_insn "*movhi_cc_sp64"
4178 [(set (match_operand:HI 0 "register_operand" "=r,r")
4179 (if_then_else:HI (match_operator 1 "comparison_operator"
4180 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4182 (match_operand:HI 3 "arith11_operand" "rL,0")
4183 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4186 mov%C1\\t%x2, %3, %0
4187 mov%c1\\t%x2, %4, %0"
4188 [(set_attr "type" "cmove")
4189 (set_attr "length" "1")])
4191 (define_insn "*movsi_cc_sp64"
4192 [(set (match_operand:SI 0 "register_operand" "=r,r")
4193 (if_then_else:SI (match_operator 1 "comparison_operator"
4194 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4196 (match_operand:SI 3 "arith11_operand" "rL,0")
4197 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4200 mov%C1\\t%x2, %3, %0
4201 mov%c1\\t%x2, %4, %0"
4202 [(set_attr "type" "cmove")
4203 (set_attr "length" "1")])
4205 ;; ??? The constraints of operands 3,4 need work.
4206 (define_insn "*movdi_cc_sp64"
4207 [(set (match_operand:DI 0 "register_operand" "=r,r")
4208 (if_then_else:DI (match_operator 1 "comparison_operator"
4209 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4211 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4212 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4215 mov%C1\\t%x2, %3, %0
4216 mov%c1\\t%x2, %4, %0"
4217 [(set_attr "type" "cmove")
4218 (set_attr "length" "1")])
4220 (define_insn "*movdi_cc_sp64_trunc"
4221 [(set (match_operand:SI 0 "register_operand" "=r,r")
4222 (if_then_else:SI (match_operator 1 "comparison_operator"
4223 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4225 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4226 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4229 mov%C1\\t%x2, %3, %0
4230 mov%c1\\t%x2, %4, %0"
4231 [(set_attr "type" "cmove")
4232 (set_attr "length" "1")])
4234 (define_insn "*movsf_cc_sp64"
4235 [(set (match_operand:SF 0 "register_operand" "=f,f")
4236 (if_then_else:SF (match_operator 1 "comparison_operator"
4237 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4239 (match_operand:SF 3 "register_operand" "f,0")
4240 (match_operand:SF 4 "register_operand" "0,f")))]
4241 "TARGET_V9 && TARGET_FPU"
4243 fmovs%C1\\t%x2, %3, %0
4244 fmovs%c1\\t%x2, %4, %0"
4245 [(set_attr "type" "fpcmove")
4246 (set_attr "length" "1")])
4248 (define_insn "movdf_cc_sp64"
4249 [(set (match_operand:DF 0 "register_operand" "=e,e")
4250 (if_then_else:DF (match_operator 1 "comparison_operator"
4251 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4253 (match_operand:DF 3 "register_operand" "e,0")
4254 (match_operand:DF 4 "register_operand" "0,e")))]
4255 "TARGET_V9 && TARGET_FPU"
4257 fmovd%C1\\t%x2, %3, %0
4258 fmovd%c1\\t%x2, %4, %0"
4259 [(set_attr "type" "fpcmove")
4260 (set_attr "length" "1")])
4262 (define_insn "*movtf_cc_hq_sp64"
4263 [(set (match_operand:TF 0 "register_operand" "=e,e")
4264 (if_then_else:TF (match_operator 1 "comparison_operator"
4265 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4267 (match_operand:TF 3 "register_operand" "e,0")
4268 (match_operand:TF 4 "register_operand" "0,e")))]
4269 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4271 fmovq%C1\\t%x2, %3, %0
4272 fmovq%c1\\t%x2, %4, %0"
4273 [(set_attr "type" "fpcmove")
4274 (set_attr "length" "1")])
4276 (define_insn "*movtf_cc_sp64"
4277 [(set (match_operand:TF 0 "register_operand" "=e,e")
4278 (if_then_else:TF (match_operator 1 "comparison_operator"
4279 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4281 (match_operand:TF 3 "register_operand" "e,0")
4282 (match_operand:TF 4 "register_operand" "0,e")))]
4283 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4285 [(set_attr "type" "fpcmove")
4286 (set_attr "length" "2")])
4289 [(set (match_operand:TF 0 "register_operand" "")
4290 (if_then_else:TF (match_operator 1 "comparison_operator"
4291 [(match_operand 2 "icc_or_fcc_reg_operand" "")
4293 (match_operand:TF 3 "register_operand" "")
4294 (match_operand:TF 4 "register_operand" "")))]
4295 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4296 [(clobber (const_int 0))]
4299 rtx set_dest = operands[0];
4300 rtx set_srca = operands[3];
4301 rtx set_srcb = operands[4];
4302 int third = rtx_equal_p (set_dest, set_srca);
4304 rtx srca1, srca2, srcb1, srcb2;
4306 if (GET_CODE (set_dest) == SUBREG)
4307 set_dest = alter_subreg (set_dest);
4308 if (GET_CODE (set_srca) == SUBREG)
4309 set_srca = alter_subreg (set_srca);
4310 if (GET_CODE (set_srcb) == SUBREG)
4311 set_srcb = alter_subreg (set_srcb);
4313 dest1 = gen_df_reg (set_dest, 0);
4314 dest2 = gen_df_reg (set_dest, 1);
4315 srca1 = gen_df_reg (set_srca, 0);
4316 srca2 = gen_df_reg (set_srca, 1);
4317 srcb1 = gen_df_reg (set_srcb, 0);
4318 srcb2 = gen_df_reg (set_srcb, 1);
4320 /* Now emit using the real source and destination we found, swapping
4321 the order if we detect overlap. */
4322 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4323 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4325 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4326 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4330 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4331 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4336 (define_insn "*movqi_cc_reg_sp64"
4337 [(set (match_operand:QI 0 "register_operand" "=r,r")
4338 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4339 [(match_operand:DI 2 "register_operand" "r,r")
4341 (match_operand:QI 3 "arith10_operand" "rM,0")
4342 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4345 movr%D1\\t%2, %r3, %0
4346 movr%d1\\t%2, %r4, %0"
4347 [(set_attr "type" "cmove")
4348 (set_attr "length" "1")])
4350 (define_insn "*movhi_cc_reg_sp64"
4351 [(set (match_operand:HI 0 "register_operand" "=r,r")
4352 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4353 [(match_operand:DI 2 "register_operand" "r,r")
4355 (match_operand:HI 3 "arith10_operand" "rM,0")
4356 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4359 movr%D1\\t%2, %r3, %0
4360 movr%d1\\t%2, %r4, %0"
4361 [(set_attr "type" "cmove")
4362 (set_attr "length" "1")])
4364 (define_insn "*movsi_cc_reg_sp64"
4365 [(set (match_operand:SI 0 "register_operand" "=r,r")
4366 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4367 [(match_operand:DI 2 "register_operand" "r,r")
4369 (match_operand:SI 3 "arith10_operand" "rM,0")
4370 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4373 movr%D1\\t%2, %r3, %0
4374 movr%d1\\t%2, %r4, %0"
4375 [(set_attr "type" "cmove")
4376 (set_attr "length" "1")])
4378 ;; ??? The constraints of operands 3,4 need work.
4379 (define_insn "*movdi_cc_reg_sp64"
4380 [(set (match_operand:DI 0 "register_operand" "=r,r")
4381 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4382 [(match_operand:DI 2 "register_operand" "r,r")
4384 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4385 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4388 movr%D1\\t%2, %r3, %0
4389 movr%d1\\t%2, %r4, %0"
4390 [(set_attr "type" "cmove")
4391 (set_attr "length" "1")])
4393 (define_insn "*movdi_cc_reg_sp64_trunc"
4394 [(set (match_operand:SI 0 "register_operand" "=r,r")
4395 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4396 [(match_operand:DI 2 "register_operand" "r,r")
4398 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4399 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4402 movr%D1\\t%2, %r3, %0
4403 movr%d1\\t%2, %r4, %0"
4404 [(set_attr "type" "cmove")
4405 (set_attr "length" "1")])
4407 (define_insn "*movsf_cc_reg_sp64"
4408 [(set (match_operand:SF 0 "register_operand" "=f,f")
4409 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4410 [(match_operand:DI 2 "register_operand" "r,r")
4412 (match_operand:SF 3 "register_operand" "f,0")
4413 (match_operand:SF 4 "register_operand" "0,f")))]
4414 "TARGET_ARCH64 && TARGET_FPU"
4416 fmovrs%D1\\t%2, %3, %0
4417 fmovrs%d1\\t%2, %4, %0"
4418 [(set_attr "type" "fpcmove")
4419 (set_attr "length" "1")])
4421 (define_insn "movdf_cc_reg_sp64"
4422 [(set (match_operand:DF 0 "register_operand" "=e,e")
4423 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4424 [(match_operand:DI 2 "register_operand" "r,r")
4426 (match_operand:DF 3 "register_operand" "e,0")
4427 (match_operand:DF 4 "register_operand" "0,e")))]
4428 "TARGET_ARCH64 && TARGET_FPU"
4430 fmovrd%D1\\t%2, %3, %0
4431 fmovrd%d1\\t%2, %4, %0"
4432 [(set_attr "type" "fpcmove")
4433 (set_attr "length" "1")])
4435 (define_insn "*movtf_cc_reg_hq_sp64"
4436 [(set (match_operand:TF 0 "register_operand" "=e,e")
4437 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4438 [(match_operand:DI 2 "register_operand" "r,r")
4440 (match_operand:TF 3 "register_operand" "e,0")
4441 (match_operand:TF 4 "register_operand" "0,e")))]
4442 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4444 fmovrq%D1\\t%2, %3, %0
4445 fmovrq%d1\\t%2, %4, %0"
4446 [(set_attr "type" "fpcmove")
4447 (set_attr "length" "1")])
4449 (define_insn "*movtf_cc_reg_sp64"
4450 [(set (match_operand:TF 0 "register_operand" "=e,e")
4451 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4452 [(match_operand:DI 2 "register_operand" "r,r")
4454 (match_operand:TF 3 "register_operand" "e,0")
4455 (match_operand:TF 4 "register_operand" "0,e")))]
4456 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4458 [(set_attr "type" "fpcmove")
4459 (set_attr "length" "2")])
4462 [(set (match_operand:TF 0 "register_operand" "")
4463 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4464 [(match_operand:DI 2 "register_operand" "")
4466 (match_operand:TF 3 "register_operand" "")
4467 (match_operand:TF 4 "register_operand" "")))]
4468 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4469 [(clobber (const_int 0))]
4472 rtx set_dest = operands[0];
4473 rtx set_srca = operands[3];
4474 rtx set_srcb = operands[4];
4475 int third = rtx_equal_p (set_dest, set_srca);
4477 rtx srca1, srca2, srcb1, srcb2;
4479 if (GET_CODE (set_dest) == SUBREG)
4480 set_dest = alter_subreg (set_dest);
4481 if (GET_CODE (set_srca) == SUBREG)
4482 set_srca = alter_subreg (set_srca);
4483 if (GET_CODE (set_srcb) == SUBREG)
4484 set_srcb = alter_subreg (set_srcb);
4486 dest1 = gen_df_reg (set_dest, 0);
4487 dest2 = gen_df_reg (set_dest, 1);
4488 srca1 = gen_df_reg (set_srca, 0);
4489 srca2 = gen_df_reg (set_srca, 1);
4490 srcb1 = gen_df_reg (set_srcb, 0);
4491 srcb2 = gen_df_reg (set_srcb, 1);
4493 /* Now emit using the real source and destination we found, swapping
4494 the order if we detect overlap. */
4495 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4496 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4498 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4499 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4503 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4504 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4510 ;;- zero extension instructions
4512 ;; These patterns originally accepted general_operands, however, slightly
4513 ;; better code is generated by only accepting register_operands, and then
4514 ;; letting combine generate the ldu[hb] insns.
4516 (define_expand "zero_extendhisi2"
4517 [(set (match_operand:SI 0 "register_operand" "")
4518 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4522 rtx temp = gen_reg_rtx (SImode);
4523 rtx shift_16 = GEN_INT (16);
4524 int op1_subbyte = 0;
4526 if (GET_CODE (operand1) == SUBREG)
4528 op1_subbyte = SUBREG_BYTE (operand1);
4529 op1_subbyte /= GET_MODE_SIZE (SImode);
4530 op1_subbyte *= GET_MODE_SIZE (SImode);
4531 operand1 = XEXP (operand1, 0);
4534 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4536 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4540 (define_insn "*zero_extendhisi2_insn"
4541 [(set (match_operand:SI 0 "register_operand" "=r")
4542 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4545 [(set_attr "type" "load")
4546 (set_attr "length" "1")])
4548 (define_expand "zero_extendqihi2"
4549 [(set (match_operand:HI 0 "register_operand" "")
4550 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4554 (define_insn "*zero_extendqihi2_insn"
4555 [(set (match_operand:HI 0 "register_operand" "=r,r")
4556 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4557 "GET_CODE (operands[1]) != CONST_INT"
4561 [(set_attr "type" "ialu,load")
4562 (set_attr "length" "1")])
4564 (define_expand "zero_extendqisi2"
4565 [(set (match_operand:SI 0 "register_operand" "")
4566 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4570 (define_insn "*zero_extendqisi2_insn"
4571 [(set (match_operand:SI 0 "register_operand" "=r,r")
4572 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4573 "GET_CODE (operands[1]) != CONST_INT"
4577 [(set_attr "type" "ialu,load")
4578 (set_attr "length" "1")])
4580 (define_expand "zero_extendqidi2"
4581 [(set (match_operand:DI 0 "register_operand" "")
4582 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4586 (define_insn "*zero_extendqidi2_insn"
4587 [(set (match_operand:DI 0 "register_operand" "=r,r")
4588 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4589 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4593 [(set_attr "type" "ialu,load")
4594 (set_attr "length" "1")])
4596 (define_expand "zero_extendhidi2"
4597 [(set (match_operand:DI 0 "register_operand" "")
4598 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4602 rtx temp = gen_reg_rtx (DImode);
4603 rtx shift_48 = GEN_INT (48);
4604 int op1_subbyte = 0;
4606 if (GET_CODE (operand1) == SUBREG)
4608 op1_subbyte = SUBREG_BYTE (operand1);
4609 op1_subbyte /= GET_MODE_SIZE (DImode);
4610 op1_subbyte *= GET_MODE_SIZE (DImode);
4611 operand1 = XEXP (operand1, 0);
4614 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4616 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4620 (define_insn "*zero_extendhidi2_insn"
4621 [(set (match_operand:DI 0 "register_operand" "=r")
4622 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4625 [(set_attr "type" "load")
4626 (set_attr "length" "1")])
4629 ;; ??? Write truncdisi pattern using sra?
4631 (define_expand "zero_extendsidi2"
4632 [(set (match_operand:DI 0 "register_operand" "")
4633 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4637 (define_insn "*zero_extendsidi2_insn_sp64"
4638 [(set (match_operand:DI 0 "register_operand" "=r,r")
4639 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4640 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4644 [(set_attr "type" "shift,load")
4645 (set_attr "length" "1")])
4647 (define_insn "*zero_extendsidi2_insn_sp32"
4648 [(set (match_operand:DI 0 "register_operand" "=r")
4649 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4652 [(set_attr "length" "2")])
4655 [(set (match_operand:DI 0 "register_operand" "")
4656 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4657 "! TARGET_ARCH64 && reload_completed"
4658 [(set (match_dup 2) (match_dup 3))
4659 (set (match_dup 4) (match_dup 5))]
4664 if (GET_CODE (operands[0]) == SUBREG)
4665 operands[0] = alter_subreg (operands[0]);
4667 dest1 = gen_highpart (SImode, operands[0]);
4668 dest2 = gen_lowpart (SImode, operands[0]);
4670 /* Swap the order in case of overlap. */
4671 if (REGNO (dest1) == REGNO (operands[1]))
4673 operands[2] = dest2;
4674 operands[3] = operands[1];
4675 operands[4] = dest1;
4676 operands[5] = const0_rtx;
4680 operands[2] = dest1;
4681 operands[3] = const0_rtx;
4682 operands[4] = dest2;
4683 operands[5] = operands[1];
4687 ;; Simplify comparisons of extended values.
4689 (define_insn "*cmp_zero_extendqisi2"
4691 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4694 "andcc\\t%0, 0xff, %%g0"
4695 [(set_attr "type" "compare")
4696 (set_attr "length" "1")])
4698 (define_insn "*cmp_zero_qi"
4700 (compare:CC (match_operand:QI 0 "register_operand" "r")
4703 "andcc\\t%0, 0xff, %%g0"
4704 [(set_attr "type" "compare")
4705 (set_attr "length" "1")])
4707 (define_insn "*cmp_zero_extendqisi2_set"
4709 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4711 (set (match_operand:SI 0 "register_operand" "=r")
4712 (zero_extend:SI (match_dup 1)))]
4714 "andcc\\t%1, 0xff, %0"
4715 [(set_attr "type" "compare")
4716 (set_attr "length" "1")])
4718 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4720 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4723 (set (match_operand:SI 0 "register_operand" "=r")
4724 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4726 "andcc\\t%1, 0xff, %0"
4727 [(set_attr "type" "compare")
4728 (set_attr "length" "1")])
4730 (define_insn "*cmp_zero_extendqidi2"
4732 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4735 "andcc\\t%0, 0xff, %%g0"
4736 [(set_attr "type" "compare")
4737 (set_attr "length" "1")])
4739 (define_insn "*cmp_zero_qi_sp64"
4741 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4744 "andcc\\t%0, 0xff, %%g0"
4745 [(set_attr "type" "compare")
4746 (set_attr "length" "1")])
4748 (define_insn "*cmp_zero_extendqidi2_set"
4750 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4752 (set (match_operand:DI 0 "register_operand" "=r")
4753 (zero_extend:DI (match_dup 1)))]
4755 "andcc\\t%1, 0xff, %0"
4756 [(set_attr "type" "compare")
4757 (set_attr "length" "1")])
4759 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4761 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4764 (set (match_operand:DI 0 "register_operand" "=r")
4765 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4767 "andcc\\t%1, 0xff, %0"
4768 [(set_attr "type" "compare")
4769 (set_attr "length" "1")])
4771 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4773 (define_insn "*cmp_siqi_trunc"
4775 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4778 "andcc\\t%0, 0xff, %%g0"
4779 [(set_attr "type" "compare")
4780 (set_attr "length" "1")])
4782 (define_insn "*cmp_siqi_trunc_set"
4784 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4786 (set (match_operand:QI 0 "register_operand" "=r")
4787 (subreg:QI (match_dup 1) 3))]
4789 "andcc\\t%1, 0xff, %0"
4790 [(set_attr "type" "compare")
4791 (set_attr "length" "1")])
4793 (define_insn "*cmp_diqi_trunc"
4795 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4798 "andcc\\t%0, 0xff, %%g0"
4799 [(set_attr "type" "compare")
4800 (set_attr "length" "1")])
4802 (define_insn "*cmp_diqi_trunc_set"
4804 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4806 (set (match_operand:QI 0 "register_operand" "=r")
4807 (subreg:QI (match_dup 1) 7))]
4809 "andcc\\t%1, 0xff, %0"
4810 [(set_attr "type" "compare")
4811 (set_attr "length" "1")])
4813 ;;- sign extension instructions
4815 ;; These patterns originally accepted general_operands, however, slightly
4816 ;; better code is generated by only accepting register_operands, and then
4817 ;; letting combine generate the lds[hb] insns.
4819 (define_expand "extendhisi2"
4820 [(set (match_operand:SI 0 "register_operand" "")
4821 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4825 rtx temp = gen_reg_rtx (SImode);
4826 rtx shift_16 = GEN_INT (16);
4827 int op1_subbyte = 0;
4829 if (GET_CODE (operand1) == SUBREG)
4831 op1_subbyte = SUBREG_BYTE (operand1);
4832 op1_subbyte /= GET_MODE_SIZE (SImode);
4833 op1_subbyte *= GET_MODE_SIZE (SImode);
4834 operand1 = XEXP (operand1, 0);
4837 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4839 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4843 (define_insn "*sign_extendhisi2_insn"
4844 [(set (match_operand:SI 0 "register_operand" "=r")
4845 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4848 [(set_attr "type" "sload")
4849 (set_attr "length" "1")])
4851 (define_expand "extendqihi2"
4852 [(set (match_operand:HI 0 "register_operand" "")
4853 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4857 rtx temp = gen_reg_rtx (SImode);
4858 rtx shift_24 = GEN_INT (24);
4859 int op1_subbyte = 0;
4860 int op0_subbyte = 0;
4862 if (GET_CODE (operand1) == SUBREG)
4864 op1_subbyte = SUBREG_BYTE (operand1);
4865 op1_subbyte /= GET_MODE_SIZE (SImode);
4866 op1_subbyte *= GET_MODE_SIZE (SImode);
4867 operand1 = XEXP (operand1, 0);
4869 if (GET_CODE (operand0) == SUBREG)
4871 op0_subbyte = SUBREG_BYTE (operand0);
4872 op0_subbyte /= GET_MODE_SIZE (SImode);
4873 op0_subbyte *= GET_MODE_SIZE (SImode);
4874 operand0 = XEXP (operand0, 0);
4876 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4878 if (GET_MODE (operand0) != SImode)
4879 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4880 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4884 (define_insn "*sign_extendqihi2_insn"
4885 [(set (match_operand:HI 0 "register_operand" "=r")
4886 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4889 [(set_attr "type" "sload")
4890 (set_attr "length" "1")])
4892 (define_expand "extendqisi2"
4893 [(set (match_operand:SI 0 "register_operand" "")
4894 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4898 rtx temp = gen_reg_rtx (SImode);
4899 rtx shift_24 = GEN_INT (24);
4900 int op1_subbyte = 0;
4902 if (GET_CODE (operand1) == SUBREG)
4904 op1_subbyte = SUBREG_BYTE (operand1);
4905 op1_subbyte /= GET_MODE_SIZE (SImode);
4906 op1_subbyte *= GET_MODE_SIZE (SImode);
4907 operand1 = XEXP (operand1, 0);
4910 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4912 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4916 (define_insn "*sign_extendqisi2_insn"
4917 [(set (match_operand:SI 0 "register_operand" "=r")
4918 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4921 [(set_attr "type" "sload")
4922 (set_attr "length" "1")])
4924 (define_expand "extendqidi2"
4925 [(set (match_operand:DI 0 "register_operand" "")
4926 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4930 rtx temp = gen_reg_rtx (DImode);
4931 rtx shift_56 = GEN_INT (56);
4932 int op1_subbyte = 0;
4934 if (GET_CODE (operand1) == SUBREG)
4936 op1_subbyte = SUBREG_BYTE (operand1);
4937 op1_subbyte /= GET_MODE_SIZE (DImode);
4938 op1_subbyte *= GET_MODE_SIZE (DImode);
4939 operand1 = XEXP (operand1, 0);
4942 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4944 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4948 (define_insn "*sign_extendqidi2_insn"
4949 [(set (match_operand:DI 0 "register_operand" "=r")
4950 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4953 [(set_attr "type" "sload")
4954 (set_attr "length" "1")])
4956 (define_expand "extendhidi2"
4957 [(set (match_operand:DI 0 "register_operand" "")
4958 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4962 rtx temp = gen_reg_rtx (DImode);
4963 rtx shift_48 = GEN_INT (48);
4964 int op1_subbyte = 0;
4966 if (GET_CODE (operand1) == SUBREG)
4968 op1_subbyte = SUBREG_BYTE (operand1);
4969 op1_subbyte /= GET_MODE_SIZE (DImode);
4970 op1_subbyte *= GET_MODE_SIZE (DImode);
4971 operand1 = XEXP (operand1, 0);
4974 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4976 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4980 (define_insn "*sign_extendhidi2_insn"
4981 [(set (match_operand:DI 0 "register_operand" "=r")
4982 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4985 [(set_attr "type" "sload")
4986 (set_attr "length" "1")])
4988 (define_expand "extendsidi2"
4989 [(set (match_operand:DI 0 "register_operand" "")
4990 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4994 (define_insn "*sign_extendsidi2_insn"
4995 [(set (match_operand:DI 0 "register_operand" "=r,r")
4996 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
5001 [(set_attr "type" "shift,sload")
5002 (set_attr "length" "1")])
5004 ;; Special pattern for optimizing bit-field compares. This is needed
5005 ;; because combine uses this as a canonical form.
5007 (define_insn "*cmp_zero_extract"
5010 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5011 (match_operand:SI 1 "small_int_or_double" "n")
5012 (match_operand:SI 2 "small_int_or_double" "n"))
5014 "(GET_CODE (operands[2]) == CONST_INT
5015 && INTVAL (operands[2]) > 19)
5016 || (GET_CODE (operands[2]) == CONST_DOUBLE
5017 && CONST_DOUBLE_LOW (operands[2]) > 19)"
5020 int len = (GET_CODE (operands[1]) == CONST_INT
5021 ? INTVAL (operands[1])
5022 : CONST_DOUBLE_LOW (operands[1]));
5024 (GET_CODE (operands[2]) == CONST_INT
5025 ? INTVAL (operands[2])
5026 : CONST_DOUBLE_LOW (operands[2])) - len;
5027 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5029 operands[1] = GEN_INT (mask);
5030 return \"andcc\\t%0, %1, %%g0\";
5032 [(set_attr "type" "compare")
5033 (set_attr "length" "1")])
5035 (define_insn "*cmp_zero_extract_sp64"
5038 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5039 (match_operand:SI 1 "small_int_or_double" "n")
5040 (match_operand:SI 2 "small_int_or_double" "n"))
5043 && ((GET_CODE (operands[2]) == CONST_INT
5044 && INTVAL (operands[2]) > 51)
5045 || (GET_CODE (operands[2]) == CONST_DOUBLE
5046 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5049 int len = (GET_CODE (operands[1]) == CONST_INT
5050 ? INTVAL (operands[1])
5051 : CONST_DOUBLE_LOW (operands[1]));
5053 (GET_CODE (operands[2]) == CONST_INT
5054 ? INTVAL (operands[2])
5055 : CONST_DOUBLE_LOW (operands[2])) - len;
5056 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5058 operands[1] = GEN_INT (mask);
5059 return \"andcc\\t%0, %1, %%g0\";
5061 [(set_attr "type" "compare")
5062 (set_attr "length" "1")])
5064 ;; Conversions between float, double and long double.
5066 (define_insn "extendsfdf2"
5067 [(set (match_operand:DF 0 "register_operand" "=e")
5069 (match_operand:SF 1 "register_operand" "f")))]
5072 [(set_attr "type" "fp")
5073 (set_attr "length" "1")])
5075 (define_expand "extendsftf2"
5076 [(set (match_operand:TF 0 "register_operand" "=e")
5078 (match_operand:SF 1 "register_operand" "f")))]
5079 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5082 if (! TARGET_HARD_QUAD)
5086 if (GET_CODE (operands[0]) != MEM)
5087 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5089 slot0 = operands[0];
5091 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5093 XEXP (slot0, 0), Pmode,
5094 operands[1], SFmode);
5096 if (GET_CODE (operands[0]) != MEM)
5097 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5102 (define_insn "*extendsftf2_hq"
5103 [(set (match_operand:TF 0 "register_operand" "=e")
5105 (match_operand:SF 1 "register_operand" "f")))]
5106 "TARGET_FPU && TARGET_HARD_QUAD"
5108 [(set_attr "type" "fp")
5109 (set_attr "length" "1")])
5111 (define_expand "extenddftf2"
5112 [(set (match_operand:TF 0 "register_operand" "=e")
5114 (match_operand:DF 1 "register_operand" "e")))]
5115 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5118 if (! TARGET_HARD_QUAD)
5122 if (GET_CODE (operands[0]) != MEM)
5123 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5125 slot0 = operands[0];
5127 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5129 XEXP (slot0, 0), Pmode,
5130 operands[1], DFmode);
5132 if (GET_CODE (operands[0]) != MEM)
5133 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5138 (define_insn "*extenddftf2_hq"
5139 [(set (match_operand:TF 0 "register_operand" "=e")
5141 (match_operand:DF 1 "register_operand" "e")))]
5142 "TARGET_FPU && TARGET_HARD_QUAD"
5144 [(set_attr "type" "fp")
5145 (set_attr "length" "1")])
5147 (define_insn "truncdfsf2"
5148 [(set (match_operand:SF 0 "register_operand" "=f")
5150 (match_operand:DF 1 "register_operand" "e")))]
5153 [(set_attr "type" "fp")
5154 (set_attr "length" "1")])
5156 (define_expand "trunctfsf2"
5157 [(set (match_operand:SF 0 "register_operand" "=f")
5159 (match_operand:TF 1 "register_operand" "e")))]
5160 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5163 if (! TARGET_HARD_QUAD)
5167 if (GET_CODE (operands[1]) != MEM)
5169 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5170 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5173 slot0 = operands[1];
5175 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5176 operands[0], 0, SFmode, 1,
5177 XEXP (slot0, 0), Pmode);
5182 (define_insn "*trunctfsf2_hq"
5183 [(set (match_operand:SF 0 "register_operand" "=f")
5185 (match_operand:TF 1 "register_operand" "e")))]
5186 "TARGET_FPU && TARGET_HARD_QUAD"
5188 [(set_attr "type" "fp")
5189 (set_attr "length" "1")])
5191 (define_expand "trunctfdf2"
5192 [(set (match_operand:DF 0 "register_operand" "=f")
5194 (match_operand:TF 1 "register_operand" "e")))]
5195 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5198 if (! TARGET_HARD_QUAD)
5202 if (GET_CODE (operands[1]) != MEM)
5204 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5205 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5208 slot0 = operands[1];
5210 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5211 operands[0], 0, DFmode, 1,
5212 XEXP (slot0, 0), Pmode);
5217 (define_insn "*trunctfdf2_hq"
5218 [(set (match_operand:DF 0 "register_operand" "=e")
5220 (match_operand:TF 1 "register_operand" "e")))]
5221 "TARGET_FPU && TARGET_HARD_QUAD"
5223 [(set_attr "type" "fp")
5224 (set_attr "length" "1")])
5226 ;; Conversion between fixed point and floating point.
5228 (define_insn "floatsisf2"
5229 [(set (match_operand:SF 0 "register_operand" "=f")
5230 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5233 [(set_attr "type" "fp")
5234 (set_attr "length" "1")])
5236 (define_insn "floatsidf2"
5237 [(set (match_operand:DF 0 "register_operand" "=e")
5238 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5241 [(set_attr "type" "fp")
5242 (set_attr "length" "1")])
5244 (define_expand "floatsitf2"
5245 [(set (match_operand:TF 0 "register_operand" "=e")
5246 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5247 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5250 if (! TARGET_HARD_QUAD)
5254 if (GET_CODE (operands[1]) != MEM)
5255 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5257 slot0 = operands[1];
5259 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5261 XEXP (slot0, 0), Pmode,
5262 operands[1], SImode);
5264 if (GET_CODE (operands[0]) != MEM)
5265 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5270 (define_insn "*floatsitf2_hq"
5271 [(set (match_operand:TF 0 "register_operand" "=e")
5272 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5273 "TARGET_FPU && TARGET_HARD_QUAD"
5275 [(set_attr "type" "fp")
5276 (set_attr "length" "1")])
5278 (define_expand "floatunssitf2"
5279 [(set (match_operand:TF 0 "register_operand" "=e")
5280 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5281 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5286 if (GET_CODE (operands[1]) != MEM)
5287 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5289 slot0 = operands[1];
5291 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5293 XEXP (slot0, 0), Pmode,
5294 operands[1], SImode);
5296 if (GET_CODE (operands[0]) != MEM)
5297 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5301 ;; Now the same for 64 bit sources.
5303 (define_insn "floatdisf2"
5304 [(set (match_operand:SF 0 "register_operand" "=f")
5305 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5306 "TARGET_V9 && TARGET_FPU"
5308 [(set_attr "type" "fp")
5309 (set_attr "length" "1")])
5311 (define_insn "floatdidf2"
5312 [(set (match_operand:DF 0 "register_operand" "=e")
5313 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5314 "TARGET_V9 && TARGET_FPU"
5316 [(set_attr "type" "fp")
5317 (set_attr "length" "1")])
5319 (define_expand "floatditf2"
5320 [(set (match_operand:TF 0 "register_operand" "=e")
5321 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5322 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5325 if (! TARGET_HARD_QUAD)
5329 if (GET_CODE (operands[1]) != MEM)
5330 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5332 slot0 = operands[1];
5334 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5336 XEXP (slot0, 0), Pmode,
5337 operands[1], DImode);
5339 if (GET_CODE (operands[0]) != MEM)
5340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5345 (define_insn "*floatditf2_hq"
5346 [(set (match_operand:TF 0 "register_operand" "=e")
5347 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5348 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5350 [(set_attr "type" "fp")
5351 (set_attr "length" "1")])
5353 (define_expand "floatunsditf2"
5354 [(set (match_operand:TF 0 "register_operand" "=e")
5355 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5356 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5361 if (GET_CODE (operands[1]) != MEM)
5362 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5364 slot0 = operands[1];
5366 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5368 XEXP (slot0, 0), Pmode,
5369 operands[1], DImode);
5371 if (GET_CODE (operands[0]) != MEM)
5372 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5376 ;; Convert a float to an actual integer.
5377 ;; Truncation is performed as part of the conversion.
5379 (define_insn "fix_truncsfsi2"
5380 [(set (match_operand:SI 0 "register_operand" "=f")
5381 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5384 [(set_attr "type" "fp")
5385 (set_attr "length" "1")])
5387 (define_insn "fix_truncdfsi2"
5388 [(set (match_operand:SI 0 "register_operand" "=f")
5389 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5392 [(set_attr "type" "fp")
5393 (set_attr "length" "1")])
5395 (define_expand "fix_trunctfsi2"
5396 [(set (match_operand:SI 0 "register_operand" "=f")
5397 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5398 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5401 if (! TARGET_HARD_QUAD)
5405 if (GET_CODE (operands[1]) != MEM)
5407 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5408 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5411 slot0 = operands[1];
5413 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5414 operands[0], 0, SImode, 1,
5415 XEXP (slot0, 0), Pmode);
5420 (define_insn "*fix_trunctfsi2_hq"
5421 [(set (match_operand:SI 0 "register_operand" "=f")
5422 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5423 "TARGET_FPU && TARGET_HARD_QUAD"
5425 [(set_attr "type" "fp")
5426 (set_attr "length" "1")])
5428 (define_expand "fixuns_trunctfsi2"
5429 [(set (match_operand:SI 0 "register_operand" "=f")
5430 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5431 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5436 if (GET_CODE (operands[1]) != MEM)
5438 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5439 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5442 slot0 = operands[1];
5444 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5445 operands[0], 0, SImode, 1,
5446 XEXP (slot0, 0), Pmode);
5450 ;; Now the same, for V9 targets
5452 (define_insn "fix_truncsfdi2"
5453 [(set (match_operand:DI 0 "register_operand" "=e")
5454 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5455 "TARGET_V9 && TARGET_FPU"
5457 [(set_attr "type" "fp")
5458 (set_attr "length" "1")])
5460 (define_insn "fix_truncdfdi2"
5461 [(set (match_operand:DI 0 "register_operand" "=e")
5462 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5463 "TARGET_V9 && TARGET_FPU"
5465 [(set_attr "type" "fp")
5466 (set_attr "length" "1")])
5468 (define_expand "fix_trunctfdi2"
5469 [(set (match_operand:DI 0 "register_operand" "=e")
5470 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5471 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5474 if (! TARGET_HARD_QUAD)
5478 if (GET_CODE (operands[1]) != MEM)
5480 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5481 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5484 slot0 = operands[1];
5486 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5487 operands[0], 0, DImode, 1,
5488 XEXP (slot0, 0), Pmode);
5493 (define_insn "*fix_trunctfdi2_hq"
5494 [(set (match_operand:DI 0 "register_operand" "=e")
5495 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5496 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5498 [(set_attr "type" "fp")
5499 (set_attr "length" "1")])
5501 (define_expand "fixuns_trunctfdi2"
5502 [(set (match_operand:DI 0 "register_operand" "=f")
5503 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5504 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5509 if (GET_CODE (operands[1]) != MEM)
5511 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5512 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5515 slot0 = operands[1];
5517 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5518 operands[0], 0, DImode, 1,
5519 XEXP (slot0, 0), Pmode);
5524 ;;- arithmetic instructions
5526 (define_expand "adddi3"
5527 [(set (match_operand:DI 0 "register_operand" "=r")
5528 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5529 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5535 if (! TARGET_ARCH64)
5537 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5538 gen_rtx_SET (VOIDmode, operands[0],
5539 gen_rtx_PLUS (DImode, operands[1],
5541 gen_rtx_CLOBBER (VOIDmode,
5542 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5545 if (arith_double_4096_operand(operands[2], DImode))
5547 switch (GET_CODE (operands[1]))
5549 case CONST_INT: i = INTVAL (operands[1]); break;
5550 case CONST_DOUBLE: i = CONST_DOUBLE_LOW (operands[1]); break;
5552 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5553 gen_rtx_MINUS (DImode, operands[1],
5557 emit_insn (gen_movdi (operands[0], GEN_INT (i + 4096)));
5562 (define_insn "adddi3_insn_sp32"
5563 [(set (match_operand:DI 0 "register_operand" "=r")
5564 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5565 (match_operand:DI 2 "arith_double_operand" "rHI")))
5566 (clobber (reg:CC 100))]
5569 [(set_attr "length" "2")])
5572 [(set (match_operand:DI 0 "register_operand" "")
5573 (plus:DI (match_operand:DI 1 "arith_double_operand" "")
5574 (match_operand:DI 2 "arith_double_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 4)
5582 (plus:SI (match_dup 4) (match_dup 5)))])
5584 (plus:SI (plus:SI (match_dup 7)
5586 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5589 operands[3] = gen_lowpart (SImode, operands[0]);
5590 operands[4] = gen_lowpart (SImode, operands[1]);
5591 operands[5] = gen_lowpart (SImode, operands[2]);
5592 operands[6] = gen_highpart (SImode, operands[0]);
5593 operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
5594 #if HOST_BITS_PER_WIDE_INT == 32
5595 if (GET_CODE (operands[2]) == CONST_INT)
5597 if (INTVAL (operands[2]) < 0)
5598 operands[8] = constm1_rtx;
5600 operands[8] = const0_rtx;
5604 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5608 [(set (match_operand:DI 0 "register_operand" "")
5609 (minus:DI (match_operand:DI 1 "arith_double_operand" "")
5610 (match_operand:DI 2 "arith_double_operand" "")))
5611 (clobber (reg:CC 100))]
5612 "! TARGET_ARCH64 && reload_completed"
5613 [(parallel [(set (reg:CC_NOOV 100)
5614 (compare:CC_NOOV (minus:SI (match_dup 4)
5618 (minus:SI (match_dup 4) (match_dup 5)))])
5620 (minus:SI (minus:SI (match_dup 7)
5622 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5625 operands[3] = gen_lowpart (SImode, operands[0]);
5626 operands[4] = gen_lowpart (SImode, operands[1]);
5627 operands[5] = gen_lowpart (SImode, operands[2]);
5628 operands[6] = gen_highpart (SImode, operands[0]);
5629 operands[7] = gen_highpart (SImode, operands[1]);
5630 #if HOST_BITS_PER_WIDE_INT == 32
5631 if (GET_CODE (operands[2]) == CONST_INT)
5633 if (INTVAL (operands[2]) < 0)
5634 operands[8] = constm1_rtx;
5636 operands[8] = const0_rtx;
5640 operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
5643 ;; LTU here means "carry set"
5645 [(set (match_operand:SI 0 "register_operand" "=r")
5646 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5647 (match_operand:SI 2 "arith_operand" "rI"))
5648 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5651 [(set_attr "length" "1")])
5653 (define_insn "*addx_extend_sp32"
5654 [(set (match_operand:DI 0 "register_operand" "=r")
5655 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5656 (match_operand:SI 2 "arith_operand" "rI"))
5657 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5660 [(set_attr "length" "2")])
5663 [(set (match_operand:DI 0 "register_operand" "")
5664 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5665 (match_operand:SI 2 "arith_operand" ""))
5666 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5667 "! TARGET_ARCH64 && reload_completed"
5668 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5669 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5670 (set (match_dup 4) (const_int 0))]
5671 "operands[3] = gen_lowpart (SImode, operands[0]);
5672 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);")
5674 (define_insn "*addx_extend_sp64"
5675 [(set (match_operand:DI 0 "register_operand" "=r")
5676 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5677 (match_operand:SI 2 "arith_operand" "rI"))
5678 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5680 "addx\\t%r1, %2, %0"
5681 [(set_attr "type" "misc")
5682 (set_attr "length" "1")])
5685 [(set (match_operand:SI 0 "register_operand" "=r")
5686 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5687 (match_operand:SI 2 "arith_operand" "rI"))
5688 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5690 "subx\\t%r1, %2, %0"
5691 [(set_attr "type" "misc")
5692 (set_attr "length" "1")])
5694 (define_insn "*subx_extend_sp64"
5695 [(set (match_operand:DI 0 "register_operand" "=r")
5696 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5697 (match_operand:SI 2 "arith_operand" "rI"))
5698 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5700 "subx\\t%r1, %2, %0"
5701 [(set_attr "type" "misc")
5702 (set_attr "length" "1")])
5704 (define_insn "*subx_extend"
5705 [(set (match_operand:DI 0 "register_operand" "=r")
5706 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5707 (match_operand:SI 2 "arith_operand" "rI"))
5708 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5711 [(set_attr "length" "2")])
5714 [(set (match_operand:DI 0 "register_operand" "")
5715 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5716 (match_operand:SI 2 "arith_operand" ""))
5717 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5718 "! TARGET_ARCH64 && reload_completed"
5719 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5720 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5721 (set (match_dup 4) (const_int 0))]
5722 "operands[3] = gen_lowpart (SImode, operands[0]);
5723 operands[4] = gen_highpart (SImode, operands[0]);")
5726 [(set (match_operand:DI 0 "register_operand" "=r")
5727 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5728 (match_operand:DI 2 "register_operand" "r")))
5729 (clobber (reg:CC 100))]
5732 [(set_attr "type" "multi")
5733 (set_attr "length" "2")])
5736 [(set (match_operand:DI 0 "register_operand" "")
5737 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5738 (match_operand:DI 2 "register_operand" "")))
5739 (clobber (reg:CC 100))]
5740 "! TARGET_ARCH64 && reload_completed"
5741 [(parallel [(set (reg:CC_NOOV 100)
5742 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5744 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5746 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5747 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5748 "operands[3] = gen_lowpart (SImode, operands[2]);
5749 operands[4] = gen_highpart (SImode, operands[2]);
5750 operands[5] = gen_lowpart (SImode, operands[0]);
5751 operands[6] = gen_highpart (SImode, operands[0]);")
5753 (define_insn "*adddi3_sp64"
5754 [(set (match_operand:DI 0 "register_operand" "=r")
5755 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5756 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5759 [(set_attr "length" "1")])
5761 (define_expand "addsi3"
5762 [(set (match_operand:SI 0 "register_operand" "=r,d")
5763 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5764 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5768 if (arith_4096_operand(operands[2], SImode))
5770 if (GET_CODE (operands[1]) == CONST_INT)
5771 emit_insn (gen_movsi (operands[0],
5772 GEN_INT (INTVAL (operands[1]) + 4096)));
5774 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5775 gen_rtx_MINUS (SImode, operands[1],
5781 (define_insn "*addsi3"
5782 [(set (match_operand:SI 0 "register_operand" "=r,d")
5783 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5784 (match_operand:SI 2 "arith_operand" "rI,d")))]
5788 fpadd32s\\t%1, %2, %0"
5789 [(set_attr "type" "ialu,fp")
5790 (set_attr "length" "1")])
5792 (define_insn "*cmp_cc_plus"
5793 [(set (reg:CC_NOOV 100)
5794 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5795 (match_operand:SI 1 "arith_operand" "rI"))
5798 "addcc\\t%0, %1, %%g0"
5799 [(set_attr "type" "compare")
5800 (set_attr "length" "1")])
5802 (define_insn "*cmp_ccx_plus"
5803 [(set (reg:CCX_NOOV 100)
5804 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5805 (match_operand:DI 1 "arith_double_operand" "rHI"))
5808 "addcc\\t%0, %1, %%g0"
5809 [(set_attr "type" "compare")
5810 (set_attr "length" "1")])
5812 (define_insn "*cmp_cc_plus_set"
5813 [(set (reg:CC_NOOV 100)
5814 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5815 (match_operand:SI 2 "arith_operand" "rI"))
5817 (set (match_operand:SI 0 "register_operand" "=r")
5818 (plus:SI (match_dup 1) (match_dup 2)))]
5820 "addcc\\t%1, %2, %0"
5821 [(set_attr "type" "compare")
5822 (set_attr "length" "1")])
5824 (define_insn "*cmp_ccx_plus_set"
5825 [(set (reg:CCX_NOOV 100)
5826 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5827 (match_operand:DI 2 "arith_double_operand" "rHI"))
5829 (set (match_operand:DI 0 "register_operand" "=r")
5830 (plus:DI (match_dup 1) (match_dup 2)))]
5832 "addcc\\t%1, %2, %0"
5833 [(set_attr "type" "compare")
5834 (set_attr "length" "1")])
5836 (define_expand "subdi3"
5837 [(set (match_operand:DI 0 "register_operand" "=r")
5838 (minus:DI (match_operand:DI 1 "register_operand" "r")
5839 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5843 if (! TARGET_ARCH64)
5845 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5846 gen_rtx_SET (VOIDmode, operands[0],
5847 gen_rtx_MINUS (DImode, operands[1],
5849 gen_rtx_CLOBBER (VOIDmode,
5850 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5853 if (arith_double_4096_operand(operands[2], DImode))
5855 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5856 gen_rtx_PLUS (DImode, operands[1],
5862 (define_insn "*subdi3_sp32"
5863 [(set (match_operand:DI 0 "register_operand" "=r")
5864 (minus:DI (match_operand:DI 1 "register_operand" "r")
5865 (match_operand:DI 2 "arith_double_operand" "rHI")))
5866 (clobber (reg:CC 100))]
5869 [(set_attr "length" "2")])
5872 [(set (match_operand:DI 0 "register_operand" "")
5873 (minus:DI (match_operand:DI 1 "register_operand" "")
5874 (match_operand:DI 2 "arith_double_operand" "")))
5875 (clobber (reg:CC 100))]
5878 && (GET_CODE (operands[2]) == CONST_INT
5879 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5880 [(clobber (const_int 0))]
5885 highp = gen_highpart_mode (SImode, DImode, operands[2]);
5886 lowp = gen_lowpart (SImode, operands[2]);
5887 if ((lowp == const0_rtx)
5888 && (operands[0] == operands[1]))
5890 emit_insn (gen_rtx_SET (VOIDmode,
5891 gen_highpart (SImode, operands[0]),
5892 gen_rtx_MINUS (SImode,
5893 gen_highpart_mode (SImode, DImode,
5899 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5900 gen_lowpart (SImode, operands[1]),
5902 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5903 gen_highpart_mode (SImode, DImode, operands[1]),
5910 [(set (match_operand:DI 0 "register_operand" "")
5911 (minus:DI (match_operand:DI 1 "register_operand" "")
5912 (match_operand:DI 2 "register_operand" "")))
5913 (clobber (reg:CC 100))]
5915 && reload_completed"
5916 [(clobber (const_int 0))]
5919 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5920 gen_lowpart (SImode, operands[1]),
5921 gen_lowpart (SImode, operands[2])));
5922 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5923 gen_highpart (SImode, operands[1]),
5924 gen_highpart (SImode, operands[2])));
5929 [(set (match_operand:DI 0 "register_operand" "=r")
5930 (minus:DI (match_operand:DI 1 "register_operand" "r")
5931 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5932 (clobber (reg:CC 100))]
5935 [(set_attr "type" "multi")
5936 (set_attr "length" "2")])
5939 [(set (match_operand:DI 0 "register_operand" "")
5940 (minus:DI (match_operand:DI 1 "register_operand" "")
5941 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5942 (clobber (reg:CC 100))]
5943 "! TARGET_ARCH64 && reload_completed"
5944 [(parallel [(set (reg:CC_NOOV 100)
5945 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5947 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5949 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5950 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5951 "operands[3] = gen_lowpart (SImode, operands[1]);
5952 operands[4] = gen_highpart (SImode, operands[1]);
5953 operands[5] = gen_lowpart (SImode, operands[0]);
5954 operands[6] = gen_highpart (SImode, operands[0]);")
5956 (define_insn "*subdi3_sp64"
5957 [(set (match_operand:DI 0 "register_operand" "=r")
5958 (minus:DI (match_operand:DI 1 "register_operand" "r")
5959 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5962 [(set_attr "length" "1")])
5964 (define_expand "subsi3"
5965 [(set (match_operand:SI 0 "register_operand" "=r,d")
5966 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5967 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5971 if (arith_4096_operand(operands[2], SImode))
5973 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5974 gen_rtx_PLUS (SImode, operands[1],
5980 (define_insn "*subsi3"
5981 [(set (match_operand:SI 0 "register_operand" "=r,d")
5982 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5983 (match_operand:SI 2 "arith_operand" "rI,d")))]
5987 fpsub32s\\t%1, %2, %0"
5988 [(set_attr "type" "ialu,fp")
5989 (set_attr "length" "1")])
5991 (define_insn "*cmp_minus_cc"
5992 [(set (reg:CC_NOOV 100)
5993 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5994 (match_operand:SI 1 "arith_operand" "rI"))
5997 "subcc\\t%r0, %1, %%g0"
5998 [(set_attr "type" "compare")
5999 (set_attr "length" "1")])
6001 (define_insn "*cmp_minus_ccx"
6002 [(set (reg:CCX_NOOV 100)
6003 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
6004 (match_operand:DI 1 "arith_double_operand" "rHI"))
6007 "subcc\\t%0, %1, %%g0"
6008 [(set_attr "type" "compare")
6009 (set_attr "length" "1")])
6011 (define_insn "cmp_minus_cc_set"
6012 [(set (reg:CC_NOOV 100)
6013 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6014 (match_operand:SI 2 "arith_operand" "rI"))
6016 (set (match_operand:SI 0 "register_operand" "=r")
6017 (minus:SI (match_dup 1) (match_dup 2)))]
6019 "subcc\\t%r1, %2, %0"
6020 [(set_attr "type" "compare")
6021 (set_attr "length" "1")])
6023 (define_insn "*cmp_minus_ccx_set"
6024 [(set (reg:CCX_NOOV 100)
6025 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6026 (match_operand:DI 2 "arith_double_operand" "rHI"))
6028 (set (match_operand:DI 0 "register_operand" "=r")
6029 (minus:DI (match_dup 1) (match_dup 2)))]
6031 "subcc\\t%1, %2, %0"
6032 [(set_attr "type" "compare")
6033 (set_attr "length" "1")])
6035 ;; Integer Multiply/Divide.
6037 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6038 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6040 (define_insn "mulsi3"
6041 [(set (match_operand:SI 0 "register_operand" "=r")
6042 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6043 (match_operand:SI 2 "arith_operand" "rI")))]
6046 [(set_attr "type" "imul")
6047 (set_attr "length" "1")])
6049 (define_expand "muldi3"
6050 [(set (match_operand:DI 0 "register_operand" "=r")
6051 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6052 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6053 "TARGET_ARCH64 || TARGET_V8PLUS"
6058 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6063 (define_insn "*muldi3_sp64"
6064 [(set (match_operand:DI 0 "register_operand" "=r")
6065 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6066 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6069 [(set_attr "type" "imul")
6070 (set_attr "length" "1")])
6072 ;; V8plus wide multiply.
6074 (define_insn "muldi3_v8plus"
6075 [(set (match_operand:DI 0 "register_operand" "=r,h")
6076 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6077 (match_operand:DI 2 "arith_double_operand" "rI,rI")))
6078 (clobber (match_scratch:SI 3 "=&h,X"))
6079 (clobber (match_scratch:SI 4 "=&h,X"))]
6083 if (sparc_check_64 (operands[1], insn) <= 0)
6084 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6085 if (which_alternative == 1)
6086 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6087 if (GET_CODE (operands[2]) == CONST_INT)
6089 if (which_alternative == 1)
6090 return \"or\\t%L1, %H1, %H1\\n\\tmulx\\t%H1, %2, %L0\;srlx\\t%L0, 32, %H0\";
6092 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\";
6094 if (sparc_check_64 (operands[2], insn) <= 0)
6095 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6096 if (which_alternative == 1)
6097 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\";
6099 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\";
6101 [(set_attr "length" "9,8")])
6103 (define_insn "*cmp_mul_set"
6105 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6106 (match_operand:SI 2 "arith_operand" "rI"))
6108 (set (match_operand:SI 0 "register_operand" "=r")
6109 (mult:SI (match_dup 1) (match_dup 2)))]
6110 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6111 "smulcc\\t%1, %2, %0"
6112 [(set_attr "type" "imul")
6113 (set_attr "length" "1")])
6115 (define_expand "mulsidi3"
6116 [(set (match_operand:DI 0 "register_operand" "")
6117 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6118 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6122 if (CONSTANT_P (operands[2]))
6125 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6128 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6134 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6139 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6140 ;; registers can hold 64 bit values in the V8plus environment.
6142 (define_insn "mulsidi3_v8plus"
6143 [(set (match_operand:DI 0 "register_operand" "=h,r")
6144 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6145 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6146 (clobber (match_scratch:SI 3 "=X,&h"))]
6149 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6150 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6151 [(set_attr "length" "2,3")])
6154 (define_insn "const_mulsidi3_v8plus"
6155 [(set (match_operand:DI 0 "register_operand" "=h,r")
6156 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6157 (match_operand:SI 2 "small_int" "I,I")))
6158 (clobber (match_scratch:SI 3 "=X,&h"))]
6161 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6162 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6163 [(set_attr "length" "2,3")])
6166 (define_insn "*mulsidi3_sp32"
6167 [(set (match_operand:DI 0 "register_operand" "=r")
6168 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6169 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6173 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6175 [(set (attr "length")
6176 (if_then_else (eq_attr "isa" "sparclet")
6177 (const_int 1) (const_int 2)))])
6179 (define_insn "*mulsidi3_sp64"
6180 [(set (match_operand:DI 0 "register_operand" "=r")
6181 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6182 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6183 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6185 [(set_attr "length" "1")])
6187 ;; Extra pattern, because sign_extend of a constant isn't valid.
6190 (define_insn "const_mulsidi3_sp32"
6191 [(set (match_operand:DI 0 "register_operand" "=r")
6192 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6193 (match_operand:SI 2 "small_int" "I")))]
6197 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6199 [(set (attr "length")
6200 (if_then_else (eq_attr "isa" "sparclet")
6201 (const_int 1) (const_int 2)))])
6203 (define_insn "const_mulsidi3_sp64"
6204 [(set (match_operand:DI 0 "register_operand" "=r")
6205 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6206 (match_operand:SI 2 "small_int" "I")))]
6207 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6209 [(set_attr "length" "1")])
6211 (define_expand "smulsi3_highpart"
6212 [(set (match_operand:SI 0 "register_operand" "")
6214 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6215 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6217 "TARGET_HARD_MUL && TARGET_ARCH32"
6220 if (CONSTANT_P (operands[2]))
6224 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6230 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6235 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6236 operands[2], GEN_INT (32)));
6242 (define_insn "smulsi3_highpart_v8plus"
6243 [(set (match_operand:SI 0 "register_operand" "=h,r")
6245 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6246 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6247 (match_operand:SI 3 "const_int_operand" "i,i"))))
6248 (clobber (match_scratch:SI 4 "=X,&h"))]
6251 smul\\t%1, %2, %0\;srlx\\t%0, %3, %0
6252 smul\\t%1, %2, %4\;srlx\\t%4, %3, %0"
6253 [(set_attr "length" "2")])
6255 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6258 [(set (match_operand:SI 0 "register_operand" "=h,r")
6261 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6262 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6263 (match_operand:SI 3 "const_int_operand" "i,i"))
6265 (clobber (match_scratch:SI 4 "=X,&h"))]
6268 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6269 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6270 [(set_attr "length" "2")])
6273 (define_insn "const_smulsi3_highpart_v8plus"
6274 [(set (match_operand:SI 0 "register_operand" "=h,r")
6276 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6277 (match_operand 2 "small_int" "i,i"))
6278 (match_operand:SI 3 "const_int_operand" "i,i"))))
6279 (clobber (match_scratch:SI 4 "=X,&h"))]
6282 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6283 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6284 [(set_attr "length" "2")])
6287 (define_insn "*smulsi3_highpart_sp32"
6288 [(set (match_operand:SI 0 "register_operand" "=r")
6290 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6291 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6294 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6295 [(set_attr "length" "2")])
6298 (define_insn "const_smulsi3_highpart"
6299 [(set (match_operand:SI 0 "register_operand" "=r")
6301 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6302 (match_operand:SI 2 "register_operand" "r"))
6305 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6306 [(set_attr "length" "2")])
6308 (define_expand "umulsidi3"
6309 [(set (match_operand:DI 0 "register_operand" "")
6310 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6311 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6315 if (CONSTANT_P (operands[2]))
6318 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6321 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6327 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6333 (define_insn "umulsidi3_v8plus"
6334 [(set (match_operand:DI 0 "register_operand" "=h,r")
6335 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6336 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6337 (clobber (match_scratch:SI 3 "=X,&h"))]
6340 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6341 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6342 [(set_attr "length" "2,3")])
6345 (define_insn "*umulsidi3_sp32"
6346 [(set (match_operand:DI 0 "register_operand" "=r")
6347 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6348 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6352 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6354 [(set (attr "length")
6355 (if_then_else (eq_attr "isa" "sparclet")
6356 (const_int 1) (const_int 2)))])
6358 (define_insn "*umulsidi3_sp64"
6359 [(set (match_operand:DI 0 "register_operand" "=r")
6360 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6361 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6362 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6364 [(set_attr "length" "1")])
6366 ;; Extra pattern, because sign_extend of a constant isn't valid.
6369 (define_insn "const_umulsidi3_sp32"
6370 [(set (match_operand:DI 0 "register_operand" "=r")
6371 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6372 (match_operand:SI 2 "uns_small_int" "")))]
6376 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6378 [(set (attr "length")
6379 (if_then_else (eq_attr "isa" "sparclet")
6380 (const_int 1) (const_int 2)))])
6382 (define_insn "const_umulsidi3_sp64"
6383 [(set (match_operand:DI 0 "register_operand" "=r")
6384 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6385 (match_operand:SI 2 "uns_small_int" "")))]
6386 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6388 [(set_attr "length" "1")])
6391 (define_insn "const_umulsidi3_v8plus"
6392 [(set (match_operand:DI 0 "register_operand" "=h,r")
6393 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6394 (match_operand:SI 2 "uns_small_int" "")))
6395 (clobber (match_scratch:SI 3 "=X,h"))]
6398 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6399 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6400 [(set_attr "length" "2,3")])
6402 (define_expand "umulsi3_highpart"
6403 [(set (match_operand:SI 0 "register_operand" "")
6405 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6406 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6408 "TARGET_HARD_MUL && TARGET_ARCH32"
6411 if (CONSTANT_P (operands[2]))
6415 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6421 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6426 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6427 operands[2], GEN_INT (32)));
6433 (define_insn "umulsi3_highpart_v8plus"
6434 [(set (match_operand:SI 0 "register_operand" "=h,r")
6436 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6437 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6438 (match_operand:SI 3 "const_int_operand" "i,i"))))
6439 (clobber (match_scratch:SI 4 "=X,h"))]
6442 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6443 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6444 [(set_attr "length" "2")])
6447 (define_insn "const_umulsi3_highpart_v8plus"
6448 [(set (match_operand:SI 0 "register_operand" "=h,r")
6450 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6451 (match_operand:SI 2 "uns_small_int" ""))
6452 (match_operand:SI 3 "const_int_operand" "i,i"))))
6453 (clobber (match_scratch:SI 4 "=X,h"))]
6456 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6457 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6458 [(set_attr "length" "2")])
6461 (define_insn "*umulsi3_highpart_sp32"
6462 [(set (match_operand:SI 0 "register_operand" "=r")
6464 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6465 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6468 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6469 [(set_attr "length" "2")])
6472 (define_insn "const_umulsi3_highpart"
6473 [(set (match_operand:SI 0 "register_operand" "=r")
6475 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6476 (match_operand:SI 2 "uns_small_int" ""))
6479 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6480 [(set_attr "length" "2")])
6482 ;; The v8 architecture specifies that there must be 3 instructions between
6483 ;; a y register write and a use of it for correct results.
6485 (define_expand "divsi3"
6486 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6487 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6488 (match_operand:SI 2 "input_operand" "rI,m")))
6489 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6490 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6495 operands[3] = gen_reg_rtx(SImode);
6496 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6497 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6503 (define_insn "divsi3_sp32"
6504 [(set (match_operand:SI 0 "register_operand" "=r,r")
6505 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6506 (match_operand:SI 2 "input_operand" "rI,m")))
6507 (clobber (match_scratch:SI 3 "=&r,&r"))]
6508 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6512 if (which_alternative == 0)
6514 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6516 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6519 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6521 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\";
6523 [(set (attr "length")
6524 (if_then_else (eq_attr "isa" "v9")
6525 (const_int 4) (const_int 7)))])
6527 (define_insn "divsi3_sp64"
6528 [(set (match_operand:SI 0 "register_operand" "=r")
6529 (div:SI (match_operand:SI 1 "register_operand" "r")
6530 (match_operand:SI 2 "input_operand" "rI")))
6531 (use (match_operand:SI 3 "register_operand" "r"))]
6532 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6533 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6534 [(set_attr "length" "2")])
6536 (define_insn "divdi3"
6537 [(set (match_operand:DI 0 "register_operand" "=r")
6538 (div:DI (match_operand:DI 1 "register_operand" "r")
6539 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6541 "sdivx\\t%1, %2, %0")
6543 (define_insn "*cmp_sdiv_cc_set"
6545 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6546 (match_operand:SI 2 "arith_operand" "rI"))
6548 (set (match_operand:SI 0 "register_operand" "=r")
6549 (div:SI (match_dup 1) (match_dup 2)))
6550 (clobber (match_scratch:SI 3 "=&r"))]
6551 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6555 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6557 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6559 [(set (attr "length")
6560 (if_then_else (eq_attr "isa" "v9")
6561 (const_int 3) (const_int 6)))])
6564 (define_expand "udivsi3"
6565 [(set (match_operand:SI 0 "register_operand" "")
6566 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6567 (match_operand:SI 2 "input_operand" "")))]
6568 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6571 (define_insn "udivsi3_sp32"
6572 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6573 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6574 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6576 || TARGET_DEPRECATED_V8_INSNS)
6580 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6581 switch (which_alternative)
6584 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6586 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6588 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6591 [(set_attr "length" "5")])
6593 (define_insn "udivsi3_sp64"
6594 [(set (match_operand:SI 0 "register_operand" "=r")
6595 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6596 (match_operand:SI 2 "input_operand" "rI")))]
6597 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6598 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6599 [(set_attr "length" "2")])
6601 (define_insn "udivdi3"
6602 [(set (match_operand:DI 0 "register_operand" "=r")
6603 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6604 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6606 "udivx\\t%1, %2, %0")
6608 (define_insn "*cmp_udiv_cc_set"
6610 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6611 (match_operand:SI 2 "arith_operand" "rI"))
6613 (set (match_operand:SI 0 "register_operand" "=r")
6614 (udiv:SI (match_dup 1) (match_dup 2)))]
6616 || TARGET_DEPRECATED_V8_INSNS"
6620 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6622 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6624 [(set (attr "length")
6625 (if_then_else (eq_attr "isa" "v9")
6626 (const_int 2) (const_int 5)))])
6628 ; sparclet multiply/accumulate insns
6630 (define_insn "*smacsi"
6631 [(set (match_operand:SI 0 "register_operand" "=r")
6632 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6633 (match_operand:SI 2 "arith_operand" "rI"))
6634 (match_operand:SI 3 "register_operand" "0")))]
6637 [(set_attr "type" "imul")
6638 (set_attr "length" "1")])
6640 (define_insn "*smacdi"
6641 [(set (match_operand:DI 0 "register_operand" "=r")
6642 (plus:DI (mult:DI (sign_extend:DI
6643 (match_operand:SI 1 "register_operand" "%r"))
6645 (match_operand:SI 2 "register_operand" "r")))
6646 (match_operand:DI 3 "register_operand" "0")))]
6648 "smacd\\t%1, %2, %L0"
6649 [(set_attr "type" "imul")
6650 (set_attr "length" "1")])
6652 (define_insn "*umacdi"
6653 [(set (match_operand:DI 0 "register_operand" "=r")
6654 (plus:DI (mult:DI (zero_extend:DI
6655 (match_operand:SI 1 "register_operand" "%r"))
6657 (match_operand:SI 2 "register_operand" "r")))
6658 (match_operand:DI 3 "register_operand" "0")))]
6660 "umacd\\t%1, %2, %L0"
6661 [(set_attr "type" "imul")
6662 (set_attr "length" "1")])
6664 ;;- Boolean instructions
6665 ;; We define DImode `and' so with DImode `not' we can get
6666 ;; DImode `andn'. Other combinations are possible.
6668 (define_expand "anddi3"
6669 [(set (match_operand:DI 0 "register_operand" "")
6670 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6671 (match_operand:DI 2 "arith_double_operand" "")))]
6675 (define_insn "*anddi3_sp32"
6676 [(set (match_operand:DI 0 "register_operand" "=r,b")
6677 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6678 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6683 [(set_attr "type" "ialu,fp")
6684 (set_attr "length" "2,1")])
6686 (define_insn "*anddi3_sp64"
6687 [(set (match_operand:DI 0 "register_operand" "=r,b")
6688 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6689 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6694 [(set_attr "type" "ialu,fp")
6695 (set_attr "length" "1,1")])
6697 (define_insn "andsi3"
6698 [(set (match_operand:SI 0 "register_operand" "=r,d")
6699 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6700 (match_operand:SI 2 "arith_operand" "rI,d")))]
6705 [(set_attr "type" "ialu,fp")
6706 (set_attr "length" "1,1")])
6709 [(set (match_operand:SI 0 "register_operand" "")
6710 (and:SI (match_operand:SI 1 "register_operand" "")
6711 (match_operand:SI 2 "" "")))
6712 (clobber (match_operand:SI 3 "register_operand" ""))]
6713 "GET_CODE (operands[2]) == CONST_INT
6714 && !SMALL_INT32 (operands[2])
6715 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6716 [(set (match_dup 3) (match_dup 4))
6717 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6720 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6723 ;; Split DImode logical operations requiring two instructions.
6725 [(set (match_operand:DI 0 "register_operand" "")
6726 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6727 [(match_operand:DI 2 "register_operand" "")
6728 (match_operand:DI 3 "arith_double_operand" "")]))]
6731 && ((GET_CODE (operands[0]) == REG
6732 && REGNO (operands[0]) < 32)
6733 || (GET_CODE (operands[0]) == SUBREG
6734 && GET_CODE (SUBREG_REG (operands[0])) == REG
6735 && REGNO (SUBREG_REG (operands[0])) < 32))"
6736 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6737 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6740 if (GET_CODE (operands[0]) == SUBREG)
6741 operands[0] = alter_subreg (operands[0]);
6742 operands[4] = gen_highpart (SImode, operands[0]);
6743 operands[5] = gen_lowpart (SImode, operands[0]);
6744 operands[6] = gen_highpart (SImode, operands[2]);
6745 operands[7] = gen_lowpart (SImode, operands[2]);
6746 #if HOST_BITS_PER_WIDE_INT == 32
6747 if (GET_CODE (operands[3]) == CONST_INT)
6749 if (INTVAL (operands[3]) < 0)
6750 operands[8] = constm1_rtx;
6752 operands[8] = const0_rtx;
6756 operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
6757 operands[9] = gen_lowpart (SImode, operands[3]);
6760 (define_insn "*and_not_di_sp32"
6761 [(set (match_operand:DI 0 "register_operand" "=r,b")
6762 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6763 (match_operand:DI 2 "register_operand" "r,b")))]
6767 fandnot1\\t%1, %2, %0"
6768 [(set_attr "type" "ialu,fp")
6769 (set_attr "length" "2,1")])
6772 [(set (match_operand:DI 0 "register_operand" "")
6773 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6774 (match_operand:DI 2 "register_operand" "")))]
6777 && ((GET_CODE (operands[0]) == REG
6778 && REGNO (operands[0]) < 32)
6779 || (GET_CODE (operands[0]) == SUBREG
6780 && GET_CODE (SUBREG_REG (operands[0])) == REG
6781 && REGNO (SUBREG_REG (operands[0])) < 32))"
6782 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6783 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6784 "if (GET_CODE (operands[0]) == SUBREG)
6785 operands[0] = alter_subreg (operands[0]);
6786 operands[3] = gen_highpart (SImode, operands[0]);
6787 operands[4] = gen_highpart (SImode, operands[1]);
6788 operands[5] = gen_highpart (SImode, operands[2]);
6789 operands[6] = gen_lowpart (SImode, operands[0]);
6790 operands[7] = gen_lowpart (SImode, operands[1]);
6791 operands[8] = gen_lowpart (SImode, operands[2]);")
6793 (define_insn "*and_not_di_sp64"
6794 [(set (match_operand:DI 0 "register_operand" "=r,b")
6795 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6796 (match_operand:DI 2 "register_operand" "r,b")))]
6800 fandnot1\\t%1, %2, %0"
6801 [(set_attr "type" "ialu,fp")
6802 (set_attr "length" "1,1")])
6804 (define_insn "*and_not_si"
6805 [(set (match_operand:SI 0 "register_operand" "=r,d")
6806 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6807 (match_operand:SI 2 "register_operand" "r,d")))]
6811 fandnot1s\\t%1, %2, %0"
6812 [(set_attr "type" "ialu,fp")
6813 (set_attr "length" "1,1")])
6815 (define_expand "iordi3"
6816 [(set (match_operand:DI 0 "register_operand" "")
6817 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6818 (match_operand:DI 2 "arith_double_operand" "")))]
6822 (define_insn "*iordi3_sp32"
6823 [(set (match_operand:DI 0 "register_operand" "=r,b")
6824 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6825 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6830 [(set_attr "type" "ialu,fp")
6831 (set_attr "length" "2,1")])
6833 (define_insn "*iordi3_sp64"
6834 [(set (match_operand:DI 0 "register_operand" "=r,b")
6835 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6836 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6841 [(set_attr "type" "ialu,fp")
6842 (set_attr "length" "1,1")])
6844 (define_insn "iorsi3"
6845 [(set (match_operand:SI 0 "register_operand" "=r,d")
6846 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6847 (match_operand:SI 2 "arith_operand" "rI,d")))]
6852 [(set_attr "type" "ialu,fp")
6853 (set_attr "length" "1,1")])
6856 [(set (match_operand:SI 0 "register_operand" "")
6857 (ior:SI (match_operand:SI 1 "register_operand" "")
6858 (match_operand:SI 2 "" "")))
6859 (clobber (match_operand:SI 3 "register_operand" ""))]
6860 "GET_CODE (operands[2]) == CONST_INT
6861 && !SMALL_INT32 (operands[2])
6862 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6863 [(set (match_dup 3) (match_dup 4))
6864 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6867 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6870 (define_insn "*or_not_di_sp32"
6871 [(set (match_operand:DI 0 "register_operand" "=r,b")
6872 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6873 (match_operand:DI 2 "register_operand" "r,b")))]
6877 fornot1\\t%1, %2, %0"
6878 [(set_attr "type" "ialu,fp")
6879 (set_attr "length" "2,1")])
6882 [(set (match_operand:DI 0 "register_operand" "")
6883 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6884 (match_operand:DI 2 "register_operand" "")))]
6887 && ((GET_CODE (operands[0]) == REG
6888 && REGNO (operands[0]) < 32)
6889 || (GET_CODE (operands[0]) == SUBREG
6890 && GET_CODE (SUBREG_REG (operands[0])) == REG
6891 && REGNO (SUBREG_REG (operands[0])) < 32))"
6892 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6893 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6894 "if (GET_CODE (operands[0]) == SUBREG)
6895 operands[0] = alter_subreg (operands[0]);
6896 operands[3] = gen_highpart (SImode, operands[0]);
6897 operands[4] = gen_highpart (SImode, operands[1]);
6898 operands[5] = gen_highpart (SImode, operands[2]);
6899 operands[6] = gen_lowpart (SImode, operands[0]);
6900 operands[7] = gen_lowpart (SImode, operands[1]);
6901 operands[8] = gen_lowpart (SImode, operands[2]);")
6903 (define_insn "*or_not_di_sp64"
6904 [(set (match_operand:DI 0 "register_operand" "=r,b")
6905 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6906 (match_operand:DI 2 "register_operand" "r,b")))]
6910 fornot1\\t%1, %2, %0"
6911 [(set_attr "type" "ialu,fp")
6912 (set_attr "length" "1,1")])
6914 (define_insn "*or_not_si"
6915 [(set (match_operand:SI 0 "register_operand" "=r,d")
6916 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6917 (match_operand:SI 2 "register_operand" "r,d")))]
6921 fornot1s\\t%1, %2, %0"
6922 [(set_attr "type" "ialu,fp")
6923 (set_attr "length" "1,1")])
6925 (define_expand "xordi3"
6926 [(set (match_operand:DI 0 "register_operand" "")
6927 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6928 (match_operand:DI 2 "arith_double_operand" "")))]
6932 (define_insn "*xordi3_sp32"
6933 [(set (match_operand:DI 0 "register_operand" "=r,b")
6934 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6935 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6940 [(set_attr "length" "2,1")
6941 (set_attr "type" "ialu,fp")])
6943 (define_insn "*xordi3_sp64"
6944 [(set (match_operand:DI 0 "register_operand" "=r,b")
6945 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6946 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6951 [(set_attr "type" "ialu,fp")
6952 (set_attr "length" "1,1")])
6954 (define_insn "*xordi3_sp64_dbl"
6955 [(set (match_operand:DI 0 "register_operand" "=r")
6956 (xor:DI (match_operand:DI 1 "register_operand" "r")
6957 (match_operand:DI 2 "const64_operand" "")))]
6959 && HOST_BITS_PER_WIDE_INT != 64)"
6961 [(set_attr "type" "ialu")
6962 (set_attr "length" "1")])
6964 (define_insn "xorsi3"
6965 [(set (match_operand:SI 0 "register_operand" "=r,d")
6966 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6967 (match_operand:SI 2 "arith_operand" "rI,d")))]
6972 [(set_attr "type" "ialu,fp")
6973 (set_attr "length" "1,1")])
6976 [(set (match_operand:SI 0 "register_operand" "")
6977 (xor:SI (match_operand:SI 1 "register_operand" "")
6978 (match_operand:SI 2 "" "")))
6979 (clobber (match_operand:SI 3 "register_operand" ""))]
6980 "GET_CODE (operands[2]) == CONST_INT
6981 && !SMALL_INT32 (operands[2])
6982 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6983 [(set (match_dup 3) (match_dup 4))
6984 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6987 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6991 [(set (match_operand:SI 0 "register_operand" "")
6992 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6993 (match_operand:SI 2 "" ""))))
6994 (clobber (match_operand:SI 3 "register_operand" ""))]
6995 "GET_CODE (operands[2]) == CONST_INT
6996 && !SMALL_INT32 (operands[2])
6997 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6998 [(set (match_dup 3) (match_dup 4))
6999 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
7002 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
7005 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
7006 ;; Combine now canonicalizes to the rightmost expression.
7007 (define_insn "*xor_not_di_sp32"
7008 [(set (match_operand:DI 0 "register_operand" "=r,b")
7009 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
7010 (match_operand:DI 2 "register_operand" "r,b"))))]
7015 [(set_attr "length" "2,1")
7016 (set_attr "type" "ialu,fp")])
7019 [(set (match_operand:DI 0 "register_operand" "")
7020 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
7021 (match_operand:DI 2 "register_operand" ""))))]
7024 && ((GET_CODE (operands[0]) == REG
7025 && REGNO (operands[0]) < 32)
7026 || (GET_CODE (operands[0]) == SUBREG
7027 && GET_CODE (SUBREG_REG (operands[0])) == REG
7028 && REGNO (SUBREG_REG (operands[0])) < 32))"
7029 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
7030 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
7031 "if (GET_CODE (operands[0]) == SUBREG)
7032 operands[0] = alter_subreg (operands[0]);
7033 operands[3] = gen_highpart (SImode, operands[0]);
7034 operands[4] = gen_highpart (SImode, operands[1]);
7035 operands[5] = gen_highpart (SImode, operands[2]);
7036 operands[6] = gen_lowpart (SImode, operands[0]);
7037 operands[7] = gen_lowpart (SImode, operands[1]);
7038 operands[8] = gen_lowpart (SImode, operands[2]);")
7040 (define_insn "*xor_not_di_sp64"
7041 [(set (match_operand:DI 0 "register_operand" "=r,b")
7042 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7043 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7048 [(set_attr "type" "ialu,fp")
7049 (set_attr "length" "1,1")])
7051 (define_insn "*xor_not_si"
7052 [(set (match_operand:SI 0 "register_operand" "=r,d")
7053 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7054 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7058 fxnors\\t%1, %2, %0"
7059 [(set_attr "type" "ialu,fp")
7060 (set_attr "length" "1,1")])
7062 ;; These correspond to the above in the case where we also (or only)
7063 ;; want to set the condition code.
7065 (define_insn "*cmp_cc_arith_op"
7068 (match_operator:SI 2 "cc_arithop"
7069 [(match_operand:SI 0 "arith_operand" "%r")
7070 (match_operand:SI 1 "arith_operand" "rI")])
7073 "%A2cc\\t%0, %1, %%g0"
7074 [(set_attr "type" "compare")
7075 (set_attr "length" "1")])
7077 (define_insn "*cmp_ccx_arith_op"
7080 (match_operator:DI 2 "cc_arithop"
7081 [(match_operand:DI 0 "arith_double_operand" "%r")
7082 (match_operand:DI 1 "arith_double_operand" "rHI")])
7085 "%A2cc\\t%0, %1, %%g0"
7086 [(set_attr "type" "compare")
7087 (set_attr "length" "1")])
7089 (define_insn "*cmp_cc_arith_op_set"
7092 (match_operator:SI 3 "cc_arithop"
7093 [(match_operand:SI 1 "arith_operand" "%r")
7094 (match_operand:SI 2 "arith_operand" "rI")])
7096 (set (match_operand:SI 0 "register_operand" "=r")
7097 (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7098 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7099 "%A3cc\\t%1, %2, %0"
7100 [(set_attr "type" "compare")
7101 (set_attr "length" "1")])
7103 (define_insn "*cmp_ccx_arith_op_set"
7106 (match_operator:DI 3 "cc_arithop"
7107 [(match_operand:DI 1 "arith_double_operand" "%r")
7108 (match_operand:DI 2 "arith_double_operand" "rHI")])
7110 (set (match_operand:DI 0 "register_operand" "=r")
7111 (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
7112 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7113 "%A3cc\\t%1, %2, %0"
7114 [(set_attr "type" "compare")
7115 (set_attr "length" "1")])
7117 (define_insn "*cmp_cc_xor_not"
7120 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7121 (match_operand:SI 1 "arith_operand" "rI")))
7124 "xnorcc\\t%r0, %1, %%g0"
7125 [(set_attr "type" "compare")
7126 (set_attr "length" "1")])
7128 (define_insn "*cmp_ccx_xor_not"
7131 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7132 (match_operand:DI 1 "arith_double_operand" "rHI")))
7135 "xnorcc\\t%r0, %1, %%g0"
7136 [(set_attr "type" "compare")
7137 (set_attr "length" "1")])
7139 (define_insn "*cmp_cc_xor_not_set"
7142 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7143 (match_operand:SI 2 "arith_operand" "rI")))
7145 (set (match_operand:SI 0 "register_operand" "=r")
7146 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7148 "xnorcc\\t%r1, %2, %0"
7149 [(set_attr "type" "compare")
7150 (set_attr "length" "1")])
7152 (define_insn "*cmp_ccx_xor_not_set"
7155 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7156 (match_operand:DI 2 "arith_double_operand" "rHI")))
7158 (set (match_operand:DI 0 "register_operand" "=r")
7159 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7161 "xnorcc\\t%r1, %2, %0"
7162 [(set_attr "type" "compare")
7163 (set_attr "length" "1")])
7165 (define_insn "*cmp_cc_arith_op_not"
7168 (match_operator:SI 2 "cc_arithopn"
7169 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7170 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7173 "%B2cc\\t%r1, %0, %%g0"
7174 [(set_attr "type" "compare")
7175 (set_attr "length" "1")])
7177 (define_insn "*cmp_ccx_arith_op_not"
7180 (match_operator:DI 2 "cc_arithopn"
7181 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7182 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7185 "%B2cc\\t%r1, %0, %%g0"
7186 [(set_attr "type" "compare")
7187 (set_attr "length" "1")])
7189 (define_insn "*cmp_cc_arith_op_not_set"
7192 (match_operator:SI 3 "cc_arithopn"
7193 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7194 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7196 (set (match_operand:SI 0 "register_operand" "=r")
7197 (match_operator:SI 4 "cc_arithopn"
7198 [(not:SI (match_dup 1)) (match_dup 2)]))]
7199 "GET_CODE (operands[3]) == GET_CODE (operands[4])"
7200 "%B3cc\\t%r2, %1, %0"
7201 [(set_attr "type" "compare")
7202 (set_attr "length" "1")])
7204 (define_insn "*cmp_ccx_arith_op_not_set"
7207 (match_operator:DI 3 "cc_arithopn"
7208 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7209 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7211 (set (match_operand:DI 0 "register_operand" "=r")
7212 (match_operator:DI 4 "cc_arithopn"
7213 [(not:DI (match_dup 1)) (match_dup 2)]))]
7214 "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
7215 "%B3cc\\t%r2, %1, %0"
7216 [(set_attr "type" "compare")
7217 (set_attr "length" "1")])
7219 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7220 ;; does not know how to make it work for constants.
7222 (define_expand "negdi2"
7223 [(set (match_operand:DI 0 "register_operand" "=r")
7224 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7228 if (! TARGET_ARCH64)
7230 emit_insn (gen_rtx_PARALLEL
7233 gen_rtx_SET (VOIDmode, operand0,
7234 gen_rtx_NEG (DImode, operand1)),
7235 gen_rtx_CLOBBER (VOIDmode,
7236 gen_rtx_REG (CCmode,
7242 (define_insn "*negdi2_sp32"
7243 [(set (match_operand:DI 0 "register_operand" "=r")
7244 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7245 (clobber (reg:CC 100))]
7248 [(set_attr "length" "2")])
7251 [(set (match_operand:DI 0 "register_operand" "")
7252 (neg:DI (match_operand:DI 1 "register_operand" "")))
7253 (clobber (reg:CC 100))]
7255 && reload_completed"
7256 [(parallel [(set (reg:CC_NOOV 100)
7257 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7259 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7260 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7261 (ltu:SI (reg:CC 100) (const_int 0))))]
7262 "operands[2] = gen_highpart (SImode, operands[0]);
7263 operands[3] = gen_highpart (SImode, operands[1]);
7264 operands[4] = gen_lowpart (SImode, operands[0]);
7265 operands[5] = gen_lowpart (SImode, operands[1]);")
7267 (define_insn "*negdi2_sp64"
7268 [(set (match_operand:DI 0 "register_operand" "=r")
7269 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7271 "sub\\t%%g0, %1, %0"
7272 [(set_attr "length" "1")])
7274 (define_insn "negsi2"
7275 [(set (match_operand:SI 0 "register_operand" "=r")
7276 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7278 "sub\\t%%g0, %1, %0"
7279 [(set_attr "length" "1")])
7281 (define_insn "*cmp_cc_neg"
7282 [(set (reg:CC_NOOV 100)
7283 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7286 "subcc\\t%%g0, %0, %%g0"
7287 [(set_attr "type" "compare")
7288 (set_attr "length" "1")])
7290 (define_insn "*cmp_ccx_neg"
7291 [(set (reg:CCX_NOOV 100)
7292 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7295 "subcc\\t%%g0, %0, %%g0"
7296 [(set_attr "type" "compare")
7297 (set_attr "length" "1")])
7299 (define_insn "*cmp_cc_set_neg"
7300 [(set (reg:CC_NOOV 100)
7301 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7303 (set (match_operand:SI 0 "register_operand" "=r")
7304 (neg:SI (match_dup 1)))]
7306 "subcc\\t%%g0, %1, %0"
7307 [(set_attr "type" "compare")
7308 (set_attr "length" "1")])
7310 (define_insn "*cmp_ccx_set_neg"
7311 [(set (reg:CCX_NOOV 100)
7312 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7314 (set (match_operand:DI 0 "register_operand" "=r")
7315 (neg:DI (match_dup 1)))]
7317 "subcc\\t%%g0, %1, %0"
7318 [(set_attr "type" "compare")
7319 (set_attr "length" "1")])
7321 ;; We cannot use the "not" pseudo insn because the Sun assembler
7322 ;; does not know how to make it work for constants.
7323 (define_expand "one_cmpldi2"
7324 [(set (match_operand:DI 0 "register_operand" "")
7325 (not:DI (match_operand:DI 1 "register_operand" "")))]
7329 (define_insn "*one_cmpldi2_sp32"
7330 [(set (match_operand:DI 0 "register_operand" "=r,b")
7331 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7336 [(set_attr "type" "*,fp")
7337 (set_attr "length" "2,1")])
7340 [(set (match_operand:DI 0 "register_operand" "")
7341 (not:DI (match_operand:DI 1 "register_operand" "")))]
7344 && ((GET_CODE (operands[0]) == REG
7345 && REGNO (operands[0]) < 32)
7346 || (GET_CODE (operands[0]) == SUBREG
7347 && GET_CODE (SUBREG_REG (operands[0])) == REG
7348 && REGNO (SUBREG_REG (operands[0])) < 32))"
7349 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7350 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7351 "if (GET_CODE (operands[0]) == SUBREG)
7352 operands[0] = alter_subreg (operands[0]);
7353 operands[2] = gen_highpart (SImode, operands[0]);
7354 operands[3] = gen_highpart (SImode, operands[1]);
7355 operands[4] = gen_lowpart (SImode, operands[0]);
7356 operands[5] = gen_lowpart (SImode, operands[1]);")
7358 (define_insn "*one_cmpldi2_sp64"
7359 [(set (match_operand:DI 0 "register_operand" "=r,b")
7360 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7365 [(set_attr "type" "*,fp")
7366 (set_attr "length" "1")])
7368 (define_insn "one_cmplsi2"
7369 [(set (match_operand:SI 0 "register_operand" "=r,d")
7370 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7375 [(set_attr "type" "*,fp")
7376 (set_attr "length" "1,1")])
7378 (define_insn "*cmp_cc_not"
7380 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7383 "xnorcc\\t%%g0, %0, %%g0"
7384 [(set_attr "type" "compare")
7385 (set_attr "length" "1")])
7387 (define_insn "*cmp_ccx_not"
7389 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7392 "xnorcc\\t%%g0, %0, %%g0"
7393 [(set_attr "type" "compare")
7394 (set_attr "length" "1")])
7396 (define_insn "*cmp_cc_set_not"
7398 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7400 (set (match_operand:SI 0 "register_operand" "=r")
7401 (not:SI (match_dup 1)))]
7403 "xnorcc\\t%%g0, %1, %0"
7404 [(set_attr "type" "compare")
7405 (set_attr "length" "1")])
7407 (define_insn "*cmp_ccx_set_not"
7409 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7411 (set (match_operand:DI 0 "register_operand" "=r")
7412 (not:DI (match_dup 1)))]
7414 "xnorcc\\t%%g0, %1, %0"
7415 [(set_attr "type" "compare")
7416 (set_attr "length" "1")])
7418 ;; Floating point arithmetic instructions.
7420 (define_expand "addtf3"
7421 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7422 (plus:TF (match_operand:TF 1 "general_operand" "")
7423 (match_operand:TF 2 "general_operand" "")))]
7424 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7427 if (! TARGET_HARD_QUAD)
7429 rtx slot0, slot1, slot2;
7431 if (GET_CODE (operands[0]) != MEM)
7432 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7434 slot0 = operands[0];
7435 if (GET_CODE (operands[1]) != MEM)
7437 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7438 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7441 slot1 = operands[1];
7442 if (GET_CODE (operands[2]) != MEM)
7444 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7445 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7448 slot2 = operands[2];
7450 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7452 XEXP (slot0, 0), Pmode,
7453 XEXP (slot1, 0), Pmode,
7454 XEXP (slot2, 0), Pmode);
7456 if (GET_CODE (operands[0]) != MEM)
7457 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7462 (define_insn "*addtf3_hq"
7463 [(set (match_operand:TF 0 "register_operand" "=e")
7464 (plus:TF (match_operand:TF 1 "register_operand" "e")
7465 (match_operand:TF 2 "register_operand" "e")))]
7466 "TARGET_FPU && TARGET_HARD_QUAD"
7467 "faddq\\t%1, %2, %0"
7468 [(set_attr "type" "fp")
7469 (set_attr "length" "1")])
7471 (define_insn "adddf3"
7472 [(set (match_operand:DF 0 "register_operand" "=e")
7473 (plus:DF (match_operand:DF 1 "register_operand" "e")
7474 (match_operand:DF 2 "register_operand" "e")))]
7476 "faddd\\t%1, %2, %0"
7477 [(set_attr "type" "fp")
7478 (set_attr "length" "1")])
7480 (define_insn "addsf3"
7481 [(set (match_operand:SF 0 "register_operand" "=f")
7482 (plus:SF (match_operand:SF 1 "register_operand" "f")
7483 (match_operand:SF 2 "register_operand" "f")))]
7485 "fadds\\t%1, %2, %0"
7486 [(set_attr "type" "fp")
7487 (set_attr "length" "1")])
7489 (define_expand "subtf3"
7490 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7491 (minus:TF (match_operand:TF 1 "general_operand" "")
7492 (match_operand:TF 2 "general_operand" "")))]
7493 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7496 if (! TARGET_HARD_QUAD)
7498 rtx slot0, slot1, slot2;
7500 if (GET_CODE (operands[0]) != MEM)
7501 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7503 slot0 = operands[0];
7504 if (GET_CODE (operands[1]) != MEM)
7506 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7507 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7510 slot1 = operands[1];
7511 if (GET_CODE (operands[2]) != MEM)
7513 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7514 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7517 slot2 = operands[2];
7519 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7521 XEXP (slot0, 0), Pmode,
7522 XEXP (slot1, 0), Pmode,
7523 XEXP (slot2, 0), Pmode);
7525 if (GET_CODE (operands[0]) != MEM)
7526 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7531 (define_insn "*subtf3_hq"
7532 [(set (match_operand:TF 0 "register_operand" "=e")
7533 (minus:TF (match_operand:TF 1 "register_operand" "e")
7534 (match_operand:TF 2 "register_operand" "e")))]
7535 "TARGET_FPU && TARGET_HARD_QUAD"
7536 "fsubq\\t%1, %2, %0"
7537 [(set_attr "type" "fp")
7538 (set_attr "length" "1")])
7540 (define_insn "subdf3"
7541 [(set (match_operand:DF 0 "register_operand" "=e")
7542 (minus:DF (match_operand:DF 1 "register_operand" "e")
7543 (match_operand:DF 2 "register_operand" "e")))]
7545 "fsubd\\t%1, %2, %0"
7546 [(set_attr "type" "fp")
7547 (set_attr "length" "1")])
7549 (define_insn "subsf3"
7550 [(set (match_operand:SF 0 "register_operand" "=f")
7551 (minus:SF (match_operand:SF 1 "register_operand" "f")
7552 (match_operand:SF 2 "register_operand" "f")))]
7554 "fsubs\\t%1, %2, %0"
7555 [(set_attr "type" "fp")
7556 (set_attr "length" "1")])
7558 (define_expand "multf3"
7559 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7560 (mult:TF (match_operand:TF 1 "general_operand" "")
7561 (match_operand:TF 2 "general_operand" "")))]
7562 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7565 if (! TARGET_HARD_QUAD)
7567 rtx slot0, slot1, slot2;
7569 if (GET_CODE (operands[0]) != MEM)
7570 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7572 slot0 = operands[0];
7573 if (GET_CODE (operands[1]) != MEM)
7575 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7576 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7579 slot1 = operands[1];
7580 if (GET_CODE (operands[2]) != MEM)
7582 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7583 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7586 slot2 = operands[2];
7588 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7590 XEXP (slot0, 0), Pmode,
7591 XEXP (slot1, 0), Pmode,
7592 XEXP (slot2, 0), Pmode);
7594 if (GET_CODE (operands[0]) != MEM)
7595 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7600 (define_insn "*multf3_hq"
7601 [(set (match_operand:TF 0 "register_operand" "=e")
7602 (mult:TF (match_operand:TF 1 "register_operand" "e")
7603 (match_operand:TF 2 "register_operand" "e")))]
7604 "TARGET_FPU && TARGET_HARD_QUAD"
7605 "fmulq\\t%1, %2, %0"
7606 [(set_attr "type" "fpmul")
7607 (set_attr "length" "1")])
7609 (define_insn "muldf3"
7610 [(set (match_operand:DF 0 "register_operand" "=e")
7611 (mult:DF (match_operand:DF 1 "register_operand" "e")
7612 (match_operand:DF 2 "register_operand" "e")))]
7614 "fmuld\\t%1, %2, %0"
7615 [(set_attr "type" "fpmul")
7616 (set_attr "length" "1")])
7618 (define_insn "mulsf3"
7619 [(set (match_operand:SF 0 "register_operand" "=f")
7620 (mult:SF (match_operand:SF 1 "register_operand" "f")
7621 (match_operand:SF 2 "register_operand" "f")))]
7623 "fmuls\\t%1, %2, %0"
7624 [(set_attr "type" "fpmul")
7625 (set_attr "length" "1")])
7627 (define_insn "*muldf3_extend"
7628 [(set (match_operand:DF 0 "register_operand" "=e")
7629 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7630 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7631 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7632 "fsmuld\\t%1, %2, %0"
7633 [(set_attr "type" "fpmul")
7634 (set_attr "length" "1")])
7636 (define_insn "*multf3_extend"
7637 [(set (match_operand:TF 0 "register_operand" "=e")
7638 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7639 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7640 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7641 "fdmulq\\t%1, %2, %0"
7642 [(set_attr "type" "fpmul")
7643 (set_attr "length" "1")])
7645 (define_expand "divtf3"
7646 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7647 (div:TF (match_operand:TF 1 "general_operand" "")
7648 (match_operand:TF 2 "general_operand" "")))]
7649 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7652 if (! TARGET_HARD_QUAD)
7654 rtx slot0, slot1, slot2;
7656 if (GET_CODE (operands[0]) != MEM)
7657 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7659 slot0 = operands[0];
7660 if (GET_CODE (operands[1]) != MEM)
7662 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7663 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7666 slot1 = operands[1];
7667 if (GET_CODE (operands[2]) != MEM)
7669 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7670 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7673 slot2 = operands[2];
7675 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7677 XEXP (slot0, 0), Pmode,
7678 XEXP (slot1, 0), Pmode,
7679 XEXP (slot2, 0), Pmode);
7681 if (GET_CODE (operands[0]) != MEM)
7682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7687 ;; don't have timing for quad-prec. divide.
7688 (define_insn "*divtf3_hq"
7689 [(set (match_operand:TF 0 "register_operand" "=e")
7690 (div:TF (match_operand:TF 1 "register_operand" "e")
7691 (match_operand:TF 2 "register_operand" "e")))]
7692 "TARGET_FPU && TARGET_HARD_QUAD"
7693 "fdivq\\t%1, %2, %0"
7694 [(set_attr "type" "fpdivd")
7695 (set_attr "length" "1")])
7697 (define_insn "divdf3"
7698 [(set (match_operand:DF 0 "register_operand" "=e")
7699 (div:DF (match_operand:DF 1 "register_operand" "e")
7700 (match_operand:DF 2 "register_operand" "e")))]
7702 "fdivd\\t%1, %2, %0"
7703 [(set_attr "type" "fpdivd")
7704 (set_attr "length" "1")])
7706 (define_insn "divsf3"
7707 [(set (match_operand:SF 0 "register_operand" "=f")
7708 (div:SF (match_operand:SF 1 "register_operand" "f")
7709 (match_operand:SF 2 "register_operand" "f")))]
7711 "fdivs\\t%1, %2, %0"
7712 [(set_attr "type" "fpdivs")
7713 (set_attr "length" "1")])
7715 (define_expand "negtf2"
7716 [(set (match_operand:TF 0 "register_operand" "=e,e")
7717 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7721 (define_insn "*negtf2_notv9"
7722 [(set (match_operand:TF 0 "register_operand" "=e,e")
7723 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7724 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7730 [(set_attr "type" "fpmove")
7731 (set_attr "length" "1,2")])
7734 [(set (match_operand:TF 0 "register_operand" "")
7735 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7739 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7740 [(set (match_dup 2) (neg:SF (match_dup 3)))
7741 (set (match_dup 4) (match_dup 5))
7742 (set (match_dup 6) (match_dup 7))]
7743 "if (GET_CODE (operands[0]) == SUBREG)
7744 operands[0] = alter_subreg (operands[0]);
7745 if (GET_CODE (operands[1]) == SUBREG)
7746 operands[1] = alter_subreg (operands[1]);
7747 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7748 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7749 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7750 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7751 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7752 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7754 (define_insn "*negtf2_v9"
7755 [(set (match_operand:TF 0 "register_operand" "=e,e")
7756 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7757 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7758 "TARGET_FPU && TARGET_V9"
7762 [(set_attr "type" "fpmove")
7763 (set_attr "length" "1,2")])
7766 [(set (match_operand:TF 0 "register_operand" "")
7767 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7771 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7772 [(set (match_dup 2) (neg:DF (match_dup 3)))
7773 (set (match_dup 4) (match_dup 5))]
7774 "if (GET_CODE (operands[0]) == SUBREG)
7775 operands[0] = alter_subreg (operands[0]);
7776 if (GET_CODE (operands[1]) == SUBREG)
7777 operands[1] = alter_subreg (operands[1]);
7778 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7779 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7780 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7781 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7783 (define_expand "negdf2"
7784 [(set (match_operand:DF 0 "register_operand" "")
7785 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7789 (define_insn "*negdf2_notv9"
7790 [(set (match_operand:DF 0 "register_operand" "=e,e")
7791 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7792 "TARGET_FPU && ! TARGET_V9"
7796 [(set_attr "type" "fpmove")
7797 (set_attr "length" "1,2")])
7800 [(set (match_operand:DF 0 "register_operand" "")
7801 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7805 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7806 [(set (match_dup 2) (neg:SF (match_dup 3)))
7807 (set (match_dup 4) (match_dup 5))]
7808 "if (GET_CODE (operands[0]) == SUBREG)
7809 operands[0] = alter_subreg (operands[0]);
7810 if (GET_CODE (operands[1]) == SUBREG)
7811 operands[1] = alter_subreg (operands[1]);
7812 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7813 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7814 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7815 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7817 (define_insn "*negdf2_v9"
7818 [(set (match_operand:DF 0 "register_operand" "=e")
7819 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7820 "TARGET_FPU && TARGET_V9"
7822 [(set_attr "type" "fpmove")
7823 (set_attr "length" "1")])
7825 (define_insn "negsf2"
7826 [(set (match_operand:SF 0 "register_operand" "=f")
7827 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7830 [(set_attr "type" "fpmove")
7831 (set_attr "length" "1")])
7833 (define_expand "abstf2"
7834 [(set (match_operand:TF 0 "register_operand" "")
7835 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7839 (define_insn "*abstf2_notv9"
7840 [(set (match_operand:TF 0 "register_operand" "=e,e")
7841 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7842 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7843 "TARGET_FPU && ! TARGET_V9"
7847 [(set_attr "type" "fpmove")
7848 (set_attr "length" "1,2")])
7851 [(set (match_operand:TF 0 "register_operand" "")
7852 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7856 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7857 [(set (match_dup 2) (abs:SF (match_dup 3)))
7858 (set (match_dup 4) (match_dup 5))
7859 (set (match_dup 6) (match_dup 7))]
7860 "if (GET_CODE (operands[0]) == SUBREG)
7861 operands[0] = alter_subreg (operands[0]);
7862 if (GET_CODE (operands[1]) == SUBREG)
7863 operands[1] = alter_subreg (operands[1]);
7864 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7865 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7866 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7867 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7868 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7869 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7871 (define_insn "*abstf2_hq_v9"
7872 [(set (match_operand:TF 0 "register_operand" "=e,e")
7873 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7874 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7878 [(set_attr "type" "fpmove")
7879 (set_attr "length" "1")])
7881 (define_insn "*abstf2_v9"
7882 [(set (match_operand:TF 0 "register_operand" "=e,e")
7883 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7884 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7888 [(set_attr "type" "fpmove")
7889 (set_attr "length" "1,2")])
7892 [(set (match_operand:TF 0 "register_operand" "")
7893 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7897 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7898 [(set (match_dup 2) (abs:DF (match_dup 3)))
7899 (set (match_dup 4) (match_dup 5))]
7900 "if (GET_CODE (operands[0]) == SUBREG)
7901 operands[0] = alter_subreg (operands[0]);
7902 if (GET_CODE (operands[1]) == SUBREG)
7903 operands[1] = alter_subreg (operands[1]);
7904 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7905 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7906 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7907 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7909 (define_expand "absdf2"
7910 [(set (match_operand:DF 0 "register_operand" "")
7911 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7915 (define_insn "*absdf2_notv9"
7916 [(set (match_operand:DF 0 "register_operand" "=e,e")
7917 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7918 "TARGET_FPU && ! TARGET_V9"
7922 [(set_attr "type" "fpmove")
7923 (set_attr "length" "1,2")])
7926 [(set (match_operand:DF 0 "register_operand" "")
7927 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7931 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7932 [(set (match_dup 2) (abs:SF (match_dup 3)))
7933 (set (match_dup 4) (match_dup 5))]
7934 "if (GET_CODE (operands[0]) == SUBREG)
7935 operands[0] = alter_subreg (operands[0]);
7936 if (GET_CODE (operands[1]) == SUBREG)
7937 operands[1] = alter_subreg (operands[1]);
7938 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7939 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7940 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7941 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7943 (define_insn "*absdf2_v9"
7944 [(set (match_operand:DF 0 "register_operand" "=e")
7945 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7946 "TARGET_FPU && TARGET_V9"
7948 [(set_attr "type" "fpmove")
7949 (set_attr "length" "1")])
7951 (define_insn "abssf2"
7952 [(set (match_operand:SF 0 "register_operand" "=f")
7953 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7956 [(set_attr "type" "fpmove")
7957 (set_attr "length" "1")])
7959 (define_expand "sqrttf2"
7960 [(set (match_operand:TF 0 "register_operand" "=e")
7961 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7962 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7965 if (! TARGET_HARD_QUAD)
7969 if (GET_CODE (operands[0]) != MEM)
7970 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7972 slot0 = operands[0];
7973 if (GET_CODE (operands[1]) != MEM)
7975 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7976 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7979 slot1 = operands[1];
7981 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7983 XEXP (slot0, 0), Pmode,
7984 XEXP (slot1, 0), Pmode);
7986 if (GET_CODE (operands[0]) != MEM)
7987 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7992 (define_insn "*sqrttf2_hq"
7993 [(set (match_operand:TF 0 "register_operand" "=e")
7994 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7995 "TARGET_FPU && TARGET_HARD_QUAD"
7997 [(set_attr "type" "fpsqrtd")
7998 (set_attr "length" "1")])
8000 (define_insn "sqrtdf2"
8001 [(set (match_operand:DF 0 "register_operand" "=e")
8002 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
8005 [(set_attr "type" "fpsqrtd")
8006 (set_attr "length" "1")])
8008 (define_insn "sqrtsf2"
8009 [(set (match_operand:SF 0 "register_operand" "=f")
8010 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
8013 [(set_attr "type" "fpsqrts")
8014 (set_attr "length" "1")])
8016 ;;- arithmetic shift instructions
8018 (define_insn "ashlsi3"
8019 [(set (match_operand:SI 0 "register_operand" "=r")
8020 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8021 (match_operand:SI 2 "arith_operand" "rI")))]
8025 if (GET_CODE (operands[2]) == CONST_INT
8026 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8027 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8029 return \"sll\\t%1, %2, %0\";
8031 [(set_attr "type" "shift")
8032 (set_attr "length" "1")])
8034 ;; We special case multiplication by two, as add can be done
8035 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8036 (define_insn "*ashlsi3_const1"
8037 [(set (match_operand:SI 0 "register_operand" "=r")
8038 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8042 [(set_attr "length" "1")])
8044 (define_expand "ashldi3"
8045 [(set (match_operand:DI 0 "register_operand" "=r")
8046 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8047 (match_operand:SI 2 "arith_operand" "rI")))]
8048 "TARGET_ARCH64 || TARGET_V8PLUS"
8051 if (! TARGET_ARCH64)
8053 if (GET_CODE (operands[2]) == CONST_INT)
8055 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
8060 ;; We special case multiplication by two, as add can be done
8061 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8062 (define_insn "*ashldi3_const1"
8063 [(set (match_operand:DI 0 "register_operand" "=r")
8064 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8068 [(set_attr "length" "1")])
8070 (define_insn "*ashldi3_sp64"
8071 [(set (match_operand:DI 0 "register_operand" "=r")
8072 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8073 (match_operand:SI 2 "arith_operand" "rI")))]
8077 if (GET_CODE (operands[2]) == CONST_INT
8078 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8079 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8081 return \"sllx\\t%1, %2, %0\";
8083 [(set_attr "type" "shift")
8084 (set_attr "length" "1")])
8087 (define_insn "ashldi3_v8plus"
8088 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8089 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8090 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8091 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8093 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8094 [(set_attr "length" "5,5,6")])
8096 ;; Optimize (1LL<<x)-1
8097 ;; XXX this also needs to be fixed to handle equal subregs
8098 ;; XXX first before we could re-enable it.
8100 ; [(set (match_operand:DI 0 "register_operand" "=h")
8101 ; (plus:DI (ashift:DI (const_int 1)
8102 ; (match_operand:SI 1 "arith_operand" "rI"))
8104 ; "0 && TARGET_V8PLUS"
8107 ; if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
8108 ; return \"mov\\t1, %L0\;sllx\\t%L0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8109 ; return \"mov\\t1, %H0\;sllx\\t%H0, %1, %L0\;sub\\t%L0, 1, %L0\;srlx\\t%L0, 32, %H0\";
8111 ; [(set_attr "length" "4")])
8113 (define_insn "*cmp_cc_ashift_1"
8114 [(set (reg:CC_NOOV 100)
8115 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8119 "addcc\\t%0, %0, %%g0"
8120 [(set_attr "type" "compare")
8121 (set_attr "length" "1")])
8123 (define_insn "*cmp_cc_set_ashift_1"
8124 [(set (reg:CC_NOOV 100)
8125 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8128 (set (match_operand:SI 0 "register_operand" "=r")
8129 (ashift:SI (match_dup 1) (const_int 1)))]
8131 "addcc\\t%1, %1, %0"
8132 [(set_attr "type" "compare")
8133 (set_attr "length" "1")])
8135 (define_insn "ashrsi3"
8136 [(set (match_operand:SI 0 "register_operand" "=r")
8137 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8138 (match_operand:SI 2 "arith_operand" "rI")))]
8142 if (GET_CODE (operands[2]) == CONST_INT
8143 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8144 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8146 return \"sra\\t%1, %2, %0\";
8148 [(set_attr "type" "shift")
8149 (set_attr "length" "1")])
8151 (define_insn "*ashrsi3_extend"
8152 [(set (match_operand:DI 0 "register_operand" "=r")
8153 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8154 (match_operand:SI 2 "arith_operand" "r"))))]
8157 [(set_attr "type" "shift")
8158 (set_attr "length" "1")])
8160 ;; This handles the case as above, but with constant shift instead of
8161 ;; register. Combiner "simplifies" it for us a little bit though.
8162 (define_insn "*ashrsi3_extend2"
8163 [(set (match_operand:DI 0 "register_operand" "=r")
8164 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8166 (match_operand:SI 2 "small_int_or_double" "n")))]
8168 && ((GET_CODE (operands[2]) == CONST_INT
8169 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8170 || (GET_CODE (operands[2]) == CONST_DOUBLE
8171 && !CONST_DOUBLE_HIGH (operands[2])
8172 && CONST_DOUBLE_LOW (operands[2]) >= 32
8173 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8176 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8178 return \"sra\\t%1, %2, %0\";
8180 [(set_attr "type" "shift")
8181 (set_attr "length" "1")])
8183 (define_expand "ashrdi3"
8184 [(set (match_operand:DI 0 "register_operand" "=r")
8185 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8186 (match_operand:SI 2 "arith_operand" "rI")))]
8187 "TARGET_ARCH64 || TARGET_V8PLUS"
8190 if (! TARGET_ARCH64)
8192 if (GET_CODE (operands[2]) == CONST_INT)
8193 FAIL; /* prefer generic code in this case */
8194 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8200 [(set (match_operand:DI 0 "register_operand" "=r")
8201 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8202 (match_operand:SI 2 "arith_operand" "rI")))]
8206 if (GET_CODE (operands[2]) == CONST_INT
8207 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8208 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8210 return \"srax\\t%1, %2, %0\";
8212 [(set_attr "type" "shift")
8213 (set_attr "length" "1")])
8216 (define_insn "ashrdi3_v8plus"
8217 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8218 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8219 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8220 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8222 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8223 [(set_attr "length" "5,5,6")])
8225 (define_insn "lshrsi3"
8226 [(set (match_operand:SI 0 "register_operand" "=r")
8227 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8228 (match_operand:SI 2 "arith_operand" "rI")))]
8232 if (GET_CODE (operands[2]) == CONST_INT
8233 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8234 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8236 return \"srl\\t%1, %2, %0\";
8238 [(set_attr "type" "shift")
8239 (set_attr "length" "1")])
8241 ;; This handles the case where
8242 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8243 ;; but combiner "simplifies" it for us.
8244 (define_insn "*lshrsi3_extend"
8245 [(set (match_operand:DI 0 "register_operand" "=r")
8246 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8247 (match_operand:SI 2 "arith_operand" "r")) 0)
8248 (match_operand 3 "" "")))]
8250 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8251 && CONST_DOUBLE_HIGH (operands[3]) == 0
8252 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8253 || (HOST_BITS_PER_WIDE_INT >= 64
8254 && GET_CODE (operands[3]) == CONST_INT
8255 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
8257 [(set_attr "type" "shift")
8258 (set_attr "length" "1")])
8260 ;; This handles the case where
8261 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8262 ;; but combiner "simplifies" it for us.
8263 (define_insn "*lshrsi3_extend2"
8264 [(set (match_operand:DI 0 "register_operand" "=r")
8265 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8266 (match_operand 2 "small_int_or_double" "n")
8269 && ((GET_CODE (operands[2]) == CONST_INT
8270 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8271 || (GET_CODE (operands[2]) == CONST_DOUBLE
8272 && CONST_DOUBLE_HIGH (operands[2]) == 0
8273 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8276 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8278 return \"srl\\t%1, %2, %0\";
8280 [(set_attr "type" "shift")
8281 (set_attr "length" "1")])
8283 (define_expand "lshrdi3"
8284 [(set (match_operand:DI 0 "register_operand" "=r")
8285 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8286 (match_operand:SI 2 "arith_operand" "rI")))]
8287 "TARGET_ARCH64 || TARGET_V8PLUS"
8290 if (! TARGET_ARCH64)
8292 if (GET_CODE (operands[2]) == CONST_INT)
8294 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8300 [(set (match_operand:DI 0 "register_operand" "=r")
8301 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8302 (match_operand:SI 2 "arith_operand" "rI")))]
8306 if (GET_CODE (operands[2]) == CONST_INT
8307 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8308 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8310 return \"srlx\\t%1, %2, %0\";
8312 [(set_attr "type" "shift")
8313 (set_attr "length" "1")])
8316 (define_insn "lshrdi3_v8plus"
8317 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8318 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8319 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8320 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8322 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8323 [(set_attr "length" "5,5,6")])
8326 [(set (match_operand:SI 0 "register_operand" "=r")
8327 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8329 (match_operand:SI 2 "small_int_or_double" "n")))]
8331 && ((GET_CODE (operands[2]) == CONST_INT
8332 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8333 || (GET_CODE (operands[2]) == CONST_DOUBLE
8334 && !CONST_DOUBLE_HIGH (operands[2])
8335 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8338 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8340 return \"srax\\t%1, %2, %0\";
8342 [(set_attr "type" "shift")
8343 (set_attr "length" "1")])
8346 [(set (match_operand:SI 0 "register_operand" "=r")
8347 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8349 (match_operand:SI 2 "small_int_or_double" "n")))]
8351 && ((GET_CODE (operands[2]) == CONST_INT
8352 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8353 || (GET_CODE (operands[2]) == CONST_DOUBLE
8354 && !CONST_DOUBLE_HIGH (operands[2])
8355 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8358 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8360 return \"srlx\\t%1, %2, %0\";
8362 [(set_attr "type" "shift")
8363 (set_attr "length" "1")])
8366 [(set (match_operand:SI 0 "register_operand" "=r")
8367 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8368 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8369 (match_operand:SI 3 "small_int_or_double" "n")))]
8371 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8372 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8373 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8374 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8377 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8379 return \"srax\\t%1, %2, %0\";
8381 [(set_attr "type" "shift")
8382 (set_attr "length" "1")])
8385 [(set (match_operand:SI 0 "register_operand" "=r")
8386 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8387 (match_operand:SI 2 "small_int_or_double" "n")) 4)
8388 (match_operand:SI 3 "small_int_or_double" "n")))]
8390 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8391 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8392 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8393 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8396 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8398 return \"srlx\\t%1, %2, %0\";
8400 [(set_attr "type" "shift")
8401 (set_attr "length" "1")])
8403 ;; Unconditional and other jump instructions
8404 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8405 ;; following insn is never executed. This saves us a nop. Dbx does not
8406 ;; handle such branches though, so we only use them when optimizing.
8408 [(set (pc) (label_ref (match_operand 0 "" "")))]
8412 /* TurboSparc is reported to have problems with
8415 i.e. an empty loop with the annul bit set. The workaround is to use
8419 if (! TARGET_V9 && flag_delayed_branch
8420 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8421 == INSN_ADDRESSES (INSN_UID (insn))))
8422 return \"b\\t%l0%#\";
8424 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8426 [(set_attr "type" "uncond_branch")])
8428 (define_expand "tablejump"
8429 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8430 (use (label_ref (match_operand 1 "" "")))])]
8434 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8437 /* In pic mode, our address differences are against the base of the
8438 table. Add that base value back in; CSE ought to be able to combine
8439 the two address loads. */
8443 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8445 if (CASE_VECTOR_MODE != Pmode)
8446 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8447 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8448 operands[0] = memory_address (Pmode, tmp);
8452 (define_insn "*tablejump_sp32"
8453 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8454 (use (label_ref (match_operand 1 "" "")))]
8457 [(set_attr "type" "uncond_branch")])
8459 (define_insn "*tablejump_sp64"
8460 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8461 (use (label_ref (match_operand 1 "" "")))]
8464 [(set_attr "type" "uncond_branch")])
8466 ;; This pattern recognizes the "instruction" that appears in
8467 ;; a function call that wants a structure value,
8468 ;; to inform the called function if compiled with Sun CC.
8469 ;(define_insn "*unimp_insn"
8470 ; [(match_operand:SI 0 "immediate_operand" "")]
8471 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8473 ; [(set_attr "type" "marker")])
8475 ;;- jump to subroutine
8476 (define_expand "call"
8477 ;; Note that this expression is not used for generating RTL.
8478 ;; All the RTL is generated explicitly below.
8479 [(call (match_operand 0 "call_operand" "")
8480 (match_operand 3 "" "i"))]
8481 ;; operands[2] is next_arg_register
8482 ;; operands[3] is struct_value_size_rtx.
8486 rtx fn_rtx, nregs_rtx;
8488 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8491 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8493 /* This is really a PIC sequence. We want to represent
8494 it as a funny jump so its delay slots can be filled.
8496 ??? But if this really *is* a CALL, will not it clobber the
8497 call-clobbered registers? We lose this if it is a JUMP_INSN.
8498 Why cannot we have delay slots filled if it were a CALL? */
8500 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8505 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8507 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8513 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8514 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8518 fn_rtx = operands[0];
8520 /* Count the number of parameter registers being used by this call.
8521 if that argument is NULL, it means we are using them all, which
8522 means 6 on the sparc. */
8525 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8527 nregs_rtx = GEN_INT (6);
8529 nregs_rtx = const0_rtx;
8532 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8536 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8538 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8543 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8544 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8548 /* If this call wants a structure value,
8549 emit an unimp insn to let the called function know about this. */
8550 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8552 rtx insn = emit_insn (operands[3]);
8553 SCHED_GROUP_P (insn) = 1;
8560 ;; We can't use the same pattern for these two insns, because then registers
8561 ;; in the address may not be properly reloaded.
8563 (define_insn "*call_address_sp32"
8564 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8565 (match_operand 1 "" ""))
8566 (clobber (reg:SI 15))]
8567 ;;- Do not use operand 1 for most machines.
8570 [(set_attr "type" "call")])
8572 (define_insn "*call_symbolic_sp32"
8573 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8574 (match_operand 1 "" ""))
8575 (clobber (reg:SI 15))]
8576 ;;- Do not use operand 1 for most machines.
8579 [(set_attr "type" "call")])
8581 (define_insn "*call_address_sp64"
8582 [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
8583 (match_operand 1 "" ""))
8584 (clobber (reg:DI 15))]
8585 ;;- Do not use operand 1 for most machines.
8588 [(set_attr "type" "call")])
8590 (define_insn "*call_symbolic_sp64"
8591 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8592 (match_operand 1 "" ""))
8593 (clobber (reg:DI 15))]
8594 ;;- Do not use operand 1 for most machines.
8597 [(set_attr "type" "call")])
8599 ;; This is a call that wants a structure value.
8600 ;; There is no such critter for v9 (??? we may need one anyway).
8601 (define_insn "*call_address_struct_value_sp32"
8602 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8603 (match_operand 1 "" ""))
8604 (match_operand 2 "immediate_operand" "")
8605 (clobber (reg:SI 15))]
8606 ;;- Do not use operand 1 for most machines.
8607 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8608 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8609 [(set_attr "type" "call_no_delay_slot")])
8611 ;; This is a call that wants a structure value.
8612 ;; There is no such critter for v9 (??? we may need one anyway).
8613 (define_insn "*call_symbolic_struct_value_sp32"
8614 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8615 (match_operand 1 "" ""))
8616 (match_operand 2 "immediate_operand" "")
8617 (clobber (reg:SI 15))]
8618 ;;- Do not use operand 1 for most machines.
8619 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8620 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8621 [(set_attr "type" "call_no_delay_slot")])
8623 ;; This is a call that may want a structure value. This is used for
8625 (define_insn "*call_address_untyped_struct_value_sp32"
8626 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8627 (match_operand 1 "" ""))
8628 (match_operand 2 "immediate_operand" "")
8629 (clobber (reg:SI 15))]
8630 ;;- Do not use operand 1 for most machines.
8631 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8632 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8633 [(set_attr "type" "call_no_delay_slot")])
8635 ;; This is a call that wants a structure value.
8636 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8637 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8638 (match_operand 1 "" ""))
8639 (match_operand 2 "immediate_operand" "")
8640 (clobber (reg:SI 15))]
8641 ;;- Do not use operand 1 for most machines.
8642 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8643 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8644 [(set_attr "type" "call_no_delay_slot")])
8646 (define_expand "call_value"
8647 ;; Note that this expression is not used for generating RTL.
8648 ;; All the RTL is generated explicitly below.
8649 [(set (match_operand 0 "register_operand" "=rf")
8650 (call (match_operand 1 "" "")
8651 (match_operand 4 "" "")))]
8652 ;; operand 2 is stack_size_rtx
8653 ;; operand 3 is next_arg_register
8657 rtx fn_rtx, nregs_rtx;
8660 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8663 fn_rtx = operands[1];
8667 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8669 nregs_rtx = GEN_INT (6);
8671 nregs_rtx = const0_rtx;
8675 gen_rtx_SET (VOIDmode, operands[0],
8676 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8677 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8679 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8684 (define_insn "*call_value_address_sp32"
8685 [(set (match_operand 0 "" "=rf")
8686 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8687 (match_operand 2 "" "")))
8688 (clobber (reg:SI 15))]
8689 ;;- Do not use operand 2 for most machines.
8692 [(set_attr "type" "call")])
8694 (define_insn "*call_value_symbolic_sp32"
8695 [(set (match_operand 0 "" "=rf")
8696 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8697 (match_operand 2 "" "")))
8698 (clobber (reg:SI 15))]
8699 ;;- Do not use operand 2 for most machines.
8702 [(set_attr "type" "call")])
8704 (define_insn "*call_value_address_sp64"
8705 [(set (match_operand 0 "" "")
8706 (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
8707 (match_operand 2 "" "")))
8708 (clobber (reg:DI 15))]
8709 ;;- Do not use operand 2 for most machines.
8712 [(set_attr "type" "call")])
8714 (define_insn "*call_value_symbolic_sp64"
8715 [(set (match_operand 0 "" "")
8716 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8717 (match_operand 2 "" "")))
8718 (clobber (reg:DI 15))]
8719 ;;- Do not use operand 2 for most machines.
8722 [(set_attr "type" "call")])
8724 (define_expand "untyped_call"
8725 [(parallel [(call (match_operand 0 "" "")
8727 (match_operand 1 "" "")
8728 (match_operand 2 "" "")])]
8734 /* Pass constm1 to indicate that it may expect a structure value, but
8735 we don't know what size it is. */
8736 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8738 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8740 rtx set = XVECEXP (operands[2], 0, i);
8741 emit_move_insn (SET_DEST (set), SET_SRC (set));
8744 /* The optimizer does not know that the call sets the function value
8745 registers we stored in the result block. We avoid problems by
8746 claiming that all hard registers are used and clobbered at this
8748 emit_insn (gen_blockage ());
8754 (define_expand "sibcall"
8755 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8760 (define_insn "*sibcall_symbolic_sp32"
8761 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8762 (match_operand 1 "" ""))
8765 "* return output_sibcall(insn, operands[0]);"
8766 [(set_attr "type" "sibcall")])
8768 (define_insn "*sibcall_symbolic_sp64"
8769 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
8770 (match_operand 1 "" ""))
8773 "* return output_sibcall(insn, operands[0]);"
8774 [(set_attr "type" "sibcall")])
8776 (define_expand "sibcall_value"
8777 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8778 (call (match_operand 1 "" "") (const_int 0)))
8783 (define_insn "*sibcall_value_symbolic_sp32"
8784 [(set (match_operand 0 "" "=rf")
8785 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8786 (match_operand 2 "" "")))
8789 "* return output_sibcall(insn, operands[1]);"
8790 [(set_attr "type" "sibcall")])
8792 (define_insn "*sibcall_value_symbolic_sp64"
8793 [(set (match_operand 0 "" "")
8794 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
8795 (match_operand 2 "" "")))
8798 "* return output_sibcall(insn, operands[1]);"
8799 [(set_attr "type" "sibcall")])
8801 (define_expand "sibcall_epilogue"
8806 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8807 ;; all of memory. This blocks insns from being moved across this point.
8809 (define_insn "blockage"
8810 [(unspec_volatile [(const_int 0)] 0)]
8813 [(set_attr "length" "0")])
8815 ;; Prepare to return any type including a structure value.
8817 (define_expand "untyped_return"
8818 [(match_operand:BLK 0 "memory_operand" "")
8819 (match_operand 1 "" "")]
8823 rtx valreg1 = gen_rtx_REG (DImode, 24);
8824 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8825 rtx result = operands[0];
8827 if (! TARGET_ARCH64)
8829 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8831 rtx value = gen_reg_rtx (SImode);
8833 /* Fetch the instruction where we will return to and see if it's an unimp
8834 instruction (the most significant 10 bits will be zero). If so,
8835 update the return address to skip the unimp instruction. */
8836 emit_move_insn (value,
8837 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8838 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8839 emit_insn (gen_update_return (rtnreg, value));
8842 /* Reload the function value registers. */
8843 emit_move_insn (valreg1, adjust_address (result, DImode, 0));
8844 emit_move_insn (valreg2,
8845 adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
8847 /* Put USE insns before the return. */
8848 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8849 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8851 /* Construct the return. */
8852 expand_null_return ();
8857 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8858 ;; and parts of the compiler don't want to believe that the add is needed.
8860 (define_insn "update_return"
8861 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8862 (match_operand:SI 1 "register_operand" "r")] 1)]
8864 "cmp\\t%1, 0\;be,a\\t.+8\;add\\t%0, 4, %0"
8865 [(set_attr "type" "multi")])
8867 (define_insn "return"
8871 "* return output_return (operands);"
8872 [(set_attr "type" "return")])
8875 [(set (match_operand:SI 0 "register_operand" "=r")
8876 (match_operand:SI 1 "arith_operand" "rI"))
8878 (use (reg:SI 31))])]
8879 "sparc_return_peephole_ok (operands[0], operands[1])"
8880 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8886 [(set_attr "type" "ialu")
8887 (set_attr "length" "1")])
8889 (define_expand "indirect_jump"
8890 [(set (pc) (match_operand 0 "address_operand" "p"))]
8894 (define_insn "*branch_sp32"
8895 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8898 [(set_attr "type" "uncond_branch")])
8900 (define_insn "*branch_sp64"
8901 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8904 [(set_attr "type" "uncond_branch")])
8906 ;; ??? Doesn't work with -mflat.
8907 (define_expand "nonlocal_goto"
8908 [(match_operand:SI 0 "general_operand" "")
8909 (match_operand:SI 1 "general_operand" "")
8910 (match_operand:SI 2 "general_operand" "")
8911 (match_operand:SI 3 "" "")]
8916 rtx chain = operands[0];
8918 rtx lab = operands[1];
8919 rtx stack = operands[2];
8920 rtx fp = operands[3];
8923 /* Trap instruction to flush all the register windows. */
8924 emit_insn (gen_flush_register_windows ());
8926 /* Load the fp value for the containing fn into %fp. This is needed
8927 because STACK refers to %fp. Note that virtual register instantiation
8928 fails if the virtual %fp isn't set from a register. */
8929 if (GET_CODE (fp) != REG)
8930 fp = force_reg (Pmode, fp);
8931 emit_move_insn (virtual_stack_vars_rtx, fp);
8933 /* Find the containing function's current nonlocal goto handler,
8934 which will do any cleanups and then jump to the label. */
8935 labreg = gen_rtx_REG (Pmode, 8);
8936 emit_move_insn (labreg, lab);
8938 /* Restore %fp from stack pointer value for containing function.
8939 The restore insn that follows will move this to %sp,
8940 and reload the appropriate value into %fp. */
8941 emit_move_insn (frame_pointer_rtx, stack);
8943 /* USE of frame_pointer_rtx added for consistency; not clear if
8945 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8946 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8949 /* Return, restoring reg window and jumping to goto handler. */
8950 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8951 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8953 emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
8959 /* Put in the static chain register the nonlocal label address. */
8960 emit_move_insn (static_chain_rtx, chain);
8963 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8964 emit_jump_insn (gen_goto_handler_and_restore (labreg));
8969 ;; Special trap insn to flush register windows.
8970 (define_insn "flush_register_windows"
8971 [(unspec_volatile [(const_int 0)] 1)]
8973 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8974 [(set_attr "type" "misc")
8975 (set_attr "length" "1")])
8977 (define_insn "goto_handler_and_restore"
8978 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8979 "GET_MODE (operands[0]) == Pmode"
8980 "jmp\\t%0+0\\n\\trestore"
8981 [(set_attr "type" "misc")
8982 (set_attr "length" "2")])
8984 ;;(define_insn "goto_handler_and_restore_v9"
8985 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8986 ;; (match_operand:SI 1 "register_operand" "=r,r")
8987 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8988 ;; "TARGET_V9 && ! TARGET_ARCH64"
8990 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8991 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8992 ;; [(set_attr "type" "misc")
8993 ;; (set_attr "length" "2,3")])
8995 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8996 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8997 ;; (match_operand:DI 1 "register_operand" "=r,r")
8998 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8999 ;; "TARGET_V9 && TARGET_ARCH64"
9001 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9002 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9003 ;; [(set_attr "type" "misc")
9004 ;; (set_attr "length" "2,3")])
9006 ;; For __builtin_setjmp we need to flush register windows iff the function
9007 ;; calls alloca as well, because otherwise the register window might be
9008 ;; saved after %sp adjustement and thus setjmp would crash
9009 (define_expand "builtin_setjmp_setup"
9010 [(match_operand 0 "register_operand" "r")]
9014 emit_insn (gen_do_builtin_setjmp_setup ());
9018 (define_insn "do_builtin_setjmp_setup"
9019 [(unspec_volatile [(const_int 0)] 5)]
9023 if (!current_function_calls_alloca)
9029 [(set_attr "type" "misc")
9030 (set_attr "length" "1")])
9032 ;; Pattern for use after a setjmp to store FP and the return register
9033 ;; into the stack area.
9035 (define_expand "setjmp"
9041 emit_insn (gen_setjmp_64 ());
9043 emit_insn (gen_setjmp_32 ());
9047 (define_expand "setjmp_32"
9048 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
9049 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
9052 { operands[0] = frame_pointer_rtx; }")
9054 (define_expand "setjmp_64"
9055 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9056 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9059 { operands[0] = frame_pointer_rtx; }")
9061 ;; Special pattern for the FLUSH instruction.
9063 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9064 ; of the define_insn otherwise missing a mode. We make "flush", aka
9065 ; gen_flush, the default one since sparc_initialize_trampoline uses
9066 ; it on SImode mem values.
9068 (define_insn "flush"
9069 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9071 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9072 [(set_attr "type" "misc")])
9074 (define_insn "flushdi"
9075 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9077 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
9078 [(set_attr "type" "misc")])
9083 ;; The scan instruction searches from the most significant bit while ffs
9084 ;; searches from the least significant bit. The bit index and treatment of
9085 ;; zero also differ. It takes at least 7 instructions to get the proper
9086 ;; result. Here is an obvious 8 instruction sequence.
9089 (define_insn "ffssi2"
9090 [(set (match_operand:SI 0 "register_operand" "=&r")
9091 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9092 (clobber (match_scratch:SI 2 "=&r"))]
9093 "TARGET_SPARCLITE || TARGET_SPARCLET"
9096 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\";
9098 [(set_attr "type" "multi")
9099 (set_attr "length" "8")])
9101 ;; ??? This should be a define expand, so that the extra instruction have
9102 ;; a chance of being optimized away.
9104 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9105 ;; does, but no one uses that and we don't have a switch for it.
9107 ;(define_insn "ffsdi2"
9108 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9109 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9110 ; (clobber (match_scratch:DI 2 "=&r"))]
9112 ; "neg\\t%1, %2\;xnor\\t%1, %2, %2\;popc\\t%2, %0\;movzr\\t%1, 0, %0"
9113 ; [(set_attr "type" "multi")
9114 ; (set_attr "length" "4")])
9118 ;; Peepholes go at the end.
9120 ;; Optimize consecutive loads or stores into ldd and std when possible.
9121 ;; The conditions in which we do this are very restricted and are
9122 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9125 [(set (match_operand:SI 0 "memory_operand" "")
9127 (set (match_operand:SI 1 "memory_operand" "")
9130 && ! MEM_VOLATILE_P (operands[0])
9131 && ! MEM_VOLATILE_P (operands[1])
9132 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
9136 [(set (match_operand:SI 0 "memory_operand" "")
9138 (set (match_operand:SI 1 "memory_operand" "")
9141 && ! MEM_VOLATILE_P (operands[0])
9142 && ! MEM_VOLATILE_P (operands[1])
9143 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
9147 [(set (match_operand:SI 0 "register_operand" "=rf")
9148 (match_operand:SI 1 "memory_operand" ""))
9149 (set (match_operand:SI 2 "register_operand" "=rf")
9150 (match_operand:SI 3 "memory_operand" ""))]
9151 "registers_ok_for_ldd_peep (operands[0], operands[2])
9152 && ! MEM_VOLATILE_P (operands[1])
9153 && ! MEM_VOLATILE_P (operands[3])
9154 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9158 [(set (match_operand:SI 0 "memory_operand" "")
9159 (match_operand:SI 1 "register_operand" "rf"))
9160 (set (match_operand:SI 2 "memory_operand" "")
9161 (match_operand:SI 3 "register_operand" "rf"))]
9162 "registers_ok_for_ldd_peep (operands[1], operands[3])
9163 && ! MEM_VOLATILE_P (operands[0])
9164 && ! MEM_VOLATILE_P (operands[2])
9165 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9169 [(set (match_operand:SF 0 "register_operand" "=fr")
9170 (match_operand:SF 1 "memory_operand" ""))
9171 (set (match_operand:SF 2 "register_operand" "=fr")
9172 (match_operand:SF 3 "memory_operand" ""))]
9173 "registers_ok_for_ldd_peep (operands[0], operands[2])
9174 && ! MEM_VOLATILE_P (operands[1])
9175 && ! MEM_VOLATILE_P (operands[3])
9176 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9180 [(set (match_operand:SF 0 "memory_operand" "")
9181 (match_operand:SF 1 "register_operand" "fr"))
9182 (set (match_operand:SF 2 "memory_operand" "")
9183 (match_operand:SF 3 "register_operand" "fr"))]
9184 "registers_ok_for_ldd_peep (operands[1], operands[3])
9185 && ! MEM_VOLATILE_P (operands[0])
9186 && ! MEM_VOLATILE_P (operands[2])
9187 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9191 [(set (match_operand:SI 0 "register_operand" "=rf")
9192 (match_operand:SI 1 "memory_operand" ""))
9193 (set (match_operand:SI 2 "register_operand" "=rf")
9194 (match_operand:SI 3 "memory_operand" ""))]
9195 "registers_ok_for_ldd_peep (operands[2], operands[0])
9196 && ! MEM_VOLATILE_P (operands[3])
9197 && ! MEM_VOLATILE_P (operands[1])
9198 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9202 [(set (match_operand:SI 0 "memory_operand" "")
9203 (match_operand:SI 1 "register_operand" "rf"))
9204 (set (match_operand:SI 2 "memory_operand" "")
9205 (match_operand:SI 3 "register_operand" "rf"))]
9206 "registers_ok_for_ldd_peep (operands[3], operands[1])
9207 && ! MEM_VOLATILE_P (operands[2])
9208 && ! MEM_VOLATILE_P (operands[0])
9209 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9213 [(set (match_operand:SF 0 "register_operand" "=fr")
9214 (match_operand:SF 1 "memory_operand" ""))
9215 (set (match_operand:SF 2 "register_operand" "=fr")
9216 (match_operand:SF 3 "memory_operand" ""))]
9217 "registers_ok_for_ldd_peep (operands[2], operands[0])
9218 && ! MEM_VOLATILE_P (operands[3])
9219 && ! MEM_VOLATILE_P (operands[1])
9220 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9224 [(set (match_operand:SF 0 "memory_operand" "")
9225 (match_operand:SF 1 "register_operand" "fr"))
9226 (set (match_operand:SF 2 "memory_operand" "")
9227 (match_operand:SF 3 "register_operand" "fr"))]
9228 "registers_ok_for_ldd_peep (operands[3], operands[1])
9229 && ! MEM_VOLATILE_P (operands[2])
9230 && ! MEM_VOLATILE_P (operands[0])
9231 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9234 ;; Optimize the case of following a reg-reg move with a test
9235 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9236 ;; This can result from a float to fix conversion.
9239 [(set (match_operand:SI 0 "register_operand" "=r")
9240 (match_operand:SI 1 "register_operand" "r"))
9242 (compare:CC (match_operand:SI 2 "register_operand" "r")
9244 "(rtx_equal_p (operands[2], operands[0])
9245 || rtx_equal_p (operands[2], operands[1]))
9246 && ! FP_REG_P (operands[0])
9247 && ! FP_REG_P (operands[1])"
9251 [(set (match_operand:DI 0 "register_operand" "=r")
9252 (match_operand:DI 1 "register_operand" "r"))
9254 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9257 && (rtx_equal_p (operands[2], operands[0])
9258 || rtx_equal_p (operands[2], operands[1]))
9259 && ! FP_REG_P (operands[0])
9260 && ! FP_REG_P (operands[1])"
9263 ;; Return peepholes. First the "normal" ones.
9264 ;; These are necessary to catch insns ending up in the epilogue delay list.
9266 (define_insn "*return_qi"
9267 [(set (match_operand:QI 0 "restore_operand" "")
9268 (match_operand:QI 1 "arith_operand" "rI"))
9273 if (! TARGET_ARCH64 && current_function_returns_struct)
9274 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9275 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9276 || IN_OR_GLOBAL_P (operands[1])))
9277 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9279 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9281 [(set_attr "type" "multi")])
9283 (define_insn "*return_hi"
9284 [(set (match_operand:HI 0 "restore_operand" "")
9285 (match_operand:HI 1 "arith_operand" "rI"))
9290 if (! TARGET_ARCH64 && current_function_returns_struct)
9291 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9292 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9293 || IN_OR_GLOBAL_P (operands[1])))
9294 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9296 return \"ret\;restore %%g0, %1, %Y0\";
9298 [(set_attr "type" "multi")])
9300 (define_insn "*return_si"
9301 [(set (match_operand:SI 0 "restore_operand" "")
9302 (match_operand:SI 1 "arith_operand" "rI"))
9307 if (! TARGET_ARCH64 && current_function_returns_struct)
9308 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9309 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9310 || IN_OR_GLOBAL_P (operands[1])))
9311 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9313 return \"ret\;restore %%g0, %1, %Y0\";
9315 [(set_attr "type" "multi")])
9317 ;; The following pattern is only generated by delayed-branch scheduling,
9318 ;; when the insn winds up in the epilogue. This can happen not only when
9319 ;; ! TARGET_FPU because we move complex types around by parts using
9321 (define_insn "*return_sf_no_fpu"
9322 [(set (match_operand:SF 0 "restore_operand" "=r")
9323 (match_operand:SF 1 "register_operand" "r"))
9328 if (! TARGET_ARCH64 && current_function_returns_struct)
9329 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9330 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9331 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9333 return \"ret\;restore %%g0, %1, %Y0\";
9335 [(set_attr "type" "multi")])
9337 (define_insn "*return_df_no_fpu"
9338 [(set (match_operand:DF 0 "restore_operand" "=r")
9339 (match_operand:DF 1 "register_operand" "r"))
9341 "! TARGET_EPILOGUE && TARGET_ARCH64"
9344 if (IN_OR_GLOBAL_P (operands[1]))
9345 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9347 return \"ret\;restore %%g0, %1, %Y0\";
9349 [(set_attr "type" "multi")])
9351 (define_insn "*return_addsi"
9352 [(set (match_operand:SI 0 "restore_operand" "")
9353 (plus:SI (match_operand:SI 1 "register_operand" "r")
9354 (match_operand:SI 2 "arith_operand" "rI")))
9359 if (! TARGET_ARCH64 && current_function_returns_struct)
9360 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9361 /* If operands are global or in registers, can use return */
9362 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9363 && (GET_CODE (operands[2]) == CONST_INT
9364 || IN_OR_GLOBAL_P (operands[2])))
9365 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9367 return \"ret\;restore %r1, %2, %Y0\";
9369 [(set_attr "type" "multi")])
9371 (define_insn "*return_losum_si"
9372 [(set (match_operand:SI 0 "restore_operand" "")
9373 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9374 (match_operand:SI 2 "immediate_operand" "in")))
9376 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9379 if (! TARGET_ARCH64 && current_function_returns_struct)
9380 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9381 /* If operands are global or in registers, can use return */
9382 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9383 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9385 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9387 [(set_attr "type" "multi")])
9389 (define_insn "*return_di"
9390 [(set (match_operand:DI 0 "restore_operand" "")
9391 (match_operand:DI 1 "arith_double_operand" "rHI"))
9393 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9394 "ret\;restore %%g0, %1, %Y0"
9395 [(set_attr "type" "multi")])
9397 (define_insn "*return_adddi"
9398 [(set (match_operand:DI 0 "restore_operand" "")
9399 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9400 (match_operand:DI 2 "arith_double_operand" "rHI")))
9402 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9403 "ret\;restore %r1, %2, %Y0"
9404 [(set_attr "type" "multi")])
9406 (define_insn "*return_losum_di"
9407 [(set (match_operand:DI 0 "restore_operand" "")
9408 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9409 (match_operand:DI 2 "immediate_operand" "in")))
9411 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9412 "ret\;restore %r1, %%lo(%a2), %Y0"
9413 [(set_attr "type" "multi")])
9415 ;; The following pattern is only generated by delayed-branch scheduling,
9416 ;; when the insn winds up in the epilogue.
9417 (define_insn "*return_sf"
9419 (match_operand:SF 0 "register_operand" "f"))
9422 "ret\;fmovs\\t%0, %%f0"
9423 [(set_attr "type" "multi")])
9425 ;; Now peepholes to do a call followed by a jump.
9428 [(parallel [(set (match_operand 0 "" "")
9429 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9430 (match_operand 2 "" "")))
9431 (clobber (reg:SI 15))])
9432 (set (pc) (label_ref (match_operand 3 "" "")))]
9433 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9434 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9435 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9438 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9439 (match_operand 1 "" ""))
9440 (clobber (reg:SI 15))])
9441 (set (pc) (label_ref (match_operand 2 "" "")))]
9442 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9443 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9444 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9447 [(parallel [(set (match_operand 0 "" "")
9448 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9449 (match_operand 2 "" "")))
9450 (clobber (reg:DI 15))])
9451 (set (pc) (label_ref (match_operand 3 "" "")))]
9453 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9454 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9455 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9458 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9459 (match_operand 1 "" ""))
9460 (clobber (reg:DI 15))])
9461 (set (pc) (label_ref (match_operand 2 "" "")))]
9463 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9464 && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
9465 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9467 (define_expand "prologue"
9469 "flag_pic && current_function_uses_pic_offset_table"
9472 load_pic_register ();
9476 ;; We need to reload %l7 for -mflat -fpic,
9477 ;; otherwise %l7 should be preserved simply
9478 ;; by loading the function's register window
9479 (define_expand "exception_receiver"
9481 "TARGET_FLAT && flag_pic"
9484 load_pic_register ();
9489 (define_expand "builtin_setjmp_receiver"
9490 [(label_ref (match_operand 0 "" ""))]
9491 "TARGET_FLAT && flag_pic"
9494 load_pic_register ();
9499 [(trap_if (const_int 1) (const_int 5))]
9502 [(set_attr "type" "misc")
9503 (set_attr "length" "1")])
9505 (define_expand "conditional_trap"
9506 [(trap_if (match_operator 0 "noov_compare_op"
9507 [(match_dup 2) (match_dup 3)])
9508 (match_operand:SI 1 "arith_operand" ""))]
9510 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9511 sparc_compare_op0, sparc_compare_op1);
9512 operands[3] = const0_rtx;")
9515 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9516 (match_operand:SI 1 "arith_operand" "rM"))]
9519 [(set_attr "type" "misc")
9520 (set_attr "length" "1")])
9523 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9524 (match_operand:SI 1 "arith_operand" "rM"))]
9527 [(set_attr "type" "misc")
9528 (set_attr "length" "1")])