1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92-98, 1999, 2000 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
28 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
33 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
39 ;; 11 embmedany_sethi, embmedany_brsum
40 ;; 13 embmedany_textuhi
41 ;; 14 embmedany_texthi
42 ;; 15 embmedany_textulo
43 ;; 16 embmedany_textlo
47 ;; UNSPEC_VOLATILE: 0 blockage
48 ;; 1 flush_register_windows
49 ;; 2 goto_handler_and_restore
50 ;; 3 goto_handler_and_restore_v9*
52 ;; 5 nonlocal_goto_receiver
55 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
56 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
57 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
58 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
59 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
61 ;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to
62 ;; test TARGET_LIVE_G0 if we have TARGET_ARCH64.
64 ;; Attribute for cpu type.
65 ;; These must match the values for enum processor_type in sparc.h.
66 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
67 (const (symbol_ref "sparc_cpu_attr")))
69 ;; Attribute for the instruction set.
70 ;; At present we only need to distinguish v9/!v9, but for clarity we
71 ;; test TARGET_V8 too.
72 (define_attr "isa" "v6,v8,v9,sparclet"
74 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
75 (symbol_ref "TARGET_V8") (const_string "v8")
76 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
77 (const_string "v6"))))
80 (define_attr "arch" "arch32bit,arch64bit"
82 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
83 (const_string "arch32bit"))))
85 ;; Whether -mlive-g0 is in effect.
86 (define_attr "live_g0" "no,yes"
88 (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")]
89 (const_string "no"))))
91 ;; Insn type. Used to default other attribute values.
93 ;; type "unary" insns have one input operand (1) and one output operand (0)
94 ;; type "binary" insns have two input operands (1,2) and one output (0)
95 ;; type "compare" insns have one or two input operands (0,1) and no output
96 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
99 "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"
100 (const_string "binary"))
102 ;; Set true if insn uses call-clobbered intermediate register.
103 (define_attr "use_clobbered" "false,true"
104 (if_then_else (and (eq_attr "type" "address")
105 (match_operand 0 "clobbered_register" ""))
106 (const_string "true")
107 (const_string "false")))
109 ;; Length (in # of insns).
110 (define_attr "length" ""
111 (cond [(eq_attr "type" "load,sload,fpload")
112 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
113 (const_int 2) (const_int 1))
115 (eq_attr "type" "store,fpstore")
116 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
117 (const_int 2) (const_int 1))
119 (eq_attr "type" "address") (const_int 2)
121 (eq_attr "type" "binary")
122 (if_then_else (ior (match_operand 2 "arith_operand" "")
123 (match_operand 2 "arith_double_operand" ""))
124 (const_int 1) (const_int 3))
126 (eq_attr "type" "multi") (const_int 2)
128 (eq_attr "type" "move,unary")
129 (if_then_else (ior (match_operand 1 "arith_operand" "")
130 (match_operand 1 "arith_double_operand" ""))
131 (const_int 1) (const_int 2))]
135 (define_asm_attributes
136 [(set_attr "length" "1")
137 (set_attr "type" "multi")])
139 ;; Attributes for instruction and branch scheduling
141 (define_attr "in_call_delay" "false,true"
142 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,return,multi")
143 (const_string "false")
144 (eq_attr "type" "load,fpload,store,fpstore")
145 (if_then_else (eq_attr "length" "1")
146 (const_string "true")
147 (const_string "false"))
148 (eq_attr "type" "address")
149 (if_then_else (eq_attr "use_clobbered" "false")
150 (const_string "true")
151 (const_string "false"))]
152 (if_then_else (eq_attr "length" "1")
153 (const_string "true")
154 (const_string "false"))))
156 (define_delay (eq_attr "type" "call")
157 [(eq_attr "in_call_delay" "true") (nil) (nil)])
159 (define_attr "leaf_function" "false,true"
160 (const (symbol_ref "current_function_uses_only_leaf_regs")))
162 (define_attr "eligible_for_return_delay" "false,true"
163 (symbol_ref "eligible_for_return_delay(insn)"))
165 (define_attr "in_return_delay" "false,true"
166 (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
167 (eq_attr "length" "1"))
168 (eq_attr "leaf_function" "false"))
169 (eq_attr "eligible_for_return_delay" "false"))
170 (const_string "true")
171 (const_string "false")))
173 (define_delay (and (eq_attr "type" "return")
174 (eq_attr "isa" "v9"))
175 [(eq_attr "in_return_delay" "true") (nil) (nil)])
177 ;; ??? Should implement the notion of predelay slots for floating point
178 ;; branches. This would allow us to remove the nop always inserted before
179 ;; a floating point branch.
181 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
182 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
183 ;; This is because doing so will add several pipeline stalls to the path
184 ;; that the load/store did not come from. Unfortunately, there is no way
185 ;; to prevent fill_eager_delay_slots from using load/store without completely
186 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
187 ;; because it prevents us from moving back the final store of inner loops.
189 (define_attr "in_branch_delay" "false,true"
190 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
191 (eq_attr "length" "1"))
192 (const_string "true")
193 (const_string "false")))
195 (define_attr "in_uncond_branch_delay" "false,true"
196 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
197 (eq_attr "length" "1"))
198 (const_string "true")
199 (const_string "false")))
201 (define_attr "in_annul_branch_delay" "false,true"
202 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
203 (eq_attr "length" "1"))
204 (const_string "true")
205 (const_string "false")))
207 (define_delay (eq_attr "type" "branch")
208 [(eq_attr "in_branch_delay" "true")
209 (nil) (eq_attr "in_annul_branch_delay" "true")])
211 (define_delay (eq_attr "type" "uncond_branch")
212 [(eq_attr "in_uncond_branch_delay" "true")
215 ;; Function units of the SPARC
217 ;; (define_function_unit {name} {num-units} {n-users} {test}
218 ;; {ready-delay} {issue-delay} [{conflict-list}])
221 ;; (Noted only for documentation; units that take one cycle do not need to
224 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
227 ;; (define_function_unit "alu" 1 0
228 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
230 ;; ---- cypress CY7C602 scheduling:
231 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
233 (define_function_unit "memory" 1 0
234 (and (eq_attr "cpu" "cypress")
235 (eq_attr "type" "load,sload,fpload"))
238 ;; SPARC has two floating-point units: the FP ALU,
239 ;; and the FP MUL/DIV/SQRT unit.
240 ;; Instruction timings on the CY7C602 are as follows
254 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
255 ;; More insns cause the chip to stall.
257 (define_function_unit "fp_alu" 1 0
258 (and (eq_attr "cpu" "cypress")
259 (eq_attr "type" "fp,fpmove"))
262 (define_function_unit "fp_mds" 1 0
263 (and (eq_attr "cpu" "cypress")
264 (eq_attr "type" "fpmul"))
267 (define_function_unit "fp_mds" 1 0
268 (and (eq_attr "cpu" "cypress")
269 (eq_attr "type" "fpdivs,fpdivd"))
272 (define_function_unit "fp_mds" 1 0
273 (and (eq_attr "cpu" "cypress")
274 (eq_attr "type" "fpsqrts,fpsqrtd"))
277 ;; ----- The TMS390Z55 scheduling
278 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
279 ;; one ld/st, one fp.
280 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
282 (define_function_unit "memory" 1 0
283 (and (eq_attr "cpu" "supersparc")
284 (eq_attr "type" "load,sload"))
287 (define_function_unit "memory" 1 0
288 (and (eq_attr "cpu" "supersparc")
289 (eq_attr "type" "fpload"))
292 (define_function_unit "memory" 1 0
293 (and (eq_attr "cpu" "supersparc")
294 (eq_attr "type" "store,fpstore"))
297 (define_function_unit "shift" 1 0
298 (and (eq_attr "cpu" "supersparc")
299 (eq_attr "type" "shift"))
302 ;; There are only two write ports to the integer register file
303 ;; A store also uses a write port
305 (define_function_unit "iwport" 2 0
306 (and (eq_attr "cpu" "supersparc")
307 (eq_attr "type" "load,sload,store,shift,ialu"))
310 ;; Timings; throughput/latency
311 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
319 (define_function_unit "fp_alu" 1 0
320 (and (eq_attr "cpu" "supersparc")
321 (eq_attr "type" "fp,fpmove,fpcmp"))
324 (define_function_unit "fp_mds" 1 0
325 (and (eq_attr "cpu" "supersparc")
326 (eq_attr "type" "fpmul"))
329 (define_function_unit "fp_mds" 1 0
330 (and (eq_attr "cpu" "supersparc")
331 (eq_attr "type" "fpdivs"))
334 (define_function_unit "fp_mds" 1 0
335 (and (eq_attr "cpu" "supersparc")
336 (eq_attr "type" "fpdivd"))
339 (define_function_unit "fp_mds" 1 0
340 (and (eq_attr "cpu" "supersparc")
341 (eq_attr "type" "fpsqrts,fpsqrtd"))
344 (define_function_unit "fp_mds" 1 0
345 (and (eq_attr "cpu" "supersparc")
346 (eq_attr "type" "imul"))
349 ;; ----- hypersparc/sparclite86x scheduling
350 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
351 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
352 ;; II/FF case is only when loading a 32 bit hi/lo constant
353 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
354 ;; Memory delivers its result in one cycle to IU
356 (define_function_unit "memory" 1 0
357 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
358 (eq_attr "type" "load,sload,fpload"))
361 (define_function_unit "memory" 1 0
362 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
363 (eq_attr "type" "store,fpstore"))
366 (define_function_unit "sparclite86x_branch" 1 0
367 (and (eq_attr "cpu" "sparclite86x")
368 (eq_attr "type" "branch"))
371 ;; integer multiply insns
372 (define_function_unit "sparclite86x_shift" 1 0
373 (and (eq_attr "cpu" "sparclite86x")
374 (eq_attr "type" "shift"))
377 (define_function_unit "fp_alu" 1 0
378 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
379 (eq_attr "type" "fp,fpmove,fpcmp"))
382 (define_function_unit "fp_mds" 1 0
383 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
384 (eq_attr "type" "fpmul"))
387 (define_function_unit "fp_mds" 1 0
388 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
389 (eq_attr "type" "fpdivs"))
392 (define_function_unit "fp_mds" 1 0
393 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
394 (eq_attr "type" "fpdivd"))
397 (define_function_unit "fp_mds" 1 0
398 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
399 (eq_attr "type" "fpsqrts,fpsqrtd"))
402 (define_function_unit "fp_mds" 1 0
403 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
404 (eq_attr "type" "imul"))
407 ;; ----- sparclet tsc701 scheduling
408 ;; The tsc701 issues 1 insn per cycle.
409 ;; Results may be written back out of order.
411 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
413 (define_function_unit "tsc701_load" 4 1
414 (and (eq_attr "cpu" "tsc701")
415 (eq_attr "type" "load,sload"))
418 ;; Stores take 2(?) extra cycles to complete.
419 ;; It is desirable to not have any memory operation in the following 2 cycles.
420 ;; (??? or 2 memory ops in the case of std).
422 (define_function_unit "tsc701_store" 1 0
423 (and (eq_attr "cpu" "tsc701")
424 (eq_attr "type" "store"))
426 [(eq_attr "type" "load,sload,store")])
428 ;; The multiply unit has a latency of 5.
429 (define_function_unit "tsc701_mul" 1 0
430 (and (eq_attr "cpu" "tsc701")
431 (eq_attr "type" "imul"))
434 ;; ----- The UltraSPARC-1 scheduling
435 ;; UltraSPARC has two integer units. Shift instructions can only execute
436 ;; on IE0. Condition code setting instructions, call, and jmpl (including
437 ;; the ret and retl pseudo-instructions) can only execute on IE1.
438 ;; Branch on register uses IE1, but branch on condition code does not.
439 ;; Conditional moves take 2 cycles. No other instruction can issue in the
440 ;; same cycle as a conditional move.
441 ;; Multiply and divide take many cycles during which no other instructions
443 ;; Memory delivers its result in two cycles (except for signed loads,
444 ;; which take one cycle more). One memory instruction can be issued per
447 (define_function_unit "memory" 1 0
448 (and (eq_attr "cpu" "ultrasparc")
449 (eq_attr "type" "load,fpload"))
452 (define_function_unit "memory" 1 0
453 (and (eq_attr "cpu" "ultrasparc")
454 (eq_attr "type" "sload"))
457 (define_function_unit "memory" 1 0
458 (and (eq_attr "cpu" "ultrasparc")
459 (eq_attr "type" "store,fpstore"))
462 (define_function_unit "ieuN" 2 0
463 (and (eq_attr "cpu" "ultrasparc")
464 (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,call_no_delay_slot,uncond_branch"))
467 (define_function_unit "ieu0" 1 0
468 (and (eq_attr "cpu" "ultrasparc")
469 (eq_attr "type" "shift"))
472 (define_function_unit "ieu0" 1 0
473 (and (eq_attr "cpu" "ultrasparc")
474 (eq_attr "type" "cmove"))
477 (define_function_unit "ieu1" 1 0
478 (and (eq_attr "cpu" "ultrasparc")
479 (eq_attr "type" "compare,call,call_no_delay_slot,uncond_branch"))
482 (define_function_unit "cti" 1 0
483 (and (eq_attr "cpu" "ultrasparc")
484 (eq_attr "type" "branch"))
487 ;; Timings; throughput/latency
488 ;; FMOV 1/1 fmov, fabs, fneg
490 ;; FADD 1/3 add/sub, format conv, compar
496 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
498 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
499 ;; use the FPM multiplier for final rounding 3 cycles before the
500 ;; end of their latency and we have no real way to model that.
502 ;; ??? This is really bogus because the timings really depend upon
503 ;; who uses the result. We should record who the user is with
504 ;; more descriptive 'type' attribute names and account for these
505 ;; issues in ultrasparc_adjust_cost.
507 (define_function_unit "fadd" 1 0
508 (and (eq_attr "cpu" "ultrasparc")
509 (eq_attr "type" "fpmove"))
512 (define_function_unit "fadd" 1 0
513 (and (eq_attr "cpu" "ultrasparc")
514 (eq_attr "type" "fpcmove"))
517 (define_function_unit "fadd" 1 0
518 (and (eq_attr "cpu" "ultrasparc")
519 (eq_attr "type" "fp"))
522 (define_function_unit "fadd" 1 0
523 (and (eq_attr "cpu" "ultrasparc")
524 (eq_attr "type" "fpcmp"))
527 (define_function_unit "fmul" 1 0
528 (and (eq_attr "cpu" "ultrasparc")
529 (eq_attr "type" "fpmul"))
532 (define_function_unit "fadd" 1 0
533 (and (eq_attr "cpu" "ultrasparc")
534 (eq_attr "type" "fpcmove"))
537 (define_function_unit "fdiv" 1 0
538 (and (eq_attr "cpu" "ultrasparc")
539 (eq_attr "type" "fpdivs"))
542 (define_function_unit "fdiv" 1 0
543 (and (eq_attr "cpu" "ultrasparc")
544 (eq_attr "type" "fpdivd"))
547 (define_function_unit "fdiv" 1 0
548 (and (eq_attr "cpu" "ultrasparc")
549 (eq_attr "type" "fpsqrts"))
552 (define_function_unit "fdiv" 1 0
553 (and (eq_attr "cpu" "ultrasparc")
554 (eq_attr "type" "fpsqrtd"))
557 ;; Compare instructions.
558 ;; This controls RTL generation and register allocation.
560 ;; We generate RTL for comparisons and branches by having the cmpxx
561 ;; patterns store away the operands. Then, the scc and bcc patterns
562 ;; emit RTL for both the compare and the branch.
564 ;; We do this because we want to generate different code for an sne and
565 ;; seq insn. In those cases, if the second operand of the compare is not
566 ;; const0_rtx, we want to compute the xor of the two operands and test
569 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
570 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
571 ;; insns that actually require more than one machine instruction.
573 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
575 (define_expand "cmpsi"
577 (compare:CC (match_operand:SI 0 "register_operand" "")
578 (match_operand:SI 1 "arith_operand" "")))]
582 sparc_compare_op0 = operands[0];
583 sparc_compare_op1 = operands[1];
587 (define_expand "cmpdi"
589 (compare:CCX (match_operand:DI 0 "register_operand" "")
590 (match_operand:DI 1 "arith_double_operand" "")))]
594 sparc_compare_op0 = operands[0];
595 sparc_compare_op1 = operands[1];
599 (define_expand "cmpsf"
600 ;; The 96 here isn't ever used by anyone.
602 (compare:CCFP (match_operand:SF 0 "register_operand" "")
603 (match_operand:SF 1 "register_operand" "")))]
607 sparc_compare_op0 = operands[0];
608 sparc_compare_op1 = operands[1];
612 (define_expand "cmpdf"
613 ;; The 96 here isn't ever used by anyone.
615 (compare:CCFP (match_operand:DF 0 "register_operand" "")
616 (match_operand:DF 1 "register_operand" "")))]
620 sparc_compare_op0 = operands[0];
621 sparc_compare_op1 = operands[1];
625 (define_expand "cmptf"
626 ;; The 96 here isn't ever used by anyone.
628 (compare:CCFP (match_operand:TF 0 "register_operand" "")
629 (match_operand:TF 1 "register_operand" "")))]
630 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
633 sparc_compare_op0 = operands[0];
634 sparc_compare_op1 = operands[1];
638 ;; Now the compare DEFINE_INSNs.
640 (define_insn "*cmpsi_insn"
642 (compare:CC (match_operand:SI 0 "register_operand" "r")
643 (match_operand:SI 1 "arith_operand" "rI")))]
646 [(set_attr "type" "compare")])
648 (define_insn "*cmpdi_sp64"
650 (compare:CCX (match_operand:DI 0 "register_operand" "r")
651 (match_operand:DI 1 "arith_double_operand" "rHI")))]
654 [(set_attr "type" "compare")])
656 (define_insn "*cmpsf_fpe"
657 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
658 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
659 (match_operand:SF 2 "register_operand" "f")))]
664 return \"fcmpes\\t%0, %1, %2\";
665 return \"fcmpes\\t%1, %2\";
667 [(set_attr "type" "fpcmp")])
669 (define_insn "*cmpdf_fpe"
670 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
671 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
672 (match_operand:DF 2 "register_operand" "e")))]
677 return \"fcmped\\t%0, %1, %2\";
678 return \"fcmped\\t%1, %2\";
680 [(set_attr "type" "fpcmp")])
682 (define_insn "*cmptf_fpe"
683 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
684 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
685 (match_operand:TF 2 "register_operand" "e")))]
686 "TARGET_FPU && TARGET_HARD_QUAD"
690 return \"fcmpeq\\t%0, %1, %2\";
691 return \"fcmpeq\\t%1, %2\";
693 [(set_attr "type" "fpcmp")])
695 (define_insn "*cmpsf_fp"
696 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
697 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
698 (match_operand:SF 2 "register_operand" "f")))]
703 return \"fcmps\\t%0, %1, %2\";
704 return \"fcmps\\t%1, %2\";
706 [(set_attr "type" "fpcmp")])
708 (define_insn "*cmpdf_fp"
709 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
710 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
711 (match_operand:DF 2 "register_operand" "e")))]
716 return \"fcmpd\\t%0, %1, %2\";
717 return \"fcmpd\\t%1, %2\";
719 [(set_attr "type" "fpcmp")])
721 (define_insn "*cmptf_fp"
722 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
723 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
724 (match_operand:TF 2 "register_operand" "e")))]
725 "TARGET_FPU && TARGET_HARD_QUAD"
729 return \"fcmpq\\t%0, %1, %2\";
730 return \"fcmpq\\t%1, %2\";
732 [(set_attr "type" "fpcmp")])
734 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
735 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
736 ;; the same code as v8 (the addx/subx method has more applications). The
737 ;; exception to this is "reg != 0" which can be done in one instruction on v9
738 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
741 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
742 ;; generate addcc/subcc instructions.
744 (define_expand "seqsi_special"
746 (xor:SI (match_operand:SI 1 "register_operand" "")
747 (match_operand:SI 2 "register_operand" "")))
748 (parallel [(set (match_operand:SI 0 "register_operand" "")
749 (eq:SI (match_dup 3) (const_int 0)))
750 (clobber (reg:CC 100))])]
752 "{ operands[3] = gen_reg_rtx (SImode); }")
754 (define_expand "seqdi_special"
756 (xor:DI (match_operand:DI 1 "register_operand" "")
757 (match_operand:DI 2 "register_operand" "")))
758 (set (match_operand:DI 0 "register_operand" "")
759 (eq:DI (match_dup 3) (const_int 0)))]
761 "{ operands[3] = gen_reg_rtx (DImode); }")
763 (define_expand "snesi_special"
765 (xor:SI (match_operand:SI 1 "register_operand" "")
766 (match_operand:SI 2 "register_operand" "")))
767 (parallel [(set (match_operand:SI 0 "register_operand" "")
768 (ne:SI (match_dup 3) (const_int 0)))
769 (clobber (reg:CC 100))])]
771 "{ operands[3] = gen_reg_rtx (SImode); }")
773 (define_expand "snedi_special"
775 (xor:DI (match_operand:DI 1 "register_operand" "")
776 (match_operand:DI 2 "register_operand" "")))
777 (set (match_operand:DI 0 "register_operand" "")
778 (ne:DI (match_dup 3) (const_int 0)))]
780 "{ operands[3] = gen_reg_rtx (DImode); }")
782 (define_expand "seqdi_special_trunc"
784 (xor:DI (match_operand:DI 1 "register_operand" "")
785 (match_operand:DI 2 "register_operand" "")))
786 (set (match_operand:SI 0 "register_operand" "")
787 (eq:SI (match_dup 3) (const_int 0)))]
789 "{ operands[3] = gen_reg_rtx (DImode); }")
791 (define_expand "snedi_special_trunc"
793 (xor:DI (match_operand:DI 1 "register_operand" "")
794 (match_operand:DI 2 "register_operand" "")))
795 (set (match_operand:SI 0 "register_operand" "")
796 (ne:SI (match_dup 3) (const_int 0)))]
798 "{ operands[3] = gen_reg_rtx (DImode); }")
800 (define_expand "seqsi_special_extend"
802 (xor:SI (match_operand:SI 1 "register_operand" "")
803 (match_operand:SI 2 "register_operand" "")))
804 (parallel [(set (match_operand:DI 0 "register_operand" "")
805 (eq:DI (match_dup 3) (const_int 0)))
806 (clobber (reg:CC 100))])]
808 "{ operands[3] = gen_reg_rtx (SImode); }")
810 (define_expand "snesi_special_extend"
812 (xor:SI (match_operand:SI 1 "register_operand" "")
813 (match_operand:SI 2 "register_operand" "")))
814 (parallel [(set (match_operand:DI 0 "register_operand" "")
815 (ne:DI (match_dup 3) (const_int 0)))
816 (clobber (reg:CC 100))])]
818 "{ operands[3] = gen_reg_rtx (SImode); }")
820 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
821 ;; However, the code handles both SImode and DImode.
823 [(set (match_operand:SI 0 "intreg_operand" "")
824 (eq:SI (match_dup 1) (const_int 0)))]
828 if (GET_MODE (sparc_compare_op0) == SImode)
832 if (GET_MODE (operands[0]) == SImode)
833 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
835 else if (! TARGET_ARCH64)
838 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
843 else if (GET_MODE (sparc_compare_op0) == DImode)
849 else if (GET_MODE (operands[0]) == SImode)
850 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
853 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
858 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
860 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
861 emit_jump_insn (gen_sne (operands[0]));
866 if (gen_v9_scc (EQ, operands))
873 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
874 ;; However, the code handles both SImode and DImode.
876 [(set (match_operand:SI 0 "intreg_operand" "")
877 (ne:SI (match_dup 1) (const_int 0)))]
881 if (GET_MODE (sparc_compare_op0) == SImode)
885 if (GET_MODE (operands[0]) == SImode)
886 pat = gen_snesi_special (operands[0], sparc_compare_op0,
888 else if (! TARGET_ARCH64)
891 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
896 else if (GET_MODE (sparc_compare_op0) == DImode)
902 else if (GET_MODE (operands[0]) == SImode)
903 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
906 pat = gen_snedi_special (operands[0], sparc_compare_op0,
911 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
913 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
914 emit_jump_insn (gen_sne (operands[0]));
919 if (gen_v9_scc (NE, operands))
927 [(set (match_operand:SI 0 "intreg_operand" "")
928 (gt:SI (match_dup 1) (const_int 0)))]
932 if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
934 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
935 emit_jump_insn (gen_sne (operands[0]));
940 if (gen_v9_scc (GT, operands))
948 [(set (match_operand:SI 0 "intreg_operand" "")
949 (lt:SI (match_dup 1) (const_int 0)))]
953 if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
955 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
956 emit_jump_insn (gen_sne (operands[0]));
961 if (gen_v9_scc (LT, operands))
969 [(set (match_operand:SI 0 "intreg_operand" "")
970 (ge:SI (match_dup 1) (const_int 0)))]
974 if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
976 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
977 emit_jump_insn (gen_sne (operands[0]));
982 if (gen_v9_scc (GE, operands))
990 [(set (match_operand:SI 0 "intreg_operand" "")
991 (le:SI (match_dup 1) (const_int 0)))]
995 if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
997 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
998 emit_jump_insn (gen_sne (operands[0]));
1003 if (gen_v9_scc (LE, operands))
1010 (define_expand "sgtu"
1011 [(set (match_operand:SI 0 "intreg_operand" "")
1012 (gtu:SI (match_dup 1) (const_int 0)))]
1020 /* We can do ltu easily, so if both operands are registers, swap them and
1022 if ((GET_CODE (sparc_compare_op0) == REG
1023 || GET_CODE (sparc_compare_op0) == SUBREG)
1024 && (GET_CODE (sparc_compare_op1) == REG
1025 || GET_CODE (sparc_compare_op1) == SUBREG))
1027 tem = sparc_compare_op0;
1028 sparc_compare_op0 = sparc_compare_op1;
1029 sparc_compare_op1 = tem;
1030 pat = gen_sltu (operands[0]);
1031 if (pat == NULL_RTX)
1039 if (gen_v9_scc (GTU, operands))
1045 (define_expand "sltu"
1046 [(set (match_operand:SI 0 "intreg_operand" "")
1047 (ltu:SI (match_dup 1) (const_int 0)))]
1053 if (gen_v9_scc (LTU, operands))
1056 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1059 (define_expand "sgeu"
1060 [(set (match_operand:SI 0 "intreg_operand" "")
1061 (geu:SI (match_dup 1) (const_int 0)))]
1067 if (gen_v9_scc (GEU, operands))
1070 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1073 (define_expand "sleu"
1074 [(set (match_operand:SI 0 "intreg_operand" "")
1075 (leu:SI (match_dup 1) (const_int 0)))]
1083 /* We can do geu easily, so if both operands are registers, swap them and
1085 if ((GET_CODE (sparc_compare_op0) == REG
1086 || GET_CODE (sparc_compare_op0) == SUBREG)
1087 && (GET_CODE (sparc_compare_op1) == REG
1088 || GET_CODE (sparc_compare_op1) == SUBREG))
1090 tem = sparc_compare_op0;
1091 sparc_compare_op0 = sparc_compare_op1;
1092 sparc_compare_op1 = tem;
1093 pat = gen_sgeu (operands[0]);
1094 if (pat == NULL_RTX)
1102 if (gen_v9_scc (LEU, operands))
1108 ;; Now the DEFINE_INSNs for the scc cases.
1110 ;; The SEQ and SNE patterns are special because they can be done
1111 ;; without any branching and do not involve a COMPARE. We want
1112 ;; them to always use the splitz below so the results can be
1115 (define_insn "*snesi_zero"
1116 [(set (match_operand:SI 0 "register_operand" "=r")
1117 (ne:SI (match_operand:SI 1 "register_operand" "r")
1119 (clobber (reg:CC 100))]
1122 [(set_attr "length" "2")])
1125 [(set (match_operand:SI 0 "register_operand" "")
1126 (ne:SI (match_operand:SI 1 "register_operand" "")
1128 (clobber (reg:CC 100))]
1130 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1132 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1135 (define_insn "*neg_snesi_zero"
1136 [(set (match_operand:SI 0 "register_operand" "=r")
1137 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1139 (clobber (reg:CC 100))]
1142 [(set_attr "length" "2")])
1145 [(set (match_operand:SI 0 "register_operand" "")
1146 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1148 (clobber (reg:CC 100))]
1150 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1152 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1155 (define_insn "*snesi_zero_extend"
1156 [(set (match_operand:DI 0 "register_operand" "=r")
1157 (ne:DI (match_operand:SI 1 "register_operand" "r")
1159 (clobber (reg:CC 100))]
1162 [(set_attr "type" "unary")
1163 (set_attr "length" "2")])
1166 [(set (match_operand:DI 0 "register_operand" "")
1167 (ne:DI (match_operand:SI 1 "register_operand" "")
1169 (clobber (reg:CC 100))]
1171 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1173 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1175 (ltu:SI (reg:CC_NOOV 100)
1179 (define_insn "*snedi_zero"
1180 [(set (match_operand:DI 0 "register_operand" "=&r")
1181 (ne:DI (match_operand:DI 1 "register_operand" "r")
1185 [(set_attr "type" "cmove")
1186 (set_attr "length" "2")])
1189 [(set (match_operand:DI 0 "register_operand" "")
1190 (ne:DI (match_operand:DI 1 "register_operand" "")
1193 [(set (match_dup 0) (const_int 0))
1194 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1200 (define_insn "*neg_snedi_zero"
1201 [(set (match_operand:DI 0 "register_operand" "=&r")
1202 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1206 [(set_attr "type" "cmove")
1207 (set_attr "length" "2")])
1210 [(set (match_operand:DI 0 "register_operand" "")
1211 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1214 [(set (match_dup 0) (const_int 0))
1215 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1221 (define_insn "*snedi_zero_trunc"
1222 [(set (match_operand:SI 0 "register_operand" "=&r")
1223 (ne:SI (match_operand:DI 1 "register_operand" "r")
1227 [(set_attr "type" "cmove")
1228 (set_attr "length" "2")])
1231 [(set (match_operand:SI 0 "register_operand" "")
1232 (ne:SI (match_operand:DI 1 "register_operand" "")
1235 [(set (match_dup 0) (const_int 0))
1236 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1242 (define_insn "*seqsi_zero"
1243 [(set (match_operand:SI 0 "register_operand" "=r")
1244 (eq:SI (match_operand:SI 1 "register_operand" "r")
1246 (clobber (reg:CC 100))]
1249 [(set_attr "length" "2")])
1252 [(set (match_operand:SI 0 "register_operand" "")
1253 (eq:SI (match_operand:SI 1 "register_operand" "")
1255 (clobber (reg:CC 100))]
1257 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1259 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1262 (define_insn "*neg_seqsi_zero"
1263 [(set (match_operand:SI 0 "register_operand" "=r")
1264 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1266 (clobber (reg:CC 100))]
1269 [(set_attr "length" "2")])
1272 [(set (match_operand:SI 0 "register_operand" "")
1273 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1275 (clobber (reg:CC 100))]
1277 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1279 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1282 (define_insn "*seqsi_zero_extend"
1283 [(set (match_operand:DI 0 "register_operand" "=r")
1284 (eq:DI (match_operand:SI 1 "register_operand" "r")
1286 (clobber (reg:CC 100))]
1289 [(set_attr "type" "unary")
1290 (set_attr "length" "2")])
1293 [(set (match_operand:DI 0 "register_operand" "")
1294 (eq:DI (match_operand:SI 1 "register_operand" "")
1296 (clobber (reg:CC 100))]
1298 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1300 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1302 (ltu:SI (reg:CC_NOOV 100)
1306 (define_insn "*seqdi_zero"
1307 [(set (match_operand:DI 0 "register_operand" "=&r")
1308 (eq:DI (match_operand:DI 1 "register_operand" "r")
1312 [(set_attr "type" "cmove")
1313 (set_attr "length" "2")])
1316 [(set (match_operand:DI 0 "register_operand" "")
1317 (eq:DI (match_operand:DI 1 "register_operand" "")
1320 [(set (match_dup 0) (const_int 0))
1321 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1327 (define_insn "*neg_seqdi_zero"
1328 [(set (match_operand:DI 0 "register_operand" "=&r")
1329 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1333 [(set_attr "type" "cmove")
1334 (set_attr "length" "2")])
1337 [(set (match_operand:DI 0 "register_operand" "")
1338 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1341 [(set (match_dup 0) (const_int 0))
1342 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1348 (define_insn "*seqdi_zero_trunc"
1349 [(set (match_operand:SI 0 "register_operand" "=&r")
1350 (eq:SI (match_operand:DI 1 "register_operand" "r")
1354 [(set_attr "type" "cmove")
1355 (set_attr "length" "2")])
1358 [(set (match_operand:SI 0 "register_operand" "")
1359 (eq:SI (match_operand:DI 1 "register_operand" "")
1362 [(set (match_dup 0) (const_int 0))
1363 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1369 ;; We can also do (x + (i == 0)) and related, so put them in.
1370 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1373 (define_insn "*x_plus_i_ne_0"
1374 [(set (match_operand:SI 0 "register_operand" "=r")
1375 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1377 (match_operand:SI 2 "register_operand" "r")))
1378 (clobber (reg:CC 100))]
1381 [(set_attr "length" "2")])
1384 [(set (match_operand:SI 0 "register_operand" "")
1385 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1387 (match_operand:SI 2 "register_operand" "")))
1388 (clobber (reg:CC 100))]
1390 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1392 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1396 (define_insn "*x_minus_i_ne_0"
1397 [(set (match_operand:SI 0 "register_operand" "=r")
1398 (minus:SI (match_operand:SI 2 "register_operand" "r")
1399 (ne:SI (match_operand:SI 1 "register_operand" "r")
1401 (clobber (reg:CC 100))]
1404 [(set_attr "length" "2")])
1407 [(set (match_operand:SI 0 "register_operand" "")
1408 (minus:SI (match_operand:SI 2 "register_operand" "")
1409 (ne:SI (match_operand:SI 1 "register_operand" "")
1411 (clobber (reg:CC 100))]
1413 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1415 (set (match_dup 0) (minus:SI (match_dup 2)
1416 (ltu:SI (reg:CC 100) (const_int 0))))]
1419 (define_insn "*x_plus_i_eq_0"
1420 [(set (match_operand:SI 0 "register_operand" "=r")
1421 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1423 (match_operand:SI 2 "register_operand" "r")))
1424 (clobber (reg:CC 100))]
1427 [(set_attr "length" "2")])
1430 [(set (match_operand:SI 0 "register_operand" "")
1431 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1433 (match_operand:SI 2 "register_operand" "")))
1434 (clobber (reg:CC 100))]
1436 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1438 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1442 (define_insn "*x_minus_i_eq_0"
1443 [(set (match_operand:SI 0 "register_operand" "=r")
1444 (minus:SI (match_operand:SI 2 "register_operand" "r")
1445 (eq:SI (match_operand:SI 1 "register_operand" "r")
1447 (clobber (reg:CC 100))]
1450 [(set_attr "length" "2")])
1453 [(set (match_operand:SI 0 "register_operand" "")
1454 (minus:SI (match_operand:SI 2 "register_operand" "")
1455 (eq:SI (match_operand:SI 1 "register_operand" "")
1457 (clobber (reg:CC 100))]
1459 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1461 (set (match_dup 0) (minus:SI (match_dup 2)
1462 (geu:SI (reg:CC 100) (const_int 0))))]
1465 ;; We can also do GEU and LTU directly, but these operate after a compare.
1466 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1469 (define_insn "*sltu_insn"
1470 [(set (match_operand:SI 0 "register_operand" "=r")
1471 (ltu:SI (reg:CC 100) (const_int 0)))]
1473 "addx\\t%%g0, 0, %0"
1474 [(set_attr "type" "misc")
1475 (set_attr "length" "1")])
1477 (define_insn "*neg_sltu_insn"
1478 [(set (match_operand:SI 0 "register_operand" "=r")
1479 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1481 "subx\\t%%g0, 0, %0"
1482 [(set_attr "type" "misc")
1483 (set_attr "length" "1")])
1485 ;; ??? Combine should canonicalize these next two to the same pattern.
1486 (define_insn "*neg_sltu_minus_x"
1487 [(set (match_operand:SI 0 "register_operand" "=r")
1488 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1489 (match_operand:SI 1 "arith_operand" "rI")))]
1491 "subx\\t%%g0, %1, %0"
1492 [(set_attr "type" "misc")
1493 (set_attr "length" "1")])
1495 (define_insn "*neg_sltu_plus_x"
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1498 (match_operand:SI 1 "arith_operand" "rI"))))]
1500 "subx\\t%%g0, %1, %0"
1501 [(set_attr "type" "misc")
1502 (set_attr "length" "1")])
1504 (define_insn "*sgeu_insn"
1505 [(set (match_operand:SI 0 "register_operand" "=r")
1506 (geu:SI (reg:CC 100) (const_int 0)))]
1508 "subx\\t%%g0, -1, %0"
1509 [(set_attr "type" "misc")
1510 (set_attr "length" "1")])
1512 (define_insn "*neg_sgeu_insn"
1513 [(set (match_operand:SI 0 "register_operand" "=r")
1514 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1516 "addx\\t%%g0, -1, %0"
1517 [(set_attr "type" "misc")
1518 (set_attr "length" "1")])
1520 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1521 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1524 (define_insn "*sltu_plus_x"
1525 [(set (match_operand:SI 0 "register_operand" "=r")
1526 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1527 (match_operand:SI 1 "arith_operand" "rI")))]
1529 "addx\\t%%g0, %1, %0"
1530 [(set_attr "type" "misc")
1531 (set_attr "length" "1")])
1533 (define_insn "*sltu_plus_x_plus_y"
1534 [(set (match_operand:SI 0 "register_operand" "=r")
1535 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1536 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1537 (match_operand:SI 2 "arith_operand" "rI"))))]
1540 [(set_attr "type" "misc")
1541 (set_attr "length" "1")])
1543 (define_insn "*x_minus_sltu"
1544 [(set (match_operand:SI 0 "register_operand" "=r")
1545 (minus:SI (match_operand:SI 1 "register_operand" "r")
1546 (ltu:SI (reg:CC 100) (const_int 0))))]
1549 [(set_attr "type" "misc")
1550 (set_attr "length" "1")])
1552 ;; ??? Combine should canonicalize these next two to the same pattern.
1553 (define_insn "*x_minus_y_minus_sltu"
1554 [(set (match_operand:SI 0 "register_operand" "=r")
1555 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1556 (match_operand:SI 2 "arith_operand" "rI"))
1557 (ltu:SI (reg:CC 100) (const_int 0))))]
1559 "subx\\t%r1, %2, %0"
1560 [(set_attr "type" "misc")
1561 (set_attr "length" "1")])
1563 (define_insn "*x_minus_sltu_plus_y"
1564 [(set (match_operand:SI 0 "register_operand" "=r")
1565 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1566 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1567 (match_operand:SI 2 "arith_operand" "rI"))))]
1569 "subx\\t%r1, %2, %0"
1570 [(set_attr "type" "misc")
1571 (set_attr "length" "1")])
1573 (define_insn "*sgeu_plus_x"
1574 [(set (match_operand:SI 0 "register_operand" "=r")
1575 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1576 (match_operand:SI 1 "register_operand" "r")))]
1579 [(set_attr "type" "misc")
1580 (set_attr "length" "1")])
1582 (define_insn "*x_minus_sgeu"
1583 [(set (match_operand:SI 0 "register_operand" "=r")
1584 (minus:SI (match_operand:SI 1 "register_operand" "r")
1585 (geu:SI (reg:CC 100) (const_int 0))))]
1588 [(set_attr "type" "misc")
1589 (set_attr "length" "1")])
1592 [(set (match_operand:SI 0 "register_operand" "=r")
1593 (match_operator:SI 2 "noov_compare_op"
1594 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1596 ;; 32 bit LTU/GEU are better implemented using addx/subx
1597 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1598 && (GET_MODE (operands[1]) == CCXmode
1599 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1600 [(set (match_dup 0) (const_int 0))
1602 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1608 ;; These control RTL generation for conditional jump insns
1610 ;; The quad-word fp compare library routines all return nonzero to indicate
1611 ;; true, which is different from the equivalent libgcc routines, so we must
1612 ;; handle them specially here.
1614 (define_expand "beq"
1616 (if_then_else (eq (match_dup 1) (const_int 0))
1617 (label_ref (match_operand 0 "" ""))
1622 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1623 && GET_CODE (sparc_compare_op0) == REG
1624 && GET_MODE (sparc_compare_op0) == DImode)
1626 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1629 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1631 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1632 emit_jump_insn (gen_bne (operands[0]));
1635 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1638 (define_expand "bne"
1640 (if_then_else (ne (match_dup 1) (const_int 0))
1641 (label_ref (match_operand 0 "" ""))
1646 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1647 && GET_CODE (sparc_compare_op0) == REG
1648 && GET_MODE (sparc_compare_op0) == DImode)
1650 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1653 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1655 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1656 emit_jump_insn (gen_bne (operands[0]));
1659 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1662 (define_expand "bgt"
1664 (if_then_else (gt (match_dup 1) (const_int 0))
1665 (label_ref (match_operand 0 "" ""))
1670 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1671 && GET_CODE (sparc_compare_op0) == REG
1672 && GET_MODE (sparc_compare_op0) == DImode)
1674 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1677 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1679 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1680 emit_jump_insn (gen_bne (operands[0]));
1683 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1686 (define_expand "bgtu"
1688 (if_then_else (gtu (match_dup 1) (const_int 0))
1689 (label_ref (match_operand 0 "" ""))
1693 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1696 (define_expand "blt"
1698 (if_then_else (lt (match_dup 1) (const_int 0))
1699 (label_ref (match_operand 0 "" ""))
1704 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1705 && GET_CODE (sparc_compare_op0) == REG
1706 && GET_MODE (sparc_compare_op0) == DImode)
1708 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1711 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1713 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1714 emit_jump_insn (gen_bne (operands[0]));
1717 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1720 (define_expand "bltu"
1722 (if_then_else (ltu (match_dup 1) (const_int 0))
1723 (label_ref (match_operand 0 "" ""))
1727 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1730 (define_expand "bge"
1732 (if_then_else (ge (match_dup 1) (const_int 0))
1733 (label_ref (match_operand 0 "" ""))
1738 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1739 && GET_CODE (sparc_compare_op0) == REG
1740 && GET_MODE (sparc_compare_op0) == DImode)
1742 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1745 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1747 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1748 emit_jump_insn (gen_bne (operands[0]));
1751 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1754 (define_expand "bgeu"
1756 (if_then_else (geu (match_dup 1) (const_int 0))
1757 (label_ref (match_operand 0 "" ""))
1761 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1764 (define_expand "ble"
1766 (if_then_else (le (match_dup 1) (const_int 0))
1767 (label_ref (match_operand 0 "" ""))
1772 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1773 && GET_CODE (sparc_compare_op0) == REG
1774 && GET_MODE (sparc_compare_op0) == DImode)
1776 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1779 else if (GET_MODE (sparc_compare_op0) == TFmode && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1781 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1782 emit_jump_insn (gen_bne (operands[0]));
1785 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1788 (define_expand "bleu"
1790 (if_then_else (leu (match_dup 1) (const_int 0))
1791 (label_ref (match_operand 0 "" ""))
1795 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1798 (define_expand "bunordered"
1800 (if_then_else (unordered (match_dup 1) (const_int 0))
1801 (label_ref (match_operand 0 "" ""))
1806 if (GET_MODE (sparc_compare_op0) == TFmode
1807 && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1809 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1811 emit_jump_insn (gen_bne (operands[0]));
1814 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1818 (define_expand "bordered"
1820 (if_then_else (ordered (match_dup 1) (const_int 0))
1821 (label_ref (match_operand 0 "" ""))
1826 if (GET_MODE (sparc_compare_op0) == TFmode
1827 && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1829 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1830 emit_jump_insn (gen_bne (operands[0]));
1833 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1837 (define_expand "bungt"
1839 (if_then_else (ungt (match_dup 1) (const_int 0))
1840 (label_ref (match_operand 0 "" ""))
1845 if (GET_MODE (sparc_compare_op0) == TFmode
1846 && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1848 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1849 emit_jump_insn (gen_bne (operands[0]));
1852 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1855 (define_expand "bunlt"
1857 (if_then_else (unlt (match_dup 1) (const_int 0))
1858 (label_ref (match_operand 0 "" ""))
1863 if (GET_MODE (sparc_compare_op0) == TFmode
1864 && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1866 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1867 emit_jump_insn (gen_bne (operands[0]));
1870 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1873 (define_expand "buneq"
1875 (if_then_else (uneq (match_dup 1) (const_int 0))
1876 (label_ref (match_operand 0 "" ""))
1881 if (GET_MODE (sparc_compare_op0) == TFmode
1882 && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1884 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1885 emit_jump_insn (gen_bne (operands[0]));
1888 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1891 (define_expand "bunge"
1893 (if_then_else (unge (match_dup 1) (const_int 0))
1894 (label_ref (match_operand 0 "" ""))
1899 if (GET_MODE (sparc_compare_op0) == TFmode
1900 && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1902 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1903 emit_jump_insn (gen_bne (operands[0]));
1906 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1909 (define_expand "bunle"
1911 (if_then_else (unle (match_dup 1) (const_int 0))
1912 (label_ref (match_operand 0 "" ""))
1917 if (GET_MODE (sparc_compare_op0) == TFmode
1918 && TARGET_ARCH64 && ! TARGET_HARD_QUAD)
1920 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1921 emit_jump_insn (gen_bne (operands[0]));
1924 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1927 ;; Now match both normal and inverted jump.
1929 ;; XXX fpcmp nop braindamage
1930 (define_insn "*normal_branch"
1932 (if_then_else (match_operator 0 "noov_compare_op"
1933 [(reg 100) (const_int 0)])
1934 (label_ref (match_operand 1 "" ""))
1939 return output_cbranch (operands[0], 1, 0,
1940 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1941 ! final_sequence, insn);
1943 [(set_attr "type" "branch")])
1945 ;; XXX fpcmp nop braindamage
1946 (define_insn "*inverted_branch"
1948 (if_then_else (match_operator 0 "noov_compare_op"
1949 [(reg 100) (const_int 0)])
1951 (label_ref (match_operand 1 "" ""))))]
1955 return output_cbranch (operands[0], 1, 1,
1956 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1957 ! final_sequence, insn);
1959 [(set_attr "type" "branch")])
1961 ;; XXX fpcmp nop braindamage
1962 (define_insn "*normal_fp_branch"
1964 (if_then_else (match_operator 1 "comparison_operator"
1965 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1967 (label_ref (match_operand 2 "" ""))
1972 return output_cbranch (operands[1], 2, 0,
1973 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1974 ! final_sequence, insn);
1976 [(set_attr "type" "branch")])
1978 ;; XXX fpcmp nop braindamage
1979 (define_insn "*inverted_fp_branch"
1981 (if_then_else (match_operator 1 "comparison_operator"
1982 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1985 (label_ref (match_operand 2 "" ""))))]
1989 return output_cbranch (operands[1], 2, 1,
1990 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1991 ! final_sequence, insn);
1993 [(set_attr "type" "branch")])
1995 ;; XXX fpcmp nop braindamage
1996 (define_insn "*normal_fpe_branch"
1998 (if_then_else (match_operator 1 "comparison_operator"
1999 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2001 (label_ref (match_operand 2 "" ""))
2006 return output_cbranch (operands[1], 2, 0,
2007 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2008 ! final_sequence, insn);
2010 [(set_attr "type" "branch")])
2012 ;; XXX fpcmp nop braindamage
2013 (define_insn "*inverted_fpe_branch"
2015 (if_then_else (match_operator 1 "comparison_operator"
2016 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2019 (label_ref (match_operand 2 "" ""))))]
2023 return output_cbranch (operands[1], 2, 1,
2024 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2025 ! final_sequence, insn);
2027 [(set_attr "type" "branch")])
2029 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2030 ;; in the architecture.
2032 ;; There are no 32 bit brreg insns.
2035 (define_insn "*normal_int_branch_sp64"
2037 (if_then_else (match_operator 0 "v9_regcmp_op"
2038 [(match_operand:DI 1 "register_operand" "r")
2040 (label_ref (match_operand 2 "" ""))
2045 return output_v9branch (operands[0], 1, 2, 0,
2046 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2047 ! final_sequence, insn);
2049 [(set_attr "type" "branch")])
2052 (define_insn "*inverted_int_branch_sp64"
2054 (if_then_else (match_operator 0 "v9_regcmp_op"
2055 [(match_operand:DI 1 "register_operand" "r")
2058 (label_ref (match_operand 2 "" ""))))]
2062 return output_v9branch (operands[0], 1, 2, 1,
2063 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2064 ! final_sequence, insn);
2066 [(set_attr "type" "branch")])
2068 ;; Load program counter insns.
2070 (define_insn "get_pc"
2071 [(clobber (reg:SI 15))
2072 (set (match_operand 0 "register_operand" "=r")
2073 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2074 "flag_pic && REGNO (operands[0]) == 23"
2075 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2076 [(set_attr "length" "3")])
2078 ;; Currently unused...
2079 ;; (define_insn "get_pc_via_rdpc"
2080 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2083 ;; [(set_attr "type" "move")])
2086 ;; Move instructions
2088 (define_expand "movqi"
2089 [(set (match_operand:QI 0 "general_operand" "")
2090 (match_operand:QI 1 "general_operand" ""))]
2094 /* Working with CONST_INTs is easier, so convert
2095 a double if needed. */
2096 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2098 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2100 else if (GET_CODE (operands[1]) == CONST_INT)
2102 /* And further, we know for all QI cases that only the
2103 low byte is significant, which we can always process
2104 in a single insn. So mask it now. */
2105 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2108 /* Handle sets of MEM first. */
2109 if (GET_CODE (operands[0]) == MEM)
2111 /* This checks TARGET_LIVE_G0 for us. */
2112 if (reg_or_0_operand (operands[1], QImode))
2115 if (! reload_in_progress)
2117 operands[0] = validize_mem (operands[0]);
2118 operands[1] = force_reg (QImode, operands[1]);
2122 /* Fixup PIC cases. */
2125 if (CONSTANT_P (operands[1])
2126 && pic_address_needs_scratch (operands[1]))
2127 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2129 if (symbolic_operand (operands[1], QImode))
2131 operands[1] = legitimize_pic_address (operands[1],
2133 (reload_in_progress ?
2140 /* All QI constants require only one insn, so proceed. */
2146 (define_insn "*movqi_insn"
2147 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2148 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2149 "(register_operand (operands[0], QImode)
2150 || reg_or_0_operand (operands[1], QImode))"
2155 [(set_attr "type" "move,load,store")
2156 (set_attr "length" "1")])
2158 (define_expand "movhi"
2159 [(set (match_operand:HI 0 "general_operand" "")
2160 (match_operand:HI 1 "general_operand" ""))]
2164 /* Working with CONST_INTs is easier, so convert
2165 a double if needed. */
2166 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2167 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2169 /* Handle sets of MEM first. */
2170 if (GET_CODE (operands[0]) == MEM)
2172 /* This checks TARGET_LIVE_G0 for us. */
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 /* This checks TARGET_LIVE_G0 for us. */
2261 if (reg_or_0_operand (operands[1], SImode))
2264 if (! reload_in_progress)
2266 operands[0] = validize_mem (operands[0]);
2267 operands[1] = force_reg (SImode, operands[1]);
2271 /* Fixup PIC cases. */
2274 if (CONSTANT_P (operands[1])
2275 && pic_address_needs_scratch (operands[1]))
2276 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2278 if (GET_CODE (operands[1]) == LABEL_REF)
2281 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2285 if (symbolic_operand (operands[1], SImode))
2287 operands[1] = legitimize_pic_address (operands[1],
2289 (reload_in_progress ?
2296 /* If we are trying to toss an integer constant into the
2297 FPU registers, force it into memory. */
2298 if (GET_CODE (operands[0]) == REG
2299 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2300 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2301 && CONSTANT_P (operands[1]))
2302 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2305 /* This makes sure we will not get rematched due to splittage. */
2306 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2308 else if (CONSTANT_P (operands[1])
2309 && GET_CODE (operands[1]) != HIGH
2310 && GET_CODE (operands[1]) != LO_SUM)
2312 sparc_emit_set_const32 (operands[0], operands[1]);
2319 ;; Special LIVE_G0 pattern to obtain zero in a register.
2320 (define_insn "*movsi_zero_liveg0"
2321 [(set (match_operand:SI 0 "register_operand" "=r")
2322 (match_operand:SI 1 "zero_operand" "J"))]
2325 [(set_attr "type" "binary")
2326 (set_attr "length" "1")])
2328 ;; This is needed to show CSE exactly which bits are set
2329 ;; in a 64-bit register by sethi instructions.
2330 (define_insn "*movsi_const64_special"
2331 [(set (match_operand:SI 0 "register_operand" "=r")
2332 (match_operand:SI 1 "const64_high_operand" ""))]
2334 "sethi\\t%%hi(%a1), %0"
2335 [(set_attr "type" "move")
2336 (set_attr "length" "1")])
2338 (define_insn "*movsi_insn"
2339 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2340 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2341 "(register_operand (operands[0], SImode)
2342 || reg_or_0_operand (operands[1], SImode))"
2346 sethi\\t%%hi(%a1), %0
2353 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2354 (set_attr "length" "1")])
2356 (define_insn "*movsi_lo_sum"
2357 [(set (match_operand:SI 0 "register_operand" "=r")
2358 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2359 (match_operand:SI 2 "immediate_operand" "in")))]
2361 "or\\t%1, %%lo(%a2), %0"
2362 [(set_attr "type" "ialu")
2363 (set_attr "length" "1")])
2365 (define_insn "*movsi_high"
2366 [(set (match_operand:SI 0 "register_operand" "=r")
2367 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2369 "sethi\\t%%hi(%a1), %0"
2370 [(set_attr "type" "move")
2371 (set_attr "length" "1")])
2373 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2374 ;; so that CSE won't optimize the address computation away.
2375 (define_insn "movsi_lo_sum_pic"
2376 [(set (match_operand:SI 0 "register_operand" "=r")
2377 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2378 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2380 "or\\t%1, %%lo(%a2), %0"
2381 [(set_attr "type" "ialu")
2382 (set_attr "length" "1")])
2384 (define_insn "movsi_high_pic"
2385 [(set (match_operand:SI 0 "register_operand" "=r")
2386 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2387 "flag_pic && check_pic (1)"
2388 "sethi\\t%%hi(%a1), %0"
2389 [(set_attr "type" "move")
2390 (set_attr "length" "1")])
2392 (define_expand "movsi_pic_label_ref"
2393 [(set (match_dup 3) (high:SI
2394 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2396 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2397 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2398 (set (match_operand:SI 0 "register_operand" "=r")
2399 (minus:SI (match_dup 5) (match_dup 4)))]
2403 current_function_uses_pic_offset_table = 1;
2404 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2407 operands[3] = operands[0];
2408 operands[4] = operands[0];
2412 operands[3] = gen_reg_rtx (SImode);
2413 operands[4] = gen_reg_rtx (SImode);
2415 operands[5] = pic_offset_table_rtx;
2418 (define_insn "*movsi_high_pic_label_ref"
2419 [(set (match_operand:SI 0 "register_operand" "=r")
2421 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2422 (match_operand:SI 2 "" "")] 5)))]
2424 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2425 [(set_attr "type" "move")
2426 (set_attr "length" "1")])
2428 (define_insn "*movsi_lo_sum_pic_label_ref"
2429 [(set (match_operand:SI 0 "register_operand" "=r")
2430 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2431 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2432 (match_operand:SI 3 "" "")] 5)))]
2434 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2435 [(set_attr "type" "ialu")
2436 (set_attr "length" "1")])
2438 (define_expand "movdi"
2439 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2440 (match_operand:DI 1 "general_operand" ""))]
2444 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2445 if (GET_CODE (operands[1]) == CONST_DOUBLE
2446 #if HOST_BITS_PER_WIDE_INT == 32
2447 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2448 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2449 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2450 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2453 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2455 /* Handle MEM cases first. */
2456 if (GET_CODE (operands[0]) == MEM)
2458 /* If it's a REG, we can always do it.
2459 The const zero case is more complex, on v9
2460 we can always perform it. */
2461 if (register_operand (operands[1], DImode)
2463 && (operands[1] == const0_rtx)))
2466 if (! reload_in_progress)
2468 operands[0] = validize_mem (operands[0]);
2469 operands[1] = force_reg (DImode, operands[1]);
2475 if (CONSTANT_P (operands[1])
2476 && pic_address_needs_scratch (operands[1]))
2477 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2479 if (GET_CODE (operands[1]) == LABEL_REF)
2481 if (! TARGET_ARCH64)
2483 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2487 if (symbolic_operand (operands[1], DImode))
2489 operands[1] = legitimize_pic_address (operands[1],
2491 (reload_in_progress ?
2498 /* If we are trying to toss an integer constant into the
2499 FPU registers, force it into memory. */
2500 if (GET_CODE (operands[0]) == REG
2501 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2502 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2503 && CONSTANT_P (operands[1]))
2504 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2507 /* This makes sure we will not get rematched due to splittage. */
2508 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2510 else if (TARGET_ARCH64
2511 && CONSTANT_P (operands[1])
2512 && GET_CODE (operands[1]) != HIGH
2513 && GET_CODE (operands[1]) != LO_SUM)
2515 sparc_emit_set_const64 (operands[0], operands[1]);
2523 ;; Be careful, fmovd does not exist when !arch64.
2524 ;; We match MEM moves directly when we have correct even
2525 ;; numbered registers, but fall into splits otherwise.
2526 ;; The constraint ordering here is really important to
2527 ;; avoid insane problems in reload, especially for patterns
2530 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2531 ;; (const_int -5016)))
2534 (define_insn "*movdi_insn_sp32"
2535 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2536 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2538 (register_operand (operands[0], DImode)
2539 || register_operand (operands[1], DImode))"
2552 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2553 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2555 ;; The following are generated by sparc_emit_set_const64
2556 (define_insn "*movdi_sp64_dbl"
2557 [(set (match_operand:DI 0 "register_operand" "=r")
2558 (match_operand:DI 1 "const64_operand" ""))]
2560 && HOST_BITS_PER_WIDE_INT != 64)"
2562 [(set_attr "type" "move")
2563 (set_attr "length" "1")])
2565 ;; This is needed to show CSE exactly which bits are set
2566 ;; in a 64-bit register by sethi instructions.
2567 (define_insn "*movdi_const64_special"
2568 [(set (match_operand:DI 0 "register_operand" "=r")
2569 (match_operand:DI 1 "const64_high_operand" ""))]
2571 "sethi\\t%%hi(%a1), %0"
2572 [(set_attr "type" "move")
2573 (set_attr "length" "1")])
2575 (define_insn "*movdi_insn_sp64"
2576 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2577 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2579 (register_operand (operands[0], DImode)
2580 || reg_or_0_operand (operands[1], DImode))"
2583 sethi\\t%%hi(%a1), %0
2591 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove")
2592 (set_attr "length" "1")])
2594 (define_expand "movdi_pic_label_ref"
2595 [(set (match_dup 3) (high:DI
2596 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2598 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2599 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2600 (set (match_operand:DI 0 "register_operand" "=r")
2601 (minus:DI (match_dup 5) (match_dup 4)))]
2602 "TARGET_ARCH64 && flag_pic"
2605 current_function_uses_pic_offset_table = 1;
2606 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2609 operands[3] = operands[0];
2610 operands[4] = operands[0];
2614 operands[3] = gen_reg_rtx (DImode);
2615 operands[4] = gen_reg_rtx (DImode);
2617 operands[5] = pic_offset_table_rtx;
2620 (define_insn "*movdi_high_pic_label_ref"
2621 [(set (match_operand:DI 0 "register_operand" "=r")
2623 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2624 (match_operand:DI 2 "" "")] 5)))]
2625 "TARGET_ARCH64 && flag_pic"
2626 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2627 [(set_attr "type" "move")
2628 (set_attr "length" "1")])
2630 (define_insn "*movdi_lo_sum_pic_label_ref"
2631 [(set (match_operand:DI 0 "register_operand" "=r")
2632 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2633 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2634 (match_operand:DI 3 "" "")] 5)))]
2635 "TARGET_ARCH64 && flag_pic"
2636 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2637 [(set_attr "type" "ialu")
2638 (set_attr "length" "1")])
2640 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2641 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2643 (define_insn "movdi_lo_sum_pic"
2644 [(set (match_operand:DI 0 "register_operand" "=r")
2645 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2646 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2647 "TARGET_ARCH64 && flag_pic"
2648 "or\\t%1, %%lo(%a2), %0"
2649 [(set_attr "type" "ialu")
2650 (set_attr "length" "1")])
2652 (define_insn "movdi_high_pic"
2653 [(set (match_operand:DI 0 "register_operand" "=r")
2654 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2655 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2656 "sethi\\t%%hi(%a1), %0"
2657 [(set_attr "type" "move")
2658 (set_attr "length" "1")])
2660 (define_insn "*sethi_di_medlow_embmedany_pic"
2661 [(set (match_operand:DI 0 "register_operand" "=r")
2662 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2663 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2664 "sethi\\t%%hi(%a1), %0"
2665 [(set_attr "type" "move")
2666 (set_attr "length" "1")])
2668 (define_insn "*sethi_di_medlow"
2669 [(set (match_operand:DI 0 "register_operand" "=r")
2670 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2671 "TARGET_CM_MEDLOW && check_pic (1)"
2672 "sethi\\t%%hi(%a1), %0"
2673 [(set_attr "type" "move")
2674 (set_attr "length" "1")])
2676 (define_insn "*losum_di_medlow"
2677 [(set (match_operand:DI 0 "register_operand" "=r")
2678 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2679 (match_operand:DI 2 "symbolic_operand" "")))]
2681 "or\\t%1, %%lo(%a2), %0"
2682 [(set_attr "type" "ialu")
2683 (set_attr "length" "1")])
2685 (define_insn "seth44"
2686 [(set (match_operand:DI 0 "register_operand" "=r")
2687 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2689 "sethi\\t%%h44(%a1), %0"
2690 [(set_attr "type" "move")
2691 (set_attr "length" "1")])
2693 (define_insn "setm44"
2694 [(set (match_operand:DI 0 "register_operand" "=r")
2695 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2696 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2698 "or\\t%1, %%m44(%a2), %0"
2699 [(set_attr "type" "move")
2700 (set_attr "length" "1")])
2702 (define_insn "setl44"
2703 [(set (match_operand:DI 0 "register_operand" "=r")
2704 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2705 (match_operand:DI 2 "symbolic_operand" "")))]
2707 "or\\t%1, %%l44(%a2), %0"
2708 [(set_attr "type" "ialu")
2709 (set_attr "length" "1")])
2711 (define_insn "sethh"
2712 [(set (match_operand:DI 0 "register_operand" "=r")
2713 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2715 "sethi\\t%%hh(%a1), %0"
2716 [(set_attr "type" "move")
2717 (set_attr "length" "1")])
2719 (define_insn "setlm"
2720 [(set (match_operand:DI 0 "register_operand" "=r")
2721 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2723 "sethi\\t%%lm(%a1), %0"
2724 [(set_attr "type" "move")
2725 (set_attr "length" "1")])
2727 (define_insn "sethm"
2728 [(set (match_operand:DI 0 "register_operand" "=r")
2729 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2730 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2732 "or\\t%1, %%hm(%a2), %0"
2733 [(set_attr "type" "ialu")
2734 (set_attr "length" "1")])
2736 (define_insn "setlo"
2737 [(set (match_operand:DI 0 "register_operand" "=r")
2738 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2739 (match_operand:DI 2 "symbolic_operand" "")))]
2741 "or\\t%1, %%lo(%a2), %0"
2742 [(set_attr "type" "ialu")
2743 (set_attr "length" "1")])
2745 (define_insn "embmedany_sethi"
2746 [(set (match_operand:DI 0 "register_operand" "=r")
2747 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2748 "TARGET_CM_EMBMEDANY && check_pic (1)"
2749 "sethi\\t%%hi(%a1), %0"
2750 [(set_attr "type" "move")
2751 (set_attr "length" "1")])
2753 (define_insn "embmedany_losum"
2754 [(set (match_operand:DI 0 "register_operand" "=r")
2755 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2756 (match_operand:DI 2 "data_segment_operand" "")))]
2757 "TARGET_CM_EMBMEDANY"
2758 "add\\t%1, %%lo(%a2), %0"
2759 [(set_attr "type" "ialu")
2760 (set_attr "length" "1")])
2762 (define_insn "embmedany_brsum"
2763 [(set (match_operand:DI 0 "register_operand" "=r")
2764 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2765 "TARGET_CM_EMBMEDANY"
2767 [(set_attr "length" "1")])
2769 (define_insn "embmedany_textuhi"
2770 [(set (match_operand:DI 0 "register_operand" "=r")
2771 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2772 "TARGET_CM_EMBMEDANY && check_pic (1)"
2773 "sethi\\t%%uhi(%a1), %0"
2774 [(set_attr "type" "move")
2775 (set_attr "length" "1")])
2777 (define_insn "embmedany_texthi"
2778 [(set (match_operand:DI 0 "register_operand" "=r")
2779 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2780 "TARGET_CM_EMBMEDANY && check_pic (1)"
2781 "sethi\\t%%hi(%a1), %0"
2782 [(set_attr "type" "move")
2783 (set_attr "length" "1")])
2785 (define_insn "embmedany_textulo"
2786 [(set (match_operand:DI 0 "register_operand" "=r")
2787 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2788 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2789 "TARGET_CM_EMBMEDANY"
2790 "or\\t%1, %%ulo(%a2), %0"
2791 [(set_attr "type" "ialu")
2792 (set_attr "length" "1")])
2794 (define_insn "embmedany_textlo"
2795 [(set (match_operand:DI 0 "register_operand" "=r")
2796 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2797 (match_operand:DI 2 "text_segment_operand" "")))]
2798 "TARGET_CM_EMBMEDANY"
2799 "or\\t%1, %%lo(%a2), %0"
2800 [(set_attr "type" "ialu")
2801 (set_attr "length" "1")])
2803 ;; Now some patterns to help reload out a bit.
2804 (define_expand "reload_indi"
2805 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2806 (match_operand:DI 1 "immediate_operand" "")
2807 (match_operand:TI 2 "register_operand" "=&r")])]
2809 || TARGET_CM_EMBMEDANY)
2813 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2814 gen_rtx_REG (DImode, REGNO (operands[2])));
2818 (define_expand "reload_outdi"
2819 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2820 (match_operand:DI 1 "immediate_operand" "")
2821 (match_operand:TI 2 "register_operand" "=&r")])]
2823 || TARGET_CM_EMBMEDANY)
2827 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2828 gen_rtx_REG (DImode, REGNO (operands[2])));
2832 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2834 [(set (match_operand:DI 0 "register_operand" "")
2835 (match_operand:DI 1 "const_int_operand" ""))]
2836 "! TARGET_ARCH64 && reload_completed"
2837 [(clobber (const_int 0))]
2840 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2841 (INTVAL (operands[1]) < 0) ?
2844 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2850 [(set (match_operand:DI 0 "register_operand" "")
2851 (match_operand:DI 1 "const_double_operand" ""))]
2852 "! TARGET_ARCH64 && reload_completed"
2853 [(clobber (const_int 0))]
2856 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2857 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2859 /* Slick... but this trick loses if this subreg constant part
2860 can be done in one insn. */
2861 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2862 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2863 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2865 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2866 gen_highpart (SImode, operands[0])));
2870 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2871 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2877 [(set (match_operand:DI 0 "register_operand" "")
2878 (match_operand:DI 1 "register_operand" ""))]
2879 "! TARGET_ARCH64 && reload_completed"
2880 [(clobber (const_int 0))]
2883 rtx set_dest = operands[0];
2884 rtx set_src = operands[1];
2888 if (GET_CODE (set_dest) == SUBREG)
2889 set_dest = alter_subreg (set_dest);
2890 if (GET_CODE (set_src) == SUBREG)
2891 set_src = alter_subreg (set_src);
2893 dest1 = gen_highpart (SImode, set_dest);
2894 dest2 = gen_lowpart (SImode, set_dest);
2895 src1 = gen_highpart (SImode, set_src);
2896 src2 = gen_lowpart (SImode, set_src);
2898 /* Now emit using the real source and destination we found, swapping
2899 the order if we detect overlap. */
2900 if (reg_overlap_mentioned_p (dest1, src2))
2902 emit_insn (gen_movsi (dest2, src2));
2903 emit_insn (gen_movsi (dest1, src1));
2907 emit_insn (gen_movsi (dest1, src1));
2908 emit_insn (gen_movsi (dest2, src2));
2913 ;; Now handle the cases of memory moves from/to non-even
2914 ;; DI mode register pairs.
2916 [(set (match_operand:DI 0 "register_operand" "")
2917 (match_operand:DI 1 "memory_operand" ""))]
2920 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2921 [(clobber (const_int 0))]
2924 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2925 rtx word1 = change_address (operands[1], SImode,
2926 plus_constant_for_output (XEXP (word0, 0), 4));
2927 rtx high_part = gen_highpart (SImode, operands[0]);
2928 rtx low_part = gen_lowpart (SImode, operands[0]);
2930 if (reg_overlap_mentioned_p (high_part, word1))
2932 emit_insn (gen_movsi (low_part, word1));
2933 emit_insn (gen_movsi (high_part, word0));
2937 emit_insn (gen_movsi (high_part, word0));
2938 emit_insn (gen_movsi (low_part, word1));
2944 [(set (match_operand:DI 0 "memory_operand" "")
2945 (match_operand:DI 1 "register_operand" ""))]
2948 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2949 [(clobber (const_int 0))]
2952 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2953 rtx word1 = change_address (operands[0], SImode,
2954 plus_constant_for_output (XEXP (word0, 0), 4));
2955 rtx high_part = gen_highpart (SImode, operands[1]);
2956 rtx low_part = gen_lowpart (SImode, operands[1]);
2958 emit_insn (gen_movsi (word0, high_part));
2959 emit_insn (gen_movsi (word1, low_part));
2964 ;; Floating point move insns
2966 (define_insn "*movsf_insn_novis_liveg0"
2967 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2968 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*r"))]
2969 "(TARGET_FPU && ! TARGET_VIS && TARGET_LIVE_G0)
2970 && (register_operand (operands[0], SFmode)
2971 || register_operand (operands[1], SFmode))"
2974 if (GET_CODE (operands[1]) == CONST_DOUBLE
2975 && (which_alternative == 2
2976 || which_alternative == 3
2977 || which_alternative == 4))
2982 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2983 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2984 operands[1] = GEN_INT (i);
2987 switch (which_alternative)
2990 return \"fmovs\\t%1, %0\";
2992 return \"and\\t%0, 0, %0\";
2994 return \"sethi\\t%%hi(%a1), %0\";
2996 return \"mov\\t%1, %0\";
3001 return \"ld\\t%1, %0\";
3004 return \"st\\t%1, %0\";
3007 [(set_attr "type" "fpmove,move,move,move,*,load,fpload,fpstore,store")
3008 (set_attr "length" "1")])
3010 (define_insn "*movsf_insn_novis_noliveg0"
3011 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
3012 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
3013 "(TARGET_FPU && ! TARGET_VIS && ! TARGET_LIVE_G0)
3014 && (register_operand (operands[0], SFmode)
3015 || register_operand (operands[1], SFmode)
3016 || fp_zero_operand (operands[1]))"
3019 if (GET_CODE (operands[1]) == CONST_DOUBLE
3020 && (which_alternative == 2
3021 || which_alternative == 3
3022 || which_alternative == 4))
3027 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3028 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3029 operands[1] = GEN_INT (i);
3032 switch (which_alternative)
3035 return \"fmovs\\t%1, %0\";
3037 return \"clr\\t%0\";
3039 return \"sethi\\t%%hi(%a1), %0\";
3041 return \"mov\\t%1, %0\";
3046 return \"ld\\t%1, %0\";
3049 return \"st\\t%r1, %0\";
3052 [(set_attr "type" "fpmove,move,move,move,*,load,fpload,fpstore,store")
3053 (set_attr "length" "1")])
3055 (define_insn "*movsf_insn_vis"
3056 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3057 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3058 "(TARGET_FPU && TARGET_VIS)
3059 && (register_operand (operands[0], SFmode)
3060 || register_operand (operands[1], SFmode)
3061 || fp_zero_operand (operands[1]))"
3064 if (GET_CODE (operands[1]) == CONST_DOUBLE
3065 && (which_alternative == 3
3066 || which_alternative == 4
3067 || which_alternative == 5))
3072 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3073 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3074 operands[1] = GEN_INT (i);
3077 switch (which_alternative)
3080 return \"fmovs\\t%1, %0\";
3082 return \"fzeros\\t%0\";
3084 return \"clr\\t%0\";
3086 return \"sethi\\t%%hi(%a1), %0\";
3088 return \"mov\\t%1, %0\";
3093 return \"ld\\t%1, %0\";
3096 return \"st\\t%r1, %0\";
3099 [(set_attr "type" "fpmove,fpmove,move,move,move,*,load,fpload,fpstore,store")
3100 (set_attr "length" "1")])
3102 (define_insn "*movsf_lo_sum"
3103 [(set (match_operand:SF 0 "register_operand" "")
3104 (lo_sum:SF (match_operand:SF 1 "register_operand" "")
3105 (match_operand:SF 2 "const_double_operand" "")))]
3106 "TARGET_FPU && fp_high_losum_p (operands[2])"
3112 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3113 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3114 operands[2] = GEN_INT (i);
3115 return \"or\\t%1, %%lo(%a2), %0\";
3117 [(set_attr "type" "ialu")
3118 (set_attr "length" "1")])
3120 (define_insn "*movsf_high"
3121 [(set (match_operand:SF 0 "register_operand" "")
3122 (high:SF (match_operand:SF 1 "const_double_operand" "")))]
3123 "TARGET_FPU && fp_high_losum_p (operands[1])"
3129 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3130 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3131 operands[1] = GEN_INT (i);
3132 return \"sethi\\t%%hi(%1), %0\";
3134 [(set_attr "type" "move")
3135 (set_attr "length" "1")])
3138 [(set (match_operand:SF 0 "register_operand" "")
3139 (match_operand:SF 1 "const_double_operand" ""))]
3141 && fp_high_losum_p (operands[1])
3142 && (GET_CODE (operands[0]) == REG
3143 && REGNO (operands[0]) < 32)"
3144 [(set (match_dup 0) (high:SF (match_dup 1)))
3145 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3147 ;; Exactly the same as above, except that all `f' cases are deleted.
3148 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3151 (define_insn "*movsf_no_f_insn"
3152 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
3153 (match_operand:SF 1 "input_operand" "r,m,r"))]
3155 && (register_operand (operands[0], SFmode)
3156 || register_operand (operands[1], SFmode))"
3161 [(set_attr "type" "move,load,store")
3162 (set_attr "length" "1")])
3164 (define_expand "movsf"
3165 [(set (match_operand:SF 0 "general_operand" "")
3166 (match_operand:SF 1 "general_operand" ""))]
3170 /* Force SFmode constants into memory. */
3171 if (GET_CODE (operands[0]) == REG
3172 && CONSTANT_P (operands[1]))
3175 && GET_CODE (operands[1]) == CONST_DOUBLE
3176 && fp_zero_operand (operands[1]))
3179 /* emit_group_store will send such bogosity to us when it is
3180 not storing directly into memory. So fix this up to avoid
3181 crashes in output_constant_pool. */
3182 if (operands [1] == const0_rtx)
3183 operands[1] = CONST0_RTX (SFmode);
3184 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3188 /* Handle sets of MEM first. */
3189 if (GET_CODE (operands[0]) == MEM)
3191 if (register_operand (operands[1], SFmode)
3192 || (! TARGET_LIVE_G0
3193 && GET_CODE (operands[1]) == CONST_DOUBLE
3194 && fp_zero_operand (operands[1])))
3197 if (! reload_in_progress)
3199 operands[0] = validize_mem (operands[0]);
3200 operands[1] = force_reg (SFmode, operands[1]);
3204 /* Fixup PIC cases. */
3207 if (CONSTANT_P (operands[1])
3208 && pic_address_needs_scratch (operands[1]))
3209 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3211 if (symbolic_operand (operands[1], SFmode))
3213 operands[1] = legitimize_pic_address (operands[1],
3215 (reload_in_progress ?
3225 (define_insn "*clear_df"
3226 [(set (match_operand:DF 0 "register_operand" "=e")
3227 (match_operand:DF 1 "const_double_operand" ""))]
3229 && fp_zero_operand (operands[1])"
3231 [(set_attr "type" "fpmove")
3232 (set_attr "length" "1")])
3234 (define_insn "*clear_dfp"
3235 [(set (match_operand:DF 0 "memory_operand" "=m")
3236 (match_operand:DF 1 "const_double_operand" ""))]
3239 && fp_zero_operand (operands[1])"
3241 [(set_attr "type" "store")
3242 (set_attr "length" "1")])
3244 (define_insn "*movdf_const_intreg_sp32"
3245 [(set (match_operand:DF 0 "register_operand" "=e,e,?r")
3246 (match_operand:DF 1 "const_double_operand" "T#F,o#F,F"))]
3247 "TARGET_FPU && ! TARGET_ARCH64"
3252 [(set_attr "type" "move")
3253 (set_attr "length" "1,2,2")])
3255 ;; Now that we redo life analysis with a clean slate after
3256 ;; instruction splitting for sched2 this can work.
3257 (define_insn "*movdf_const_intreg_sp64"
3258 [(set (match_operand:DF 0 "register_operand" "=e,?r")
3259 (match_operand:DF 1 "const_double_operand" "m#F,F"))]
3260 "TARGET_FPU && TARGET_ARCH64"
3264 [(set_attr "type" "move")
3265 (set_attr "length" "1,2")])
3268 [(set (match_operand:DF 0 "register_operand" "")
3269 (match_operand:DF 1 "const_double_operand" ""))]
3271 && (GET_CODE (operands[0]) == REG
3272 && REGNO (operands[0]) < 32)
3273 && reload_completed"
3274 [(clobber (const_int 0))]
3280 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3281 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3282 if (GET_CODE (operands[0]) == SUBREG)
3283 operands[0] = alter_subreg (operands[0]);
3284 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3288 #if HOST_BITS_PER_WIDE_INT == 64
3291 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3292 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3293 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3295 emit_insn (gen_movdi (operands[0],
3296 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3302 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3305 /* Slick... but this trick loses if this subreg constant part
3306 can be done in one insn. */
3308 && !(SPARC_SETHI_P (l[0])
3309 || SPARC_SIMM13_P (l[0])))
3311 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3312 gen_highpart (SImode, operands[0])));
3316 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3323 (define_expand "movdf"
3324 [(set (match_operand:DF 0 "general_operand" "")
3325 (match_operand:DF 1 "general_operand" ""))]
3329 /* Force DFmode constants into memory. */
3330 if (GET_CODE (operands[0]) == REG
3331 && CONSTANT_P (operands[1]))
3334 && GET_CODE (operands[1]) == CONST_DOUBLE
3335 && fp_zero_operand (operands[1]))
3338 /* emit_group_store will send such bogosity to us when it is
3339 not storing directly into memory. So fix this up to avoid
3340 crashes in output_constant_pool. */
3341 if (operands [1] == const0_rtx)
3342 operands[1] = CONST0_RTX (DFmode);
3343 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3347 /* Handle MEM cases first. */
3348 if (GET_CODE (operands[0]) == MEM)
3350 if (register_operand (operands[1], DFmode))
3353 if (! reload_in_progress)
3355 operands[0] = validize_mem (operands[0]);
3356 operands[1] = force_reg (DFmode, operands[1]);
3360 /* Fixup PIC cases. */
3363 if (CONSTANT_P (operands[1])
3364 && pic_address_needs_scratch (operands[1]))
3365 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3367 if (symbolic_operand (operands[1], DFmode))
3369 operands[1] = legitimize_pic_address (operands[1],
3371 (reload_in_progress ?
3381 ;; Be careful, fmovd does not exist when !v9.
3382 (define_insn "*movdf_insn_sp32"
3383 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,e,r,r,o,e,o")
3384 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3387 && (register_operand (operands[0], DFmode)
3388 || register_operand (operands[1], DFmode))"
3400 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3401 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3403 (define_insn "*movdf_no_e_insn_sp32"
3404 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,r,r,o")
3405 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3408 && (register_operand (operands[0], DFmode)
3409 || register_operand (operands[1], DFmode))"
3416 [(set_attr "type" "load,store,*,*,*")
3417 (set_attr "length" "1,1,2,2,2")])
3419 ;; We have available v9 double floats but not 64-bit
3420 ;; integer registers.
3421 (define_insn "*movdf_insn_v9only"
3422 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o")
3423 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3427 && (register_operand (operands[0], DFmode)
3428 || register_operand (operands[1], DFmode))"
3438 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3439 (set_attr "length" "1,1,1,1,1,2,2,2")])
3441 ;; We have available both v9 double floats and 64-bit
3442 ;; integer registers.
3443 (define_insn "*movdf_insn_sp64"
3444 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,r,r,m")
3445 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3449 && (register_operand (operands[0], DFmode)
3450 || register_operand (operands[1], DFmode))"
3458 [(set_attr "type" "fpmove,load,store,move,load,store")
3459 (set_attr "length" "1")])
3461 (define_insn "*movdf_no_e_insn_sp64"
3462 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3463 (match_operand:DF 1 "input_operand" "r,m,r"))]
3466 && (register_operand (operands[0], DFmode)
3467 || register_operand (operands[1], DFmode))"
3472 [(set_attr "type" "move,load,store")
3473 (set_attr "length" "1")])
3475 ;; Ok, now the splits to handle all the multi insn and
3476 ;; mis-aligned memory address cases.
3477 ;; In these splits please take note that we must be
3478 ;; careful when V9 but not ARCH64 because the integer
3479 ;; register DFmode cases must be handled.
3481 [(set (match_operand:DF 0 "register_operand" "")
3482 (match_operand:DF 1 "register_operand" ""))]
3485 && ((GET_CODE (operands[0]) == REG
3486 && REGNO (operands[0]) < 32)
3487 || (GET_CODE (operands[0]) == SUBREG
3488 && GET_CODE (SUBREG_REG (operands[0])) == REG
3489 && REGNO (SUBREG_REG (operands[0])) < 32))))
3490 && reload_completed"
3491 [(clobber (const_int 0))]
3494 rtx set_dest = operands[0];
3495 rtx set_src = operands[1];
3499 if (GET_CODE (set_dest) == SUBREG)
3500 set_dest = alter_subreg (set_dest);
3501 if (GET_CODE (set_src) == SUBREG)
3502 set_src = alter_subreg (set_src);
3504 dest1 = gen_highpart (SFmode, set_dest);
3505 dest2 = gen_lowpart (SFmode, set_dest);
3506 src1 = gen_highpart (SFmode, set_src);
3507 src2 = gen_lowpart (SFmode, set_src);
3509 /* Now emit using the real source and destination we found, swapping
3510 the order if we detect overlap. */
3511 if (reg_overlap_mentioned_p (dest1, src2))
3513 emit_insn (gen_movsf (dest2, src2));
3514 emit_insn (gen_movsf (dest1, src1));
3518 emit_insn (gen_movsf (dest1, src1));
3519 emit_insn (gen_movsf (dest2, src2));
3525 [(set (match_operand:DF 0 "register_operand" "")
3526 (match_operand:DF 1 "memory_operand" ""))]
3529 && ((GET_CODE (operands[0]) == REG
3530 && REGNO (operands[0]) < 32)
3531 || (GET_CODE (operands[0]) == SUBREG
3532 && GET_CODE (SUBREG_REG (operands[0])) == REG
3533 && REGNO (SUBREG_REG (operands[0])) < 32))))
3534 && (reload_completed
3535 && (((REGNO (operands[0])) % 2) != 0
3536 || ! mem_min_alignment (operands[1], 8))
3537 && offsettable_memref_p (operands[1])))"
3538 [(clobber (const_int 0))]
3541 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3542 rtx word1 = change_address (operands[1], SFmode,
3543 plus_constant_for_output (XEXP (word0, 0), 4));
3545 if (GET_CODE (operands[0]) == SUBREG)
3546 operands[0] = alter_subreg (operands[0]);
3548 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3550 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3552 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3557 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3559 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3566 [(set (match_operand:DF 0 "memory_operand" "")
3567 (match_operand:DF 1 "register_operand" ""))]
3570 && ((GET_CODE (operands[1]) == REG
3571 && REGNO (operands[1]) < 32)
3572 || (GET_CODE (operands[1]) == SUBREG
3573 && GET_CODE (SUBREG_REG (operands[1])) == REG
3574 && REGNO (SUBREG_REG (operands[1])) < 32))))
3575 && (reload_completed
3576 && (((REGNO (operands[1])) % 2) != 0
3577 || ! mem_min_alignment (operands[0], 8))
3578 && offsettable_memref_p (operands[0])))"
3579 [(clobber (const_int 0))]
3582 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3583 rtx word1 = change_address (operands[0], SFmode,
3584 plus_constant_for_output (XEXP (word0, 0), 4));
3586 if (GET_CODE (operands[1]) == SUBREG)
3587 operands[1] = alter_subreg (operands[1]);
3588 emit_insn (gen_movsf (word0,
3589 gen_highpart (SFmode, operands[1])));
3590 emit_insn (gen_movsf (word1,
3591 gen_lowpart (SFmode, operands[1])));
3595 (define_insn "*clear_tf"
3596 [(set (match_operand:TF 0 "register_operand" "=e")
3597 (match_operand:TF 1 "const_double_operand" ""))]
3599 && fp_zero_operand (operands[1])"
3601 [(set_attr "type" "fpmove")
3602 (set_attr "length" "2")])
3605 [(set (match_operand:TF 0 "register_operand" "")
3606 (match_operand:TF 1 "const_double_operand" ""))]
3607 "TARGET_VIS && reload_completed
3608 && fp_zero_operand (operands[1])"
3609 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3610 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3613 operands[1] = CONST0_RTX (DFmode);
3617 (define_insn "*clear_tfp"
3618 [(set (match_operand:TF 0 "memory_operand" "=m")
3619 (match_operand:TF 1 "const_double_operand" ""))]
3622 && fp_zero_operand (operands[1])"
3624 [(set_attr "type" "fpmove")
3625 (set_attr "length" "2")])
3628 [(set (match_operand:TF 0 "memory_operand" "=m")
3629 (match_operand:TF 1 "const_double_operand" ""))]
3631 && TARGET_V9 && reload_completed
3632 && fp_zero_operand (operands[1])"
3633 [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
3634 (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
3637 operands[1] = CONST0_RTX (DFmode);
3641 (define_expand "movtf"
3642 [(set (match_operand:TF 0 "general_operand" "")
3643 (match_operand:TF 1 "general_operand" ""))]
3647 /* Force TFmode constants into memory. */
3648 if (GET_CODE (operands[0]) == REG
3649 && CONSTANT_P (operands[1]))
3652 && GET_CODE (operands[1]) == CONST_DOUBLE
3653 && fp_zero_operand (operands[1]))
3656 /* emit_group_store will send such bogosity to us when it is
3657 not storing directly into memory. So fix this up to avoid
3658 crashes in output_constant_pool. */
3659 if (operands [1] == const0_rtx)
3660 operands[1] = CONST0_RTX (TFmode);
3661 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3665 /* Handle MEM cases first, note that only v9 guarentees
3666 full 16-byte alignment for quads. */
3667 if (GET_CODE (operands[0]) == MEM)
3669 if (register_operand (operands[1], TFmode))
3672 if (! reload_in_progress)
3674 operands[0] = validize_mem (operands[0]);
3675 operands[1] = force_reg (TFmode, operands[1]);
3679 /* Fixup PIC cases. */
3682 if (CONSTANT_P (operands[1])
3683 && pic_address_needs_scratch (operands[1]))
3684 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3686 if (symbolic_operand (operands[1], TFmode))
3688 operands[1] = legitimize_pic_address (operands[1],
3690 (reload_in_progress ?
3700 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3701 ;; we must split them all. :-(
3702 (define_insn "*movtf_insn_sp32"
3703 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,e,r,r,o")
3704 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3707 && (register_operand (operands[0], TFmode)
3708 || register_operand (operands[1], TFmode))"
3710 [(set_attr "length" "4")])
3712 ;; Exactly the same as above, except that all `e' cases are deleted.
3713 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3716 (define_insn "*movtf_no_e_insn_sp32"
3717 [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o")
3718 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3721 && (register_operand (operands[0], TFmode)
3722 || register_operand (operands[1], TFmode))"
3724 [(set_attr "length" "4")])
3726 ;; Now handle the float reg cases directly when arch64,
3727 ;; hard_quad, and proper reg number alignment are all true.
3728 (define_insn "*movtf_insn_hq_sp64"
3729 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,r,r,o")
3730 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3735 && (register_operand (operands[0], TFmode)
3736 || register_operand (operands[1], TFmode))"
3744 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3745 (set_attr "length" "1,1,1,2,2,2")])
3747 ;; Now we allow the integer register cases even when
3748 ;; only arch64 is true.
3749 (define_insn "*movtf_insn_sp64"
3750 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r")
3751 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3754 && ! TARGET_HARD_QUAD
3755 && (register_operand (operands[0], TFmode)
3756 || register_operand (operands[1], TFmode))"
3758 [(set_attr "length" "2")])
3760 (define_insn "*movtf_no_e_insn_sp64"
3761 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r")
3762 (match_operand:TF 1 "input_operand" "o,r,r"))]
3765 && (register_operand (operands[0], TFmode)
3766 || register_operand (operands[1], TFmode))"
3768 [(set_attr "length" "2")])
3770 ;; Now all the splits to handle multi-insn TF mode moves.
3772 [(set (match_operand:TF 0 "register_operand" "")
3773 (match_operand:TF 1 "register_operand" ""))]
3777 && ! TARGET_HARD_QUAD))"
3778 [(clobber (const_int 0))]
3781 rtx set_dest = operands[0];
3782 rtx set_src = operands[1];
3786 if (GET_CODE (set_dest) == SUBREG)
3787 set_dest = alter_subreg (set_dest);
3788 if (GET_CODE (set_src) == SUBREG)
3789 set_src = alter_subreg (set_src);
3791 dest1 = gen_df_reg (set_dest, 0);
3792 dest2 = gen_df_reg (set_dest, 1);
3793 src1 = gen_df_reg (set_src, 0);
3794 src2 = gen_df_reg (set_src, 1);
3796 /* Now emit using the real source and destination we found, swapping
3797 the order if we detect overlap. */
3798 if (reg_overlap_mentioned_p (dest1, src2))
3800 emit_insn (gen_movdf (dest2, src2));
3801 emit_insn (gen_movdf (dest1, src1));
3805 emit_insn (gen_movdf (dest1, src1));
3806 emit_insn (gen_movdf (dest2, src2));
3812 [(set (match_operand:TF 0 "register_operand" "")
3813 (match_operand:TF 1 "memory_operand" ""))]
3815 && offsettable_memref_p (operands[1]))"
3816 [(clobber (const_int 0))]
3819 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3820 rtx word1 = change_address (operands[1], DFmode,
3821 plus_constant_for_output (XEXP (word0, 0), 8));
3822 rtx set_dest, dest1, dest2;
3824 set_dest = operands[0];
3825 if (GET_CODE (set_dest) == SUBREG)
3826 set_dest = alter_subreg (set_dest);
3828 dest1 = gen_df_reg (set_dest, 0);
3829 dest2 = gen_df_reg (set_dest, 1);
3831 /* Now output, ordering such that we don't clobber any registers
3832 mentioned in the address. */
3833 if (reg_overlap_mentioned_p (dest1, word1))
3836 emit_insn (gen_movdf (dest2, word1));
3837 emit_insn (gen_movdf (dest1, word0));
3841 emit_insn (gen_movdf (dest1, word0));
3842 emit_insn (gen_movdf (dest2, word1));
3848 [(set (match_operand:TF 0 "memory_operand" "")
3849 (match_operand:TF 1 "register_operand" ""))]
3851 && offsettable_memref_p (operands[0]))"
3852 [(clobber (const_int 0))]
3855 rtx word1 = change_address (operands[0], DFmode, NULL_RTX);
3856 rtx word2 = change_address (operands[0], DFmode,
3857 plus_constant_for_output (XEXP (word1, 0), 8));
3860 set_src = operands[1];
3861 if (GET_CODE (set_src) == SUBREG)
3862 set_src = alter_subreg (set_src);
3864 emit_insn (gen_movdf (word1, gen_df_reg (set_src, 0)));
3865 emit_insn (gen_movdf (word2, gen_df_reg (set_src, 1)));
3869 ;; Sparc V9 conditional move instructions.
3871 ;; We can handle larger constants here for some flavors, but for now we keep
3872 ;; it simple and only allow those constants supported by all flavours.
3873 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3874 ;; 3 contains the constant if one is present, but we handle either for
3875 ;; generality (sparc.c puts a constant in operand 2).
3877 (define_expand "movqicc"
3878 [(set (match_operand:QI 0 "register_operand" "")
3879 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3880 (match_operand:QI 2 "arith10_operand" "")
3881 (match_operand:QI 3 "arith10_operand" "")))]
3885 enum rtx_code code = GET_CODE (operands[1]);
3887 if (GET_MODE (sparc_compare_op0) == DImode
3891 if (sparc_compare_op1 == const0_rtx
3892 && GET_CODE (sparc_compare_op0) == REG
3893 && GET_MODE (sparc_compare_op0) == DImode
3894 && v9_regcmp_p (code))
3896 operands[1] = gen_rtx_fmt_ee (code, DImode,
3897 sparc_compare_op0, sparc_compare_op1);
3901 rtx cc_reg = gen_compare_reg (code,
3902 sparc_compare_op0, sparc_compare_op1);
3903 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3907 (define_expand "movhicc"
3908 [(set (match_operand:HI 0 "register_operand" "")
3909 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3910 (match_operand:HI 2 "arith10_operand" "")
3911 (match_operand:HI 3 "arith10_operand" "")))]
3915 enum rtx_code code = GET_CODE (operands[1]);
3917 if (GET_MODE (sparc_compare_op0) == DImode
3921 if (sparc_compare_op1 == const0_rtx
3922 && GET_CODE (sparc_compare_op0) == REG
3923 && GET_MODE (sparc_compare_op0) == DImode
3924 && v9_regcmp_p (code))
3926 operands[1] = gen_rtx_fmt_ee (code, DImode,
3927 sparc_compare_op0, sparc_compare_op1);
3931 rtx cc_reg = gen_compare_reg (code,
3932 sparc_compare_op0, sparc_compare_op1);
3933 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3937 (define_expand "movsicc"
3938 [(set (match_operand:SI 0 "register_operand" "")
3939 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3940 (match_operand:SI 2 "arith10_operand" "")
3941 (match_operand:SI 3 "arith10_operand" "")))]
3945 enum rtx_code code = GET_CODE (operands[1]);
3946 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3948 if (sparc_compare_op1 == const0_rtx
3949 && GET_CODE (sparc_compare_op0) == REG
3950 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3952 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3953 sparc_compare_op0, sparc_compare_op1);
3957 rtx cc_reg = gen_compare_reg (code,
3958 sparc_compare_op0, sparc_compare_op1);
3959 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3960 cc_reg, const0_rtx);
3964 (define_expand "movdicc"
3965 [(set (match_operand:DI 0 "register_operand" "")
3966 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3967 (match_operand:DI 2 "arith10_double_operand" "")
3968 (match_operand:DI 3 "arith10_double_operand" "")))]
3972 enum rtx_code code = GET_CODE (operands[1]);
3974 if (sparc_compare_op1 == const0_rtx
3975 && GET_CODE (sparc_compare_op0) == REG
3976 && GET_MODE (sparc_compare_op0) == DImode
3977 && v9_regcmp_p (code))
3979 operands[1] = gen_rtx_fmt_ee (code, DImode,
3980 sparc_compare_op0, sparc_compare_op1);
3984 rtx cc_reg = gen_compare_reg (code,
3985 sparc_compare_op0, sparc_compare_op1);
3986 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3987 cc_reg, const0_rtx);
3991 (define_expand "movsfcc"
3992 [(set (match_operand:SF 0 "register_operand" "")
3993 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3994 (match_operand:SF 2 "register_operand" "")
3995 (match_operand:SF 3 "register_operand" "")))]
3996 "TARGET_V9 && TARGET_FPU"
3999 enum rtx_code code = GET_CODE (operands[1]);
4001 if (GET_MODE (sparc_compare_op0) == DImode
4005 if (sparc_compare_op1 == const0_rtx
4006 && GET_CODE (sparc_compare_op0) == REG
4007 && GET_MODE (sparc_compare_op0) == DImode
4008 && v9_regcmp_p (code))
4010 operands[1] = gen_rtx_fmt_ee (code, DImode,
4011 sparc_compare_op0, sparc_compare_op1);
4015 rtx cc_reg = gen_compare_reg (code,
4016 sparc_compare_op0, sparc_compare_op1);
4017 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4021 (define_expand "movdfcc"
4022 [(set (match_operand:DF 0 "register_operand" "")
4023 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4024 (match_operand:DF 2 "register_operand" "")
4025 (match_operand:DF 3 "register_operand" "")))]
4026 "TARGET_V9 && TARGET_FPU"
4029 enum rtx_code code = GET_CODE (operands[1]);
4031 if (GET_MODE (sparc_compare_op0) == DImode
4035 if (sparc_compare_op1 == const0_rtx
4036 && GET_CODE (sparc_compare_op0) == REG
4037 && GET_MODE (sparc_compare_op0) == DImode
4038 && v9_regcmp_p (code))
4040 operands[1] = gen_rtx_fmt_ee (code, DImode,
4041 sparc_compare_op0, sparc_compare_op1);
4045 rtx cc_reg = gen_compare_reg (code,
4046 sparc_compare_op0, sparc_compare_op1);
4047 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4051 (define_expand "movtfcc"
4052 [(set (match_operand:TF 0 "register_operand" "")
4053 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4054 (match_operand:TF 2 "register_operand" "")
4055 (match_operand:TF 3 "register_operand" "")))]
4056 "TARGET_V9 && TARGET_FPU"
4059 enum rtx_code code = GET_CODE (operands[1]);
4061 if (GET_MODE (sparc_compare_op0) == DImode
4065 if (sparc_compare_op1 == const0_rtx
4066 && GET_CODE (sparc_compare_op0) == REG
4067 && GET_MODE (sparc_compare_op0) == DImode
4068 && v9_regcmp_p (code))
4070 operands[1] = gen_rtx_fmt_ee (code, DImode,
4071 sparc_compare_op0, sparc_compare_op1);
4075 rtx cc_reg = gen_compare_reg (code,
4076 sparc_compare_op0, sparc_compare_op1);
4077 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4081 ;; Conditional move define_insns.
4083 (define_insn "*movqi_cc_sp64"
4084 [(set (match_operand:QI 0 "register_operand" "=r,r")
4085 (if_then_else:QI (match_operator 1 "comparison_operator"
4086 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4088 (match_operand:QI 3 "arith11_operand" "rL,0")
4089 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4092 mov%C1\\t%x2, %3, %0
4093 mov%c1\\t%x2, %4, %0"
4094 [(set_attr "type" "cmove")
4095 (set_attr "length" "1")])
4097 (define_insn "*movhi_cc_sp64"
4098 [(set (match_operand:HI 0 "register_operand" "=r,r")
4099 (if_then_else:HI (match_operator 1 "comparison_operator"
4100 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4102 (match_operand:HI 3 "arith11_operand" "rL,0")
4103 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4106 mov%C1\\t%x2, %3, %0
4107 mov%c1\\t%x2, %4, %0"
4108 [(set_attr "type" "cmove")
4109 (set_attr "length" "1")])
4111 (define_insn "*movsi_cc_sp64"
4112 [(set (match_operand:SI 0 "register_operand" "=r,r")
4113 (if_then_else:SI (match_operator 1 "comparison_operator"
4114 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4116 (match_operand:SI 3 "arith11_operand" "rL,0")
4117 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4120 mov%C1\\t%x2, %3, %0
4121 mov%c1\\t%x2, %4, %0"
4122 [(set_attr "type" "cmove")
4123 (set_attr "length" "1")])
4125 ;; ??? The constraints of operands 3,4 need work.
4126 (define_insn "*movdi_cc_sp64"
4127 [(set (match_operand:DI 0 "register_operand" "=r,r")
4128 (if_then_else:DI (match_operator 1 "comparison_operator"
4129 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4131 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4132 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4135 mov%C1\\t%x2, %3, %0
4136 mov%c1\\t%x2, %4, %0"
4137 [(set_attr "type" "cmove")
4138 (set_attr "length" "1")])
4140 (define_insn "*movdi_cc_sp64_trunc"
4141 [(set (match_operand:SI 0 "register_operand" "=r,r")
4142 (if_then_else:SI (match_operator 1 "comparison_operator"
4143 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4145 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4146 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4149 mov%C1\\t%x2, %3, %0
4150 mov%c1\\t%x2, %4, %0"
4151 [(set_attr "type" "cmove")
4152 (set_attr "length" "1")])
4154 (define_insn "*movsf_cc_sp64"
4155 [(set (match_operand:SF 0 "register_operand" "=f,f")
4156 (if_then_else:SF (match_operator 1 "comparison_operator"
4157 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4159 (match_operand:SF 3 "register_operand" "f,0")
4160 (match_operand:SF 4 "register_operand" "0,f")))]
4161 "TARGET_V9 && TARGET_FPU"
4163 fmovs%C1\\t%x2, %3, %0
4164 fmovs%c1\\t%x2, %4, %0"
4165 [(set_attr "type" "fpcmove")
4166 (set_attr "length" "1")])
4168 (define_insn "movdf_cc_sp64"
4169 [(set (match_operand:DF 0 "register_operand" "=e,e")
4170 (if_then_else:DF (match_operator 1 "comparison_operator"
4171 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4173 (match_operand:DF 3 "register_operand" "e,0")
4174 (match_operand:DF 4 "register_operand" "0,e")))]
4175 "TARGET_V9 && TARGET_FPU"
4177 fmovd%C1\\t%x2, %3, %0
4178 fmovd%c1\\t%x2, %4, %0"
4179 [(set_attr "type" "fpcmove")
4180 (set_attr "length" "1")])
4182 (define_insn "*movtf_cc_hq_sp64"
4183 [(set (match_operand:TF 0 "register_operand" "=e,e")
4184 (if_then_else:TF (match_operator 1 "comparison_operator"
4185 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4187 (match_operand:TF 3 "register_operand" "e,0")
4188 (match_operand:TF 4 "register_operand" "0,e")))]
4189 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4191 fmovq%C1\\t%x2, %3, %0
4192 fmovq%c1\\t%x2, %4, %0"
4193 [(set_attr "type" "fpcmove")
4194 (set_attr "length" "1")])
4196 (define_insn "*movtf_cc_sp64"
4197 [(set (match_operand:TF 0 "register_operand" "=e,e")
4198 (if_then_else:TF (match_operator 1 "comparison_operator"
4199 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4201 (match_operand:TF 3 "register_operand" "e,0")
4202 (match_operand:TF 4 "register_operand" "0,e")))]
4203 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4205 [(set_attr "type" "fpcmove")
4206 (set_attr "length" "2")])
4209 [(set (match_operand:TF 0 "register_operand" "=e,e")
4210 (if_then_else:TF (match_operator 1 "comparison_operator"
4211 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4213 (match_operand:TF 3 "register_operand" "e,0")
4214 (match_operand:TF 4 "register_operand" "0,e")))]
4215 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4216 [(clobber (const_int 0))]
4219 rtx set_dest = operands[0];
4220 rtx set_srca = operands[3];
4221 rtx set_srcb = operands[4];
4222 int third = rtx_equal_p (set_dest, set_srca);
4224 rtx srca1, srca2, srcb1, srcb2;
4226 if (GET_CODE (set_dest) == SUBREG)
4227 set_dest = alter_subreg (set_dest);
4228 if (GET_CODE (set_srca) == SUBREG)
4229 set_srca = alter_subreg (set_srca);
4230 if (GET_CODE (set_srcb) == SUBREG)
4231 set_srcb = alter_subreg (set_srcb);
4233 dest1 = gen_df_reg (set_dest, 0);
4234 dest2 = gen_df_reg (set_dest, 1);
4235 srca1 = gen_df_reg (set_srca, 0);
4236 srca2 = gen_df_reg (set_srca, 1);
4237 srcb1 = gen_df_reg (set_srcb, 0);
4238 srcb2 = gen_df_reg (set_srcb, 1);
4240 /* Now emit using the real source and destination we found, swapping
4241 the order if we detect overlap. */
4242 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4243 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4245 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4246 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4250 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4251 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4256 (define_insn "*movqi_cc_reg_sp64"
4257 [(set (match_operand:QI 0 "register_operand" "=r,r")
4258 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4259 [(match_operand:DI 2 "register_operand" "r,r")
4261 (match_operand:QI 3 "arith10_operand" "rM,0")
4262 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4265 movr%D1\\t%2, %r3, %0
4266 movr%d1\\t%2, %r4, %0"
4267 [(set_attr "type" "cmove")
4268 (set_attr "length" "1")])
4270 (define_insn "*movhi_cc_reg_sp64"
4271 [(set (match_operand:HI 0 "register_operand" "=r,r")
4272 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4273 [(match_operand:DI 2 "register_operand" "r,r")
4275 (match_operand:HI 3 "arith10_operand" "rM,0")
4276 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4279 movr%D1\\t%2, %r3, %0
4280 movr%d1\\t%2, %r4, %0"
4281 [(set_attr "type" "cmove")
4282 (set_attr "length" "1")])
4284 (define_insn "*movsi_cc_reg_sp64"
4285 [(set (match_operand:SI 0 "register_operand" "=r,r")
4286 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4287 [(match_operand:DI 2 "register_operand" "r,r")
4289 (match_operand:SI 3 "arith10_operand" "rM,0")
4290 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4293 movr%D1\\t%2, %r3, %0
4294 movr%d1\\t%2, %r4, %0"
4295 [(set_attr "type" "cmove")
4296 (set_attr "length" "1")])
4298 ;; ??? The constraints of operands 3,4 need work.
4299 (define_insn "*movdi_cc_reg_sp64"
4300 [(set (match_operand:DI 0 "register_operand" "=r,r")
4301 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4302 [(match_operand:DI 2 "register_operand" "r,r")
4304 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4305 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4308 movr%D1\\t%2, %r3, %0
4309 movr%d1\\t%2, %r4, %0"
4310 [(set_attr "type" "cmove")
4311 (set_attr "length" "1")])
4313 (define_insn "*movdi_cc_reg_sp64_trunc"
4314 [(set (match_operand:SI 0 "register_operand" "=r,r")
4315 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4316 [(match_operand:DI 2 "register_operand" "r,r")
4318 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4319 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4322 movr%D1\\t%2, %r3, %0
4323 movr%d1\\t%2, %r4, %0"
4324 [(set_attr "type" "cmove")
4325 (set_attr "length" "1")])
4327 (define_insn "*movsf_cc_reg_sp64"
4328 [(set (match_operand:SF 0 "register_operand" "=f,f")
4329 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4330 [(match_operand:DI 2 "register_operand" "r,r")
4332 (match_operand:SF 3 "register_operand" "f,0")
4333 (match_operand:SF 4 "register_operand" "0,f")))]
4334 "TARGET_ARCH64 && TARGET_FPU"
4336 fmovrs%D1\\t%2, %3, %0
4337 fmovrs%d1\\t%2, %4, %0"
4338 [(set_attr "type" "fpcmove")
4339 (set_attr "length" "1")])
4341 (define_insn "movdf_cc_reg_sp64"
4342 [(set (match_operand:DF 0 "register_operand" "=e,e")
4343 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4344 [(match_operand:DI 2 "register_operand" "r,r")
4346 (match_operand:DF 3 "register_operand" "e,0")
4347 (match_operand:DF 4 "register_operand" "0,e")))]
4348 "TARGET_ARCH64 && TARGET_FPU"
4350 fmovrd%D1\\t%2, %3, %0
4351 fmovrd%d1\\t%2, %4, %0"
4352 [(set_attr "type" "fpcmove")
4353 (set_attr "length" "1")])
4355 (define_insn "*movtf_cc_reg_hq_sp64"
4356 [(set (match_operand:TF 0 "register_operand" "=e,e")
4357 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4358 [(match_operand:DI 2 "register_operand" "r,r")
4360 (match_operand:TF 3 "register_operand" "e,0")
4361 (match_operand:TF 4 "register_operand" "0,e")))]
4362 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4364 fmovrq%D1\\t%2, %3, %0
4365 fmovrq%d1\\t%2, %4, %0"
4366 [(set_attr "type" "fpcmove")
4367 (set_attr "length" "1")])
4369 (define_insn "*movtf_cc_reg_sp64"
4370 [(set (match_operand:TF 0 "register_operand" "=e,e")
4371 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4372 [(match_operand:DI 2 "register_operand" "r,r")
4374 (match_operand:TF 3 "register_operand" "e,0")
4375 (match_operand:TF 4 "register_operand" "0,e")))]
4376 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4378 [(set_attr "type" "fpcmove")
4379 (set_attr "length" "2")])
4382 [(set (match_operand:TF 0 "register_operand" "=e,e")
4383 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4384 [(match_operand:DI 2 "register_operand" "r,r")
4386 (match_operand:TF 3 "register_operand" "e,0")
4387 (match_operand:TF 4 "register_operand" "0,e")))]
4388 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4389 [(clobber (const_int 0))]
4392 rtx set_dest = operands[0];
4393 rtx set_srca = operands[3];
4394 rtx set_srcb = operands[4];
4395 int third = rtx_equal_p (set_dest, set_srca);
4397 rtx srca1, srca2, srcb1, srcb2;
4399 if (GET_CODE (set_dest) == SUBREG)
4400 set_dest = alter_subreg (set_dest);
4401 if (GET_CODE (set_srca) == SUBREG)
4402 set_srca = alter_subreg (set_srca);
4403 if (GET_CODE (set_srcb) == SUBREG)
4404 set_srcb = alter_subreg (set_srcb);
4406 dest1 = gen_df_reg (set_dest, 0);
4407 dest2 = gen_df_reg (set_dest, 1);
4408 srca1 = gen_df_reg (set_srca, 0);
4409 srca2 = gen_df_reg (set_srca, 1);
4410 srcb1 = gen_df_reg (set_srcb, 0);
4411 srcb2 = gen_df_reg (set_srcb, 1);
4413 /* Now emit using the real source and destination we found, swapping
4414 the order if we detect overlap. */
4415 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4416 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4418 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4419 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4423 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4424 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4430 ;;- zero extension instructions
4432 ;; These patterns originally accepted general_operands, however, slightly
4433 ;; better code is generated by only accepting register_operands, and then
4434 ;; letting combine generate the ldu[hb] insns.
4436 (define_expand "zero_extendhisi2"
4437 [(set (match_operand:SI 0 "register_operand" "")
4438 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4442 rtx temp = gen_reg_rtx (SImode);
4443 rtx shift_16 = GEN_INT (16);
4444 int op1_subword = 0;
4446 if (GET_CODE (operand1) == SUBREG)
4448 op1_subword = SUBREG_WORD (operand1);
4449 operand1 = XEXP (operand1, 0);
4452 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4454 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4458 (define_insn "*zero_extendhisi2_insn"
4459 [(set (match_operand:SI 0 "register_operand" "=r")
4460 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4463 [(set_attr "type" "load")
4464 (set_attr "length" "1")])
4466 (define_expand "zero_extendqihi2"
4467 [(set (match_operand:HI 0 "register_operand" "")
4468 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4472 (define_insn "*zero_extendqihi2_insn"
4473 [(set (match_operand:HI 0 "register_operand" "=r,r")
4474 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4475 "GET_CODE (operands[1]) != CONST_INT"
4479 [(set_attr "type" "unary,load")
4480 (set_attr "length" "1")])
4482 (define_expand "zero_extendqisi2"
4483 [(set (match_operand:SI 0 "register_operand" "")
4484 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4488 (define_insn "*zero_extendqisi2_insn"
4489 [(set (match_operand:SI 0 "register_operand" "=r,r")
4490 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4491 "GET_CODE (operands[1]) != CONST_INT"
4495 [(set_attr "type" "unary,load")
4496 (set_attr "length" "1")])
4498 (define_expand "zero_extendqidi2"
4499 [(set (match_operand:DI 0 "register_operand" "")
4500 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4504 (define_insn "*zero_extendqidi2_insn"
4505 [(set (match_operand:DI 0 "register_operand" "=r,r")
4506 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4507 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4511 [(set_attr "type" "unary,load")
4512 (set_attr "length" "1")])
4514 (define_expand "zero_extendhidi2"
4515 [(set (match_operand:DI 0 "register_operand" "")
4516 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4520 rtx temp = gen_reg_rtx (DImode);
4521 rtx shift_48 = GEN_INT (48);
4522 int op1_subword = 0;
4524 if (GET_CODE (operand1) == SUBREG)
4526 op1_subword = SUBREG_WORD (operand1);
4527 operand1 = XEXP (operand1, 0);
4530 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4532 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4536 (define_insn "*zero_extendhidi2_insn"
4537 [(set (match_operand:DI 0 "register_operand" "=r")
4538 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4541 [(set_attr "type" "load")
4542 (set_attr "length" "1")])
4545 ;; ??? Write truncdisi pattern using sra?
4547 (define_expand "zero_extendsidi2"
4548 [(set (match_operand:DI 0 "register_operand" "")
4549 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4553 (define_insn "*zero_extendsidi2_insn_sp64"
4554 [(set (match_operand:DI 0 "register_operand" "=r,r")
4555 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4556 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4560 [(set_attr "type" "shift,load")
4561 (set_attr "length" "1")])
4563 (define_insn "*zero_extendsidi2_insn_sp32"
4564 [(set (match_operand:DI 0 "register_operand" "=r")
4565 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4568 [(set_attr "type" "unary")
4569 (set_attr "length" "2")])
4572 [(set (match_operand:DI 0 "register_operand" "")
4573 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4574 "! TARGET_ARCH64 && reload_completed"
4575 [(set (match_dup 2) (match_dup 3))
4576 (set (match_dup 4) (match_dup 5))]
4581 if (GET_CODE (operands[0]) == SUBREG)
4582 operands[0] = alter_subreg (operands[0]);
4584 dest1 = gen_highpart (SImode, operands[0]);
4585 dest2 = gen_lowpart (SImode, operands[0]);
4587 /* Swap the order in case of overlap. */
4588 if (REGNO (dest1) == REGNO (operands[1]))
4590 operands[2] = dest2;
4591 operands[3] = operands[1];
4592 operands[4] = dest1;
4593 operands[5] = const0_rtx;
4597 operands[2] = dest1;
4598 operands[3] = const0_rtx;
4599 operands[4] = dest2;
4600 operands[5] = operands[1];
4604 ;; Simplify comparisons of extended values.
4606 (define_insn "*cmp_zero_extendqisi2"
4608 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4611 "andcc\\t%0, 0xff, %%g0"
4612 [(set_attr "type" "compare")
4613 (set_attr "length" "1")])
4615 (define_insn "*cmp_zero_qi"
4617 (compare:CC (match_operand:QI 0 "register_operand" "r")
4620 "andcc\\t%0, 0xff, %%g0"
4621 [(set_attr "type" "compare")
4622 (set_attr "length" "1")])
4624 (define_insn "*cmp_zero_extendqisi2_set"
4626 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4628 (set (match_operand:SI 0 "register_operand" "=r")
4629 (zero_extend:SI (match_dup 1)))]
4631 "andcc\\t%1, 0xff, %0"
4632 [(set_attr "type" "compare")
4633 (set_attr "length" "1")])
4635 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4637 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4640 (set (match_operand:SI 0 "register_operand" "=r")
4641 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4643 "andcc\\t%1, 0xff, %0"
4644 [(set_attr "type" "compare")
4645 (set_attr "length" "1")])
4647 (define_insn "*cmp_zero_extendqidi2"
4649 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4652 "andcc\\t%0, 0xff, %%g0"
4653 [(set_attr "type" "compare")
4654 (set_attr "length" "1")])
4656 (define_insn "*cmp_zero_qi_sp64"
4658 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4661 "andcc\\t%0, 0xff, %%g0"
4662 [(set_attr "type" "compare")
4663 (set_attr "length" "1")])
4665 (define_insn "*cmp_zero_extendqidi2_set"
4667 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4669 (set (match_operand:DI 0 "register_operand" "=r")
4670 (zero_extend:DI (match_dup 1)))]
4672 "andcc\\t%1, 0xff, %0"
4673 [(set_attr "type" "compare")
4674 (set_attr "length" "1")])
4676 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4678 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4681 (set (match_operand:DI 0 "register_operand" "=r")
4682 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4684 "andcc\\t%1, 0xff, %0"
4685 [(set_attr "type" "compare")
4686 (set_attr "length" "1")])
4688 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4690 (define_insn "*cmp_siqi_trunc"
4692 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4695 "andcc\\t%0, 0xff, %%g0"
4696 [(set_attr "type" "compare")
4697 (set_attr "length" "1")])
4699 (define_insn "*cmp_siqi_trunc_set"
4701 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4703 (set (match_operand:QI 0 "register_operand" "=r")
4704 (subreg:QI (match_dup 1) 0))]
4706 "andcc\\t%1, 0xff, %0"
4707 [(set_attr "type" "compare")
4708 (set_attr "length" "1")])
4710 (define_insn "*cmp_diqi_trunc"
4712 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4715 "andcc\\t%0, 0xff, %%g0"
4716 [(set_attr "type" "compare")
4717 (set_attr "length" "1")])
4719 (define_insn "*cmp_diqi_trunc_set"
4721 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4723 (set (match_operand:QI 0 "register_operand" "=r")
4724 (subreg:QI (match_dup 1) 0))]
4726 "andcc\\t%1, 0xff, %0"
4727 [(set_attr "type" "compare")
4728 (set_attr "length" "1")])
4730 ;;- sign extension instructions
4732 ;; These patterns originally accepted general_operands, however, slightly
4733 ;; better code is generated by only accepting register_operands, and then
4734 ;; letting combine generate the lds[hb] insns.
4736 (define_expand "extendhisi2"
4737 [(set (match_operand:SI 0 "register_operand" "")
4738 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4742 rtx temp = gen_reg_rtx (SImode);
4743 rtx shift_16 = GEN_INT (16);
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_16));
4758 (define_insn "*sign_extendhisi2_insn"
4759 [(set (match_operand:SI 0 "register_operand" "=r")
4760 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4763 [(set_attr "type" "sload")
4764 (set_attr "length" "1")])
4766 (define_expand "extendqihi2"
4767 [(set (match_operand:HI 0 "register_operand" "")
4768 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4772 rtx temp = gen_reg_rtx (SImode);
4773 rtx shift_24 = GEN_INT (24);
4774 int op1_subword = 0;
4775 int op0_subword = 0;
4777 if (GET_CODE (operand1) == SUBREG)
4779 op1_subword = SUBREG_WORD (operand1);
4780 operand1 = XEXP (operand1, 0);
4782 if (GET_CODE (operand0) == SUBREG)
4784 op0_subword = SUBREG_WORD (operand0);
4785 operand0 = XEXP (operand0, 0);
4787 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4789 if (GET_MODE (operand0) != SImode)
4790 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4791 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4795 (define_insn "*sign_extendqihi2_insn"
4796 [(set (match_operand:HI 0 "register_operand" "=r")
4797 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4800 [(set_attr "type" "sload")
4801 (set_attr "length" "1")])
4803 (define_expand "extendqisi2"
4804 [(set (match_operand:SI 0 "register_operand" "")
4805 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4809 rtx temp = gen_reg_rtx (SImode);
4810 rtx shift_24 = GEN_INT (24);
4811 int op1_subword = 0;
4813 if (GET_CODE (operand1) == SUBREG)
4815 op1_subword = SUBREG_WORD (operand1);
4816 operand1 = XEXP (operand1, 0);
4819 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4821 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4825 (define_insn "*sign_extendqisi2_insn"
4826 [(set (match_operand:SI 0 "register_operand" "=r")
4827 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4830 [(set_attr "type" "sload")
4831 (set_attr "length" "1")])
4833 (define_expand "extendqidi2"
4834 [(set (match_operand:DI 0 "register_operand" "")
4835 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4839 rtx temp = gen_reg_rtx (DImode);
4840 rtx shift_56 = GEN_INT (56);
4841 int op1_subword = 0;
4843 if (GET_CODE (operand1) == SUBREG)
4845 op1_subword = SUBREG_WORD (operand1);
4846 operand1 = XEXP (operand1, 0);
4849 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4851 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4855 (define_insn "*sign_extendqidi2_insn"
4856 [(set (match_operand:DI 0 "register_operand" "=r")
4857 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4860 [(set_attr "type" "sload")
4861 (set_attr "length" "1")])
4863 (define_expand "extendhidi2"
4864 [(set (match_operand:DI 0 "register_operand" "")
4865 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4869 rtx temp = gen_reg_rtx (DImode);
4870 rtx shift_48 = GEN_INT (48);
4871 int op1_subword = 0;
4873 if (GET_CODE (operand1) == SUBREG)
4875 op1_subword = SUBREG_WORD (operand1);
4876 operand1 = XEXP (operand1, 0);
4879 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4881 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4885 (define_insn "*sign_extendhidi2_insn"
4886 [(set (match_operand:DI 0 "register_operand" "=r")
4887 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4890 [(set_attr "type" "sload")
4891 (set_attr "length" "1")])
4893 (define_expand "extendsidi2"
4894 [(set (match_operand:DI 0 "register_operand" "")
4895 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4899 (define_insn "*sign_extendsidi2_insn"
4900 [(set (match_operand:DI 0 "register_operand" "=r,r")
4901 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4906 [(set_attr "type" "shift,sload")
4907 (set_attr "length" "1")])
4909 ;; Special pattern for optimizing bit-field compares. This is needed
4910 ;; because combine uses this as a canonical form.
4912 (define_insn "*cmp_zero_extract"
4915 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4916 (match_operand:SI 1 "small_int_or_double" "n")
4917 (match_operand:SI 2 "small_int_or_double" "n"))
4920 && ((GET_CODE (operands[2]) == CONST_INT
4921 && INTVAL (operands[2]) > 19)
4922 || (GET_CODE (operands[2]) == CONST_DOUBLE
4923 && CONST_DOUBLE_LOW (operands[2]) > 19))"
4926 int len = (GET_CODE (operands[1]) == CONST_INT
4927 ? INTVAL (operands[1])
4928 : CONST_DOUBLE_LOW (operands[1]));
4930 (GET_CODE (operands[2]) == CONST_INT
4931 ? INTVAL (operands[2])
4932 : CONST_DOUBLE_LOW (operands[2])) - len;
4933 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4935 operands[1] = GEN_INT (mask);
4936 return \"andcc\\t%0, %1, %%g0\";
4938 [(set_attr "type" "compare")
4939 (set_attr "length" "1")])
4941 (define_insn "*cmp_zero_extract_sp64"
4944 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4945 (match_operand:SI 1 "small_int_or_double" "n")
4946 (match_operand:SI 2 "small_int_or_double" "n"))
4949 && ((GET_CODE (operands[2]) == CONST_INT
4950 && INTVAL (operands[2]) > 51)
4951 || (GET_CODE (operands[2]) == CONST_DOUBLE
4952 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4955 int len = (GET_CODE (operands[1]) == CONST_INT
4956 ? INTVAL (operands[1])
4957 : CONST_DOUBLE_LOW (operands[1]));
4959 (GET_CODE (operands[2]) == CONST_INT
4960 ? INTVAL (operands[2])
4961 : CONST_DOUBLE_LOW (operands[2])) - len;
4962 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4964 operands[1] = GEN_INT (mask);
4965 return \"andcc\\t%0, %1, %%g0\";
4967 [(set_attr "type" "compare")
4968 (set_attr "length" "1")])
4970 ;; Conversions between float, double and long double.
4972 (define_insn "extendsfdf2"
4973 [(set (match_operand:DF 0 "register_operand" "=e")
4975 (match_operand:SF 1 "register_operand" "f")))]
4978 [(set_attr "type" "fp")
4979 (set_attr "length" "1")])
4981 (define_expand "extendsftf2"
4982 [(set (match_operand:TF 0 "register_operand" "=e")
4984 (match_operand:SF 1 "register_operand" "f")))]
4985 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4988 if (! TARGET_HARD_QUAD)
4992 if (GET_CODE (operands[0]) != MEM)
4993 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
4995 slot0 = operands[0];
4997 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
4999 XEXP (slot0, 0), Pmode,
5000 operands[1], SFmode);
5002 if (GET_CODE (operands[0]) != MEM)
5003 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5008 (define_insn "*extendsftf2_hq"
5009 [(set (match_operand:TF 0 "register_operand" "=e")
5011 (match_operand:SF 1 "register_operand" "f")))]
5012 "TARGET_FPU && TARGET_HARD_QUAD"
5014 [(set_attr "type" "fp")
5015 (set_attr "length" "1")])
5017 (define_expand "extenddftf2"
5018 [(set (match_operand:TF 0 "register_operand" "=e")
5020 (match_operand:DF 1 "register_operand" "e")))]
5021 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5024 if (! TARGET_HARD_QUAD)
5028 if (GET_CODE (operands[0]) != MEM)
5029 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5031 slot0 = operands[0];
5033 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5035 XEXP (slot0, 0), Pmode,
5036 operands[1], DFmode);
5038 if (GET_CODE (operands[0]) != MEM)
5039 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5044 (define_insn "*extenddftf2_hq"
5045 [(set (match_operand:TF 0 "register_operand" "=e")
5047 (match_operand:DF 1 "register_operand" "e")))]
5048 "TARGET_FPU && TARGET_HARD_QUAD"
5050 [(set_attr "type" "fp")
5051 (set_attr "length" "1")])
5053 (define_insn "truncdfsf2"
5054 [(set (match_operand:SF 0 "register_operand" "=f")
5056 (match_operand:DF 1 "register_operand" "e")))]
5059 [(set_attr "type" "fp")
5060 (set_attr "length" "1")])
5062 (define_expand "trunctfsf2"
5063 [(set (match_operand:SF 0 "register_operand" "=f")
5065 (match_operand:TF 1 "register_operand" "e")))]
5066 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5069 if (! TARGET_HARD_QUAD)
5073 if (GET_CODE (operands[1]) != MEM)
5075 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5076 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5079 slot0 = operands[1];
5081 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5082 operands[0], 0, SFmode, 1,
5083 XEXP (slot0, 0), Pmode);
5088 (define_insn "*trunctfsf2_hq"
5089 [(set (match_operand:SF 0 "register_operand" "=f")
5091 (match_operand:TF 1 "register_operand" "e")))]
5092 "TARGET_FPU && TARGET_HARD_QUAD"
5094 [(set_attr "type" "fp")
5095 (set_attr "length" "1")])
5097 (define_expand "trunctfdf2"
5098 [(set (match_operand:DF 0 "register_operand" "=f")
5100 (match_operand:TF 1 "register_operand" "e")))]
5101 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5104 if (! TARGET_HARD_QUAD)
5108 if (GET_CODE (operands[1]) != MEM)
5110 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5111 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5114 slot0 = operands[1];
5116 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5117 operands[0], 0, DFmode, 1,
5118 XEXP (slot0, 0), Pmode);
5123 (define_insn "*trunctfdf2_hq"
5124 [(set (match_operand:DF 0 "register_operand" "=e")
5126 (match_operand:TF 1 "register_operand" "e")))]
5127 "TARGET_FPU && TARGET_HARD_QUAD"
5129 [(set_attr "type" "fp")
5130 (set_attr "length" "1")])
5132 ;; Conversion between fixed point and floating point.
5134 (define_insn "floatsisf2"
5135 [(set (match_operand:SF 0 "register_operand" "=f")
5136 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5139 [(set_attr "type" "fp")
5140 (set_attr "length" "1")])
5142 (define_insn "floatsidf2"
5143 [(set (match_operand:DF 0 "register_operand" "=e")
5144 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5147 [(set_attr "type" "fp")
5148 (set_attr "length" "1")])
5150 (define_expand "floatsitf2"
5151 [(set (match_operand:TF 0 "register_operand" "=e")
5152 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5153 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5156 if (! TARGET_HARD_QUAD)
5160 if (GET_CODE (operands[1]) != MEM)
5161 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5163 slot0 = operands[1];
5165 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5167 XEXP (slot0, 0), Pmode,
5168 operands[1], SImode);
5170 if (GET_CODE (operands[0]) != MEM)
5171 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5176 (define_insn "*floatsitf2_hq"
5177 [(set (match_operand:TF 0 "register_operand" "=e")
5178 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5179 "TARGET_FPU && TARGET_HARD_QUAD"
5181 [(set_attr "type" "fp")
5182 (set_attr "length" "1")])
5184 (define_expand "floatunssitf2"
5185 [(set (match_operand:TF 0 "register_operand" "=e")
5186 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5187 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5192 if (GET_CODE (operands[1]) != MEM)
5193 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5195 slot0 = operands[1];
5197 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5199 XEXP (slot0, 0), Pmode,
5200 operands[1], SImode);
5202 if (GET_CODE (operands[0]) != MEM)
5203 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5207 ;; Now the same for 64 bit sources.
5209 (define_insn "floatdisf2"
5210 [(set (match_operand:SF 0 "register_operand" "=f")
5211 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5212 "TARGET_V9 && TARGET_FPU"
5214 [(set_attr "type" "fp")
5215 (set_attr "length" "1")])
5217 (define_insn "floatdidf2"
5218 [(set (match_operand:DF 0 "register_operand" "=e")
5219 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5220 "TARGET_V9 && TARGET_FPU"
5222 [(set_attr "type" "fp")
5223 (set_attr "length" "1")])
5225 (define_expand "floatditf2"
5226 [(set (match_operand:TF 0 "register_operand" "=e")
5227 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5228 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5231 if (! TARGET_HARD_QUAD)
5235 if (GET_CODE (operands[1]) != MEM)
5236 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5238 slot0 = operands[1];
5240 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5242 XEXP (slot0, 0), Pmode,
5243 operands[1], DImode);
5245 if (GET_CODE (operands[0]) != MEM)
5246 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5251 (define_insn "*floatditf2_hq"
5252 [(set (match_operand:TF 0 "register_operand" "=e")
5253 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5254 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5256 [(set_attr "type" "fp")
5257 (set_attr "length" "1")])
5259 (define_expand "floatunsditf2"
5260 [(set (match_operand:TF 0 "register_operand" "=e")
5261 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5262 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5267 if (GET_CODE (operands[1]) != MEM)
5268 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5270 slot0 = operands[1];
5272 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5274 XEXP (slot0, 0), Pmode,
5275 operands[1], DImode);
5277 if (GET_CODE (operands[0]) != MEM)
5278 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5282 ;; Convert a float to an actual integer.
5283 ;; Truncation is performed as part of the conversion.
5285 (define_insn "fix_truncsfsi2"
5286 [(set (match_operand:SI 0 "register_operand" "=f")
5287 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5290 [(set_attr "type" "fp")
5291 (set_attr "length" "1")])
5293 (define_insn "fix_truncdfsi2"
5294 [(set (match_operand:SI 0 "register_operand" "=f")
5295 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5298 [(set_attr "type" "fp")
5299 (set_attr "length" "1")])
5301 (define_expand "fix_trunctfsi2"
5302 [(set (match_operand:SI 0 "register_operand" "=f")
5303 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5304 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5307 if (! TARGET_HARD_QUAD)
5311 if (GET_CODE (operands[1]) != MEM)
5313 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5314 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5317 slot0 = operands[1];
5319 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5320 operands[0], 0, SImode, 1,
5321 XEXP (slot0, 0), Pmode);
5326 (define_insn "*fix_trunctfsi2_hq"
5327 [(set (match_operand:SI 0 "register_operand" "=f")
5328 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5329 "TARGET_FPU && TARGET_HARD_QUAD"
5331 [(set_attr "type" "fp")
5332 (set_attr "length" "1")])
5334 (define_expand "fixuns_trunctfsi2"
5335 [(set (match_operand:SI 0 "register_operand" "=f")
5336 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5337 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5342 if (GET_CODE (operands[1]) != MEM)
5344 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5345 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5348 slot0 = operands[1];
5350 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5351 operands[0], 0, SImode, 1,
5352 XEXP (slot0, 0), Pmode);
5356 ;; Now the same, for V9 targets
5358 (define_insn "fix_truncsfdi2"
5359 [(set (match_operand:DI 0 "register_operand" "=e")
5360 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5361 "TARGET_V9 && TARGET_FPU"
5363 [(set_attr "type" "fp")
5364 (set_attr "length" "1")])
5366 (define_insn "fix_truncdfdi2"
5367 [(set (match_operand:DI 0 "register_operand" "=e")
5368 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5369 "TARGET_V9 && TARGET_FPU"
5371 [(set_attr "type" "fp")
5372 (set_attr "length" "1")])
5374 (define_expand "fix_trunctfdi2"
5375 [(set (match_operand:DI 0 "register_operand" "=e")
5376 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5377 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5380 if (! TARGET_HARD_QUAD)
5384 if (GET_CODE (operands[1]) != MEM)
5386 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5387 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5390 slot0 = operands[1];
5392 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5393 operands[0], 0, DImode, 1,
5394 XEXP (slot0, 0), Pmode);
5399 (define_insn "*fix_trunctfdi2_hq"
5400 [(set (match_operand:DI 0 "register_operand" "=e")
5401 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5402 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5404 [(set_attr "type" "fp")
5405 (set_attr "length" "1")])
5407 (define_expand "fixuns_trunctfdi2"
5408 [(set (match_operand:DI 0 "register_operand" "=f")
5409 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5410 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5415 if (GET_CODE (operands[1]) != MEM)
5417 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5418 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5421 slot0 = operands[1];
5423 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5424 operands[0], 0, DImode, 1,
5425 XEXP (slot0, 0), Pmode);
5430 ;;- arithmetic instructions
5432 (define_expand "adddi3"
5433 [(set (match_operand:DI 0 "register_operand" "=r")
5434 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5435 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5439 if (! TARGET_ARCH64)
5441 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5442 gen_rtx_SET (VOIDmode, operands[0],
5443 gen_rtx_PLUS (DImode, operands[1],
5445 gen_rtx_CLOBBER (VOIDmode,
5446 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5449 if (arith_double_4096_operand(operands[2], DImode))
5451 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5452 gen_rtx_MINUS (DImode, operands[1],
5458 (define_insn "adddi3_insn_sp32"
5459 [(set (match_operand:DI 0 "register_operand" "=r")
5460 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5461 (match_operand:DI 2 "arith_double_operand" "rHI")))
5462 (clobber (reg:CC 100))]
5465 [(set_attr "length" "2")])
5468 [(set (match_operand:DI 0 "register_operand" "=r")
5469 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5470 (match_operand:DI 2 "arith_double_operand" "rHI")))
5471 (clobber (reg:CC 100))]
5472 "! TARGET_ARCH64 && reload_completed"
5473 [(parallel [(set (reg:CC_NOOV 100)
5474 (compare:CC_NOOV (plus:SI (match_dup 4)
5478 (plus:SI (match_dup 4) (match_dup 5)))])
5480 (plus:SI (plus:SI (match_dup 7)
5482 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5485 operands[3] = gen_lowpart (SImode, operands[0]);
5486 operands[4] = gen_lowpart (SImode, operands[1]);
5487 operands[5] = gen_lowpart (SImode, operands[2]);
5488 operands[6] = gen_highpart (SImode, operands[0]);
5489 operands[7] = gen_highpart (SImode, operands[1]);
5490 if (GET_CODE (operands[2]) == CONST_INT)
5492 if (INTVAL (operands[2]) < 0)
5493 operands[8] = constm1_rtx;
5495 operands[8] = const0_rtx;
5498 operands[8] = gen_highpart (SImode, operands[2]);
5502 [(set (match_operand:DI 0 "register_operand" "=r")
5503 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
5504 (match_operand:DI 2 "arith_double_operand" "rHI")))
5505 (clobber (reg:CC 100))]
5506 "! TARGET_ARCH64 && reload_completed"
5507 [(parallel [(set (reg:CC_NOOV 100)
5508 (compare:CC_NOOV (minus:SI (match_dup 4)
5512 (minus:SI (match_dup 4) (match_dup 5)))])
5514 (minus:SI (minus:SI (match_dup 7)
5516 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5519 operands[3] = gen_lowpart (SImode, operands[0]);
5520 operands[4] = gen_lowpart (SImode, operands[1]);
5521 operands[5] = gen_lowpart (SImode, operands[2]);
5522 operands[6] = gen_highpart (SImode, operands[0]);
5523 operands[7] = gen_highpart (SImode, operands[1]);
5524 if (GET_CODE (operands[2]) == CONST_INT)
5526 if (INTVAL (operands[2]) < 0)
5527 operands[8] = constm1_rtx;
5529 operands[8] = const0_rtx;
5532 operands[8] = gen_highpart (SImode, operands[2]);
5535 ;; LTU here means "carry set"
5537 [(set (match_operand:SI 0 "register_operand" "=r")
5538 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5539 (match_operand:SI 2 "arith_operand" "rI"))
5540 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5543 [(set_attr "type" "unary")
5544 (set_attr "length" "1")])
5546 (define_insn "*addx_extend_sp32"
5547 [(set (match_operand:DI 0 "register_operand" "=r")
5548 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5549 (match_operand:SI 2 "arith_operand" "rI"))
5550 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5553 [(set_attr "type" "unary")
5554 (set_attr "length" "2")])
5557 [(set (match_operand:DI 0 "register_operand" "")
5558 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5559 (match_operand:SI 2 "arith_operand" ""))
5560 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5561 "! TARGET_ARCH64 && reload_completed"
5562 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5563 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5564 (set (match_dup 4) (const_int 0))]
5565 "operands[3] = gen_lowpart (SImode, operands[0]);
5566 operands[4] = gen_highpart (SImode, operands[1]);")
5568 (define_insn "*addx_extend_sp64"
5569 [(set (match_operand:DI 0 "register_operand" "=r")
5570 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5571 (match_operand:SI 2 "arith_operand" "rI"))
5572 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5574 "addx\\t%r1, %2, %0"
5575 [(set_attr "type" "misc")
5576 (set_attr "length" "1")])
5579 [(set (match_operand:SI 0 "register_operand" "=r")
5580 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5581 (match_operand:SI 2 "arith_operand" "rI"))
5582 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5584 "subx\\t%r1, %2, %0"
5585 [(set_attr "type" "misc")
5586 (set_attr "length" "1")])
5588 (define_insn "*subx_extend_sp64"
5589 [(set (match_operand:DI 0 "register_operand" "=r")
5590 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5591 (match_operand:SI 2 "arith_operand" "rI"))
5592 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5594 "subx\\t%r1, %2, %0"
5595 [(set_attr "type" "misc")
5596 (set_attr "length" "1")])
5598 (define_insn "*subx_extend"
5599 [(set (match_operand:DI 0 "register_operand" "=r")
5600 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5601 (match_operand:SI 2 "arith_operand" "rI"))
5602 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5605 [(set_attr "type" "unary")
5606 (set_attr "length" "2")])
5609 [(set (match_operand:DI 0 "register_operand" "=r")
5610 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5611 (match_operand:SI 2 "arith_operand" "rI"))
5612 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5613 "! TARGET_ARCH64 && reload_completed"
5614 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5615 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5616 (set (match_dup 4) (const_int 0))]
5617 "operands[3] = gen_lowpart (SImode, operands[0]);
5618 operands[4] = gen_highpart (SImode, operands[0]);")
5621 [(set (match_operand:DI 0 "register_operand" "=r")
5622 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5623 (match_operand:DI 2 "register_operand" "r")))
5624 (clobber (reg:CC 100))]
5627 [(set_attr "type" "multi")
5628 (set_attr "length" "2")])
5631 [(set (match_operand:DI 0 "register_operand" "")
5632 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5633 (match_operand:DI 2 "register_operand" "")))
5634 (clobber (reg:CC 100))]
5635 "! TARGET_ARCH64 && reload_completed"
5636 [(parallel [(set (reg:CC_NOOV 100)
5637 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5639 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5641 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5642 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5643 "operands[3] = gen_lowpart (SImode, operands[2]);
5644 operands[4] = gen_highpart (SImode, operands[2]);
5645 operands[5] = gen_lowpart (SImode, operands[0]);
5646 operands[6] = gen_highpart (SImode, operands[0]);")
5648 (define_insn "*adddi3_sp64"
5649 [(set (match_operand:DI 0 "register_operand" "=r")
5650 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5651 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5654 [(set_attr "type" "binary")
5655 (set_attr "length" "1")])
5657 (define_expand "addsi3"
5658 [(set (match_operand:SI 0 "register_operand" "=r,d")
5659 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5660 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5664 if (arith_4096_operand(operands[2], DImode))
5666 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5667 gen_rtx_MINUS (SImode, operands[1],
5673 (define_insn "*addsi3"
5674 [(set (match_operand:SI 0 "register_operand" "=r,d")
5675 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5676 (match_operand:SI 2 "arith_operand" "rI,d")))]
5680 fpadd32s\\t%1, %2, %0"
5681 [(set_attr "type" "ialu,fp")
5682 (set_attr "length" "1")])
5684 (define_insn "*cmp_cc_plus"
5685 [(set (reg:CC_NOOV 100)
5686 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5687 (match_operand:SI 1 "arith_operand" "rI"))
5690 "addcc\\t%0, %1, %%g0"
5691 [(set_attr "type" "compare")
5692 (set_attr "length" "1")])
5694 (define_insn "*cmp_ccx_plus"
5695 [(set (reg:CCX_NOOV 100)
5696 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5697 (match_operand:DI 1 "arith_double_operand" "rHI"))
5700 "addcc\\t%0, %1, %%g0"
5701 [(set_attr "type" "compare")
5702 (set_attr "length" "1")])
5704 (define_insn "*cmp_cc_plus_set"
5705 [(set (reg:CC_NOOV 100)
5706 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5707 (match_operand:SI 2 "arith_operand" "rI"))
5709 (set (match_operand:SI 0 "register_operand" "=r")
5710 (plus:SI (match_dup 1) (match_dup 2)))]
5712 "addcc\\t%1, %2, %0"
5713 [(set_attr "type" "compare")
5714 (set_attr "length" "1")])
5716 (define_insn "*cmp_ccx_plus_set"
5717 [(set (reg:CCX_NOOV 100)
5718 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5719 (match_operand:DI 2 "arith_double_operand" "rHI"))
5721 (set (match_operand:DI 0 "register_operand" "=r")
5722 (plus:DI (match_dup 1) (match_dup 2)))]
5724 "addcc\\t%1, %2, %0"
5725 [(set_attr "type" "compare")
5726 (set_attr "length" "1")])
5728 (define_expand "subdi3"
5729 [(set (match_operand:DI 0 "register_operand" "=r")
5730 (minus:DI (match_operand:DI 1 "register_operand" "r")
5731 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5735 if (! TARGET_ARCH64)
5737 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5738 gen_rtx_SET (VOIDmode, operands[0],
5739 gen_rtx_MINUS (DImode, operands[1],
5741 gen_rtx_CLOBBER (VOIDmode,
5742 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5745 if (arith_double_4096_operand(operands[2], DImode))
5747 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5748 gen_rtx_PLUS (DImode, operands[1],
5754 (define_insn "*subdi3_sp32"
5755 [(set (match_operand:DI 0 "register_operand" "=r")
5756 (minus:DI (match_operand:DI 1 "register_operand" "r")
5757 (match_operand:DI 2 "arith_double_operand" "rHI")))
5758 (clobber (reg:CC 100))]
5761 [(set_attr "length" "2")])
5764 [(set (match_operand:DI 0 "register_operand" "")
5765 (minus:DI (match_operand:DI 1 "register_operand" "")
5766 (match_operand:DI 2 "arith_double_operand" "")))
5767 (clobber (reg:CC 100))]
5770 && (GET_CODE (operands[2]) == CONST_INT
5771 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5772 [(clobber (const_int 0))]
5777 highp = gen_highpart (SImode, operands[2]);
5778 lowp = gen_lowpart (SImode, operands[2]);
5779 if ((lowp == const0_rtx)
5780 && (operands[0] == operands[1]))
5782 emit_insn (gen_rtx_SET (VOIDmode,
5783 gen_highpart (SImode, operands[0]),
5784 gen_rtx_MINUS (SImode,
5785 gen_highpart (SImode, operands[1]),
5790 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5791 gen_lowpart (SImode, operands[1]),
5793 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5794 gen_highpart (SImode, operands[1]),
5801 [(set (match_operand:DI 0 "register_operand" "")
5802 (minus:DI (match_operand:DI 1 "register_operand" "")
5803 (match_operand:DI 2 "register_operand" "")))
5804 (clobber (reg:CC 100))]
5806 && reload_completed"
5807 [(clobber (const_int 0))]
5810 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5811 gen_lowpart (SImode, operands[1]),
5812 gen_lowpart (SImode, operands[2])));
5813 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5814 gen_highpart (SImode, operands[1]),
5815 gen_highpart (SImode, operands[2])));
5820 [(set (match_operand:DI 0 "register_operand" "=r")
5821 (minus:DI (match_operand:DI 1 "register_operand" "r")
5822 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5823 (clobber (reg:CC 100))]
5826 [(set_attr "type" "multi")
5827 (set_attr "length" "2")])
5830 [(set (match_operand:DI 0 "register_operand" "")
5831 (minus:DI (match_operand:DI 1 "register_operand" "")
5832 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5833 (clobber (reg:CC 100))]
5834 "! TARGET_ARCH64 && reload_completed"
5835 [(parallel [(set (reg:CC_NOOV 100)
5836 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5838 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5840 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5841 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5842 "operands[3] = gen_lowpart (SImode, operands[1]);
5843 operands[4] = gen_highpart (SImode, operands[1]);
5844 operands[5] = gen_lowpart (SImode, operands[0]);
5845 operands[6] = gen_highpart (SImode, operands[0]);")
5847 (define_insn "*subdi3_sp64"
5848 [(set (match_operand:DI 0 "register_operand" "=r")
5849 (minus:DI (match_operand:DI 1 "register_operand" "r")
5850 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5853 [(set_attr "type" "binary")
5854 (set_attr "length" "1")])
5856 (define_expand "subsi3"
5857 [(set (match_operand:SI 0 "register_operand" "=r,d")
5858 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5859 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5863 if (arith_4096_operand(operands[2], DImode))
5865 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5866 gen_rtx_PLUS (SImode, operands[1],
5872 (define_insn "*subsi3"
5873 [(set (match_operand:SI 0 "register_operand" "=r,d")
5874 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5875 (match_operand:SI 2 "arith_operand" "rI,d")))]
5879 fpsub32s\\t%1, %2, %0"
5880 [(set_attr "type" "ialu,fp")
5881 (set_attr "length" "1")])
5883 (define_insn "*cmp_minus_cc"
5884 [(set (reg:CC_NOOV 100)
5885 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5886 (match_operand:SI 1 "arith_operand" "rI"))
5889 "subcc\\t%r0, %1, %%g0"
5890 [(set_attr "type" "compare")
5891 (set_attr "length" "1")])
5893 (define_insn "*cmp_minus_ccx"
5894 [(set (reg:CCX_NOOV 100)
5895 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5896 (match_operand:DI 1 "arith_double_operand" "rHI"))
5899 "subcc\\t%0, %1, %%g0"
5900 [(set_attr "type" "compare")
5901 (set_attr "length" "1")])
5903 (define_insn "cmp_minus_cc_set"
5904 [(set (reg:CC_NOOV 100)
5905 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5906 (match_operand:SI 2 "arith_operand" "rI"))
5908 (set (match_operand:SI 0 "register_operand" "=r")
5909 (minus:SI (match_dup 1) (match_dup 2)))]
5911 "subcc\\t%r1, %2, %0"
5912 [(set_attr "type" "compare")
5913 (set_attr "length" "1")])
5915 (define_insn "*cmp_minus_ccx_set"
5916 [(set (reg:CCX_NOOV 100)
5917 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5918 (match_operand:DI 2 "arith_double_operand" "rHI"))
5920 (set (match_operand:DI 0 "register_operand" "=r")
5921 (minus:DI (match_dup 1) (match_dup 2)))]
5923 "subcc\\t%1, %2, %0"
5924 [(set_attr "type" "compare")
5925 (set_attr "length" "1")])
5927 ;; Integer Multiply/Divide.
5929 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5930 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5932 (define_insn "mulsi3"
5933 [(set (match_operand:SI 0 "register_operand" "=r")
5934 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5935 (match_operand:SI 2 "arith_operand" "rI")))]
5938 [(set_attr "type" "imul")
5939 (set_attr "length" "1")])
5941 (define_expand "muldi3"
5942 [(set (match_operand:DI 0 "register_operand" "=r")
5943 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5944 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5945 "TARGET_ARCH64 || TARGET_V8PLUS"
5950 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5955 (define_insn "*muldi3_sp64"
5956 [(set (match_operand:DI 0 "register_operand" "=r")
5957 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5958 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5961 [(set_attr "type" "imul")
5962 (set_attr "length" "1")])
5964 ;; V8plus wide multiply.
5966 (define_insn "muldi3_v8plus"
5967 [(set (match_operand:DI 0 "register_operand" "=r,h")
5968 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5969 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5970 (clobber (match_scratch:SI 3 "=&h,X"))
5971 (clobber (match_scratch:SI 4 "=&h,X"))]
5975 if (sparc_check_64 (operands[1], insn) <= 0)
5976 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5977 if (which_alternative == 1)
5978 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5979 if (sparc_check_64 (operands[2], insn) <= 0)
5980 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5981 if (which_alternative == 1)
5982 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\";
5984 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\";
5986 [(set_attr "length" "9,8")])
5988 (define_insn "*cmp_mul_set"
5990 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5991 (match_operand:SI 2 "arith_operand" "rI"))
5993 (set (match_operand:SI 0 "register_operand" "=r")
5994 (mult:SI (match_dup 1) (match_dup 2)))]
5995 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5996 "smulcc\\t%1, %2, %0"
5997 [(set_attr "type" "imul")
5998 (set_attr "length" "1")])
6000 (define_expand "mulsidi3"
6001 [(set (match_operand:DI 0 "register_operand" "")
6002 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6003 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6007 if (CONSTANT_P (operands[2]))
6010 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6013 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6019 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6024 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6025 ;; registers can hold 64 bit values in the V8plus environment.
6027 (define_insn "mulsidi3_v8plus"
6028 [(set (match_operand:DI 0 "register_operand" "=h,r")
6029 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6030 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6031 (clobber (match_scratch:SI 3 "=X,&h"))]
6034 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6035 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6036 [(set_attr "length" "2,3")])
6039 (define_insn "const_mulsidi3_v8plus"
6040 [(set (match_operand:DI 0 "register_operand" "=h,r")
6041 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6042 (match_operand:SI 2 "small_int" "I,I")))
6043 (clobber (match_scratch:SI 3 "=X,&h"))]
6046 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6047 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6048 [(set_attr "length" "2,3")])
6051 (define_insn "*mulsidi3_sp32"
6052 [(set (match_operand:DI 0 "register_operand" "=r")
6053 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6054 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6058 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6060 [(set (attr "length")
6061 (if_then_else (eq_attr "isa" "sparclet")
6062 (const_int 1) (const_int 2)))])
6064 (define_insn "*mulsidi3_sp64"
6065 [(set (match_operand:DI 0 "register_operand" "=r")
6066 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6067 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6068 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6070 [(set_attr "length" "1")])
6072 ;; Extra pattern, because sign_extend of a constant isn't valid.
6075 (define_insn "const_mulsidi3_sp32"
6076 [(set (match_operand:DI 0 "register_operand" "=r")
6077 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6078 (match_operand:SI 2 "small_int" "I")))]
6082 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6084 [(set (attr "length")
6085 (if_then_else (eq_attr "isa" "sparclet")
6086 (const_int 1) (const_int 2)))])
6088 (define_insn "const_mulsidi3_sp64"
6089 [(set (match_operand:DI 0 "register_operand" "=r")
6090 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6091 (match_operand:SI 2 "small_int" "I")))]
6092 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6094 [(set_attr "length" "1")])
6096 (define_expand "smulsi3_highpart"
6097 [(set (match_operand:SI 0 "register_operand" "")
6099 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6100 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6102 "TARGET_HARD_MUL && TARGET_ARCH32"
6105 if (CONSTANT_P (operands[2]))
6109 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6115 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6120 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6121 operands[2], GEN_INT (32)));
6127 (define_insn "smulsi3_highpart_v8plus"
6128 [(set (match_operand:SI 0 "register_operand" "=h,r")
6130 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6131 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6132 (match_operand:SI 3 "const_int_operand" "i,i"))))
6133 (clobber (match_scratch:SI 4 "=X,&h"))]
6136 smul %1,%2,%0\;srlx %0,%3,%0
6137 smul %1,%2,%4\;srlx %4,%3,%0"
6138 [(set_attr "length" "2")])
6140 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6143 [(set (match_operand:SI 0 "register_operand" "=h,r")
6146 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6147 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6148 (match_operand:SI 3 "const_int_operand" "i,i"))
6150 (clobber (match_scratch:SI 4 "=X,&h"))]
6153 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6154 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6155 [(set_attr "length" "2")])
6158 (define_insn "const_smulsi3_highpart_v8plus"
6159 [(set (match_operand:SI 0 "register_operand" "=h,r")
6161 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6162 (match_operand 2 "small_int" "i,i"))
6163 (match_operand:SI 3 "const_int_operand" "i,i"))))
6164 (clobber (match_scratch:SI 4 "=X,&h"))]
6167 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6168 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6169 [(set_attr "length" "2")])
6172 (define_insn "*smulsi3_highpart_sp32"
6173 [(set (match_operand:SI 0 "register_operand" "=r")
6175 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6176 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6178 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
6179 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6180 [(set_attr "length" "2")])
6183 (define_insn "const_smulsi3_highpart"
6184 [(set (match_operand:SI 0 "register_operand" "=r")
6186 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6187 (match_operand:SI 2 "register_operand" "r"))
6189 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
6190 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6191 [(set_attr "length" "2")])
6193 (define_expand "umulsidi3"
6194 [(set (match_operand:DI 0 "register_operand" "")
6195 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6196 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6200 if (CONSTANT_P (operands[2]))
6203 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6206 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6212 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6218 (define_insn "umulsidi3_v8plus"
6219 [(set (match_operand:DI 0 "register_operand" "=h,r")
6220 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6221 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6222 (clobber (match_scratch:SI 3 "=X,&h"))]
6225 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6226 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6227 [(set_attr "length" "2,3")])
6230 (define_insn "*umulsidi3_sp32"
6231 [(set (match_operand:DI 0 "register_operand" "=r")
6232 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6233 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6237 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6239 [(set (attr "length")
6240 (if_then_else (eq_attr "isa" "sparclet")
6241 (const_int 1) (const_int 2)))])
6243 (define_insn "*umulsidi3_sp64"
6244 [(set (match_operand:DI 0 "register_operand" "=r")
6245 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6246 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6247 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6249 [(set_attr "length" "1")])
6251 ;; Extra pattern, because sign_extend of a constant isn't valid.
6254 (define_insn "const_umulsidi3_sp32"
6255 [(set (match_operand:DI 0 "register_operand" "=r")
6256 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6257 (match_operand:SI 2 "uns_small_int" "")))]
6261 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6263 [(set (attr "length")
6264 (if_then_else (eq_attr "isa" "sparclet")
6265 (const_int 1) (const_int 2)))])
6267 (define_insn "const_umulsidi3_sp64"
6268 [(set (match_operand:DI 0 "register_operand" "=r")
6269 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6270 (match_operand:SI 2 "uns_small_int" "")))]
6271 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6273 [(set_attr "length" "1")])
6276 (define_insn "const_umulsidi3_v8plus"
6277 [(set (match_operand:DI 0 "register_operand" "=h,r")
6278 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6279 (match_operand:SI 2 "uns_small_int" "")))
6280 (clobber (match_scratch:SI 3 "=X,h"))]
6283 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6284 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6285 [(set_attr "length" "2,3")])
6287 (define_expand "umulsi3_highpart"
6288 [(set (match_operand:SI 0 "register_operand" "")
6290 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6291 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6293 "TARGET_HARD_MUL && TARGET_ARCH32"
6296 if (CONSTANT_P (operands[2]))
6300 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6306 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6311 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6312 operands[2], GEN_INT (32)));
6318 (define_insn "umulsi3_highpart_v8plus"
6319 [(set (match_operand:SI 0 "register_operand" "=h,r")
6321 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6322 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6323 (match_operand:SI 3 "const_int_operand" "i,i"))))
6324 (clobber (match_scratch:SI 4 "=X,h"))]
6327 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6328 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6329 [(set_attr "length" "2")])
6332 (define_insn "const_umulsi3_highpart_v8plus"
6333 [(set (match_operand:SI 0 "register_operand" "=h,r")
6335 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6336 (match_operand:SI 2 "uns_small_int" ""))
6337 (match_operand:SI 3 "const_int_operand" "i,i"))))
6338 (clobber (match_scratch:SI 4 "=X,h"))]
6341 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6342 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6343 [(set_attr "length" "2")])
6346 (define_insn "*umulsi3_highpart_sp32"
6347 [(set (match_operand:SI 0 "register_operand" "=r")
6349 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6350 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6352 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
6353 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6354 [(set_attr "length" "2")])
6357 (define_insn "const_umulsi3_highpart"
6358 [(set (match_operand:SI 0 "register_operand" "=r")
6360 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6361 (match_operand:SI 2 "uns_small_int" ""))
6363 "TARGET_HARD_MUL32 && ! TARGET_LIVE_G0"
6364 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6365 [(set_attr "length" "2")])
6367 ;; The v8 architecture specifies that there must be 3 instructions between
6368 ;; a y register write and a use of it for correct results.
6370 (define_expand "divsi3"
6371 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6372 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6373 (match_operand:SI 2 "input_operand" "rI,m")))
6374 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6375 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6380 operands[3] = gen_reg_rtx(SImode);
6381 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6382 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6388 (define_insn "divsi3_sp32"
6389 [(set (match_operand:SI 0 "register_operand" "=r,r")
6390 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6391 (match_operand:SI 2 "input_operand" "rI,m")))
6392 (clobber (match_scratch:SI 3 "=&r,&r"))]
6393 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6397 if (which_alternative == 0)
6399 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6401 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6404 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6406 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\";
6408 [(set (attr "length")
6409 (if_then_else (eq_attr "isa" "v9")
6410 (const_int 4) (const_int 7)))])
6412 (define_insn "divsi3_sp64"
6413 [(set (match_operand:SI 0 "register_operand" "=r")
6414 (div:SI (match_operand:SI 1 "register_operand" "r")
6415 (match_operand:SI 2 "input_operand" "rI")))
6416 (use (match_operand:SI 3 "register_operand" "r"))]
6417 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6418 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6419 [(set_attr "length" "2")])
6421 (define_insn "divdi3"
6422 [(set (match_operand:DI 0 "register_operand" "=r")
6423 (div:DI (match_operand:DI 1 "register_operand" "r")
6424 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6426 "sdivx\\t%1, %2, %0")
6428 (define_insn "*cmp_sdiv_cc_set"
6430 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6431 (match_operand:SI 2 "arith_operand" "rI"))
6433 (set (match_operand:SI 0 "register_operand" "=r")
6434 (div:SI (match_dup 1) (match_dup 2)))
6435 (clobber (match_scratch:SI 3 "=&r"))]
6436 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6440 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6442 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6444 [(set (attr "length")
6445 (if_then_else (eq_attr "isa" "v9")
6446 (const_int 3) (const_int 6)))])
6449 (define_expand "udivsi3"
6450 [(set (match_operand:SI 0 "register_operand" "")
6451 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6452 (match_operand:SI 2 "input_operand" "")))]
6453 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && ! TARGET_LIVE_G0"
6456 (define_insn "udivsi3_sp32"
6457 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6458 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6459 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6461 || TARGET_DEPRECATED_V8_INSNS)
6462 && TARGET_ARCH32 && ! TARGET_LIVE_G0"
6465 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6466 switch (which_alternative)
6469 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6471 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6473 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6476 [(set_attr "length" "5")])
6478 (define_insn "udivsi3_sp64"
6479 [(set (match_operand:SI 0 "register_operand" "=r")
6480 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6481 (match_operand:SI 2 "input_operand" "rI")))]
6482 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6483 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6484 [(set_attr "length" "2")])
6486 (define_insn "udivdi3"
6487 [(set (match_operand:DI 0 "register_operand" "=r")
6488 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6489 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6491 "udivx\\t%1, %2, %0")
6493 (define_insn "*cmp_udiv_cc_set"
6495 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6496 (match_operand:SI 2 "arith_operand" "rI"))
6498 (set (match_operand:SI 0 "register_operand" "=r")
6499 (udiv:SI (match_dup 1) (match_dup 2)))]
6501 || TARGET_DEPRECATED_V8_INSNS)
6502 && ! TARGET_LIVE_G0"
6506 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6508 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6510 [(set (attr "length")
6511 (if_then_else (eq_attr "isa" "v9")
6512 (const_int 2) (const_int 5)))])
6514 ; sparclet multiply/accumulate insns
6516 (define_insn "*smacsi"
6517 [(set (match_operand:SI 0 "register_operand" "=r")
6518 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6519 (match_operand:SI 2 "arith_operand" "rI"))
6520 (match_operand:SI 3 "register_operand" "0")))]
6523 [(set_attr "type" "imul")
6524 (set_attr "length" "1")])
6526 (define_insn "*smacdi"
6527 [(set (match_operand:DI 0 "register_operand" "=r")
6528 (plus:DI (mult:DI (sign_extend:DI
6529 (match_operand:SI 1 "register_operand" "%r"))
6531 (match_operand:SI 2 "register_operand" "r")))
6532 (match_operand:DI 3 "register_operand" "0")))]
6534 "smacd\\t%1, %2, %L0"
6535 [(set_attr "type" "imul")
6536 (set_attr "length" "1")])
6538 (define_insn "*umacdi"
6539 [(set (match_operand:DI 0 "register_operand" "=r")
6540 (plus:DI (mult:DI (zero_extend:DI
6541 (match_operand:SI 1 "register_operand" "%r"))
6543 (match_operand:SI 2 "register_operand" "r")))
6544 (match_operand:DI 3 "register_operand" "0")))]
6546 "umacd\\t%1, %2, %L0"
6547 [(set_attr "type" "imul")
6548 (set_attr "length" "1")])
6550 ;;- Boolean instructions
6551 ;; We define DImode `and' so with DImode `not' we can get
6552 ;; DImode `andn'. Other combinations are possible.
6554 (define_expand "anddi3"
6555 [(set (match_operand:DI 0 "register_operand" "")
6556 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6557 (match_operand:DI 2 "arith_double_operand" "")))]
6561 (define_insn "*anddi3_sp32"
6562 [(set (match_operand:DI 0 "register_operand" "=r,b")
6563 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6564 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6569 [(set_attr "type" "ialu,fp")
6570 (set_attr "length" "2,1")])
6572 (define_insn "*anddi3_sp64"
6573 [(set (match_operand:DI 0 "register_operand" "=r,b")
6574 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6575 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6580 [(set_attr "type" "ialu,fp")
6581 (set_attr "length" "1,1")])
6583 (define_insn "andsi3"
6584 [(set (match_operand:SI 0 "register_operand" "=r,d")
6585 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6586 (match_operand:SI 2 "arith_operand" "rI,d")))]
6591 [(set_attr "type" "ialu,fp")
6592 (set_attr "length" "1,1")])
6595 [(set (match_operand:SI 0 "register_operand" "")
6596 (and:SI (match_operand:SI 1 "register_operand" "")
6597 (match_operand:SI 2 "" "")))
6598 (clobber (match_operand:SI 3 "register_operand" ""))]
6599 "GET_CODE (operands[2]) == CONST_INT
6600 && !SMALL_INT32 (operands[2])
6601 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6602 [(set (match_dup 3) (match_dup 4))
6603 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6606 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6609 ;; Split DImode logical operations requiring two instructions.
6611 [(set (match_operand:DI 0 "register_operand" "")
6612 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6613 [(match_operand:DI 2 "register_operand" "")
6614 (match_operand:DI 3 "arith_double_operand" "")]))]
6617 && ((GET_CODE (operands[0]) == REG
6618 && REGNO (operands[0]) < 32)
6619 || (GET_CODE (operands[0]) == SUBREG
6620 && GET_CODE (SUBREG_REG (operands[0])) == REG
6621 && REGNO (SUBREG_REG (operands[0])) < 32))"
6622 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6623 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6626 if (GET_CODE (operands[0]) == SUBREG)
6627 operands[0] = alter_subreg (operands[0]);
6628 operands[4] = gen_highpart (SImode, operands[0]);
6629 operands[5] = gen_lowpart (SImode, operands[0]);
6630 operands[6] = gen_highpart (SImode, operands[2]);
6631 operands[7] = gen_lowpart (SImode, operands[2]);
6632 if (GET_CODE (operands[3]) == CONST_INT)
6634 if (INTVAL (operands[3]) < 0)
6635 operands[8] = constm1_rtx;
6637 operands[8] = const0_rtx;
6640 operands[8] = gen_highpart (SImode, operands[3]);
6641 operands[9] = gen_lowpart (SImode, operands[3]);
6644 (define_insn "*and_not_di_sp32"
6645 [(set (match_operand:DI 0 "register_operand" "=r,b")
6646 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6647 (match_operand:DI 2 "register_operand" "r,b")))]
6651 fandnot1\\t%1, %2, %0"
6652 [(set_attr "type" "ialu,fp")
6653 (set_attr "length" "2,1")])
6656 [(set (match_operand:DI 0 "register_operand" "")
6657 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6658 (match_operand:DI 2 "register_operand" "")))]
6661 && ((GET_CODE (operands[0]) == REG
6662 && REGNO (operands[0]) < 32)
6663 || (GET_CODE (operands[0]) == SUBREG
6664 && GET_CODE (SUBREG_REG (operands[0])) == REG
6665 && REGNO (SUBREG_REG (operands[0])) < 32))"
6666 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6667 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6668 "if (GET_CODE (operands[0]) == SUBREG)
6669 operands[0] = alter_subreg (operands[0]);
6670 operands[3] = gen_highpart (SImode, operands[0]);
6671 operands[4] = gen_highpart (SImode, operands[1]);
6672 operands[5] = gen_highpart (SImode, operands[2]);
6673 operands[6] = gen_lowpart (SImode, operands[0]);
6674 operands[7] = gen_lowpart (SImode, operands[1]);
6675 operands[8] = gen_lowpart (SImode, operands[2]);")
6677 (define_insn "*and_not_di_sp64"
6678 [(set (match_operand:DI 0 "register_operand" "=r,b")
6679 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6680 (match_operand:DI 2 "register_operand" "r,b")))]
6684 fandnot1\\t%1, %2, %0"
6685 [(set_attr "type" "ialu,fp")
6686 (set_attr "length" "1,1")])
6688 (define_insn "*and_not_si"
6689 [(set (match_operand:SI 0 "register_operand" "=r,d")
6690 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6691 (match_operand:SI 2 "register_operand" "r,d")))]
6695 fandnot1s\\t%1, %2, %0"
6696 [(set_attr "type" "ialu,fp")
6697 (set_attr "length" "1,1")])
6699 (define_expand "iordi3"
6700 [(set (match_operand:DI 0 "register_operand" "")
6701 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6702 (match_operand:DI 2 "arith_double_operand" "")))]
6706 (define_insn "*iordi3_sp32"
6707 [(set (match_operand:DI 0 "register_operand" "=r,b")
6708 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6709 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6714 [(set_attr "type" "ialu,fp")
6715 (set_attr "length" "2,1")])
6717 (define_insn "*iordi3_sp64"
6718 [(set (match_operand:DI 0 "register_operand" "=r,b")
6719 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6720 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6725 [(set_attr "type" "ialu,fp")
6726 (set_attr "length" "1,1")])
6728 (define_insn "iorsi3"
6729 [(set (match_operand:SI 0 "register_operand" "=r,d")
6730 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6731 (match_operand:SI 2 "arith_operand" "rI,d")))]
6736 [(set_attr "type" "ialu,fp")
6737 (set_attr "length" "1,1")])
6740 [(set (match_operand:SI 0 "register_operand" "")
6741 (ior:SI (match_operand:SI 1 "register_operand" "")
6742 (match_operand:SI 2 "" "")))
6743 (clobber (match_operand:SI 3 "register_operand" ""))]
6744 "GET_CODE (operands[2]) == CONST_INT
6745 && !SMALL_INT32 (operands[2])
6746 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6747 [(set (match_dup 3) (match_dup 4))
6748 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6751 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6754 (define_insn "*or_not_di_sp32"
6755 [(set (match_operand:DI 0 "register_operand" "=r,b")
6756 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6757 (match_operand:DI 2 "register_operand" "r,b")))]
6761 fornot1\\t%1, %2, %0"
6762 [(set_attr "type" "ialu,fp")
6763 (set_attr "length" "2,1")])
6766 [(set (match_operand:DI 0 "register_operand" "")
6767 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6768 (match_operand:DI 2 "register_operand" "")))]
6771 && ((GET_CODE (operands[0]) == REG
6772 && REGNO (operands[0]) < 32)
6773 || (GET_CODE (operands[0]) == SUBREG
6774 && GET_CODE (SUBREG_REG (operands[0])) == REG
6775 && REGNO (SUBREG_REG (operands[0])) < 32))"
6776 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6777 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6778 "if (GET_CODE (operands[0]) == SUBREG)
6779 operands[0] = alter_subreg (operands[0]);
6780 operands[3] = gen_highpart (SImode, operands[0]);
6781 operands[4] = gen_highpart (SImode, operands[1]);
6782 operands[5] = gen_highpart (SImode, operands[2]);
6783 operands[6] = gen_lowpart (SImode, operands[0]);
6784 operands[7] = gen_lowpart (SImode, operands[1]);
6785 operands[8] = gen_lowpart (SImode, operands[2]);")
6787 (define_insn "*or_not_di_sp64"
6788 [(set (match_operand:DI 0 "register_operand" "=r,b")
6789 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6790 (match_operand:DI 2 "register_operand" "r,b")))]
6794 fornot1\\t%1, %2, %0"
6795 [(set_attr "type" "ialu,fp")
6796 (set_attr "length" "1,1")])
6798 (define_insn "*or_not_si"
6799 [(set (match_operand:SI 0 "register_operand" "=r,d")
6800 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6801 (match_operand:SI 2 "register_operand" "r,d")))]
6805 fornot1s\\t%1, %2, %0"
6806 [(set_attr "type" "ialu,fp")
6807 (set_attr "length" "1,1")])
6809 (define_expand "xordi3"
6810 [(set (match_operand:DI 0 "register_operand" "")
6811 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6812 (match_operand:DI 2 "arith_double_operand" "")))]
6816 (define_insn "*xordi3_sp32"
6817 [(set (match_operand:DI 0 "register_operand" "=r,b")
6818 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6819 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6824 [(set_attr "length" "2,1")
6825 (set_attr "type" "ialu,fp")])
6827 (define_insn "*xordi3_sp64"
6828 [(set (match_operand:DI 0 "register_operand" "=r,b")
6829 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6830 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6835 [(set_attr "type" "ialu,fp")
6836 (set_attr "length" "1,1")])
6838 (define_insn "*xordi3_sp64_dbl"
6839 [(set (match_operand:DI 0 "register_operand" "=r")
6840 (xor:DI (match_operand:DI 1 "register_operand" "r")
6841 (match_operand:DI 2 "const64_operand" "")))]
6843 && HOST_BITS_PER_WIDE_INT != 64)"
6845 [(set_attr "type" "ialu")
6846 (set_attr "length" "1")])
6848 (define_insn "xorsi3"
6849 [(set (match_operand:SI 0 "register_operand" "=r,d")
6850 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6851 (match_operand:SI 2 "arith_operand" "rI,d")))]
6856 [(set_attr "type" "ialu,fp")
6857 (set_attr "length" "1,1")])
6860 [(set (match_operand:SI 0 "register_operand" "")
6861 (xor:SI (match_operand:SI 1 "register_operand" "")
6862 (match_operand:SI 2 "" "")))
6863 (clobber (match_operand:SI 3 "register_operand" ""))]
6864 "GET_CODE (operands[2]) == CONST_INT
6865 && !SMALL_INT32 (operands[2])
6866 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6867 [(set (match_dup 3) (match_dup 4))
6868 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6871 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6875 [(set (match_operand:SI 0 "register_operand" "")
6876 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6877 (match_operand:SI 2 "" ""))))
6878 (clobber (match_operand:SI 3 "register_operand" ""))]
6879 "GET_CODE (operands[2]) == CONST_INT
6880 && !SMALL_INT32 (operands[2])
6881 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6882 [(set (match_dup 3) (match_dup 4))
6883 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6886 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6889 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6890 ;; Combine now canonicalizes to the rightmost expression.
6891 (define_insn "*xor_not_di_sp32"
6892 [(set (match_operand:DI 0 "register_operand" "=r,b")
6893 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6894 (match_operand:DI 2 "register_operand" "r,b"))))]
6899 [(set_attr "length" "2,1")
6900 (set_attr "type" "ialu,fp")])
6903 [(set (match_operand:DI 0 "register_operand" "")
6904 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6905 (match_operand:DI 2 "register_operand" ""))))]
6908 && ((GET_CODE (operands[0]) == REG
6909 && REGNO (operands[0]) < 32)
6910 || (GET_CODE (operands[0]) == SUBREG
6911 && GET_CODE (SUBREG_REG (operands[0])) == REG
6912 && REGNO (SUBREG_REG (operands[0])) < 32))"
6913 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6914 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6915 "if (GET_CODE (operands[0]) == SUBREG)
6916 operands[0] = alter_subreg (operands[0]);
6917 operands[3] = gen_highpart (SImode, operands[0]);
6918 operands[4] = gen_highpart (SImode, operands[1]);
6919 operands[5] = gen_highpart (SImode, operands[2]);
6920 operands[6] = gen_lowpart (SImode, operands[0]);
6921 operands[7] = gen_lowpart (SImode, operands[1]);
6922 operands[8] = gen_lowpart (SImode, operands[2]);")
6924 (define_insn "*xor_not_di_sp64"
6925 [(set (match_operand:DI 0 "register_operand" "=r,b")
6926 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6927 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6932 [(set_attr "type" "ialu,fp")
6933 (set_attr "length" "1,1")])
6935 (define_insn "*xor_not_si"
6936 [(set (match_operand:SI 0 "register_operand" "=r,d")
6937 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6938 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6942 fxnors\\t%1, %2, %0"
6943 [(set_attr "type" "ialu,fp")
6944 (set_attr "length" "1,1")])
6946 ;; These correspond to the above in the case where we also (or only)
6947 ;; want to set the condition code.
6949 (define_insn "*cmp_cc_arith_op"
6952 (match_operator:SI 2 "cc_arithop"
6953 [(match_operand:SI 0 "arith_operand" "%r")
6954 (match_operand:SI 1 "arith_operand" "rI")])
6957 "%A2cc\\t%0, %1, %%g0"
6958 [(set_attr "type" "compare")
6959 (set_attr "length" "1")])
6961 (define_insn "*cmp_ccx_arith_op"
6964 (match_operator:DI 2 "cc_arithop"
6965 [(match_operand:DI 0 "arith_double_operand" "%r")
6966 (match_operand:DI 1 "arith_double_operand" "rHI")])
6969 "%A2cc\\t%0, %1, %%g0"
6970 [(set_attr "type" "compare")
6971 (set_attr "length" "1")])
6973 (define_insn "*cmp_cc_arith_op_set"
6976 (match_operator:SI 3 "cc_arithop"
6977 [(match_operand:SI 1 "arith_operand" "%r")
6978 (match_operand:SI 2 "arith_operand" "rI")])
6980 (set (match_operand:SI 0 "register_operand" "=r")
6983 "%A3cc\\t%1, %2, %0"
6984 [(set_attr "type" "compare")
6985 (set_attr "length" "1")])
6987 (define_insn "*cmp_ccx_arith_op_set"
6990 (match_operator:DI 3 "cc_arithop"
6991 [(match_operand:DI 1 "arith_double_operand" "%r")
6992 (match_operand:DI 2 "arith_double_operand" "rHI")])
6994 (set (match_operand:DI 0 "register_operand" "=r")
6997 "%A3cc\\t%1, %2, %0"
6998 [(set_attr "type" "compare")
6999 (set_attr "length" "1")])
7001 (define_insn "*cmp_cc_xor_not"
7004 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7005 (match_operand:SI 1 "arith_operand" "rI")))
7008 "xnorcc\\t%r0, %1, %%g0"
7009 [(set_attr "type" "compare")
7010 (set_attr "length" "1")])
7012 (define_insn "*cmp_ccx_xor_not"
7015 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7016 (match_operand:DI 1 "arith_double_operand" "rHI")))
7019 "xnorcc\\t%r0, %1, %%g0"
7020 [(set_attr "type" "compare")
7021 (set_attr "length" "1")])
7023 (define_insn "*cmp_cc_xor_not_set"
7026 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7027 (match_operand:SI 2 "arith_operand" "rI")))
7029 (set (match_operand:SI 0 "register_operand" "=r")
7030 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7032 "xnorcc\\t%r1, %2, %0"
7033 [(set_attr "type" "compare")
7034 (set_attr "length" "1")])
7036 (define_insn "*cmp_ccx_xor_not_set"
7039 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7040 (match_operand:DI 2 "arith_double_operand" "rHI")))
7042 (set (match_operand:DI 0 "register_operand" "=r")
7043 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7045 "xnorcc\\t%r1, %2, %0"
7046 [(set_attr "type" "compare")
7047 (set_attr "length" "1")])
7049 (define_insn "*cmp_cc_arith_op_not"
7052 (match_operator:SI 2 "cc_arithopn"
7053 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7054 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7057 "%B2cc\\t%r1, %0, %%g0"
7058 [(set_attr "type" "compare")
7059 (set_attr "length" "1")])
7061 (define_insn "*cmp_ccx_arith_op_not"
7064 (match_operator:DI 2 "cc_arithopn"
7065 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7066 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7069 "%B2cc\\t%r1, %0, %%g0"
7070 [(set_attr "type" "compare")
7071 (set_attr "length" "1")])
7073 (define_insn "*cmp_cc_arith_op_not_set"
7076 (match_operator:SI 3 "cc_arithopn"
7077 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7078 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7080 (set (match_operand:SI 0 "register_operand" "=r")
7083 "%B3cc\\t%r2, %1, %0"
7084 [(set_attr "type" "compare")
7085 (set_attr "length" "1")])
7087 (define_insn "*cmp_ccx_arith_op_not_set"
7090 (match_operator:DI 3 "cc_arithopn"
7091 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7092 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7094 (set (match_operand:DI 0 "register_operand" "=r")
7097 "%B3cc\\t%r2, %1, %0"
7098 [(set_attr "type" "compare")
7099 (set_attr "length" "1")])
7101 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7102 ;; does not know how to make it work for constants.
7104 (define_expand "negdi2"
7105 [(set (match_operand:DI 0 "register_operand" "=r")
7106 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7110 if (! TARGET_ARCH64)
7112 emit_insn (gen_rtx_PARALLEL
7115 gen_rtx_SET (VOIDmode, operand0,
7116 gen_rtx_NEG (DImode, operand1)),
7117 gen_rtx_CLOBBER (VOIDmode,
7118 gen_rtx_REG (CCmode,
7124 (define_insn "*negdi2_sp32"
7125 [(set (match_operand:DI 0 "register_operand" "=r")
7126 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7127 (clobber (reg:CC 100))]
7129 && ! TARGET_LIVE_G0"
7131 [(set_attr "type" "unary")
7132 (set_attr "length" "2")])
7135 [(set (match_operand:DI 0 "register_operand" "")
7136 (neg:DI (match_operand:DI 1 "register_operand" "")))
7137 (clobber (reg:CC 100))]
7140 && reload_completed"
7141 [(parallel [(set (reg:CC_NOOV 100)
7142 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7144 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7145 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7146 (ltu:SI (reg:CC 100) (const_int 0))))]
7147 "operands[2] = gen_highpart (SImode, operands[0]);
7148 operands[3] = gen_highpart (SImode, operands[1]);
7149 operands[4] = gen_lowpart (SImode, operands[0]);
7150 operands[5] = gen_lowpart (SImode, operands[1]);")
7152 (define_insn "*negdi2_sp64"
7153 [(set (match_operand:DI 0 "register_operand" "=r")
7154 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7156 "sub\\t%%g0, %1, %0"
7157 [(set_attr "type" "unary")
7158 (set_attr "length" "1")])
7160 (define_expand "negsi2"
7161 [(set (match_operand:SI 0 "register_operand" "")
7162 (neg:SI (match_operand:SI 1 "arith_operand" "")))]
7168 rtx zero_reg = gen_reg_rtx (SImode);
7170 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
7171 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
7172 gen_rtx_MINUS (SImode, zero_reg,
7178 (define_insn "*negsi2_not_liveg0"
7179 [(set (match_operand:SI 0 "register_operand" "=r")
7180 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7182 "sub\\t%%g0, %1, %0"
7183 [(set_attr "type" "unary")
7184 (set_attr "length" "1")])
7186 (define_insn "*cmp_cc_neg"
7187 [(set (reg:CC_NOOV 100)
7188 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7191 "subcc\\t%%g0, %0, %%g0"
7192 [(set_attr "type" "compare")
7193 (set_attr "length" "1")])
7195 (define_insn "*cmp_ccx_neg"
7196 [(set (reg:CCX_NOOV 100)
7197 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7200 "subcc\\t%%g0, %0, %%g0"
7201 [(set_attr "type" "compare")
7202 (set_attr "length" "1")])
7204 (define_insn "*cmp_cc_set_neg"
7205 [(set (reg:CC_NOOV 100)
7206 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7208 (set (match_operand:SI 0 "register_operand" "=r")
7209 (neg:SI (match_dup 1)))]
7211 "subcc\\t%%g0, %1, %0"
7212 [(set_attr "type" "compare")
7213 (set_attr "length" "1")])
7215 (define_insn "*cmp_ccx_set_neg"
7216 [(set (reg:CCX_NOOV 100)
7217 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7219 (set (match_operand:DI 0 "register_operand" "=r")
7220 (neg:DI (match_dup 1)))]
7222 "subcc\\t%%g0, %1, %0"
7223 [(set_attr "type" "compare")
7224 (set_attr "length" "1")])
7226 ;; We cannot use the "not" pseudo insn because the Sun assembler
7227 ;; does not know how to make it work for constants.
7228 (define_expand "one_cmpldi2"
7229 [(set (match_operand:DI 0 "register_operand" "")
7230 (not:DI (match_operand:DI 1 "register_operand" "")))]
7234 (define_insn "*one_cmpldi2_sp32"
7235 [(set (match_operand:DI 0 "register_operand" "=r,b")
7236 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7241 [(set_attr "type" "unary,fp")
7242 (set_attr "length" "2,1")])
7245 [(set (match_operand:DI 0 "register_operand" "")
7246 (not:DI (match_operand:DI 1 "register_operand" "")))]
7249 && ((GET_CODE (operands[0]) == REG
7250 && REGNO (operands[0]) < 32)
7251 || (GET_CODE (operands[0]) == SUBREG
7252 && GET_CODE (SUBREG_REG (operands[0])) == REG
7253 && REGNO (SUBREG_REG (operands[0])) < 32))"
7254 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7255 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7256 "if (GET_CODE (operands[0]) == SUBREG)
7257 operands[0] = alter_subreg (operands[0]);
7258 operands[2] = gen_highpart (SImode, operands[0]);
7259 operands[3] = gen_highpart (SImode, operands[1]);
7260 operands[4] = gen_lowpart (SImode, operands[0]);
7261 operands[5] = gen_lowpart (SImode, operands[1]);")
7263 (define_insn "*one_cmpldi2_sp64"
7264 [(set (match_operand:DI 0 "register_operand" "=r,b")
7265 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7270 [(set_attr "type" "unary,fp")
7271 (set_attr "length" "1")])
7273 (define_expand "one_cmplsi2"
7274 [(set (match_operand:SI 0 "register_operand" "")
7275 (not:SI (match_operand:SI 1 "arith_operand" "")))]
7280 && GET_CODE (operands[1]) == CONST_INT)
7282 rtx zero_reg = gen_reg_rtx (SImode);
7284 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
7285 emit_insn (gen_rtx_SET (VOIDmode,
7287 gen_rtx_NOT (SImode,
7288 gen_rtx_XOR (SImode,
7295 (define_insn "*one_cmplsi2_not_liveg0"
7296 [(set (match_operand:SI 0 "register_operand" "=r,d")
7297 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7302 [(set_attr "type" "unary,fp")
7303 (set_attr "length" "1,1")])
7305 (define_insn "*one_cmplsi2_liveg0"
7306 [(set (match_operand:SI 0 "register_operand" "=r,d")
7307 (not:SI (match_operand:SI 1 "arith_operand" "r,d")))]
7312 [(set_attr "type" "unary,fp")
7313 (set_attr "length" "1,1")])
7315 (define_insn "*cmp_cc_not"
7317 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7320 "xnorcc\\t%%g0, %0, %%g0"
7321 [(set_attr "type" "compare")
7322 (set_attr "length" "1")])
7324 (define_insn "*cmp_ccx_not"
7326 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7329 "xnorcc\\t%%g0, %0, %%g0"
7330 [(set_attr "type" "compare")
7331 (set_attr "length" "1")])
7333 (define_insn "*cmp_cc_set_not"
7335 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7337 (set (match_operand:SI 0 "register_operand" "=r")
7338 (not:SI (match_dup 1)))]
7340 "xnorcc\\t%%g0, %1, %0"
7341 [(set_attr "type" "compare")
7342 (set_attr "length" "1")])
7344 (define_insn "*cmp_ccx_set_not"
7346 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7348 (set (match_operand:DI 0 "register_operand" "=r")
7349 (not:DI (match_dup 1)))]
7351 "xnorcc\\t%%g0, %1, %0"
7352 [(set_attr "type" "compare")
7353 (set_attr "length" "1")])
7355 ;; Floating point arithmetic instructions.
7357 (define_expand "addtf3"
7358 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7359 (plus:TF (match_operand:TF 1 "general_operand" "")
7360 (match_operand:TF 2 "general_operand" "")))]
7361 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7364 if (! TARGET_HARD_QUAD)
7366 rtx slot0, slot1, slot2;
7368 if (GET_CODE (operands[0]) != MEM)
7369 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7371 slot0 = operands[0];
7372 if (GET_CODE (operands[1]) != MEM)
7374 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7375 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7378 slot1 = operands[1];
7379 if (GET_CODE (operands[2]) != MEM)
7381 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7382 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7385 slot2 = operands[2];
7387 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7389 XEXP (slot0, 0), Pmode,
7390 XEXP (slot1, 0), Pmode,
7391 XEXP (slot2, 0), Pmode);
7393 if (GET_CODE (operands[0]) != MEM)
7394 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7399 (define_insn "*addtf3_hq"
7400 [(set (match_operand:TF 0 "register_operand" "=e")
7401 (plus:TF (match_operand:TF 1 "register_operand" "e")
7402 (match_operand:TF 2 "register_operand" "e")))]
7403 "TARGET_FPU && TARGET_HARD_QUAD"
7404 "faddq\\t%1, %2, %0"
7405 [(set_attr "type" "fp")
7406 (set_attr "length" "1")])
7408 (define_insn "adddf3"
7409 [(set (match_operand:DF 0 "register_operand" "=e")
7410 (plus:DF (match_operand:DF 1 "register_operand" "e")
7411 (match_operand:DF 2 "register_operand" "e")))]
7413 "faddd\\t%1, %2, %0"
7414 [(set_attr "type" "fp")
7415 (set_attr "length" "1")])
7417 (define_insn "addsf3"
7418 [(set (match_operand:SF 0 "register_operand" "=f")
7419 (plus:SF (match_operand:SF 1 "register_operand" "f")
7420 (match_operand:SF 2 "register_operand" "f")))]
7422 "fadds\\t%1, %2, %0"
7423 [(set_attr "type" "fp")
7424 (set_attr "length" "1")])
7426 (define_expand "subtf3"
7427 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7428 (minus:TF (match_operand:TF 1 "general_operand" "")
7429 (match_operand:TF 2 "general_operand" "")))]
7430 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7433 if (! TARGET_HARD_QUAD)
7435 rtx slot0, slot1, slot2;
7437 if (GET_CODE (operands[0]) != MEM)
7438 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7440 slot0 = operands[0];
7441 if (GET_CODE (operands[1]) != MEM)
7443 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7444 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7447 slot1 = operands[1];
7448 if (GET_CODE (operands[2]) != MEM)
7450 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7451 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7454 slot2 = operands[2];
7456 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7458 XEXP (slot0, 0), Pmode,
7459 XEXP (slot1, 0), Pmode,
7460 XEXP (slot2, 0), Pmode);
7462 if (GET_CODE (operands[0]) != MEM)
7463 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7468 (define_insn "*subtf3_hq"
7469 [(set (match_operand:TF 0 "register_operand" "=e")
7470 (minus:TF (match_operand:TF 1 "register_operand" "e")
7471 (match_operand:TF 2 "register_operand" "e")))]
7472 "TARGET_FPU && TARGET_HARD_QUAD"
7473 "fsubq\\t%1, %2, %0"
7474 [(set_attr "type" "fp")
7475 (set_attr "length" "1")])
7477 (define_insn "subdf3"
7478 [(set (match_operand:DF 0 "register_operand" "=e")
7479 (minus:DF (match_operand:DF 1 "register_operand" "e")
7480 (match_operand:DF 2 "register_operand" "e")))]
7482 "fsubd\\t%1, %2, %0"
7483 [(set_attr "type" "fp")
7484 (set_attr "length" "1")])
7486 (define_insn "subsf3"
7487 [(set (match_operand:SF 0 "register_operand" "=f")
7488 (minus:SF (match_operand:SF 1 "register_operand" "f")
7489 (match_operand:SF 2 "register_operand" "f")))]
7491 "fsubs\\t%1, %2, %0"
7492 [(set_attr "type" "fp")
7493 (set_attr "length" "1")])
7495 (define_expand "multf3"
7496 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7497 (mult:TF (match_operand:TF 1 "general_operand" "")
7498 (match_operand:TF 2 "general_operand" "")))]
7499 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7502 if (! TARGET_HARD_QUAD)
7504 rtx slot0, slot1, slot2;
7506 if (GET_CODE (operands[0]) != MEM)
7507 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7509 slot0 = operands[0];
7510 if (GET_CODE (operands[1]) != MEM)
7512 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7513 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7516 slot1 = operands[1];
7517 if (GET_CODE (operands[2]) != MEM)
7519 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7520 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7523 slot2 = operands[2];
7525 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7527 XEXP (slot0, 0), Pmode,
7528 XEXP (slot1, 0), Pmode,
7529 XEXP (slot2, 0), Pmode);
7531 if (GET_CODE (operands[0]) != MEM)
7532 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7537 (define_insn "*multf3_hq"
7538 [(set (match_operand:TF 0 "register_operand" "=e")
7539 (mult:TF (match_operand:TF 1 "register_operand" "e")
7540 (match_operand:TF 2 "register_operand" "e")))]
7541 "TARGET_FPU && TARGET_HARD_QUAD"
7542 "fmulq\\t%1, %2, %0"
7543 [(set_attr "type" "fpmul")
7544 (set_attr "length" "1")])
7546 (define_insn "muldf3"
7547 [(set (match_operand:DF 0 "register_operand" "=e")
7548 (mult:DF (match_operand:DF 1 "register_operand" "e")
7549 (match_operand:DF 2 "register_operand" "e")))]
7551 "fmuld\\t%1, %2, %0"
7552 [(set_attr "type" "fpmul")
7553 (set_attr "length" "1")])
7555 (define_insn "mulsf3"
7556 [(set (match_operand:SF 0 "register_operand" "=f")
7557 (mult:SF (match_operand:SF 1 "register_operand" "f")
7558 (match_operand:SF 2 "register_operand" "f")))]
7560 "fmuls\\t%1, %2, %0"
7561 [(set_attr "type" "fpmul")
7562 (set_attr "length" "1")])
7564 (define_insn "*muldf3_extend"
7565 [(set (match_operand:DF 0 "register_operand" "=e")
7566 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7567 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7568 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7569 "fsmuld\\t%1, %2, %0"
7570 [(set_attr "type" "fpmul")
7571 (set_attr "length" "1")])
7573 (define_insn "*multf3_extend"
7574 [(set (match_operand:TF 0 "register_operand" "=e")
7575 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7576 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7577 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7578 "fdmulq\\t%1, %2, %0"
7579 [(set_attr "type" "fpmul")
7580 (set_attr "length" "1")])
7582 (define_expand "divtf3"
7583 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7584 (div:TF (match_operand:TF 1 "general_operand" "")
7585 (match_operand:TF 2 "general_operand" "")))]
7586 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7589 if (! TARGET_HARD_QUAD)
7591 rtx slot0, slot1, slot2;
7593 if (GET_CODE (operands[0]) != MEM)
7594 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7596 slot0 = operands[0];
7597 if (GET_CODE (operands[1]) != MEM)
7599 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7600 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7603 slot1 = operands[1];
7604 if (GET_CODE (operands[2]) != MEM)
7606 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7607 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7610 slot2 = operands[2];
7612 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7614 XEXP (slot0, 0), Pmode,
7615 XEXP (slot1, 0), Pmode,
7616 XEXP (slot2, 0), Pmode);
7618 if (GET_CODE (operands[0]) != MEM)
7619 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7624 ;; don't have timing for quad-prec. divide.
7625 (define_insn "*divtf3_hq"
7626 [(set (match_operand:TF 0 "register_operand" "=e")
7627 (div:TF (match_operand:TF 1 "register_operand" "e")
7628 (match_operand:TF 2 "register_operand" "e")))]
7629 "TARGET_FPU && TARGET_HARD_QUAD"
7630 "fdivq\\t%1, %2, %0"
7631 [(set_attr "type" "fpdivd")
7632 (set_attr "length" "1")])
7634 (define_insn "divdf3"
7635 [(set (match_operand:DF 0 "register_operand" "=e")
7636 (div:DF (match_operand:DF 1 "register_operand" "e")
7637 (match_operand:DF 2 "register_operand" "e")))]
7639 "fdivd\\t%1, %2, %0"
7640 [(set_attr "type" "fpdivd")
7641 (set_attr "length" "1")])
7643 (define_insn "divsf3"
7644 [(set (match_operand:SF 0 "register_operand" "=f")
7645 (div:SF (match_operand:SF 1 "register_operand" "f")
7646 (match_operand:SF 2 "register_operand" "f")))]
7648 "fdivs\\t%1, %2, %0"
7649 [(set_attr "type" "fpdivs")
7650 (set_attr "length" "1")])
7652 (define_expand "negtf2"
7653 [(set (match_operand:TF 0 "register_operand" "=e,e")
7654 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7658 (define_insn "*negtf2_notv9"
7659 [(set (match_operand:TF 0 "register_operand" "=e,e")
7660 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7661 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7667 [(set_attr "type" "fpmove")
7668 (set_attr "length" "1,2")])
7671 [(set (match_operand:TF 0 "register_operand" "")
7672 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7676 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7677 [(set (match_dup 2) (neg:SF (match_dup 3)))
7678 (set (match_dup 4) (match_dup 5))
7679 (set (match_dup 6) (match_dup 7))]
7680 "if (GET_CODE (operands[0]) == SUBREG)
7681 operands[0] = alter_subreg (operands[0]);
7682 if (GET_CODE (operands[1]) == SUBREG)
7683 operands[1] = alter_subreg (operands[1]);
7684 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7685 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7686 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7687 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7688 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7689 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7691 (define_insn "*negtf2_v9"
7692 [(set (match_operand:TF 0 "register_operand" "=e,e")
7693 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7694 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7695 "TARGET_FPU && TARGET_V9"
7699 [(set_attr "type" "fpmove")
7700 (set_attr "length" "1,2")])
7703 [(set (match_operand:TF 0 "register_operand" "")
7704 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7708 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7709 [(set (match_dup 2) (neg:DF (match_dup 3)))
7710 (set (match_dup 4) (match_dup 5))]
7711 "if (GET_CODE (operands[0]) == SUBREG)
7712 operands[0] = alter_subreg (operands[0]);
7713 if (GET_CODE (operands[1]) == SUBREG)
7714 operands[1] = alter_subreg (operands[1]);
7715 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7716 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7717 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7718 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7720 (define_expand "negdf2"
7721 [(set (match_operand:DF 0 "register_operand" "")
7722 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7726 (define_insn "*negdf2_notv9"
7727 [(set (match_operand:DF 0 "register_operand" "=e,e")
7728 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7729 "TARGET_FPU && ! TARGET_V9"
7733 [(set_attr "type" "fpmove")
7734 (set_attr "length" "1,2")])
7737 [(set (match_operand:DF 0 "register_operand" "")
7738 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7742 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7743 [(set (match_dup 2) (neg:SF (match_dup 3)))
7744 (set (match_dup 4) (match_dup 5))]
7745 "if (GET_CODE (operands[0]) == SUBREG)
7746 operands[0] = alter_subreg (operands[0]);
7747 if (GET_CODE (operands[1]) == SUBREG)
7748 operands[1] = alter_subreg (operands[1]);
7749 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7750 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7751 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7752 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7754 (define_insn "*negdf2_v9"
7755 [(set (match_operand:DF 0 "register_operand" "=e")
7756 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7757 "TARGET_FPU && TARGET_V9"
7759 [(set_attr "type" "fpmove")
7760 (set_attr "length" "1")])
7762 (define_insn "negsf2"
7763 [(set (match_operand:SF 0 "register_operand" "=f")
7764 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7767 [(set_attr "type" "fpmove")
7768 (set_attr "length" "1")])
7770 (define_expand "abstf2"
7771 [(set (match_operand:TF 0 "register_operand" "")
7772 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7776 (define_insn "*abstf2_notv9"
7777 [(set (match_operand:TF 0 "register_operand" "=e,e")
7778 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7779 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7780 "TARGET_FPU && ! TARGET_V9"
7784 [(set_attr "type" "fpmove")
7785 (set_attr "length" "1,2")])
7788 [(set (match_operand:TF 0 "register_operand" "=e,e")
7789 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7793 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7794 [(set (match_dup 2) (abs:SF (match_dup 3)))
7795 (set (match_dup 4) (match_dup 5))
7796 (set (match_dup 6) (match_dup 7))]
7797 "if (GET_CODE (operands[0]) == SUBREG)
7798 operands[0] = alter_subreg (operands[0]);
7799 if (GET_CODE (operands[1]) == SUBREG)
7800 operands[1] = alter_subreg (operands[1]);
7801 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7802 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7803 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7804 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7805 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7806 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7808 (define_insn "*abstf2_hq_v9"
7809 [(set (match_operand:TF 0 "register_operand" "=e,e")
7810 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7811 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7815 [(set_attr "type" "fpmove")
7816 (set_attr "length" "1")])
7818 (define_insn "*abstf2_v9"
7819 [(set (match_operand:TF 0 "register_operand" "=e,e")
7820 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7821 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7825 [(set_attr "type" "fpmove")
7826 (set_attr "length" "1,2")])
7829 [(set (match_operand:TF 0 "register_operand" "=e,e")
7830 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7834 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7835 [(set (match_dup 2) (abs:DF (match_dup 3)))
7836 (set (match_dup 4) (match_dup 5))]
7837 "if (GET_CODE (operands[0]) == SUBREG)
7838 operands[0] = alter_subreg (operands[0]);
7839 if (GET_CODE (operands[1]) == SUBREG)
7840 operands[1] = alter_subreg (operands[1]);
7841 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7842 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7843 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7844 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7846 (define_expand "absdf2"
7847 [(set (match_operand:DF 0 "register_operand" "")
7848 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7852 (define_insn "*absdf2_notv9"
7853 [(set (match_operand:DF 0 "register_operand" "=e,e")
7854 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7855 "TARGET_FPU && ! TARGET_V9"
7859 [(set_attr "type" "fpmove")
7860 (set_attr "length" "1,2")])
7863 [(set (match_operand:DF 0 "register_operand" "=e,e")
7864 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7868 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7869 [(set (match_dup 2) (abs:SF (match_dup 3)))
7870 (set (match_dup 4) (match_dup 5))]
7871 "if (GET_CODE (operands[0]) == SUBREG)
7872 operands[0] = alter_subreg (operands[0]);
7873 if (GET_CODE (operands[1]) == SUBREG)
7874 operands[1] = alter_subreg (operands[1]);
7875 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7876 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7877 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7878 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7880 (define_insn "*absdf2_v9"
7881 [(set (match_operand:DF 0 "register_operand" "=e")
7882 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7883 "TARGET_FPU && TARGET_V9"
7885 [(set_attr "type" "fpmove")
7886 (set_attr "length" "1")])
7888 (define_insn "abssf2"
7889 [(set (match_operand:SF 0 "register_operand" "=f")
7890 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7893 [(set_attr "type" "fpmove")
7894 (set_attr "length" "1")])
7896 (define_expand "sqrttf2"
7897 [(set (match_operand:TF 0 "register_operand" "=e")
7898 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7899 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7902 if (! TARGET_HARD_QUAD)
7906 if (GET_CODE (operands[0]) != MEM)
7907 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7909 slot0 = operands[0];
7910 if (GET_CODE (operands[1]) != MEM)
7912 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7913 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7916 slot1 = operands[1];
7918 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7920 XEXP (slot0, 0), Pmode,
7921 XEXP (slot1, 0), Pmode);
7923 if (GET_CODE (operands[0]) != MEM)
7924 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7929 (define_insn "*sqrttf2_hq"
7930 [(set (match_operand:TF 0 "register_operand" "=e")
7931 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7932 "TARGET_FPU && TARGET_HARD_QUAD"
7934 [(set_attr "type" "fpsqrtd")
7935 (set_attr "length" "1")])
7937 (define_insn "sqrtdf2"
7938 [(set (match_operand:DF 0 "register_operand" "=e")
7939 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7942 [(set_attr "type" "fpsqrtd")
7943 (set_attr "length" "1")])
7945 (define_insn "sqrtsf2"
7946 [(set (match_operand:SF 0 "register_operand" "=f")
7947 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7950 [(set_attr "type" "fpsqrts")
7951 (set_attr "length" "1")])
7953 ;;- arithmetic shift instructions
7955 (define_insn "ashlsi3"
7956 [(set (match_operand:SI 0 "register_operand" "=r")
7957 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7958 (match_operand:SI 2 "arith_operand" "rI")))]
7962 if (GET_CODE (operands[2]) == CONST_INT
7963 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7964 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7966 return \"sll\\t%1, %2, %0\";
7968 [(set_attr "type" "shift")
7969 (set_attr "length" "1")])
7971 ;; We special case multiplication by two, as add can be done
7972 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
7973 (define_insn "*ashlsi3_const1"
7974 [(set (match_operand:SI 0 "register_operand" "=r")
7975 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7979 [(set_attr "type" "binary")
7980 (set_attr "length" "1")])
7982 (define_expand "ashldi3"
7983 [(set (match_operand:DI 0 "register_operand" "=r")
7984 (ashift:DI (match_operand:DI 1 "register_operand" "r")
7985 (match_operand:SI 2 "arith_operand" "rI")))]
7986 "TARGET_ARCH64 || TARGET_V8PLUS"
7989 if (! TARGET_ARCH64)
7991 if (GET_CODE (operands[2]) == CONST_INT)
7993 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7998 ;; We special case multiplication by two, as add can be done
7999 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8000 (define_insn "*ashldi3_const1"
8001 [(set (match_operand:DI 0 "register_operand" "=r")
8002 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8006 [(set_attr "type" "binary")
8007 (set_attr "length" "1")])
8009 (define_insn "*ashldi3_sp64"
8010 [(set (match_operand:DI 0 "register_operand" "=r")
8011 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8012 (match_operand:SI 2 "arith_operand" "rI")))]
8016 if (GET_CODE (operands[2]) == CONST_INT
8017 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8018 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8020 return \"sllx\\t%1, %2, %0\";
8022 [(set_attr "type" "shift")
8023 (set_attr "length" "1")])
8026 (define_insn "ashldi3_v8plus"
8027 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8028 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8029 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8030 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8032 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8033 [(set_attr "length" "5,5,6")])
8035 ;; Optimize (1LL<<x)-1
8036 ;; XXX this also needs to be fixed to handle equal subregs
8037 ;; XXX first before we could re-enable it.
8039 [(set (match_operand:DI 0 "register_operand" "=h")
8040 (plus:DI (ashift:DI (const_int 1)
8041 (match_operand:SI 2 "arith_operand" "rI"))
8043 "0 && TARGET_V8PLUS"
8046 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
8047 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
8048 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
8050 [(set_attr "length" "4")])
8052 (define_insn "*cmp_cc_ashift_1"
8053 [(set (reg:CC_NOOV 100)
8054 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8058 "addcc\\t%0, %0, %%g0"
8059 [(set_attr "type" "compare")
8060 (set_attr "length" "1")])
8062 (define_insn "*cmp_cc_set_ashift_1"
8063 [(set (reg:CC_NOOV 100)
8064 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8067 (set (match_operand:SI 0 "register_operand" "=r")
8068 (ashift:SI (match_dup 1) (const_int 1)))]
8070 "addcc\\t%1, %1, %0"
8071 [(set_attr "type" "compare")
8072 (set_attr "length" "1")])
8074 (define_insn "ashrsi3"
8075 [(set (match_operand:SI 0 "register_operand" "=r")
8076 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8077 (match_operand:SI 2 "arith_operand" "rI")))]
8081 if (GET_CODE (operands[2]) == CONST_INT
8082 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8083 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8085 return \"sra\\t%1, %2, %0\";
8087 [(set_attr "type" "shift")
8088 (set_attr "length" "1")])
8090 (define_insn "*ashrsi3_extend"
8091 [(set (match_operand:DI 0 "register_operand" "=r")
8092 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8093 (match_operand:SI 2 "arith_operand" "r"))))]
8096 [(set_attr "type" "shift")
8097 (set_attr "length" "1")])
8099 ;; This handles the case as above, but with constant shift instead of
8100 ;; register. Combiner "simplifies" it for us a little bit though.
8101 (define_insn "*ashrsi3_extend2"
8102 [(set (match_operand:DI 0 "register_operand" "=r")
8103 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8105 (match_operand:SI 2 "small_int_or_double" "n")))]
8107 && ((GET_CODE (operands[2]) == CONST_INT
8108 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8109 || (GET_CODE (operands[2]) == CONST_DOUBLE
8110 && !CONST_DOUBLE_HIGH (operands[2])
8111 && CONST_DOUBLE_LOW (operands[2]) >= 32
8112 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8115 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8117 return \"sra\\t%1, %2, %0\";
8119 [(set_attr "type" "shift")
8120 (set_attr "length" "1")])
8122 (define_expand "ashrdi3"
8123 [(set (match_operand:DI 0 "register_operand" "=r")
8124 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8125 (match_operand:SI 2 "arith_operand" "rI")))]
8126 "TARGET_ARCH64 || TARGET_V8PLUS"
8129 if (! TARGET_ARCH64)
8131 if (GET_CODE (operands[2]) == CONST_INT)
8132 FAIL; /* prefer generic code in this case */
8133 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8139 [(set (match_operand:DI 0 "register_operand" "=r")
8140 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8141 (match_operand:SI 2 "arith_operand" "rI")))]
8145 if (GET_CODE (operands[2]) == CONST_INT
8146 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8147 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8149 return \"srax\\t%1, %2, %0\";
8151 [(set_attr "type" "shift")
8152 (set_attr "length" "1")])
8155 (define_insn "ashrdi3_v8plus"
8156 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8157 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8158 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8159 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8161 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8162 [(set_attr "length" "5,5,6")])
8164 (define_insn "lshrsi3"
8165 [(set (match_operand:SI 0 "register_operand" "=r")
8166 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8167 (match_operand:SI 2 "arith_operand" "rI")))]
8171 if (GET_CODE (operands[2]) == CONST_INT
8172 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8173 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8175 return \"srl\\t%1, %2, %0\";
8177 [(set_attr "type" "shift")
8178 (set_attr "length" "1")])
8180 ;; This handles the case where
8181 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8182 ;; but combiner "simplifies" it for us.
8183 (define_insn "*lshrsi3_extend"
8184 [(set (match_operand:DI 0 "register_operand" "=r")
8185 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8186 (match_operand:SI 2 "arith_operand" "r")) 0)
8187 (match_operand 3 "" "")))]
8189 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8190 && CONST_DOUBLE_HIGH (operands[3]) == 0
8191 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8192 #if HOST_BITS_PER_WIDE_INT >= 64
8193 || (GET_CODE (operands[3]) == CONST_INT
8194 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
8198 [(set_attr "type" "shift")
8199 (set_attr "length" "1")])
8201 ;; This handles the case where
8202 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8203 ;; but combiner "simplifies" it for us.
8204 (define_insn "*lshrsi3_extend2"
8205 [(set (match_operand:DI 0 "register_operand" "=r")
8206 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8207 (match_operand 2 "small_int_or_double" "n")
8210 && ((GET_CODE (operands[2]) == CONST_INT
8211 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8212 || (GET_CODE (operands[2]) == CONST_DOUBLE
8213 && CONST_DOUBLE_HIGH (operands[2]) == 0
8214 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8217 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8219 return \"srl\\t%1, %2, %0\";
8221 [(set_attr "type" "shift")
8222 (set_attr "length" "1")])
8224 (define_expand "lshrdi3"
8225 [(set (match_operand:DI 0 "register_operand" "=r")
8226 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8227 (match_operand:SI 2 "arith_operand" "rI")))]
8228 "TARGET_ARCH64 || TARGET_V8PLUS"
8231 if (! TARGET_ARCH64)
8233 if (GET_CODE (operands[2]) == CONST_INT)
8235 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8241 [(set (match_operand:DI 0 "register_operand" "=r")
8242 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8243 (match_operand:SI 2 "arith_operand" "rI")))]
8247 if (GET_CODE (operands[2]) == CONST_INT
8248 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8249 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8251 return \"srlx\\t%1, %2, %0\";
8253 [(set_attr "type" "shift")
8254 (set_attr "length" "1")])
8257 (define_insn "lshrdi3_v8plus"
8258 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8259 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8260 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8261 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8263 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8264 [(set_attr "length" "5,5,6")])
8267 [(set (match_operand:SI 0 "register_operand" "=r")
8268 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8270 (match_operand:SI 2 "small_int_or_double" "n")))]
8272 && ((GET_CODE (operands[2]) == CONST_INT
8273 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8274 || (GET_CODE (operands[2]) == CONST_DOUBLE
8275 && !CONST_DOUBLE_HIGH (operands[2])
8276 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8279 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8281 return \"srax\\t%1, %2, %0\";
8283 [(set_attr "type" "shift")
8284 (set_attr "length" "1")])
8287 [(set (match_operand:SI 0 "register_operand" "=r")
8288 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8290 (match_operand:SI 2 "small_int_or_double" "n")))]
8292 && ((GET_CODE (operands[2]) == CONST_INT
8293 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8294 || (GET_CODE (operands[2]) == CONST_DOUBLE
8295 && !CONST_DOUBLE_HIGH (operands[2])
8296 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8299 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8301 return \"srlx\\t%1, %2, %0\";
8303 [(set_attr "type" "shift")
8304 (set_attr "length" "1")])
8307 [(set (match_operand:SI 0 "register_operand" "=r")
8308 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8309 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8310 (match_operand:SI 3 "small_int_or_double" "n")))]
8312 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8313 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8314 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8315 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8318 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8320 return \"srax\\t%1, %2, %0\";
8322 [(set_attr "type" "shift")
8323 (set_attr "length" "1")])
8326 [(set (match_operand:SI 0 "register_operand" "=r")
8327 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8328 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8329 (match_operand:SI 3 "small_int_or_double" "n")))]
8331 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8332 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8333 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8334 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8337 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8339 return \"srlx\\t%1, %2, %0\";
8341 [(set_attr "type" "shift")
8342 (set_attr "length" "1")])
8344 ;; Unconditional and other jump instructions
8345 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8346 ;; following insn is never executed. This saves us a nop. Dbx does not
8347 ;; handle such branches though, so we only use them when optimizing.
8349 [(set (pc) (label_ref (match_operand 0 "" "")))]
8353 /* TurboSparc is reported to have problems with
8356 i.e. an empty loop with the annul bit set. The workaround is to use
8360 if (! TARGET_V9 && flag_delayed_branch
8361 && (insn_addresses[INSN_UID (operands[0])]
8362 == insn_addresses[INSN_UID (insn)]))
8363 return \"b\\t%l0%#\";
8365 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8367 [(set_attr "type" "uncond_branch")])
8369 (define_expand "tablejump"
8370 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8371 (use (label_ref (match_operand 1 "" "")))])]
8375 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8378 /* In pic mode, our address differences are against the base of the
8379 table. Add that base value back in; CSE ought to be able to combine
8380 the two address loads. */
8384 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8386 if (CASE_VECTOR_MODE != Pmode)
8387 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8388 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8389 operands[0] = memory_address (Pmode, tmp);
8393 (define_insn "*tablejump_sp32"
8394 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8395 (use (label_ref (match_operand 1 "" "")))]
8398 [(set_attr "type" "uncond_branch")])
8400 (define_insn "*tablejump_sp64"
8401 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8402 (use (label_ref (match_operand 1 "" "")))]
8405 [(set_attr "type" "uncond_branch")])
8407 ;; This pattern recognizes the "instruction" that appears in
8408 ;; a function call that wants a structure value,
8409 ;; to inform the called function if compiled with Sun CC.
8410 ;(define_insn "*unimp_insn"
8411 ; [(match_operand:SI 0 "immediate_operand" "")]
8412 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8414 ; [(set_attr "type" "marker")])
8416 ;;- jump to subroutine
8417 (define_expand "call"
8418 ;; Note that this expression is not used for generating RTL.
8419 ;; All the RTL is generated explicitly below.
8420 [(call (match_operand 0 "call_operand" "")
8421 (match_operand 3 "" "i"))]
8422 ;; operands[2] is next_arg_register
8423 ;; operands[3] is struct_value_size_rtx.
8427 rtx fn_rtx, nregs_rtx;
8429 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8432 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8434 /* This is really a PIC sequence. We want to represent
8435 it as a funny jump so its delay slots can be filled.
8437 ??? But if this really *is* a CALL, will not it clobber the
8438 call-clobbered registers? We lose this if it is a JUMP_INSN.
8439 Why cannot we have delay slots filled if it were a CALL? */
8441 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8446 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8448 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8454 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8455 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8459 fn_rtx = operands[0];
8461 /* Count the number of parameter registers being used by this call.
8462 if that argument is NULL, it means we are using them all, which
8463 means 6 on the sparc. */
8466 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8468 nregs_rtx = GEN_INT (6);
8470 nregs_rtx = const0_rtx;
8473 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8477 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8479 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8484 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8485 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8489 /* If this call wants a structure value,
8490 emit an unimp insn to let the called function know about this. */
8491 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8493 rtx insn = emit_insn (operands[3]);
8494 SCHED_GROUP_P (insn) = 1;
8501 ;; We can't use the same pattern for these two insns, because then registers
8502 ;; in the address may not be properly reloaded.
8504 (define_insn "*call_address_sp32"
8505 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8506 (match_operand 1 "" ""))
8507 (clobber (reg:SI 15))]
8508 ;;- Do not use operand 1 for most machines.
8511 [(set_attr "type" "call")])
8513 (define_insn "*call_symbolic_sp32"
8514 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8515 (match_operand 1 "" ""))
8516 (clobber (reg:SI 15))]
8517 ;;- Do not use operand 1 for most machines.
8520 [(set_attr "type" "call")])
8522 (define_insn "*call_address_sp64"
8523 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
8524 (match_operand 1 "" ""))
8525 (clobber (reg:DI 15))]
8526 ;;- Do not use operand 1 for most machines.
8529 [(set_attr "type" "call")])
8531 (define_insn "*call_symbolic_sp64"
8532 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
8533 (match_operand 1 "" ""))
8534 (clobber (reg:DI 15))]
8535 ;;- Do not use operand 1 for most machines.
8538 [(set_attr "type" "call")])
8540 ;; This is a call that wants a structure value.
8541 ;; There is no such critter for v9 (??? we may need one anyway).
8542 (define_insn "*call_address_struct_value_sp32"
8543 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8544 (match_operand 1 "" ""))
8545 (match_operand 2 "immediate_operand" "")
8546 (clobber (reg:SI 15))]
8547 ;;- Do not use operand 1 for most machines.
8548 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8549 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8550 [(set_attr "type" "call_no_delay_slot")])
8552 ;; This is a call that wants a structure value.
8553 ;; There is no such critter for v9 (??? we may need one anyway).
8554 (define_insn "*call_symbolic_struct_value_sp32"
8555 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8556 (match_operand 1 "" ""))
8557 (match_operand 2 "immediate_operand" "")
8558 (clobber (reg:SI 15))]
8559 ;;- Do not use operand 1 for most machines.
8560 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8561 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8562 [(set_attr "type" "call_no_delay_slot")])
8564 ;; This is a call that may want a structure value. This is used for
8566 (define_insn "*call_address_untyped_struct_value_sp32"
8567 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8568 (match_operand 1 "" ""))
8569 (match_operand 2 "immediate_operand" "")
8570 (clobber (reg:SI 15))]
8571 ;;- Do not use operand 1 for most machines.
8572 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8573 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8574 [(set_attr "type" "call_no_delay_slot")])
8576 ;; This is a call that wants a structure value.
8577 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8578 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8579 (match_operand 1 "" ""))
8580 (match_operand 2 "immediate_operand" "")
8581 (clobber (reg:SI 15))]
8582 ;;- Do not use operand 1 for most machines.
8583 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8584 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8585 [(set_attr "type" "call_no_delay_slot")])
8587 (define_expand "call_value"
8588 ;; Note that this expression is not used for generating RTL.
8589 ;; All the RTL is generated explicitly below.
8590 [(set (match_operand 0 "register_operand" "=rf")
8591 (call (match_operand:SI 1 "" "")
8592 (match_operand 4 "" "")))]
8593 ;; operand 2 is stack_size_rtx
8594 ;; operand 3 is next_arg_register
8598 rtx fn_rtx, nregs_rtx;
8601 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8604 fn_rtx = operands[1];
8608 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8610 nregs_rtx = GEN_INT (6);
8612 nregs_rtx = const0_rtx;
8616 gen_rtx_SET (VOIDmode, operands[0],
8617 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8618 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8620 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8625 (define_insn "*call_value_address_sp32"
8626 [(set (match_operand 0 "" "=rf")
8627 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8628 (match_operand 2 "" "")))
8629 (clobber (reg:SI 15))]
8630 ;;- Do not use operand 2 for most machines.
8633 [(set_attr "type" "call")])
8635 (define_insn "*call_value_symbolic_sp32"
8636 [(set (match_operand 0 "" "=rf")
8637 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8638 (match_operand 2 "" "")))
8639 (clobber (reg:SI 15))]
8640 ;;- Do not use operand 2 for most machines.
8643 [(set_attr "type" "call")])
8645 (define_insn "*call_value_address_sp64"
8646 [(set (match_operand 0 "" "")
8647 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
8648 (match_operand 2 "" "")))
8649 (clobber (reg:DI 15))]
8650 ;;- Do not use operand 2 for most machines.
8653 [(set_attr "type" "call")])
8655 (define_insn "*call_value_symbolic_sp64"
8656 [(set (match_operand 0 "" "")
8657 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
8658 (match_operand 2 "" "")))
8659 (clobber (reg:DI 15))]
8660 ;;- Do not use operand 2 for most machines.
8663 [(set_attr "type" "call")])
8665 (define_expand "untyped_call"
8666 [(parallel [(call (match_operand 0 "" "")
8668 (match_operand 1 "" "")
8669 (match_operand 2 "" "")])]
8675 /* Pass constm1 to indicate that it may expect a structure value, but
8676 we don't know what size it is. */
8677 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
8679 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8681 rtx set = XVECEXP (operands[2], 0, i);
8682 emit_move_insn (SET_DEST (set), SET_SRC (set));
8685 /* The optimizer does not know that the call sets the function value
8686 registers we stored in the result block. We avoid problems by
8687 claiming that all hard registers are used and clobbered at this
8689 emit_insn (gen_blockage ());
8694 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8695 ;; all of memory. This blocks insns from being moved across this point.
8697 (define_insn "blockage"
8698 [(unspec_volatile [(const_int 0)] 0)]
8701 [(set_attr "length" "0")])
8703 ;; Prepare to return any type including a structure value.
8705 (define_expand "untyped_return"
8706 [(match_operand:BLK 0 "memory_operand" "")
8707 (match_operand 1 "" "")]
8711 rtx valreg1 = gen_rtx_REG (DImode, 24);
8712 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8713 rtx result = operands[0];
8715 if (! TARGET_ARCH64)
8717 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8719 rtx value = gen_reg_rtx (SImode);
8721 /* Fetch the instruction where we will return to and see if it's an unimp
8722 instruction (the most significant 10 bits will be zero). If so,
8723 update the return address to skip the unimp instruction. */
8724 emit_move_insn (value,
8725 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8726 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8727 emit_insn (gen_update_return (rtnreg, value));
8730 /* Reload the function value registers. */
8731 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
8732 emit_move_insn (valreg2,
8733 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
8734 plus_constant (XEXP (result, 0), 8)));
8736 /* Put USE insns before the return. */
8737 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8738 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8740 /* Construct the return. */
8741 expand_null_return ();
8746 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8747 ;; and parts of the compiler don't want to believe that the add is needed.
8749 (define_insn "update_return"
8750 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8751 (match_operand:SI 1 "register_operand" "r")] 1)]
8753 "cmp %1,0\;be,a .+8\;add %0,4,%0"
8754 [(set_attr "type" "multi")])
8756 (define_insn "return"
8760 "* return output_return (operands);"
8761 [(set_attr "type" "return")])
8764 [(set (match_operand:SI 0 "register_operand" "=r")
8765 (match_operand:SI 1 "arith_operand" "rI"))
8767 (use (reg:SI 31))])]
8768 "sparc_return_peephole_ok (operands[0], operands[1])"
8769 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8775 [(set_attr "type" "ialu")
8776 (set_attr "length" "1")])
8778 (define_expand "indirect_jump"
8779 [(set (pc) (match_operand 0 "address_operand" "p"))]
8783 (define_insn "*branch_sp32"
8784 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8787 [(set_attr "type" "uncond_branch")])
8789 (define_insn "*branch_sp64"
8790 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8793 [(set_attr "type" "uncond_branch")])
8795 ;; ??? Doesn't work with -mflat.
8796 (define_expand "nonlocal_goto"
8797 [(match_operand:SI 0 "general_operand" "")
8798 (match_operand:SI 1 "general_operand" "")
8799 (match_operand:SI 2 "general_operand" "")
8800 (match_operand:SI 3 "" "")]
8805 rtx chain = operands[0];
8807 rtx fp = operands[1];
8808 rtx stack = operands[2];
8809 rtx lab = operands[3];
8812 /* Trap instruction to flush all the register windows. */
8813 emit_insn (gen_flush_register_windows ());
8815 /* Load the fp value for the containing fn into %fp. This is needed
8816 because STACK refers to %fp. Note that virtual register instantiation
8817 fails if the virtual %fp isn't set from a register. */
8818 if (GET_CODE (fp) != REG)
8819 fp = force_reg (Pmode, fp);
8820 emit_move_insn (virtual_stack_vars_rtx, fp);
8822 /* Find the containing function's current nonlocal goto handler,
8823 which will do any cleanups and then jump to the label. */
8824 labreg = gen_rtx_REG (Pmode, 8);
8825 emit_move_insn (labreg, lab);
8827 /* Restore %fp from stack pointer value for containing function.
8828 The restore insn that follows will move this to %sp,
8829 and reload the appropriate value into %fp. */
8830 emit_move_insn (frame_pointer_rtx, stack);
8832 /* USE of frame_pointer_rtx added for consistency; not clear if
8834 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8835 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8838 /* Return, restoring reg window and jumping to goto handler. */
8839 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8840 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8842 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
8847 /* Put in the static chain register the nonlocal label address. */
8848 emit_move_insn (static_chain_rtx, chain);
8851 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8852 emit_insn (gen_goto_handler_and_restore (labreg));
8857 ;; Special trap insn to flush register windows.
8858 (define_insn "flush_register_windows"
8859 [(unspec_volatile [(const_int 0)] 1)]
8861 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8862 [(set_attr "type" "misc")
8863 (set_attr "length" "1")])
8865 (define_insn "goto_handler_and_restore"
8866 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8867 "GET_MODE (operands[0]) == Pmode"
8868 "jmp\\t%0+0\\n\\trestore"
8869 [(set_attr "type" "misc")
8870 (set_attr "length" "2")])
8872 ;;(define_insn "goto_handler_and_restore_v9"
8873 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8874 ;; (match_operand:SI 1 "register_operand" "=r,r")
8875 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8876 ;; "TARGET_V9 && ! TARGET_ARCH64"
8878 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8879 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8880 ;; [(set_attr "type" "misc")
8881 ;; (set_attr "length" "2,3")])
8883 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8884 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8885 ;; (match_operand:DI 1 "register_operand" "=r,r")
8886 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8887 ;; "TARGET_V9 && TARGET_ARCH64"
8889 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8890 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8891 ;; [(set_attr "type" "misc")
8892 ;; (set_attr "length" "2,3")])
8894 ;; Pattern for use after a setjmp to store FP and the return register
8895 ;; into the stack area.
8897 (define_expand "setjmp"
8903 emit_insn (gen_setjmp_64 ());
8905 emit_insn (gen_setjmp_32 ());
8909 (define_expand "setjmp_32"
8910 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8911 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8914 { operands[0] = frame_pointer_rtx; }")
8916 (define_expand "setjmp_64"
8917 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
8918 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
8921 { operands[0] = frame_pointer_rtx; }")
8923 ;; Special pattern for the FLUSH instruction.
8925 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8926 ; of the define_insn otherwise missing a mode. We make "flush", aka
8927 ; gen_flush, the default one since sparc_initialize_trampoline uses
8928 ; it on SImode mem values.
8930 (define_insn "flush"
8931 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
8933 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
8934 [(set_attr "type" "misc")])
8936 (define_insn "flushdi"
8937 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
8939 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
8940 [(set_attr "type" "misc")])
8945 ;; The scan instruction searches from the most significant bit while ffs
8946 ;; searches from the least significant bit. The bit index and treatment of
8947 ;; zero also differ. It takes at least 7 instructions to get the proper
8948 ;; result. Here is an obvious 8 instruction sequence.
8951 (define_insn "ffssi2"
8952 [(set (match_operand:SI 0 "register_operand" "=&r")
8953 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8954 (clobber (match_scratch:SI 2 "=&r"))]
8955 "TARGET_SPARCLITE || TARGET_SPARCLET"
8959 output_asm_insn (\"and %%g0,0,%%g0\", operands);
8960 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\";
8962 [(set_attr "type" "multi")
8963 (set_attr "length" "8")])
8965 ;; ??? This should be a define expand, so that the extra instruction have
8966 ;; a chance of being optimized away.
8968 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
8969 ;; does, but no one uses that and we don't have a switch for it.
8971 ;(define_insn "ffsdi2"
8972 ; [(set (match_operand:DI 0 "register_operand" "=&r")
8973 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8974 ; (clobber (match_scratch:DI 2 "=&r"))]
8976 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
8977 ; [(set_attr "type" "multi")
8978 ; (set_attr "length" "4")])
8982 ;; Peepholes go at the end.
8984 ;; Optimize consecutive loads or stores into ldd and std when possible.
8985 ;; The conditions in which we do this are very restricted and are
8986 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8989 [(set (match_operand:SI 0 "memory_operand" "")
8991 (set (match_operand:SI 1 "memory_operand" "")
8994 && ! MEM_VOLATILE_P (operands[0])
8995 && ! MEM_VOLATILE_P (operands[1])
8996 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
9000 [(set (match_operand:SI 0 "memory_operand" "")
9002 (set (match_operand:SI 1 "memory_operand" "")
9005 && ! MEM_VOLATILE_P (operands[0])
9006 && ! MEM_VOLATILE_P (operands[1])
9007 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
9011 [(set (match_operand:SI 0 "register_operand" "=rf")
9012 (match_operand:SI 1 "memory_operand" ""))
9013 (set (match_operand:SI 2 "register_operand" "=rf")
9014 (match_operand:SI 3 "memory_operand" ""))]
9015 "registers_ok_for_ldd_peep (operands[0], operands[2])
9016 && ! MEM_VOLATILE_P (operands[1])
9017 && ! MEM_VOLATILE_P (operands[3])
9018 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9022 [(set (match_operand:SI 0 "memory_operand" "")
9023 (match_operand:SI 1 "register_operand" "rf"))
9024 (set (match_operand:SI 2 "memory_operand" "")
9025 (match_operand:SI 3 "register_operand" "rf"))]
9026 "registers_ok_for_ldd_peep (operands[1], operands[3])
9027 && ! MEM_VOLATILE_P (operands[0])
9028 && ! MEM_VOLATILE_P (operands[2])
9029 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9033 [(set (match_operand:SF 0 "register_operand" "=fr")
9034 (match_operand:SF 1 "memory_operand" ""))
9035 (set (match_operand:SF 2 "register_operand" "=fr")
9036 (match_operand:SF 3 "memory_operand" ""))]
9037 "registers_ok_for_ldd_peep (operands[0], operands[2])
9038 && ! MEM_VOLATILE_P (operands[1])
9039 && ! MEM_VOLATILE_P (operands[3])
9040 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9044 [(set (match_operand:SF 0 "memory_operand" "")
9045 (match_operand:SF 1 "register_operand" "fr"))
9046 (set (match_operand:SF 2 "memory_operand" "")
9047 (match_operand:SF 3 "register_operand" "fr"))]
9048 "registers_ok_for_ldd_peep (operands[1], operands[3])
9049 && ! MEM_VOLATILE_P (operands[0])
9050 && ! MEM_VOLATILE_P (operands[2])
9051 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9055 [(set (match_operand:SI 0 "register_operand" "=rf")
9056 (match_operand:SI 1 "memory_operand" ""))
9057 (set (match_operand:SI 2 "register_operand" "=rf")
9058 (match_operand:SI 3 "memory_operand" ""))]
9059 "registers_ok_for_ldd_peep (operands[2], operands[0])
9060 && ! MEM_VOLATILE_P (operands[3])
9061 && ! MEM_VOLATILE_P (operands[1])
9062 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9066 [(set (match_operand:SI 0 "memory_operand" "")
9067 (match_operand:SI 1 "register_operand" "rf"))
9068 (set (match_operand:SI 2 "memory_operand" "")
9069 (match_operand:SI 3 "register_operand" "rf"))]
9070 "registers_ok_for_ldd_peep (operands[3], operands[1])
9071 && ! MEM_VOLATILE_P (operands[2])
9072 && ! MEM_VOLATILE_P (operands[0])
9073 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9077 [(set (match_operand:SF 0 "register_operand" "=fr")
9078 (match_operand:SF 1 "memory_operand" ""))
9079 (set (match_operand:SF 2 "register_operand" "=fr")
9080 (match_operand:SF 3 "memory_operand" ""))]
9081 "registers_ok_for_ldd_peep (operands[2], operands[0])
9082 && ! MEM_VOLATILE_P (operands[3])
9083 && ! MEM_VOLATILE_P (operands[1])
9084 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9088 [(set (match_operand:SF 0 "memory_operand" "")
9089 (match_operand:SF 1 "register_operand" "fr"))
9090 (set (match_operand:SF 2 "memory_operand" "")
9091 (match_operand:SF 3 "register_operand" "fr"))]
9092 "registers_ok_for_ldd_peep (operands[3], operands[1])
9093 && ! MEM_VOLATILE_P (operands[2])
9094 && ! MEM_VOLATILE_P (operands[0])
9095 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9098 ;; Optimize the case of following a reg-reg move with a test
9099 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9100 ;; This can result from a float to fix conversion.
9103 [(set (match_operand:SI 0 "register_operand" "=r")
9104 (match_operand:SI 1 "register_operand" "r"))
9106 (compare:CC (match_operand:SI 2 "register_operand" "r")
9108 "(rtx_equal_p (operands[2], operands[0])
9109 || rtx_equal_p (operands[2], operands[1]))
9110 && ! FP_REG_P (operands[0])
9111 && ! FP_REG_P (operands[1])"
9115 [(set (match_operand:DI 0 "register_operand" "=r")
9116 (match_operand:DI 1 "register_operand" "r"))
9118 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9121 && (rtx_equal_p (operands[2], operands[0])
9122 || rtx_equal_p (operands[2], operands[1]))
9123 && ! FP_REG_P (operands[0])
9124 && ! FP_REG_P (operands[1])"
9127 ;; Return peepholes. First the "normal" ones.
9128 ;; These are necessary to catch insns ending up in the epilogue delay list.
9130 (define_insn "*return_qi"
9131 [(set (match_operand:QI 0 "restore_operand" "")
9132 (match_operand:QI 1 "arith_operand" "rI"))
9134 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
9137 if (! TARGET_ARCH64 && current_function_returns_struct)
9138 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9139 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9140 || IN_OR_GLOBAL_P (operands[1])))
9141 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9143 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9145 [(set_attr "type" "multi")])
9147 (define_insn "*return_hi"
9148 [(set (match_operand:HI 0 "restore_operand" "")
9149 (match_operand:HI 1 "arith_operand" "rI"))
9151 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
9154 if (! TARGET_ARCH64 && current_function_returns_struct)
9155 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9156 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9157 || IN_OR_GLOBAL_P (operands[1])))
9158 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9160 return \"ret\;restore %%g0, %1, %Y0\";
9162 [(set_attr "type" "multi")])
9164 (define_insn "*return_si"
9165 [(set (match_operand:SI 0 "restore_operand" "")
9166 (match_operand:SI 1 "arith_operand" "rI"))
9168 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
9171 if (! TARGET_ARCH64 && current_function_returns_struct)
9172 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9173 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9174 || IN_OR_GLOBAL_P (operands[1])))
9175 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9177 return \"ret\;restore %%g0, %1, %Y0\";
9179 [(set_attr "type" "multi")])
9181 ;; The following pattern is only generated by delayed-branch scheduling,
9182 ;; when the insn winds up in the epilogue. This can happen not only when
9183 ;; ! TARGET_FPU because we move complex types around by parts using
9185 (define_insn "*return_sf_no_fpu"
9186 [(set (match_operand:SF 0 "restore_operand" "=r")
9187 (match_operand:SF 1 "register_operand" "r"))
9189 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
9192 if (! TARGET_ARCH64 && current_function_returns_struct)
9193 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9194 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9195 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9197 return \"ret\;restore %%g0, %1, %Y0\";
9199 [(set_attr "type" "multi")])
9201 (define_insn "*return_addsi"
9202 [(set (match_operand:SI 0 "restore_operand" "")
9203 (plus:SI (match_operand:SI 1 "register_operand" "r")
9204 (match_operand:SI 2 "arith_operand" "rI")))
9206 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
9209 if (! TARGET_ARCH64 && current_function_returns_struct)
9210 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9211 /* If operands are global or in registers, can use return */
9212 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9213 && (GET_CODE (operands[2]) == CONST_INT
9214 || IN_OR_GLOBAL_P (operands[2])))
9215 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9217 return \"ret\;restore %r1, %2, %Y0\";
9219 [(set_attr "type" "multi")])
9221 (define_insn "*return_losum_si"
9222 [(set (match_operand:SI 0 "restore_operand" "")
9223 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9224 (match_operand:SI 2 "immediate_operand" "in")))
9226 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0 && ! TARGET_CM_MEDMID"
9229 if (! TARGET_ARCH64 && current_function_returns_struct)
9230 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9231 /* If operands are global or in registers, can use return */
9232 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9233 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9235 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9237 [(set_attr "type" "multi")])
9239 (define_insn "*return_di"
9240 [(set (match_operand:DI 0 "restore_operand" "")
9241 (match_operand:DI 1 "arith_double_operand" "rHI"))
9243 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9244 "ret\;restore %%g0, %1, %Y0"
9245 [(set_attr "type" "multi")])
9247 (define_insn "*return_adddi"
9248 [(set (match_operand:DI 0 "restore_operand" "")
9249 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9250 (match_operand:DI 2 "arith_double_operand" "rHI")))
9252 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9253 "ret\;restore %r1, %2, %Y0"
9254 [(set_attr "type" "multi")])
9256 (define_insn "*return_losum_di"
9257 [(set (match_operand:DI 0 "restore_operand" "")
9258 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9259 (match_operand:DI 2 "immediate_operand" "in")))
9261 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9262 "ret\;restore %r1, %%lo(%a2), %Y0"
9263 [(set_attr "type" "multi")])
9265 ;; The following pattern is only generated by delayed-branch scheduling,
9266 ;; when the insn winds up in the epilogue.
9267 (define_insn "*return_sf"
9269 (match_operand:SF 0 "register_operand" "f"))
9272 "ret\;fmovs\\t%0, %%f0"
9273 [(set_attr "type" "multi")])
9275 ;; Now peepholes to do a call followed by a jump.
9278 [(parallel [(set (match_operand 0 "" "")
9279 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9280 (match_operand 2 "" "")))
9281 (clobber (reg:SI 15))])
9282 (set (pc) (label_ref (match_operand 3 "" "")))]
9283 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9284 && in_same_eh_region (insn, operands[3])
9285 && in_same_eh_region (insn, ins1)"
9286 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9289 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9290 (match_operand 1 "" ""))
9291 (clobber (reg:SI 15))])
9292 (set (pc) (label_ref (match_operand 2 "" "")))]
9293 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9294 && in_same_eh_region (insn, operands[2])
9295 && in_same_eh_region (insn, ins1)"
9296 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9299 [(parallel [(set (match_operand 0 "" "")
9300 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9301 (match_operand 2 "" "")))
9302 (clobber (reg:DI 15))])
9303 (set (pc) (label_ref (match_operand 3 "" "")))]
9305 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9306 && in_same_eh_region (insn, operands[3])
9307 && in_same_eh_region (insn, ins1)"
9308 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9311 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9312 (match_operand 1 "" ""))
9313 (clobber (reg:DI 15))])
9314 (set (pc) (label_ref (match_operand 2 "" "")))]
9316 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9317 && in_same_eh_region (insn, operands[2])
9318 && in_same_eh_region (insn, ins1)"
9319 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9321 ;; After a nonlocal goto, we need to restore the PIC register, but only
9322 ;; if we need it. So do nothing much here, but we'll check for this in
9325 ;; Make sure this unspec_volatile number agrees with finalize_pic.
9326 (define_insn "nonlocal_goto_receiver"
9327 [(unspec_volatile [(const_int 0)] 5)]
9330 [(set_attr "length" "0")])
9333 [(trap_if (const_int 1) (const_int 5))]
9336 [(set_attr "type" "misc")
9337 (set_attr "length" "1")])
9339 (define_expand "conditional_trap"
9340 [(trap_if (match_operator 0 "noov_compare_op"
9341 [(match_dup 2) (match_dup 3)])
9342 (match_operand:SI 1 "arith_operand" ""))]
9344 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9345 sparc_compare_op0, sparc_compare_op1);
9346 operands[3] = const0_rtx;")
9349 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9350 (match_operand:SI 1 "arith_operand" "rM"))]
9353 [(set_attr "type" "misc")
9354 (set_attr "length" "1")])
9357 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9358 (match_operand:SI 1 "arith_operand" "rM"))]
9361 [(set_attr "type" "misc")
9362 (set_attr "length" "1")])