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 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 nonlocal_goto_receiver
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"))))
83 ;; Insn type. Used to default other attribute values.
85 ;; type "unary" insns have one input operand (1) and one output operand (0)
86 ;; type "binary" insns have two input operands (1,2) and one output (0)
87 ;; type "compare" insns have one or two input operands (0,1) and no output
88 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
91 "move,unary,binary,compare,load,sload,store,ialu,shift,uncond_branch,branch,call,call_no_delay_slot,return,address,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
92 (const_string "binary"))
94 ;; Set true if insn uses call-clobbered intermediate register.
95 (define_attr "use_clobbered" "false,true"
96 (if_then_else (and (eq_attr "type" "address")
97 (match_operand 0 "clobbered_register" ""))
99 (const_string "false")))
101 ;; Length (in # of insns).
102 (define_attr "length" ""
103 (cond [(eq_attr "type" "load,sload,fpload")
104 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
105 (const_int 2) (const_int 1))
107 (eq_attr "type" "store,fpstore")
108 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
109 (const_int 2) (const_int 1))
111 (eq_attr "type" "address") (const_int 2)
113 (eq_attr "type" "binary")
114 (if_then_else (ior (match_operand 2 "arith_operand" "")
115 (match_operand 2 "arith_double_operand" ""))
116 (const_int 1) (const_int 3))
118 (eq_attr "type" "multi") (const_int 2)
120 (eq_attr "type" "move,unary")
121 (if_then_else (ior (match_operand 1 "arith_operand" "")
122 (match_operand 1 "arith_double_operand" ""))
123 (const_int 1) (const_int 2))]
127 (define_asm_attributes
128 [(set_attr "length" "1")
129 (set_attr "type" "multi")])
131 ;; Attributes for instruction and branch scheduling
133 (define_attr "in_call_delay" "false,true"
134 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,return,multi")
135 (const_string "false")
136 (eq_attr "type" "load,fpload,store,fpstore")
137 (if_then_else (eq_attr "length" "1")
138 (const_string "true")
139 (const_string "false"))
140 (eq_attr "type" "address")
141 (if_then_else (eq_attr "use_clobbered" "false")
142 (const_string "true")
143 (const_string "false"))]
144 (if_then_else (eq_attr "length" "1")
145 (const_string "true")
146 (const_string "false"))))
148 (define_delay (eq_attr "type" "call")
149 [(eq_attr "in_call_delay" "true") (nil) (nil)])
151 (define_attr "leaf_function" "false,true"
152 (const (symbol_ref "current_function_uses_only_leaf_regs")))
154 (define_attr "eligible_for_return_delay" "false,true"
155 (symbol_ref "eligible_for_return_delay(insn)"))
157 (define_attr "in_return_delay" "false,true"
158 (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
159 (eq_attr "length" "1"))
160 (eq_attr "leaf_function" "false"))
161 (eq_attr "eligible_for_return_delay" "false"))
162 (const_string "true")
163 (const_string "false")))
165 (define_delay (and (eq_attr "type" "return")
166 (eq_attr "isa" "v9"))
167 [(eq_attr "in_return_delay" "true") (nil) (nil)])
169 ;; ??? Should implement the notion of predelay slots for floating point
170 ;; branches. This would allow us to remove the nop always inserted before
171 ;; a floating point branch.
173 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
174 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
175 ;; This is because doing so will add several pipeline stalls to the path
176 ;; that the load/store did not come from. Unfortunately, there is no way
177 ;; to prevent fill_eager_delay_slots from using load/store without completely
178 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
179 ;; because it prevents us from moving back the final store of inner loops.
181 (define_attr "in_branch_delay" "false,true"
182 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
183 (eq_attr "length" "1"))
184 (const_string "true")
185 (const_string "false")))
187 (define_attr "in_uncond_branch_delay" "false,true"
188 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
189 (eq_attr "length" "1"))
190 (const_string "true")
191 (const_string "false")))
193 (define_attr "in_annul_branch_delay" "false,true"
194 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
195 (eq_attr "length" "1"))
196 (const_string "true")
197 (const_string "false")))
199 (define_delay (eq_attr "type" "branch")
200 [(eq_attr "in_branch_delay" "true")
201 (nil) (eq_attr "in_annul_branch_delay" "true")])
203 (define_delay (eq_attr "type" "uncond_branch")
204 [(eq_attr "in_uncond_branch_delay" "true")
207 ;; Function units of the SPARC
209 ;; (define_function_unit {name} {num-units} {n-users} {test}
210 ;; {ready-delay} {issue-delay} [{conflict-list}])
213 ;; (Noted only for documentation; units that take one cycle do not need to
216 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
219 ;; (define_function_unit "alu" 1 0
220 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
222 ;; ---- cypress CY7C602 scheduling:
223 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
225 (define_function_unit "memory" 1 0
226 (and (eq_attr "cpu" "cypress")
227 (eq_attr "type" "load,sload,fpload"))
230 ;; SPARC has two floating-point units: the FP ALU,
231 ;; and the FP MUL/DIV/SQRT unit.
232 ;; Instruction timings on the CY7C602 are as follows
246 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
247 ;; More insns cause the chip to stall.
249 (define_function_unit "fp_alu" 1 0
250 (and (eq_attr "cpu" "cypress")
251 (eq_attr "type" "fp,fpmove"))
254 (define_function_unit "fp_mds" 1 0
255 (and (eq_attr "cpu" "cypress")
256 (eq_attr "type" "fpmul"))
259 (define_function_unit "fp_mds" 1 0
260 (and (eq_attr "cpu" "cypress")
261 (eq_attr "type" "fpdivs,fpdivd"))
264 (define_function_unit "fp_mds" 1 0
265 (and (eq_attr "cpu" "cypress")
266 (eq_attr "type" "fpsqrts,fpsqrtd"))
269 ;; ----- The TMS390Z55 scheduling
270 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
271 ;; one ld/st, one fp.
272 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
274 (define_function_unit "memory" 1 0
275 (and (eq_attr "cpu" "supersparc")
276 (eq_attr "type" "load,sload"))
279 (define_function_unit "memory" 1 0
280 (and (eq_attr "cpu" "supersparc")
281 (eq_attr "type" "fpload"))
284 (define_function_unit "memory" 1 0
285 (and (eq_attr "cpu" "supersparc")
286 (eq_attr "type" "store,fpstore"))
289 (define_function_unit "shift" 1 0
290 (and (eq_attr "cpu" "supersparc")
291 (eq_attr "type" "shift"))
294 ;; There are only two write ports to the integer register file
295 ;; A store also uses a write port
297 (define_function_unit "iwport" 2 0
298 (and (eq_attr "cpu" "supersparc")
299 (eq_attr "type" "load,sload,store,shift,ialu"))
302 ;; Timings; throughput/latency
303 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
311 (define_function_unit "fp_alu" 1 0
312 (and (eq_attr "cpu" "supersparc")
313 (eq_attr "type" "fp,fpmove,fpcmp"))
316 (define_function_unit "fp_mds" 1 0
317 (and (eq_attr "cpu" "supersparc")
318 (eq_attr "type" "fpmul"))
321 (define_function_unit "fp_mds" 1 0
322 (and (eq_attr "cpu" "supersparc")
323 (eq_attr "type" "fpdivs"))
326 (define_function_unit "fp_mds" 1 0
327 (and (eq_attr "cpu" "supersparc")
328 (eq_attr "type" "fpdivd"))
331 (define_function_unit "fp_mds" 1 0
332 (and (eq_attr "cpu" "supersparc")
333 (eq_attr "type" "fpsqrts,fpsqrtd"))
336 (define_function_unit "fp_mds" 1 0
337 (and (eq_attr "cpu" "supersparc")
338 (eq_attr "type" "imul"))
341 ;; ----- hypersparc/sparclite86x scheduling
342 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
343 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
344 ;; II/FF case is only when loading a 32 bit hi/lo constant
345 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
346 ;; Memory delivers its result in one cycle to IU
348 (define_function_unit "memory" 1 0
349 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
350 (eq_attr "type" "load,sload,fpload"))
353 (define_function_unit "memory" 1 0
354 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
355 (eq_attr "type" "store,fpstore"))
358 (define_function_unit "sparclite86x_branch" 1 0
359 (and (eq_attr "cpu" "sparclite86x")
360 (eq_attr "type" "branch"))
363 ;; integer multiply insns
364 (define_function_unit "sparclite86x_shift" 1 0
365 (and (eq_attr "cpu" "sparclite86x")
366 (eq_attr "type" "shift"))
369 (define_function_unit "fp_alu" 1 0
370 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
371 (eq_attr "type" "fp,fpmove,fpcmp"))
374 (define_function_unit "fp_mds" 1 0
375 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
376 (eq_attr "type" "fpmul"))
379 (define_function_unit "fp_mds" 1 0
380 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
381 (eq_attr "type" "fpdivs"))
384 (define_function_unit "fp_mds" 1 0
385 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
386 (eq_attr "type" "fpdivd"))
389 (define_function_unit "fp_mds" 1 0
390 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
391 (eq_attr "type" "fpsqrts,fpsqrtd"))
394 (define_function_unit "fp_mds" 1 0
395 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
396 (eq_attr "type" "imul"))
399 ;; ----- sparclet tsc701 scheduling
400 ;; The tsc701 issues 1 insn per cycle.
401 ;; Results may be written back out of order.
403 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
405 (define_function_unit "tsc701_load" 4 1
406 (and (eq_attr "cpu" "tsc701")
407 (eq_attr "type" "load,sload"))
410 ;; Stores take 2(?) extra cycles to complete.
411 ;; It is desirable to not have any memory operation in the following 2 cycles.
412 ;; (??? or 2 memory ops in the case of std).
414 (define_function_unit "tsc701_store" 1 0
415 (and (eq_attr "cpu" "tsc701")
416 (eq_attr "type" "store"))
418 [(eq_attr "type" "load,sload,store")])
420 ;; The multiply unit has a latency of 5.
421 (define_function_unit "tsc701_mul" 1 0
422 (and (eq_attr "cpu" "tsc701")
423 (eq_attr "type" "imul"))
426 ;; ----- The UltraSPARC-1 scheduling
427 ;; UltraSPARC has two integer units. Shift instructions can only execute
428 ;; on IE0. Condition code setting instructions, call, and jmpl (including
429 ;; the ret and retl pseudo-instructions) can only execute on IE1.
430 ;; Branch on register uses IE1, but branch on condition code does not.
431 ;; Conditional moves take 2 cycles. No other instruction can issue in the
432 ;; same cycle as a conditional move.
433 ;; Multiply and divide take many cycles during which no other instructions
435 ;; Memory delivers its result in two cycles (except for signed loads,
436 ;; which take one cycle more). One memory instruction can be issued per
439 (define_function_unit "memory" 1 0
440 (and (eq_attr "cpu" "ultrasparc")
441 (eq_attr "type" "load,fpload"))
444 (define_function_unit "memory" 1 0
445 (and (eq_attr "cpu" "ultrasparc")
446 (eq_attr "type" "sload"))
449 (define_function_unit "memory" 1 0
450 (and (eq_attr "cpu" "ultrasparc")
451 (eq_attr "type" "store,fpstore"))
454 (define_function_unit "ieuN" 2 0
455 (and (eq_attr "cpu" "ultrasparc")
456 (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,call_no_delay_slot,uncond_branch"))
459 (define_function_unit "ieu0" 1 0
460 (and (eq_attr "cpu" "ultrasparc")
461 (eq_attr "type" "shift"))
464 (define_function_unit "ieu0" 1 0
465 (and (eq_attr "cpu" "ultrasparc")
466 (eq_attr "type" "cmove"))
469 (define_function_unit "ieu1" 1 0
470 (and (eq_attr "cpu" "ultrasparc")
471 (eq_attr "type" "compare,call,call_no_delay_slot,uncond_branch"))
474 (define_function_unit "cti" 1 0
475 (and (eq_attr "cpu" "ultrasparc")
476 (eq_attr "type" "branch"))
479 ;; Timings; throughput/latency
480 ;; FMOV 1/1 fmov, fabs, fneg
482 ;; FADD 1/3 add/sub, format conv, compar
488 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
490 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
491 ;; use the FPM multiplier for final rounding 3 cycles before the
492 ;; end of their latency and we have no real way to model that.
494 ;; ??? This is really bogus because the timings really depend upon
495 ;; who uses the result. We should record who the user is with
496 ;; more descriptive 'type' attribute names and account for these
497 ;; issues in ultrasparc_adjust_cost.
499 (define_function_unit "fadd" 1 0
500 (and (eq_attr "cpu" "ultrasparc")
501 (eq_attr "type" "fpmove"))
504 (define_function_unit "fadd" 1 0
505 (and (eq_attr "cpu" "ultrasparc")
506 (eq_attr "type" "fpcmove"))
509 (define_function_unit "fadd" 1 0
510 (and (eq_attr "cpu" "ultrasparc")
511 (eq_attr "type" "fp"))
514 (define_function_unit "fadd" 1 0
515 (and (eq_attr "cpu" "ultrasparc")
516 (eq_attr "type" "fpcmp"))
519 (define_function_unit "fmul" 1 0
520 (and (eq_attr "cpu" "ultrasparc")
521 (eq_attr "type" "fpmul"))
524 (define_function_unit "fadd" 1 0
525 (and (eq_attr "cpu" "ultrasparc")
526 (eq_attr "type" "fpcmove"))
529 (define_function_unit "fdiv" 1 0
530 (and (eq_attr "cpu" "ultrasparc")
531 (eq_attr "type" "fpdivs"))
534 (define_function_unit "fdiv" 1 0
535 (and (eq_attr "cpu" "ultrasparc")
536 (eq_attr "type" "fpdivd"))
539 (define_function_unit "fdiv" 1 0
540 (and (eq_attr "cpu" "ultrasparc")
541 (eq_attr "type" "fpsqrts"))
544 (define_function_unit "fdiv" 1 0
545 (and (eq_attr "cpu" "ultrasparc")
546 (eq_attr "type" "fpsqrtd"))
549 ;; Compare instructions.
550 ;; This controls RTL generation and register allocation.
552 ;; We generate RTL for comparisons and branches by having the cmpxx
553 ;; patterns store away the operands. Then, the scc and bcc patterns
554 ;; emit RTL for both the compare and the branch.
556 ;; We do this because we want to generate different code for an sne and
557 ;; seq insn. In those cases, if the second operand of the compare is not
558 ;; const0_rtx, we want to compute the xor of the two operands and test
561 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
562 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
563 ;; insns that actually require more than one machine instruction.
565 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
567 (define_expand "cmpsi"
569 (compare:CC (match_operand:SI 0 "register_operand" "")
570 (match_operand:SI 1 "arith_operand" "")))]
574 sparc_compare_op0 = operands[0];
575 sparc_compare_op1 = operands[1];
579 (define_expand "cmpdi"
581 (compare:CCX (match_operand:DI 0 "register_operand" "")
582 (match_operand:DI 1 "arith_double_operand" "")))]
586 sparc_compare_op0 = operands[0];
587 sparc_compare_op1 = operands[1];
591 (define_expand "cmpsf"
592 ;; The 96 here isn't ever used by anyone.
594 (compare:CCFP (match_operand:SF 0 "register_operand" "")
595 (match_operand:SF 1 "register_operand" "")))]
599 sparc_compare_op0 = operands[0];
600 sparc_compare_op1 = operands[1];
604 (define_expand "cmpdf"
605 ;; The 96 here isn't ever used by anyone.
607 (compare:CCFP (match_operand:DF 0 "register_operand" "")
608 (match_operand:DF 1 "register_operand" "")))]
612 sparc_compare_op0 = operands[0];
613 sparc_compare_op1 = operands[1];
617 (define_expand "cmptf"
618 ;; The 96 here isn't ever used by anyone.
620 (compare:CCFP (match_operand:TF 0 "register_operand" "")
621 (match_operand:TF 1 "register_operand" "")))]
625 sparc_compare_op0 = operands[0];
626 sparc_compare_op1 = operands[1];
630 ;; Now the compare DEFINE_INSNs.
632 (define_insn "*cmpsi_insn"
634 (compare:CC (match_operand:SI 0 "register_operand" "r")
635 (match_operand:SI 1 "arith_operand" "rI")))]
638 [(set_attr "type" "compare")])
640 (define_insn "*cmpdi_sp64"
642 (compare:CCX (match_operand:DI 0 "register_operand" "r")
643 (match_operand:DI 1 "arith_double_operand" "rHI")))]
646 [(set_attr "type" "compare")])
648 (define_insn "*cmpsf_fpe"
649 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
650 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
651 (match_operand:SF 2 "register_operand" "f")))]
656 return \"fcmpes\\t%0, %1, %2\";
657 return \"fcmpes\\t%1, %2\";
659 [(set_attr "type" "fpcmp")])
661 (define_insn "*cmpdf_fpe"
662 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
663 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
664 (match_operand:DF 2 "register_operand" "e")))]
669 return \"fcmped\\t%0, %1, %2\";
670 return \"fcmped\\t%1, %2\";
672 [(set_attr "type" "fpcmp")])
674 (define_insn "*cmptf_fpe"
675 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
676 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
677 (match_operand:TF 2 "register_operand" "e")))]
678 "TARGET_FPU && TARGET_HARD_QUAD"
682 return \"fcmpeq\\t%0, %1, %2\";
683 return \"fcmpeq\\t%1, %2\";
685 [(set_attr "type" "fpcmp")])
687 (define_insn "*cmpsf_fp"
688 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
689 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
690 (match_operand:SF 2 "register_operand" "f")))]
695 return \"fcmps\\t%0, %1, %2\";
696 return \"fcmps\\t%1, %2\";
698 [(set_attr "type" "fpcmp")])
700 (define_insn "*cmpdf_fp"
701 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
702 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
703 (match_operand:DF 2 "register_operand" "e")))]
708 return \"fcmpd\\t%0, %1, %2\";
709 return \"fcmpd\\t%1, %2\";
711 [(set_attr "type" "fpcmp")])
713 (define_insn "*cmptf_fp"
714 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
715 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
716 (match_operand:TF 2 "register_operand" "e")))]
717 "TARGET_FPU && TARGET_HARD_QUAD"
721 return \"fcmpq\\t%0, %1, %2\";
722 return \"fcmpq\\t%1, %2\";
724 [(set_attr "type" "fpcmp")])
726 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
727 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
728 ;; the same code as v8 (the addx/subx method has more applications). The
729 ;; exception to this is "reg != 0" which can be done in one instruction on v9
730 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
733 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
734 ;; generate addcc/subcc instructions.
736 (define_expand "seqsi_special"
738 (xor:SI (match_operand:SI 1 "register_operand" "")
739 (match_operand:SI 2 "register_operand" "")))
740 (parallel [(set (match_operand:SI 0 "register_operand" "")
741 (eq:SI (match_dup 3) (const_int 0)))
742 (clobber (reg:CC 100))])]
744 "{ operands[3] = gen_reg_rtx (SImode); }")
746 (define_expand "seqdi_special"
748 (xor:DI (match_operand:DI 1 "register_operand" "")
749 (match_operand:DI 2 "register_operand" "")))
750 (set (match_operand:DI 0 "register_operand" "")
751 (eq:DI (match_dup 3) (const_int 0)))]
753 "{ operands[3] = gen_reg_rtx (DImode); }")
755 (define_expand "snesi_special"
757 (xor:SI (match_operand:SI 1 "register_operand" "")
758 (match_operand:SI 2 "register_operand" "")))
759 (parallel [(set (match_operand:SI 0 "register_operand" "")
760 (ne:SI (match_dup 3) (const_int 0)))
761 (clobber (reg:CC 100))])]
763 "{ operands[3] = gen_reg_rtx (SImode); }")
765 (define_expand "snedi_special"
767 (xor:DI (match_operand:DI 1 "register_operand" "")
768 (match_operand:DI 2 "register_operand" "")))
769 (set (match_operand:DI 0 "register_operand" "")
770 (ne:DI (match_dup 3) (const_int 0)))]
772 "{ operands[3] = gen_reg_rtx (DImode); }")
774 (define_expand "seqdi_special_trunc"
776 (xor:DI (match_operand:DI 1 "register_operand" "")
777 (match_operand:DI 2 "register_operand" "")))
778 (set (match_operand:SI 0 "register_operand" "")
779 (eq:SI (match_dup 3) (const_int 0)))]
781 "{ operands[3] = gen_reg_rtx (DImode); }")
783 (define_expand "snedi_special_trunc"
785 (xor:DI (match_operand:DI 1 "register_operand" "")
786 (match_operand:DI 2 "register_operand" "")))
787 (set (match_operand:SI 0 "register_operand" "")
788 (ne:SI (match_dup 3) (const_int 0)))]
790 "{ operands[3] = gen_reg_rtx (DImode); }")
792 (define_expand "seqsi_special_extend"
794 (xor:SI (match_operand:SI 1 "register_operand" "")
795 (match_operand:SI 2 "register_operand" "")))
796 (parallel [(set (match_operand:DI 0 "register_operand" "")
797 (eq:DI (match_dup 3) (const_int 0)))
798 (clobber (reg:CC 100))])]
800 "{ operands[3] = gen_reg_rtx (SImode); }")
802 (define_expand "snesi_special_extend"
804 (xor:SI (match_operand:SI 1 "register_operand" "")
805 (match_operand:SI 2 "register_operand" "")))
806 (parallel [(set (match_operand:DI 0 "register_operand" "")
807 (ne:DI (match_dup 3) (const_int 0)))
808 (clobber (reg:CC 100))])]
810 "{ operands[3] = gen_reg_rtx (SImode); }")
812 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
813 ;; However, the code handles both SImode and DImode.
815 [(set (match_operand:SI 0 "intreg_operand" "")
816 (eq:SI (match_dup 1) (const_int 0)))]
820 if (GET_MODE (sparc_compare_op0) == SImode)
824 if (GET_MODE (operands[0]) == SImode)
825 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
827 else if (! TARGET_ARCH64)
830 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
835 else if (GET_MODE (sparc_compare_op0) == DImode)
841 else if (GET_MODE (operands[0]) == SImode)
842 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
845 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
850 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
852 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
853 emit_jump_insn (gen_sne (operands[0]));
858 if (gen_v9_scc (EQ, operands))
865 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
866 ;; However, the code handles both SImode and DImode.
868 [(set (match_operand:SI 0 "intreg_operand" "")
869 (ne:SI (match_dup 1) (const_int 0)))]
873 if (GET_MODE (sparc_compare_op0) == SImode)
877 if (GET_MODE (operands[0]) == SImode)
878 pat = gen_snesi_special (operands[0], sparc_compare_op0,
880 else if (! TARGET_ARCH64)
883 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
888 else if (GET_MODE (sparc_compare_op0) == DImode)
894 else if (GET_MODE (operands[0]) == SImode)
895 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
898 pat = gen_snedi_special (operands[0], sparc_compare_op0,
903 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
905 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
906 emit_jump_insn (gen_sne (operands[0]));
911 if (gen_v9_scc (NE, operands))
919 [(set (match_operand:SI 0 "intreg_operand" "")
920 (gt:SI (match_dup 1) (const_int 0)))]
924 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
926 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
927 emit_jump_insn (gen_sne (operands[0]));
932 if (gen_v9_scc (GT, operands))
940 [(set (match_operand:SI 0 "intreg_operand" "")
941 (lt:SI (match_dup 1) (const_int 0)))]
945 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
947 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
948 emit_jump_insn (gen_sne (operands[0]));
953 if (gen_v9_scc (LT, operands))
961 [(set (match_operand:SI 0 "intreg_operand" "")
962 (ge:SI (match_dup 1) (const_int 0)))]
966 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
968 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
969 emit_jump_insn (gen_sne (operands[0]));
974 if (gen_v9_scc (GE, operands))
982 [(set (match_operand:SI 0 "intreg_operand" "")
983 (le:SI (match_dup 1) (const_int 0)))]
987 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
989 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
990 emit_jump_insn (gen_sne (operands[0]));
995 if (gen_v9_scc (LE, operands))
1002 (define_expand "sgtu"
1003 [(set (match_operand:SI 0 "intreg_operand" "")
1004 (gtu:SI (match_dup 1) (const_int 0)))]
1012 /* We can do ltu easily, so if both operands are registers, swap them and
1014 if ((GET_CODE (sparc_compare_op0) == REG
1015 || GET_CODE (sparc_compare_op0) == SUBREG)
1016 && (GET_CODE (sparc_compare_op1) == REG
1017 || GET_CODE (sparc_compare_op1) == SUBREG))
1019 tem = sparc_compare_op0;
1020 sparc_compare_op0 = sparc_compare_op1;
1021 sparc_compare_op1 = tem;
1022 pat = gen_sltu (operands[0]);
1023 if (pat == NULL_RTX)
1031 if (gen_v9_scc (GTU, operands))
1037 (define_expand "sltu"
1038 [(set (match_operand:SI 0 "intreg_operand" "")
1039 (ltu:SI (match_dup 1) (const_int 0)))]
1045 if (gen_v9_scc (LTU, operands))
1048 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1051 (define_expand "sgeu"
1052 [(set (match_operand:SI 0 "intreg_operand" "")
1053 (geu:SI (match_dup 1) (const_int 0)))]
1059 if (gen_v9_scc (GEU, operands))
1062 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1065 (define_expand "sleu"
1066 [(set (match_operand:SI 0 "intreg_operand" "")
1067 (leu:SI (match_dup 1) (const_int 0)))]
1075 /* We can do geu easily, so if both operands are registers, swap them and
1077 if ((GET_CODE (sparc_compare_op0) == REG
1078 || GET_CODE (sparc_compare_op0) == SUBREG)
1079 && (GET_CODE (sparc_compare_op1) == REG
1080 || GET_CODE (sparc_compare_op1) == SUBREG))
1082 tem = sparc_compare_op0;
1083 sparc_compare_op0 = sparc_compare_op1;
1084 sparc_compare_op1 = tem;
1085 pat = gen_sgeu (operands[0]);
1086 if (pat == NULL_RTX)
1094 if (gen_v9_scc (LEU, operands))
1100 ;; Now the DEFINE_INSNs for the scc cases.
1102 ;; The SEQ and SNE patterns are special because they can be done
1103 ;; without any branching and do not involve a COMPARE. We want
1104 ;; them to always use the splitz below so the results can be
1107 (define_insn "*snesi_zero"
1108 [(set (match_operand:SI 0 "register_operand" "=r")
1109 (ne:SI (match_operand:SI 1 "register_operand" "r")
1111 (clobber (reg:CC 100))]
1114 [(set_attr "length" "2")])
1117 [(set (match_operand:SI 0 "register_operand" "")
1118 (ne:SI (match_operand:SI 1 "register_operand" "")
1120 (clobber (reg:CC 100))]
1122 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1124 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1127 (define_insn "*neg_snesi_zero"
1128 [(set (match_operand:SI 0 "register_operand" "=r")
1129 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1131 (clobber (reg:CC 100))]
1134 [(set_attr "length" "2")])
1137 [(set (match_operand:SI 0 "register_operand" "")
1138 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1140 (clobber (reg:CC 100))]
1142 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1144 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1147 (define_insn "*snesi_zero_extend"
1148 [(set (match_operand:DI 0 "register_operand" "=r")
1149 (ne:DI (match_operand:SI 1 "register_operand" "r")
1151 (clobber (reg:CC 100))]
1154 [(set_attr "type" "unary")
1155 (set_attr "length" "2")])
1158 [(set (match_operand:DI 0 "register_operand" "")
1159 (ne:DI (match_operand:SI 1 "register_operand" "")
1161 (clobber (reg:CC 100))]
1163 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1165 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1167 (ltu:SI (reg:CC_NOOV 100)
1171 (define_insn "*snedi_zero"
1172 [(set (match_operand:DI 0 "register_operand" "=&r")
1173 (ne:DI (match_operand:DI 1 "register_operand" "r")
1177 [(set_attr "type" "cmove")
1178 (set_attr "length" "2")])
1181 [(set (match_operand:DI 0 "register_operand" "")
1182 (ne:DI (match_operand:DI 1 "register_operand" "")
1185 [(set (match_dup 0) (const_int 0))
1186 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1192 (define_insn "*neg_snedi_zero"
1193 [(set (match_operand:DI 0 "register_operand" "=&r")
1194 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1198 [(set_attr "type" "cmove")
1199 (set_attr "length" "2")])
1202 [(set (match_operand:DI 0 "register_operand" "")
1203 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1206 [(set (match_dup 0) (const_int 0))
1207 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1213 (define_insn "*snedi_zero_trunc"
1214 [(set (match_operand:SI 0 "register_operand" "=&r")
1215 (ne:SI (match_operand:DI 1 "register_operand" "r")
1219 [(set_attr "type" "cmove")
1220 (set_attr "length" "2")])
1223 [(set (match_operand:SI 0 "register_operand" "")
1224 (ne:SI (match_operand:DI 1 "register_operand" "")
1227 [(set (match_dup 0) (const_int 0))
1228 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1234 (define_insn "*seqsi_zero"
1235 [(set (match_operand:SI 0 "register_operand" "=r")
1236 (eq:SI (match_operand:SI 1 "register_operand" "r")
1238 (clobber (reg:CC 100))]
1241 [(set_attr "length" "2")])
1244 [(set (match_operand:SI 0 "register_operand" "")
1245 (eq:SI (match_operand:SI 1 "register_operand" "")
1247 (clobber (reg:CC 100))]
1249 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1251 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1254 (define_insn "*neg_seqsi_zero"
1255 [(set (match_operand:SI 0 "register_operand" "=r")
1256 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1258 (clobber (reg:CC 100))]
1261 [(set_attr "length" "2")])
1264 [(set (match_operand:SI 0 "register_operand" "")
1265 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1267 (clobber (reg:CC 100))]
1269 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1271 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1274 (define_insn "*seqsi_zero_extend"
1275 [(set (match_operand:DI 0 "register_operand" "=r")
1276 (eq:DI (match_operand:SI 1 "register_operand" "r")
1278 (clobber (reg:CC 100))]
1281 [(set_attr "type" "unary")
1282 (set_attr "length" "2")])
1285 [(set (match_operand:DI 0 "register_operand" "")
1286 (eq:DI (match_operand:SI 1 "register_operand" "")
1288 (clobber (reg:CC 100))]
1290 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1292 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1294 (ltu:SI (reg:CC_NOOV 100)
1298 (define_insn "*seqdi_zero"
1299 [(set (match_operand:DI 0 "register_operand" "=&r")
1300 (eq:DI (match_operand:DI 1 "register_operand" "r")
1304 [(set_attr "type" "cmove")
1305 (set_attr "length" "2")])
1308 [(set (match_operand:DI 0 "register_operand" "")
1309 (eq:DI (match_operand:DI 1 "register_operand" "")
1312 [(set (match_dup 0) (const_int 0))
1313 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1319 (define_insn "*neg_seqdi_zero"
1320 [(set (match_operand:DI 0 "register_operand" "=&r")
1321 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1325 [(set_attr "type" "cmove")
1326 (set_attr "length" "2")])
1329 [(set (match_operand:DI 0 "register_operand" "")
1330 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1333 [(set (match_dup 0) (const_int 0))
1334 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1340 (define_insn "*seqdi_zero_trunc"
1341 [(set (match_operand:SI 0 "register_operand" "=&r")
1342 (eq:SI (match_operand:DI 1 "register_operand" "r")
1346 [(set_attr "type" "cmove")
1347 (set_attr "length" "2")])
1350 [(set (match_operand:SI 0 "register_operand" "")
1351 (eq:SI (match_operand:DI 1 "register_operand" "")
1354 [(set (match_dup 0) (const_int 0))
1355 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1361 ;; We can also do (x + (i == 0)) and related, so put them in.
1362 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1365 (define_insn "*x_plus_i_ne_0"
1366 [(set (match_operand:SI 0 "register_operand" "=r")
1367 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1369 (match_operand:SI 2 "register_operand" "r")))
1370 (clobber (reg:CC 100))]
1373 [(set_attr "length" "2")])
1376 [(set (match_operand:SI 0 "register_operand" "")
1377 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1379 (match_operand:SI 2 "register_operand" "")))
1380 (clobber (reg:CC 100))]
1382 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1384 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1388 (define_insn "*x_minus_i_ne_0"
1389 [(set (match_operand:SI 0 "register_operand" "=r")
1390 (minus:SI (match_operand:SI 2 "register_operand" "r")
1391 (ne:SI (match_operand:SI 1 "register_operand" "r")
1393 (clobber (reg:CC 100))]
1396 [(set_attr "length" "2")])
1399 [(set (match_operand:SI 0 "register_operand" "")
1400 (minus:SI (match_operand:SI 2 "register_operand" "")
1401 (ne:SI (match_operand:SI 1 "register_operand" "")
1403 (clobber (reg:CC 100))]
1405 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1407 (set (match_dup 0) (minus:SI (match_dup 2)
1408 (ltu:SI (reg:CC 100) (const_int 0))))]
1411 (define_insn "*x_plus_i_eq_0"
1412 [(set (match_operand:SI 0 "register_operand" "=r")
1413 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1415 (match_operand:SI 2 "register_operand" "r")))
1416 (clobber (reg:CC 100))]
1419 [(set_attr "length" "2")])
1422 [(set (match_operand:SI 0 "register_operand" "")
1423 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1425 (match_operand:SI 2 "register_operand" "")))
1426 (clobber (reg:CC 100))]
1428 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1430 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1434 (define_insn "*x_minus_i_eq_0"
1435 [(set (match_operand:SI 0 "register_operand" "=r")
1436 (minus:SI (match_operand:SI 2 "register_operand" "r")
1437 (eq:SI (match_operand:SI 1 "register_operand" "r")
1439 (clobber (reg:CC 100))]
1442 [(set_attr "length" "2")])
1445 [(set (match_operand:SI 0 "register_operand" "")
1446 (minus:SI (match_operand:SI 2 "register_operand" "")
1447 (eq:SI (match_operand:SI 1 "register_operand" "")
1449 (clobber (reg:CC 100))]
1451 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1453 (set (match_dup 0) (minus:SI (match_dup 2)
1454 (geu:SI (reg:CC 100) (const_int 0))))]
1457 ;; We can also do GEU and LTU directly, but these operate after a compare.
1458 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1461 (define_insn "*sltu_insn"
1462 [(set (match_operand:SI 0 "register_operand" "=r")
1463 (ltu:SI (reg:CC 100) (const_int 0)))]
1465 "addx\\t%%g0, 0, %0"
1466 [(set_attr "type" "misc")
1467 (set_attr "length" "1")])
1469 (define_insn "*neg_sltu_insn"
1470 [(set (match_operand:SI 0 "register_operand" "=r")
1471 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1473 "subx\\t%%g0, 0, %0"
1474 [(set_attr "type" "misc")
1475 (set_attr "length" "1")])
1477 ;; ??? Combine should canonicalize these next two to the same pattern.
1478 (define_insn "*neg_sltu_minus_x"
1479 [(set (match_operand:SI 0 "register_operand" "=r")
1480 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1481 (match_operand:SI 1 "arith_operand" "rI")))]
1483 "subx\\t%%g0, %1, %0"
1484 [(set_attr "type" "misc")
1485 (set_attr "length" "1")])
1487 (define_insn "*neg_sltu_plus_x"
1488 [(set (match_operand:SI 0 "register_operand" "=r")
1489 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1490 (match_operand:SI 1 "arith_operand" "rI"))))]
1492 "subx\\t%%g0, %1, %0"
1493 [(set_attr "type" "misc")
1494 (set_attr "length" "1")])
1496 (define_insn "*sgeu_insn"
1497 [(set (match_operand:SI 0 "register_operand" "=r")
1498 (geu:SI (reg:CC 100) (const_int 0)))]
1500 "subx\\t%%g0, -1, %0"
1501 [(set_attr "type" "misc")
1502 (set_attr "length" "1")])
1504 (define_insn "*neg_sgeu_insn"
1505 [(set (match_operand:SI 0 "register_operand" "=r")
1506 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1508 "addx\\t%%g0, -1, %0"
1509 [(set_attr "type" "misc")
1510 (set_attr "length" "1")])
1512 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1513 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1516 (define_insn "*sltu_plus_x"
1517 [(set (match_operand:SI 0 "register_operand" "=r")
1518 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1519 (match_operand:SI 1 "arith_operand" "rI")))]
1521 "addx\\t%%g0, %1, %0"
1522 [(set_attr "type" "misc")
1523 (set_attr "length" "1")])
1525 (define_insn "*sltu_plus_x_plus_y"
1526 [(set (match_operand:SI 0 "register_operand" "=r")
1527 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1528 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1529 (match_operand:SI 2 "arith_operand" "rI"))))]
1532 [(set_attr "type" "misc")
1533 (set_attr "length" "1")])
1535 (define_insn "*x_minus_sltu"
1536 [(set (match_operand:SI 0 "register_operand" "=r")
1537 (minus:SI (match_operand:SI 1 "register_operand" "r")
1538 (ltu:SI (reg:CC 100) (const_int 0))))]
1541 [(set_attr "type" "misc")
1542 (set_attr "length" "1")])
1544 ;; ??? Combine should canonicalize these next two to the same pattern.
1545 (define_insn "*x_minus_y_minus_sltu"
1546 [(set (match_operand:SI 0 "register_operand" "=r")
1547 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1548 (match_operand:SI 2 "arith_operand" "rI"))
1549 (ltu:SI (reg:CC 100) (const_int 0))))]
1551 "subx\\t%r1, %2, %0"
1552 [(set_attr "type" "misc")
1553 (set_attr "length" "1")])
1555 (define_insn "*x_minus_sltu_plus_y"
1556 [(set (match_operand:SI 0 "register_operand" "=r")
1557 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1558 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1559 (match_operand:SI 2 "arith_operand" "rI"))))]
1561 "subx\\t%r1, %2, %0"
1562 [(set_attr "type" "misc")
1563 (set_attr "length" "1")])
1565 (define_insn "*sgeu_plus_x"
1566 [(set (match_operand:SI 0 "register_operand" "=r")
1567 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1568 (match_operand:SI 1 "register_operand" "r")))]
1571 [(set_attr "type" "misc")
1572 (set_attr "length" "1")])
1574 (define_insn "*x_minus_sgeu"
1575 [(set (match_operand:SI 0 "register_operand" "=r")
1576 (minus:SI (match_operand:SI 1 "register_operand" "r")
1577 (geu:SI (reg:CC 100) (const_int 0))))]
1580 [(set_attr "type" "misc")
1581 (set_attr "length" "1")])
1584 [(set (match_operand:SI 0 "register_operand" "=r")
1585 (match_operator:SI 2 "noov_compare_op"
1586 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1588 ;; 32 bit LTU/GEU are better implemented using addx/subx
1589 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1590 && (GET_MODE (operands[1]) == CCXmode
1591 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1592 [(set (match_dup 0) (const_int 0))
1594 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1600 ;; These control RTL generation for conditional jump insns
1602 ;; The quad-word fp compare library routines all return nonzero to indicate
1603 ;; true, which is different from the equivalent libgcc routines, so we must
1604 ;; handle them specially here.
1606 (define_expand "beq"
1608 (if_then_else (eq (match_dup 1) (const_int 0))
1609 (label_ref (match_operand 0 "" ""))
1614 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1615 && GET_CODE (sparc_compare_op0) == REG
1616 && GET_MODE (sparc_compare_op0) == DImode)
1618 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1621 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1623 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1624 emit_jump_insn (gen_bne (operands[0]));
1627 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1630 (define_expand "bne"
1632 (if_then_else (ne (match_dup 1) (const_int 0))
1633 (label_ref (match_operand 0 "" ""))
1638 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1639 && GET_CODE (sparc_compare_op0) == REG
1640 && GET_MODE (sparc_compare_op0) == DImode)
1642 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1645 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1647 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1648 emit_jump_insn (gen_bne (operands[0]));
1651 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1654 (define_expand "bgt"
1656 (if_then_else (gt (match_dup 1) (const_int 0))
1657 (label_ref (match_operand 0 "" ""))
1662 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1663 && GET_CODE (sparc_compare_op0) == REG
1664 && GET_MODE (sparc_compare_op0) == DImode)
1666 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1669 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1671 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1672 emit_jump_insn (gen_bne (operands[0]));
1675 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1678 (define_expand "bgtu"
1680 (if_then_else (gtu (match_dup 1) (const_int 0))
1681 (label_ref (match_operand 0 "" ""))
1685 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1688 (define_expand "blt"
1690 (if_then_else (lt (match_dup 1) (const_int 0))
1691 (label_ref (match_operand 0 "" ""))
1696 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1697 && GET_CODE (sparc_compare_op0) == REG
1698 && GET_MODE (sparc_compare_op0) == DImode)
1700 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1703 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1705 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1706 emit_jump_insn (gen_bne (operands[0]));
1709 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1712 (define_expand "bltu"
1714 (if_then_else (ltu (match_dup 1) (const_int 0))
1715 (label_ref (match_operand 0 "" ""))
1719 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1722 (define_expand "bge"
1724 (if_then_else (ge (match_dup 1) (const_int 0))
1725 (label_ref (match_operand 0 "" ""))
1730 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1731 && GET_CODE (sparc_compare_op0) == REG
1732 && GET_MODE (sparc_compare_op0) == DImode)
1734 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1737 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1739 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1740 emit_jump_insn (gen_bne (operands[0]));
1743 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1746 (define_expand "bgeu"
1748 (if_then_else (geu (match_dup 1) (const_int 0))
1749 (label_ref (match_operand 0 "" ""))
1753 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1756 (define_expand "ble"
1758 (if_then_else (le (match_dup 1) (const_int 0))
1759 (label_ref (match_operand 0 "" ""))
1764 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1765 && GET_CODE (sparc_compare_op0) == REG
1766 && GET_MODE (sparc_compare_op0) == DImode)
1768 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1771 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1773 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1774 emit_jump_insn (gen_bne (operands[0]));
1777 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1780 (define_expand "bleu"
1782 (if_then_else (leu (match_dup 1) (const_int 0))
1783 (label_ref (match_operand 0 "" ""))
1787 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1790 (define_expand "bunordered"
1792 (if_then_else (unordered (match_dup 1) (const_int 0))
1793 (label_ref (match_operand 0 "" ""))
1798 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1800 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1802 emit_jump_insn (gen_beq (operands[0]));
1805 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1809 (define_expand "bordered"
1811 (if_then_else (ordered (match_dup 1) (const_int 0))
1812 (label_ref (match_operand 0 "" ""))
1817 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1819 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1820 emit_jump_insn (gen_bne (operands[0]));
1823 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1827 (define_expand "bungt"
1829 (if_then_else (ungt (match_dup 1) (const_int 0))
1830 (label_ref (match_operand 0 "" ""))
1835 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1837 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1838 emit_jump_insn (gen_bgt (operands[0]));
1841 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1844 (define_expand "bunlt"
1846 (if_then_else (unlt (match_dup 1) (const_int 0))
1847 (label_ref (match_operand 0 "" ""))
1852 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1854 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1855 emit_jump_insn (gen_bne (operands[0]));
1858 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1861 (define_expand "buneq"
1863 (if_then_else (uneq (match_dup 1) (const_int 0))
1864 (label_ref (match_operand 0 "" ""))
1869 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1871 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1872 emit_jump_insn (gen_beq (operands[0]));
1875 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1878 (define_expand "bunge"
1880 (if_then_else (unge (match_dup 1) (const_int 0))
1881 (label_ref (match_operand 0 "" ""))
1886 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1888 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1889 emit_jump_insn (gen_bne (operands[0]));
1892 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1895 (define_expand "bunle"
1897 (if_then_else (unle (match_dup 1) (const_int 0))
1898 (label_ref (match_operand 0 "" ""))
1903 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1905 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1906 emit_jump_insn (gen_bne (operands[0]));
1909 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1912 (define_expand "bltgt"
1914 (if_then_else (ltgt (match_dup 1) (const_int 0))
1915 (label_ref (match_operand 0 "" ""))
1920 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1922 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1923 emit_jump_insn (gen_bne (operands[0]));
1926 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1929 ;; Now match both normal and inverted jump.
1931 ;; XXX fpcmp nop braindamage
1932 (define_insn "*normal_branch"
1934 (if_then_else (match_operator 0 "noov_compare_op"
1935 [(reg 100) (const_int 0)])
1936 (label_ref (match_operand 1 "" ""))
1941 return output_cbranch (operands[0], 1, 0,
1942 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1943 ! final_sequence, insn);
1945 [(set_attr "type" "branch")])
1947 ;; XXX fpcmp nop braindamage
1948 (define_insn "*inverted_branch"
1950 (if_then_else (match_operator 0 "noov_compare_op"
1951 [(reg 100) (const_int 0)])
1953 (label_ref (match_operand 1 "" ""))))]
1957 return output_cbranch (operands[0], 1, 1,
1958 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1959 ! final_sequence, insn);
1961 [(set_attr "type" "branch")])
1963 ;; XXX fpcmp nop braindamage
1964 (define_insn "*normal_fp_branch"
1966 (if_then_else (match_operator 1 "comparison_operator"
1967 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1969 (label_ref (match_operand 2 "" ""))
1974 return output_cbranch (operands[1], 2, 0,
1975 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1976 ! final_sequence, insn);
1978 [(set_attr "type" "branch")])
1980 ;; XXX fpcmp nop braindamage
1981 (define_insn "*inverted_fp_branch"
1983 (if_then_else (match_operator 1 "comparison_operator"
1984 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1987 (label_ref (match_operand 2 "" ""))))]
1991 return output_cbranch (operands[1], 2, 1,
1992 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1993 ! final_sequence, insn);
1995 [(set_attr "type" "branch")])
1997 ;; XXX fpcmp nop braindamage
1998 (define_insn "*normal_fpe_branch"
2000 (if_then_else (match_operator 1 "comparison_operator"
2001 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2003 (label_ref (match_operand 2 "" ""))
2008 return output_cbranch (operands[1], 2, 0,
2009 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2010 ! final_sequence, insn);
2012 [(set_attr "type" "branch")])
2014 ;; XXX fpcmp nop braindamage
2015 (define_insn "*inverted_fpe_branch"
2017 (if_then_else (match_operator 1 "comparison_operator"
2018 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2021 (label_ref (match_operand 2 "" ""))))]
2025 return output_cbranch (operands[1], 2, 1,
2026 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2027 ! final_sequence, insn);
2029 [(set_attr "type" "branch")])
2031 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2032 ;; in the architecture.
2034 ;; There are no 32 bit brreg insns.
2037 (define_insn "*normal_int_branch_sp64"
2039 (if_then_else (match_operator 0 "v9_regcmp_op"
2040 [(match_operand:DI 1 "register_operand" "r")
2042 (label_ref (match_operand 2 "" ""))
2047 return output_v9branch (operands[0], 1, 2, 0,
2048 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2049 ! final_sequence, insn);
2051 [(set_attr "type" "branch")])
2054 (define_insn "*inverted_int_branch_sp64"
2056 (if_then_else (match_operator 0 "v9_regcmp_op"
2057 [(match_operand:DI 1 "register_operand" "r")
2060 (label_ref (match_operand 2 "" ""))))]
2064 return output_v9branch (operands[0], 1, 2, 1,
2065 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2066 ! final_sequence, insn);
2068 [(set_attr "type" "branch")])
2070 ;; Load program counter insns.
2072 (define_insn "get_pc"
2073 [(clobber (reg:SI 15))
2074 (set (match_operand 0 "register_operand" "=r")
2075 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2076 "flag_pic && REGNO (operands[0]) == 23"
2077 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2078 [(set_attr "length" "3")])
2080 ;; Currently unused...
2081 ;; (define_insn "get_pc_via_rdpc"
2082 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2085 ;; [(set_attr "type" "move")])
2088 ;; Move instructions
2090 (define_expand "movqi"
2091 [(set (match_operand:QI 0 "general_operand" "")
2092 (match_operand:QI 1 "general_operand" ""))]
2096 /* Working with CONST_INTs is easier, so convert
2097 a double if needed. */
2098 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2100 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2102 else if (GET_CODE (operands[1]) == CONST_INT)
2104 /* And further, we know for all QI cases that only the
2105 low byte is significant, which we can always process
2106 in a single insn. So mask it now. */
2107 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2110 /* Handle sets of MEM first. */
2111 if (GET_CODE (operands[0]) == MEM)
2113 if (reg_or_0_operand (operands[1], QImode))
2116 if (! reload_in_progress)
2118 operands[0] = validize_mem (operands[0]);
2119 operands[1] = force_reg (QImode, operands[1]);
2123 /* Fixup PIC cases. */
2126 if (CONSTANT_P (operands[1])
2127 && pic_address_needs_scratch (operands[1]))
2128 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2130 if (symbolic_operand (operands[1], QImode))
2132 operands[1] = legitimize_pic_address (operands[1],
2134 (reload_in_progress ?
2141 /* All QI constants require only one insn, so proceed. */
2147 (define_insn "*movqi_insn"
2148 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2149 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2150 "(register_operand (operands[0], QImode)
2151 || reg_or_0_operand (operands[1], QImode))"
2156 [(set_attr "type" "move,load,store")
2157 (set_attr "length" "1")])
2159 (define_expand "movhi"
2160 [(set (match_operand:HI 0 "general_operand" "")
2161 (match_operand:HI 1 "general_operand" ""))]
2165 /* Working with CONST_INTs is easier, so convert
2166 a double if needed. */
2167 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2168 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2170 /* Handle sets of MEM first. */
2171 if (GET_CODE (operands[0]) == MEM)
2173 if (reg_or_0_operand (operands[1], HImode))
2176 if (! reload_in_progress)
2178 operands[0] = validize_mem (operands[0]);
2179 operands[1] = force_reg (HImode, operands[1]);
2183 /* Fixup PIC cases. */
2186 if (CONSTANT_P (operands[1])
2187 && pic_address_needs_scratch (operands[1]))
2188 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2190 if (symbolic_operand (operands[1], HImode))
2192 operands[1] = legitimize_pic_address (operands[1],
2194 (reload_in_progress ?
2201 /* This makes sure we will not get rematched due to splittage. */
2202 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2204 else if (CONSTANT_P (operands[1])
2205 && GET_CODE (operands[1]) != HIGH
2206 && GET_CODE (operands[1]) != LO_SUM)
2208 sparc_emit_set_const32 (operands[0], operands[1]);
2215 (define_insn "*movhi_const64_special"
2216 [(set (match_operand:HI 0 "register_operand" "=r")
2217 (match_operand:HI 1 "const64_high_operand" ""))]
2219 "sethi\\t%%hi(%a1), %0"
2220 [(set_attr "type" "move")
2221 (set_attr "length" "1")])
2223 (define_insn "*movhi_insn"
2224 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2225 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2226 "(register_operand (operands[0], HImode)
2227 || reg_or_0_operand (operands[1], HImode))"
2230 sethi\\t%%hi(%a1), %0
2233 [(set_attr "type" "move,move,load,store")
2234 (set_attr "length" "1")])
2236 ;; We always work with constants here.
2237 (define_insn "*movhi_lo_sum"
2238 [(set (match_operand:HI 0 "register_operand" "=r")
2239 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2240 (match_operand:HI 2 "arith_operand" "I")))]
2243 [(set_attr "type" "ialu")
2244 (set_attr "length" "1")])
2246 (define_expand "movsi"
2247 [(set (match_operand:SI 0 "general_operand" "")
2248 (match_operand:SI 1 "general_operand" ""))]
2252 /* Working with CONST_INTs is easier, so convert
2253 a double if needed. */
2254 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2255 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2257 /* Handle sets of MEM first. */
2258 if (GET_CODE (operands[0]) == MEM)
2260 if (reg_or_0_operand (operands[1], SImode))
2263 if (! reload_in_progress)
2265 operands[0] = validize_mem (operands[0]);
2266 operands[1] = force_reg (SImode, operands[1]);
2270 /* Fixup PIC cases. */
2273 if (CONSTANT_P (operands[1])
2274 && pic_address_needs_scratch (operands[1]))
2275 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2277 if (GET_CODE (operands[1]) == LABEL_REF)
2280 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2284 if (symbolic_operand (operands[1], SImode))
2286 operands[1] = legitimize_pic_address (operands[1],
2288 (reload_in_progress ?
2295 /* If we are trying to toss an integer constant into the
2296 FPU registers, force it into memory. */
2297 if (GET_CODE (operands[0]) == REG
2298 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2299 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2300 && CONSTANT_P (operands[1]))
2301 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2304 /* This makes sure we will not get rematched due to splittage. */
2305 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2307 else if (CONSTANT_P (operands[1])
2308 && GET_CODE (operands[1]) != HIGH
2309 && GET_CODE (operands[1]) != LO_SUM)
2311 sparc_emit_set_const32 (operands[0], operands[1]);
2318 ;; This is needed to show CSE exactly which bits are set
2319 ;; in a 64-bit register by sethi instructions.
2320 (define_insn "*movsi_const64_special"
2321 [(set (match_operand:SI 0 "register_operand" "=r")
2322 (match_operand:SI 1 "const64_high_operand" ""))]
2324 "sethi\\t%%hi(%a1), %0"
2325 [(set_attr "type" "move")
2326 (set_attr "length" "1")])
2328 (define_insn "*movsi_insn"
2329 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2330 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2331 "(register_operand (operands[0], SImode)
2332 || reg_or_0_operand (operands[1], SImode))"
2336 sethi\\t%%hi(%a1), %0
2343 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2344 (set_attr "length" "1")])
2346 (define_insn "*movsi_lo_sum"
2347 [(set (match_operand:SI 0 "register_operand" "=r")
2348 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2349 (match_operand:SI 2 "immediate_operand" "in")))]
2351 "or\\t%1, %%lo(%a2), %0"
2352 [(set_attr "type" "ialu")
2353 (set_attr "length" "1")])
2355 (define_insn "*movsi_high"
2356 [(set (match_operand:SI 0 "register_operand" "=r")
2357 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2359 "sethi\\t%%hi(%a1), %0"
2360 [(set_attr "type" "move")
2361 (set_attr "length" "1")])
2363 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2364 ;; so that CSE won't optimize the address computation away.
2365 (define_insn "movsi_lo_sum_pic"
2366 [(set (match_operand:SI 0 "register_operand" "=r")
2367 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2368 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2370 "or\\t%1, %%lo(%a2), %0"
2371 [(set_attr "type" "ialu")
2372 (set_attr "length" "1")])
2374 (define_insn "movsi_high_pic"
2375 [(set (match_operand:SI 0 "register_operand" "=r")
2376 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2377 "flag_pic && check_pic (1)"
2378 "sethi\\t%%hi(%a1), %0"
2379 [(set_attr "type" "move")
2380 (set_attr "length" "1")])
2382 (define_expand "movsi_pic_label_ref"
2383 [(set (match_dup 3) (high:SI
2384 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2386 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2387 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2388 (set (match_operand:SI 0 "register_operand" "=r")
2389 (minus:SI (match_dup 5) (match_dup 4)))]
2393 current_function_uses_pic_offset_table = 1;
2394 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2397 operands[3] = operands[0];
2398 operands[4] = operands[0];
2402 operands[3] = gen_reg_rtx (SImode);
2403 operands[4] = gen_reg_rtx (SImode);
2405 operands[5] = pic_offset_table_rtx;
2408 (define_insn "*movsi_high_pic_label_ref"
2409 [(set (match_operand:SI 0 "register_operand" "=r")
2411 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2412 (match_operand:SI 2 "" "")] 5)))]
2414 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2415 [(set_attr "type" "move")
2416 (set_attr "length" "1")])
2418 (define_insn "*movsi_lo_sum_pic_label_ref"
2419 [(set (match_operand:SI 0 "register_operand" "=r")
2420 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2421 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2422 (match_operand:SI 3 "" "")] 5)))]
2424 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2425 [(set_attr "type" "ialu")
2426 (set_attr "length" "1")])
2428 (define_expand "movdi"
2429 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2430 (match_operand:DI 1 "general_operand" ""))]
2434 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2435 if (GET_CODE (operands[1]) == CONST_DOUBLE
2436 #if HOST_BITS_PER_WIDE_INT == 32
2437 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2438 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2439 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2440 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2443 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2445 /* Handle MEM cases first. */
2446 if (GET_CODE (operands[0]) == MEM)
2448 /* If it's a REG, we can always do it.
2449 The const zero case is more complex, on v9
2450 we can always perform it. */
2451 if (register_operand (operands[1], DImode)
2453 && (operands[1] == const0_rtx)))
2456 if (! reload_in_progress)
2458 operands[0] = validize_mem (operands[0]);
2459 operands[1] = force_reg (DImode, operands[1]);
2465 if (CONSTANT_P (operands[1])
2466 && pic_address_needs_scratch (operands[1]))
2467 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2469 if (GET_CODE (operands[1]) == LABEL_REF)
2471 if (! TARGET_ARCH64)
2473 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2477 if (symbolic_operand (operands[1], DImode))
2479 operands[1] = legitimize_pic_address (operands[1],
2481 (reload_in_progress ?
2488 /* If we are trying to toss an integer constant into the
2489 FPU registers, force it into memory. */
2490 if (GET_CODE (operands[0]) == REG
2491 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2492 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2493 && CONSTANT_P (operands[1]))
2494 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2497 /* This makes sure we will not get rematched due to splittage. */
2498 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2500 else if (TARGET_ARCH64
2501 && CONSTANT_P (operands[1])
2502 && GET_CODE (operands[1]) != HIGH
2503 && GET_CODE (operands[1]) != LO_SUM)
2505 sparc_emit_set_const64 (operands[0], operands[1]);
2513 ;; Be careful, fmovd does not exist when !arch64.
2514 ;; We match MEM moves directly when we have correct even
2515 ;; numbered registers, but fall into splits otherwise.
2516 ;; The constraint ordering here is really important to
2517 ;; avoid insane problems in reload, especially for patterns
2520 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2521 ;; (const_int -5016)))
2524 (define_insn "*movdi_insn_sp32"
2525 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2526 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2528 (register_operand (operands[0], DImode)
2529 || register_operand (operands[1], DImode))"
2542 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2543 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2545 ;; The following are generated by sparc_emit_set_const64
2546 (define_insn "*movdi_sp64_dbl"
2547 [(set (match_operand:DI 0 "register_operand" "=r")
2548 (match_operand:DI 1 "const64_operand" ""))]
2550 && HOST_BITS_PER_WIDE_INT != 64)"
2552 [(set_attr "type" "move")
2553 (set_attr "length" "1")])
2555 ;; This is needed to show CSE exactly which bits are set
2556 ;; in a 64-bit register by sethi instructions.
2557 (define_insn "*movdi_const64_special"
2558 [(set (match_operand:DI 0 "register_operand" "=r")
2559 (match_operand:DI 1 "const64_high_operand" ""))]
2561 "sethi\\t%%hi(%a1), %0"
2562 [(set_attr "type" "move")
2563 (set_attr "length" "1")])
2565 (define_insn "*movdi_insn_sp64"
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"))]
2569 (register_operand (operands[0], DImode)
2570 || reg_or_0_operand (operands[1], DImode))"
2573 sethi\\t%%hi(%a1), %0
2581 [(set_attr "type" "move,move,move,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 "type" "move")
2618 (set_attr "length" "1")])
2620 (define_insn "*movdi_lo_sum_pic_label_ref"
2621 [(set (match_operand:DI 0 "register_operand" "=r")
2622 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2623 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2624 (match_operand:DI 3 "" "")] 5)))]
2625 "TARGET_ARCH64 && flag_pic"
2626 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2627 [(set_attr "type" "ialu")
2628 (set_attr "length" "1")])
2630 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2631 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2633 (define_insn "movdi_lo_sum_pic"
2634 [(set (match_operand:DI 0 "register_operand" "=r")
2635 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2636 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2637 "TARGET_ARCH64 && flag_pic"
2638 "or\\t%1, %%lo(%a2), %0"
2639 [(set_attr "type" "ialu")
2640 (set_attr "length" "1")])
2642 (define_insn "movdi_high_pic"
2643 [(set (match_operand:DI 0 "register_operand" "=r")
2644 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2645 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2646 "sethi\\t%%hi(%a1), %0"
2647 [(set_attr "type" "move")
2648 (set_attr "length" "1")])
2650 (define_insn "*sethi_di_medlow_embmedany_pic"
2651 [(set (match_operand:DI 0 "register_operand" "=r")
2652 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2653 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2654 "sethi\\t%%hi(%a1), %0"
2655 [(set_attr "type" "move")
2656 (set_attr "length" "1")])
2658 (define_insn "*sethi_di_medlow"
2659 [(set (match_operand:DI 0 "register_operand" "=r")
2660 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2661 "TARGET_CM_MEDLOW && check_pic (1)"
2662 "sethi\\t%%hi(%a1), %0"
2663 [(set_attr "type" "move")
2664 (set_attr "length" "1")])
2666 (define_insn "*losum_di_medlow"
2667 [(set (match_operand:DI 0 "register_operand" "=r")
2668 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2669 (match_operand:DI 2 "symbolic_operand" "")))]
2671 "or\\t%1, %%lo(%a2), %0"
2672 [(set_attr "type" "ialu")
2673 (set_attr "length" "1")])
2675 (define_insn "seth44"
2676 [(set (match_operand:DI 0 "register_operand" "=r")
2677 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2679 "sethi\\t%%h44(%a1), %0"
2680 [(set_attr "type" "move")
2681 (set_attr "length" "1")])
2683 (define_insn "setm44"
2684 [(set (match_operand:DI 0 "register_operand" "=r")
2685 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2686 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2688 "or\\t%1, %%m44(%a2), %0"
2689 [(set_attr "type" "move")
2690 (set_attr "length" "1")])
2692 (define_insn "setl44"
2693 [(set (match_operand:DI 0 "register_operand" "=r")
2694 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2695 (match_operand:DI 2 "symbolic_operand" "")))]
2697 "or\\t%1, %%l44(%a2), %0"
2698 [(set_attr "type" "ialu")
2699 (set_attr "length" "1")])
2701 (define_insn "sethh"
2702 [(set (match_operand:DI 0 "register_operand" "=r")
2703 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2705 "sethi\\t%%hh(%a1), %0"
2706 [(set_attr "type" "move")
2707 (set_attr "length" "1")])
2709 (define_insn "setlm"
2710 [(set (match_operand:DI 0 "register_operand" "=r")
2711 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2713 "sethi\\t%%lm(%a1), %0"
2714 [(set_attr "type" "move")
2715 (set_attr "length" "1")])
2717 (define_insn "sethm"
2718 [(set (match_operand:DI 0 "register_operand" "=r")
2719 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2720 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2722 "or\\t%1, %%hm(%a2), %0"
2723 [(set_attr "type" "ialu")
2724 (set_attr "length" "1")])
2726 (define_insn "setlo"
2727 [(set (match_operand:DI 0 "register_operand" "=r")
2728 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2729 (match_operand:DI 2 "symbolic_operand" "")))]
2731 "or\\t%1, %%lo(%a2), %0"
2732 [(set_attr "type" "ialu")
2733 (set_attr "length" "1")])
2735 (define_insn "embmedany_sethi"
2736 [(set (match_operand:DI 0 "register_operand" "=r")
2737 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2738 "TARGET_CM_EMBMEDANY && check_pic (1)"
2739 "sethi\\t%%hi(%a1), %0"
2740 [(set_attr "type" "move")
2741 (set_attr "length" "1")])
2743 (define_insn "embmedany_losum"
2744 [(set (match_operand:DI 0 "register_operand" "=r")
2745 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2746 (match_operand:DI 2 "data_segment_operand" "")))]
2747 "TARGET_CM_EMBMEDANY"
2748 "add\\t%1, %%lo(%a2), %0"
2749 [(set_attr "type" "ialu")
2750 (set_attr "length" "1")])
2752 (define_insn "embmedany_brsum"
2753 [(set (match_operand:DI 0 "register_operand" "=r")
2754 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2755 "TARGET_CM_EMBMEDANY"
2757 [(set_attr "length" "1")])
2759 (define_insn "embmedany_textuhi"
2760 [(set (match_operand:DI 0 "register_operand" "=r")
2761 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2762 "TARGET_CM_EMBMEDANY && check_pic (1)"
2763 "sethi\\t%%uhi(%a1), %0"
2764 [(set_attr "type" "move")
2765 (set_attr "length" "1")])
2767 (define_insn "embmedany_texthi"
2768 [(set (match_operand:DI 0 "register_operand" "=r")
2769 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2770 "TARGET_CM_EMBMEDANY && check_pic (1)"
2771 "sethi\\t%%hi(%a1), %0"
2772 [(set_attr "type" "move")
2773 (set_attr "length" "1")])
2775 (define_insn "embmedany_textulo"
2776 [(set (match_operand:DI 0 "register_operand" "=r")
2777 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2778 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2779 "TARGET_CM_EMBMEDANY"
2780 "or\\t%1, %%ulo(%a2), %0"
2781 [(set_attr "type" "ialu")
2782 (set_attr "length" "1")])
2784 (define_insn "embmedany_textlo"
2785 [(set (match_operand:DI 0 "register_operand" "=r")
2786 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2787 (match_operand:DI 2 "text_segment_operand" "")))]
2788 "TARGET_CM_EMBMEDANY"
2789 "or\\t%1, %%lo(%a2), %0"
2790 [(set_attr "type" "ialu")
2791 (set_attr "length" "1")])
2793 ;; Now some patterns to help reload out a bit.
2794 (define_expand "reload_indi"
2795 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2796 (match_operand:DI 1 "immediate_operand" "")
2797 (match_operand:TI 2 "register_operand" "=&r")])]
2799 || TARGET_CM_EMBMEDANY)
2803 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2804 gen_rtx_REG (DImode, REGNO (operands[2])));
2808 (define_expand "reload_outdi"
2809 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2810 (match_operand:DI 1 "immediate_operand" "")
2811 (match_operand:TI 2 "register_operand" "=&r")])]
2813 || TARGET_CM_EMBMEDANY)
2817 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2818 gen_rtx_REG (DImode, REGNO (operands[2])));
2822 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2824 [(set (match_operand:DI 0 "register_operand" "")
2825 (match_operand:DI 1 "const_int_operand" ""))]
2826 "! TARGET_ARCH64 && reload_completed"
2827 [(clobber (const_int 0))]
2830 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2831 (INTVAL (operands[1]) < 0) ?
2834 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2840 [(set (match_operand:DI 0 "register_operand" "")
2841 (match_operand:DI 1 "const_double_operand" ""))]
2842 "! TARGET_ARCH64 && reload_completed"
2843 [(clobber (const_int 0))]
2846 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2847 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2849 /* Slick... but this trick loses if this subreg constant part
2850 can be done in one insn. */
2851 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2852 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2853 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2855 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2856 gen_highpart (SImode, operands[0])));
2860 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2861 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2867 [(set (match_operand:DI 0 "register_operand" "")
2868 (match_operand:DI 1 "register_operand" ""))]
2869 "! TARGET_ARCH64 && reload_completed"
2870 [(clobber (const_int 0))]
2873 rtx set_dest = operands[0];
2874 rtx set_src = operands[1];
2878 if (GET_CODE (set_dest) == SUBREG)
2879 set_dest = alter_subreg (set_dest);
2880 if (GET_CODE (set_src) == SUBREG)
2881 set_src = alter_subreg (set_src);
2883 dest1 = gen_highpart (SImode, set_dest);
2884 dest2 = gen_lowpart (SImode, set_dest);
2885 src1 = gen_highpart (SImode, set_src);
2886 src2 = gen_lowpart (SImode, set_src);
2888 /* Now emit using the real source and destination we found, swapping
2889 the order if we detect overlap. */
2890 if (reg_overlap_mentioned_p (dest1, src2))
2892 emit_insn (gen_movsi (dest2, src2));
2893 emit_insn (gen_movsi (dest1, src1));
2897 emit_insn (gen_movsi (dest1, src1));
2898 emit_insn (gen_movsi (dest2, src2));
2903 ;; Now handle the cases of memory moves from/to non-even
2904 ;; DI mode register pairs.
2906 [(set (match_operand:DI 0 "register_operand" "")
2907 (match_operand:DI 1 "memory_operand" ""))]
2910 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2911 [(clobber (const_int 0))]
2914 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2915 rtx word1 = change_address (operands[1], SImode,
2916 plus_constant_for_output (XEXP (word0, 0), 4));
2917 rtx high_part = gen_highpart (SImode, operands[0]);
2918 rtx low_part = gen_lowpart (SImode, operands[0]);
2920 if (reg_overlap_mentioned_p (high_part, word1))
2922 emit_insn (gen_movsi (low_part, word1));
2923 emit_insn (gen_movsi (high_part, word0));
2927 emit_insn (gen_movsi (high_part, word0));
2928 emit_insn (gen_movsi (low_part, word1));
2934 [(set (match_operand:DI 0 "memory_operand" "")
2935 (match_operand:DI 1 "register_operand" ""))]
2938 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2939 [(clobber (const_int 0))]
2942 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2943 rtx word1 = change_address (operands[0], SImode,
2944 plus_constant_for_output (XEXP (word0, 0), 4));
2945 rtx high_part = gen_highpart (SImode, operands[1]);
2946 rtx low_part = gen_lowpart (SImode, operands[1]);
2948 emit_insn (gen_movsi (word0, high_part));
2949 emit_insn (gen_movsi (word1, low_part));
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,move,move,move,*,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,move,move,move,*,load,fpload,fpstore,store")
3050 (set_attr "length" "1")])
3052 (define_insn "*movsf_lo_sum"
3053 [(set (match_operand:SF 0 "register_operand" "")
3054 (lo_sum:SF (match_operand:SF 1 "register_operand" "")
3055 (match_operand:SF 2 "const_double_operand" "")))]
3056 "TARGET_FPU && fp_high_losum_p (operands[2])"
3062 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3063 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3064 operands[2] = GEN_INT (i);
3065 return \"or\\t%1, %%lo(%a2), %0\";
3067 [(set_attr "type" "ialu")
3068 (set_attr "length" "1")])
3070 (define_insn "*movsf_high"
3071 [(set (match_operand:SF 0 "register_operand" "")
3072 (high:SF (match_operand:SF 1 "const_double_operand" "")))]
3073 "TARGET_FPU && fp_high_losum_p (operands[1])"
3079 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3080 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3081 operands[1] = GEN_INT (i);
3082 return \"sethi\\t%%hi(%1), %0\";
3084 [(set_attr "type" "move")
3085 (set_attr "length" "1")])
3088 [(set (match_operand:SF 0 "register_operand" "")
3089 (match_operand:SF 1 "const_double_operand" ""))]
3091 && fp_high_losum_p (operands[1])
3092 && (GET_CODE (operands[0]) == REG
3093 && REGNO (operands[0]) < 32)"
3094 [(set (match_dup 0) (high:SF (match_dup 1)))
3095 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3097 ;; Exactly the same as above, except that all `f' cases are deleted.
3098 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3101 (define_insn "*movsf_no_f_insn"
3102 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
3103 (match_operand:SF 1 "input_operand" "r,m,r"))]
3105 && (register_operand (operands[0], SFmode)
3106 || register_operand (operands[1], SFmode))"
3111 [(set_attr "type" "move,load,store")
3112 (set_attr "length" "1")])
3114 (define_expand "movsf"
3115 [(set (match_operand:SF 0 "general_operand" "")
3116 (match_operand:SF 1 "general_operand" ""))]
3120 /* Force SFmode constants into memory. */
3121 if (GET_CODE (operands[0]) == REG
3122 && CONSTANT_P (operands[1]))
3124 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3127 /* emit_group_store will send such bogosity to us when it is
3128 not storing directly into memory. So fix this up to avoid
3129 crashes in output_constant_pool. */
3130 if (operands [1] == const0_rtx)
3131 operands[1] = CONST0_RTX (SFmode);
3132 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3136 /* Handle sets of MEM first. */
3137 if (GET_CODE (operands[0]) == MEM)
3139 if (register_operand (operands[1], SFmode)
3140 || fp_zero_operand (operands[1], SFmode))
3143 if (! reload_in_progress)
3145 operands[0] = validize_mem (operands[0]);
3146 operands[1] = force_reg (SFmode, operands[1]);
3150 /* Fixup PIC cases. */
3153 if (CONSTANT_P (operands[1])
3154 && pic_address_needs_scratch (operands[1]))
3155 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3157 if (symbolic_operand (operands[1], SFmode))
3159 operands[1] = legitimize_pic_address (operands[1],
3161 (reload_in_progress ?
3171 (define_insn "*clear_df"
3172 [(set (match_operand:DF 0 "register_operand" "=e")
3173 (match_operand:DF 1 "fp_zero_operand" ""))]
3176 [(set_attr "type" "fpmove")
3177 (set_attr "length" "1")])
3179 (define_insn "*clear_dfp"
3180 [(set (match_operand:DF 0 "memory_operand" "=m")
3181 (match_operand:DF 1 "fp_zero_operand" ""))]
3184 [(set_attr "type" "store")
3185 (set_attr "length" "1")])
3187 (define_insn "*movdf_const_intreg_sp32"
3188 [(set (match_operand:DF 0 "register_operand" "=e,e,?r")
3189 (match_operand:DF 1 "const_double_operand" "T#F,o#F,F"))]
3190 "TARGET_FPU && ! TARGET_ARCH64"
3195 [(set_attr "type" "move")
3196 (set_attr "length" "1,2,2")])
3198 ;; Now that we redo life analysis with a clean slate after
3199 ;; instruction splitting for sched2 this can work.
3200 (define_insn "*movdf_const_intreg_sp64"
3201 [(set (match_operand:DF 0 "register_operand" "=e,?r")
3202 (match_operand:DF 1 "const_double_operand" "m#F,F"))]
3203 "TARGET_FPU && TARGET_ARCH64"
3207 [(set_attr "type" "move")
3208 (set_attr "length" "1,2")])
3211 [(set (match_operand:DF 0 "register_operand" "")
3212 (match_operand:DF 1 "const_double_operand" ""))]
3214 && (GET_CODE (operands[0]) == REG
3215 && REGNO (operands[0]) < 32)
3216 && reload_completed"
3217 [(clobber (const_int 0))]
3223 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3224 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3225 if (GET_CODE (operands[0]) == SUBREG)
3226 operands[0] = alter_subreg (operands[0]);
3227 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3231 #if HOST_BITS_PER_WIDE_INT == 64
3234 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3235 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3236 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3238 emit_insn (gen_movdi (operands[0],
3239 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3245 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3248 /* Slick... but this trick loses if this subreg constant part
3249 can be done in one insn. */
3251 && !(SPARC_SETHI_P (l[0])
3252 || SPARC_SIMM13_P (l[0])))
3254 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3255 gen_highpart (SImode, operands[0])));
3259 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3266 (define_expand "movdf"
3267 [(set (match_operand:DF 0 "general_operand" "")
3268 (match_operand:DF 1 "general_operand" ""))]
3272 /* Force DFmode constants into memory. */
3273 if (GET_CODE (operands[0]) == REG
3274 && CONSTANT_P (operands[1]))
3276 if (TARGET_VIS && fp_zero_operand (operands[1], DFmode))
3279 /* emit_group_store will send such bogosity to us when it is
3280 not storing directly into memory. So fix this up to avoid
3281 crashes in output_constant_pool. */
3282 if (operands [1] == const0_rtx)
3283 operands[1] = CONST0_RTX (DFmode);
3284 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3288 /* Handle MEM cases first. */
3289 if (GET_CODE (operands[0]) == MEM)
3291 if (register_operand (operands[1], DFmode))
3294 if (! reload_in_progress)
3296 operands[0] = validize_mem (operands[0]);
3297 operands[1] = force_reg (DFmode, operands[1]);
3301 /* Fixup PIC cases. */
3304 if (CONSTANT_P (operands[1])
3305 && pic_address_needs_scratch (operands[1]))
3306 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3308 if (symbolic_operand (operands[1], DFmode))
3310 operands[1] = legitimize_pic_address (operands[1],
3312 (reload_in_progress ?
3322 ;; Be careful, fmovd does not exist when !v9.
3323 (define_insn "*movdf_insn_sp32"
3324 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,e,r,r,o,e,o")
3325 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3328 && (register_operand (operands[0], DFmode)
3329 || register_operand (operands[1], DFmode))"
3341 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3342 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3344 (define_insn "*movdf_no_e_insn_sp32"
3345 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,r,r,o")
3346 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3349 && (register_operand (operands[0], DFmode)
3350 || register_operand (operands[1], DFmode))"
3357 [(set_attr "type" "load,store,*,*,*")
3358 (set_attr "length" "1,1,2,2,2")])
3360 ;; We have available v9 double floats but not 64-bit
3361 ;; integer registers.
3362 (define_insn "*movdf_insn_v9only"
3363 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o")
3364 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3368 && (register_operand (operands[0], DFmode)
3369 || register_operand (operands[1], DFmode))"
3379 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3380 (set_attr "length" "1,1,1,1,1,2,2,2")])
3382 ;; We have available both v9 double floats and 64-bit
3383 ;; integer registers.
3384 (define_insn "*movdf_insn_sp64"
3385 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,r,r,m")
3386 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3390 && (register_operand (operands[0], DFmode)
3391 || register_operand (operands[1], DFmode))"
3399 [(set_attr "type" "fpmove,load,store,move,load,store")
3400 (set_attr "length" "1")])
3402 (define_insn "*movdf_no_e_insn_sp64"
3403 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3404 (match_operand:DF 1 "input_operand" "r,m,r"))]
3407 && (register_operand (operands[0], DFmode)
3408 || register_operand (operands[1], DFmode))"
3413 [(set_attr "type" "move,load,store")
3414 (set_attr "length" "1")])
3416 ;; Ok, now the splits to handle all the multi insn and
3417 ;; mis-aligned memory address cases.
3418 ;; In these splits please take note that we must be
3419 ;; careful when V9 but not ARCH64 because the integer
3420 ;; register DFmode cases must be handled.
3422 [(set (match_operand:DF 0 "register_operand" "")
3423 (match_operand:DF 1 "register_operand" ""))]
3426 && ((GET_CODE (operands[0]) == REG
3427 && REGNO (operands[0]) < 32)
3428 || (GET_CODE (operands[0]) == SUBREG
3429 && GET_CODE (SUBREG_REG (operands[0])) == REG
3430 && REGNO (SUBREG_REG (operands[0])) < 32))))
3431 && reload_completed"
3432 [(clobber (const_int 0))]
3435 rtx set_dest = operands[0];
3436 rtx set_src = operands[1];
3440 if (GET_CODE (set_dest) == SUBREG)
3441 set_dest = alter_subreg (set_dest);
3442 if (GET_CODE (set_src) == SUBREG)
3443 set_src = alter_subreg (set_src);
3445 dest1 = gen_highpart (SFmode, set_dest);
3446 dest2 = gen_lowpart (SFmode, set_dest);
3447 src1 = gen_highpart (SFmode, set_src);
3448 src2 = gen_lowpart (SFmode, set_src);
3450 /* Now emit using the real source and destination we found, swapping
3451 the order if we detect overlap. */
3452 if (reg_overlap_mentioned_p (dest1, src2))
3454 emit_insn (gen_movsf (dest2, src2));
3455 emit_insn (gen_movsf (dest1, src1));
3459 emit_insn (gen_movsf (dest1, src1));
3460 emit_insn (gen_movsf (dest2, src2));
3466 [(set (match_operand:DF 0 "register_operand" "")
3467 (match_operand:DF 1 "memory_operand" ""))]
3470 && ((GET_CODE (operands[0]) == REG
3471 && REGNO (operands[0]) < 32)
3472 || (GET_CODE (operands[0]) == SUBREG
3473 && GET_CODE (SUBREG_REG (operands[0])) == REG
3474 && REGNO (SUBREG_REG (operands[0])) < 32))))
3475 && (reload_completed
3476 && (((REGNO (operands[0])) % 2) != 0
3477 || ! mem_min_alignment (operands[1], 8))
3478 && offsettable_memref_p (operands[1])))"
3479 [(clobber (const_int 0))]
3482 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3483 rtx word1 = change_address (operands[1], SFmode,
3484 plus_constant_for_output (XEXP (word0, 0), 4));
3486 if (GET_CODE (operands[0]) == SUBREG)
3487 operands[0] = alter_subreg (operands[0]);
3489 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3491 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3493 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3498 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3500 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3507 [(set (match_operand:DF 0 "memory_operand" "")
3508 (match_operand:DF 1 "register_operand" ""))]
3511 && ((GET_CODE (operands[1]) == REG
3512 && REGNO (operands[1]) < 32)
3513 || (GET_CODE (operands[1]) == SUBREG
3514 && GET_CODE (SUBREG_REG (operands[1])) == REG
3515 && REGNO (SUBREG_REG (operands[1])) < 32))))
3516 && (reload_completed
3517 && (((REGNO (operands[1])) % 2) != 0
3518 || ! mem_min_alignment (operands[0], 8))
3519 && offsettable_memref_p (operands[0])))"
3520 [(clobber (const_int 0))]
3523 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3524 rtx word1 = change_address (operands[0], SFmode,
3525 plus_constant_for_output (XEXP (word0, 0), 4));
3527 if (GET_CODE (operands[1]) == SUBREG)
3528 operands[1] = alter_subreg (operands[1]);
3529 emit_insn (gen_movsf (word0,
3530 gen_highpart (SFmode, operands[1])));
3531 emit_insn (gen_movsf (word1,
3532 gen_lowpart (SFmode, operands[1])));
3536 (define_insn "*clear_tf"
3537 [(set (match_operand:TF 0 "register_operand" "=e")
3538 (match_operand:TF 1 "fp_zero_operand" ""))]
3541 [(set_attr "type" "fpmove")
3542 (set_attr "length" "2")])
3545 [(set (match_operand:TF 0 "register_operand" "")
3546 (match_operand:TF 1 "fp_zero_operand" ""))]
3547 "TARGET_VIS && reload_completed"
3548 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3549 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3552 operands[1] = CONST0_RTX (DFmode);
3556 (define_insn "*clear_tfp"
3557 [(set (match_operand:TF 0 "memory_operand" "=m")
3558 (match_operand:TF 1 "fp_zero_operand" ""))]
3561 [(set_attr "type" "fpmove")
3562 (set_attr "length" "2")])
3565 [(set (match_operand:TF 0 "memory_operand" "=m")
3566 (match_operand:TF 1 "fp_zero_operand" ""))]
3567 "TARGET_V9 && reload_completed"
3568 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3569 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3572 operands[1] = CONST0_RTX (DFmode);
3576 (define_expand "movtf"
3577 [(set (match_operand:TF 0 "general_operand" "")
3578 (match_operand:TF 1 "general_operand" ""))]
3582 /* Force TFmode constants into memory. */
3583 if (GET_CODE (operands[0]) == REG
3584 && CONSTANT_P (operands[1]))
3586 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3589 /* emit_group_store will send such bogosity to us when it is
3590 not storing directly into memory. So fix this up to avoid
3591 crashes in output_constant_pool. */
3592 if (operands [1] == const0_rtx)
3593 operands[1] = CONST0_RTX (TFmode);
3594 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3598 /* Handle MEM cases first, note that only v9 guarentees
3599 full 16-byte alignment for quads. */
3600 if (GET_CODE (operands[0]) == MEM)
3602 if (register_operand (operands[1], TFmode))
3605 if (! reload_in_progress)
3607 operands[0] = validize_mem (operands[0]);
3608 operands[1] = force_reg (TFmode, operands[1]);
3612 /* Fixup PIC cases. */
3615 if (CONSTANT_P (operands[1])
3616 && pic_address_needs_scratch (operands[1]))
3617 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3619 if (symbolic_operand (operands[1], TFmode))
3621 operands[1] = legitimize_pic_address (operands[1],
3623 (reload_in_progress ?
3633 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3634 ;; we must split them all. :-(
3635 (define_insn "*movtf_insn_sp32"
3636 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,e,r,r,o")
3637 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3640 && (register_operand (operands[0], TFmode)
3641 || register_operand (operands[1], TFmode))"
3643 [(set_attr "length" "4")])
3645 ;; Exactly the same as above, except that all `e' cases are deleted.
3646 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3649 (define_insn "*movtf_no_e_insn_sp32"
3650 [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o")
3651 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3654 && (register_operand (operands[0], TFmode)
3655 || register_operand (operands[1], TFmode))"
3657 [(set_attr "length" "4")])
3659 ;; Now handle the float reg cases directly when arch64,
3660 ;; hard_quad, and proper reg number alignment are all true.
3661 (define_insn "*movtf_insn_hq_sp64"
3662 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,r,r,o")
3663 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3668 && (register_operand (operands[0], TFmode)
3669 || register_operand (operands[1], TFmode))"
3677 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3678 (set_attr "length" "1,1,1,2,2,2")])
3680 ;; Now we allow the integer register cases even when
3681 ;; only arch64 is true.
3682 (define_insn "*movtf_insn_sp64"
3683 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r")
3684 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3687 && ! TARGET_HARD_QUAD
3688 && (register_operand (operands[0], TFmode)
3689 || register_operand (operands[1], TFmode))"
3691 [(set_attr "length" "2")])
3693 (define_insn "*movtf_no_e_insn_sp64"
3694 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r")
3695 (match_operand:TF 1 "input_operand" "o,r,r"))]
3698 && (register_operand (operands[0], TFmode)
3699 || register_operand (operands[1], TFmode))"
3701 [(set_attr "length" "2")])
3703 ;; Now all the splits to handle multi-insn TF mode moves.
3705 [(set (match_operand:TF 0 "register_operand" "")
3706 (match_operand:TF 1 "register_operand" ""))]
3710 && ! TARGET_HARD_QUAD))"
3711 [(clobber (const_int 0))]
3714 rtx set_dest = operands[0];
3715 rtx set_src = operands[1];
3719 if (GET_CODE (set_dest) == SUBREG)
3720 set_dest = alter_subreg (set_dest);
3721 if (GET_CODE (set_src) == SUBREG)
3722 set_src = alter_subreg (set_src);
3724 dest1 = gen_df_reg (set_dest, 0);
3725 dest2 = gen_df_reg (set_dest, 1);
3726 src1 = gen_df_reg (set_src, 0);
3727 src2 = gen_df_reg (set_src, 1);
3729 /* Now emit using the real source and destination we found, swapping
3730 the order if we detect overlap. */
3731 if (reg_overlap_mentioned_p (dest1, src2))
3733 emit_insn (gen_movdf (dest2, src2));
3734 emit_insn (gen_movdf (dest1, src1));
3738 emit_insn (gen_movdf (dest1, src1));
3739 emit_insn (gen_movdf (dest2, src2));
3745 [(set (match_operand:TF 0 "register_operand" "")
3746 (match_operand:TF 1 "memory_operand" ""))]
3748 && offsettable_memref_p (operands[1]))"
3749 [(clobber (const_int 0))]
3752 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3753 rtx word1 = change_address (operands[1], DFmode,
3754 plus_constant_for_output (XEXP (word0, 0), 8));
3755 rtx set_dest, dest1, dest2;
3757 set_dest = operands[0];
3758 if (GET_CODE (set_dest) == SUBREG)
3759 set_dest = alter_subreg (set_dest);
3761 dest1 = gen_df_reg (set_dest, 0);
3762 dest2 = gen_df_reg (set_dest, 1);
3764 /* Now output, ordering such that we don't clobber any registers
3765 mentioned in the address. */
3766 if (reg_overlap_mentioned_p (dest1, word1))
3769 emit_insn (gen_movdf (dest2, word1));
3770 emit_insn (gen_movdf (dest1, word0));
3774 emit_insn (gen_movdf (dest1, word0));
3775 emit_insn (gen_movdf (dest2, word1));
3781 [(set (match_operand:TF 0 "memory_operand" "")
3782 (match_operand:TF 1 "register_operand" ""))]
3784 && offsettable_memref_p (operands[0]))"
3785 [(clobber (const_int 0))]
3788 rtx word1 = change_address (operands[0], DFmode, NULL_RTX);
3789 rtx word2 = change_address (operands[0], DFmode,
3790 plus_constant_for_output (XEXP (word1, 0), 8));
3793 set_src = operands[1];
3794 if (GET_CODE (set_src) == SUBREG)
3795 set_src = alter_subreg (set_src);
3797 emit_insn (gen_movdf (word1, gen_df_reg (set_src, 0)));
3798 emit_insn (gen_movdf (word2, gen_df_reg (set_src, 1)));
3802 ;; Sparc V9 conditional move instructions.
3804 ;; We can handle larger constants here for some flavors, but for now we keep
3805 ;; it simple and only allow those constants supported by all flavours.
3806 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3807 ;; 3 contains the constant if one is present, but we handle either for
3808 ;; generality (sparc.c puts a constant in operand 2).
3810 (define_expand "movqicc"
3811 [(set (match_operand:QI 0 "register_operand" "")
3812 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3813 (match_operand:QI 2 "arith10_operand" "")
3814 (match_operand:QI 3 "arith10_operand" "")))]
3818 enum rtx_code code = GET_CODE (operands[1]);
3820 if (GET_MODE (sparc_compare_op0) == DImode
3824 if (sparc_compare_op1 == const0_rtx
3825 && GET_CODE (sparc_compare_op0) == REG
3826 && GET_MODE (sparc_compare_op0) == DImode
3827 && v9_regcmp_p (code))
3829 operands[1] = gen_rtx_fmt_ee (code, DImode,
3830 sparc_compare_op0, sparc_compare_op1);
3834 rtx cc_reg = gen_compare_reg (code,
3835 sparc_compare_op0, sparc_compare_op1);
3836 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3840 (define_expand "movhicc"
3841 [(set (match_operand:HI 0 "register_operand" "")
3842 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3843 (match_operand:HI 2 "arith10_operand" "")
3844 (match_operand:HI 3 "arith10_operand" "")))]
3848 enum rtx_code code = GET_CODE (operands[1]);
3850 if (GET_MODE (sparc_compare_op0) == DImode
3854 if (sparc_compare_op1 == const0_rtx
3855 && GET_CODE (sparc_compare_op0) == REG
3856 && GET_MODE (sparc_compare_op0) == DImode
3857 && v9_regcmp_p (code))
3859 operands[1] = gen_rtx_fmt_ee (code, DImode,
3860 sparc_compare_op0, sparc_compare_op1);
3864 rtx cc_reg = gen_compare_reg (code,
3865 sparc_compare_op0, sparc_compare_op1);
3866 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3870 (define_expand "movsicc"
3871 [(set (match_operand:SI 0 "register_operand" "")
3872 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3873 (match_operand:SI 2 "arith10_operand" "")
3874 (match_operand:SI 3 "arith10_operand" "")))]
3878 enum rtx_code code = GET_CODE (operands[1]);
3879 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3881 if (sparc_compare_op1 == const0_rtx
3882 && GET_CODE (sparc_compare_op0) == REG
3883 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3885 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3886 sparc_compare_op0, sparc_compare_op1);
3890 rtx cc_reg = gen_compare_reg (code,
3891 sparc_compare_op0, sparc_compare_op1);
3892 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3893 cc_reg, const0_rtx);
3897 (define_expand "movdicc"
3898 [(set (match_operand:DI 0 "register_operand" "")
3899 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3900 (match_operand:DI 2 "arith10_double_operand" "")
3901 (match_operand:DI 3 "arith10_double_operand" "")))]
3905 enum rtx_code code = GET_CODE (operands[1]);
3907 if (sparc_compare_op1 == const0_rtx
3908 && GET_CODE (sparc_compare_op0) == REG
3909 && GET_MODE (sparc_compare_op0) == DImode
3910 && v9_regcmp_p (code))
3912 operands[1] = gen_rtx_fmt_ee (code, DImode,
3913 sparc_compare_op0, sparc_compare_op1);
3917 rtx cc_reg = gen_compare_reg (code,
3918 sparc_compare_op0, sparc_compare_op1);
3919 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3920 cc_reg, const0_rtx);
3924 (define_expand "movsfcc"
3925 [(set (match_operand:SF 0 "register_operand" "")
3926 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3927 (match_operand:SF 2 "register_operand" "")
3928 (match_operand:SF 3 "register_operand" "")))]
3929 "TARGET_V9 && TARGET_FPU"
3932 enum rtx_code code = GET_CODE (operands[1]);
3934 if (GET_MODE (sparc_compare_op0) == DImode
3938 if (sparc_compare_op1 == const0_rtx
3939 && GET_CODE (sparc_compare_op0) == REG
3940 && GET_MODE (sparc_compare_op0) == DImode
3941 && v9_regcmp_p (code))
3943 operands[1] = gen_rtx_fmt_ee (code, DImode,
3944 sparc_compare_op0, sparc_compare_op1);
3948 rtx cc_reg = gen_compare_reg (code,
3949 sparc_compare_op0, sparc_compare_op1);
3950 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3954 (define_expand "movdfcc"
3955 [(set (match_operand:DF 0 "register_operand" "")
3956 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3957 (match_operand:DF 2 "register_operand" "")
3958 (match_operand:DF 3 "register_operand" "")))]
3959 "TARGET_V9 && TARGET_FPU"
3962 enum rtx_code code = GET_CODE (operands[1]);
3964 if (GET_MODE (sparc_compare_op0) == DImode
3968 if (sparc_compare_op1 == const0_rtx
3969 && GET_CODE (sparc_compare_op0) == REG
3970 && GET_MODE (sparc_compare_op0) == DImode
3971 && v9_regcmp_p (code))
3973 operands[1] = gen_rtx_fmt_ee (code, DImode,
3974 sparc_compare_op0, sparc_compare_op1);
3978 rtx cc_reg = gen_compare_reg (code,
3979 sparc_compare_op0, sparc_compare_op1);
3980 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3984 (define_expand "movtfcc"
3985 [(set (match_operand:TF 0 "register_operand" "")
3986 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3987 (match_operand:TF 2 "register_operand" "")
3988 (match_operand:TF 3 "register_operand" "")))]
3989 "TARGET_V9 && TARGET_FPU"
3992 enum rtx_code code = GET_CODE (operands[1]);
3994 if (GET_MODE (sparc_compare_op0) == DImode
3998 if (sparc_compare_op1 == const0_rtx
3999 && GET_CODE (sparc_compare_op0) == REG
4000 && GET_MODE (sparc_compare_op0) == DImode
4001 && v9_regcmp_p (code))
4003 operands[1] = gen_rtx_fmt_ee (code, DImode,
4004 sparc_compare_op0, sparc_compare_op1);
4008 rtx cc_reg = gen_compare_reg (code,
4009 sparc_compare_op0, sparc_compare_op1);
4010 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4014 ;; Conditional move define_insns.
4016 (define_insn "*movqi_cc_sp64"
4017 [(set (match_operand:QI 0 "register_operand" "=r,r")
4018 (if_then_else:QI (match_operator 1 "comparison_operator"
4019 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4021 (match_operand:QI 3 "arith11_operand" "rL,0")
4022 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4025 mov%C1\\t%x2, %3, %0
4026 mov%c1\\t%x2, %4, %0"
4027 [(set_attr "type" "cmove")
4028 (set_attr "length" "1")])
4030 (define_insn "*movhi_cc_sp64"
4031 [(set (match_operand:HI 0 "register_operand" "=r,r")
4032 (if_then_else:HI (match_operator 1 "comparison_operator"
4033 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4035 (match_operand:HI 3 "arith11_operand" "rL,0")
4036 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4039 mov%C1\\t%x2, %3, %0
4040 mov%c1\\t%x2, %4, %0"
4041 [(set_attr "type" "cmove")
4042 (set_attr "length" "1")])
4044 (define_insn "*movsi_cc_sp64"
4045 [(set (match_operand:SI 0 "register_operand" "=r,r")
4046 (if_then_else:SI (match_operator 1 "comparison_operator"
4047 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4049 (match_operand:SI 3 "arith11_operand" "rL,0")
4050 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4053 mov%C1\\t%x2, %3, %0
4054 mov%c1\\t%x2, %4, %0"
4055 [(set_attr "type" "cmove")
4056 (set_attr "length" "1")])
4058 ;; ??? The constraints of operands 3,4 need work.
4059 (define_insn "*movdi_cc_sp64"
4060 [(set (match_operand:DI 0 "register_operand" "=r,r")
4061 (if_then_else:DI (match_operator 1 "comparison_operator"
4062 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4064 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4065 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4068 mov%C1\\t%x2, %3, %0
4069 mov%c1\\t%x2, %4, %0"
4070 [(set_attr "type" "cmove")
4071 (set_attr "length" "1")])
4073 (define_insn "*movdi_cc_sp64_trunc"
4074 [(set (match_operand:SI 0 "register_operand" "=r,r")
4075 (if_then_else:SI (match_operator 1 "comparison_operator"
4076 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4078 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4079 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4082 mov%C1\\t%x2, %3, %0
4083 mov%c1\\t%x2, %4, %0"
4084 [(set_attr "type" "cmove")
4085 (set_attr "length" "1")])
4087 (define_insn "*movsf_cc_sp64"
4088 [(set (match_operand:SF 0 "register_operand" "=f,f")
4089 (if_then_else:SF (match_operator 1 "comparison_operator"
4090 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4092 (match_operand:SF 3 "register_operand" "f,0")
4093 (match_operand:SF 4 "register_operand" "0,f")))]
4094 "TARGET_V9 && TARGET_FPU"
4096 fmovs%C1\\t%x2, %3, %0
4097 fmovs%c1\\t%x2, %4, %0"
4098 [(set_attr "type" "fpcmove")
4099 (set_attr "length" "1")])
4101 (define_insn "movdf_cc_sp64"
4102 [(set (match_operand:DF 0 "register_operand" "=e,e")
4103 (if_then_else:DF (match_operator 1 "comparison_operator"
4104 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4106 (match_operand:DF 3 "register_operand" "e,0")
4107 (match_operand:DF 4 "register_operand" "0,e")))]
4108 "TARGET_V9 && TARGET_FPU"
4110 fmovd%C1\\t%x2, %3, %0
4111 fmovd%c1\\t%x2, %4, %0"
4112 [(set_attr "type" "fpcmove")
4113 (set_attr "length" "1")])
4115 (define_insn "*movtf_cc_hq_sp64"
4116 [(set (match_operand:TF 0 "register_operand" "=e,e")
4117 (if_then_else:TF (match_operator 1 "comparison_operator"
4118 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4120 (match_operand:TF 3 "register_operand" "e,0")
4121 (match_operand:TF 4 "register_operand" "0,e")))]
4122 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4124 fmovq%C1\\t%x2, %3, %0
4125 fmovq%c1\\t%x2, %4, %0"
4126 [(set_attr "type" "fpcmove")
4127 (set_attr "length" "1")])
4129 (define_insn "*movtf_cc_sp64"
4130 [(set (match_operand:TF 0 "register_operand" "=e,e")
4131 (if_then_else:TF (match_operator 1 "comparison_operator"
4132 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4134 (match_operand:TF 3 "register_operand" "e,0")
4135 (match_operand:TF 4 "register_operand" "0,e")))]
4136 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4138 [(set_attr "type" "fpcmove")
4139 (set_attr "length" "2")])
4142 [(set (match_operand:TF 0 "register_operand" "=e,e")
4143 (if_then_else:TF (match_operator 1 "comparison_operator"
4144 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4146 (match_operand:TF 3 "register_operand" "e,0")
4147 (match_operand:TF 4 "register_operand" "0,e")))]
4148 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4149 [(clobber (const_int 0))]
4152 rtx set_dest = operands[0];
4153 rtx set_srca = operands[3];
4154 rtx set_srcb = operands[4];
4155 int third = rtx_equal_p (set_dest, set_srca);
4157 rtx srca1, srca2, srcb1, srcb2;
4159 if (GET_CODE (set_dest) == SUBREG)
4160 set_dest = alter_subreg (set_dest);
4161 if (GET_CODE (set_srca) == SUBREG)
4162 set_srca = alter_subreg (set_srca);
4163 if (GET_CODE (set_srcb) == SUBREG)
4164 set_srcb = alter_subreg (set_srcb);
4166 dest1 = gen_df_reg (set_dest, 0);
4167 dest2 = gen_df_reg (set_dest, 1);
4168 srca1 = gen_df_reg (set_srca, 0);
4169 srca2 = gen_df_reg (set_srca, 1);
4170 srcb1 = gen_df_reg (set_srcb, 0);
4171 srcb2 = gen_df_reg (set_srcb, 1);
4173 /* Now emit using the real source and destination we found, swapping
4174 the order if we detect overlap. */
4175 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4176 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4178 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4179 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4183 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4184 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4189 (define_insn "*movqi_cc_reg_sp64"
4190 [(set (match_operand:QI 0 "register_operand" "=r,r")
4191 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4192 [(match_operand:DI 2 "register_operand" "r,r")
4194 (match_operand:QI 3 "arith10_operand" "rM,0")
4195 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4198 movr%D1\\t%2, %r3, %0
4199 movr%d1\\t%2, %r4, %0"
4200 [(set_attr "type" "cmove")
4201 (set_attr "length" "1")])
4203 (define_insn "*movhi_cc_reg_sp64"
4204 [(set (match_operand:HI 0 "register_operand" "=r,r")
4205 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4206 [(match_operand:DI 2 "register_operand" "r,r")
4208 (match_operand:HI 3 "arith10_operand" "rM,0")
4209 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4212 movr%D1\\t%2, %r3, %0
4213 movr%d1\\t%2, %r4, %0"
4214 [(set_attr "type" "cmove")
4215 (set_attr "length" "1")])
4217 (define_insn "*movsi_cc_reg_sp64"
4218 [(set (match_operand:SI 0 "register_operand" "=r,r")
4219 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4220 [(match_operand:DI 2 "register_operand" "r,r")
4222 (match_operand:SI 3 "arith10_operand" "rM,0")
4223 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4226 movr%D1\\t%2, %r3, %0
4227 movr%d1\\t%2, %r4, %0"
4228 [(set_attr "type" "cmove")
4229 (set_attr "length" "1")])
4231 ;; ??? The constraints of operands 3,4 need work.
4232 (define_insn "*movdi_cc_reg_sp64"
4233 [(set (match_operand:DI 0 "register_operand" "=r,r")
4234 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4235 [(match_operand:DI 2 "register_operand" "r,r")
4237 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4238 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4241 movr%D1\\t%2, %r3, %0
4242 movr%d1\\t%2, %r4, %0"
4243 [(set_attr "type" "cmove")
4244 (set_attr "length" "1")])
4246 (define_insn "*movdi_cc_reg_sp64_trunc"
4247 [(set (match_operand:SI 0 "register_operand" "=r,r")
4248 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4249 [(match_operand:DI 2 "register_operand" "r,r")
4251 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4252 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4255 movr%D1\\t%2, %r3, %0
4256 movr%d1\\t%2, %r4, %0"
4257 [(set_attr "type" "cmove")
4258 (set_attr "length" "1")])
4260 (define_insn "*movsf_cc_reg_sp64"
4261 [(set (match_operand:SF 0 "register_operand" "=f,f")
4262 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4263 [(match_operand:DI 2 "register_operand" "r,r")
4265 (match_operand:SF 3 "register_operand" "f,0")
4266 (match_operand:SF 4 "register_operand" "0,f")))]
4267 "TARGET_ARCH64 && TARGET_FPU"
4269 fmovrs%D1\\t%2, %3, %0
4270 fmovrs%d1\\t%2, %4, %0"
4271 [(set_attr "type" "fpcmove")
4272 (set_attr "length" "1")])
4274 (define_insn "movdf_cc_reg_sp64"
4275 [(set (match_operand:DF 0 "register_operand" "=e,e")
4276 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4277 [(match_operand:DI 2 "register_operand" "r,r")
4279 (match_operand:DF 3 "register_operand" "e,0")
4280 (match_operand:DF 4 "register_operand" "0,e")))]
4281 "TARGET_ARCH64 && TARGET_FPU"
4283 fmovrd%D1\\t%2, %3, %0
4284 fmovrd%d1\\t%2, %4, %0"
4285 [(set_attr "type" "fpcmove")
4286 (set_attr "length" "1")])
4288 (define_insn "*movtf_cc_reg_hq_sp64"
4289 [(set (match_operand:TF 0 "register_operand" "=e,e")
4290 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4291 [(match_operand:DI 2 "register_operand" "r,r")
4293 (match_operand:TF 3 "register_operand" "e,0")
4294 (match_operand:TF 4 "register_operand" "0,e")))]
4295 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4297 fmovrq%D1\\t%2, %3, %0
4298 fmovrq%d1\\t%2, %4, %0"
4299 [(set_attr "type" "fpcmove")
4300 (set_attr "length" "1")])
4302 (define_insn "*movtf_cc_reg_sp64"
4303 [(set (match_operand:TF 0 "register_operand" "=e,e")
4304 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4305 [(match_operand:DI 2 "register_operand" "r,r")
4307 (match_operand:TF 3 "register_operand" "e,0")
4308 (match_operand:TF 4 "register_operand" "0,e")))]
4309 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4311 [(set_attr "type" "fpcmove")
4312 (set_attr "length" "2")])
4315 [(set (match_operand:TF 0 "register_operand" "=e,e")
4316 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4317 [(match_operand:DI 2 "register_operand" "r,r")
4319 (match_operand:TF 3 "register_operand" "e,0")
4320 (match_operand:TF 4 "register_operand" "0,e")))]
4321 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4322 [(clobber (const_int 0))]
4325 rtx set_dest = operands[0];
4326 rtx set_srca = operands[3];
4327 rtx set_srcb = operands[4];
4328 int third = rtx_equal_p (set_dest, set_srca);
4330 rtx srca1, srca2, srcb1, srcb2;
4332 if (GET_CODE (set_dest) == SUBREG)
4333 set_dest = alter_subreg (set_dest);
4334 if (GET_CODE (set_srca) == SUBREG)
4335 set_srca = alter_subreg (set_srca);
4336 if (GET_CODE (set_srcb) == SUBREG)
4337 set_srcb = alter_subreg (set_srcb);
4339 dest1 = gen_df_reg (set_dest, 0);
4340 dest2 = gen_df_reg (set_dest, 1);
4341 srca1 = gen_df_reg (set_srca, 0);
4342 srca2 = gen_df_reg (set_srca, 1);
4343 srcb1 = gen_df_reg (set_srcb, 0);
4344 srcb2 = gen_df_reg (set_srcb, 1);
4346 /* Now emit using the real source and destination we found, swapping
4347 the order if we detect overlap. */
4348 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4349 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4351 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4352 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4356 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4357 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4363 ;;- zero extension instructions
4365 ;; These patterns originally accepted general_operands, however, slightly
4366 ;; better code is generated by only accepting register_operands, and then
4367 ;; letting combine generate the ldu[hb] insns.
4369 (define_expand "zero_extendhisi2"
4370 [(set (match_operand:SI 0 "register_operand" "")
4371 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4375 rtx temp = gen_reg_rtx (SImode);
4376 rtx shift_16 = GEN_INT (16);
4377 int op1_subword = 0;
4379 if (GET_CODE (operand1) == SUBREG)
4381 op1_subword = SUBREG_WORD (operand1);
4382 operand1 = XEXP (operand1, 0);
4385 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4387 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4391 (define_insn "*zero_extendhisi2_insn"
4392 [(set (match_operand:SI 0 "register_operand" "=r")
4393 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4396 [(set_attr "type" "load")
4397 (set_attr "length" "1")])
4399 (define_expand "zero_extendqihi2"
4400 [(set (match_operand:HI 0 "register_operand" "")
4401 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4405 (define_insn "*zero_extendqihi2_insn"
4406 [(set (match_operand:HI 0 "register_operand" "=r,r")
4407 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4408 "GET_CODE (operands[1]) != CONST_INT"
4412 [(set_attr "type" "unary,load")
4413 (set_attr "length" "1")])
4415 (define_expand "zero_extendqisi2"
4416 [(set (match_operand:SI 0 "register_operand" "")
4417 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4421 (define_insn "*zero_extendqisi2_insn"
4422 [(set (match_operand:SI 0 "register_operand" "=r,r")
4423 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4424 "GET_CODE (operands[1]) != CONST_INT"
4428 [(set_attr "type" "unary,load")
4429 (set_attr "length" "1")])
4431 (define_expand "zero_extendqidi2"
4432 [(set (match_operand:DI 0 "register_operand" "")
4433 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4437 (define_insn "*zero_extendqidi2_insn"
4438 [(set (match_operand:DI 0 "register_operand" "=r,r")
4439 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4440 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4444 [(set_attr "type" "unary,load")
4445 (set_attr "length" "1")])
4447 (define_expand "zero_extendhidi2"
4448 [(set (match_operand:DI 0 "register_operand" "")
4449 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4453 rtx temp = gen_reg_rtx (DImode);
4454 rtx shift_48 = GEN_INT (48);
4455 int op1_subword = 0;
4457 if (GET_CODE (operand1) == SUBREG)
4459 op1_subword = SUBREG_WORD (operand1);
4460 operand1 = XEXP (operand1, 0);
4463 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4465 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4469 (define_insn "*zero_extendhidi2_insn"
4470 [(set (match_operand:DI 0 "register_operand" "=r")
4471 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4474 [(set_attr "type" "load")
4475 (set_attr "length" "1")])
4478 ;; ??? Write truncdisi pattern using sra?
4480 (define_expand "zero_extendsidi2"
4481 [(set (match_operand:DI 0 "register_operand" "")
4482 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4486 (define_insn "*zero_extendsidi2_insn_sp64"
4487 [(set (match_operand:DI 0 "register_operand" "=r,r")
4488 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4489 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4493 [(set_attr "type" "shift,load")
4494 (set_attr "length" "1")])
4496 (define_insn "*zero_extendsidi2_insn_sp32"
4497 [(set (match_operand:DI 0 "register_operand" "=r")
4498 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4501 [(set_attr "type" "unary")
4502 (set_attr "length" "2")])
4505 [(set (match_operand:DI 0 "register_operand" "")
4506 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4507 "! TARGET_ARCH64 && reload_completed"
4508 [(set (match_dup 2) (match_dup 3))
4509 (set (match_dup 4) (match_dup 5))]
4514 if (GET_CODE (operands[0]) == SUBREG)
4515 operands[0] = alter_subreg (operands[0]);
4517 dest1 = gen_highpart (SImode, operands[0]);
4518 dest2 = gen_lowpart (SImode, operands[0]);
4520 /* Swap the order in case of overlap. */
4521 if (REGNO (dest1) == REGNO (operands[1]))
4523 operands[2] = dest2;
4524 operands[3] = operands[1];
4525 operands[4] = dest1;
4526 operands[5] = const0_rtx;
4530 operands[2] = dest1;
4531 operands[3] = const0_rtx;
4532 operands[4] = dest2;
4533 operands[5] = operands[1];
4537 ;; Simplify comparisons of extended values.
4539 (define_insn "*cmp_zero_extendqisi2"
4541 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4544 "andcc\\t%0, 0xff, %%g0"
4545 [(set_attr "type" "compare")
4546 (set_attr "length" "1")])
4548 (define_insn "*cmp_zero_qi"
4550 (compare:CC (match_operand:QI 0 "register_operand" "r")
4553 "andcc\\t%0, 0xff, %%g0"
4554 [(set_attr "type" "compare")
4555 (set_attr "length" "1")])
4557 (define_insn "*cmp_zero_extendqisi2_set"
4559 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4561 (set (match_operand:SI 0 "register_operand" "=r")
4562 (zero_extend:SI (match_dup 1)))]
4564 "andcc\\t%1, 0xff, %0"
4565 [(set_attr "type" "compare")
4566 (set_attr "length" "1")])
4568 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4570 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4573 (set (match_operand:SI 0 "register_operand" "=r")
4574 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4576 "andcc\\t%1, 0xff, %0"
4577 [(set_attr "type" "compare")
4578 (set_attr "length" "1")])
4580 (define_insn "*cmp_zero_extendqidi2"
4582 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4585 "andcc\\t%0, 0xff, %%g0"
4586 [(set_attr "type" "compare")
4587 (set_attr "length" "1")])
4589 (define_insn "*cmp_zero_qi_sp64"
4591 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4594 "andcc\\t%0, 0xff, %%g0"
4595 [(set_attr "type" "compare")
4596 (set_attr "length" "1")])
4598 (define_insn "*cmp_zero_extendqidi2_set"
4600 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4602 (set (match_operand:DI 0 "register_operand" "=r")
4603 (zero_extend:DI (match_dup 1)))]
4605 "andcc\\t%1, 0xff, %0"
4606 [(set_attr "type" "compare")
4607 (set_attr "length" "1")])
4609 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4611 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4614 (set (match_operand:DI 0 "register_operand" "=r")
4615 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4617 "andcc\\t%1, 0xff, %0"
4618 [(set_attr "type" "compare")
4619 (set_attr "length" "1")])
4621 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4623 (define_insn "*cmp_siqi_trunc"
4625 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4628 "andcc\\t%0, 0xff, %%g0"
4629 [(set_attr "type" "compare")
4630 (set_attr "length" "1")])
4632 (define_insn "*cmp_siqi_trunc_set"
4634 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4636 (set (match_operand:QI 0 "register_operand" "=r")
4637 (subreg:QI (match_dup 1) 0))]
4639 "andcc\\t%1, 0xff, %0"
4640 [(set_attr "type" "compare")
4641 (set_attr "length" "1")])
4643 (define_insn "*cmp_diqi_trunc"
4645 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4648 "andcc\\t%0, 0xff, %%g0"
4649 [(set_attr "type" "compare")
4650 (set_attr "length" "1")])
4652 (define_insn "*cmp_diqi_trunc_set"
4654 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4656 (set (match_operand:QI 0 "register_operand" "=r")
4657 (subreg:QI (match_dup 1) 0))]
4659 "andcc\\t%1, 0xff, %0"
4660 [(set_attr "type" "compare")
4661 (set_attr "length" "1")])
4663 ;;- sign extension instructions
4665 ;; These patterns originally accepted general_operands, however, slightly
4666 ;; better code is generated by only accepting register_operands, and then
4667 ;; letting combine generate the lds[hb] insns.
4669 (define_expand "extendhisi2"
4670 [(set (match_operand:SI 0 "register_operand" "")
4671 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4675 rtx temp = gen_reg_rtx (SImode);
4676 rtx shift_16 = GEN_INT (16);
4677 int op1_subword = 0;
4679 if (GET_CODE (operand1) == SUBREG)
4681 op1_subword = SUBREG_WORD (operand1);
4682 operand1 = XEXP (operand1, 0);
4685 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4687 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4691 (define_insn "*sign_extendhisi2_insn"
4692 [(set (match_operand:SI 0 "register_operand" "=r")
4693 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4696 [(set_attr "type" "sload")
4697 (set_attr "length" "1")])
4699 (define_expand "extendqihi2"
4700 [(set (match_operand:HI 0 "register_operand" "")
4701 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4705 rtx temp = gen_reg_rtx (SImode);
4706 rtx shift_24 = GEN_INT (24);
4707 int op1_subword = 0;
4708 int op0_subword = 0;
4710 if (GET_CODE (operand1) == SUBREG)
4712 op1_subword = SUBREG_WORD (operand1);
4713 operand1 = XEXP (operand1, 0);
4715 if (GET_CODE (operand0) == SUBREG)
4717 op0_subword = SUBREG_WORD (operand0);
4718 operand0 = XEXP (operand0, 0);
4720 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4722 if (GET_MODE (operand0) != SImode)
4723 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4724 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4728 (define_insn "*sign_extendqihi2_insn"
4729 [(set (match_operand:HI 0 "register_operand" "=r")
4730 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4733 [(set_attr "type" "sload")
4734 (set_attr "length" "1")])
4736 (define_expand "extendqisi2"
4737 [(set (match_operand:SI 0 "register_operand" "")
4738 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4742 rtx temp = gen_reg_rtx (SImode);
4743 rtx shift_24 = GEN_INT (24);
4744 int op1_subword = 0;
4746 if (GET_CODE (operand1) == SUBREG)
4748 op1_subword = SUBREG_WORD (operand1);
4749 operand1 = XEXP (operand1, 0);
4752 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4754 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4758 (define_insn "*sign_extendqisi2_insn"
4759 [(set (match_operand:SI 0 "register_operand" "=r")
4760 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4763 [(set_attr "type" "sload")
4764 (set_attr "length" "1")])
4766 (define_expand "extendqidi2"
4767 [(set (match_operand:DI 0 "register_operand" "")
4768 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4772 rtx temp = gen_reg_rtx (DImode);
4773 rtx shift_56 = GEN_INT (56);
4774 int op1_subword = 0;
4776 if (GET_CODE (operand1) == SUBREG)
4778 op1_subword = SUBREG_WORD (operand1);
4779 operand1 = XEXP (operand1, 0);
4782 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4784 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4788 (define_insn "*sign_extendqidi2_insn"
4789 [(set (match_operand:DI 0 "register_operand" "=r")
4790 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4793 [(set_attr "type" "sload")
4794 (set_attr "length" "1")])
4796 (define_expand "extendhidi2"
4797 [(set (match_operand:DI 0 "register_operand" "")
4798 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4802 rtx temp = gen_reg_rtx (DImode);
4803 rtx shift_48 = GEN_INT (48);
4804 int op1_subword = 0;
4806 if (GET_CODE (operand1) == SUBREG)
4808 op1_subword = SUBREG_WORD (operand1);
4809 operand1 = XEXP (operand1, 0);
4812 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4814 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4818 (define_insn "*sign_extendhidi2_insn"
4819 [(set (match_operand:DI 0 "register_operand" "=r")
4820 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4823 [(set_attr "type" "sload")
4824 (set_attr "length" "1")])
4826 (define_expand "extendsidi2"
4827 [(set (match_operand:DI 0 "register_operand" "")
4828 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4832 (define_insn "*sign_extendsidi2_insn"
4833 [(set (match_operand:DI 0 "register_operand" "=r,r")
4834 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4839 [(set_attr "type" "shift,sload")
4840 (set_attr "length" "1")])
4842 ;; Special pattern for optimizing bit-field compares. This is needed
4843 ;; because combine uses this as a canonical form.
4845 (define_insn "*cmp_zero_extract"
4848 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4849 (match_operand:SI 1 "small_int_or_double" "n")
4850 (match_operand:SI 2 "small_int_or_double" "n"))
4852 "(GET_CODE (operands[2]) == CONST_INT
4853 && INTVAL (operands[2]) > 19)
4854 || (GET_CODE (operands[2]) == CONST_DOUBLE
4855 && CONST_DOUBLE_LOW (operands[2]) > 19)"
4858 int len = (GET_CODE (operands[1]) == CONST_INT
4859 ? INTVAL (operands[1])
4860 : CONST_DOUBLE_LOW (operands[1]));
4862 (GET_CODE (operands[2]) == CONST_INT
4863 ? INTVAL (operands[2])
4864 : CONST_DOUBLE_LOW (operands[2])) - len;
4865 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4867 operands[1] = GEN_INT (mask);
4868 return \"andcc\\t%0, %1, %%g0\";
4870 [(set_attr "type" "compare")
4871 (set_attr "length" "1")])
4873 (define_insn "*cmp_zero_extract_sp64"
4876 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4877 (match_operand:SI 1 "small_int_or_double" "n")
4878 (match_operand:SI 2 "small_int_or_double" "n"))
4881 && ((GET_CODE (operands[2]) == CONST_INT
4882 && INTVAL (operands[2]) > 51)
4883 || (GET_CODE (operands[2]) == CONST_DOUBLE
4884 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4887 int len = (GET_CODE (operands[1]) == CONST_INT
4888 ? INTVAL (operands[1])
4889 : CONST_DOUBLE_LOW (operands[1]));
4891 (GET_CODE (operands[2]) == CONST_INT
4892 ? INTVAL (operands[2])
4893 : CONST_DOUBLE_LOW (operands[2])) - len;
4894 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4896 operands[1] = GEN_INT (mask);
4897 return \"andcc\\t%0, %1, %%g0\";
4899 [(set_attr "type" "compare")
4900 (set_attr "length" "1")])
4902 ;; Conversions between float, double and long double.
4904 (define_insn "extendsfdf2"
4905 [(set (match_operand:DF 0 "register_operand" "=e")
4907 (match_operand:SF 1 "register_operand" "f")))]
4910 [(set_attr "type" "fp")
4911 (set_attr "length" "1")])
4913 (define_expand "extendsftf2"
4914 [(set (match_operand:TF 0 "register_operand" "=e")
4916 (match_operand:SF 1 "register_operand" "f")))]
4917 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4920 if (! TARGET_HARD_QUAD)
4924 if (GET_CODE (operands[0]) != MEM)
4925 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4927 slot0 = operands[0];
4929 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4931 XEXP (slot0, 0), Pmode,
4932 operands[1], SFmode);
4934 if (GET_CODE (operands[0]) != MEM)
4935 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4940 (define_insn "*extendsftf2_hq"
4941 [(set (match_operand:TF 0 "register_operand" "=e")
4943 (match_operand:SF 1 "register_operand" "f")))]
4944 "TARGET_FPU && TARGET_HARD_QUAD"
4946 [(set_attr "type" "fp")
4947 (set_attr "length" "1")])
4949 (define_expand "extenddftf2"
4950 [(set (match_operand:TF 0 "register_operand" "=e")
4952 (match_operand:DF 1 "register_operand" "e")))]
4953 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4956 if (! TARGET_HARD_QUAD)
4960 if (GET_CODE (operands[0]) != MEM)
4961 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4963 slot0 = operands[0];
4965 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
4967 XEXP (slot0, 0), Pmode,
4968 operands[1], DFmode);
4970 if (GET_CODE (operands[0]) != MEM)
4971 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
4976 (define_insn "*extenddftf2_hq"
4977 [(set (match_operand:TF 0 "register_operand" "=e")
4979 (match_operand:DF 1 "register_operand" "e")))]
4980 "TARGET_FPU && TARGET_HARD_QUAD"
4982 [(set_attr "type" "fp")
4983 (set_attr "length" "1")])
4985 (define_insn "truncdfsf2"
4986 [(set (match_operand:SF 0 "register_operand" "=f")
4988 (match_operand:DF 1 "register_operand" "e")))]
4991 [(set_attr "type" "fp")
4992 (set_attr "length" "1")])
4994 (define_expand "trunctfsf2"
4995 [(set (match_operand:SF 0 "register_operand" "=f")
4997 (match_operand:TF 1 "register_operand" "e")))]
4998 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5001 if (! TARGET_HARD_QUAD)
5005 if (GET_CODE (operands[1]) != MEM)
5007 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5008 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5011 slot0 = operands[1];
5013 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5014 operands[0], 0, SFmode, 1,
5015 XEXP (slot0, 0), Pmode);
5020 (define_insn "*trunctfsf2_hq"
5021 [(set (match_operand:SF 0 "register_operand" "=f")
5023 (match_operand:TF 1 "register_operand" "e")))]
5024 "TARGET_FPU && TARGET_HARD_QUAD"
5026 [(set_attr "type" "fp")
5027 (set_attr "length" "1")])
5029 (define_expand "trunctfdf2"
5030 [(set (match_operand:DF 0 "register_operand" "=f")
5032 (match_operand:TF 1 "register_operand" "e")))]
5033 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5036 if (! TARGET_HARD_QUAD)
5040 if (GET_CODE (operands[1]) != MEM)
5042 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5043 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5046 slot0 = operands[1];
5048 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5049 operands[0], 0, DFmode, 1,
5050 XEXP (slot0, 0), Pmode);
5055 (define_insn "*trunctfdf2_hq"
5056 [(set (match_operand:DF 0 "register_operand" "=e")
5058 (match_operand:TF 1 "register_operand" "e")))]
5059 "TARGET_FPU && TARGET_HARD_QUAD"
5061 [(set_attr "type" "fp")
5062 (set_attr "length" "1")])
5064 ;; Conversion between fixed point and floating point.
5066 (define_insn "floatsisf2"
5067 [(set (match_operand:SF 0 "register_operand" "=f")
5068 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5071 [(set_attr "type" "fp")
5072 (set_attr "length" "1")])
5074 (define_insn "floatsidf2"
5075 [(set (match_operand:DF 0 "register_operand" "=e")
5076 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5079 [(set_attr "type" "fp")
5080 (set_attr "length" "1")])
5082 (define_expand "floatsitf2"
5083 [(set (match_operand:TF 0 "register_operand" "=e")
5084 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5085 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5088 if (! TARGET_HARD_QUAD)
5092 if (GET_CODE (operands[1]) != MEM)
5093 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5095 slot0 = operands[1];
5097 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5099 XEXP (slot0, 0), Pmode,
5100 operands[1], SImode);
5102 if (GET_CODE (operands[0]) != MEM)
5103 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5108 (define_insn "*floatsitf2_hq"
5109 [(set (match_operand:TF 0 "register_operand" "=e")
5110 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5111 "TARGET_FPU && TARGET_HARD_QUAD"
5113 [(set_attr "type" "fp")
5114 (set_attr "length" "1")])
5116 (define_expand "floatunssitf2"
5117 [(set (match_operand:TF 0 "register_operand" "=e")
5118 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5119 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5124 if (GET_CODE (operands[1]) != MEM)
5125 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5127 slot0 = operands[1];
5129 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5131 XEXP (slot0, 0), Pmode,
5132 operands[1], SImode);
5134 if (GET_CODE (operands[0]) != MEM)
5135 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5139 ;; Now the same for 64 bit sources.
5141 (define_insn "floatdisf2"
5142 [(set (match_operand:SF 0 "register_operand" "=f")
5143 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5144 "TARGET_V9 && TARGET_FPU"
5146 [(set_attr "type" "fp")
5147 (set_attr "length" "1")])
5149 (define_insn "floatdidf2"
5150 [(set (match_operand:DF 0 "register_operand" "=e")
5151 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5152 "TARGET_V9 && TARGET_FPU"
5154 [(set_attr "type" "fp")
5155 (set_attr "length" "1")])
5157 (define_expand "floatditf2"
5158 [(set (match_operand:TF 0 "register_operand" "=e")
5159 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5160 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5163 if (! TARGET_HARD_QUAD)
5167 if (GET_CODE (operands[1]) != MEM)
5168 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5170 slot0 = operands[1];
5172 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5174 XEXP (slot0, 0), Pmode,
5175 operands[1], DImode);
5177 if (GET_CODE (operands[0]) != MEM)
5178 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5183 (define_insn "*floatditf2_hq"
5184 [(set (match_operand:TF 0 "register_operand" "=e")
5185 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5186 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5188 [(set_attr "type" "fp")
5189 (set_attr "length" "1")])
5191 (define_expand "floatunsditf2"
5192 [(set (match_operand:TF 0 "register_operand" "=e")
5193 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5194 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5199 if (GET_CODE (operands[1]) != MEM)
5200 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5202 slot0 = operands[1];
5204 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5206 XEXP (slot0, 0), Pmode,
5207 operands[1], DImode);
5209 if (GET_CODE (operands[0]) != MEM)
5210 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5214 ;; Convert a float to an actual integer.
5215 ;; Truncation is performed as part of the conversion.
5217 (define_insn "fix_truncsfsi2"
5218 [(set (match_operand:SI 0 "register_operand" "=f")
5219 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5222 [(set_attr "type" "fp")
5223 (set_attr "length" "1")])
5225 (define_insn "fix_truncdfsi2"
5226 [(set (match_operand:SI 0 "register_operand" "=f")
5227 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5230 [(set_attr "type" "fp")
5231 (set_attr "length" "1")])
5233 (define_expand "fix_trunctfsi2"
5234 [(set (match_operand:SI 0 "register_operand" "=f")
5235 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5236 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5239 if (! TARGET_HARD_QUAD)
5243 if (GET_CODE (operands[1]) != MEM)
5245 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5246 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5249 slot0 = operands[1];
5251 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5252 operands[0], 0, SImode, 1,
5253 XEXP (slot0, 0), Pmode);
5258 (define_insn "*fix_trunctfsi2_hq"
5259 [(set (match_operand:SI 0 "register_operand" "=f")
5260 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5261 "TARGET_FPU && TARGET_HARD_QUAD"
5263 [(set_attr "type" "fp")
5264 (set_attr "length" "1")])
5266 (define_expand "fixuns_trunctfsi2"
5267 [(set (match_operand:SI 0 "register_operand" "=f")
5268 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5269 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5274 if (GET_CODE (operands[1]) != MEM)
5276 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5277 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5280 slot0 = operands[1];
5282 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5283 operands[0], 0, SImode, 1,
5284 XEXP (slot0, 0), Pmode);
5288 ;; Now the same, for V9 targets
5290 (define_insn "fix_truncsfdi2"
5291 [(set (match_operand:DI 0 "register_operand" "=e")
5292 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5293 "TARGET_V9 && TARGET_FPU"
5295 [(set_attr "type" "fp")
5296 (set_attr "length" "1")])
5298 (define_insn "fix_truncdfdi2"
5299 [(set (match_operand:DI 0 "register_operand" "=e")
5300 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5301 "TARGET_V9 && TARGET_FPU"
5303 [(set_attr "type" "fp")
5304 (set_attr "length" "1")])
5306 (define_expand "fix_trunctfdi2"
5307 [(set (match_operand:DI 0 "register_operand" "=e")
5308 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5309 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5312 if (! TARGET_HARD_QUAD)
5316 if (GET_CODE (operands[1]) != MEM)
5318 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5319 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5322 slot0 = operands[1];
5324 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5325 operands[0], 0, DImode, 1,
5326 XEXP (slot0, 0), Pmode);
5331 (define_insn "*fix_trunctfdi2_hq"
5332 [(set (match_operand:DI 0 "register_operand" "=e")
5333 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5334 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5336 [(set_attr "type" "fp")
5337 (set_attr "length" "1")])
5339 (define_expand "fixuns_trunctfdi2"
5340 [(set (match_operand:DI 0 "register_operand" "=f")
5341 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5342 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5347 if (GET_CODE (operands[1]) != MEM)
5349 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5350 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5353 slot0 = operands[1];
5355 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5356 operands[0], 0, DImode, 1,
5357 XEXP (slot0, 0), Pmode);
5362 ;;- arithmetic instructions
5364 (define_expand "adddi3"
5365 [(set (match_operand:DI 0 "register_operand" "=r")
5366 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5367 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5371 if (! TARGET_ARCH64)
5373 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5374 gen_rtx_SET (VOIDmode, operands[0],
5375 gen_rtx_PLUS (DImode, operands[1],
5377 gen_rtx_CLOBBER (VOIDmode,
5378 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5381 if (arith_double_4096_operand(operands[2], DImode))
5383 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5384 gen_rtx_MINUS (DImode, operands[1],
5390 (define_insn "adddi3_insn_sp32"
5391 [(set (match_operand:DI 0 "register_operand" "=r")
5392 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5393 (match_operand:DI 2 "arith_double_operand" "rHI")))
5394 (clobber (reg:CC 100))]
5397 [(set_attr "length" "2")])
5400 [(set (match_operand:DI 0 "register_operand" "=r")
5401 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5402 (match_operand:DI 2 "arith_double_operand" "rHI")))
5403 (clobber (reg:CC 100))]
5404 "! TARGET_ARCH64 && reload_completed"
5405 [(parallel [(set (reg:CC_NOOV 100)
5406 (compare:CC_NOOV (plus:SI (match_dup 4)
5410 (plus:SI (match_dup 4) (match_dup 5)))])
5412 (plus:SI (plus:SI (match_dup 7)
5414 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5417 operands[3] = gen_lowpart (SImode, operands[0]);
5418 operands[4] = gen_lowpart (SImode, operands[1]);
5419 operands[5] = gen_lowpart (SImode, operands[2]);
5420 operands[6] = gen_highpart (SImode, operands[0]);
5421 operands[7] = gen_highpart (SImode, operands[1]);
5422 if (GET_CODE (operands[2]) == CONST_INT)
5424 if (INTVAL (operands[2]) < 0)
5425 operands[8] = constm1_rtx;
5427 operands[8] = const0_rtx;
5430 operands[8] = gen_highpart (SImode, operands[2]);
5434 [(set (match_operand:DI 0 "register_operand" "=r")
5435 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
5436 (match_operand:DI 2 "arith_double_operand" "rHI")))
5437 (clobber (reg:CC 100))]
5438 "! TARGET_ARCH64 && reload_completed"
5439 [(parallel [(set (reg:CC_NOOV 100)
5440 (compare:CC_NOOV (minus:SI (match_dup 4)
5444 (minus:SI (match_dup 4) (match_dup 5)))])
5446 (minus:SI (minus:SI (match_dup 7)
5448 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5451 operands[3] = gen_lowpart (SImode, operands[0]);
5452 operands[4] = gen_lowpart (SImode, operands[1]);
5453 operands[5] = gen_lowpart (SImode, operands[2]);
5454 operands[6] = gen_highpart (SImode, operands[0]);
5455 operands[7] = gen_highpart (SImode, operands[1]);
5456 if (GET_CODE (operands[2]) == CONST_INT)
5458 if (INTVAL (operands[2]) < 0)
5459 operands[8] = constm1_rtx;
5461 operands[8] = const0_rtx;
5464 operands[8] = gen_highpart (SImode, operands[2]);
5467 ;; LTU here means "carry set"
5469 [(set (match_operand:SI 0 "register_operand" "=r")
5470 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5471 (match_operand:SI 2 "arith_operand" "rI"))
5472 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5475 [(set_attr "type" "unary")
5476 (set_attr "length" "1")])
5478 (define_insn "*addx_extend_sp32"
5479 [(set (match_operand:DI 0 "register_operand" "=r")
5480 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5481 (match_operand:SI 2 "arith_operand" "rI"))
5482 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5485 [(set_attr "type" "unary")
5486 (set_attr "length" "2")])
5489 [(set (match_operand:DI 0 "register_operand" "")
5490 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5491 (match_operand:SI 2 "arith_operand" ""))
5492 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5493 "! TARGET_ARCH64 && reload_completed"
5494 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5495 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5496 (set (match_dup 4) (const_int 0))]
5497 "operands[3] = gen_lowpart (SImode, operands[0]);
5498 operands[4] = gen_highpart (SImode, operands[1]);")
5500 (define_insn "*addx_extend_sp64"
5501 [(set (match_operand:DI 0 "register_operand" "=r")
5502 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5503 (match_operand:SI 2 "arith_operand" "rI"))
5504 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5506 "addx\\t%r1, %2, %0"
5507 [(set_attr "type" "misc")
5508 (set_attr "length" "1")])
5511 [(set (match_operand:SI 0 "register_operand" "=r")
5512 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5513 (match_operand:SI 2 "arith_operand" "rI"))
5514 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5516 "subx\\t%r1, %2, %0"
5517 [(set_attr "type" "misc")
5518 (set_attr "length" "1")])
5520 (define_insn "*subx_extend_sp64"
5521 [(set (match_operand:DI 0 "register_operand" "=r")
5522 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5523 (match_operand:SI 2 "arith_operand" "rI"))
5524 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5526 "subx\\t%r1, %2, %0"
5527 [(set_attr "type" "misc")
5528 (set_attr "length" "1")])
5530 (define_insn "*subx_extend"
5531 [(set (match_operand:DI 0 "register_operand" "=r")
5532 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5533 (match_operand:SI 2 "arith_operand" "rI"))
5534 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5537 [(set_attr "type" "unary")
5538 (set_attr "length" "2")])
5541 [(set (match_operand:DI 0 "register_operand" "=r")
5542 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5543 (match_operand:SI 2 "arith_operand" "rI"))
5544 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5545 "! TARGET_ARCH64 && reload_completed"
5546 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5547 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5548 (set (match_dup 4) (const_int 0))]
5549 "operands[3] = gen_lowpart (SImode, operands[0]);
5550 operands[4] = gen_highpart (SImode, operands[0]);")
5553 [(set (match_operand:DI 0 "register_operand" "=r")
5554 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5555 (match_operand:DI 2 "register_operand" "r")))
5556 (clobber (reg:CC 100))]
5559 [(set_attr "type" "multi")
5560 (set_attr "length" "2")])
5563 [(set (match_operand:DI 0 "register_operand" "")
5564 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5565 (match_operand:DI 2 "register_operand" "")))
5566 (clobber (reg:CC 100))]
5567 "! TARGET_ARCH64 && reload_completed"
5568 [(parallel [(set (reg:CC_NOOV 100)
5569 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5571 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5573 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5574 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5575 "operands[3] = gen_lowpart (SImode, operands[2]);
5576 operands[4] = gen_highpart (SImode, operands[2]);
5577 operands[5] = gen_lowpart (SImode, operands[0]);
5578 operands[6] = gen_highpart (SImode, operands[0]);")
5580 (define_insn "*adddi3_sp64"
5581 [(set (match_operand:DI 0 "register_operand" "=r")
5582 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5583 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5586 [(set_attr "type" "binary")
5587 (set_attr "length" "1")])
5589 (define_expand "addsi3"
5590 [(set (match_operand:SI 0 "register_operand" "=r,d")
5591 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5592 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5596 if (arith_4096_operand(operands[2], DImode))
5598 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5599 gen_rtx_MINUS (SImode, operands[1],
5605 (define_insn "*addsi3"
5606 [(set (match_operand:SI 0 "register_operand" "=r,d")
5607 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5608 (match_operand:SI 2 "arith_operand" "rI,d")))]
5612 fpadd32s\\t%1, %2, %0"
5613 [(set_attr "type" "ialu,fp")
5614 (set_attr "length" "1")])
5616 (define_insn "*cmp_cc_plus"
5617 [(set (reg:CC_NOOV 100)
5618 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5619 (match_operand:SI 1 "arith_operand" "rI"))
5622 "addcc\\t%0, %1, %%g0"
5623 [(set_attr "type" "compare")
5624 (set_attr "length" "1")])
5626 (define_insn "*cmp_ccx_plus"
5627 [(set (reg:CCX_NOOV 100)
5628 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5629 (match_operand:DI 1 "arith_double_operand" "rHI"))
5632 "addcc\\t%0, %1, %%g0"
5633 [(set_attr "type" "compare")
5634 (set_attr "length" "1")])
5636 (define_insn "*cmp_cc_plus_set"
5637 [(set (reg:CC_NOOV 100)
5638 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5639 (match_operand:SI 2 "arith_operand" "rI"))
5641 (set (match_operand:SI 0 "register_operand" "=r")
5642 (plus:SI (match_dup 1) (match_dup 2)))]
5644 "addcc\\t%1, %2, %0"
5645 [(set_attr "type" "compare")
5646 (set_attr "length" "1")])
5648 (define_insn "*cmp_ccx_plus_set"
5649 [(set (reg:CCX_NOOV 100)
5650 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5651 (match_operand:DI 2 "arith_double_operand" "rHI"))
5653 (set (match_operand:DI 0 "register_operand" "=r")
5654 (plus:DI (match_dup 1) (match_dup 2)))]
5656 "addcc\\t%1, %2, %0"
5657 [(set_attr "type" "compare")
5658 (set_attr "length" "1")])
5660 (define_expand "subdi3"
5661 [(set (match_operand:DI 0 "register_operand" "=r")
5662 (minus:DI (match_operand:DI 1 "register_operand" "r")
5663 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5667 if (! TARGET_ARCH64)
5669 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5670 gen_rtx_SET (VOIDmode, operands[0],
5671 gen_rtx_MINUS (DImode, operands[1],
5673 gen_rtx_CLOBBER (VOIDmode,
5674 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5677 if (arith_double_4096_operand(operands[2], DImode))
5679 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5680 gen_rtx_PLUS (DImode, operands[1],
5686 (define_insn "*subdi3_sp32"
5687 [(set (match_operand:DI 0 "register_operand" "=r")
5688 (minus:DI (match_operand:DI 1 "register_operand" "r")
5689 (match_operand:DI 2 "arith_double_operand" "rHI")))
5690 (clobber (reg:CC 100))]
5693 [(set_attr "length" "2")])
5696 [(set (match_operand:DI 0 "register_operand" "")
5697 (minus:DI (match_operand:DI 1 "register_operand" "")
5698 (match_operand:DI 2 "arith_double_operand" "")))
5699 (clobber (reg:CC 100))]
5702 && (GET_CODE (operands[2]) == CONST_INT
5703 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5704 [(clobber (const_int 0))]
5709 highp = gen_highpart (SImode, operands[2]);
5710 lowp = gen_lowpart (SImode, operands[2]);
5711 if ((lowp == const0_rtx)
5712 && (operands[0] == operands[1]))
5714 emit_insn (gen_rtx_SET (VOIDmode,
5715 gen_highpart (SImode, operands[0]),
5716 gen_rtx_MINUS (SImode,
5717 gen_highpart (SImode, operands[1]),
5722 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5723 gen_lowpart (SImode, operands[1]),
5725 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5726 gen_highpart (SImode, operands[1]),
5733 [(set (match_operand:DI 0 "register_operand" "")
5734 (minus:DI (match_operand:DI 1 "register_operand" "")
5735 (match_operand:DI 2 "register_operand" "")))
5736 (clobber (reg:CC 100))]
5738 && reload_completed"
5739 [(clobber (const_int 0))]
5742 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5743 gen_lowpart (SImode, operands[1]),
5744 gen_lowpart (SImode, operands[2])));
5745 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5746 gen_highpart (SImode, operands[1]),
5747 gen_highpart (SImode, operands[2])));
5752 [(set (match_operand:DI 0 "register_operand" "=r")
5753 (minus:DI (match_operand:DI 1 "register_operand" "r")
5754 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5755 (clobber (reg:CC 100))]
5758 [(set_attr "type" "multi")
5759 (set_attr "length" "2")])
5762 [(set (match_operand:DI 0 "register_operand" "")
5763 (minus:DI (match_operand:DI 1 "register_operand" "")
5764 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5765 (clobber (reg:CC 100))]
5766 "! TARGET_ARCH64 && reload_completed"
5767 [(parallel [(set (reg:CC_NOOV 100)
5768 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5770 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5772 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5773 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5774 "operands[3] = gen_lowpart (SImode, operands[1]);
5775 operands[4] = gen_highpart (SImode, operands[1]);
5776 operands[5] = gen_lowpart (SImode, operands[0]);
5777 operands[6] = gen_highpart (SImode, operands[0]);")
5779 (define_insn "*subdi3_sp64"
5780 [(set (match_operand:DI 0 "register_operand" "=r")
5781 (minus:DI (match_operand:DI 1 "register_operand" "r")
5782 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5785 [(set_attr "type" "binary")
5786 (set_attr "length" "1")])
5788 (define_expand "subsi3"
5789 [(set (match_operand:SI 0 "register_operand" "=r,d")
5790 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5791 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5795 if (arith_4096_operand(operands[2], DImode))
5797 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5798 gen_rtx_PLUS (SImode, operands[1],
5804 (define_insn "*subsi3"
5805 [(set (match_operand:SI 0 "register_operand" "=r,d")
5806 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5807 (match_operand:SI 2 "arith_operand" "rI,d")))]
5811 fpsub32s\\t%1, %2, %0"
5812 [(set_attr "type" "ialu,fp")
5813 (set_attr "length" "1")])
5815 (define_insn "*cmp_minus_cc"
5816 [(set (reg:CC_NOOV 100)
5817 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5818 (match_operand:SI 1 "arith_operand" "rI"))
5821 "subcc\\t%r0, %1, %%g0"
5822 [(set_attr "type" "compare")
5823 (set_attr "length" "1")])
5825 (define_insn "*cmp_minus_ccx"
5826 [(set (reg:CCX_NOOV 100)
5827 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5828 (match_operand:DI 1 "arith_double_operand" "rHI"))
5831 "subcc\\t%0, %1, %%g0"
5832 [(set_attr "type" "compare")
5833 (set_attr "length" "1")])
5835 (define_insn "cmp_minus_cc_set"
5836 [(set (reg:CC_NOOV 100)
5837 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5838 (match_operand:SI 2 "arith_operand" "rI"))
5840 (set (match_operand:SI 0 "register_operand" "=r")
5841 (minus:SI (match_dup 1) (match_dup 2)))]
5843 "subcc\\t%r1, %2, %0"
5844 [(set_attr "type" "compare")
5845 (set_attr "length" "1")])
5847 (define_insn "*cmp_minus_ccx_set"
5848 [(set (reg:CCX_NOOV 100)
5849 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5850 (match_operand:DI 2 "arith_double_operand" "rHI"))
5852 (set (match_operand:DI 0 "register_operand" "=r")
5853 (minus:DI (match_dup 1) (match_dup 2)))]
5855 "subcc\\t%1, %2, %0"
5856 [(set_attr "type" "compare")
5857 (set_attr "length" "1")])
5859 ;; Integer Multiply/Divide.
5861 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5862 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5864 (define_insn "mulsi3"
5865 [(set (match_operand:SI 0 "register_operand" "=r")
5866 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5867 (match_operand:SI 2 "arith_operand" "rI")))]
5870 [(set_attr "type" "imul")
5871 (set_attr "length" "1")])
5873 (define_expand "muldi3"
5874 [(set (match_operand:DI 0 "register_operand" "=r")
5875 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5876 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5877 "TARGET_ARCH64 || TARGET_V8PLUS"
5882 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5887 (define_insn "*muldi3_sp64"
5888 [(set (match_operand:DI 0 "register_operand" "=r")
5889 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5890 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5893 [(set_attr "type" "imul")
5894 (set_attr "length" "1")])
5896 ;; V8plus wide multiply.
5898 (define_insn "muldi3_v8plus"
5899 [(set (match_operand:DI 0 "register_operand" "=r,h")
5900 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5901 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5902 (clobber (match_scratch:SI 3 "=&h,X"))
5903 (clobber (match_scratch:SI 4 "=&h,X"))]
5907 if (sparc_check_64 (operands[1], insn) <= 0)
5908 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5909 if (which_alternative == 1)
5910 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5911 if (sparc_check_64 (operands[2], insn) <= 0)
5912 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5913 if (which_alternative == 1)
5914 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\";
5916 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\";
5918 [(set_attr "length" "9,8")])
5920 (define_insn "*cmp_mul_set"
5922 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5923 (match_operand:SI 2 "arith_operand" "rI"))
5925 (set (match_operand:SI 0 "register_operand" "=r")
5926 (mult:SI (match_dup 1) (match_dup 2)))]
5927 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5928 "smulcc\\t%1, %2, %0"
5929 [(set_attr "type" "imul")
5930 (set_attr "length" "1")])
5932 (define_expand "mulsidi3"
5933 [(set (match_operand:DI 0 "register_operand" "")
5934 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5935 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5939 if (CONSTANT_P (operands[2]))
5942 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5945 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5951 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5956 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5957 ;; registers can hold 64 bit values in the V8plus environment.
5959 (define_insn "mulsidi3_v8plus"
5960 [(set (match_operand:DI 0 "register_operand" "=h,r")
5961 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5962 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5963 (clobber (match_scratch:SI 3 "=X,&h"))]
5966 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5967 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5968 [(set_attr "length" "2,3")])
5971 (define_insn "const_mulsidi3_v8plus"
5972 [(set (match_operand:DI 0 "register_operand" "=h,r")
5973 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5974 (match_operand:SI 2 "small_int" "I,I")))
5975 (clobber (match_scratch:SI 3 "=X,&h"))]
5978 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5979 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5980 [(set_attr "length" "2,3")])
5983 (define_insn "*mulsidi3_sp32"
5984 [(set (match_operand:DI 0 "register_operand" "=r")
5985 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5986 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5990 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5992 [(set (attr "length")
5993 (if_then_else (eq_attr "isa" "sparclet")
5994 (const_int 1) (const_int 2)))])
5996 (define_insn "*mulsidi3_sp64"
5997 [(set (match_operand:DI 0 "register_operand" "=r")
5998 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5999 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6000 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6002 [(set_attr "length" "1")])
6004 ;; Extra pattern, because sign_extend of a constant isn't valid.
6007 (define_insn "const_mulsidi3_sp32"
6008 [(set (match_operand:DI 0 "register_operand" "=r")
6009 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6010 (match_operand:SI 2 "small_int" "I")))]
6014 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6016 [(set (attr "length")
6017 (if_then_else (eq_attr "isa" "sparclet")
6018 (const_int 1) (const_int 2)))])
6020 (define_insn "const_mulsidi3_sp64"
6021 [(set (match_operand:DI 0 "register_operand" "=r")
6022 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6023 (match_operand:SI 2 "small_int" "I")))]
6024 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6026 [(set_attr "length" "1")])
6028 (define_expand "smulsi3_highpart"
6029 [(set (match_operand:SI 0 "register_operand" "")
6031 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6032 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6034 "TARGET_HARD_MUL && TARGET_ARCH32"
6037 if (CONSTANT_P (operands[2]))
6041 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6047 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6052 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6053 operands[2], GEN_INT (32)));
6059 (define_insn "smulsi3_highpart_v8plus"
6060 [(set (match_operand:SI 0 "register_operand" "=h,r")
6062 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6063 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6064 (match_operand:SI 3 "const_int_operand" "i,i"))))
6065 (clobber (match_scratch:SI 4 "=X,&h"))]
6068 smul %1,%2,%0\;srlx %0,%3,%0
6069 smul %1,%2,%4\;srlx %4,%3,%0"
6070 [(set_attr "length" "2")])
6072 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6075 [(set (match_operand:SI 0 "register_operand" "=h,r")
6078 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6079 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6080 (match_operand:SI 3 "const_int_operand" "i,i"))
6082 (clobber (match_scratch:SI 4 "=X,&h"))]
6085 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6086 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6087 [(set_attr "length" "2")])
6090 (define_insn "const_smulsi3_highpart_v8plus"
6091 [(set (match_operand:SI 0 "register_operand" "=h,r")
6093 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6094 (match_operand 2 "small_int" "i,i"))
6095 (match_operand:SI 3 "const_int_operand" "i,i"))))
6096 (clobber (match_scratch:SI 4 "=X,&h"))]
6099 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6100 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6101 [(set_attr "length" "2")])
6104 (define_insn "*smulsi3_highpart_sp32"
6105 [(set (match_operand:SI 0 "register_operand" "=r")
6107 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6108 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6111 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6112 [(set_attr "length" "2")])
6115 (define_insn "const_smulsi3_highpart"
6116 [(set (match_operand:SI 0 "register_operand" "=r")
6118 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6119 (match_operand:SI 2 "register_operand" "r"))
6122 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6123 [(set_attr "length" "2")])
6125 (define_expand "umulsidi3"
6126 [(set (match_operand:DI 0 "register_operand" "")
6127 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6128 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6132 if (CONSTANT_P (operands[2]))
6135 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6138 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6144 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6150 (define_insn "umulsidi3_v8plus"
6151 [(set (match_operand:DI 0 "register_operand" "=h,r")
6152 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6153 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6154 (clobber (match_scratch:SI 3 "=X,&h"))]
6157 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6158 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6159 [(set_attr "length" "2,3")])
6162 (define_insn "*umulsidi3_sp32"
6163 [(set (match_operand:DI 0 "register_operand" "=r")
6164 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6165 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6169 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6171 [(set (attr "length")
6172 (if_then_else (eq_attr "isa" "sparclet")
6173 (const_int 1) (const_int 2)))])
6175 (define_insn "*umulsidi3_sp64"
6176 [(set (match_operand:DI 0 "register_operand" "=r")
6177 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6178 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6179 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6181 [(set_attr "length" "1")])
6183 ;; Extra pattern, because sign_extend of a constant isn't valid.
6186 (define_insn "const_umulsidi3_sp32"
6187 [(set (match_operand:DI 0 "register_operand" "=r")
6188 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6189 (match_operand:SI 2 "uns_small_int" "")))]
6193 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6195 [(set (attr "length")
6196 (if_then_else (eq_attr "isa" "sparclet")
6197 (const_int 1) (const_int 2)))])
6199 (define_insn "const_umulsidi3_sp64"
6200 [(set (match_operand:DI 0 "register_operand" "=r")
6201 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6202 (match_operand:SI 2 "uns_small_int" "")))]
6203 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6205 [(set_attr "length" "1")])
6208 (define_insn "const_umulsidi3_v8plus"
6209 [(set (match_operand:DI 0 "register_operand" "=h,r")
6210 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6211 (match_operand:SI 2 "uns_small_int" "")))
6212 (clobber (match_scratch:SI 3 "=X,h"))]
6215 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6216 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6217 [(set_attr "length" "2,3")])
6219 (define_expand "umulsi3_highpart"
6220 [(set (match_operand:SI 0 "register_operand" "")
6222 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6223 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6225 "TARGET_HARD_MUL && TARGET_ARCH32"
6228 if (CONSTANT_P (operands[2]))
6232 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6238 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6243 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6244 operands[2], GEN_INT (32)));
6250 (define_insn "umulsi3_highpart_v8plus"
6251 [(set (match_operand:SI 0 "register_operand" "=h,r")
6253 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6254 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6255 (match_operand:SI 3 "const_int_operand" "i,i"))))
6256 (clobber (match_scratch:SI 4 "=X,h"))]
6259 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6260 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6261 [(set_attr "length" "2")])
6264 (define_insn "const_umulsi3_highpart_v8plus"
6265 [(set (match_operand:SI 0 "register_operand" "=h,r")
6267 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6268 (match_operand:SI 2 "uns_small_int" ""))
6269 (match_operand:SI 3 "const_int_operand" "i,i"))))
6270 (clobber (match_scratch:SI 4 "=X,h"))]
6273 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6274 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6275 [(set_attr "length" "2")])
6278 (define_insn "*umulsi3_highpart_sp32"
6279 [(set (match_operand:SI 0 "register_operand" "=r")
6281 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6282 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6285 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6286 [(set_attr "length" "2")])
6289 (define_insn "const_umulsi3_highpart"
6290 [(set (match_operand:SI 0 "register_operand" "=r")
6292 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6293 (match_operand:SI 2 "uns_small_int" ""))
6296 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6297 [(set_attr "length" "2")])
6299 ;; The v8 architecture specifies that there must be 3 instructions between
6300 ;; a y register write and a use of it for correct results.
6302 (define_expand "divsi3"
6303 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6304 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6305 (match_operand:SI 2 "input_operand" "rI,m")))
6306 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6307 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6312 operands[3] = gen_reg_rtx(SImode);
6313 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6314 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6320 (define_insn "divsi3_sp32"
6321 [(set (match_operand:SI 0 "register_operand" "=r,r")
6322 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6323 (match_operand:SI 2 "input_operand" "rI,m")))
6324 (clobber (match_scratch:SI 3 "=&r,&r"))]
6325 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6329 if (which_alternative == 0)
6331 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6333 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6336 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6338 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\";
6340 [(set (attr "length")
6341 (if_then_else (eq_attr "isa" "v9")
6342 (const_int 4) (const_int 7)))])
6344 (define_insn "divsi3_sp64"
6345 [(set (match_operand:SI 0 "register_operand" "=r")
6346 (div:SI (match_operand:SI 1 "register_operand" "r")
6347 (match_operand:SI 2 "input_operand" "rI")))
6348 (use (match_operand:SI 3 "register_operand" "r"))]
6349 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6350 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6351 [(set_attr "length" "2")])
6353 (define_insn "divdi3"
6354 [(set (match_operand:DI 0 "register_operand" "=r")
6355 (div:DI (match_operand:DI 1 "register_operand" "r")
6356 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6358 "sdivx\\t%1, %2, %0")
6360 (define_insn "*cmp_sdiv_cc_set"
6362 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6363 (match_operand:SI 2 "arith_operand" "rI"))
6365 (set (match_operand:SI 0 "register_operand" "=r")
6366 (div:SI (match_dup 1) (match_dup 2)))
6367 (clobber (match_scratch:SI 3 "=&r"))]
6368 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6372 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6374 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6376 [(set (attr "length")
6377 (if_then_else (eq_attr "isa" "v9")
6378 (const_int 3) (const_int 6)))])
6381 (define_expand "udivsi3"
6382 [(set (match_operand:SI 0 "register_operand" "")
6383 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6384 (match_operand:SI 2 "input_operand" "")))]
6385 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6388 (define_insn "udivsi3_sp32"
6389 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6390 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6391 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6393 || TARGET_DEPRECATED_V8_INSNS)
6397 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6398 switch (which_alternative)
6401 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6403 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6405 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6408 [(set_attr "length" "5")])
6410 (define_insn "udivsi3_sp64"
6411 [(set (match_operand:SI 0 "register_operand" "=r")
6412 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6413 (match_operand:SI 2 "input_operand" "rI")))]
6414 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6415 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6416 [(set_attr "length" "2")])
6418 (define_insn "udivdi3"
6419 [(set (match_operand:DI 0 "register_operand" "=r")
6420 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6421 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6423 "udivx\\t%1, %2, %0")
6425 (define_insn "*cmp_udiv_cc_set"
6427 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6428 (match_operand:SI 2 "arith_operand" "rI"))
6430 (set (match_operand:SI 0 "register_operand" "=r")
6431 (udiv:SI (match_dup 1) (match_dup 2)))]
6433 || TARGET_DEPRECATED_V8_INSNS"
6437 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6439 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6441 [(set (attr "length")
6442 (if_then_else (eq_attr "isa" "v9")
6443 (const_int 2) (const_int 5)))])
6445 ; sparclet multiply/accumulate insns
6447 (define_insn "*smacsi"
6448 [(set (match_operand:SI 0 "register_operand" "=r")
6449 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6450 (match_operand:SI 2 "arith_operand" "rI"))
6451 (match_operand:SI 3 "register_operand" "0")))]
6454 [(set_attr "type" "imul")
6455 (set_attr "length" "1")])
6457 (define_insn "*smacdi"
6458 [(set (match_operand:DI 0 "register_operand" "=r")
6459 (plus:DI (mult:DI (sign_extend:DI
6460 (match_operand:SI 1 "register_operand" "%r"))
6462 (match_operand:SI 2 "register_operand" "r")))
6463 (match_operand:DI 3 "register_operand" "0")))]
6465 "smacd\\t%1, %2, %L0"
6466 [(set_attr "type" "imul")
6467 (set_attr "length" "1")])
6469 (define_insn "*umacdi"
6470 [(set (match_operand:DI 0 "register_operand" "=r")
6471 (plus:DI (mult:DI (zero_extend:DI
6472 (match_operand:SI 1 "register_operand" "%r"))
6474 (match_operand:SI 2 "register_operand" "r")))
6475 (match_operand:DI 3 "register_operand" "0")))]
6477 "umacd\\t%1, %2, %L0"
6478 [(set_attr "type" "imul")
6479 (set_attr "length" "1")])
6481 ;;- Boolean instructions
6482 ;; We define DImode `and' so with DImode `not' we can get
6483 ;; DImode `andn'. Other combinations are possible.
6485 (define_expand "anddi3"
6486 [(set (match_operand:DI 0 "register_operand" "")
6487 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6488 (match_operand:DI 2 "arith_double_operand" "")))]
6492 (define_insn "*anddi3_sp32"
6493 [(set (match_operand:DI 0 "register_operand" "=r,b")
6494 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6495 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6500 [(set_attr "type" "ialu,fp")
6501 (set_attr "length" "2,1")])
6503 (define_insn "*anddi3_sp64"
6504 [(set (match_operand:DI 0 "register_operand" "=r,b")
6505 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6506 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6511 [(set_attr "type" "ialu,fp")
6512 (set_attr "length" "1,1")])
6514 (define_insn "andsi3"
6515 [(set (match_operand:SI 0 "register_operand" "=r,d")
6516 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6517 (match_operand:SI 2 "arith_operand" "rI,d")))]
6522 [(set_attr "type" "ialu,fp")
6523 (set_attr "length" "1,1")])
6526 [(set (match_operand:SI 0 "register_operand" "")
6527 (and:SI (match_operand:SI 1 "register_operand" "")
6528 (match_operand:SI 2 "" "")))
6529 (clobber (match_operand:SI 3 "register_operand" ""))]
6530 "GET_CODE (operands[2]) == CONST_INT
6531 && !SMALL_INT32 (operands[2])
6532 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6533 [(set (match_dup 3) (match_dup 4))
6534 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6537 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6540 ;; Split DImode logical operations requiring two instructions.
6542 [(set (match_operand:DI 0 "register_operand" "")
6543 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6544 [(match_operand:DI 2 "register_operand" "")
6545 (match_operand:DI 3 "arith_double_operand" "")]))]
6548 && ((GET_CODE (operands[0]) == REG
6549 && REGNO (operands[0]) < 32)
6550 || (GET_CODE (operands[0]) == SUBREG
6551 && GET_CODE (SUBREG_REG (operands[0])) == REG
6552 && REGNO (SUBREG_REG (operands[0])) < 32))"
6553 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6554 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6557 if (GET_CODE (operands[0]) == SUBREG)
6558 operands[0] = alter_subreg (operands[0]);
6559 operands[4] = gen_highpart (SImode, operands[0]);
6560 operands[5] = gen_lowpart (SImode, operands[0]);
6561 operands[6] = gen_highpart (SImode, operands[2]);
6562 operands[7] = gen_lowpart (SImode, operands[2]);
6563 if (GET_CODE (operands[3]) == CONST_INT)
6565 if (INTVAL (operands[3]) < 0)
6566 operands[8] = constm1_rtx;
6568 operands[8] = const0_rtx;
6571 operands[8] = gen_highpart (SImode, operands[3]);
6572 operands[9] = gen_lowpart (SImode, operands[3]);
6575 (define_insn "*and_not_di_sp32"
6576 [(set (match_operand:DI 0 "register_operand" "=r,b")
6577 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6578 (match_operand:DI 2 "register_operand" "r,b")))]
6582 fandnot1\\t%1, %2, %0"
6583 [(set_attr "type" "ialu,fp")
6584 (set_attr "length" "2,1")])
6587 [(set (match_operand:DI 0 "register_operand" "")
6588 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6589 (match_operand:DI 2 "register_operand" "")))]
6592 && ((GET_CODE (operands[0]) == REG
6593 && REGNO (operands[0]) < 32)
6594 || (GET_CODE (operands[0]) == SUBREG
6595 && GET_CODE (SUBREG_REG (operands[0])) == REG
6596 && REGNO (SUBREG_REG (operands[0])) < 32))"
6597 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6598 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6599 "if (GET_CODE (operands[0]) == SUBREG)
6600 operands[0] = alter_subreg (operands[0]);
6601 operands[3] = gen_highpart (SImode, operands[0]);
6602 operands[4] = gen_highpart (SImode, operands[1]);
6603 operands[5] = gen_highpart (SImode, operands[2]);
6604 operands[6] = gen_lowpart (SImode, operands[0]);
6605 operands[7] = gen_lowpart (SImode, operands[1]);
6606 operands[8] = gen_lowpart (SImode, operands[2]);")
6608 (define_insn "*and_not_di_sp64"
6609 [(set (match_operand:DI 0 "register_operand" "=r,b")
6610 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6611 (match_operand:DI 2 "register_operand" "r,b")))]
6615 fandnot1\\t%1, %2, %0"
6616 [(set_attr "type" "ialu,fp")
6617 (set_attr "length" "1,1")])
6619 (define_insn "*and_not_si"
6620 [(set (match_operand:SI 0 "register_operand" "=r,d")
6621 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6622 (match_operand:SI 2 "register_operand" "r,d")))]
6626 fandnot1s\\t%1, %2, %0"
6627 [(set_attr "type" "ialu,fp")
6628 (set_attr "length" "1,1")])
6630 (define_expand "iordi3"
6631 [(set (match_operand:DI 0 "register_operand" "")
6632 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6633 (match_operand:DI 2 "arith_double_operand" "")))]
6637 (define_insn "*iordi3_sp32"
6638 [(set (match_operand:DI 0 "register_operand" "=r,b")
6639 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6640 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6645 [(set_attr "type" "ialu,fp")
6646 (set_attr "length" "2,1")])
6648 (define_insn "*iordi3_sp64"
6649 [(set (match_operand:DI 0 "register_operand" "=r,b")
6650 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6651 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6656 [(set_attr "type" "ialu,fp")
6657 (set_attr "length" "1,1")])
6659 (define_insn "iorsi3"
6660 [(set (match_operand:SI 0 "register_operand" "=r,d")
6661 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6662 (match_operand:SI 2 "arith_operand" "rI,d")))]
6667 [(set_attr "type" "ialu,fp")
6668 (set_attr "length" "1,1")])
6671 [(set (match_operand:SI 0 "register_operand" "")
6672 (ior:SI (match_operand:SI 1 "register_operand" "")
6673 (match_operand:SI 2 "" "")))
6674 (clobber (match_operand:SI 3 "register_operand" ""))]
6675 "GET_CODE (operands[2]) == CONST_INT
6676 && !SMALL_INT32 (operands[2])
6677 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6678 [(set (match_dup 3) (match_dup 4))
6679 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6682 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6685 (define_insn "*or_not_di_sp32"
6686 [(set (match_operand:DI 0 "register_operand" "=r,b")
6687 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6688 (match_operand:DI 2 "register_operand" "r,b")))]
6692 fornot1\\t%1, %2, %0"
6693 [(set_attr "type" "ialu,fp")
6694 (set_attr "length" "2,1")])
6697 [(set (match_operand:DI 0 "register_operand" "")
6698 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6699 (match_operand:DI 2 "register_operand" "")))]
6702 && ((GET_CODE (operands[0]) == REG
6703 && REGNO (operands[0]) < 32)
6704 || (GET_CODE (operands[0]) == SUBREG
6705 && GET_CODE (SUBREG_REG (operands[0])) == REG
6706 && REGNO (SUBREG_REG (operands[0])) < 32))"
6707 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6708 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6709 "if (GET_CODE (operands[0]) == SUBREG)
6710 operands[0] = alter_subreg (operands[0]);
6711 operands[3] = gen_highpart (SImode, operands[0]);
6712 operands[4] = gen_highpart (SImode, operands[1]);
6713 operands[5] = gen_highpart (SImode, operands[2]);
6714 operands[6] = gen_lowpart (SImode, operands[0]);
6715 operands[7] = gen_lowpart (SImode, operands[1]);
6716 operands[8] = gen_lowpart (SImode, operands[2]);")
6718 (define_insn "*or_not_di_sp64"
6719 [(set (match_operand:DI 0 "register_operand" "=r,b")
6720 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6721 (match_operand:DI 2 "register_operand" "r,b")))]
6725 fornot1\\t%1, %2, %0"
6726 [(set_attr "type" "ialu,fp")
6727 (set_attr "length" "1,1")])
6729 (define_insn "*or_not_si"
6730 [(set (match_operand:SI 0 "register_operand" "=r,d")
6731 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6732 (match_operand:SI 2 "register_operand" "r,d")))]
6736 fornot1s\\t%1, %2, %0"
6737 [(set_attr "type" "ialu,fp")
6738 (set_attr "length" "1,1")])
6740 (define_expand "xordi3"
6741 [(set (match_operand:DI 0 "register_operand" "")
6742 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6743 (match_operand:DI 2 "arith_double_operand" "")))]
6747 (define_insn "*xordi3_sp32"
6748 [(set (match_operand:DI 0 "register_operand" "=r,b")
6749 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6750 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6755 [(set_attr "length" "2,1")
6756 (set_attr "type" "ialu,fp")])
6758 (define_insn "*xordi3_sp64"
6759 [(set (match_operand:DI 0 "register_operand" "=r,b")
6760 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6761 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6766 [(set_attr "type" "ialu,fp")
6767 (set_attr "length" "1,1")])
6769 (define_insn "*xordi3_sp64_dbl"
6770 [(set (match_operand:DI 0 "register_operand" "=r")
6771 (xor:DI (match_operand:DI 1 "register_operand" "r")
6772 (match_operand:DI 2 "const64_operand" "")))]
6774 && HOST_BITS_PER_WIDE_INT != 64)"
6776 [(set_attr "type" "ialu")
6777 (set_attr "length" "1")])
6779 (define_insn "xorsi3"
6780 [(set (match_operand:SI 0 "register_operand" "=r,d")
6781 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6782 (match_operand:SI 2 "arith_operand" "rI,d")))]
6787 [(set_attr "type" "ialu,fp")
6788 (set_attr "length" "1,1")])
6791 [(set (match_operand:SI 0 "register_operand" "")
6792 (xor:SI (match_operand:SI 1 "register_operand" "")
6793 (match_operand:SI 2 "" "")))
6794 (clobber (match_operand:SI 3 "register_operand" ""))]
6795 "GET_CODE (operands[2]) == CONST_INT
6796 && !SMALL_INT32 (operands[2])
6797 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6798 [(set (match_dup 3) (match_dup 4))
6799 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6802 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6806 [(set (match_operand:SI 0 "register_operand" "")
6807 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6808 (match_operand:SI 2 "" ""))))
6809 (clobber (match_operand:SI 3 "register_operand" ""))]
6810 "GET_CODE (operands[2]) == CONST_INT
6811 && !SMALL_INT32 (operands[2])
6812 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6813 [(set (match_dup 3) (match_dup 4))
6814 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6817 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6820 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6821 ;; Combine now canonicalizes to the rightmost expression.
6822 (define_insn "*xor_not_di_sp32"
6823 [(set (match_operand:DI 0 "register_operand" "=r,b")
6824 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6825 (match_operand:DI 2 "register_operand" "r,b"))))]
6830 [(set_attr "length" "2,1")
6831 (set_attr "type" "ialu,fp")])
6834 [(set (match_operand:DI 0 "register_operand" "")
6835 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6836 (match_operand:DI 2 "register_operand" ""))))]
6839 && ((GET_CODE (operands[0]) == REG
6840 && REGNO (operands[0]) < 32)
6841 || (GET_CODE (operands[0]) == SUBREG
6842 && GET_CODE (SUBREG_REG (operands[0])) == REG
6843 && REGNO (SUBREG_REG (operands[0])) < 32))"
6844 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6845 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6846 "if (GET_CODE (operands[0]) == SUBREG)
6847 operands[0] = alter_subreg (operands[0]);
6848 operands[3] = gen_highpart (SImode, operands[0]);
6849 operands[4] = gen_highpart (SImode, operands[1]);
6850 operands[5] = gen_highpart (SImode, operands[2]);
6851 operands[6] = gen_lowpart (SImode, operands[0]);
6852 operands[7] = gen_lowpart (SImode, operands[1]);
6853 operands[8] = gen_lowpart (SImode, operands[2]);")
6855 (define_insn "*xor_not_di_sp64"
6856 [(set (match_operand:DI 0 "register_operand" "=r,b")
6857 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6858 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6863 [(set_attr "type" "ialu,fp")
6864 (set_attr "length" "1,1")])
6866 (define_insn "*xor_not_si"
6867 [(set (match_operand:SI 0 "register_operand" "=r,d")
6868 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6869 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6873 fxnors\\t%1, %2, %0"
6874 [(set_attr "type" "ialu,fp")
6875 (set_attr "length" "1,1")])
6877 ;; These correspond to the above in the case where we also (or only)
6878 ;; want to set the condition code.
6880 (define_insn "*cmp_cc_arith_op"
6883 (match_operator:SI 2 "cc_arithop"
6884 [(match_operand:SI 0 "arith_operand" "%r")
6885 (match_operand:SI 1 "arith_operand" "rI")])
6888 "%A2cc\\t%0, %1, %%g0"
6889 [(set_attr "type" "compare")
6890 (set_attr "length" "1")])
6892 (define_insn "*cmp_ccx_arith_op"
6895 (match_operator:DI 2 "cc_arithop"
6896 [(match_operand:DI 0 "arith_double_operand" "%r")
6897 (match_operand:DI 1 "arith_double_operand" "rHI")])
6900 "%A2cc\\t%0, %1, %%g0"
6901 [(set_attr "type" "compare")
6902 (set_attr "length" "1")])
6904 (define_insn "*cmp_cc_arith_op_set"
6907 (match_operator:SI 3 "cc_arithop"
6908 [(match_operand:SI 1 "arith_operand" "%r")
6909 (match_operand:SI 2 "arith_operand" "rI")])
6911 (set (match_operand:SI 0 "register_operand" "=r")
6914 "%A3cc\\t%1, %2, %0"
6915 [(set_attr "type" "compare")
6916 (set_attr "length" "1")])
6918 (define_insn "*cmp_ccx_arith_op_set"
6921 (match_operator:DI 3 "cc_arithop"
6922 [(match_operand:DI 1 "arith_double_operand" "%r")
6923 (match_operand:DI 2 "arith_double_operand" "rHI")])
6925 (set (match_operand:DI 0 "register_operand" "=r")
6928 "%A3cc\\t%1, %2, %0"
6929 [(set_attr "type" "compare")
6930 (set_attr "length" "1")])
6932 (define_insn "*cmp_cc_xor_not"
6935 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6936 (match_operand:SI 1 "arith_operand" "rI")))
6939 "xnorcc\\t%r0, %1, %%g0"
6940 [(set_attr "type" "compare")
6941 (set_attr "length" "1")])
6943 (define_insn "*cmp_ccx_xor_not"
6946 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6947 (match_operand:DI 1 "arith_double_operand" "rHI")))
6950 "xnorcc\\t%r0, %1, %%g0"
6951 [(set_attr "type" "compare")
6952 (set_attr "length" "1")])
6954 (define_insn "*cmp_cc_xor_not_set"
6957 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6958 (match_operand:SI 2 "arith_operand" "rI")))
6960 (set (match_operand:SI 0 "register_operand" "=r")
6961 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6963 "xnorcc\\t%r1, %2, %0"
6964 [(set_attr "type" "compare")
6965 (set_attr "length" "1")])
6967 (define_insn "*cmp_ccx_xor_not_set"
6970 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6971 (match_operand:DI 2 "arith_double_operand" "rHI")))
6973 (set (match_operand:DI 0 "register_operand" "=r")
6974 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6976 "xnorcc\\t%r1, %2, %0"
6977 [(set_attr "type" "compare")
6978 (set_attr "length" "1")])
6980 (define_insn "*cmp_cc_arith_op_not"
6983 (match_operator:SI 2 "cc_arithopn"
6984 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6985 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6988 "%B2cc\\t%r1, %0, %%g0"
6989 [(set_attr "type" "compare")
6990 (set_attr "length" "1")])
6992 (define_insn "*cmp_ccx_arith_op_not"
6995 (match_operator:DI 2 "cc_arithopn"
6996 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6997 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7000 "%B2cc\\t%r1, %0, %%g0"
7001 [(set_attr "type" "compare")
7002 (set_attr "length" "1")])
7004 (define_insn "*cmp_cc_arith_op_not_set"
7007 (match_operator:SI 3 "cc_arithopn"
7008 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7009 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7011 (set (match_operand:SI 0 "register_operand" "=r")
7014 "%B3cc\\t%r2, %1, %0"
7015 [(set_attr "type" "compare")
7016 (set_attr "length" "1")])
7018 (define_insn "*cmp_ccx_arith_op_not_set"
7021 (match_operator:DI 3 "cc_arithopn"
7022 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7023 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7025 (set (match_operand:DI 0 "register_operand" "=r")
7028 "%B3cc\\t%r2, %1, %0"
7029 [(set_attr "type" "compare")
7030 (set_attr "length" "1")])
7032 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7033 ;; does not know how to make it work for constants.
7035 (define_expand "negdi2"
7036 [(set (match_operand:DI 0 "register_operand" "=r")
7037 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7041 if (! TARGET_ARCH64)
7043 emit_insn (gen_rtx_PARALLEL
7046 gen_rtx_SET (VOIDmode, operand0,
7047 gen_rtx_NEG (DImode, operand1)),
7048 gen_rtx_CLOBBER (VOIDmode,
7049 gen_rtx_REG (CCmode,
7055 (define_insn "*negdi2_sp32"
7056 [(set (match_operand:DI 0 "register_operand" "=r")
7057 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7058 (clobber (reg:CC 100))]
7061 [(set_attr "type" "unary")
7062 (set_attr "length" "2")])
7065 [(set (match_operand:DI 0 "register_operand" "")
7066 (neg:DI (match_operand:DI 1 "register_operand" "")))
7067 (clobber (reg:CC 100))]
7069 && reload_completed"
7070 [(parallel [(set (reg:CC_NOOV 100)
7071 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7073 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7074 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7075 (ltu:SI (reg:CC 100) (const_int 0))))]
7076 "operands[2] = gen_highpart (SImode, operands[0]);
7077 operands[3] = gen_highpart (SImode, operands[1]);
7078 operands[4] = gen_lowpart (SImode, operands[0]);
7079 operands[5] = gen_lowpart (SImode, operands[1]);")
7081 (define_insn "*negdi2_sp64"
7082 [(set (match_operand:DI 0 "register_operand" "=r")
7083 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7085 "sub\\t%%g0, %1, %0"
7086 [(set_attr "type" "unary")
7087 (set_attr "length" "1")])
7089 (define_insn "negsi2"
7090 [(set (match_operand:SI 0 "register_operand" "=r")
7091 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7093 "sub\\t%%g0, %1, %0"
7094 [(set_attr "type" "unary")
7095 (set_attr "length" "1")])
7097 (define_insn "*cmp_cc_neg"
7098 [(set (reg:CC_NOOV 100)
7099 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7102 "subcc\\t%%g0, %0, %%g0"
7103 [(set_attr "type" "compare")
7104 (set_attr "length" "1")])
7106 (define_insn "*cmp_ccx_neg"
7107 [(set (reg:CCX_NOOV 100)
7108 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7111 "subcc\\t%%g0, %0, %%g0"
7112 [(set_attr "type" "compare")
7113 (set_attr "length" "1")])
7115 (define_insn "*cmp_cc_set_neg"
7116 [(set (reg:CC_NOOV 100)
7117 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7119 (set (match_operand:SI 0 "register_operand" "=r")
7120 (neg:SI (match_dup 1)))]
7122 "subcc\\t%%g0, %1, %0"
7123 [(set_attr "type" "compare")
7124 (set_attr "length" "1")])
7126 (define_insn "*cmp_ccx_set_neg"
7127 [(set (reg:CCX_NOOV 100)
7128 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7130 (set (match_operand:DI 0 "register_operand" "=r")
7131 (neg:DI (match_dup 1)))]
7133 "subcc\\t%%g0, %1, %0"
7134 [(set_attr "type" "compare")
7135 (set_attr "length" "1")])
7137 ;; We cannot use the "not" pseudo insn because the Sun assembler
7138 ;; does not know how to make it work for constants.
7139 (define_expand "one_cmpldi2"
7140 [(set (match_operand:DI 0 "register_operand" "")
7141 (not:DI (match_operand:DI 1 "register_operand" "")))]
7145 (define_insn "*one_cmpldi2_sp32"
7146 [(set (match_operand:DI 0 "register_operand" "=r,b")
7147 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7152 [(set_attr "type" "unary,fp")
7153 (set_attr "length" "2,1")])
7156 [(set (match_operand:DI 0 "register_operand" "")
7157 (not:DI (match_operand:DI 1 "register_operand" "")))]
7160 && ((GET_CODE (operands[0]) == REG
7161 && REGNO (operands[0]) < 32)
7162 || (GET_CODE (operands[0]) == SUBREG
7163 && GET_CODE (SUBREG_REG (operands[0])) == REG
7164 && REGNO (SUBREG_REG (operands[0])) < 32))"
7165 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7166 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7167 "if (GET_CODE (operands[0]) == SUBREG)
7168 operands[0] = alter_subreg (operands[0]);
7169 operands[2] = gen_highpart (SImode, operands[0]);
7170 operands[3] = gen_highpart (SImode, operands[1]);
7171 operands[4] = gen_lowpart (SImode, operands[0]);
7172 operands[5] = gen_lowpart (SImode, operands[1]);")
7174 (define_insn "*one_cmpldi2_sp64"
7175 [(set (match_operand:DI 0 "register_operand" "=r,b")
7176 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7181 [(set_attr "type" "unary,fp")
7182 (set_attr "length" "1")])
7184 (define_insn "one_cmplsi2"
7185 [(set (match_operand:SI 0 "register_operand" "=r,d")
7186 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7191 [(set_attr "type" "unary,fp")
7192 (set_attr "length" "1,1")])
7194 (define_insn "*cmp_cc_not"
7196 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7199 "xnorcc\\t%%g0, %0, %%g0"
7200 [(set_attr "type" "compare")
7201 (set_attr "length" "1")])
7203 (define_insn "*cmp_ccx_not"
7205 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7208 "xnorcc\\t%%g0, %0, %%g0"
7209 [(set_attr "type" "compare")
7210 (set_attr "length" "1")])
7212 (define_insn "*cmp_cc_set_not"
7214 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7216 (set (match_operand:SI 0 "register_operand" "=r")
7217 (not:SI (match_dup 1)))]
7219 "xnorcc\\t%%g0, %1, %0"
7220 [(set_attr "type" "compare")
7221 (set_attr "length" "1")])
7223 (define_insn "*cmp_ccx_set_not"
7225 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7227 (set (match_operand:DI 0 "register_operand" "=r")
7228 (not:DI (match_dup 1)))]
7230 "xnorcc\\t%%g0, %1, %0"
7231 [(set_attr "type" "compare")
7232 (set_attr "length" "1")])
7234 ;; Floating point arithmetic instructions.
7236 (define_expand "addtf3"
7237 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7238 (plus:TF (match_operand:TF 1 "general_operand" "")
7239 (match_operand:TF 2 "general_operand" "")))]
7240 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7243 if (! TARGET_HARD_QUAD)
7245 rtx slot0, slot1, slot2;
7247 if (GET_CODE (operands[0]) != MEM)
7248 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7250 slot0 = operands[0];
7251 if (GET_CODE (operands[1]) != MEM)
7253 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7254 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7257 slot1 = operands[1];
7258 if (GET_CODE (operands[2]) != MEM)
7260 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7261 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7264 slot2 = operands[2];
7266 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7268 XEXP (slot0, 0), Pmode,
7269 XEXP (slot1, 0), Pmode,
7270 XEXP (slot2, 0), Pmode);
7272 if (GET_CODE (operands[0]) != MEM)
7273 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7278 (define_insn "*addtf3_hq"
7279 [(set (match_operand:TF 0 "register_operand" "=e")
7280 (plus:TF (match_operand:TF 1 "register_operand" "e")
7281 (match_operand:TF 2 "register_operand" "e")))]
7282 "TARGET_FPU && TARGET_HARD_QUAD"
7283 "faddq\\t%1, %2, %0"
7284 [(set_attr "type" "fp")
7285 (set_attr "length" "1")])
7287 (define_insn "adddf3"
7288 [(set (match_operand:DF 0 "register_operand" "=e")
7289 (plus:DF (match_operand:DF 1 "register_operand" "e")
7290 (match_operand:DF 2 "register_operand" "e")))]
7292 "faddd\\t%1, %2, %0"
7293 [(set_attr "type" "fp")
7294 (set_attr "length" "1")])
7296 (define_insn "addsf3"
7297 [(set (match_operand:SF 0 "register_operand" "=f")
7298 (plus:SF (match_operand:SF 1 "register_operand" "f")
7299 (match_operand:SF 2 "register_operand" "f")))]
7301 "fadds\\t%1, %2, %0"
7302 [(set_attr "type" "fp")
7303 (set_attr "length" "1")])
7305 (define_expand "subtf3"
7306 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7307 (minus:TF (match_operand:TF 1 "general_operand" "")
7308 (match_operand:TF 2 "general_operand" "")))]
7309 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7312 if (! TARGET_HARD_QUAD)
7314 rtx slot0, slot1, slot2;
7316 if (GET_CODE (operands[0]) != MEM)
7317 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7319 slot0 = operands[0];
7320 if (GET_CODE (operands[1]) != MEM)
7322 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7323 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7326 slot1 = operands[1];
7327 if (GET_CODE (operands[2]) != MEM)
7329 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7330 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7333 slot2 = operands[2];
7335 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7337 XEXP (slot0, 0), Pmode,
7338 XEXP (slot1, 0), Pmode,
7339 XEXP (slot2, 0), Pmode);
7341 if (GET_CODE (operands[0]) != MEM)
7342 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7347 (define_insn "*subtf3_hq"
7348 [(set (match_operand:TF 0 "register_operand" "=e")
7349 (minus:TF (match_operand:TF 1 "register_operand" "e")
7350 (match_operand:TF 2 "register_operand" "e")))]
7351 "TARGET_FPU && TARGET_HARD_QUAD"
7352 "fsubq\\t%1, %2, %0"
7353 [(set_attr "type" "fp")
7354 (set_attr "length" "1")])
7356 (define_insn "subdf3"
7357 [(set (match_operand:DF 0 "register_operand" "=e")
7358 (minus:DF (match_operand:DF 1 "register_operand" "e")
7359 (match_operand:DF 2 "register_operand" "e")))]
7361 "fsubd\\t%1, %2, %0"
7362 [(set_attr "type" "fp")
7363 (set_attr "length" "1")])
7365 (define_insn "subsf3"
7366 [(set (match_operand:SF 0 "register_operand" "=f")
7367 (minus:SF (match_operand:SF 1 "register_operand" "f")
7368 (match_operand:SF 2 "register_operand" "f")))]
7370 "fsubs\\t%1, %2, %0"
7371 [(set_attr "type" "fp")
7372 (set_attr "length" "1")])
7374 (define_expand "multf3"
7375 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7376 (mult:TF (match_operand:TF 1 "general_operand" "")
7377 (match_operand:TF 2 "general_operand" "")))]
7378 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7381 if (! TARGET_HARD_QUAD)
7383 rtx slot0, slot1, slot2;
7385 if (GET_CODE (operands[0]) != MEM)
7386 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7388 slot0 = operands[0];
7389 if (GET_CODE (operands[1]) != MEM)
7391 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7392 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7395 slot1 = operands[1];
7396 if (GET_CODE (operands[2]) != MEM)
7398 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7399 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7402 slot2 = operands[2];
7404 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7406 XEXP (slot0, 0), Pmode,
7407 XEXP (slot1, 0), Pmode,
7408 XEXP (slot2, 0), Pmode);
7410 if (GET_CODE (operands[0]) != MEM)
7411 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7416 (define_insn "*multf3_hq"
7417 [(set (match_operand:TF 0 "register_operand" "=e")
7418 (mult:TF (match_operand:TF 1 "register_operand" "e")
7419 (match_operand:TF 2 "register_operand" "e")))]
7420 "TARGET_FPU && TARGET_HARD_QUAD"
7421 "fmulq\\t%1, %2, %0"
7422 [(set_attr "type" "fpmul")
7423 (set_attr "length" "1")])
7425 (define_insn "muldf3"
7426 [(set (match_operand:DF 0 "register_operand" "=e")
7427 (mult:DF (match_operand:DF 1 "register_operand" "e")
7428 (match_operand:DF 2 "register_operand" "e")))]
7430 "fmuld\\t%1, %2, %0"
7431 [(set_attr "type" "fpmul")
7432 (set_attr "length" "1")])
7434 (define_insn "mulsf3"
7435 [(set (match_operand:SF 0 "register_operand" "=f")
7436 (mult:SF (match_operand:SF 1 "register_operand" "f")
7437 (match_operand:SF 2 "register_operand" "f")))]
7439 "fmuls\\t%1, %2, %0"
7440 [(set_attr "type" "fpmul")
7441 (set_attr "length" "1")])
7443 (define_insn "*muldf3_extend"
7444 [(set (match_operand:DF 0 "register_operand" "=e")
7445 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7446 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7447 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7448 "fsmuld\\t%1, %2, %0"
7449 [(set_attr "type" "fpmul")
7450 (set_attr "length" "1")])
7452 (define_insn "*multf3_extend"
7453 [(set (match_operand:TF 0 "register_operand" "=e")
7454 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7455 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7456 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7457 "fdmulq\\t%1, %2, %0"
7458 [(set_attr "type" "fpmul")
7459 (set_attr "length" "1")])
7461 (define_expand "divtf3"
7462 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7463 (div:TF (match_operand:TF 1 "general_operand" "")
7464 (match_operand:TF 2 "general_operand" "")))]
7465 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7468 if (! TARGET_HARD_QUAD)
7470 rtx slot0, slot1, slot2;
7472 if (GET_CODE (operands[0]) != MEM)
7473 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7475 slot0 = operands[0];
7476 if (GET_CODE (operands[1]) != MEM)
7478 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7479 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7482 slot1 = operands[1];
7483 if (GET_CODE (operands[2]) != MEM)
7485 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7486 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7489 slot2 = operands[2];
7491 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7493 XEXP (slot0, 0), Pmode,
7494 XEXP (slot1, 0), Pmode,
7495 XEXP (slot2, 0), Pmode);
7497 if (GET_CODE (operands[0]) != MEM)
7498 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7503 ;; don't have timing for quad-prec. divide.
7504 (define_insn "*divtf3_hq"
7505 [(set (match_operand:TF 0 "register_operand" "=e")
7506 (div:TF (match_operand:TF 1 "register_operand" "e")
7507 (match_operand:TF 2 "register_operand" "e")))]
7508 "TARGET_FPU && TARGET_HARD_QUAD"
7509 "fdivq\\t%1, %2, %0"
7510 [(set_attr "type" "fpdivd")
7511 (set_attr "length" "1")])
7513 (define_insn "divdf3"
7514 [(set (match_operand:DF 0 "register_operand" "=e")
7515 (div:DF (match_operand:DF 1 "register_operand" "e")
7516 (match_operand:DF 2 "register_operand" "e")))]
7518 "fdivd\\t%1, %2, %0"
7519 [(set_attr "type" "fpdivd")
7520 (set_attr "length" "1")])
7522 (define_insn "divsf3"
7523 [(set (match_operand:SF 0 "register_operand" "=f")
7524 (div:SF (match_operand:SF 1 "register_operand" "f")
7525 (match_operand:SF 2 "register_operand" "f")))]
7527 "fdivs\\t%1, %2, %0"
7528 [(set_attr "type" "fpdivs")
7529 (set_attr "length" "1")])
7531 (define_expand "negtf2"
7532 [(set (match_operand:TF 0 "register_operand" "=e,e")
7533 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7537 (define_insn "*negtf2_notv9"
7538 [(set (match_operand:TF 0 "register_operand" "=e,e")
7539 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7540 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7546 [(set_attr "type" "fpmove")
7547 (set_attr "length" "1,2")])
7550 [(set (match_operand:TF 0 "register_operand" "")
7551 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7555 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7556 [(set (match_dup 2) (neg:SF (match_dup 3)))
7557 (set (match_dup 4) (match_dup 5))
7558 (set (match_dup 6) (match_dup 7))]
7559 "if (GET_CODE (operands[0]) == SUBREG)
7560 operands[0] = alter_subreg (operands[0]);
7561 if (GET_CODE (operands[1]) == SUBREG)
7562 operands[1] = alter_subreg (operands[1]);
7563 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7564 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7565 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7566 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7567 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7568 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7570 (define_insn "*negtf2_v9"
7571 [(set (match_operand:TF 0 "register_operand" "=e,e")
7572 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7573 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7574 "TARGET_FPU && TARGET_V9"
7578 [(set_attr "type" "fpmove")
7579 (set_attr "length" "1,2")])
7582 [(set (match_operand:TF 0 "register_operand" "")
7583 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7587 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7588 [(set (match_dup 2) (neg:DF (match_dup 3)))
7589 (set (match_dup 4) (match_dup 5))]
7590 "if (GET_CODE (operands[0]) == SUBREG)
7591 operands[0] = alter_subreg (operands[0]);
7592 if (GET_CODE (operands[1]) == SUBREG)
7593 operands[1] = alter_subreg (operands[1]);
7594 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7595 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7596 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7597 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7599 (define_expand "negdf2"
7600 [(set (match_operand:DF 0 "register_operand" "")
7601 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7605 (define_insn "*negdf2_notv9"
7606 [(set (match_operand:DF 0 "register_operand" "=e,e")
7607 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7608 "TARGET_FPU && ! TARGET_V9"
7612 [(set_attr "type" "fpmove")
7613 (set_attr "length" "1,2")])
7616 [(set (match_operand:DF 0 "register_operand" "")
7617 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7621 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7622 [(set (match_dup 2) (neg:SF (match_dup 3)))
7623 (set (match_dup 4) (match_dup 5))]
7624 "if (GET_CODE (operands[0]) == SUBREG)
7625 operands[0] = alter_subreg (operands[0]);
7626 if (GET_CODE (operands[1]) == SUBREG)
7627 operands[1] = alter_subreg (operands[1]);
7628 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7629 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7630 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7631 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7633 (define_insn "*negdf2_v9"
7634 [(set (match_operand:DF 0 "register_operand" "=e")
7635 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7636 "TARGET_FPU && TARGET_V9"
7638 [(set_attr "type" "fpmove")
7639 (set_attr "length" "1")])
7641 (define_insn "negsf2"
7642 [(set (match_operand:SF 0 "register_operand" "=f")
7643 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7646 [(set_attr "type" "fpmove")
7647 (set_attr "length" "1")])
7649 (define_expand "abstf2"
7650 [(set (match_operand:TF 0 "register_operand" "")
7651 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7655 (define_insn "*abstf2_notv9"
7656 [(set (match_operand:TF 0 "register_operand" "=e,e")
7657 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7658 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7659 "TARGET_FPU && ! TARGET_V9"
7663 [(set_attr "type" "fpmove")
7664 (set_attr "length" "1,2")])
7667 [(set (match_operand:TF 0 "register_operand" "=e,e")
7668 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7672 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7673 [(set (match_dup 2) (abs:SF (match_dup 3)))
7674 (set (match_dup 4) (match_dup 5))
7675 (set (match_dup 6) (match_dup 7))]
7676 "if (GET_CODE (operands[0]) == SUBREG)
7677 operands[0] = alter_subreg (operands[0]);
7678 if (GET_CODE (operands[1]) == SUBREG)
7679 operands[1] = alter_subreg (operands[1]);
7680 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7681 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7682 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7683 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7684 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7685 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7687 (define_insn "*abstf2_hq_v9"
7688 [(set (match_operand:TF 0 "register_operand" "=e,e")
7689 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7690 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7694 [(set_attr "type" "fpmove")
7695 (set_attr "length" "1")])
7697 (define_insn "*abstf2_v9"
7698 [(set (match_operand:TF 0 "register_operand" "=e,e")
7699 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7700 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7704 [(set_attr "type" "fpmove")
7705 (set_attr "length" "1,2")])
7708 [(set (match_operand:TF 0 "register_operand" "=e,e")
7709 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7713 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7714 [(set (match_dup 2) (abs:DF (match_dup 3)))
7715 (set (match_dup 4) (match_dup 5))]
7716 "if (GET_CODE (operands[0]) == SUBREG)
7717 operands[0] = alter_subreg (operands[0]);
7718 if (GET_CODE (operands[1]) == SUBREG)
7719 operands[1] = alter_subreg (operands[1]);
7720 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7721 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7722 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7723 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7725 (define_expand "absdf2"
7726 [(set (match_operand:DF 0 "register_operand" "")
7727 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7731 (define_insn "*absdf2_notv9"
7732 [(set (match_operand:DF 0 "register_operand" "=e,e")
7733 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7734 "TARGET_FPU && ! TARGET_V9"
7738 [(set_attr "type" "fpmove")
7739 (set_attr "length" "1,2")])
7742 [(set (match_operand:DF 0 "register_operand" "=e,e")
7743 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7747 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7748 [(set (match_dup 2) (abs:SF (match_dup 3)))
7749 (set (match_dup 4) (match_dup 5))]
7750 "if (GET_CODE (operands[0]) == SUBREG)
7751 operands[0] = alter_subreg (operands[0]);
7752 if (GET_CODE (operands[1]) == SUBREG)
7753 operands[1] = alter_subreg (operands[1]);
7754 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7755 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7756 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7757 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7759 (define_insn "*absdf2_v9"
7760 [(set (match_operand:DF 0 "register_operand" "=e")
7761 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7762 "TARGET_FPU && TARGET_V9"
7764 [(set_attr "type" "fpmove")
7765 (set_attr "length" "1")])
7767 (define_insn "abssf2"
7768 [(set (match_operand:SF 0 "register_operand" "=f")
7769 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7772 [(set_attr "type" "fpmove")
7773 (set_attr "length" "1")])
7775 (define_expand "sqrttf2"
7776 [(set (match_operand:TF 0 "register_operand" "=e")
7777 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7778 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7781 if (! TARGET_HARD_QUAD)
7785 if (GET_CODE (operands[0]) != MEM)
7786 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7788 slot0 = operands[0];
7789 if (GET_CODE (operands[1]) != MEM)
7791 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7792 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7795 slot1 = operands[1];
7797 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7799 XEXP (slot0, 0), Pmode,
7800 XEXP (slot1, 0), Pmode);
7802 if (GET_CODE (operands[0]) != MEM)
7803 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7808 (define_insn "*sqrttf2_hq"
7809 [(set (match_operand:TF 0 "register_operand" "=e")
7810 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7811 "TARGET_FPU && TARGET_HARD_QUAD"
7813 [(set_attr "type" "fpsqrtd")
7814 (set_attr "length" "1")])
7816 (define_insn "sqrtdf2"
7817 [(set (match_operand:DF 0 "register_operand" "=e")
7818 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7821 [(set_attr "type" "fpsqrtd")
7822 (set_attr "length" "1")])
7824 (define_insn "sqrtsf2"
7825 [(set (match_operand:SF 0 "register_operand" "=f")
7826 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7829 [(set_attr "type" "fpsqrts")
7830 (set_attr "length" "1")])
7832 ;;- arithmetic shift instructions
7834 (define_insn "ashlsi3"
7835 [(set (match_operand:SI 0 "register_operand" "=r")
7836 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7837 (match_operand:SI 2 "arith_operand" "rI")))]
7841 if (GET_CODE (operands[2]) == CONST_INT
7842 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7843 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7845 return \"sll\\t%1, %2, %0\";
7847 [(set_attr "type" "shift")
7848 (set_attr "length" "1")])
7850 ;; We special case multiplication by two, as add can be done
7851 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7852 (define_insn "*ashlsi3_const1"
7853 [(set (match_operand:SI 0 "register_operand" "=r")
7854 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7858 [(set_attr "type" "binary")
7859 (set_attr "length" "1")])
7861 (define_expand "ashldi3"
7862 [(set (match_operand:DI 0 "register_operand" "=r")
7863 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7864 (match_operand:SI 2 "arith_operand" "rI")))]
7865 "TARGET_ARCH64 || TARGET_V8PLUS"
7868 if (! TARGET_ARCH64)
7870 if (GET_CODE (operands[2]) == CONST_INT)
7872 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7877 ;; We special case multiplication by two, as add can be done
7878 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7879 (define_insn "*ashldi3_const1"
7880 [(set (match_operand:DI 0 "register_operand" "=r")
7881 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7885 [(set_attr "type" "binary")
7886 (set_attr "length" "1")])
7888 (define_insn "*ashldi3_sp64"
7889 [(set (match_operand:DI 0 "register_operand" "=r")
7890 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7891 (match_operand:SI 2 "arith_operand" "rI")))]
7895 if (GET_CODE (operands[2]) == CONST_INT
7896 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7897 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7899 return \"sllx\\t%1, %2, %0\";
7901 [(set_attr "type" "shift")
7902 (set_attr "length" "1")])
7905 (define_insn "ashldi3_v8plus"
7906 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7907 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7908 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7909 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7911 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
7912 [(set_attr "length" "5,5,6")])
7914 ;; Optimize (1LL<<x)-1
7915 ;; XXX this also needs to be fixed to handle equal subregs
7916 ;; XXX first before we could re-enable it.
7918 [(set (match_operand:DI 0 "register_operand" "=h")
7919 (plus:DI (ashift:DI (const_int 1)
7920 (match_operand:SI 2 "arith_operand" "rI"))
7922 "0 && TARGET_V8PLUS"
7925 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
7926 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7927 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
7929 [(set_attr "length" "4")])
7931 (define_insn "*cmp_cc_ashift_1"
7932 [(set (reg:CC_NOOV 100)
7933 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7937 "addcc\\t%0, %0, %%g0"
7938 [(set_attr "type" "compare")
7939 (set_attr "length" "1")])
7941 (define_insn "*cmp_cc_set_ashift_1"
7942 [(set (reg:CC_NOOV 100)
7943 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7946 (set (match_operand:SI 0 "register_operand" "=r")
7947 (ashift:SI (match_dup 1) (const_int 1)))]
7949 "addcc\\t%1, %1, %0"
7950 [(set_attr "type" "compare")
7951 (set_attr "length" "1")])
7953 (define_insn "ashrsi3"
7954 [(set (match_operand:SI 0 "register_operand" "=r")
7955 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7956 (match_operand:SI 2 "arith_operand" "rI")))]
7960 if (GET_CODE (operands[2]) == CONST_INT
7961 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7962 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7964 return \"sra\\t%1, %2, %0\";
7966 [(set_attr "type" "shift")
7967 (set_attr "length" "1")])
7969 (define_insn "*ashrsi3_extend"
7970 [(set (match_operand:DI 0 "register_operand" "=r")
7971 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7972 (match_operand:SI 2 "arith_operand" "r"))))]
7975 [(set_attr "type" "shift")
7976 (set_attr "length" "1")])
7978 ;; This handles the case as above, but with constant shift instead of
7979 ;; register. Combiner "simplifies" it for us a little bit though.
7980 (define_insn "*ashrsi3_extend2"
7981 [(set (match_operand:DI 0 "register_operand" "=r")
7982 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7984 (match_operand:SI 2 "small_int_or_double" "n")))]
7986 && ((GET_CODE (operands[2]) == CONST_INT
7987 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7988 || (GET_CODE (operands[2]) == CONST_DOUBLE
7989 && !CONST_DOUBLE_HIGH (operands[2])
7990 && CONST_DOUBLE_LOW (operands[2]) >= 32
7991 && CONST_DOUBLE_LOW (operands[2]) < 64))"
7994 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7996 return \"sra\\t%1, %2, %0\";
7998 [(set_attr "type" "shift")
7999 (set_attr "length" "1")])
8001 (define_expand "ashrdi3"
8002 [(set (match_operand:DI 0 "register_operand" "=r")
8003 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8004 (match_operand:SI 2 "arith_operand" "rI")))]
8005 "TARGET_ARCH64 || TARGET_V8PLUS"
8008 if (! TARGET_ARCH64)
8010 if (GET_CODE (operands[2]) == CONST_INT)
8011 FAIL; /* prefer generic code in this case */
8012 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8018 [(set (match_operand:DI 0 "register_operand" "=r")
8019 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8020 (match_operand:SI 2 "arith_operand" "rI")))]
8024 if (GET_CODE (operands[2]) == CONST_INT
8025 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8026 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8028 return \"srax\\t%1, %2, %0\";
8030 [(set_attr "type" "shift")
8031 (set_attr "length" "1")])
8034 (define_insn "ashrdi3_v8plus"
8035 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8036 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8037 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8038 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8040 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8041 [(set_attr "length" "5,5,6")])
8043 (define_insn "lshrsi3"
8044 [(set (match_operand:SI 0 "register_operand" "=r")
8045 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8046 (match_operand:SI 2 "arith_operand" "rI")))]
8050 if (GET_CODE (operands[2]) == CONST_INT
8051 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8052 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8054 return \"srl\\t%1, %2, %0\";
8056 [(set_attr "type" "shift")
8057 (set_attr "length" "1")])
8059 ;; This handles the case where
8060 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8061 ;; but combiner "simplifies" it for us.
8062 (define_insn "*lshrsi3_extend"
8063 [(set (match_operand:DI 0 "register_operand" "=r")
8064 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8065 (match_operand:SI 2 "arith_operand" "r")) 0)
8066 (match_operand 3 "" "")))]
8068 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8069 && CONST_DOUBLE_HIGH (operands[3]) == 0
8070 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8071 #if HOST_BITS_PER_WIDE_INT >= 64
8072 || (GET_CODE (operands[3]) == CONST_INT
8073 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
8077 [(set_attr "type" "shift")
8078 (set_attr "length" "1")])
8080 ;; This handles the case where
8081 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8082 ;; but combiner "simplifies" it for us.
8083 (define_insn "*lshrsi3_extend2"
8084 [(set (match_operand:DI 0 "register_operand" "=r")
8085 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8086 (match_operand 2 "small_int_or_double" "n")
8089 && ((GET_CODE (operands[2]) == CONST_INT
8090 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8091 || (GET_CODE (operands[2]) == CONST_DOUBLE
8092 && CONST_DOUBLE_HIGH (operands[2]) == 0
8093 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8096 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8098 return \"srl\\t%1, %2, %0\";
8100 [(set_attr "type" "shift")
8101 (set_attr "length" "1")])
8103 (define_expand "lshrdi3"
8104 [(set (match_operand:DI 0 "register_operand" "=r")
8105 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8106 (match_operand:SI 2 "arith_operand" "rI")))]
8107 "TARGET_ARCH64 || TARGET_V8PLUS"
8110 if (! TARGET_ARCH64)
8112 if (GET_CODE (operands[2]) == CONST_INT)
8114 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8120 [(set (match_operand:DI 0 "register_operand" "=r")
8121 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8122 (match_operand:SI 2 "arith_operand" "rI")))]
8126 if (GET_CODE (operands[2]) == CONST_INT
8127 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8128 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8130 return \"srlx\\t%1, %2, %0\";
8132 [(set_attr "type" "shift")
8133 (set_attr "length" "1")])
8136 (define_insn "lshrdi3_v8plus"
8137 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8138 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8139 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8140 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8142 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8143 [(set_attr "length" "5,5,6")])
8146 [(set (match_operand:SI 0 "register_operand" "=r")
8147 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8149 (match_operand:SI 2 "small_int_or_double" "n")))]
8151 && ((GET_CODE (operands[2]) == CONST_INT
8152 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8153 || (GET_CODE (operands[2]) == CONST_DOUBLE
8154 && !CONST_DOUBLE_HIGH (operands[2])
8155 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8158 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8160 return \"srax\\t%1, %2, %0\";
8162 [(set_attr "type" "shift")
8163 (set_attr "length" "1")])
8166 [(set (match_operand:SI 0 "register_operand" "=r")
8167 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8169 (match_operand:SI 2 "small_int_or_double" "n")))]
8171 && ((GET_CODE (operands[2]) == CONST_INT
8172 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8173 || (GET_CODE (operands[2]) == CONST_DOUBLE
8174 && !CONST_DOUBLE_HIGH (operands[2])
8175 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8178 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8180 return \"srlx\\t%1, %2, %0\";
8182 [(set_attr "type" "shift")
8183 (set_attr "length" "1")])
8186 [(set (match_operand:SI 0 "register_operand" "=r")
8187 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8188 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8189 (match_operand:SI 3 "small_int_or_double" "n")))]
8191 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8192 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8193 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8194 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8197 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8199 return \"srax\\t%1, %2, %0\";
8201 [(set_attr "type" "shift")
8202 (set_attr "length" "1")])
8205 [(set (match_operand:SI 0 "register_operand" "=r")
8206 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8207 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8208 (match_operand:SI 3 "small_int_or_double" "n")))]
8210 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8211 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8212 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8213 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8216 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8218 return \"srlx\\t%1, %2, %0\";
8220 [(set_attr "type" "shift")
8221 (set_attr "length" "1")])
8223 ;; Unconditional and other jump instructions
8224 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8225 ;; following insn is never executed. This saves us a nop. Dbx does not
8226 ;; handle such branches though, so we only use them when optimizing.
8228 [(set (pc) (label_ref (match_operand 0 "" "")))]
8232 /* TurboSparc is reported to have problems with
8235 i.e. an empty loop with the annul bit set. The workaround is to use
8239 if (! TARGET_V9 && flag_delayed_branch
8240 && (insn_addresses[INSN_UID (operands[0])]
8241 == insn_addresses[INSN_UID (insn)]))
8242 return \"b\\t%l0%#\";
8244 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8246 [(set_attr "type" "uncond_branch")])
8248 (define_expand "tablejump"
8249 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8250 (use (label_ref (match_operand 1 "" "")))])]
8254 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8257 /* In pic mode, our address differences are against the base of the
8258 table. Add that base value back in; CSE ought to be able to combine
8259 the two address loads. */
8263 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8265 if (CASE_VECTOR_MODE != Pmode)
8266 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8267 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8268 operands[0] = memory_address (Pmode, tmp);
8272 (define_insn "*tablejump_sp32"
8273 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8274 (use (label_ref (match_operand 1 "" "")))]
8277 [(set_attr "type" "uncond_branch")])
8279 (define_insn "*tablejump_sp64"
8280 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8281 (use (label_ref (match_operand 1 "" "")))]
8284 [(set_attr "type" "uncond_branch")])
8286 ;; This pattern recognizes the "instruction" that appears in
8287 ;; a function call that wants a structure value,
8288 ;; to inform the called function if compiled with Sun CC.
8289 ;(define_insn "*unimp_insn"
8290 ; [(match_operand:SI 0 "immediate_operand" "")]
8291 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8293 ; [(set_attr "type" "marker")])
8295 ;;- jump to subroutine
8296 (define_expand "call"
8297 ;; Note that this expression is not used for generating RTL.
8298 ;; All the RTL is generated explicitly below.
8299 [(call (match_operand 0 "call_operand" "")
8300 (match_operand 3 "" "i"))]
8301 ;; operands[2] is next_arg_register
8302 ;; operands[3] is struct_value_size_rtx.
8306 rtx fn_rtx, nregs_rtx;
8308 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8311 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8313 /* This is really a PIC sequence. We want to represent
8314 it as a funny jump so its delay slots can be filled.
8316 ??? But if this really *is* a CALL, will not it clobber the
8317 call-clobbered registers? We lose this if it is a JUMP_INSN.
8318 Why cannot we have delay slots filled if it were a CALL? */
8320 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8325 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8327 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8333 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8334 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8338 fn_rtx = operands[0];
8340 /* Count the number of parameter registers being used by this call.
8341 if that argument is NULL, it means we are using them all, which
8342 means 6 on the sparc. */
8345 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8347 nregs_rtx = GEN_INT (6);
8349 nregs_rtx = const0_rtx;
8352 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8356 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8358 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8363 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8364 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8368 /* If this call wants a structure value,
8369 emit an unimp insn to let the called function know about this. */
8370 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8372 rtx insn = emit_insn (operands[3]);
8373 SCHED_GROUP_P (insn) = 1;
8380 ;; We can't use the same pattern for these two insns, because then registers
8381 ;; in the address may not be properly reloaded.
8383 (define_insn "*call_address_sp32"
8384 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8385 (match_operand 1 "" ""))
8386 (clobber (reg:SI 15))]
8387 ;;- Do not use operand 1 for most machines.
8390 [(set_attr "type" "call")])
8392 (define_insn "*call_symbolic_sp32"
8393 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8394 (match_operand 1 "" ""))
8395 (clobber (reg:SI 15))]
8396 ;;- Do not use operand 1 for most machines.
8399 [(set_attr "type" "call")])
8401 (define_insn "*call_address_sp64"
8402 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
8403 (match_operand 1 "" ""))
8404 (clobber (reg:DI 15))]
8405 ;;- Do not use operand 1 for most machines.
8408 [(set_attr "type" "call")])
8410 (define_insn "*call_symbolic_sp64"
8411 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
8412 (match_operand 1 "" ""))
8413 (clobber (reg:DI 15))]
8414 ;;- Do not use operand 1 for most machines.
8417 [(set_attr "type" "call")])
8419 ;; This is a call that wants a structure value.
8420 ;; There is no such critter for v9 (??? we may need one anyway).
8421 (define_insn "*call_address_struct_value_sp32"
8422 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8423 (match_operand 1 "" ""))
8424 (match_operand 2 "immediate_operand" "")
8425 (clobber (reg:SI 15))]
8426 ;;- Do not use operand 1 for most machines.
8427 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8428 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8429 [(set_attr "type" "call_no_delay_slot")])
8431 ;; This is a call that wants a structure value.
8432 ;; There is no such critter for v9 (??? we may need one anyway).
8433 (define_insn "*call_symbolic_struct_value_sp32"
8434 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8435 (match_operand 1 "" ""))
8436 (match_operand 2 "immediate_operand" "")
8437 (clobber (reg:SI 15))]
8438 ;;- Do not use operand 1 for most machines.
8439 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8440 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8441 [(set_attr "type" "call_no_delay_slot")])
8443 ;; This is a call that may want a structure value. This is used for
8445 (define_insn "*call_address_untyped_struct_value_sp32"
8446 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8447 (match_operand 1 "" ""))
8448 (match_operand 2 "immediate_operand" "")
8449 (clobber (reg:SI 15))]
8450 ;;- Do not use operand 1 for most machines.
8451 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8452 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8453 [(set_attr "type" "call_no_delay_slot")])
8455 ;; This is a call that wants a structure value.
8456 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8457 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8458 (match_operand 1 "" ""))
8459 (match_operand 2 "immediate_operand" "")
8460 (clobber (reg:SI 15))]
8461 ;;- Do not use operand 1 for most machines.
8462 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8463 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8464 [(set_attr "type" "call_no_delay_slot")])
8466 (define_expand "call_value"
8467 ;; Note that this expression is not used for generating RTL.
8468 ;; All the RTL is generated explicitly below.
8469 [(set (match_operand 0 "register_operand" "=rf")
8470 (call (match_operand:SI 1 "" "")
8471 (match_operand 4 "" "")))]
8472 ;; operand 2 is stack_size_rtx
8473 ;; operand 3 is next_arg_register
8477 rtx fn_rtx, nregs_rtx;
8480 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8483 fn_rtx = operands[1];
8487 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8489 nregs_rtx = GEN_INT (6);
8491 nregs_rtx = const0_rtx;
8495 gen_rtx_SET (VOIDmode, operands[0],
8496 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8497 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8499 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8504 (define_insn "*call_value_address_sp32"
8505 [(set (match_operand 0 "" "=rf")
8506 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8507 (match_operand 2 "" "")))
8508 (clobber (reg:SI 15))]
8509 ;;- Do not use operand 2 for most machines.
8512 [(set_attr "type" "call")])
8514 (define_insn "*call_value_symbolic_sp32"
8515 [(set (match_operand 0 "" "=rf")
8516 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8517 (match_operand 2 "" "")))
8518 (clobber (reg:SI 15))]
8519 ;;- Do not use operand 2 for most machines.
8522 [(set_attr "type" "call")])
8524 (define_insn "*call_value_address_sp64"
8525 [(set (match_operand 0 "" "")
8526 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
8527 (match_operand 2 "" "")))
8528 (clobber (reg:DI 15))]
8529 ;;- Do not use operand 2 for most machines.
8532 [(set_attr "type" "call")])
8534 (define_insn "*call_value_symbolic_sp64"
8535 [(set (match_operand 0 "" "")
8536 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
8537 (match_operand 2 "" "")))
8538 (clobber (reg:DI 15))]
8539 ;;- Do not use operand 2 for most machines.
8542 [(set_attr "type" "call")])
8544 (define_expand "untyped_call"
8545 [(parallel [(call (match_operand 0 "" "")
8547 (match_operand 1 "" "")
8548 (match_operand 2 "" "")])]
8554 /* Pass constm1 to indicate that it may expect a structure value, but
8555 we don't know what size it is. */
8556 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
8558 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8560 rtx set = XVECEXP (operands[2], 0, i);
8561 emit_move_insn (SET_DEST (set), SET_SRC (set));
8564 /* The optimizer does not know that the call sets the function value
8565 registers we stored in the result block. We avoid problems by
8566 claiming that all hard registers are used and clobbered at this
8568 emit_insn (gen_blockage ());
8573 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8574 ;; all of memory. This blocks insns from being moved across this point.
8576 (define_insn "blockage"
8577 [(unspec_volatile [(const_int 0)] 0)]
8580 [(set_attr "length" "0")])
8582 ;; Prepare to return any type including a structure value.
8584 (define_expand "untyped_return"
8585 [(match_operand:BLK 0 "memory_operand" "")
8586 (match_operand 1 "" "")]
8590 rtx valreg1 = gen_rtx_REG (DImode, 24);
8591 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8592 rtx result = operands[0];
8594 if (! TARGET_ARCH64)
8596 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8598 rtx value = gen_reg_rtx (SImode);
8600 /* Fetch the instruction where we will return to and see if it's an unimp
8601 instruction (the most significant 10 bits will be zero). If so,
8602 update the return address to skip the unimp instruction. */
8603 emit_move_insn (value,
8604 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8605 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8606 emit_insn (gen_update_return (rtnreg, value));
8609 /* Reload the function value registers. */
8610 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
8611 emit_move_insn (valreg2,
8612 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
8613 plus_constant (XEXP (result, 0), 8)));
8615 /* Put USE insns before the return. */
8616 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8617 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8619 /* Construct the return. */
8620 expand_null_return ();
8625 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8626 ;; and parts of the compiler don't want to believe that the add is needed.
8628 (define_insn "update_return"
8629 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8630 (match_operand:SI 1 "register_operand" "r")] 1)]
8632 "cmp %1,0\;be,a .+8\;add %0,4,%0"
8633 [(set_attr "type" "multi")])
8635 (define_insn "return"
8639 "* return output_return (operands);"
8640 [(set_attr "type" "return")])
8643 [(set (match_operand:SI 0 "register_operand" "=r")
8644 (match_operand:SI 1 "arith_operand" "rI"))
8646 (use (reg:SI 31))])]
8647 "sparc_return_peephole_ok (operands[0], operands[1])"
8648 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8654 [(set_attr "type" "ialu")
8655 (set_attr "length" "1")])
8657 (define_expand "indirect_jump"
8658 [(set (pc) (match_operand 0 "address_operand" "p"))]
8662 (define_insn "*branch_sp32"
8663 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8666 [(set_attr "type" "uncond_branch")])
8668 (define_insn "*branch_sp64"
8669 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8672 [(set_attr "type" "uncond_branch")])
8674 ;; ??? Doesn't work with -mflat.
8675 (define_expand "nonlocal_goto"
8676 [(match_operand:SI 0 "general_operand" "")
8677 (match_operand:SI 1 "general_operand" "")
8678 (match_operand:SI 2 "general_operand" "")
8679 (match_operand:SI 3 "" "")]
8684 rtx chain = operands[0];
8686 rtx fp = operands[1];
8687 rtx stack = operands[2];
8688 rtx lab = operands[3];
8691 /* Trap instruction to flush all the register windows. */
8692 emit_insn (gen_flush_register_windows ());
8694 /* Load the fp value for the containing fn into %fp. This is needed
8695 because STACK refers to %fp. Note that virtual register instantiation
8696 fails if the virtual %fp isn't set from a register. */
8697 if (GET_CODE (fp) != REG)
8698 fp = force_reg (Pmode, fp);
8699 emit_move_insn (virtual_stack_vars_rtx, fp);
8701 /* Find the containing function's current nonlocal goto handler,
8702 which will do any cleanups and then jump to the label. */
8703 labreg = gen_rtx_REG (Pmode, 8);
8704 emit_move_insn (labreg, lab);
8706 /* Restore %fp from stack pointer value for containing function.
8707 The restore insn that follows will move this to %sp,
8708 and reload the appropriate value into %fp. */
8709 emit_move_insn (frame_pointer_rtx, stack);
8711 /* USE of frame_pointer_rtx added for consistency; not clear if
8713 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8714 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8717 /* Return, restoring reg window and jumping to goto handler. */
8718 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8719 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8721 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
8726 /* Put in the static chain register the nonlocal label address. */
8727 emit_move_insn (static_chain_rtx, chain);
8730 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8731 emit_insn (gen_goto_handler_and_restore (labreg));
8736 ;; Special trap insn to flush register windows.
8737 (define_insn "flush_register_windows"
8738 [(unspec_volatile [(const_int 0)] 1)]
8740 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8741 [(set_attr "type" "misc")
8742 (set_attr "length" "1")])
8744 (define_insn "goto_handler_and_restore"
8745 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8746 "GET_MODE (operands[0]) == Pmode"
8747 "jmp\\t%0+0\\n\\trestore"
8748 [(set_attr "type" "misc")
8749 (set_attr "length" "2")])
8751 ;;(define_insn "goto_handler_and_restore_v9"
8752 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8753 ;; (match_operand:SI 1 "register_operand" "=r,r")
8754 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8755 ;; "TARGET_V9 && ! TARGET_ARCH64"
8757 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8758 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8759 ;; [(set_attr "type" "misc")
8760 ;; (set_attr "length" "2,3")])
8762 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8763 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8764 ;; (match_operand:DI 1 "register_operand" "=r,r")
8765 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8766 ;; "TARGET_V9 && TARGET_ARCH64"
8768 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8769 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8770 ;; [(set_attr "type" "misc")
8771 ;; (set_attr "length" "2,3")])
8773 ;; Pattern for use after a setjmp to store FP and the return register
8774 ;; into the stack area.
8776 (define_expand "setjmp"
8782 emit_insn (gen_setjmp_64 ());
8784 emit_insn (gen_setjmp_32 ());
8788 (define_expand "setjmp_32"
8789 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8790 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8793 { operands[0] = frame_pointer_rtx; }")
8795 (define_expand "setjmp_64"
8796 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8797 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8800 { operands[0] = frame_pointer_rtx; }")
8802 ;; Special pattern for the FLUSH instruction.
8804 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8805 ; of the define_insn otherwise missing a mode. We make "flush", aka
8806 ; gen_flush, the default one since sparc_initialize_trampoline uses
8807 ; it on SImode mem values.
8809 (define_insn "flush"
8810 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8812 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
8813 [(set_attr "type" "misc")])
8815 (define_insn "flushdi"
8816 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8818 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
8819 [(set_attr "type" "misc")])
8824 ;; The scan instruction searches from the most significant bit while ffs
8825 ;; searches from the least significant bit. The bit index and treatment of
8826 ;; zero also differ. It takes at least 7 instructions to get the proper
8827 ;; result. Here is an obvious 8 instruction sequence.
8830 (define_insn "ffssi2"
8831 [(set (match_operand:SI 0 "register_operand" "=&r")
8832 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8833 (clobber (match_scratch:SI 2 "=&r"))]
8834 "TARGET_SPARCLITE || TARGET_SPARCLET"
8837 return \"sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0\";
8839 [(set_attr "type" "multi")
8840 (set_attr "length" "8")])
8842 ;; ??? This should be a define expand, so that the extra instruction have
8843 ;; a chance of being optimized away.
8845 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8846 ;; does, but no one uses that and we don't have a switch for it.
8848 ;(define_insn "ffsdi2"
8849 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8850 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8851 ; (clobber (match_scratch:DI 2 "=&r"))]
8853 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
8854 ; [(set_attr "type" "multi")
8855 ; (set_attr "length" "4")])
8859 ;; Peepholes go at the end.
8861 ;; Optimize consecutive loads or stores into ldd and std when possible.
8862 ;; The conditions in which we do this are very restricted and are
8863 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8866 [(set (match_operand:SI 0 "memory_operand" "")
8868 (set (match_operand:SI 1 "memory_operand" "")
8871 && ! MEM_VOLATILE_P (operands[0])
8872 && ! MEM_VOLATILE_P (operands[1])
8873 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
8877 [(set (match_operand:SI 0 "memory_operand" "")
8879 (set (match_operand:SI 1 "memory_operand" "")
8882 && ! MEM_VOLATILE_P (operands[0])
8883 && ! MEM_VOLATILE_P (operands[1])
8884 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
8888 [(set (match_operand:SI 0 "register_operand" "=rf")
8889 (match_operand:SI 1 "memory_operand" ""))
8890 (set (match_operand:SI 2 "register_operand" "=rf")
8891 (match_operand:SI 3 "memory_operand" ""))]
8892 "registers_ok_for_ldd_peep (operands[0], operands[2])
8893 && ! MEM_VOLATILE_P (operands[1])
8894 && ! MEM_VOLATILE_P (operands[3])
8895 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8899 [(set (match_operand:SI 0 "memory_operand" "")
8900 (match_operand:SI 1 "register_operand" "rf"))
8901 (set (match_operand:SI 2 "memory_operand" "")
8902 (match_operand:SI 3 "register_operand" "rf"))]
8903 "registers_ok_for_ldd_peep (operands[1], operands[3])
8904 && ! MEM_VOLATILE_P (operands[0])
8905 && ! MEM_VOLATILE_P (operands[2])
8906 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8910 [(set (match_operand:SF 0 "register_operand" "=fr")
8911 (match_operand:SF 1 "memory_operand" ""))
8912 (set (match_operand:SF 2 "register_operand" "=fr")
8913 (match_operand:SF 3 "memory_operand" ""))]
8914 "registers_ok_for_ldd_peep (operands[0], operands[2])
8915 && ! MEM_VOLATILE_P (operands[1])
8916 && ! MEM_VOLATILE_P (operands[3])
8917 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
8921 [(set (match_operand:SF 0 "memory_operand" "")
8922 (match_operand:SF 1 "register_operand" "fr"))
8923 (set (match_operand:SF 2 "memory_operand" "")
8924 (match_operand:SF 3 "register_operand" "fr"))]
8925 "registers_ok_for_ldd_peep (operands[1], operands[3])
8926 && ! MEM_VOLATILE_P (operands[0])
8927 && ! MEM_VOLATILE_P (operands[2])
8928 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
8932 [(set (match_operand:SI 0 "register_operand" "=rf")
8933 (match_operand:SI 1 "memory_operand" ""))
8934 (set (match_operand:SI 2 "register_operand" "=rf")
8935 (match_operand:SI 3 "memory_operand" ""))]
8936 "registers_ok_for_ldd_peep (operands[2], operands[0])
8937 && ! MEM_VOLATILE_P (operands[3])
8938 && ! MEM_VOLATILE_P (operands[1])
8939 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8943 [(set (match_operand:SI 0 "memory_operand" "")
8944 (match_operand:SI 1 "register_operand" "rf"))
8945 (set (match_operand:SI 2 "memory_operand" "")
8946 (match_operand:SI 3 "register_operand" "rf"))]
8947 "registers_ok_for_ldd_peep (operands[3], operands[1])
8948 && ! MEM_VOLATILE_P (operands[2])
8949 && ! MEM_VOLATILE_P (operands[0])
8950 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8954 [(set (match_operand:SF 0 "register_operand" "=fr")
8955 (match_operand:SF 1 "memory_operand" ""))
8956 (set (match_operand:SF 2 "register_operand" "=fr")
8957 (match_operand:SF 3 "memory_operand" ""))]
8958 "registers_ok_for_ldd_peep (operands[2], operands[0])
8959 && ! MEM_VOLATILE_P (operands[3])
8960 && ! MEM_VOLATILE_P (operands[1])
8961 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
8965 [(set (match_operand:SF 0 "memory_operand" "")
8966 (match_operand:SF 1 "register_operand" "fr"))
8967 (set (match_operand:SF 2 "memory_operand" "")
8968 (match_operand:SF 3 "register_operand" "fr"))]
8969 "registers_ok_for_ldd_peep (operands[3], operands[1])
8970 && ! MEM_VOLATILE_P (operands[2])
8971 && ! MEM_VOLATILE_P (operands[0])
8972 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
8975 ;; Optimize the case of following a reg-reg move with a test
8976 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
8977 ;; This can result from a float to fix conversion.
8980 [(set (match_operand:SI 0 "register_operand" "=r")
8981 (match_operand:SI 1 "register_operand" "r"))
8983 (compare:CC (match_operand:SI 2 "register_operand" "r")
8985 "(rtx_equal_p (operands[2], operands[0])
8986 || rtx_equal_p (operands[2], operands[1]))
8987 && ! FP_REG_P (operands[0])
8988 && ! FP_REG_P (operands[1])"
8992 [(set (match_operand:DI 0 "register_operand" "=r")
8993 (match_operand:DI 1 "register_operand" "r"))
8995 (compare:CCX (match_operand:DI 2 "register_operand" "r")
8998 && (rtx_equal_p (operands[2], operands[0])
8999 || rtx_equal_p (operands[2], operands[1]))
9000 && ! FP_REG_P (operands[0])
9001 && ! FP_REG_P (operands[1])"
9004 ;; Return peepholes. First the "normal" ones.
9005 ;; These are necessary to catch insns ending up in the epilogue delay list.
9007 (define_insn "*return_qi"
9008 [(set (match_operand:QI 0 "restore_operand" "")
9009 (match_operand:QI 1 "arith_operand" "rI"))
9014 if (! TARGET_ARCH64 && current_function_returns_struct)
9015 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9016 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9017 || IN_OR_GLOBAL_P (operands[1])))
9018 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9020 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9022 [(set_attr "type" "multi")])
9024 (define_insn "*return_hi"
9025 [(set (match_operand:HI 0 "restore_operand" "")
9026 (match_operand:HI 1 "arith_operand" "rI"))
9031 if (! TARGET_ARCH64 && current_function_returns_struct)
9032 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9033 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9034 || IN_OR_GLOBAL_P (operands[1])))
9035 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9037 return \"ret\;restore %%g0, %1, %Y0\";
9039 [(set_attr "type" "multi")])
9041 (define_insn "*return_si"
9042 [(set (match_operand:SI 0 "restore_operand" "")
9043 (match_operand:SI 1 "arith_operand" "rI"))
9048 if (! TARGET_ARCH64 && current_function_returns_struct)
9049 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9050 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9051 || IN_OR_GLOBAL_P (operands[1])))
9052 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9054 return \"ret\;restore %%g0, %1, %Y0\";
9056 [(set_attr "type" "multi")])
9058 ;; The following pattern is only generated by delayed-branch scheduling,
9059 ;; when the insn winds up in the epilogue. This can happen not only when
9060 ;; ! TARGET_FPU because we move complex types around by parts using
9062 (define_insn "*return_sf_no_fpu"
9063 [(set (match_operand:SF 0 "restore_operand" "=r")
9064 (match_operand:SF 1 "register_operand" "r"))
9069 if (! TARGET_ARCH64 && current_function_returns_struct)
9070 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9071 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9072 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9074 return \"ret\;restore %%g0, %1, %Y0\";
9076 [(set_attr "type" "multi")])
9078 (define_insn "*return_df_no_fpu"
9079 [(set (match_operand:DF 0 "restore_operand" "=r")
9080 (match_operand:DF 1 "register_operand" "r"))
9082 "! TARGET_EPILOGUE && TARGET_ARCH64"
9085 if (IN_OR_GLOBAL_P (operands[1]))
9086 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9088 return \"ret\;restore %%g0, %1, %Y0\";
9090 [(set_attr "type" "multi")])
9092 (define_insn "*return_addsi"
9093 [(set (match_operand:SI 0 "restore_operand" "")
9094 (plus:SI (match_operand:SI 1 "register_operand" "r")
9095 (match_operand:SI 2 "arith_operand" "rI")))
9100 if (! TARGET_ARCH64 && current_function_returns_struct)
9101 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9102 /* If operands are global or in registers, can use return */
9103 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9104 && (GET_CODE (operands[2]) == CONST_INT
9105 || IN_OR_GLOBAL_P (operands[2])))
9106 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9108 return \"ret\;restore %r1, %2, %Y0\";
9110 [(set_attr "type" "multi")])
9112 (define_insn "*return_losum_si"
9113 [(set (match_operand:SI 0 "restore_operand" "")
9114 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9115 (match_operand:SI 2 "immediate_operand" "in")))
9117 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9120 if (! TARGET_ARCH64 && current_function_returns_struct)
9121 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9122 /* If operands are global or in registers, can use return */
9123 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9124 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9126 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9128 [(set_attr "type" "multi")])
9130 (define_insn "*return_di"
9131 [(set (match_operand:DI 0 "restore_operand" "")
9132 (match_operand:DI 1 "arith_double_operand" "rHI"))
9134 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9135 "ret\;restore %%g0, %1, %Y0"
9136 [(set_attr "type" "multi")])
9138 (define_insn "*return_adddi"
9139 [(set (match_operand:DI 0 "restore_operand" "")
9140 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9141 (match_operand:DI 2 "arith_double_operand" "rHI")))
9143 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9144 "ret\;restore %r1, %2, %Y0"
9145 [(set_attr "type" "multi")])
9147 (define_insn "*return_losum_di"
9148 [(set (match_operand:DI 0 "restore_operand" "")
9149 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9150 (match_operand:DI 2 "immediate_operand" "in")))
9152 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9153 "ret\;restore %r1, %%lo(%a2), %Y0"
9154 [(set_attr "type" "multi")])
9156 ;; The following pattern is only generated by delayed-branch scheduling,
9157 ;; when the insn winds up in the epilogue.
9158 (define_insn "*return_sf"
9160 (match_operand:SF 0 "register_operand" "f"))
9163 "ret\;fmovs\\t%0, %%f0"
9164 [(set_attr "type" "multi")])
9166 ;; Now peepholes to do a call followed by a jump.
9169 [(parallel [(set (match_operand 0 "" "")
9170 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9171 (match_operand 2 "" "")))
9172 (clobber (reg:SI 15))])
9173 (set (pc) (label_ref (match_operand 3 "" "")))]
9174 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9175 && in_same_eh_region (insn, operands[3])
9176 && in_same_eh_region (insn, ins1)"
9177 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9180 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9181 (match_operand 1 "" ""))
9182 (clobber (reg:SI 15))])
9183 (set (pc) (label_ref (match_operand 2 "" "")))]
9184 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9185 && in_same_eh_region (insn, operands[2])
9186 && in_same_eh_region (insn, ins1)"
9187 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9190 [(parallel [(set (match_operand 0 "" "")
9191 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9192 (match_operand 2 "" "")))
9193 (clobber (reg:DI 15))])
9194 (set (pc) (label_ref (match_operand 3 "" "")))]
9196 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9197 && in_same_eh_region (insn, operands[3])
9198 && in_same_eh_region (insn, ins1)"
9199 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9202 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9203 (match_operand 1 "" ""))
9204 (clobber (reg:DI 15))])
9205 (set (pc) (label_ref (match_operand 2 "" "")))]
9207 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9208 && in_same_eh_region (insn, operands[2])
9209 && in_same_eh_region (insn, ins1)"
9210 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9212 ;; After a nonlocal goto, we need to restore the PIC register, but only
9213 ;; if we need it. So do nothing much here, but we'll check for this in
9216 ;; Make sure this unspec_volatile number agrees with finalize_pic.
9217 (define_insn "nonlocal_goto_receiver"
9218 [(unspec_volatile [(const_int 0)] 5)]
9221 [(set_attr "length" "0")])
9224 [(trap_if (const_int 1) (const_int 5))]
9227 [(set_attr "type" "misc")
9228 (set_attr "length" "1")])
9230 (define_expand "conditional_trap"
9231 [(trap_if (match_operator 0 "noov_compare_op"
9232 [(match_dup 2) (match_dup 3)])
9233 (match_operand:SI 1 "arith_operand" ""))]
9235 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9236 sparc_compare_op0, sparc_compare_op1);
9237 operands[3] = const0_rtx;")
9240 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9241 (match_operand:SI 1 "arith_operand" "rM"))]
9244 [(set_attr "type" "misc")
9245 (set_attr "length" "1")])
9248 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9249 (match_operand:SI 1 "arith_operand" "rM"))]
9252 [(set_attr "type" "misc")
9253 (set_attr "length" "1")])