1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 88, 89, 92-96, 1997 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 ;; 12 movsf_const_high
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
49 ;; UNSPEC_VOLATILE: 0 blockage
50 ;; 1 flush_register_windows
51 ;; 2 goto_handler_and_restore
52 ;; 3 goto_handler_and_restore_v9*
54 ;; 5 nonlocal_goto_receiver
57 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
58 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
59 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
60 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
61 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
63 ;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to
64 ;; test TARGET_LIVE_G0 if we have TARGET_ARCH64.
66 ;; Attribute for cpu type.
67 ;; These must match the values for enum processor_type in sparc.h.
68 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v9,ultrasparc"
69 (const (symbol_ref "sparc_cpu_attr")))
71 ;; Attribute for the instruction set.
72 ;; At present we only need to distinguish v9/!v9, but for clarity we
73 ;; test TARGET_V8 too.
74 (define_attr "isa" "v6,v8,v9,sparclet"
76 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
77 (symbol_ref "TARGET_V8") (const_string "v8")
78 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
79 (const_string "v6"))))
82 (define_attr "arch" "arch32bit,arch64bit"
84 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
85 (const_string "arch32bit"))))
87 ;; Whether -mlive-g0 is in effect.
88 (define_attr "live_g0" "no,yes"
90 (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")]
91 (const_string "no"))))
93 ;; Insn type. Used to default other attribute values.
95 ;; type "unary" insns have one input operand (1) and one output operand (0)
96 ;; type "binary" insns have two input operands (1,2) and one output (0)
97 ;; type "compare" insns have one or two input operands (0,1) and no output
98 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
101 "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,fpsqrt,cmove,multi,misc"
102 (const_string "binary"))
104 ;; Set true if insn uses call-clobbered intermediate register.
105 (define_attr "use_clobbered" "false,true"
106 (if_then_else (and (eq_attr "type" "address")
107 (match_operand 0 "clobbered_register" ""))
108 (const_string "true")
109 (const_string "false")))
111 ;; Length (in # of insns).
112 (define_attr "length" ""
113 (cond [(eq_attr "type" "load,sload,fpload")
114 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
115 (const_int 2) (const_int 1))
117 (eq_attr "type" "store,fpstore")
118 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
119 (const_int 2) (const_int 1))
121 (eq_attr "type" "address") (const_int 2)
123 (eq_attr "type" "binary")
124 (if_then_else (ior (match_operand 2 "arith_operand" "")
125 (match_operand 2 "arith_double_operand" ""))
126 (const_int 1) (const_int 3))
128 (eq_attr "type" "multi") (const_int 2)
130 (eq_attr "type" "move,unary")
131 (if_then_else (ior (match_operand 1 "arith_operand" "")
132 (match_operand 1 "arith_double_operand" ""))
133 (const_int 1) (const_int 2))]
137 (define_asm_attributes
138 [(set_attr "length" "1")
139 (set_attr "type" "multi")])
141 ;; Attributes for instruction and branch scheduling
143 (define_attr "in_call_delay" "false,true"
144 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,return,multi")
145 (const_string "false")
146 (eq_attr "type" "load,fpload,store,fpstore")
147 (if_then_else (eq_attr "length" "1")
148 (const_string "true")
149 (const_string "false"))
150 (eq_attr "type" "address")
151 (if_then_else (eq_attr "use_clobbered" "false")
152 (const_string "true")
153 (const_string "false"))]
154 (if_then_else (eq_attr "length" "1")
155 (const_string "true")
156 (const_string "false"))))
158 (define_delay (eq_attr "type" "call")
159 [(eq_attr "in_call_delay" "true") (nil) (nil)])
161 (define_attr "leaf_function" "false,true"
162 (const (symbol_ref "leaf_function")))
164 (define_attr "in_return_delay" "false,true"
165 (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
166 (eq_attr "length" "1"))
167 (eq_attr "leaf_function" "false"))
168 (match_insn "eligible_for_return_delay"))
169 (const_string "true")
170 (const_string "false")))
172 (define_delay (and (eq_attr "type" "return")
173 (eq_attr "isa" "v9"))
174 [(eq_attr "in_return_delay" "true") (nil) (nil)])
176 ;; ??? Should implement the notion of predelay slots for floating point
177 ;; branches. This would allow us to remove the nop always inserted before
178 ;; a floating point branch.
180 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
181 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
182 ;; This is because doing so will add several pipeline stalls to the path
183 ;; that the load/store did not come from. Unfortunately, there is no way
184 ;; to prevent fill_eager_delay_slots from using load/store without completely
185 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
186 ;; because it prevents us from moving back the final store of inner loops.
188 (define_attr "in_branch_delay" "false,true"
189 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
190 (eq_attr "length" "1"))
191 (const_string "true")
192 (const_string "false")))
194 (define_attr "in_uncond_branch_delay" "false,true"
195 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
196 (eq_attr "length" "1"))
197 (const_string "true")
198 (const_string "false")))
200 (define_attr "in_annul_branch_delay" "false,true"
201 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
202 (eq_attr "length" "1"))
203 (const_string "true")
204 (const_string "false")))
206 (define_delay (eq_attr "type" "branch")
207 [(eq_attr "in_branch_delay" "true")
208 (nil) (eq_attr "in_annul_branch_delay" "true")])
210 (define_delay (eq_attr "type" "uncond_branch")
211 [(eq_attr "in_uncond_branch_delay" "true")
214 ;; Function units of the SPARC
216 ;; (define_function_unit {name} {num-units} {n-users} {test}
217 ;; {ready-delay} {issue-delay} [{conflict-list}])
220 ;; (Noted only for documentation; units that take one cycle do not need to
223 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
226 ;; (define_function_unit "alu" 1 0
227 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
229 ;; ---- cypress CY7C602 scheduling:
230 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
232 (define_function_unit "memory" 1 0
233 (and (eq_attr "cpu" "cypress")
234 (eq_attr "type" "load,sload,fpload"))
237 ;; SPARC has two floating-point units: the FP ALU,
238 ;; and the FP MUL/DIV/SQRT unit.
239 ;; Instruction timings on the CY7C602 are as follows
253 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
254 ;; More insns cause the chip to stall.
256 (define_function_unit "fp_alu" 1 0
257 (and (eq_attr "cpu" "cypress")
258 (eq_attr "type" "fp,fpmove"))
261 (define_function_unit "fp_mds" 1 0
262 (and (eq_attr "cpu" "cypress")
263 (eq_attr "type" "fpmul"))
266 (define_function_unit "fp_mds" 1 0
267 (and (eq_attr "cpu" "cypress")
268 (eq_attr "type" "fpdivs,fpdivd"))
271 (define_function_unit "fp_mds" 1 0
272 (and (eq_attr "cpu" "cypress")
273 (eq_attr "type" "fpsqrt"))
276 ;; ----- The TMS390Z55 scheduling
277 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
278 ;; one ld/st, one fp.
279 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
281 (define_function_unit "memory" 1 0
282 (and (eq_attr "cpu" "supersparc")
283 (eq_attr "type" "load,sload"))
286 (define_function_unit "memory" 1 0
287 (and (eq_attr "cpu" "supersparc")
288 (eq_attr "type" "fpload"))
291 (define_function_unit "memory" 1 0
292 (and (eq_attr "cpu" "supersparc")
293 (eq_attr "type" "store,fpstore"))
296 (define_function_unit "shift" 1 0
297 (and (eq_attr "cpu" "supersparc")
298 (eq_attr "type" "shift"))
301 ;; There are only two write ports to the integer register file
302 ;; A store also uses a write port
304 (define_function_unit "iwport" 2 0
305 (and (eq_attr "cpu" "supersparc")
306 (eq_attr "type" "load,sload,store,shift,ialu"))
309 ;; Timings; throughput/latency
310 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
318 (define_function_unit "fp_alu" 1 0
319 (and (eq_attr "cpu" "supersparc")
320 (eq_attr "type" "fp,fpmove,fpcmp"))
323 (define_function_unit "fp_mds" 1 0
324 (and (eq_attr "cpu" "supersparc")
325 (eq_attr "type" "fpmul"))
328 (define_function_unit "fp_mds" 1 0
329 (and (eq_attr "cpu" "supersparc")
330 (eq_attr "type" "fpdivs"))
333 (define_function_unit "fp_mds" 1 0
334 (and (eq_attr "cpu" "supersparc")
335 (eq_attr "type" "fpdivd"))
338 (define_function_unit "fp_mds" 1 0
339 (and (eq_attr "cpu" "supersparc")
340 (eq_attr "type" "fpsqrt"))
343 (define_function_unit "fp_mds" 1 0
344 (and (eq_attr "cpu" "supersparc")
345 (eq_attr "type" "imul"))
348 ;; ----- sparclet tsc701 scheduling
349 ;; The tsc701 issues 1 insn per cycle.
350 ;; Results may be written back out of order.
352 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
354 (define_function_unit "tsc701_load" 4 1
355 (and (eq_attr "cpu" "tsc701")
356 (eq_attr "type" "load,sload"))
359 ;; Stores take 2(?) extra cycles to complete.
360 ;; It is desirable to not have any memory operation in the following 2 cycles.
361 ;; (??? or 2 memory ops in the case of std).
363 (define_function_unit "tsc701_store" 1 0
364 (and (eq_attr "cpu" "tsc701")
365 (eq_attr "type" "store"))
367 [(eq_attr "type" "load,sload,store")])
369 ;; The multiply unit has a latency of 5.
370 (define_function_unit "tsc701_mul" 1 0
371 (and (eq_attr "cpu" "tsc701")
372 (eq_attr "type" "imul"))
375 ;; ----- The UltraSPARC-1 scheduling
376 ;; UltraSPARC has two integer units. Shift instructions can only execute
377 ;; on IE0. Condition code setting instructions, call, and jmpl (including
378 ;; the ret and retl pseudo-instructions) can only execute on IE1.
379 ;; Branch on register uses IE1, but branch on condition code does not.
380 ;; Conditional moves take 2 cycles. No other instruction can issue in the
381 ;; same cycle as a conditional move.
382 ;; Multiply and divide take many cycles during which no other instructions
384 ;; Memory delivers its result in two cycles (except for signed loads,
385 ;; which take one cycle more). One memory instruction can be issued per
388 (define_function_unit "memory" 1 0
389 (and (eq_attr "cpu" "ultrasparc")
390 (eq_attr "type" "load,fpload"))
393 (define_function_unit "memory" 1 0
394 (and (eq_attr "cpu" "ultrasparc")
395 (eq_attr "type" "sload"))
398 (define_function_unit "memory" 1 0
399 (and (eq_attr "cpu" "ultrasparc")
400 (eq_attr "type" "store,fpstore"))
403 (define_function_unit "ieuN" 2 0
404 (and (eq_attr "cpu" "ultrasparc")
405 (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,call_no_delay_slot,uncond_branch"))
408 (define_function_unit "ieu0" 1 0
409 (and (eq_attr "cpu" "ultrasparc")
410 (eq_attr "type" "shift"))
413 (define_function_unit "ieu0" 1 0
414 (and (eq_attr "cpu" "ultrasparc")
415 (eq_attr "type" "cmove"))
418 (define_function_unit "ieu1" 1 0
419 (and (eq_attr "cpu" "ultrasparc")
420 (eq_attr "type" "compare,call,call_no_delay_slot,uncond_branch"))
423 (define_function_unit "cti" 1 0
424 (and (eq_attr "cpu" "ultrasparc")
425 (eq_attr "type" "branch"))
428 ;; Timings; throughput/latency
429 ;; FMOV 1/1 fmov, fabs, fneg
431 ;; FADD 1/4 add/sub, format conv, compar
437 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
439 ;; ??? This is really bogus because the timings really depend upon
440 ;; who uses the result. We should record who the user is with
441 ;; more descriptive 'type' attribute names and account for these
442 ;; issues in ultrasparc_adjust_cost.
444 (define_function_unit "fadd" 1 0
445 (and (eq_attr "cpu" "ultrasparc")
446 (eq_attr "type" "fpmove"))
449 (define_function_unit "fadd" 1 0
450 (and (eq_attr "cpu" "ultrasparc")
451 (eq_attr "type" "fpcmove"))
454 (define_function_unit "fadd" 1 0
455 (and (eq_attr "cpu" "ultrasparc")
456 (eq_attr "type" "fp"))
459 (define_function_unit "fadd" 1 0
460 (and (eq_attr "cpu" "ultrasparc")
461 (eq_attr "type" "fpcmp"))
464 (define_function_unit "fmul" 1 0
465 (and (eq_attr "cpu" "ultrasparc")
466 (eq_attr "type" "fpmul"))
469 (define_function_unit "fadd" 1 0
470 (and (eq_attr "cpu" "ultrasparc")
471 (eq_attr "type" "fpcmove"))
474 (define_function_unit "fmul" 1 0
475 (and (eq_attr "cpu" "ultrasparc")
476 (eq_attr "type" "fpdivs"))
479 (define_function_unit "fmul" 1 0
480 (and (eq_attr "cpu" "ultrasparc")
481 (eq_attr "type" "fpdivd"))
484 (define_function_unit "fmul" 1 0
485 (and (eq_attr "cpu" "ultrasparc")
486 (eq_attr "type" "fpsqrt"))
489 ;; Compare instructions.
490 ;; This controls RTL generation and register allocation.
492 ;; We generate RTL for comparisons and branches by having the cmpxx
493 ;; patterns store away the operands. Then, the scc and bcc patterns
494 ;; emit RTL for both the compare and the branch.
496 ;; We do this because we want to generate different code for an sne and
497 ;; seq insn. In those cases, if the second operand of the compare is not
498 ;; const0_rtx, we want to compute the xor of the two operands and test
501 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
502 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
503 ;; insns that actually require more than one machine instruction.
505 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
507 (define_expand "cmpsi"
509 (compare:CC (match_operand:SI 0 "register_operand" "")
510 (match_operand:SI 1 "arith_operand" "")))]
514 sparc_compare_op0 = operands[0];
515 sparc_compare_op1 = operands[1];
519 (define_expand "cmpdi"
521 (compare:CCX (match_operand:DI 0 "register_operand" "")
522 (match_operand:DI 1 "arith_double_operand" "")))]
526 sparc_compare_op0 = operands[0];
527 sparc_compare_op1 = operands[1];
531 (define_expand "cmpsf"
532 ;; The 96 here isn't ever used by anyone.
534 (compare:CCFP (match_operand:SF 0 "register_operand" "")
535 (match_operand:SF 1 "register_operand" "")))]
539 sparc_compare_op0 = operands[0];
540 sparc_compare_op1 = operands[1];
544 (define_expand "cmpdf"
545 ;; The 96 here isn't ever used by anyone.
547 (compare:CCFP (match_operand:DF 0 "register_operand" "")
548 (match_operand:DF 1 "register_operand" "")))]
552 sparc_compare_op0 = operands[0];
553 sparc_compare_op1 = operands[1];
557 (define_expand "cmptf"
558 ;; The 96 here isn't ever used by anyone.
560 (compare:CCFP (match_operand:TF 0 "register_operand" "")
561 (match_operand:TF 1 "register_operand" "")))]
565 sparc_compare_op0 = operands[0];
566 sparc_compare_op1 = operands[1];
570 ;; Now the compare DEFINE_INSNs.
572 (define_insn "*cmpsi_insn"
574 (compare:CC (match_operand:SI 0 "register_operand" "r")
575 (match_operand:SI 1 "arith_operand" "rI")))]
578 [(set_attr "type" "compare")])
580 (define_insn "*cmpdi_sp64"
582 (compare:CCX (match_operand:DI 0 "register_operand" "r")
583 (match_operand:DI 1 "arith_double_operand" "rHI")))]
586 [(set_attr "type" "compare")])
588 (define_insn "*cmpsf_fpe"
589 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
590 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
591 (match_operand:SF 2 "register_operand" "f")))]
596 return \"fcmpes\\t%0, %1, %2\";
597 return \"fcmpes\\t%1, %2\";
599 [(set_attr "type" "fpcmp")])
601 (define_insn "*cmpdf_fpe"
602 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
603 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
604 (match_operand:DF 2 "register_operand" "e")))]
609 return \"fcmped\\t%0, %1, %2\";
610 return \"fcmped\\t%1, %2\";
612 [(set_attr "type" "fpcmp")])
614 (define_insn "*cmptf_fpe"
615 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
616 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
617 (match_operand:TF 2 "register_operand" "e")))]
618 "TARGET_FPU && TARGET_HARD_QUAD"
622 return \"fcmpeq\\t%0, %1, %2\";
623 return \"fcmpeq\\t%1, %2\";
625 [(set_attr "type" "fpcmp")])
627 (define_insn "*cmpsf_fp"
628 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
629 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
630 (match_operand:SF 2 "register_operand" "f")))]
635 return \"fcmps\\t%0, %1, %2\";
636 return \"fcmps\\t%1, %2\";
638 [(set_attr "type" "fpcmp")])
640 (define_insn "*cmpdf_fp"
641 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
642 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
643 (match_operand:DF 2 "register_operand" "e")))]
648 return \"fcmpd\\t%0, %1, %2\";
649 return \"fcmpd\\t%1, %2\";
651 [(set_attr "type" "fpcmp")])
653 (define_insn "*cmptf_fp"
654 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
655 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
656 (match_operand:TF 2 "register_operand" "e")))]
657 "TARGET_FPU && TARGET_HARD_QUAD"
661 return \"fcmpq\\t%0, %1, %2\";
662 return \"fcmpq\\t%1, %2\";
664 [(set_attr "type" "fpcmp")])
666 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
667 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
668 ;; the same code as v8 (the addx/subx method has more applications). The
669 ;; exception to this is "reg != 0" which can be done in one instruction on v9
670 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
673 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
674 ;; generate addcc/subcc instructions.
676 (define_expand "seqsi_special"
678 (xor:SI (match_operand:SI 1 "register_operand" "")
679 (match_operand:SI 2 "register_operand" "")))
680 (parallel [(set (match_operand:SI 0 "register_operand" "")
681 (eq:SI (match_dup 3) (const_int 0)))
682 (clobber (reg:CC 100))])]
684 "{ operands[3] = gen_reg_rtx (SImode); }")
686 (define_expand "seqdi_special"
688 (xor:DI (match_operand:DI 1 "register_operand" "")
689 (match_operand:DI 2 "register_operand" "")))
690 (set (match_operand:DI 0 "register_operand" "")
691 (eq:DI (match_dup 3) (const_int 0)))]
693 "{ operands[3] = gen_reg_rtx (DImode); }")
695 (define_expand "snesi_special"
697 (xor:SI (match_operand:SI 1 "register_operand" "")
698 (match_operand:SI 2 "register_operand" "")))
699 (parallel [(set (match_operand:SI 0 "register_operand" "")
700 (ne:SI (match_dup 3) (const_int 0)))
701 (clobber (reg:CC 100))])]
703 "{ operands[3] = gen_reg_rtx (SImode); }")
705 (define_expand "snedi_special"
707 (xor:DI (match_operand:DI 1 "register_operand" "")
708 (match_operand:DI 2 "register_operand" "")))
709 (set (match_operand:DI 0 "register_operand" "")
710 (ne:DI (match_dup 3) (const_int 0)))]
712 "{ operands[3] = gen_reg_rtx (DImode); }")
714 (define_expand "seqdi_special_trunc"
716 (xor:DI (match_operand:DI 1 "register_operand" "")
717 (match_operand:DI 2 "register_operand" "")))
718 (set (match_operand:SI 0 "register_operand" "")
719 (eq:SI (match_dup 3) (const_int 0)))]
721 "{ operands[3] = gen_reg_rtx (DImode); }")
723 (define_expand "snedi_special_trunc"
725 (xor:DI (match_operand:DI 1 "register_operand" "")
726 (match_operand:DI 2 "register_operand" "")))
727 (set (match_operand:SI 0 "register_operand" "")
728 (ne:SI (match_dup 3) (const_int 0)))]
730 "{ operands[3] = gen_reg_rtx (DImode); }")
732 (define_expand "seqsi_special_extend"
734 (xor:SI (match_operand:SI 1 "register_operand" "")
735 (match_operand:SI 2 "register_operand" "")))
736 (parallel [(set (match_operand:DI 0 "register_operand" "")
737 (eq:DI (match_dup 3) (const_int 0)))
738 (clobber (reg:CC 100))])]
740 "{ operands[3] = gen_reg_rtx (SImode); }")
742 (define_expand "snesi_special_extend"
744 (xor:SI (match_operand:SI 1 "register_operand" "")
745 (match_operand:SI 2 "register_operand" "")))
746 (parallel [(set (match_operand:DI 0 "register_operand" "")
747 (ne:DI (match_dup 3) (const_int 0)))
748 (clobber (reg:CC 100))])]
750 "{ operands[3] = gen_reg_rtx (SImode); }")
752 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
753 ;; However, the code handles both SImode and DImode.
755 [(set (match_operand:SI 0 "intreg_operand" "")
756 (eq:SI (match_dup 1) (const_int 0)))]
760 if (GET_MODE (sparc_compare_op0) == SImode)
764 if (GET_MODE (operands[0]) == SImode)
765 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
767 else if (! TARGET_ARCH64)
770 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
775 else if (GET_MODE (sparc_compare_op0) == DImode)
781 else if (GET_MODE (operands[0]) == SImode)
782 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
785 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
790 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
792 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
793 emit_insn (gen_sne (operands[0]));
798 if (gen_v9_scc (EQ, operands))
805 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
806 ;; However, the code handles both SImode and DImode.
808 [(set (match_operand:SI 0 "intreg_operand" "")
809 (ne:SI (match_dup 1) (const_int 0)))]
813 if (GET_MODE (sparc_compare_op0) == SImode)
817 if (GET_MODE (operands[0]) == SImode)
818 pat = gen_snesi_special (operands[0], sparc_compare_op0,
820 else if (! TARGET_ARCH64)
823 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
828 else if (GET_MODE (sparc_compare_op0) == DImode)
834 else if (GET_MODE (operands[0]) == SImode)
835 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
838 pat = gen_snedi_special (operands[0], sparc_compare_op0,
843 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
845 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
846 emit_insn (gen_sne (operands[0]));
851 if (gen_v9_scc (NE, operands))
859 [(set (match_operand:SI 0 "intreg_operand" "")
860 (gt:SI (match_dup 1) (const_int 0)))]
864 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
866 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
867 emit_insn (gen_sne (operands[0]));
872 if (gen_v9_scc (GT, operands))
880 [(set (match_operand:SI 0 "intreg_operand" "")
881 (lt:SI (match_dup 1) (const_int 0)))]
885 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
887 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
888 emit_insn (gen_sne (operands[0]));
893 if (gen_v9_scc (LT, operands))
901 [(set (match_operand:SI 0 "intreg_operand" "")
902 (ge:SI (match_dup 1) (const_int 0)))]
906 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
908 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
909 emit_insn (gen_sne (operands[0]));
914 if (gen_v9_scc (GE, operands))
922 [(set (match_operand:SI 0 "intreg_operand" "")
923 (le:SI (match_dup 1) (const_int 0)))]
927 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
929 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
930 emit_insn (gen_sne (operands[0]));
935 if (gen_v9_scc (LE, operands))
942 (define_expand "sgtu"
943 [(set (match_operand:SI 0 "intreg_operand" "")
944 (gtu:SI (match_dup 1) (const_int 0)))]
952 /* We can do ltu easily, so if both operands are registers, swap them and
954 if ((GET_CODE (sparc_compare_op0) == REG
955 || GET_CODE (sparc_compare_op0) == SUBREG)
956 && (GET_CODE (sparc_compare_op1) == REG
957 || GET_CODE (sparc_compare_op1) == SUBREG))
959 tem = sparc_compare_op0;
960 sparc_compare_op0 = sparc_compare_op1;
961 sparc_compare_op1 = tem;
962 pat = gen_sltu (operands[0]);
971 if (gen_v9_scc (GTU, operands))
977 (define_expand "sltu"
978 [(set (match_operand:SI 0 "intreg_operand" "")
979 (ltu:SI (match_dup 1) (const_int 0)))]
985 if (gen_v9_scc (LTU, operands))
988 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
991 (define_expand "sgeu"
992 [(set (match_operand:SI 0 "intreg_operand" "")
993 (geu:SI (match_dup 1) (const_int 0)))]
999 if (gen_v9_scc (GEU, operands))
1002 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1005 (define_expand "sleu"
1006 [(set (match_operand:SI 0 "intreg_operand" "")
1007 (leu:SI (match_dup 1) (const_int 0)))]
1015 /* We can do geu easily, so if both operands are registers, swap them and
1017 if ((GET_CODE (sparc_compare_op0) == REG
1018 || GET_CODE (sparc_compare_op0) == SUBREG)
1019 && (GET_CODE (sparc_compare_op1) == REG
1020 || GET_CODE (sparc_compare_op1) == SUBREG))
1022 tem = sparc_compare_op0;
1023 sparc_compare_op0 = sparc_compare_op1;
1024 sparc_compare_op1 = tem;
1025 pat = gen_sgeu (operands[0]);
1026 if (pat == NULL_RTX)
1034 if (gen_v9_scc (LEU, operands))
1040 ;; Now the DEFINE_INSNs for the scc cases.
1042 ;; The SEQ and SNE patterns are special because they can be done
1043 ;; without any branching and do not involve a COMPARE. We want
1044 ;; them to always use the splitz below so the results can be
1047 (define_insn "*snesi_zero"
1048 [(set (match_operand:SI 0 "register_operand" "=r")
1049 (ne:SI (match_operand:SI 1 "register_operand" "r")
1051 (clobber (reg:CC 100))]
1054 [(set_attr "length" "2")])
1057 [(set (match_operand:SI 0 "register_operand" "")
1058 (ne:SI (match_operand:SI 1 "register_operand" "")
1060 (clobber (reg:CC 100))]
1062 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1064 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1067 (define_insn "*neg_snesi_zero"
1068 [(set (match_operand:SI 0 "register_operand" "=r")
1069 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1071 (clobber (reg:CC 100))]
1074 [(set_attr "length" "2")])
1077 [(set (match_operand:SI 0 "register_operand" "")
1078 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1080 (clobber (reg:CC 100))]
1082 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1084 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1087 (define_insn "*snesi_zero_extend"
1088 [(set (match_operand:DI 0 "register_operand" "=r")
1089 (ne:DI (match_operand:SI 1 "register_operand" "r")
1091 (clobber (reg:CC 100))]
1094 [(set_attr "type" "unary")
1095 (set_attr "length" "2")])
1098 [(set (match_operand:DI 0 "register_operand" "")
1099 (ne:DI (match_operand:SI 1 "register_operand" "")
1101 (clobber (reg:CC 100))]
1103 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1105 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1107 (ltu:SI (reg:CC_NOOV 100)
1111 (define_insn "*snedi_zero"
1112 [(set (match_operand:DI 0 "register_operand" "=&r")
1113 (ne:DI (match_operand:DI 1 "register_operand" "r")
1117 [(set_attr "type" "cmove")
1118 (set_attr "length" "2")])
1121 [(set (match_operand:DI 0 "register_operand" "")
1122 (ne:DI (match_operand:DI 1 "register_operand" "")
1125 [(set (match_dup 0) (const_int 0))
1126 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1132 (define_insn "*neg_snedi_zero"
1133 [(set (match_operand:DI 0 "register_operand" "=&r")
1134 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1138 [(set_attr "type" "cmove")
1139 (set_attr "length" "2")])
1142 [(set (match_operand:DI 0 "register_operand" "")
1143 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1146 [(set (match_dup 0) (const_int 0))
1147 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1153 (define_insn "*snedi_zero_trunc"
1154 [(set (match_operand:SI 0 "register_operand" "=&r")
1155 (ne:SI (match_operand:DI 1 "register_operand" "r")
1159 [(set_attr "type" "cmove")
1160 (set_attr "length" "2")])
1163 [(set (match_operand:SI 0 "register_operand" "")
1164 (ne:SI (match_operand:DI 1 "register_operand" "")
1167 [(set (match_dup 0) (const_int 0))
1168 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1174 (define_insn "*seqsi_zero"
1175 [(set (match_operand:SI 0 "register_operand" "=r")
1176 (eq:SI (match_operand:SI 1 "register_operand" "r")
1178 (clobber (reg:CC 100))]
1181 [(set_attr "length" "2")])
1184 [(set (match_operand:SI 0 "register_operand" "")
1185 (eq:SI (match_operand:SI 1 "register_operand" "")
1187 (clobber (reg:CC 100))]
1189 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1191 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1194 (define_insn "*neg_seqsi_zero"
1195 [(set (match_operand:SI 0 "register_operand" "=r")
1196 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1198 (clobber (reg:CC 100))]
1201 [(set_attr "length" "2")])
1204 [(set (match_operand:SI 0 "register_operand" "")
1205 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1207 (clobber (reg:CC 100))]
1209 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1211 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1214 (define_insn "*seqsi_zero_extend"
1215 [(set (match_operand:DI 0 "register_operand" "=r")
1216 (eq:DI (match_operand:SI 1 "register_operand" "r")
1218 (clobber (reg:CC 100))]
1221 [(set_attr "type" "unary")
1222 (set_attr "length" "2")])
1225 [(set (match_operand:DI 0 "register_operand" "")
1226 (eq:DI (match_operand:SI 1 "register_operand" "")
1228 (clobber (reg:CC 100))]
1230 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1232 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1234 (ltu:SI (reg:CC_NOOV 100)
1238 (define_insn "*seqdi_zero"
1239 [(set (match_operand:DI 0 "register_operand" "=&r")
1240 (eq:DI (match_operand:DI 1 "register_operand" "r")
1244 [(set_attr "type" "cmove")
1245 (set_attr "length" "2")])
1248 [(set (match_operand:DI 0 "register_operand" "")
1249 (eq:DI (match_operand:DI 1 "register_operand" "")
1252 [(set (match_dup 0) (const_int 0))
1253 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1259 (define_insn "*neg_seqdi_zero"
1260 [(set (match_operand:DI 0 "register_operand" "=&r")
1261 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1265 [(set_attr "type" "cmove")
1266 (set_attr "length" "2")])
1269 [(set (match_operand:DI 0 "register_operand" "")
1270 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1273 [(set (match_dup 0) (const_int 0))
1274 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1280 (define_insn "*seqdi_zero_trunc"
1281 [(set (match_operand:SI 0 "register_operand" "=&r")
1282 (eq:SI (match_operand:DI 1 "register_operand" "r")
1286 [(set_attr "type" "cmove")
1287 (set_attr "length" "2")])
1290 [(set (match_operand:SI 0 "register_operand" "")
1291 (eq:SI (match_operand:DI 1 "register_operand" "")
1294 [(set (match_dup 0) (const_int 0))
1295 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1301 ;; We can also do (x + (i == 0)) and related, so put them in.
1302 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1305 (define_insn "*x_plus_i_ne_0"
1306 [(set (match_operand:SI 0 "register_operand" "=r")
1307 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1309 (match_operand:SI 2 "register_operand" "r")))
1310 (clobber (reg:CC 100))]
1313 [(set_attr "length" "2")])
1316 [(set (match_operand:SI 0 "register_operand" "")
1317 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1319 (match_operand:SI 2 "register_operand" "")))
1320 (clobber (reg:CC 100))]
1322 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1324 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1328 (define_insn "*x_minus_i_ne_0"
1329 [(set (match_operand:SI 0 "register_operand" "=r")
1330 (minus:SI (match_operand:SI 2 "register_operand" "r")
1331 (ne:SI (match_operand:SI 1 "register_operand" "r")
1333 (clobber (reg:CC 100))]
1336 [(set_attr "length" "2")])
1339 [(set (match_operand:SI 0 "register_operand" "")
1340 (minus:SI (match_operand:SI 2 "register_operand" "")
1341 (ne:SI (match_operand:SI 1 "register_operand" "")
1343 (clobber (reg:CC 100))]
1345 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1347 (set (match_dup 0) (minus:SI (match_dup 2)
1348 (ltu:SI (reg:CC 100) (const_int 0))))]
1351 (define_insn "*x_plus_i_eq_0"
1352 [(set (match_operand:SI 0 "register_operand" "=r")
1353 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1355 (match_operand:SI 2 "register_operand" "r")))
1356 (clobber (reg:CC 100))]
1359 [(set_attr "length" "2")])
1362 [(set (match_operand:SI 0 "register_operand" "")
1363 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1365 (match_operand:SI 2 "register_operand" "")))
1366 (clobber (reg:CC 100))]
1368 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1370 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1374 (define_insn "*x_minus_i_eq_0"
1375 [(set (match_operand:SI 0 "register_operand" "=r")
1376 (minus:SI (match_operand:SI 2 "register_operand" "r")
1377 (eq:SI (match_operand:SI 1 "register_operand" "r")
1379 (clobber (reg:CC 100))]
1382 [(set_attr "length" "2")])
1385 [(set (match_operand:SI 0 "register_operand" "")
1386 (minus:SI (match_operand:SI 2 "register_operand" "")
1387 (eq:SI (match_operand:SI 1 "register_operand" "")
1389 (clobber (reg:CC 100))]
1391 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1393 (set (match_dup 0) (minus:SI (match_dup 2)
1394 (geu:SI (reg:CC 100) (const_int 0))))]
1397 ;; We can also do GEU and LTU directly, but these operate after a compare.
1398 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1401 (define_insn "*sltu_insn"
1402 [(set (match_operand:SI 0 "register_operand" "=r")
1403 (ltu:SI (reg:CC 100) (const_int 0)))]
1405 "addx\\t%%g0, 0, %0"
1406 [(set_attr "type" "misc")
1407 (set_attr "length" "1")])
1409 (define_insn "*neg_sltu_insn"
1410 [(set (match_operand:SI 0 "register_operand" "=r")
1411 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1413 "subx\\t%%g0, 0, %0"
1414 [(set_attr "type" "misc")
1415 (set_attr "length" "1")])
1417 ;; ??? Combine should canonicalize these next two to the same pattern.
1418 (define_insn "*neg_sltu_minus_x"
1419 [(set (match_operand:SI 0 "register_operand" "=r")
1420 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1421 (match_operand:SI 1 "arith_operand" "rI")))]
1423 "subx\\t%%g0, %1, %0"
1424 [(set_attr "type" "misc")
1425 (set_attr "length" "1")])
1427 (define_insn "*neg_sltu_plus_x"
1428 [(set (match_operand:SI 0 "register_operand" "=r")
1429 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1430 (match_operand:SI 1 "arith_operand" "rI"))))]
1432 "subx\\t%%g0, %1, %0"
1433 [(set_attr "type" "misc")
1434 (set_attr "length" "1")])
1436 (define_insn "*sgeu_insn"
1437 [(set (match_operand:SI 0 "register_operand" "=r")
1438 (geu:SI (reg:CC 100) (const_int 0)))]
1440 "subx\\t%%g0, -1, %0"
1441 [(set_attr "type" "misc")
1442 (set_attr "length" "1")])
1444 (define_insn "*neg_sgeu_insn"
1445 [(set (match_operand:SI 0 "register_operand" "=r")
1446 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1448 "addx\\t%%g0, -1, %0"
1449 [(set_attr "type" "misc")
1450 (set_attr "length" "1")])
1452 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1453 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1456 (define_insn "*sltu_plus_x"
1457 [(set (match_operand:SI 0 "register_operand" "=r")
1458 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1459 (match_operand:SI 1 "arith_operand" "rI")))]
1461 "addx\\t%%g0, %1, %0"
1462 [(set_attr "type" "misc")
1463 (set_attr "length" "1")])
1465 (define_insn "*sltu_plus_x_plus_y"
1466 [(set (match_operand:SI 0 "register_operand" "=r")
1467 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1468 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1469 (match_operand:SI 2 "arith_operand" "rI"))))]
1472 [(set_attr "type" "misc")
1473 (set_attr "length" "1")])
1475 (define_insn "*x_minus_sltu"
1476 [(set (match_operand:SI 0 "register_operand" "=r")
1477 (minus:SI (match_operand:SI 1 "register_operand" "r")
1478 (ltu:SI (reg:CC 100) (const_int 0))))]
1481 [(set_attr "type" "misc")
1482 (set_attr "length" "1")])
1484 ;; ??? Combine should canonicalize these next two to the same pattern.
1485 (define_insn "*x_minus_y_minus_sltu"
1486 [(set (match_operand:SI 0 "register_operand" "=r")
1487 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1488 (match_operand:SI 2 "arith_operand" "rI"))
1489 (ltu:SI (reg:CC 100) (const_int 0))))]
1491 "subx\\t%r1, %2, %0"
1492 [(set_attr "type" "misc")
1493 (set_attr "length" "1")])
1495 (define_insn "*x_minus_sltu_plus_y"
1496 [(set (match_operand:SI 0 "register_operand" "=r")
1497 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1498 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1499 (match_operand:SI 2 "arith_operand" "rI"))))]
1501 "subx\\t%r1, %2, %0"
1502 [(set_attr "type" "misc")
1503 (set_attr "length" "1")])
1505 (define_insn "*sgeu_plus_x"
1506 [(set (match_operand:SI 0 "register_operand" "=r")
1507 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1508 (match_operand:SI 1 "register_operand" "r")))]
1511 [(set_attr "type" "misc")
1512 (set_attr "length" "1")])
1514 (define_insn "*x_minus_sgeu"
1515 [(set (match_operand:SI 0 "register_operand" "=r")
1516 (minus:SI (match_operand:SI 1 "register_operand" "r")
1517 (geu:SI (reg:CC 100) (const_int 0))))]
1520 [(set_attr "type" "misc")
1521 (set_attr "length" "1")])
1524 [(set (match_operand:SI 0 "register_operand" "=r")
1525 (match_operator:SI 2 "noov_compare_op"
1526 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1528 ;; 32 bit LTU/GEU are better implemented using addx/subx
1529 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1530 && (GET_MODE (operands[1]) == CCXmode
1531 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1532 [(set (match_dup 0) (const_int 0))
1534 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1540 ;; These control RTL generation for conditional jump insns
1542 ;; The quad-word fp compare library routines all return nonzero to indicate
1543 ;; true, which is different from the equivalent libgcc routines, so we must
1544 ;; handle them specially here.
1546 (define_expand "beq"
1548 (if_then_else (eq (match_dup 1) (const_int 0))
1549 (label_ref (match_operand 0 "" ""))
1554 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1555 && GET_CODE (sparc_compare_op0) == REG
1556 && GET_MODE (sparc_compare_op0) == DImode)
1558 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1561 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1563 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1564 emit_jump_insn (gen_bne (operands[0]));
1567 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1570 (define_expand "bne"
1572 (if_then_else (ne (match_dup 1) (const_int 0))
1573 (label_ref (match_operand 0 "" ""))
1578 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1579 && GET_CODE (sparc_compare_op0) == REG
1580 && GET_MODE (sparc_compare_op0) == DImode)
1582 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1585 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1587 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1588 emit_jump_insn (gen_bne (operands[0]));
1591 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1594 (define_expand "bgt"
1596 (if_then_else (gt (match_dup 1) (const_int 0))
1597 (label_ref (match_operand 0 "" ""))
1602 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1603 && GET_CODE (sparc_compare_op0) == REG
1604 && GET_MODE (sparc_compare_op0) == DImode)
1606 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1609 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1611 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1612 emit_jump_insn (gen_bne (operands[0]));
1615 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1618 (define_expand "bgtu"
1620 (if_then_else (gtu (match_dup 1) (const_int 0))
1621 (label_ref (match_operand 0 "" ""))
1625 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1628 (define_expand "blt"
1630 (if_then_else (lt (match_dup 1) (const_int 0))
1631 (label_ref (match_operand 0 "" ""))
1636 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1637 && GET_CODE (sparc_compare_op0) == REG
1638 && GET_MODE (sparc_compare_op0) == DImode)
1640 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1643 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1645 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1646 emit_jump_insn (gen_bne (operands[0]));
1649 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1652 (define_expand "bltu"
1654 (if_then_else (ltu (match_dup 1) (const_int 0))
1655 (label_ref (match_operand 0 "" ""))
1659 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1662 (define_expand "bge"
1664 (if_then_else (ge (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 (GE, sparc_compare_op0, operands[0]);
1677 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1679 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1680 emit_jump_insn (gen_bne (operands[0]));
1683 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1686 (define_expand "bgeu"
1688 (if_then_else (geu (match_dup 1) (const_int 0))
1689 (label_ref (match_operand 0 "" ""))
1693 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1696 (define_expand "ble"
1698 (if_then_else (le (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 (LE, sparc_compare_op0, operands[0]);
1711 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1713 emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1714 emit_jump_insn (gen_bne (operands[0]));
1717 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1720 (define_expand "bleu"
1722 (if_then_else (leu (match_dup 1) (const_int 0))
1723 (label_ref (match_operand 0 "" ""))
1727 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1730 ;; Now match both normal and inverted jump.
1732 ;; XXX fpcmp nop braindamage
1733 (define_insn "*normal_branch"
1735 (if_then_else (match_operator 0 "noov_compare_op"
1736 [(reg 100) (const_int 0)])
1737 (label_ref (match_operand 1 "" ""))
1742 return output_cbranch (operands[0], 1, 0,
1743 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1744 ! final_sequence, insn);
1746 [(set_attr "type" "branch")])
1748 ;; XXX fpcmp nop braindamage
1749 (define_insn "*inverted_branch"
1751 (if_then_else (match_operator 0 "noov_compare_op"
1752 [(reg 100) (const_int 0)])
1754 (label_ref (match_operand 1 "" ""))))]
1758 return output_cbranch (operands[0], 1, 1,
1759 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1760 ! final_sequence, insn);
1762 [(set_attr "type" "branch")])
1764 ;; XXX fpcmp nop braindamage
1765 (define_insn "*normal_fp_branch"
1767 (if_then_else (match_operator 1 "comparison_operator"
1768 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1770 (label_ref (match_operand 2 "" ""))
1775 return output_cbranch (operands[1], 2, 0,
1776 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1777 ! final_sequence, insn);
1779 [(set_attr "type" "branch")])
1781 ;; XXX fpcmp nop braindamage
1782 (define_insn "*inverted_fp_branch"
1784 (if_then_else (match_operator 1 "comparison_operator"
1785 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1788 (label_ref (match_operand 2 "" ""))))]
1792 return output_cbranch (operands[1], 2, 1,
1793 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1794 ! final_sequence, insn);
1796 [(set_attr "type" "branch")])
1798 ;; XXX fpcmp nop braindamage
1799 (define_insn "*normal_fpe_branch"
1801 (if_then_else (match_operator 1 "comparison_operator"
1802 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1804 (label_ref (match_operand 2 "" ""))
1809 return output_cbranch (operands[1], 2, 0,
1810 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1811 ! final_sequence, insn);
1813 [(set_attr "type" "branch")])
1815 ;; XXX fpcmp nop braindamage
1816 (define_insn "*inverted_fpe_branch"
1818 (if_then_else (match_operator 1 "comparison_operator"
1819 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1822 (label_ref (match_operand 2 "" ""))))]
1826 return output_cbranch (operands[1], 2, 1,
1827 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1828 ! final_sequence, insn);
1830 [(set_attr "type" "branch")])
1832 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
1833 ;; in the architecture.
1835 ;; There are no 32 bit brreg insns.
1838 (define_insn "*normal_int_branch_sp64"
1840 (if_then_else (match_operator 0 "v9_regcmp_op"
1841 [(match_operand:DI 1 "register_operand" "r")
1843 (label_ref (match_operand 2 "" ""))
1848 return output_v9branch (operands[0], 1, 2, 0,
1849 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1850 ! final_sequence, insn);
1852 [(set_attr "type" "branch")])
1855 (define_insn "*inverted_int_branch_sp64"
1857 (if_then_else (match_operator 0 "v9_regcmp_op"
1858 [(match_operand:DI 1 "register_operand" "r")
1861 (label_ref (match_operand 2 "" ""))))]
1865 return output_v9branch (operands[0], 1, 2, 1,
1866 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1867 ! final_sequence, insn);
1869 [(set_attr "type" "branch")])
1871 ;; Load program counter insns.
1873 (define_insn "get_pc"
1874 [(clobber (reg:SI 15))
1875 (set (match_operand 0 "register_operand" "=r")
1876 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
1877 "flag_pic && REGNO (operands[0]) == 23"
1878 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
1879 [(set_attr "length" "3")])
1881 ;; Currently unused...
1882 ;; (define_insn "get_pc_via_rdpc"
1883 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
1886 ;; [(set_attr "type" "move")])
1889 ;; Move instructions
1891 (define_expand "movqi"
1892 [(set (match_operand:QI 0 "general_operand" "")
1893 (match_operand:QI 1 "general_operand" ""))]
1897 /* Working with CONST_INTs is easier, so convert
1898 a double if needed. */
1899 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1901 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
1903 else if (GET_CODE (operands[1]) == CONST_INT)
1905 /* And further, we know for all QI cases that only the
1906 low byte is significant, which we can always process
1907 in a single insn. So mask it now. */
1908 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
1911 /* Handle sets of MEM first. */
1912 if (GET_CODE (operands[0]) == MEM)
1914 /* This checks TARGET_LIVE_G0 for us. */
1915 if (reg_or_0_operand (operands[1], QImode))
1918 if (! reload_in_progress)
1920 operands[0] = validize_mem (operands[0]);
1921 operands[1] = force_reg (QImode, operands[1]);
1925 /* Fixup PIC cases. */
1928 if (CONSTANT_P (operands[1])
1929 && pic_address_needs_scratch (operands[1]))
1930 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1932 if (symbolic_operand (operands[1], QImode))
1934 operands[1] = legitimize_pic_address (operands[1],
1936 (reload_in_progress ?
1943 /* All QI constants require only one insn, so proceed. */
1949 (define_insn "*movqi_insn"
1950 [(set (match_operand:QI 0 "general_operand" "=r,r,m")
1951 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
1952 "(register_operand (operands[0], QImode)
1953 || reg_or_0_operand (operands[1], QImode))"
1958 [(set_attr "type" "move,load,store")
1959 (set_attr "length" "1")])
1961 (define_expand "movhi"
1962 [(set (match_operand:HI 0 "general_operand" "")
1963 (match_operand:HI 1 "general_operand" ""))]
1967 /* Working with CONST_INTs is easier, so convert
1968 a double if needed. */
1969 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1970 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1972 /* Handle sets of MEM first. */
1973 if (GET_CODE (operands[0]) == MEM)
1975 /* This checks TARGET_LIVE_G0 for us. */
1976 if (reg_or_0_operand (operands[1], HImode))
1979 if (! reload_in_progress)
1981 operands[0] = validize_mem (operands[0]);
1982 operands[1] = force_reg (HImode, operands[1]);
1986 /* Fixup PIC cases. */
1989 if (CONSTANT_P (operands[1])
1990 && pic_address_needs_scratch (operands[1]))
1991 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1993 if (symbolic_operand (operands[1], HImode))
1995 operands[1] = legitimize_pic_address (operands[1],
1997 (reload_in_progress ?
2004 /* This makes sure we will not get rematched due to splittage. */
2005 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2007 else if (CONSTANT_P (operands[1])
2008 && GET_CODE (operands[1]) != HIGH
2009 && GET_CODE (operands[1]) != LO_SUM)
2011 sparc_emit_set_const32 (operands[0], operands[1]);
2018 (define_insn "*movhi_const64_special"
2019 [(set (match_operand:HI 0 "register_operand" "=r")
2020 (match_operand:HI 1 "const64_high_operand" ""))]
2022 "sethi\\t%%hi(%a1), %0"
2023 [(set_attr "type" "move")
2024 (set_attr "length" "1")])
2026 (define_insn "*movhi_insn"
2027 [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
2028 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2029 "(register_operand (operands[0], HImode)
2030 || reg_or_0_operand (operands[1], HImode))"
2033 sethi\\t%%hi(%a1), %0
2036 [(set_attr "type" "move,move,load,store")
2037 (set_attr "length" "1")])
2039 ;; We always work with constants here.
2040 (define_insn "*movhi_lo_sum"
2041 [(set (match_operand:HI 0 "register_operand" "=r")
2042 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2043 (match_operand:HI 2 "arith_operand" "I")))]
2046 [(set_attr "type" "ialu")
2047 (set_attr "length" "1")])
2049 (define_expand "movsi"
2050 [(set (match_operand:SI 0 "general_operand" "")
2051 (match_operand:SI 1 "general_operand" ""))]
2055 /* Working with CONST_INTs is easier, so convert
2056 a double if needed. */
2057 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2058 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2060 /* Handle sets of MEM first. */
2061 if (GET_CODE (operands[0]) == MEM)
2063 /* This checks TARGET_LIVE_G0 for us. */
2064 if (reg_or_0_operand (operands[1], SImode))
2067 if (! reload_in_progress)
2069 operands[0] = validize_mem (operands[0]);
2070 operands[1] = force_reg (SImode, operands[1]);
2074 /* Fixup PIC cases. */
2077 if (CONSTANT_P (operands[1])
2078 && pic_address_needs_scratch (operands[1]))
2079 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2081 if (GET_CODE (operands[1]) == LABEL_REF)
2084 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2088 if (symbolic_operand (operands[1], SImode))
2090 operands[1] = legitimize_pic_address (operands[1],
2092 (reload_in_progress ?
2099 /* If we are trying to toss an integer constant into the
2100 FPU registers, force it into memory. */
2101 if (GET_CODE (operands[0]) == REG
2102 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2103 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2104 && CONSTANT_P (operands[1]))
2105 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2108 /* This makes sure we will not get rematched due to splittage. */
2109 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2111 else if (CONSTANT_P (operands[1])
2112 && GET_CODE (operands[1]) != HIGH
2113 && GET_CODE (operands[1]) != LO_SUM)
2115 sparc_emit_set_const32 (operands[0], operands[1]);
2122 ;; Special LIVE_G0 pattern to obtain zero in a register.
2123 (define_insn "*movsi_zero_liveg0"
2124 [(set (match_operand:SI 0 "register_operand" "=r")
2125 (match_operand:SI 1 "zero_operand" "J"))]
2128 [(set_attr "type" "binary")
2129 (set_attr "length" "1")])
2131 ;; This is needed to show CSE exactly which bits are set
2132 ;; in a 64-bit register by sethi instructions.
2133 (define_insn "*movsi_const64_special"
2134 [(set (match_operand:SI 0 "register_operand" "=r")
2135 (match_operand:SI 1 "const64_high_operand" ""))]
2137 "sethi\\t%%hi(%a1), %0"
2138 [(set_attr "type" "move")
2139 (set_attr "length" "1")])
2141 (define_insn "*movsi_insn"
2142 [(set (match_operand:SI 0 "general_operand" "=r,f,r,r,r,f,m,m,d")
2143 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2144 "(register_operand (operands[0], SImode)
2145 || reg_or_0_operand (operands[1], SImode))"
2149 sethi\\t%%hi(%a1), %0
2156 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2157 (set_attr "length" "1")])
2159 (define_insn "*movsi_lo_sum"
2160 [(set (match_operand:SI 0 "register_operand" "=r")
2161 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2162 (match_operand:SI 2 "immediate_operand" "in")))]
2164 "or\\t%1, %%lo(%a2), %0"
2165 [(set_attr "type" "ialu")
2166 (set_attr "length" "1")])
2168 (define_insn "*movsi_high"
2169 [(set (match_operand:SI 0 "register_operand" "=r")
2170 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2172 "sethi\\t%%hi(%a1), %0"
2173 [(set_attr "type" "move")
2174 (set_attr "length" "1")])
2176 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2177 ;; so that CSE won't optimize the address computation away.
2178 (define_insn "movsi_lo_sum_pic"
2179 [(set (match_operand:SI 0 "register_operand" "=r")
2180 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2181 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2183 "or\\t%1, %%lo(%a2), %0"
2184 [(set_attr "type" "ialu")
2185 (set_attr "length" "1")])
2187 (define_insn "movsi_high_pic"
2188 [(set (match_operand:SI 0 "register_operand" "=r")
2189 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2190 "flag_pic && check_pic (1)"
2191 "sethi\\t%%hi(%a1), %0"
2192 [(set_attr "type" "move")
2193 (set_attr "length" "1")])
2195 (define_expand "movsi_pic_label_ref"
2196 [(set (match_dup 3) (high:SI
2197 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2199 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2200 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2201 (set (match_operand:SI 0 "register_operand" "=r")
2202 (minus:SI (match_dup 5) (match_dup 4)))]
2206 current_function_uses_pic_offset_table = 1;
2207 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2208 operands[3] = gen_reg_rtx (SImode);
2209 operands[4] = gen_reg_rtx (SImode);
2210 operands[5] = pic_offset_table_rtx;
2213 (define_insn "*movsi_high_pic_label_ref"
2214 [(set (match_operand:SI 0 "register_operand" "=r")
2216 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2217 (match_operand:SI 2 "" "")] 5)))]
2219 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2220 [(set_attr "type" "move")
2221 (set_attr "length" "1")])
2223 (define_insn "*movsi_lo_sum_pic_label_ref"
2224 [(set (match_operand:SI 0 "register_operand" "=r")
2225 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2226 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2227 (match_operand:SI 3 "" "")] 5)))]
2229 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2230 [(set_attr "type" "ialu")
2231 (set_attr "length" "1")])
2233 (define_expand "movdi"
2234 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2235 (match_operand:DI 1 "general_operand" ""))]
2239 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2240 if (GET_CODE (operands[1]) == CONST_DOUBLE
2241 #if HOST_BITS_PER_WIDE_INT != 64
2242 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2243 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2244 || (CONST_DOUBLE_HIGH (operands[1]) == 0xffffffff
2245 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2248 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2250 /* Handle MEM cases first. */
2251 if (GET_CODE (operands[0]) == MEM)
2253 /* If it's a REG, we can always do it.
2254 The const zero case is more complex, on v9
2255 we can always perform it. */
2256 if (register_operand (operands[1], DImode)
2258 && (operands[1] == const0_rtx)))
2261 if (! reload_in_progress)
2263 operands[0] = validize_mem (operands[0]);
2264 operands[1] = force_reg (DImode, operands[1]);
2270 if (CONSTANT_P (operands[1])
2271 && pic_address_needs_scratch (operands[1]))
2272 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2274 if (GET_CODE (operands[1]) == LABEL_REF)
2276 if (! TARGET_ARCH64)
2278 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2282 if (symbolic_operand (operands[1], DImode))
2284 operands[1] = legitimize_pic_address (operands[1],
2286 (reload_in_progress ?
2293 /* If we are trying to toss an integer constant into the
2294 FPU registers, force it into memory. */
2295 if (GET_CODE (operands[0]) == REG
2296 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2297 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2298 && CONSTANT_P (operands[1]))
2299 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2302 /* This makes sure we will not get rematched due to splittage. */
2303 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2305 else if (TARGET_ARCH64
2306 && CONSTANT_P (operands[1])
2307 && GET_CODE (operands[1]) != HIGH
2308 && GET_CODE (operands[1]) != LO_SUM)
2310 sparc_emit_set_const64 (operands[0], operands[1]);
2318 ;; Be careful, fmovd does not exist when !arch64.
2319 ;; We match MEM moves directly when we have correct even
2320 ;; numbered registers, but fall into splits otherwise.
2321 ;; The constraint ordering here is really important to
2322 ;; avoid insane problems in reload, especially for patterns
2325 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2326 ;; (const_int -5016)))
2329 (define_insn "*movdi_insn_sp32"
2330 [(set (match_operand:DI 0 "general_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2331 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2333 (register_operand (operands[0], DImode)
2334 || register_operand (operands[1], DImode))"
2347 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2348 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2350 ;; The following are generated by sparc_emit_set_const64
2351 (define_insn "*movdi_sp64_dbl"
2352 [(set (match_operand:DI 0 "register_operand" "=r")
2353 (match_operand:DI 1 "const64_operand" ""))]
2355 && HOST_BITS_PER_WIDE_INT != 64)"
2357 [(set_attr "type" "move")
2358 (set_attr "length" "1")])
2360 ;; This is needed to show CSE exactly which bits are set
2361 ;; in a 64-bit register by sethi instructions.
2362 (define_insn "*movdi_const64_special"
2363 [(set (match_operand:DI 0 "register_operand" "=r")
2364 (match_operand:DI 1 "const64_high_operand" ""))]
2366 "sethi\\t%%hi(%a1), %0"
2367 [(set_attr "type" "move")
2368 (set_attr "length" "1")])
2370 (define_insn "*movdi_insn_sp64"
2371 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,m,?e,?e,?m,b")
2372 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2374 (register_operand (operands[0], DImode)
2375 || reg_or_0_operand (operands[1], DImode))"
2378 sethi\\t%%hi(%a1), %0
2386 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove")
2387 (set_attr "length" "1")])
2389 (define_expand "movdi_pic_label_ref"
2390 [(set (match_dup 3) (high:DI
2391 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2393 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2394 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2395 (set (match_operand:DI 0 "register_operand" "=r")
2396 (minus:DI (match_dup 5) (match_dup 4)))]
2397 "TARGET_ARCH64 && flag_pic"
2400 current_function_uses_pic_offset_table = 1;
2401 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2402 operands[3] = gen_reg_rtx (DImode);
2403 operands[4] = gen_reg_rtx (DImode);
2404 operands[5] = pic_offset_table_rtx;
2407 (define_insn "*movdi_high_pic_label_ref"
2408 [(set (match_operand:DI 0 "register_operand" "=r")
2410 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2411 (match_operand:DI 2 "" "")] 5)))]
2412 "TARGET_ARCH64 && flag_pic"
2413 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2414 [(set_attr "type" "move")
2415 (set_attr "length" "1")])
2417 (define_insn "*movdi_lo_sum_pic_label_ref"
2418 [(set (match_operand:DI 0 "register_operand" "=r")
2419 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2420 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2421 (match_operand:DI 3 "" "")] 5)))]
2422 "TARGET_ARCH64 && flag_pic"
2423 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2424 [(set_attr "type" "ialu")
2425 (set_attr "length" "1")])
2427 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2428 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2430 (define_insn "movdi_lo_sum_pic"
2431 [(set (match_operand:DI 0 "register_operand" "=r")
2432 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2433 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2434 "TARGET_ARCH64 && flag_pic"
2435 "or\\t%1, %%lo(%a2), %0"
2436 [(set_attr "type" "ialu")
2437 (set_attr "length" "1")])
2439 (define_insn "movdi_high_pic"
2440 [(set (match_operand:DI 0 "register_operand" "=r")
2441 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2442 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2443 "sethi\\t%%hi(%a1), %0"
2444 [(set_attr "type" "move")
2445 (set_attr "length" "1")])
2447 (define_insn "*sethi_di_medlow_embmedany_pic"
2448 [(set (match_operand:DI 0 "register_operand" "=r")
2449 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2450 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2451 "sethi\\t%%lo(%a1), %0"
2452 [(set_attr "type" "move")
2453 (set_attr "length" "1")])
2455 (define_insn "*sethi_di_medlow"
2456 [(set (match_operand:DI 0 "register_operand" "=r")
2457 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2458 "TARGET_CM_MEDLOW && check_pic (1)"
2459 "sethi\\t%%hi(%a1), %0"
2460 [(set_attr "type" "move")
2461 (set_attr "length" "1")])
2463 (define_insn "*losum_di_medlow"
2464 [(set (match_operand:DI 0 "register_operand" "=r")
2465 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2466 (match_operand:DI 2 "symbolic_operand" "")))]
2468 "or\\t%1, %%lo(%a2), %0"
2469 [(set_attr "type" "ialu")
2470 (set_attr "length" "1")])
2472 (define_insn "seth44"
2473 [(set (match_operand:DI 0 "register_operand" "=r")
2474 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2476 "sethi\\t%%h44(%a1), %0"
2477 [(set_attr "type" "move")
2478 (set_attr "length" "1")])
2480 (define_insn "setm44"
2481 [(set (match_operand:DI 0 "register_operand" "=r")
2482 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2483 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2485 "or\\t%1, %%m44(%a2), %0"
2486 [(set_attr "type" "move")
2487 (set_attr "length" "1")])
2489 (define_insn "setl44"
2490 [(set (match_operand:DI 0 "register_operand" "=r")
2491 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2492 (match_operand:DI 2 "symbolic_operand" "")))]
2494 "or\\t%1, %%l44(%a2), %0"
2495 [(set_attr "type" "ialu")
2496 (set_attr "length" "1")])
2498 (define_insn "sethh"
2499 [(set (match_operand:DI 0 "register_operand" "=r")
2500 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2502 "sethi\\t%%hh(%a1), %0"
2503 [(set_attr "type" "move")
2504 (set_attr "length" "1")])
2506 (define_insn "setlm"
2507 [(set (match_operand:DI 0 "register_operand" "=r")
2508 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2510 "sethi\\t%%lm(%a1), %0"
2511 [(set_attr "type" "move")
2512 (set_attr "length" "1")])
2514 (define_insn "sethm"
2515 [(set (match_operand:DI 0 "register_operand" "=r")
2516 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2517 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2519 "or\\t%1, %%hm(%a2), %0"
2520 [(set_attr "type" "ialu")
2521 (set_attr "length" "1")])
2523 (define_insn "setlo"
2524 [(set (match_operand:DI 0 "register_operand" "=r")
2525 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2526 (match_operand:DI 2 "symbolic_operand" "")))]
2528 "or\\t%1, %%lo(%a2), %0"
2529 [(set_attr "type" "ialu")
2530 (set_attr "length" "1")])
2532 (define_insn "embmedany_sethi"
2533 [(set (match_operand:DI 0 "register_operand" "=r")
2534 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2535 "TARGET_CM_EMBMEDANY && check_pic (1)"
2536 "sethi\\t%%hi(%a1), %0"
2537 [(set_attr "type" "move")
2538 (set_attr "length" "1")])
2540 (define_insn "embmedany_losum"
2541 [(set (match_operand:DI 0 "register_operand" "=r")
2542 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2543 (match_operand:DI 2 "data_segment_operand" "")))]
2544 "TARGET_CM_EMBMEDANY"
2545 "add\\t%1, %%lo(%a2), %0"
2546 [(set_attr "type" "ialu")
2547 (set_attr "length" "1")])
2549 (define_insn "embmedany_brsum"
2550 [(set (match_operand:DI 0 "register_operand" "=r")
2551 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2552 "TARGET_CM_EMBMEDANY"
2554 [(set_attr "length" "1")])
2556 (define_insn "embmedany_textuhi"
2557 [(set (match_operand:DI 0 "register_operand" "=r")
2558 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2559 "TARGET_CM_EMBMEDANY && check_pic (1)"
2560 "sethi\\t%%uhi(%a1), %0"
2561 [(set_attr "type" "move")
2562 (set_attr "length" "1")])
2564 (define_insn "embmedany_texthi"
2565 [(set (match_operand:DI 0 "register_operand" "=r")
2566 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2567 "TARGET_CM_EMBMEDANY && check_pic (1)"
2568 "sethi\\t%%hi(%a1), %0"
2569 [(set_attr "type" "move")
2570 (set_attr "length" "1")])
2572 (define_insn "embmedany_textulo"
2573 [(set (match_operand:DI 0 "register_operand" "=r")
2574 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2575 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2576 "TARGET_CM_EMBMEDANY"
2577 "or\\t%1, %%ulo(%a2), %0"
2578 [(set_attr "type" "ialu")
2579 (set_attr "length" "1")])
2581 (define_insn "embmedany_textlo"
2582 [(set (match_operand:DI 0 "register_operand" "=r")
2583 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2584 (match_operand:DI 2 "text_segment_operand" "")))]
2585 "TARGET_CM_EMBMEDANY"
2586 "or\\t%1, %%lo(%a2), %0"
2587 [(set_attr "type" "ialu")
2588 (set_attr "length" "1")])
2590 ;; Now some patterns to help reload out a bit.
2591 (define_expand "reload_indi"
2592 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2593 (match_operand:DI 1 "immediate_operand" "")
2594 (match_operand:TI 2 "register_operand" "=&r")])]
2596 || TARGET_CM_EMBMEDANY)
2600 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2601 gen_rtx_REG (DImode, REGNO (operands[2])));
2605 (define_expand "reload_outdi"
2606 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2607 (match_operand:DI 1 "immediate_operand" "")
2608 (match_operand:TI 2 "register_operand" "=&r")])]
2610 || TARGET_CM_EMBMEDANY)
2614 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2615 gen_rtx_REG (DImode, REGNO (operands[2])));
2619 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2621 [(set (match_operand:DI 0 "register_operand" "")
2622 (match_operand:DI 1 "const_int_operand" ""))]
2623 "! TARGET_ARCH64 && reload_completed"
2624 [(clobber (const_int 0))]
2627 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2628 (INTVAL (operands[1]) < 0) ?
2631 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2637 [(set (match_operand:DI 0 "register_operand" "")
2638 (match_operand:DI 1 "const_double_operand" ""))]
2639 "! TARGET_ARCH64 && reload_completed"
2640 [(clobber (const_int 0))]
2643 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2644 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2646 /* Slick... but this trick loses if this subreg constant part
2647 can be done in one insn. */
2648 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2649 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2650 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2652 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2653 gen_highpart (SImode, operands[0])));
2657 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2658 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2664 [(set (match_operand:DI 0 "register_operand" "")
2665 (match_operand:DI 1 "register_operand" ""))]
2666 "! TARGET_ARCH64 && reload_completed"
2667 [(clobber (const_int 0))]
2670 rtx set_dest = operands[0];
2671 rtx set_src = operands[1];
2675 if (GET_CODE (set_dest) == SUBREG)
2676 set_dest = alter_subreg (set_dest);
2677 if (GET_CODE (set_src) == SUBREG)
2678 set_src = alter_subreg (set_src);
2680 dest1 = gen_highpart (SImode, set_dest);
2681 dest2 = gen_lowpart (SImode, set_dest);
2682 src1 = gen_highpart (SImode, set_src);
2683 src2 = gen_lowpart (SImode, set_src);
2685 /* Now emit using the real source and destination we found, swapping
2686 the order if we detect overlap. */
2687 if (reg_overlap_mentioned_p (dest1, src2))
2689 emit_insn (gen_movsi (dest2, src2));
2690 emit_insn (gen_movsi (dest1, src1));
2694 emit_insn (gen_movsi (dest1, src1));
2695 emit_insn (gen_movsi (dest2, src2));
2700 ;; Now handle the cases of memory moves from/to non-even
2701 ;; DI mode register pairs.
2703 [(set (match_operand:DI 0 "register_operand" "")
2704 (match_operand:DI 1 "memory_operand" ""))]
2707 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2708 [(clobber (const_int 0))]
2711 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2712 rtx word1 = change_address (operands[1], SImode,
2713 plus_constant_for_output (XEXP (word0, 0), 4));
2714 rtx high_part = gen_highpart (SImode, operands[0]);
2715 rtx low_part = gen_lowpart (SImode, operands[0]);
2717 if (reg_overlap_mentioned_p (high_part, word1))
2719 emit_insn (gen_movsi (low_part, word1));
2720 emit_insn (gen_movsi (high_part, word0));
2724 emit_insn (gen_movsi (high_part, word0));
2725 emit_insn (gen_movsi (low_part, word1));
2731 [(set (match_operand:DI 0 "memory_operand" "")
2732 (match_operand:DI 1 "register_operand" ""))]
2735 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2736 [(clobber (const_int 0))]
2739 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2740 rtx word1 = change_address (operands[0], SImode,
2741 plus_constant_for_output (XEXP (word0, 0), 4));
2742 rtx high_part = gen_highpart (SImode, operands[1]);
2743 rtx low_part = gen_lowpart (SImode, operands[1]);
2745 emit_insn (gen_movsi (word0, high_part));
2746 emit_insn (gen_movsi (word1, low_part));
2751 ;; Floating point move insns
2753 (define_insn "*clear_sf"
2754 [(set (match_operand:SF 0 "general_operand" "=f")
2755 (match_operand:SF 1 "" ""))]
2757 && GET_CODE (operands[1]) == CONST_DOUBLE
2758 && GET_CODE (operands[0]) == REG
2759 && fp_zero_operand (operands[1])"
2761 [(set_attr "type" "fpmove")
2762 (set_attr "length" "1")])
2764 (define_insn "*movsf_const_intreg"
2765 [(set (match_operand:SF 0 "general_operand" "=f,r")
2766 (match_operand:SF 1 "" "m,F"))]
2768 && GET_CODE (operands[1]) == CONST_DOUBLE
2769 && GET_CODE (operands[0]) == REG"
2775 if (which_alternative == 0)
2776 return \"ld\\t%1, %0\";
2778 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2779 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2780 if (SPARC_SIMM13_P (i) || SPARC_SETHI_P (i))
2782 operands[1] = GEN_INT (i);
2783 if (SPARC_SIMM13_P (INTVAL (operands[1])))
2784 return \"mov\\t%1, %0\";
2785 else if (SPARC_SETHI_P (INTVAL (operands[1])))
2786 return \"sethi\\t%%hi(%a1), %0\";
2793 [(set_attr "type" "move")
2794 (set_attr "length" "1")])
2796 ;; There isn't much I can do about this, if I change the
2797 ;; mode then flow info gets really confused because the
2798 ;; destination no longer looks the same. Ho hum...
2799 (define_insn "*movsf_const_high"
2800 [(set (match_operand:SF 0 "register_operand" "=r")
2801 (unspec:SF [(match_operand 1 "const_int_operand" "")] 12))]
2803 "sethi\\t%%hi(%a1), %0"
2804 [(set_attr "type" "move")
2805 (set_attr "length" "1")])
2807 (define_insn "*movsf_const_lo"
2808 [(set (match_operand:SF 0 "register_operand" "=r")
2809 (unspec:SF [(match_operand 1 "register_operand" "r")
2810 (match_operand 2 "const_int_operand" "")] 17))]
2812 "or\\t%1, %%lo(%a2), %0"
2813 [(set_attr "type" "move")
2814 (set_attr "length" "1")])
2817 [(set (match_operand:SF 0 "register_operand" "")
2818 (match_operand:SF 1 "const_double_operand" ""))]
2820 && (GET_CODE (operands[0]) == REG
2821 && REGNO (operands[0]) < 32)"
2822 [(set (match_dup 0) (unspec:SF [(match_dup 1)] 12))
2823 (set (match_dup 0) (unspec:SF [(match_dup 0) (match_dup 1)] 17))]
2829 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2830 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2831 operands[1] = GEN_INT (i);
2834 (define_expand "movsf"
2835 [(set (match_operand:SF 0 "general_operand" "")
2836 (match_operand:SF 1 "general_operand" ""))]
2840 /* Force SFmode constants into memory. */
2841 if (GET_CODE (operands[0]) == REG
2842 && CONSTANT_P (operands[1]))
2845 && GET_CODE (operands[1]) == CONST_DOUBLE
2846 && fp_zero_operand (operands[1]))
2849 /* emit_group_store will send such bogosity to us when it is
2850 not storing directly into memory. So fix this up to avoid
2851 crashes in output_constant_pool. */
2852 if (operands [1] == const0_rtx)
2853 operands[1] = CONST0_RTX (SFmode);
2854 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2858 /* Handle sets of MEM first. */
2859 if (GET_CODE (operands[0]) == MEM)
2861 if (register_operand (operands[1], SFmode))
2864 if (! reload_in_progress)
2866 operands[0] = validize_mem (operands[0]);
2867 operands[1] = force_reg (SFmode, operands[1]);
2871 /* Fixup PIC cases. */
2874 if (CONSTANT_P (operands[1])
2875 && pic_address_needs_scratch (operands[1]))
2876 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2878 if (symbolic_operand (operands[1], SFmode))
2880 operands[1] = legitimize_pic_address (operands[1],
2882 (reload_in_progress ?
2892 (define_insn "*movsf_insn"
2893 [(set (match_operand:SF 0 "general_operand" "=f,f,m,r,r,m")
2894 (match_operand:SF 1 "input_operand" "f,m,f,r,m,r"))]
2896 && (register_operand (operands[0], SFmode)
2897 || register_operand (operands[1], SFmode))"
2905 [(set_attr "type" "fpmove,fpload,fpstore,move,load,store")
2906 (set_attr "length" "1")])
2908 ;; Exactly the same as above, except that all `f' cases are deleted.
2909 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2912 (define_insn "*movsf_no_f_insn"
2913 [(set (match_operand:SF 0 "general_operand" "=r,r,m")
2914 (match_operand:SF 1 "input_operand" "r,m,r"))]
2916 && (register_operand (operands[0], SFmode)
2917 || register_operand (operands[1], SFmode))"
2922 [(set_attr "type" "move,load,store")
2923 (set_attr "length" "1")])
2925 (define_insn "*clear_df"
2926 [(set (match_operand:DF 0 "general_operand" "=e")
2927 (match_operand:DF 1 "" ""))]
2929 && GET_CODE (operands[1]) == CONST_DOUBLE
2930 && GET_CODE (operands[0]) == REG
2931 && fp_zero_operand (operands[1])"
2933 [(set_attr "type" "fpmove")
2934 (set_attr "length" "1")])
2936 (define_insn "*movdf_const_intreg_sp32"
2937 [(set (match_operand:DF 0 "general_operand" "=e,e,r")
2938 (match_operand:DF 1 "" "T,o,F"))]
2939 "TARGET_FPU && ! TARGET_ARCH64
2940 && GET_CODE (operands[1]) == CONST_DOUBLE
2941 && GET_CODE (operands[0]) == REG"
2944 if (which_alternative == 0)
2945 return \"ldd\\t%1, %0\";
2949 [(set_attr "type" "move")
2950 (set_attr "length" "1")])
2952 (define_insn "*movdf_const_intreg_sp64"
2953 [(set (match_operand:DF 0 "general_operand" "=e,e,r")
2954 (match_operand:DF 1 "" "m,o,F"))]
2955 "TARGET_FPU && TARGET_ARCH64
2956 && GET_CODE (operands[1]) == CONST_DOUBLE
2957 && GET_CODE (operands[0]) == REG"
2960 if (which_alternative == 0)
2961 return \"ldd\\t%1, %0\";
2965 [(set_attr "type" "move")
2966 (set_attr "length" "1")])
2969 [(set (match_operand:DF 0 "register_operand" "")
2970 (match_operand:DF 1 "const_double_operand" ""))]
2972 && GET_CODE (operands[1]) == CONST_DOUBLE
2973 && (GET_CODE (operands[0]) == REG
2974 && REGNO (operands[0]) < 32)
2975 && reload_completed"
2976 [(clobber (const_int 0))]
2982 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2983 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2984 if (GET_CODE (operands[0]) == SUBREG)
2985 operands[0] = alter_subreg (operands[0]);
2986 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2988 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2991 /* Slick... but this trick loses if this subreg constant part
2992 can be done in one insn. */
2994 && !(SPARC_SETHI_P (l[0])
2995 || SPARC_SIMM13_P (l[0])))
2997 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2998 gen_highpart (SImode, operands[0])));
3002 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3008 (define_expand "movdf"
3009 [(set (match_operand:DF 0 "general_operand" "")
3010 (match_operand:DF 1 "general_operand" ""))]
3014 /* Force DFmode constants into memory. */
3015 if (GET_CODE (operands[0]) == REG
3016 && CONSTANT_P (operands[1]))
3019 && GET_CODE (operands[1]) == CONST_DOUBLE
3020 && fp_zero_operand (operands[1]))
3023 /* emit_group_store will send such bogosity to us when it is
3024 not storing directly into memory. So fix this up to avoid
3025 crashes in output_constant_pool. */
3026 if (operands [1] == const0_rtx)
3027 operands[1] = CONST0_RTX (DFmode);
3028 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3032 /* Handle MEM cases first. */
3033 if (GET_CODE (operands[0]) == MEM)
3035 if (register_operand (operands[1], DFmode))
3038 if (! reload_in_progress)
3040 operands[0] = validize_mem (operands[0]);
3041 operands[1] = force_reg (DFmode, operands[1]);
3045 /* Fixup PIC cases. */
3048 if (CONSTANT_P (operands[1])
3049 && pic_address_needs_scratch (operands[1]))
3050 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3052 if (symbolic_operand (operands[1], DFmode))
3054 operands[1] = legitimize_pic_address (operands[1],
3056 (reload_in_progress ?
3066 ;; Be careful, fmovd does not exist when !v9.
3067 (define_insn "*movdf_insn_sp32"
3068 [(set (match_operand:DF 0 "general_operand" "=e,T,U,T,e,r,r,o,e,o")
3069 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3072 && (register_operand (operands[0], DFmode)
3073 || register_operand (operands[1], DFmode))"
3085 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3086 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3088 (define_insn "*movdf_no_e_insn_sp32"
3089 [(set (match_operand:DF 0 "general_operand" "=U,T,r,r,o")
3090 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3093 && (register_operand (operands[0], DFmode)
3094 || register_operand (operands[1], DFmode))"
3101 [(set_attr "type" "load,store,*,*,*")
3102 (set_attr "length" "1,1,2,2,2")])
3104 ;; We have available v9 double floats but not 64-bit
3105 ;; integer registers.
3106 (define_insn "*movdf_insn_v9only"
3107 [(set (match_operand:DF 0 "general_operand" "=e,e,m,U,T,r,r,o")
3108 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3112 && (register_operand (operands[0], DFmode)
3113 || register_operand (operands[1], DFmode))"
3123 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3124 (set_attr "length" "1,1,1,1,1,2,2,2")])
3126 ;; We have available both v9 double floats and 64-bit
3127 ;; integer registers.
3128 (define_insn "*movdf_insn_sp64"
3129 [(set (match_operand:DF 0 "general_operand" "=e,e,m,r,r,m")
3130 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3134 && (register_operand (operands[0], DFmode)
3135 || register_operand (operands[1], DFmode))"
3143 [(set_attr "type" "fpmove,load,store,move,load,store")
3144 (set_attr "length" "1")])
3146 (define_insn "*movdf_no_e_insn_sp64"
3147 [(set (match_operand:DF 0 "general_operand" "=r,r,m")
3148 (match_operand:DF 1 "input_operand" "r,m,r"))]
3151 && (register_operand (operands[0], DFmode)
3152 || register_operand (operands[1], DFmode))"
3157 [(set_attr "type" "move,load,store")
3158 (set_attr "length" "1")])
3160 ;; Ok, now the splits to handle all the multi insn and
3161 ;; mis-aligned memory address cases.
3162 ;; In these splits please take note that we must be
3163 ;; careful when V9 but not ARCH64 because the integer
3164 ;; register DFmode cases must be handled.
3166 [(set (match_operand:DF 0 "register_operand" "")
3167 (match_operand:DF 1 "register_operand" ""))]
3170 && ((GET_CODE (operands[0]) == REG
3171 && REGNO (operands[0]) < 32)
3172 || (GET_CODE (operands[0]) == SUBREG
3173 && GET_CODE (SUBREG_REG (operands[0])) == REG
3174 && REGNO (SUBREG_REG (operands[0])) < 32))))
3175 && reload_completed"
3176 [(clobber (const_int 0))]
3179 rtx set_dest = operands[0];
3180 rtx set_src = operands[1];
3184 if (GET_CODE (set_dest) == SUBREG)
3185 set_dest = alter_subreg (set_dest);
3186 if (GET_CODE (set_src) == SUBREG)
3187 set_src = alter_subreg (set_src);
3189 dest1 = gen_highpart (SFmode, set_dest);
3190 dest2 = gen_lowpart (SFmode, set_dest);
3191 src1 = gen_highpart (SFmode, set_src);
3192 src2 = gen_lowpart (SFmode, set_src);
3194 /* Now emit using the real source and destination we found, swapping
3195 the order if we detect overlap. */
3196 if (reg_overlap_mentioned_p (dest1, src2))
3198 emit_insn (gen_movsf (dest2, src2));
3199 emit_insn (gen_movsf (dest1, src1));
3203 emit_insn (gen_movsf (dest1, src1));
3204 emit_insn (gen_movsf (dest2, src2));
3210 [(set (match_operand:DF 0 "register_operand" "")
3211 (match_operand:DF 1 "memory_operand" ""))]
3214 && ((GET_CODE (operands[0]) == REG
3215 && REGNO (operands[0]) < 32)
3216 || (GET_CODE (operands[0]) == SUBREG
3217 && GET_CODE (SUBREG_REG (operands[0])) == REG
3218 && REGNO (SUBREG_REG (operands[0])) < 32))))
3219 && (reload_completed
3220 && (((REGNO (operands[0])) % 2) != 0
3221 || ! mem_min_alignment (operands[1], 8))
3222 && offsettable_memref_p (operands[1])))"
3223 [(clobber (const_int 0))]
3226 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3227 rtx word1 = change_address (operands[1], SFmode,
3228 plus_constant_for_output (XEXP (word0, 0), 4));
3230 if (GET_CODE (operands[0]) == SUBREG)
3231 operands[0] = alter_subreg (operands[0]);
3233 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3235 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3237 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3242 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3244 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3251 [(set (match_operand:DF 0 "memory_operand" "")
3252 (match_operand:DF 1 "register_operand" ""))]
3255 && ((GET_CODE (operands[1]) == REG
3256 && REGNO (operands[1]) < 32)
3257 || (GET_CODE (operands[1]) == SUBREG
3258 && GET_CODE (SUBREG_REG (operands[1])) == REG
3259 && REGNO (SUBREG_REG (operands[1])) < 32))))
3260 && (reload_completed
3261 && (((REGNO (operands[1])) % 2) != 0
3262 || ! mem_min_alignment (operands[0], 8))
3263 && offsettable_memref_p (operands[0])))"
3264 [(clobber (const_int 0))]
3267 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3268 rtx word1 = change_address (operands[0], SFmode,
3269 plus_constant_for_output (XEXP (word0, 0), 4));
3271 if (GET_CODE (operands[1]) == SUBREG)
3272 operands[1] = alter_subreg (operands[1]);
3273 emit_insn (gen_movsf (word0,
3274 gen_highpart (SFmode, operands[1])));
3275 emit_insn (gen_movsf (word1,
3276 gen_lowpart (SFmode, operands[1])));
3280 (define_expand "movtf"
3281 [(set (match_operand:TF 0 "general_operand" "")
3282 (match_operand:TF 1 "general_operand" ""))]
3286 /* Force TFmode constants into memory. */
3287 if (GET_CODE (operands[0]) == REG
3288 && CONSTANT_P (operands[1]))
3290 /* emit_group_store will send such bogosity to us when it is
3291 not storing directly into memory. So fix this up to avoid
3292 crashes in output_constant_pool. */
3293 if (operands [1] == const0_rtx)
3294 operands[1] = CONST0_RTX (TFmode);
3295 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3299 /* Handle MEM cases first, note that only v9 guarentees
3300 full 16-byte alignment for quads. */
3301 if (GET_CODE (operands[0]) == MEM)
3303 if (register_operand (operands[1], TFmode))
3306 if (! reload_in_progress)
3308 operands[0] = validize_mem (operands[0]);
3309 operands[1] = force_reg (TFmode, operands[1]);
3313 /* Fixup PIC cases. */
3316 if (CONSTANT_P (operands[1])
3317 && pic_address_needs_scratch (operands[1]))
3318 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3320 if (symbolic_operand (operands[1], TFmode))
3322 operands[1] = legitimize_pic_address (operands[1],
3324 (reload_in_progress ?
3334 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3335 ;; we must split them all. :-(
3336 (define_insn "*movtf_insn_sp32"
3337 [(set (match_operand:TF 0 "general_operand" "=e,o,U,o,e,r,r,o")
3338 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3341 && (register_operand (operands[0], TFmode)
3342 || register_operand (operands[1], TFmode))"
3344 [(set_attr "length" "4")])
3346 ;; Exactly the same as above, except that all `e' cases are deleted.
3347 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3350 (define_insn "*movtf_no_e_insn_sp32"
3351 [(set (match_operand:TF 0 "general_operand" "=U,o,r,r,o")
3352 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3355 && (register_operand (operands[0], TFmode)
3356 || register_operand (operands[1], TFmode))"
3358 [(set_attr "length" "4")])
3360 ;; Now handle the float reg cases directly when arch64,
3361 ;; hard_quad, and proper reg number alignment are all true.
3362 (define_insn "*movtf_insn_hq_sp64"
3363 [(set (match_operand:TF 0 "general_operand" "=e,e,m,r,r,o")
3364 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3369 && (register_operand (operands[0], TFmode)
3370 || register_operand (operands[1], TFmode))"
3378 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3379 (set_attr "length" "1,1,1,2,2,2")])
3381 ;; Now we allow the integer register cases even when
3382 ;; only arch64 is true.
3383 (define_insn "*movtf_insn_sp64"
3384 [(set (match_operand:TF 0 "general_operand" "=e,o,r,o,e,r")
3385 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3388 && ! TARGET_HARD_QUAD
3389 && (register_operand (operands[0], TFmode)
3390 || register_operand (operands[1], TFmode))"
3392 [(set_attr "length" "2")])
3394 (define_insn "*movtf_no_e_insn_sp64"
3395 [(set (match_operand:TF 0 "general_operand" "=r,o,r")
3396 (match_operand:TF 1 "input_operand" "o,r,r"))]
3399 && (register_operand (operands[0], TFmode)
3400 || register_operand (operands[1], TFmode))"
3402 [(set_attr "length" "2")])
3404 ;; Now all the splits to handle multi-insn TF mode moves.
3406 [(set (match_operand:TF 0 "register_operand" "")
3407 (match_operand:TF 1 "register_operand" ""))]
3411 && ! TARGET_HARD_QUAD))"
3412 [(clobber (const_int 0))]
3415 rtx set_dest = operands[0];
3416 rtx set_src = operands[1];
3420 if (GET_CODE (set_dest) == SUBREG)
3421 set_dest = alter_subreg (set_dest);
3422 if (GET_CODE (set_src) == SUBREG)
3423 set_src = alter_subreg (set_src);
3425 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3426 dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
3427 dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
3428 src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0);
3429 src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0);
3431 /* Now emit using the real source and destination we found, swapping
3432 the order if we detect overlap. */
3433 if (reg_overlap_mentioned_p (dest1, src2))
3435 emit_insn (gen_movdf (dest2, src2));
3436 emit_insn (gen_movdf (dest1, src1));
3440 emit_insn (gen_movdf (dest1, src1));
3441 emit_insn (gen_movdf (dest2, src2));
3447 [(set (match_operand:TF 0 "register_operand" "")
3448 (match_operand:TF 1 "memory_operand" ""))]
3450 && offsettable_memref_p (operands[1]))"
3451 [(clobber (const_int 0))]
3454 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3455 rtx word1 = change_address (operands[1], DFmode,
3456 plus_constant_for_output (XEXP (word0, 0), 8));
3459 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3460 dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
3461 dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
3463 /* Now output, ordering such that we don't clobber any registers
3464 mentioned in the address. */
3465 if (reg_overlap_mentioned_p (dest1, word1))
3468 emit_insn (gen_movdf (dest2, word1));
3469 emit_insn (gen_movdf (dest1, word0));
3473 emit_insn (gen_movdf (dest1, word0));
3474 emit_insn (gen_movdf (dest2, word1));
3480 [(set (match_operand:TF 0 "memory_operand" "")
3481 (match_operand:TF 1 "register_operand" ""))]
3483 && offsettable_memref_p (operands[0]))"
3484 [(clobber (const_int 0))]
3487 rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
3488 rtx word1 = change_address (operands[0], DFmode,
3489 plus_constant_for_output (XEXP (word0, 0), 8));
3492 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3493 src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
3494 src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
3495 emit_insn (gen_movdf (word0, src1));
3496 emit_insn (gen_movdf (word1, src2));
3500 ;; Sparc V9 conditional move instructions.
3502 ;; We can handle larger constants here for some flavors, but for now we keep
3503 ;; it simple and only allow those constants supported by all flavours.
3504 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3505 ;; 3 contains the constant if one is present, but we handle either for
3506 ;; generality (sparc.c puts a constant in operand 2).
3508 (define_expand "movqicc"
3509 [(set (match_operand:QI 0 "register_operand" "")
3510 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3511 (match_operand:QI 2 "arith10_operand" "")
3512 (match_operand:QI 3 "arith10_operand" "")))]
3516 enum rtx_code code = GET_CODE (operands[1]);
3518 if (GET_MODE (sparc_compare_op0) == DImode
3522 if (sparc_compare_op1 == const0_rtx
3523 && GET_CODE (sparc_compare_op0) == REG
3524 && GET_MODE (sparc_compare_op0) == DImode
3525 && v9_regcmp_p (code))
3527 operands[1] = gen_rtx_fmt_ee (code, DImode,
3528 sparc_compare_op0, sparc_compare_op1);
3532 rtx cc_reg = gen_compare_reg (code,
3533 sparc_compare_op0, sparc_compare_op1);
3534 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3538 (define_expand "movhicc"
3539 [(set (match_operand:HI 0 "register_operand" "")
3540 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3541 (match_operand:HI 2 "arith10_operand" "")
3542 (match_operand:HI 3 "arith10_operand" "")))]
3546 enum rtx_code code = GET_CODE (operands[1]);
3548 if (GET_MODE (sparc_compare_op0) == DImode
3552 if (sparc_compare_op1 == const0_rtx
3553 && GET_CODE (sparc_compare_op0) == REG
3554 && GET_MODE (sparc_compare_op0) == DImode
3555 && v9_regcmp_p (code))
3557 operands[1] = gen_rtx_fmt_ee (code, DImode,
3558 sparc_compare_op0, sparc_compare_op1);
3562 rtx cc_reg = gen_compare_reg (code,
3563 sparc_compare_op0, sparc_compare_op1);
3564 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3568 (define_expand "movsicc"
3569 [(set (match_operand:SI 0 "register_operand" "")
3570 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3571 (match_operand:SI 2 "arith10_operand" "")
3572 (match_operand:SI 3 "arith10_operand" "")))]
3576 enum rtx_code code = GET_CODE (operands[1]);
3577 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3579 if (sparc_compare_op1 == const0_rtx
3580 && GET_CODE (sparc_compare_op0) == REG
3581 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3583 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3584 sparc_compare_op0, sparc_compare_op1);
3588 rtx cc_reg = gen_compare_reg (code,
3589 sparc_compare_op0, sparc_compare_op1);
3590 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3591 cc_reg, const0_rtx);
3595 (define_expand "movdicc"
3596 [(set (match_operand:DI 0 "register_operand" "")
3597 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3598 (match_operand:DI 2 "arith10_double_operand" "")
3599 (match_operand:DI 3 "arith10_double_operand" "")))]
3603 enum rtx_code code = GET_CODE (operands[1]);
3605 if (sparc_compare_op1 == const0_rtx
3606 && GET_CODE (sparc_compare_op0) == REG
3607 && GET_MODE (sparc_compare_op0) == DImode
3608 && v9_regcmp_p (code))
3610 operands[1] = gen_rtx_fmt_ee (code, DImode,
3611 sparc_compare_op0, sparc_compare_op1);
3615 rtx cc_reg = gen_compare_reg (code,
3616 sparc_compare_op0, sparc_compare_op1);
3617 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3618 cc_reg, const0_rtx);
3622 (define_expand "movsfcc"
3623 [(set (match_operand:SF 0 "register_operand" "")
3624 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3625 (match_operand:SF 2 "register_operand" "")
3626 (match_operand:SF 3 "register_operand" "")))]
3627 "TARGET_V9 && TARGET_FPU"
3630 enum rtx_code code = GET_CODE (operands[1]);
3632 if (GET_MODE (sparc_compare_op0) == DImode
3636 if (sparc_compare_op1 == const0_rtx
3637 && GET_CODE (sparc_compare_op0) == REG
3638 && GET_MODE (sparc_compare_op0) == DImode
3639 && v9_regcmp_p (code))
3641 operands[1] = gen_rtx_fmt_ee (code, DImode,
3642 sparc_compare_op0, sparc_compare_op1);
3646 rtx cc_reg = gen_compare_reg (code,
3647 sparc_compare_op0, sparc_compare_op1);
3648 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3652 (define_expand "movdfcc"
3653 [(set (match_operand:DF 0 "register_operand" "")
3654 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3655 (match_operand:DF 2 "register_operand" "")
3656 (match_operand:DF 3 "register_operand" "")))]
3657 "TARGET_V9 && TARGET_FPU"
3660 enum rtx_code code = GET_CODE (operands[1]);
3662 if (GET_MODE (sparc_compare_op0) == DImode
3666 if (sparc_compare_op1 == const0_rtx
3667 && GET_CODE (sparc_compare_op0) == REG
3668 && GET_MODE (sparc_compare_op0) == DImode
3669 && v9_regcmp_p (code))
3671 operands[1] = gen_rtx_fmt_ee (code, DImode,
3672 sparc_compare_op0, sparc_compare_op1);
3676 rtx cc_reg = gen_compare_reg (code,
3677 sparc_compare_op0, sparc_compare_op1);
3678 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3682 (define_expand "movtfcc"
3683 [(set (match_operand:TF 0 "register_operand" "")
3684 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3685 (match_operand:TF 2 "register_operand" "")
3686 (match_operand:TF 3 "register_operand" "")))]
3687 "TARGET_V9 && TARGET_FPU"
3690 enum rtx_code code = GET_CODE (operands[1]);
3692 if (GET_MODE (sparc_compare_op0) == DImode
3696 if (sparc_compare_op1 == const0_rtx
3697 && GET_CODE (sparc_compare_op0) == REG
3698 && GET_MODE (sparc_compare_op0) == DImode
3699 && v9_regcmp_p (code))
3701 operands[1] = gen_rtx_fmt_ee (code, DImode,
3702 sparc_compare_op0, sparc_compare_op1);
3706 rtx cc_reg = gen_compare_reg (code,
3707 sparc_compare_op0, sparc_compare_op1);
3708 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3712 ;; Conditional move define_insns.
3714 (define_insn "*movqi_cc_sp64"
3715 [(set (match_operand:QI 0 "register_operand" "=r,r")
3716 (if_then_else:QI (match_operator 1 "comparison_operator"
3717 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3719 (match_operand:QI 3 "arith11_operand" "rL,0")
3720 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3723 mov%C1\\t%x2, %3, %0
3724 mov%c1\\t%x2, %4, %0"
3725 [(set_attr "type" "cmove")
3726 (set_attr "length" "1")])
3728 (define_insn "*movhi_cc_sp64"
3729 [(set (match_operand:HI 0 "register_operand" "=r,r")
3730 (if_then_else:HI (match_operator 1 "comparison_operator"
3731 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3733 (match_operand:HI 3 "arith11_operand" "rL,0")
3734 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3737 mov%C1\\t%x2, %3, %0
3738 mov%c1\\t%x2, %4, %0"
3739 [(set_attr "type" "cmove")
3740 (set_attr "length" "1")])
3742 (define_insn "*movsi_cc_sp64"
3743 [(set (match_operand:SI 0 "register_operand" "=r,r")
3744 (if_then_else:SI (match_operator 1 "comparison_operator"
3745 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3747 (match_operand:SI 3 "arith11_operand" "rL,0")
3748 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3751 mov%C1\\t%x2, %3, %0
3752 mov%c1\\t%x2, %4, %0"
3753 [(set_attr "type" "cmove")
3754 (set_attr "length" "1")])
3756 ;; ??? The constraints of operands 3,4 need work.
3757 (define_insn "*movdi_cc_sp64"
3758 [(set (match_operand:DI 0 "register_operand" "=r,r")
3759 (if_then_else:DI (match_operator 1 "comparison_operator"
3760 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3762 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3763 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3766 mov%C1\\t%x2, %3, %0
3767 mov%c1\\t%x2, %4, %0"
3768 [(set_attr "type" "cmove")
3769 (set_attr "length" "1")])
3771 (define_insn "*movdi_cc_sp64_trunc"
3772 [(set (match_operand:SI 0 "register_operand" "=r,r")
3773 (if_then_else:SI (match_operator 1 "comparison_operator"
3774 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3776 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3777 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3780 mov%C1\\t%x2, %3, %0
3781 mov%c1\\t%x2, %4, %0"
3782 [(set_attr "type" "cmove")
3783 (set_attr "length" "1")])
3785 (define_insn "*movsf_cc_sp64"
3786 [(set (match_operand:SF 0 "register_operand" "=f,f")
3787 (if_then_else:SF (match_operator 1 "comparison_operator"
3788 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3790 (match_operand:SF 3 "register_operand" "f,0")
3791 (match_operand:SF 4 "register_operand" "0,f")))]
3792 "TARGET_V9 && TARGET_FPU"
3794 fmovs%C1\\t%x2, %3, %0
3795 fmovs%c1\\t%x2, %4, %0"
3796 [(set_attr "type" "fpcmove")
3797 (set_attr "length" "1")])
3799 (define_insn "*movdf_cc_sp64"
3800 [(set (match_operand:DF 0 "register_operand" "=e,e")
3801 (if_then_else:DF (match_operator 1 "comparison_operator"
3802 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3804 (match_operand:DF 3 "register_operand" "e,0")
3805 (match_operand:DF 4 "register_operand" "0,e")))]
3806 "TARGET_V9 && TARGET_FPU"
3808 fmovd%C1\\t%x2, %3, %0
3809 fmovd%c1\\t%x2, %4, %0"
3810 [(set_attr "type" "fpcmove")
3811 (set_attr "length" "1")])
3813 (define_insn "*movtf_cc_sp64"
3814 [(set (match_operand:TF 0 "register_operand" "=e,e")
3815 (if_then_else:TF (match_operator 1 "comparison_operator"
3816 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3818 (match_operand:TF 3 "register_operand" "e,0")
3819 (match_operand:TF 4 "register_operand" "0,e")))]
3820 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3822 fmovq%C1\\t%x2, %3, %0
3823 fmovq%c1\\t%x2, %4, %0"
3824 [(set_attr "type" "fpcmove")
3825 (set_attr "length" "1")])
3827 (define_insn "*movqi_cc_reg_sp64"
3828 [(set (match_operand:QI 0 "register_operand" "=r,r")
3829 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3830 [(match_operand:DI 2 "register_operand" "r,r")
3832 (match_operand:QI 3 "arith10_operand" "rM,0")
3833 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3836 movr%D1\\t%2, %r3, %0
3837 movr%d1\\t%2, %r4, %0"
3838 [(set_attr "type" "cmove")
3839 (set_attr "length" "1")])
3841 (define_insn "*movhi_cc_reg_sp64"
3842 [(set (match_operand:HI 0 "register_operand" "=r,r")
3843 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3844 [(match_operand:DI 2 "register_operand" "r,r")
3846 (match_operand:HI 3 "arith10_operand" "rM,0")
3847 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3850 movr%D1\\t%2, %r3, %0
3851 movr%d1\\t%2, %r4, %0"
3852 [(set_attr "type" "cmove")
3853 (set_attr "length" "1")])
3855 (define_insn "*movsi_cc_reg_sp64"
3856 [(set (match_operand:SI 0 "register_operand" "=r,r")
3857 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3858 [(match_operand:DI 2 "register_operand" "r,r")
3860 (match_operand:SI 3 "arith10_operand" "rM,0")
3861 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3864 movr%D1\\t%2, %r3, %0
3865 movr%d1\\t%2, %r4, %0"
3866 [(set_attr "type" "cmove")
3867 (set_attr "length" "1")])
3869 ;; ??? The constraints of operands 3,4 need work.
3870 (define_insn "*movdi_cc_reg_sp64"
3871 [(set (match_operand:DI 0 "register_operand" "=r,r")
3872 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3873 [(match_operand:DI 2 "register_operand" "r,r")
3875 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3876 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3879 movr%D1\\t%2, %r3, %0
3880 movr%d1\\t%2, %r4, %0"
3881 [(set_attr "type" "cmove")
3882 (set_attr "length" "1")])
3884 (define_insn "*movdi_cc_reg_sp64_trunc"
3885 [(set (match_operand:SI 0 "register_operand" "=r,r")
3886 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3887 [(match_operand:DI 2 "register_operand" "r,r")
3889 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3890 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3893 movr%D1\\t%2, %r3, %0
3894 movr%d1\\t%2, %r4, %0"
3895 [(set_attr "type" "cmove")
3896 (set_attr "length" "1")])
3898 (define_insn "*movsf_cc_reg_sp64"
3899 [(set (match_operand:SF 0 "register_operand" "=f,f")
3900 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3901 [(match_operand:DI 2 "register_operand" "r,r")
3903 (match_operand:SF 3 "register_operand" "f,0")
3904 (match_operand:SF 4 "register_operand" "0,f")))]
3905 "TARGET_ARCH64 && TARGET_FPU"
3907 fmovrs%D1\\t%2, %3, %0
3908 fmovrs%d1\\t%2, %4, %0"
3909 [(set_attr "type" "fpcmove")
3910 (set_attr "length" "1")])
3912 (define_insn "*movdf_cc_reg_sp64"
3913 [(set (match_operand:DF 0 "register_operand" "=e,e")
3914 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3915 [(match_operand:DI 2 "register_operand" "r,r")
3917 (match_operand:DF 3 "register_operand" "e,0")
3918 (match_operand:DF 4 "register_operand" "0,e")))]
3919 "TARGET_ARCH64 && TARGET_FPU"
3921 fmovrd%D1\\t%2, %3, %0
3922 fmovrd%d1\\t%2, %4, %0"
3923 [(set_attr "type" "fpcmove")
3924 (set_attr "length" "1")])
3926 (define_insn "*movtf_cc_reg_sp64"
3927 [(set (match_operand:TF 0 "register_operand" "=e,e")
3928 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3929 [(match_operand:DI 2 "register_operand" "r,r")
3931 (match_operand:TF 3 "register_operand" "e,0")
3932 (match_operand:TF 4 "register_operand" "0,e")))]
3933 "TARGET_ARCH64 && TARGET_FPU"
3935 fmovrq%D1\\t%2, %3, %0
3936 fmovrq%d1\\t%2, %4, %0"
3937 [(set_attr "type" "fpcmove")
3938 (set_attr "length" "1")])
3940 ;;- zero extension instructions
3942 ;; These patterns originally accepted general_operands, however, slightly
3943 ;; better code is generated by only accepting register_operands, and then
3944 ;; letting combine generate the ldu[hb] insns.
3946 (define_expand "zero_extendhisi2"
3947 [(set (match_operand:SI 0 "register_operand" "")
3948 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3952 rtx temp = gen_reg_rtx (SImode);
3953 rtx shift_16 = GEN_INT (16);
3954 int op1_subword = 0;
3956 if (GET_CODE (operand1) == SUBREG)
3958 op1_subword = SUBREG_WORD (operand1);
3959 operand1 = XEXP (operand1, 0);
3962 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
3965 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3969 (define_insn "*zero_extendhisi2_insn"
3970 [(set (match_operand:SI 0 "register_operand" "=r")
3971 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3974 [(set_attr "type" "load")
3975 (set_attr "length" "1")])
3977 (define_expand "zero_extendqihi2"
3978 [(set (match_operand:HI 0 "register_operand" "")
3979 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3983 (define_insn "*zero_extendqihi2_insn"
3984 [(set (match_operand:HI 0 "register_operand" "=r,r")
3985 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3986 "GET_CODE (operands[1]) != CONST_INT"
3990 [(set_attr "type" "unary,load")
3991 (set_attr "length" "1")])
3993 (define_expand "zero_extendqisi2"
3994 [(set (match_operand:SI 0 "register_operand" "")
3995 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3999 (define_insn "*zero_extendqisi2_insn"
4000 [(set (match_operand:SI 0 "register_operand" "=r,r")
4001 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4002 "GET_CODE (operands[1]) != CONST_INT"
4006 [(set_attr "type" "unary,load")
4007 (set_attr "length" "1")])
4009 (define_expand "zero_extendqidi2"
4010 [(set (match_operand:DI 0 "register_operand" "")
4011 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4015 (define_insn "*zero_extendqidi2_insn"
4016 [(set (match_operand:DI 0 "register_operand" "=r,r")
4017 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4018 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4022 [(set_attr "type" "unary,load")
4023 (set_attr "length" "1")])
4025 (define_expand "zero_extendhidi2"
4026 [(set (match_operand:DI 0 "register_operand" "")
4027 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4031 rtx temp = gen_reg_rtx (DImode);
4032 rtx shift_48 = GEN_INT (48);
4033 int op1_subword = 0;
4035 if (GET_CODE (operand1) == SUBREG)
4037 op1_subword = SUBREG_WORD (operand1);
4038 operand1 = XEXP (operand1, 0);
4041 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4044 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4048 (define_insn "*zero_extendhidi2_insn"
4049 [(set (match_operand:DI 0 "register_operand" "=r")
4050 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4053 [(set_attr "type" "load")
4054 (set_attr "length" "1")])
4057 ;; ??? Write truncdisi pattern using sra?
4059 (define_expand "zero_extendsidi2"
4060 [(set (match_operand:DI 0 "register_operand" "")
4061 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4065 (define_insn "*zero_extendsidi2_insn_sp64"
4066 [(set (match_operand:DI 0 "register_operand" "=r,r")
4067 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4068 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4072 [(set_attr "type" "shift,load")
4073 (set_attr "length" "1")])
4075 (define_insn "*zero_extendsidi2_insn_sp32"
4076 [(set (match_operand:DI 0 "register_operand" "=r")
4077 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4080 [(set_attr "type" "unary")
4081 (set_attr "length" "2")])
4084 [(set (match_operand:DI 0 "register_operand" "")
4085 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4086 "! TARGET_ARCH64 && reload_completed"
4087 [(set (match_dup 2) (match_dup 3))
4088 (set (match_dup 4) (match_dup 5))]
4093 if (GET_CODE (operands[0]) == SUBREG)
4094 operands[0] = alter_subreg (operands[0]);
4096 dest1 = gen_highpart (SImode, operands[0]);
4097 dest2 = gen_lowpart (SImode, operands[0]);
4099 /* Swap the order in case of overlap. */
4100 if (REGNO (dest1) == REGNO (operands[1]))
4102 operands[2] = dest2;
4103 operands[3] = operands[1];
4104 operands[4] = dest1;
4105 operands[5] = const0_rtx;
4109 operands[2] = dest1;
4110 operands[3] = const0_rtx;
4111 operands[4] = dest2;
4112 operands[5] = operands[1];
4116 ;; Simplify comparisons of extended values.
4118 (define_insn "*cmp_zero_extendqisi2"
4120 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4123 "andcc\\t%0, 0xff, %%g0"
4124 [(set_attr "type" "compare")
4125 (set_attr "length" "1")])
4127 (define_insn "*cmp_zero_extendqisi2_set"
4129 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4131 (set (match_operand:SI 0 "register_operand" "=r")
4132 (zero_extend:SI (match_dup 1)))]
4134 "andcc\\t%1, 0xff, %0"
4135 [(set_attr "type" "compare")
4136 (set_attr "length" "1")])
4138 (define_insn "*cmp_zero_extendqidi2"
4140 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4143 "andcc\\t%0, 0xff, %%g0"
4144 [(set_attr "type" "compare")
4145 (set_attr "length" "1")])
4147 (define_insn "*cmp_zero_extendqidi2_set"
4149 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4151 (set (match_operand:DI 0 "register_operand" "=r")
4152 (zero_extend:DI (match_dup 1)))]
4154 "andcc\\t%1, 0xff, %0"
4155 [(set_attr "type" "compare")
4156 (set_attr "length" "1")])
4158 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4160 (define_insn "*cmp_siqi_trunc"
4162 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4165 "andcc\\t%0, 0xff, %%g0"
4166 [(set_attr "type" "compare")
4167 (set_attr "length" "1")])
4169 (define_insn "*cmp_siqi_trunc_set"
4171 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4173 (set (match_operand:QI 0 "register_operand" "=r")
4174 (subreg:QI (match_dup 1) 0))]
4176 "andcc\\t%1, 0xff, %0"
4177 [(set_attr "type" "compare")
4178 (set_attr "length" "1")])
4180 (define_insn "*cmp_diqi_trunc"
4182 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4185 "andcc\\t%0, 0xff, %%g0"
4186 [(set_attr "type" "compare")
4187 (set_attr "length" "1")])
4189 (define_insn "*cmp_diqi_trunc_set"
4191 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4193 (set (match_operand:QI 0 "register_operand" "=r")
4194 (subreg:QI (match_dup 1) 0))]
4196 "andcc\\t%1, 0xff, %0"
4197 [(set_attr "type" "compare")
4198 (set_attr "length" "1")])
4200 ;;- sign extension instructions
4202 ;; These patterns originally accepted general_operands, however, slightly
4203 ;; better code is generated by only accepting register_operands, and then
4204 ;; letting combine generate the lds[hb] insns.
4206 (define_expand "extendhisi2"
4207 [(set (match_operand:SI 0 "register_operand" "")
4208 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4212 rtx temp = gen_reg_rtx (SImode);
4213 rtx shift_16 = GEN_INT (16);
4214 int op1_subword = 0;
4216 if (GET_CODE (operand1) == SUBREG)
4218 op1_subword = SUBREG_WORD (operand1);
4219 operand1 = XEXP (operand1, 0);
4222 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4225 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4229 (define_insn "*sign_extendhisi2_insn"
4230 [(set (match_operand:SI 0 "register_operand" "=r")
4231 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4234 [(set_attr "type" "sload")
4235 (set_attr "length" "1")])
4237 (define_expand "extendqihi2"
4238 [(set (match_operand:HI 0 "register_operand" "")
4239 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4243 rtx temp = gen_reg_rtx (SImode);
4244 rtx shift_24 = GEN_INT (24);
4245 int op1_subword = 0;
4246 int op0_subword = 0;
4248 if (GET_CODE (operand1) == SUBREG)
4250 op1_subword = SUBREG_WORD (operand1);
4251 operand1 = XEXP (operand1, 0);
4253 if (GET_CODE (operand0) == SUBREG)
4255 op0_subword = SUBREG_WORD (operand0);
4256 operand0 = XEXP (operand0, 0);
4258 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4261 if (GET_MODE (operand0) != SImode)
4262 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4263 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4267 (define_insn "*sign_extendqihi2_insn"
4268 [(set (match_operand:HI 0 "register_operand" "=r")
4269 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4272 [(set_attr "type" "sload")
4273 (set_attr "length" "1")])
4275 (define_expand "extendqisi2"
4276 [(set (match_operand:SI 0 "register_operand" "")
4277 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4281 rtx temp = gen_reg_rtx (SImode);
4282 rtx shift_24 = GEN_INT (24);
4283 int op1_subword = 0;
4285 if (GET_CODE (operand1) == SUBREG)
4287 op1_subword = SUBREG_WORD (operand1);
4288 operand1 = XEXP (operand1, 0);
4291 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4294 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4298 (define_insn "*sign_extendqisi2_insn"
4299 [(set (match_operand:SI 0 "register_operand" "=r")
4300 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4303 [(set_attr "type" "sload")
4304 (set_attr "length" "1")])
4306 (define_expand "extendqidi2"
4307 [(set (match_operand:DI 0 "register_operand" "")
4308 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4312 rtx temp = gen_reg_rtx (DImode);
4313 rtx shift_56 = GEN_INT (56);
4314 int op1_subword = 0;
4316 if (GET_CODE (operand1) == SUBREG)
4318 op1_subword = SUBREG_WORD (operand1);
4319 operand1 = XEXP (operand1, 0);
4322 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4325 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4329 (define_insn "*sign_extendqidi2_insn"
4330 [(set (match_operand:DI 0 "register_operand" "=r")
4331 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4334 [(set_attr "type" "sload")
4335 (set_attr "length" "1")])
4337 (define_expand "extendhidi2"
4338 [(set (match_operand:DI 0 "register_operand" "")
4339 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4343 rtx temp = gen_reg_rtx (DImode);
4344 rtx shift_48 = GEN_INT (48);
4345 int op1_subword = 0;
4347 if (GET_CODE (operand1) == SUBREG)
4349 op1_subword = SUBREG_WORD (operand1);
4350 operand1 = XEXP (operand1, 0);
4353 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4356 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4360 (define_insn "*sign_extendhidi2_insn"
4361 [(set (match_operand:DI 0 "register_operand" "=r")
4362 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4365 [(set_attr "type" "sload")
4366 (set_attr "length" "1")])
4368 (define_expand "extendsidi2"
4369 [(set (match_operand:DI 0 "register_operand" "")
4370 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4374 (define_insn "*sign_extendsidi2_insn"
4375 [(set (match_operand:DI 0 "register_operand" "=r,r")
4376 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4381 [(set_attr "type" "shift,sload")
4382 (set_attr "length" "1")])
4384 ;; Special pattern for optimizing bit-field compares. This is needed
4385 ;; because combine uses this as a canonical form.
4387 (define_insn "*cmp_zero_extract"
4390 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4391 (match_operand:SI 1 "small_int_or_double" "n")
4392 (match_operand:SI 2 "small_int_or_double" "n"))
4395 && ((GET_CODE (operands[2]) == CONST_INT
4396 && INTVAL (operands[2]) > 19)
4397 || (GET_CODE (operands[2]) == CONST_DOUBLE
4398 && CONST_DOUBLE_LOW (operands[2]) > 19))"
4401 int len = (GET_CODE (operands[1]) == CONST_INT
4402 ? INTVAL (operands[1])
4403 : CONST_DOUBLE_LOW (operands[1]));
4405 (GET_CODE (operands[2]) == CONST_INT
4406 ? INTVAL (operands[2])
4407 : CONST_DOUBLE_LOW (operands[2])) - len;
4408 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4410 operands[1] = GEN_INT (mask);
4411 return \"andcc\\t%0, %1, %%g0\";
4413 [(set_attr "type" "compare")
4414 (set_attr "length" "1")])
4416 (define_insn "*cmp_zero_extract_sp64"
4419 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4420 (match_operand:SI 1 "small_int_or_double" "n")
4421 (match_operand:SI 2 "small_int_or_double" "n"))
4424 && ((GET_CODE (operands[2]) == CONST_INT
4425 && INTVAL (operands[2]) > 51)
4426 || (GET_CODE (operands[2]) == CONST_DOUBLE
4427 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4430 int len = (GET_CODE (operands[1]) == CONST_INT
4431 ? INTVAL (operands[1])
4432 : CONST_DOUBLE_LOW (operands[1]));
4434 (GET_CODE (operands[2]) == CONST_INT
4435 ? INTVAL (operands[2])
4436 : CONST_DOUBLE_LOW (operands[2])) - len;
4437 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4439 operands[1] = GEN_INT (mask);
4440 return \"andcc\\t%0, %1, %%g0\";
4442 [(set_attr "type" "compare")
4443 (set_attr "length" "1")])
4445 ;; Conversions between float, double and long double.
4447 (define_insn "extendsfdf2"
4448 [(set (match_operand:DF 0 "register_operand" "=e")
4450 (match_operand:SF 1 "register_operand" "f")))]
4453 [(set_attr "type" "fp")
4454 (set_attr "length" "1")])
4456 (define_insn "extendsftf2"
4457 [(set (match_operand:TF 0 "register_operand" "=e")
4459 (match_operand:SF 1 "register_operand" "f")))]
4460 "TARGET_FPU && TARGET_HARD_QUAD"
4462 [(set_attr "type" "fp")
4463 (set_attr "length" "1")])
4465 (define_insn "extenddftf2"
4466 [(set (match_operand:TF 0 "register_operand" "=e")
4468 (match_operand:DF 1 "register_operand" "e")))]
4469 "TARGET_FPU && TARGET_HARD_QUAD"
4471 [(set_attr "type" "fp")
4472 (set_attr "length" "1")])
4474 (define_insn "truncdfsf2"
4475 [(set (match_operand:SF 0 "register_operand" "=f")
4477 (match_operand:DF 1 "register_operand" "e")))]
4480 [(set_attr "type" "fp")
4481 (set_attr "length" "1")])
4483 (define_insn "trunctfsf2"
4484 [(set (match_operand:SF 0 "register_operand" "=f")
4486 (match_operand:TF 1 "register_operand" "e")))]
4487 "TARGET_FPU && TARGET_HARD_QUAD"
4489 [(set_attr "type" "fp")
4490 (set_attr "length" "1")])
4492 (define_insn "trunctfdf2"
4493 [(set (match_operand:DF 0 "register_operand" "=e")
4495 (match_operand:TF 1 "register_operand" "e")))]
4496 "TARGET_FPU && TARGET_HARD_QUAD"
4498 [(set_attr "type" "fp")
4499 (set_attr "length" "1")])
4501 ;; Conversion between fixed point and floating point.
4503 (define_insn "floatsisf2"
4504 [(set (match_operand:SF 0 "register_operand" "=f")
4505 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4508 [(set_attr "type" "fp")
4509 (set_attr "length" "1")])
4511 (define_insn "floatsidf2"
4512 [(set (match_operand:DF 0 "register_operand" "=e")
4513 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4516 [(set_attr "type" "fp")
4517 (set_attr "length" "1")])
4519 (define_insn "floatsitf2"
4520 [(set (match_operand:TF 0 "register_operand" "=e")
4521 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4522 "TARGET_FPU && TARGET_HARD_QUAD"
4524 [(set_attr "type" "fp")
4525 (set_attr "length" "1")])
4527 ;; Now the same for 64 bit sources.
4529 (define_insn "floatdisf2"
4530 [(set (match_operand:SF 0 "register_operand" "=f")
4531 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4532 "TARGET_V9 && TARGET_FPU"
4534 [(set_attr "type" "fp")
4535 (set_attr "length" "1")])
4537 (define_insn "floatdidf2"
4538 [(set (match_operand:DF 0 "register_operand" "=e")
4539 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4540 "TARGET_V9 && TARGET_FPU"
4542 [(set_attr "type" "fp")
4543 (set_attr "length" "1")])
4545 (define_insn "floatditf2"
4546 [(set (match_operand:TF 0 "register_operand" "=e")
4547 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4548 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4550 [(set_attr "type" "fp")
4551 (set_attr "length" "1")])
4553 ;; Convert a float to an actual integer.
4554 ;; Truncation is performed as part of the conversion.
4556 (define_insn "fix_truncsfsi2"
4557 [(set (match_operand:SI 0 "register_operand" "=f")
4558 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4561 [(set_attr "type" "fp")
4562 (set_attr "length" "1")])
4564 (define_insn "fix_truncdfsi2"
4565 [(set (match_operand:SI 0 "register_operand" "=f")
4566 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4569 [(set_attr "type" "fp")
4570 (set_attr "length" "1")])
4572 (define_insn "fix_trunctfsi2"
4573 [(set (match_operand:SI 0 "register_operand" "=f")
4574 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4575 "TARGET_FPU && TARGET_HARD_QUAD"
4577 [(set_attr "type" "fp")
4578 (set_attr "length" "1")])
4580 ;; Now the same, for V9 targets
4582 (define_insn "fix_truncsfdi2"
4583 [(set (match_operand:DI 0 "register_operand" "=e")
4584 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4585 "TARGET_V9 && TARGET_FPU"
4587 [(set_attr "type" "fp")
4588 (set_attr "length" "1")])
4590 (define_insn "fix_truncdfdi2"
4591 [(set (match_operand:DI 0 "register_operand" "=e")
4592 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4593 "TARGET_V9 && TARGET_FPU"
4595 [(set_attr "type" "fp")
4596 (set_attr "length" "1")])
4598 (define_insn "fix_trunctfdi2"
4599 [(set (match_operand:DI 0 "register_operand" "=e")
4600 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4601 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4603 [(set_attr "type" "fp")
4604 (set_attr "length" "1")])
4606 ;;- arithmetic instructions
4608 (define_expand "adddi3"
4609 [(set (match_operand:DI 0 "register_operand" "=r")
4610 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4611 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4615 if (! TARGET_ARCH64)
4617 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4618 gen_rtx_SET (VOIDmode, operands[0],
4619 gen_rtx_PLUS (DImode, operands[1],
4621 gen_rtx_CLOBBER (VOIDmode,
4622 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4625 if (arith_double_4096_operand(operands[2], DImode))
4627 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4628 gen_rtx_MINUS (DImode, operands[1],
4634 (define_insn "adddi3_insn_sp32"
4635 [(set (match_operand:DI 0 "register_operand" "=r")
4636 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4637 (match_operand:DI 2 "arith_double_operand" "rHI")))
4638 (clobber (reg:CC 100))]
4641 [(set_attr "length" "2")])
4644 [(set (match_operand:DI 0 "register_operand" "=r")
4645 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4646 (match_operand:DI 2 "arith_double_operand" "rHI")))
4647 (clobber (reg:CC 100))]
4648 "! TARGET_ARCH64 && reload_completed"
4649 [(parallel [(set (reg:CC_NOOV 100)
4650 (compare:CC_NOOV (plus:SI (match_dup 4)
4654 (plus:SI (match_dup 4) (match_dup 5)))])
4656 (plus:SI (plus:SI (match_dup 7)
4658 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4661 operands[3] = gen_lowpart (SImode, operands[0]);
4662 operands[4] = gen_lowpart (SImode, operands[1]);
4663 operands[5] = gen_lowpart (SImode, operands[2]);
4664 operands[6] = gen_highpart (SImode, operands[0]);
4665 operands[7] = gen_highpart (SImode, operands[1]);
4666 if (GET_CODE (operands[2]) == CONST_INT)
4668 if (INTVAL (operands[2]) < 0)
4669 operands[8] = constm1_rtx;
4671 operands[8] = const0_rtx;
4674 operands[8] = gen_highpart (SImode, operands[2]);
4678 [(set (match_operand:DI 0 "register_operand" "=r")
4679 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
4680 (match_operand:DI 2 "arith_double_operand" "rHI")))
4681 (clobber (reg:CC 100))]
4682 "! TARGET_ARCH64 && reload_completed"
4683 [(parallel [(set (reg:CC_NOOV 100)
4684 (compare:CC_NOOV (minus:SI (match_dup 4)
4688 (minus:SI (match_dup 4) (match_dup 5)))])
4690 (minus:SI (minus:SI (match_dup 7)
4692 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4695 operands[3] = gen_lowpart (SImode, operands[0]);
4696 operands[4] = gen_lowpart (SImode, operands[1]);
4697 operands[5] = gen_lowpart (SImode, operands[2]);
4698 operands[6] = gen_highpart (SImode, operands[0]);
4699 operands[7] = gen_highpart (SImode, operands[1]);
4700 if (GET_CODE (operands[2]) == CONST_INT)
4702 if (INTVAL (operands[2]) < 0)
4703 operands[8] = constm1_rtx;
4705 operands[8] = const0_rtx;
4708 operands[8] = gen_highpart (SImode, operands[2]);
4711 ;; LTU here means "carry set"
4713 [(set (match_operand:SI 0 "register_operand" "=r")
4714 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4715 (match_operand:SI 2 "arith_operand" "rI"))
4716 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4719 [(set_attr "type" "unary")
4720 (set_attr "length" "1")])
4722 (define_insn "*addx_extend_sp32"
4723 [(set (match_operand:DI 0 "register_operand" "=r")
4724 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4725 (match_operand:SI 2 "arith_operand" "rI"))
4726 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4729 [(set_attr "type" "unary")
4730 (set_attr "length" "2")])
4733 [(set (match_operand:DI 0 "register_operand" "")
4734 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
4735 (match_operand:SI 2 "arith_operand" ""))
4736 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4737 "! TARGET_ARCH64 && reload_completed"
4738 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4739 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4740 (set (match_dup 4) (const_int 0))]
4741 "operands[3] = gen_lowpart (SImode, operands[0]);
4742 operands[4] = gen_highpart (SImode, operands[1]);")
4744 (define_insn "*addx_extend_sp64"
4745 [(set (match_operand:DI 0 "register_operand" "=r")
4746 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4747 (match_operand:SI 2 "arith_operand" "rI"))
4748 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4750 "addx\\t%r1, %2, %0"
4751 [(set_attr "type" "misc")
4752 (set_attr "length" "1")])
4755 [(set (match_operand:SI 0 "register_operand" "=r")
4756 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4757 (match_operand:SI 2 "arith_operand" "rI"))
4758 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4760 "subx\\t%r1, %2, %0"
4761 [(set_attr "type" "misc")
4762 (set_attr "length" "1")])
4764 (define_insn "*subx_extend_sp64"
4765 [(set (match_operand:DI 0 "register_operand" "=r")
4766 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4767 (match_operand:SI 2 "arith_operand" "rI"))
4768 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4770 "subx\\t%r1, %2, %0"
4771 [(set_attr "type" "misc")
4772 (set_attr "length" "1")])
4774 (define_insn "*subx_extend"
4775 [(set (match_operand:DI 0 "register_operand" "=r")
4776 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4777 (match_operand:SI 2 "arith_operand" "rI"))
4778 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4781 [(set_attr "type" "unary")
4782 (set_attr "length" "2")])
4785 [(set (match_operand:DI 0 "register_operand" "=r")
4786 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4787 (match_operand:SI 2 "arith_operand" "rI"))
4788 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4789 "! TARGET_ARCH64 && reload_completed"
4790 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4791 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4792 (set (match_dup 4) (const_int 0))]
4793 "operands[3] = gen_lowpart (SImode, operands[0]);
4794 operands[4] = gen_highpart (SImode, operands[0]);")
4797 [(set (match_operand:DI 0 "register_operand" "=r")
4798 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4799 (match_operand:DI 2 "register_operand" "r")))
4800 (clobber (reg:CC 100))]
4803 [(set_attr "type" "multi")
4804 (set_attr "length" "2")])
4807 [(set (match_operand:DI 0 "register_operand" "")
4808 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4809 (match_operand:DI 2 "register_operand" "")))
4810 (clobber (reg:CC 100))]
4811 "! TARGET_ARCH64 && reload_completed"
4812 [(parallel [(set (reg:CC_NOOV 100)
4813 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4815 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4817 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4818 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4819 "operands[3] = gen_lowpart (SImode, operands[2]);
4820 operands[4] = gen_highpart (SImode, operands[2]);
4821 operands[5] = gen_lowpart (SImode, operands[0]);
4822 operands[6] = gen_highpart (SImode, operands[0]);")
4824 (define_insn "*adddi3_sp64"
4825 [(set (match_operand:DI 0 "register_operand" "=r")
4826 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4827 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4830 [(set_attr "type" "binary")
4831 (set_attr "length" "1")])
4833 (define_expand "addsi3"
4834 [(set (match_operand:SI 0 "register_operand" "=r,d")
4835 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4836 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4840 if (arith_4096_operand(operands[2], DImode))
4842 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4843 gen_rtx_MINUS (SImode, operands[1],
4849 (define_insn "*addsi3"
4850 [(set (match_operand:SI 0 "register_operand" "=r,d")
4851 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4852 (match_operand:SI 2 "arith_operand" "rI,d")))]
4856 fpadd32s\\t%1, %2, %0"
4857 [(set_attr "type" "ialu,fp")
4858 (set_attr "length" "1")])
4860 (define_insn "*cmp_cc_plus"
4861 [(set (reg:CC_NOOV 100)
4862 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4863 (match_operand:SI 1 "arith_operand" "rI"))
4866 "addcc\\t%0, %1, %%g0"
4867 [(set_attr "type" "compare")
4868 (set_attr "length" "1")])
4870 (define_insn "*cmp_ccx_plus"
4871 [(set (reg:CCX_NOOV 100)
4872 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4873 (match_operand:DI 1 "arith_double_operand" "rHI"))
4876 "addcc\\t%0, %1, %%g0"
4877 [(set_attr "type" "compare")
4878 (set_attr "length" "1")])
4880 (define_insn "*cmp_cc_plus_set"
4881 [(set (reg:CC_NOOV 100)
4882 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4883 (match_operand:SI 2 "arith_operand" "rI"))
4885 (set (match_operand:SI 0 "register_operand" "=r")
4886 (plus:SI (match_dup 1) (match_dup 2)))]
4888 "addcc\\t%1, %2, %0"
4889 [(set_attr "type" "compare")
4890 (set_attr "length" "1")])
4892 (define_insn "*cmp_ccx_plus_set"
4893 [(set (reg:CCX_NOOV 100)
4894 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4895 (match_operand:DI 2 "arith_double_operand" "rHI"))
4897 (set (match_operand:DI 0 "register_operand" "=r")
4898 (plus:DI (match_dup 1) (match_dup 2)))]
4900 "addcc\\t%1, %2, %0"
4901 [(set_attr "type" "compare")
4902 (set_attr "length" "1")])
4904 (define_expand "subdi3"
4905 [(set (match_operand:DI 0 "register_operand" "=r")
4906 (minus:DI (match_operand:DI 1 "register_operand" "r")
4907 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4911 if (! TARGET_ARCH64)
4913 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4914 gen_rtx_SET (VOIDmode, operands[0],
4915 gen_rtx_MINUS (DImode, operands[1],
4917 gen_rtx_CLOBBER (VOIDmode,
4918 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4921 if (arith_double_4096_operand(operands[2], DImode))
4923 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4924 gen_rtx_PLUS (DImode, operands[1],
4930 (define_insn "*subdi3_sp32"
4931 [(set (match_operand:DI 0 "register_operand" "=r")
4932 (minus:DI (match_operand:DI 1 "register_operand" "r")
4933 (match_operand:DI 2 "arith_double_operand" "rHI")))
4934 (clobber (reg:CC 100))]
4937 [(set_attr "length" "2")])
4940 [(set (match_operand:DI 0 "register_operand" "")
4941 (minus:DI (match_operand:DI 1 "register_operand" "")
4942 (match_operand:DI 2 "arith_double_operand" "")))
4943 (clobber (reg:CC 100))]
4946 && (GET_CODE (operands[2]) == CONST_INT
4947 || GET_CODE (operands[2]) == CONST_DOUBLE)"
4948 [(clobber (const_int 0))]
4953 highp = gen_highpart (SImode, operands[2]);
4954 lowp = gen_lowpart (SImode, operands[2]);
4955 if ((lowp == const0_rtx)
4956 && (operands[0] == operands[1]))
4958 emit_insn (gen_rtx_SET (VOIDmode,
4959 gen_highpart (SImode, operands[0]),
4960 gen_rtx_MINUS (SImode,
4961 gen_highpart (SImode, operands[1]),
4966 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
4967 gen_lowpart (SImode, operands[1]),
4969 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
4970 gen_highpart (SImode, operands[1]),
4977 [(set (match_operand:DI 0 "register_operand" "")
4978 (minus:DI (match_operand:DI 1 "register_operand" "")
4979 (match_operand:DI 2 "register_operand" "")))
4980 (clobber (reg:CC 100))]
4982 && reload_completed"
4983 [(clobber (const_int 0))]
4986 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
4987 gen_lowpart (SImode, operands[1]),
4988 gen_lowpart (SImode, operands[2])));
4989 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
4990 gen_highpart (SImode, operands[1]),
4991 gen_highpart (SImode, operands[2])));
4996 [(set (match_operand:DI 0 "register_operand" "=r")
4997 (minus:DI (match_operand:DI 1 "register_operand" "r")
4998 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4999 (clobber (reg:CC 100))]
5002 [(set_attr "type" "multi")
5003 (set_attr "length" "2")])
5006 [(set (match_operand:DI 0 "register_operand" "")
5007 (minus:DI (match_operand:DI 1 "register_operand" "")
5008 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5009 (clobber (reg:CC 100))]
5010 "! TARGET_ARCH64 && reload_completed"
5011 [(parallel [(set (reg:CC_NOOV 100)
5012 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5014 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5016 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5017 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5018 "operands[3] = gen_lowpart (SImode, operands[1]);
5019 operands[4] = gen_highpart (SImode, operands[1]);
5020 operands[5] = gen_lowpart (SImode, operands[0]);
5021 operands[6] = gen_highpart (SImode, operands[0]);")
5023 (define_insn "*subdi3_sp64"
5024 [(set (match_operand:DI 0 "register_operand" "=r")
5025 (minus:DI (match_operand:DI 1 "register_operand" "r")
5026 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5029 [(set_attr "type" "binary")
5030 (set_attr "length" "1")])
5032 (define_expand "subsi3"
5033 [(set (match_operand:SI 0 "register_operand" "=r,d")
5034 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5035 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5039 if (arith_4096_operand(operands[2], DImode))
5041 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5042 gen_rtx_PLUS (SImode, operands[1],
5048 (define_insn "*subsi3"
5049 [(set (match_operand:SI 0 "register_operand" "=r,d")
5050 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5051 (match_operand:SI 2 "arith_operand" "rI,d")))]
5055 fpsub32s\\t%1, %2, %0"
5056 [(set_attr "type" "ialu,fp")
5057 (set_attr "length" "1")])
5059 (define_insn "*cmp_minus_cc"
5060 [(set (reg:CC_NOOV 100)
5061 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5062 (match_operand:SI 1 "arith_operand" "rI"))
5065 "subcc\\t%r0, %1, %%g0"
5066 [(set_attr "type" "compare")
5067 (set_attr "length" "1")])
5069 (define_insn "*cmp_minus_ccx"
5070 [(set (reg:CCX_NOOV 100)
5071 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5072 (match_operand:DI 1 "arith_double_operand" "rHI"))
5075 "subcc\\t%0, %1, %%g0"
5076 [(set_attr "type" "compare")
5077 (set_attr "length" "1")])
5079 (define_insn "cmp_minus_cc_set"
5080 [(set (reg:CC_NOOV 100)
5081 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5082 (match_operand:SI 2 "arith_operand" "rI"))
5084 (set (match_operand:SI 0 "register_operand" "=r")
5085 (minus:SI (match_dup 1) (match_dup 2)))]
5087 "subcc\\t%r1, %2, %0"
5088 [(set_attr "type" "compare")
5089 (set_attr "length" "1")])
5091 (define_insn "*cmp_minus_ccx_set"
5092 [(set (reg:CCX_NOOV 100)
5093 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5094 (match_operand:DI 2 "arith_double_operand" "rHI"))
5096 (set (match_operand:DI 0 "register_operand" "=r")
5097 (minus:DI (match_dup 1) (match_dup 2)))]
5099 "subcc\\t%1, %2, %0"
5100 [(set_attr "type" "compare")
5101 (set_attr "length" "1")])
5103 ;; Integer Multiply/Divide.
5105 ;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't
5106 ;; we used. We still use them in 32 bit v9 compilers.
5107 ;; The 64 bit v9 compiler will (/should) widen the args and use muldi3.
5109 (define_insn "mulsi3"
5110 [(set (match_operand:SI 0 "register_operand" "=r")
5111 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5112 (match_operand:SI 2 "arith_operand" "rI")))]
5115 [(set_attr "type" "imul")
5116 (set_attr "length" "1")])
5118 (define_expand "muldi3"
5119 [(set (match_operand:DI 0 "register_operand" "=r")
5120 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5121 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5122 "TARGET_ARCH64 || TARGET_V8PLUS"
5127 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5132 (define_insn "*muldi3_sp64"
5133 [(set (match_operand:DI 0 "register_operand" "=r")
5134 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5135 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5138 [(set_attr "type" "imul")
5139 (set_attr "length" "1")])
5141 ;; V8plus wide multiply.
5143 (define_insn "muldi3_v8plus"
5144 [(set (match_operand:DI 0 "register_operand" "=r,h")
5145 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5146 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5147 (clobber (match_scratch:SI 3 "=&h,X"))
5148 (clobber (match_scratch:SI 4 "=&h,X"))]
5152 if (sparc_check_64 (operands[1], insn) <= 0)
5153 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5154 if (which_alternative == 1)
5155 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5156 if (sparc_check_64 (operands[2], insn) <= 0)
5157 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5158 if (which_alternative == 1)
5159 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\";
5161 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\";
5163 [(set_attr "length" "9,8")])
5165 ;; It is not known whether this will match.
5167 (define_insn "*cmp_mul_set"
5168 [(set (match_operand:SI 0 "register_operand" "=r")
5169 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5170 (match_operand:SI 2 "arith_operand" "rI")))
5171 (set (reg:CC_NOOV 100)
5172 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
5174 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5175 "smulcc\\t%1, %2, %0"
5176 [(set_attr "type" "imul")
5177 (set_attr "length" "1")])
5179 (define_expand "mulsidi3"
5180 [(set (match_operand:DI 0 "register_operand" "")
5181 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5182 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5186 if (CONSTANT_P (operands[2]))
5190 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5194 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
5199 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5204 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5205 ;; registers can hold 64 bit values in the V8plus environment.
5207 (define_insn "mulsidi3_v8plus"
5208 [(set (match_operand:DI 0 "register_operand" "=h,r")
5209 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5210 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5211 (clobber (match_scratch:SI 3 "=X,&h"))]
5214 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5215 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5216 [(set_attr "length" "2,3")])
5219 (define_insn "const_mulsidi3_v8plus"
5220 [(set (match_operand:DI 0 "register_operand" "=h,r")
5221 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5222 (match_operand:SI 2 "small_int" "I,I")))
5223 (clobber (match_scratch:SI 3 "=X,&h"))]
5226 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5227 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5228 [(set_attr "length" "2,3")])
5231 (define_insn "*mulsidi3_sp32"
5232 [(set (match_operand:DI 0 "register_operand" "=r")
5233 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5234 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5238 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5240 [(set (attr "length")
5241 (if_then_else (eq_attr "isa" "sparclet")
5242 (const_int 1) (const_int 2)))])
5244 ;; Extra pattern, because sign_extend of a constant isn't valid.
5247 (define_insn "const_mulsidi3"
5248 [(set (match_operand:DI 0 "register_operand" "=r")
5249 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5250 (match_operand:SI 2 "small_int" "I")))]
5254 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5256 [(set (attr "length")
5257 (if_then_else (eq_attr "isa" "sparclet")
5258 (const_int 1) (const_int 2)))])
5260 (define_expand "smulsi3_highpart"
5261 [(set (match_operand:SI 0 "register_operand" "")
5263 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5264 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5269 if (CONSTANT_P (operands[2]))
5273 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5279 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5284 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5285 operands[2], GEN_INT (32)));
5291 (define_insn "smulsi3_highpart_v8plus"
5292 [(set (match_operand:SI 0 "register_operand" "=h,r")
5294 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5295 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5296 (match_operand:SI 3 "const_int_operand" "i,i"))))
5297 (clobber (match_scratch:SI 4 "=X,&h"))]
5300 smul %1,%2,%0\;srlx %0,%3,%0
5301 smul %1,%2,%4\;srlx %4,%3,%0"
5302 [(set_attr "length" "2")])
5304 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5307 [(set (match_operand:SI 0 "register_operand" "=h,r")
5310 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5311 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5312 (match_operand:SI 3 "const_int_operand" "i,i"))
5314 (clobber (match_scratch:SI 4 "=X,&h"))]
5317 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5318 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5319 [(set_attr "length" "2")])
5322 (define_insn "const_smulsi3_highpart_v8plus"
5323 [(set (match_operand:SI 0 "register_operand" "=h,r")
5325 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5326 (match_operand 2 "small_int" "i,i"))
5327 (match_operand:SI 3 "const_int_operand" "i,i"))))
5328 (clobber (match_scratch:SI 4 "=X,&h"))]
5331 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5332 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5333 [(set_attr "length" "2")])
5336 (define_insn "*smulsi3_highpart_sp32"
5337 [(set (match_operand:SI 0 "register_operand" "=r")
5339 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5340 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5343 && ! TARGET_LIVE_G0"
5344 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5345 [(set_attr "length" "2")])
5348 (define_insn "const_smulsi3_highpart"
5349 [(set (match_operand:SI 0 "register_operand" "=r")
5351 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5352 (match_operand:SI 2 "register_operand" "r"))
5355 && ! TARGET_LIVE_G0"
5356 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5357 [(set_attr "length" "2")])
5359 (define_expand "umulsidi3"
5360 [(set (match_operand:DI 0 "register_operand" "")
5361 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5362 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5366 if (CONSTANT_P (operands[2]))
5370 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5374 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
5379 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5385 (define_insn "umulsidi3_v8plus"
5386 [(set (match_operand:DI 0 "register_operand" "=h,r")
5387 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5388 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5389 (clobber (match_scratch:SI 3 "=X,&h"))]
5392 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5393 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5394 [(set_attr "length" "2,3")])
5397 (define_insn "*umulsidi3_sp32"
5398 [(set (match_operand:DI 0 "register_operand" "=r")
5399 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5400 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5404 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5406 [(set (attr "length")
5407 (if_then_else (eq_attr "isa" "sparclet")
5408 (const_int 1) (const_int 2)))])
5410 ;; Extra pattern, because sign_extend of a constant isn't valid.
5413 (define_insn "const_umulsidi3"
5414 [(set (match_operand:DI 0 "register_operand" "=r")
5415 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5416 (match_operand:SI 2 "uns_small_int" "")))]
5420 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5422 [(set (attr "length")
5423 (if_then_else (eq_attr "isa" "sparclet")
5424 (const_int 1) (const_int 2)))])
5427 (define_insn "const_umulsidi3_v8plus"
5428 [(set (match_operand:DI 0 "register_operand" "=h,r")
5429 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5430 (match_operand:SI 2 "uns_small_int" "")))
5431 (clobber (match_scratch:SI 3 "=X,h"))]
5434 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5435 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5436 [(set_attr "length" "2,3")])
5438 (define_expand "umulsi3_highpart"
5439 [(set (match_operand:SI 0 "register_operand" "")
5441 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5442 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5447 if (CONSTANT_P (operands[2]))
5451 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5457 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5462 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5463 operands[2], GEN_INT (32)));
5469 (define_insn "umulsi3_highpart_v8plus"
5470 [(set (match_operand:SI 0 "register_operand" "=h,r")
5472 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5473 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5474 (match_operand:SI 3 "const_int_operand" "i,i"))))
5475 (clobber (match_scratch:SI 4 "=X,h"))]
5478 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5479 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5480 [(set_attr "length" "2")])
5483 (define_insn "const_umulsi3_highpart_v8plus"
5484 [(set (match_operand:SI 0 "register_operand" "=h,r")
5486 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5487 (match_operand:SI 2 "uns_small_int" ""))
5488 (match_operand:SI 3 "const_int_operand" "i,i"))))
5489 (clobber (match_scratch:SI 4 "=X,h"))]
5492 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5493 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5494 [(set_attr "length" "2")])
5497 (define_insn "*umulsi3_highpart_sp32"
5498 [(set (match_operand:SI 0 "register_operand" "=r")
5500 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5501 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5504 && ! TARGET_LIVE_G0"
5505 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5506 [(set_attr "length" "2")])
5509 (define_insn "const_umulsi3_highpart"
5510 [(set (match_operand:SI 0 "register_operand" "=r")
5512 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5513 (match_operand:SI 2 "uns_small_int" ""))
5516 && ! TARGET_LIVE_G0"
5517 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5518 [(set_attr "length" "2")])
5520 ;; The v8 architecture specifies that there must be 3 instructions between
5521 ;; a y register write and a use of it for correct results.
5524 (define_insn "divsi3"
5525 [(set (match_operand:SI 0 "register_operand" "=r,r")
5526 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5527 (match_operand:SI 2 "input_operand" "rI,m")))
5528 (clobber (match_scratch:SI 3 "=&r,&r"))]
5530 || TARGET_DEPRECATED_V8_INSNS)
5531 && ! TARGET_LIVE_G0"
5534 if (which_alternative == 0)
5536 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0\";
5538 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5541 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5543 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
5545 [(set (attr "length")
5546 (if_then_else (eq_attr "isa" "v9")
5547 (const_int 4) (const_int 7)))])
5549 (define_insn "divdi3"
5550 [(set (match_operand:DI 0 "register_operand" "=r")
5551 (div:DI (match_operand:DI 1 "register_operand" "r")
5552 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5554 "sdivx\\t%1, %2, %0")
5556 ;; It is not known whether this will match.
5558 ;; XXX I hope it doesn't fucking match...
5559 (define_insn "*cmp_sdiv_cc_set"
5560 [(set (match_operand:SI 0 "register_operand" "=r")
5561 (div:SI (match_operand:SI 1 "register_operand" "r")
5562 (match_operand:SI 2 "arith_operand" "rI")))
5564 (compare:CC (div:SI (match_dup 1) (match_dup 2))
5566 (clobber (match_scratch:SI 3 "=&r"))]
5568 || TARGET_DEPRECATED_V8_INSNS)
5569 && ! TARGET_LIVE_G0"
5573 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5575 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5577 [(set (attr "length")
5578 (if_then_else (eq_attr "isa" "v9")
5579 (const_int 3) (const_int 6)))])
5582 (define_insn "udivsi3"
5583 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5584 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5585 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5587 || TARGET_DEPRECATED_V8_INSNS)
5588 && ! TARGET_LIVE_G0"
5591 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
5592 switch (which_alternative)
5596 return \"udiv\\t%1, %2, %0\";
5597 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
5599 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
5601 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
5604 [(set (attr "length")
5605 (if_then_else (and (eq_attr "isa" "v9")
5606 (eq_attr "alternative" "0"))
5607 (const_int 2) (const_int 5)))])
5609 (define_insn "udivdi3"
5610 [(set (match_operand:DI 0 "register_operand" "=r")
5611 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5612 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5614 "udivx\\t%1, %2, %0")
5616 ;; It is not known whether this will match.
5618 ;; XXX I hope it doesn't fucking match...
5619 (define_insn "*cmp_udiv_cc_set"
5620 [(set (match_operand:SI 0 "register_operand" "=r")
5621 (udiv:SI (match_operand:SI 1 "register_operand" "r")
5622 (match_operand:SI 2 "arith_operand" "rI")))
5624 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
5627 || TARGET_DEPRECATED_V8_INSNS)
5628 && ! TARGET_LIVE_G0"
5632 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
5634 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
5636 [(set (attr "length")
5637 (if_then_else (eq_attr "isa" "v9")
5638 (const_int 2) (const_int 5)))])
5640 ; sparclet multiply/accumulate insns
5642 (define_insn "*smacsi"
5643 [(set (match_operand:SI 0 "register_operand" "=r")
5644 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5645 (match_operand:SI 2 "arith_operand" "rI"))
5646 (match_operand:SI 3 "register_operand" "0")))]
5649 [(set_attr "type" "imul")
5650 (set_attr "length" "1")])
5652 (define_insn "*smacdi"
5653 [(set (match_operand:DI 0 "register_operand" "=r")
5654 (plus:DI (mult:DI (sign_extend:DI
5655 (match_operand:SI 1 "register_operand" "%r"))
5657 (match_operand:SI 2 "register_operand" "r")))
5658 (match_operand:DI 3 "register_operand" "0")))]
5660 "smacd\\t%1, %2, %L0"
5661 [(set_attr "type" "imul")
5662 (set_attr "length" "1")])
5664 (define_insn "*umacdi"
5665 [(set (match_operand:DI 0 "register_operand" "=r")
5666 (plus:DI (mult:DI (zero_extend:DI
5667 (match_operand:SI 1 "register_operand" "%r"))
5669 (match_operand:SI 2 "register_operand" "r")))
5670 (match_operand:DI 3 "register_operand" "0")))]
5672 "umacd\\t%1, %2, %L0"
5673 [(set_attr "type" "imul")
5674 (set_attr "length" "1")])
5676 ;;- Boolean instructions
5677 ;; We define DImode `and' so with DImode `not' we can get
5678 ;; DImode `andn'. Other combinations are possible.
5680 (define_expand "anddi3"
5681 [(set (match_operand:DI 0 "register_operand" "")
5682 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5683 (match_operand:DI 2 "arith_double_operand" "")))]
5687 (define_insn "*anddi3_sp32"
5688 [(set (match_operand:DI 0 "register_operand" "=r,b")
5689 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5690 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5695 [(set_attr "type" "ialu,fp")
5696 (set_attr "length" "2,1")])
5698 (define_insn "*anddi3_sp64"
5699 [(set (match_operand:DI 0 "register_operand" "=r,b")
5700 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5701 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5706 [(set_attr "type" "ialu,fp")
5707 (set_attr "length" "1,1")])
5709 (define_insn "andsi3"
5710 [(set (match_operand:SI 0 "register_operand" "=r,d")
5711 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5712 (match_operand:SI 2 "arith_operand" "rI,d")))]
5717 [(set_attr "type" "ialu,fp")
5718 (set_attr "length" "1,1")])
5721 [(set (match_operand:SI 0 "register_operand" "")
5722 (and:SI (match_operand:SI 1 "register_operand" "")
5723 (match_operand:SI 2 "" "")))
5724 (clobber (match_operand:SI 3 "register_operand" ""))]
5725 "GET_CODE (operands[2]) == CONST_INT
5726 && !SMALL_INT32 (operands[2])
5727 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5728 [(set (match_dup 3) (match_dup 4))
5729 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5732 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5735 ;; Split DImode logical operations requiring two instructions.
5737 [(set (match_operand:DI 0 "register_operand" "")
5738 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5739 [(match_operand:DI 2 "register_operand" "")
5740 (match_operand:DI 3 "arith_double_operand" "")]))]
5743 && ((GET_CODE (operands[0]) == REG
5744 && REGNO (operands[0]) < 32)
5745 || (GET_CODE (operands[0]) == SUBREG
5746 && GET_CODE (SUBREG_REG (operands[0])) == REG
5747 && REGNO (SUBREG_REG (operands[0])) < 32))"
5748 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5749 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5752 if (GET_CODE (operands[0]) == SUBREG)
5753 operands[0] = alter_subreg (operands[0]);
5754 operands[4] = gen_highpart (SImode, operands[0]);
5755 operands[5] = gen_lowpart (SImode, operands[0]);
5756 operands[6] = gen_highpart (SImode, operands[2]);
5757 operands[7] = gen_lowpart (SImode, operands[2]);
5758 if (GET_CODE (operands[3]) == CONST_INT)
5760 if (INTVAL (operands[3]) < 0)
5761 operands[8] = constm1_rtx;
5763 operands[8] = const0_rtx;
5766 operands[8] = gen_highpart (SImode, operands[3]);
5767 operands[9] = gen_lowpart (SImode, operands[3]);
5770 (define_insn "*and_not_di_sp32"
5771 [(set (match_operand:DI 0 "register_operand" "=r,b")
5772 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5773 (match_operand:DI 2 "register_operand" "r,b")))]
5777 fandnot1\\t%1, %2, %0"
5778 [(set_attr "type" "ialu,fp")
5779 (set_attr "length" "2,1")])
5782 [(set (match_operand:DI 0 "register_operand" "")
5783 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5784 (match_operand:DI 2 "register_operand" "")))]
5787 && ((GET_CODE (operands[0]) == REG
5788 && REGNO (operands[0]) < 32)
5789 || (GET_CODE (operands[0]) == SUBREG
5790 && GET_CODE (SUBREG_REG (operands[0])) == REG
5791 && REGNO (SUBREG_REG (operands[0])) < 32))"
5792 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5793 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5794 "if (GET_CODE (operands[0]) == SUBREG)
5795 operands[0] = alter_subreg (operands[0]);
5796 operands[3] = gen_highpart (SImode, operands[0]);
5797 operands[4] = gen_highpart (SImode, operands[1]);
5798 operands[5] = gen_highpart (SImode, operands[2]);
5799 operands[6] = gen_lowpart (SImode, operands[0]);
5800 operands[7] = gen_lowpart (SImode, operands[1]);
5801 operands[8] = gen_lowpart (SImode, operands[2]);")
5803 (define_insn "*and_not_di_sp64"
5804 [(set (match_operand:DI 0 "register_operand" "=r,b")
5805 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5806 (match_operand:DI 2 "register_operand" "r,b")))]
5810 fandnot1\\t%1, %2, %0"
5811 [(set_attr "type" "ialu,fp")
5812 (set_attr "length" "1,1")])
5814 (define_insn "*and_not_si"
5815 [(set (match_operand:SI 0 "register_operand" "=r,d")
5816 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5817 (match_operand:SI 2 "register_operand" "r,d")))]
5821 fandnot1s\\t%1, %2, %0"
5822 [(set_attr "type" "ialu,fp")
5823 (set_attr "length" "1,1")])
5825 (define_expand "iordi3"
5826 [(set (match_operand:DI 0 "register_operand" "")
5827 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5828 (match_operand:DI 2 "arith_double_operand" "")))]
5832 (define_insn "*iordi3_sp32"
5833 [(set (match_operand:DI 0 "register_operand" "=r,b")
5834 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5835 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5840 [(set_attr "type" "ialu,fp")
5841 (set_attr "length" "2,1")])
5843 (define_insn "*iordi3_sp64"
5844 [(set (match_operand:DI 0 "register_operand" "=r,b")
5845 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5846 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5851 [(set_attr "type" "ialu,fp")
5852 (set_attr "length" "1,1")])
5854 (define_insn "iorsi3"
5855 [(set (match_operand:SI 0 "register_operand" "=r,d")
5856 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
5857 (match_operand:SI 2 "arith_operand" "rI,d")))]
5862 [(set_attr "type" "ialu,fp")
5863 (set_attr "length" "1,1")])
5866 [(set (match_operand:SI 0 "register_operand" "")
5867 (ior:SI (match_operand:SI 1 "register_operand" "")
5868 (match_operand:SI 2 "" "")))
5869 (clobber (match_operand:SI 3 "register_operand" ""))]
5870 "GET_CODE (operands[2]) == CONST_INT
5871 && !SMALL_INT32 (operands[2])
5872 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5873 [(set (match_dup 3) (match_dup 4))
5874 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5877 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5880 (define_insn "*or_not_di_sp32"
5881 [(set (match_operand:DI 0 "register_operand" "=r,b")
5882 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5883 (match_operand:DI 2 "register_operand" "r,b")))]
5887 fornot1\\t%1, %2, %0"
5888 [(set_attr "type" "ialu,fp")
5889 (set_attr "length" "2,1")])
5892 [(set (match_operand:DI 0 "register_operand" "")
5893 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5894 (match_operand:DI 2 "register_operand" "")))]
5897 && ((GET_CODE (operands[0]) == REG
5898 && REGNO (operands[0]) < 32)
5899 || (GET_CODE (operands[0]) == SUBREG
5900 && GET_CODE (SUBREG_REG (operands[0])) == REG
5901 && REGNO (SUBREG_REG (operands[0])) < 32))"
5902 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5903 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5904 "if (GET_CODE (operands[0]) == SUBREG)
5905 operands[0] = alter_subreg (operands[0]);
5906 operands[3] = gen_highpart (SImode, operands[0]);
5907 operands[4] = gen_highpart (SImode, operands[1]);
5908 operands[5] = gen_highpart (SImode, operands[2]);
5909 operands[6] = gen_lowpart (SImode, operands[0]);
5910 operands[7] = gen_lowpart (SImode, operands[1]);
5911 operands[8] = gen_lowpart (SImode, operands[2]);")
5913 (define_insn "*or_not_di_sp64"
5914 [(set (match_operand:DI 0 "register_operand" "=r,b")
5915 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5916 (match_operand:DI 2 "register_operand" "r,b")))]
5920 fornot1\\t%1, %2, %0"
5921 [(set_attr "type" "ialu,fp")
5922 (set_attr "length" "1,1")])
5924 (define_insn "*or_not_si"
5925 [(set (match_operand:SI 0 "register_operand" "=r,d")
5926 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5927 (match_operand:SI 2 "register_operand" "r,d")))]
5931 fornot1s\\t%1, %2, %0"
5932 [(set_attr "type" "ialu,fp")
5933 (set_attr "length" "1,1")])
5935 (define_expand "xordi3"
5936 [(set (match_operand:DI 0 "register_operand" "")
5937 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
5938 (match_operand:DI 2 "arith_double_operand" "")))]
5942 (define_insn "*xordi3_sp32"
5943 [(set (match_operand:DI 0 "register_operand" "=r,b")
5944 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5945 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5950 [(set_attr "length" "2,1")
5951 (set_attr "type" "ialu,fp")])
5953 (define_insn "*xordi3_sp64"
5954 [(set (match_operand:DI 0 "register_operand" "=r,b")
5955 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
5956 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5961 [(set_attr "type" "ialu,fp")
5962 (set_attr "length" "1,1")])
5964 (define_insn "*xordi3_sp64_dbl"
5965 [(set (match_operand:DI 0 "register_operand" "=r")
5966 (xor:DI (match_operand:DI 1 "register_operand" "r")
5967 (match_operand:DI 2 "const64_operand" "")))]
5969 && HOST_BITS_PER_WIDE_INT != 64)"
5971 [(set_attr "type" "ialu")
5972 (set_attr "length" "1")])
5974 (define_insn "xorsi3"
5975 [(set (match_operand:SI 0 "register_operand" "=r,d")
5976 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
5977 (match_operand:SI 2 "arith_operand" "rI,d")))]
5982 [(set_attr "type" "ialu,fp")
5983 (set_attr "length" "1,1")])
5986 [(set (match_operand:SI 0 "register_operand" "")
5987 (xor:SI (match_operand:SI 1 "register_operand" "")
5988 (match_operand:SI 2 "" "")))
5989 (clobber (match_operand:SI 3 "register_operand" ""))]
5990 "GET_CODE (operands[2]) == CONST_INT
5991 && !SMALL_INT32 (operands[2])
5992 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5993 [(set (match_dup 3) (match_dup 4))
5994 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5997 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6001 [(set (match_operand:SI 0 "register_operand" "")
6002 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6003 (match_operand:SI 2 "" ""))))
6004 (clobber (match_operand:SI 3 "register_operand" ""))]
6005 "GET_CODE (operands[2]) == CONST_INT
6006 && !SMALL_INT32 (operands[2])
6007 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6008 [(set (match_dup 3) (match_dup 4))
6009 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6012 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6015 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6016 ;; Combine now canonicalizes to the rightmost expression.
6017 (define_insn "*xor_not_di_sp32"
6018 [(set (match_operand:DI 0 "register_operand" "=r,b")
6019 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6020 (match_operand:DI 2 "register_operand" "r,b"))))]
6025 [(set_attr "length" "2,1")
6026 (set_attr "type" "ialu,fp")])
6029 [(set (match_operand:DI 0 "register_operand" "")
6030 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6031 (match_operand:DI 2 "register_operand" ""))))]
6034 && ((GET_CODE (operands[0]) == REG
6035 && REGNO (operands[0]) < 32)
6036 || (GET_CODE (operands[0]) == SUBREG
6037 && GET_CODE (SUBREG_REG (operands[0])) == REG
6038 && REGNO (SUBREG_REG (operands[0])) < 32))"
6039 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6040 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6041 "if (GET_CODE (operands[0]) == SUBREG)
6042 operands[0] = alter_subreg (operands[0]);
6043 operands[3] = gen_highpart (SImode, operands[0]);
6044 operands[4] = gen_highpart (SImode, operands[1]);
6045 operands[5] = gen_highpart (SImode, operands[2]);
6046 operands[6] = gen_lowpart (SImode, operands[0]);
6047 operands[7] = gen_lowpart (SImode, operands[1]);
6048 operands[8] = gen_lowpart (SImode, operands[2]);")
6050 (define_insn "*xor_not_di_sp64"
6051 [(set (match_operand:DI 0 "register_operand" "=r,b")
6052 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6053 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6058 [(set_attr "type" "ialu,fp")
6059 (set_attr "length" "1,1")])
6061 (define_insn "*xor_not_si"
6062 [(set (match_operand:SI 0 "register_operand" "=r,d")
6063 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6064 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6068 fxnors\\t%1, %2, %0"
6069 [(set_attr "type" "ialu,fp")
6070 (set_attr "length" "1,1")])
6072 ;; These correspond to the above in the case where we also (or only)
6073 ;; want to set the condition code.
6075 (define_insn "*cmp_cc_arith_op"
6078 (match_operator:SI 2 "cc_arithop"
6079 [(match_operand:SI 0 "arith_operand" "%r")
6080 (match_operand:SI 1 "arith_operand" "rI")])
6083 "%A2cc\\t%0, %1, %%g0"
6084 [(set_attr "type" "compare")
6085 (set_attr "length" "1")])
6087 (define_insn "*cmp_ccx_arith_op"
6090 (match_operator:DI 2 "cc_arithop"
6091 [(match_operand:DI 0 "arith_double_operand" "%r")
6092 (match_operand:DI 1 "arith_double_operand" "rHI")])
6095 "%A2cc\\t%0, %1, %%g0"
6096 [(set_attr "type" "compare")
6097 (set_attr "length" "1")])
6099 (define_insn "*cmp_cc_arith_op_set"
6102 (match_operator:SI 3 "cc_arithop"
6103 [(match_operand:SI 1 "arith_operand" "%r")
6104 (match_operand:SI 2 "arith_operand" "rI")])
6106 (set (match_operand:SI 0 "register_operand" "=r")
6109 "%A3cc\\t%1, %2, %0"
6110 [(set_attr "type" "compare")
6111 (set_attr "length" "1")])
6113 (define_insn "*cmp_ccx_arith_op_set"
6116 (match_operator:DI 3 "cc_arithop"
6117 [(match_operand:DI 1 "arith_double_operand" "%r")
6118 (match_operand:DI 2 "arith_double_operand" "rHI")])
6120 (set (match_operand:DI 0 "register_operand" "=r")
6123 "%A3cc\\t%1, %2, %0"
6124 [(set_attr "type" "compare")
6125 (set_attr "length" "1")])
6127 (define_insn "*cmp_cc_xor_not"
6130 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6131 (match_operand:SI 1 "arith_operand" "rI")))
6134 "xnorcc\\t%r0, %1, %%g0"
6135 [(set_attr "type" "compare")
6136 (set_attr "length" "1")])
6138 (define_insn "*cmp_ccx_xor_not"
6141 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6142 (match_operand:DI 1 "arith_double_operand" "rHI")))
6145 "xnorcc\\t%r0, %1, %%g0"
6146 [(set_attr "type" "compare")
6147 (set_attr "length" "1")])
6149 (define_insn "*cmp_cc_xor_not_set"
6152 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6153 (match_operand:SI 2 "arith_operand" "rI")))
6155 (set (match_operand:SI 0 "register_operand" "=r")
6156 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6158 "xnorcc\\t%r1, %2, %0"
6159 [(set_attr "type" "compare")
6160 (set_attr "length" "1")])
6162 (define_insn "*cmp_ccx_xor_not_set"
6165 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6166 (match_operand:DI 2 "arith_double_operand" "rHI")))
6168 (set (match_operand:DI 0 "register_operand" "=r")
6169 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6171 "xnorcc\\t%r1, %2, %0"
6172 [(set_attr "type" "compare")
6173 (set_attr "length" "1")])
6175 (define_insn "*cmp_cc_arith_op_not"
6178 (match_operator:SI 2 "cc_arithopn"
6179 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6180 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6183 "%B2cc\\t%r1, %0, %%g0"
6184 [(set_attr "type" "compare")
6185 (set_attr "length" "1")])
6187 (define_insn "*cmp_ccx_arith_op_not"
6190 (match_operator:DI 2 "cc_arithopn"
6191 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6192 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6195 "%B2cc\\t%r1, %0, %%g0"
6196 [(set_attr "type" "compare")
6197 (set_attr "length" "1")])
6199 (define_insn "*cmp_cc_arith_op_not_set"
6202 (match_operator:SI 3 "cc_arithopn"
6203 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6204 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6206 (set (match_operand:SI 0 "register_operand" "=r")
6209 "%B3cc\\t%r2, %1, %0"
6210 [(set_attr "type" "compare")
6211 (set_attr "length" "1")])
6213 (define_insn "*cmp_ccx_arith_op_not_set"
6216 (match_operator:DI 3 "cc_arithopn"
6217 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6218 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6220 (set (match_operand:DI 0 "register_operand" "=r")
6223 "%B3cc\\t%r2, %1, %0"
6224 [(set_attr "type" "compare")
6225 (set_attr "length" "1")])
6227 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6228 ;; does not know how to make it work for constants.
6230 (define_expand "negdi2"
6231 [(set (match_operand:DI 0 "register_operand" "=r")
6232 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6236 if (! TARGET_ARCH64)
6238 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
6239 gen_rtx_SET (VOIDmode, operand0,
6240 gen_rtx_NEG (DImode, operand1)),
6241 gen_rtx_CLOBBER (VOIDmode,
6242 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
6247 (define_insn "*negdi2_sp32"
6248 [(set (match_operand:DI 0 "register_operand" "=r")
6249 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6250 (clobber (reg:CC 100))]
6252 && ! TARGET_LIVE_G0"
6254 [(set_attr "type" "unary")
6255 (set_attr "length" "2")])
6258 [(set (match_operand:DI 0 "register_operand" "")
6259 (neg:DI (match_operand:DI 1 "register_operand" "")))
6260 (clobber (reg:CC 100))]
6263 && reload_completed"
6264 [(parallel [(set (reg:CC_NOOV 100)
6265 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6267 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6268 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6269 (ltu:SI (reg:CC 100) (const_int 0))))]
6270 "operands[2] = gen_highpart (SImode, operands[0]);
6271 operands[3] = gen_highpart (SImode, operands[1]);
6272 operands[4] = gen_lowpart (SImode, operands[0]);
6273 operands[5] = gen_lowpart (SImode, operands[1]);")
6275 (define_insn "*negdi2_sp64"
6276 [(set (match_operand:DI 0 "register_operand" "=r")
6277 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6279 "sub\\t%%g0, %1, %0"
6280 [(set_attr "type" "unary")
6281 (set_attr "length" "1")])
6283 (define_expand "negsi2"
6284 [(set (match_operand:SI 0 "register_operand" "")
6285 (neg:SI (match_operand:SI 1 "arith_operand" "")))]
6291 rtx zero_reg = gen_reg_rtx (SImode);
6293 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6294 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6295 gen_rtx_MINUS (SImode, zero_reg,
6301 (define_insn "*negsi2_not_liveg0"
6302 [(set (match_operand:SI 0 "register_operand" "=r")
6303 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6305 "sub\\t%%g0, %1, %0"
6306 [(set_attr "type" "unary")
6307 (set_attr "length" "1")])
6309 (define_insn "*cmp_cc_neg"
6310 [(set (reg:CC_NOOV 100)
6311 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6314 "subcc\\t%%g0, %0, %%g0"
6315 [(set_attr "type" "compare")
6316 (set_attr "length" "1")])
6318 (define_insn "*cmp_ccx_neg"
6319 [(set (reg:CCX_NOOV 100)
6320 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6323 "subcc\\t%%g0, %0, %%g0"
6324 [(set_attr "type" "compare")
6325 (set_attr "length" "1")])
6327 (define_insn "*cmp_cc_set_neg"
6328 [(set (reg:CC_NOOV 100)
6329 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6331 (set (match_operand:SI 0 "register_operand" "=r")
6332 (neg:SI (match_dup 1)))]
6334 "subcc\\t%%g0, %1, %0"
6335 [(set_attr "type" "compare")
6336 (set_attr "length" "1")])
6338 (define_insn "*cmp_ccx_set_neg"
6339 [(set (reg:CCX_NOOV 100)
6340 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6342 (set (match_operand:DI 0 "register_operand" "=r")
6343 (neg:DI (match_dup 1)))]
6345 "subcc\\t%%g0, %1, %0"
6346 [(set_attr "type" "compare")
6347 (set_attr "length" "1")])
6349 ;; We cannot use the "not" pseudo insn because the Sun assembler
6350 ;; does not know how to make it work for constants.
6351 (define_expand "one_cmpldi2"
6352 [(set (match_operand:DI 0 "register_operand" "")
6353 (not:DI (match_operand:DI 1 "register_operand" "")))]
6357 (define_insn "*one_cmpldi2_sp32"
6358 [(set (match_operand:DI 0 "register_operand" "=r,b")
6359 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6364 [(set_attr "type" "unary,fp")
6365 (set_attr "length" "2,1")])
6368 [(set (match_operand:DI 0 "register_operand" "")
6369 (not:DI (match_operand:DI 1 "register_operand" "")))]
6372 && ((GET_CODE (operands[0]) == REG
6373 && REGNO (operands[0]) < 32)
6374 || (GET_CODE (operands[0]) == SUBREG
6375 && GET_CODE (SUBREG_REG (operands[0])) == REG
6376 && REGNO (SUBREG_REG (operands[0])) < 32))"
6377 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6378 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6379 "if (GET_CODE (operands[0]) == SUBREG)
6380 operands[0] = alter_subreg (operands[0]);
6381 operands[2] = gen_highpart (SImode, operands[0]);
6382 operands[3] = gen_highpart (SImode, operands[1]);
6383 operands[4] = gen_lowpart (SImode, operands[0]);
6384 operands[5] = gen_lowpart (SImode, operands[1]);")
6386 (define_insn "*one_cmpldi2_sp64"
6387 [(set (match_operand:DI 0 "register_operand" "=r,b")
6388 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6393 [(set_attr "type" "unary,fp")
6394 (set_attr "length" "1")])
6396 (define_expand "one_cmplsi2"
6397 [(set (match_operand:SI 0 "register_operand" "")
6398 (not:SI (match_operand:SI 1 "arith_operand" "")))]
6403 && GET_CODE (operands[1]) == CONST_INT)
6405 rtx zero_reg = gen_reg_rtx (SImode);
6407 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6408 emit_insn (gen_rtx_SET (VOIDmode,
6410 gen_rtx_NOT (SImode,
6411 gen_rtx_XOR (SImode,
6418 (define_insn "*one_cmplsi2_not_liveg0"
6419 [(set (match_operand:SI 0 "register_operand" "=r,d")
6420 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6425 [(set_attr "type" "unary,fp")
6426 (set_attr "length" "1,1")])
6428 (define_insn "*one_cmplsi2_liveg0"
6429 [(set (match_operand:SI 0 "register_operand" "=r,d")
6430 (not:SI (match_operand:SI 1 "arith_operand" "r,d")))]
6435 [(set_attr "type" "unary,fp")
6436 (set_attr "length" "1,1")])
6438 (define_insn "*cmp_cc_not"
6440 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6443 "xnorcc\\t%%g0, %0, %%g0"
6444 [(set_attr "type" "compare")
6445 (set_attr "length" "1")])
6447 (define_insn "*cmp_ccx_not"
6449 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6452 "xnorcc\\t%%g0, %0, %%g0"
6453 [(set_attr "type" "compare")
6454 (set_attr "length" "1")])
6456 (define_insn "*cmp_cc_set_not"
6458 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6460 (set (match_operand:SI 0 "register_operand" "=r")
6461 (not:SI (match_dup 1)))]
6463 "xnorcc\\t%%g0, %1, %0"
6464 [(set_attr "type" "compare")
6465 (set_attr "length" "1")])
6467 (define_insn "*cmp_ccx_set_not"
6469 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6471 (set (match_operand:DI 0 "register_operand" "=r")
6472 (not:DI (match_dup 1)))]
6474 "xnorcc\\t%%g0, %1, %0"
6475 [(set_attr "type" "compare")
6476 (set_attr "length" "1")])
6478 ;; Floating point arithmetic instructions.
6480 (define_insn "addtf3"
6481 [(set (match_operand:TF 0 "register_operand" "=e")
6482 (plus:TF (match_operand:TF 1 "register_operand" "e")
6483 (match_operand:TF 2 "register_operand" "e")))]
6484 "TARGET_FPU && TARGET_HARD_QUAD"
6485 "faddq\\t%1, %2, %0"
6486 [(set_attr "type" "fp")
6487 (set_attr "length" "1")])
6489 (define_insn "adddf3"
6490 [(set (match_operand:DF 0 "register_operand" "=e")
6491 (plus:DF (match_operand:DF 1 "register_operand" "e")
6492 (match_operand:DF 2 "register_operand" "e")))]
6494 "faddd\\t%1, %2, %0"
6495 [(set_attr "type" "fp")
6496 (set_attr "length" "1")])
6498 (define_insn "addsf3"
6499 [(set (match_operand:SF 0 "register_operand" "=f")
6500 (plus:SF (match_operand:SF 1 "register_operand" "f")
6501 (match_operand:SF 2 "register_operand" "f")))]
6503 "fadds\\t%1, %2, %0"
6504 [(set_attr "type" "fp")
6505 (set_attr "length" "1")])
6507 (define_insn "subtf3"
6508 [(set (match_operand:TF 0 "register_operand" "=e")
6509 (minus:TF (match_operand:TF 1 "register_operand" "e")
6510 (match_operand:TF 2 "register_operand" "e")))]
6511 "TARGET_FPU && TARGET_HARD_QUAD"
6512 "fsubq\\t%1, %2, %0"
6513 [(set_attr "type" "fp")
6514 (set_attr "length" "1")])
6516 (define_insn "subdf3"
6517 [(set (match_operand:DF 0 "register_operand" "=e")
6518 (minus:DF (match_operand:DF 1 "register_operand" "e")
6519 (match_operand:DF 2 "register_operand" "e")))]
6521 "fsubd\\t%1, %2, %0"
6522 [(set_attr "type" "fp")
6523 (set_attr "length" "1")])
6525 (define_insn "subsf3"
6526 [(set (match_operand:SF 0 "register_operand" "=f")
6527 (minus:SF (match_operand:SF 1 "register_operand" "f")
6528 (match_operand:SF 2 "register_operand" "f")))]
6530 "fsubs\\t%1, %2, %0"
6531 [(set_attr "type" "fp")
6532 (set_attr "length" "1")])
6534 (define_insn "multf3"
6535 [(set (match_operand:TF 0 "register_operand" "=e")
6536 (mult:TF (match_operand:TF 1 "register_operand" "e")
6537 (match_operand:TF 2 "register_operand" "e")))]
6538 "TARGET_FPU && TARGET_HARD_QUAD"
6539 "fmulq\\t%1, %2, %0"
6540 [(set_attr "type" "fpmul")
6541 (set_attr "length" "1")])
6543 (define_insn "muldf3"
6544 [(set (match_operand:DF 0 "register_operand" "=e")
6545 (mult:DF (match_operand:DF 1 "register_operand" "e")
6546 (match_operand:DF 2 "register_operand" "e")))]
6548 "fmuld\\t%1, %2, %0"
6549 [(set_attr "type" "fpmul")
6550 (set_attr "length" "1")])
6552 (define_insn "mulsf3"
6553 [(set (match_operand:SF 0 "register_operand" "=f")
6554 (mult:SF (match_operand:SF 1 "register_operand" "f")
6555 (match_operand:SF 2 "register_operand" "f")))]
6557 "fmuls\\t%1, %2, %0"
6558 [(set_attr "type" "fpmul")
6559 (set_attr "length" "1")])
6561 (define_insn "*muldf3_extend"
6562 [(set (match_operand:DF 0 "register_operand" "=e")
6563 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6564 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6565 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6566 "fsmuld\\t%1, %2, %0"
6567 [(set_attr "type" "fpmul")
6568 (set_attr "length" "1")])
6570 (define_insn "*multf3_extend"
6571 [(set (match_operand:TF 0 "register_operand" "=e")
6572 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6573 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6574 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6575 "fdmulq\\t%1, %2, %0"
6576 [(set_attr "type" "fpmul")
6577 (set_attr "length" "1")])
6579 ;; don't have timing for quad-prec. divide.
6580 (define_insn "divtf3"
6581 [(set (match_operand:TF 0 "register_operand" "=e")
6582 (div:TF (match_operand:TF 1 "register_operand" "e")
6583 (match_operand:TF 2 "register_operand" "e")))]
6584 "TARGET_FPU && TARGET_HARD_QUAD"
6585 "fdivq\\t%1, %2, %0"
6586 [(set_attr "type" "fpdivd")
6587 (set_attr "length" "1")])
6589 (define_insn "divdf3"
6590 [(set (match_operand:DF 0 "register_operand" "=e")
6591 (div:DF (match_operand:DF 1 "register_operand" "e")
6592 (match_operand:DF 2 "register_operand" "e")))]
6594 "fdivd\\t%1, %2, %0"
6595 [(set_attr "type" "fpdivd")
6596 (set_attr "length" "1")])
6598 (define_insn "divsf3"
6599 [(set (match_operand:SF 0 "register_operand" "=f")
6600 (div:SF (match_operand:SF 1 "register_operand" "f")
6601 (match_operand:SF 2 "register_operand" "f")))]
6603 "fdivs\\t%1, %2, %0"
6604 [(set_attr "type" "fpdivs")
6605 (set_attr "length" "1")])
6607 (define_expand "negtf2"
6608 [(set (match_operand:TF 0 "register_operand" "=e,e")
6609 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6613 (define_insn "*negtf2_notv9"
6614 [(set (match_operand:TF 0 "register_operand" "=e,e")
6615 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6616 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6622 [(set_attr "type" "fpmove")
6623 (set_attr "length" "1,2")])
6626 [(set (match_operand:TF 0 "register_operand" "")
6627 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6631 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6632 [(set (match_dup 2) (neg:SF (match_dup 3)))
6633 (set (match_dup 4) (match_dup 5))
6634 (set (match_dup 6) (match_dup 7))]
6635 "if (GET_CODE (operands[0]) == SUBREG)
6636 operands[0] = alter_subreg (operands[0]);
6637 if (GET_CODE (operands[1]) == SUBREG)
6638 operands[1] = alter_subreg (operands[1]);
6639 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6640 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6641 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6642 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6643 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6644 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6646 (define_insn "*negtf2_v9"
6647 [(set (match_operand:TF 0 "register_operand" "=e,e")
6648 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6649 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6650 "TARGET_FPU && TARGET_V9"
6654 [(set_attr "type" "fpmove")
6655 (set_attr "length" "1,2")])
6658 [(set (match_operand:TF 0 "register_operand" "")
6659 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6663 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6664 [(set (match_dup 2) (neg:DF (match_dup 3)))
6665 (set (match_dup 4) (match_dup 5))]
6666 "if (GET_CODE (operands[0]) == SUBREG)
6667 operands[0] = alter_subreg (operands[0]);
6668 if (GET_CODE (operands[1]) == SUBREG)
6669 operands[1] = alter_subreg (operands[1]);
6670 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6671 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6672 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6673 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6675 (define_expand "negdf2"
6676 [(set (match_operand:DF 0 "register_operand" "")
6677 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6681 (define_insn "*negdf2_notv9"
6682 [(set (match_operand:DF 0 "register_operand" "=e,e")
6683 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6684 "TARGET_FPU && ! TARGET_V9"
6688 [(set_attr "type" "fpmove")
6689 (set_attr "length" "1,2")])
6692 [(set (match_operand:DF 0 "register_operand" "")
6693 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6697 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6698 [(set (match_dup 2) (neg:SF (match_dup 3)))
6699 (set (match_dup 4) (match_dup 5))]
6700 "if (GET_CODE (operands[0]) == SUBREG)
6701 operands[0] = alter_subreg (operands[0]);
6702 if (GET_CODE (operands[1]) == SUBREG)
6703 operands[1] = alter_subreg (operands[1]);
6704 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6705 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6706 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6707 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6709 (define_insn "*negdf2_v9"
6710 [(set (match_operand:DF 0 "register_operand" "=e")
6711 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6712 "TARGET_FPU && TARGET_V9"
6714 [(set_attr "type" "fpmove")
6715 (set_attr "length" "1")])
6717 (define_insn "negsf2"
6718 [(set (match_operand:SF 0 "register_operand" "=f")
6719 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6722 [(set_attr "type" "fpmove")
6723 (set_attr "length" "1")])
6725 (define_insn "abstf2"
6726 [(set (match_operand:TF 0 "register_operand" "")
6727 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6731 (define_insn "*abstf2_notv9"
6732 [(set (match_operand:TF 0 "register_operand" "=e,e")
6733 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6734 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6735 "TARGET_FPU && ! TARGET_V9"
6739 [(set_attr "type" "fpmove")
6740 (set_attr "length" "1,2")])
6743 [(set (match_operand:TF 0 "register_operand" "=e,e")
6744 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6748 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6749 [(set (match_dup 2) (abs:SF (match_dup 3)))
6750 (set (match_dup 4) (match_dup 5))
6751 (set (match_dup 6) (match_dup 7))]
6752 "if (GET_CODE (operands[0]) == SUBREG)
6753 operands[0] = alter_subreg (operands[0]);
6754 if (GET_CODE (operands[1]) == SUBREG)
6755 operands[1] = alter_subreg (operands[1]);
6756 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6757 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6758 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6759 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6760 operands[6] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 2);
6761 operands[7] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 2);")
6763 (define_insn "*abstf2_v9"
6764 [(set (match_operand:TF 0 "register_operand" "=e,e")
6765 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6766 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6767 "TARGET_FPU && TARGET_V9"
6771 [(set_attr "type" "fpmove")
6772 (set_attr "length" "1,2")])
6775 [(set (match_operand:TF 0 "register_operand" "=e,e")
6776 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6780 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6781 [(set (match_dup 2) (abs:DF (match_dup 3)))
6782 (set (match_dup 4) (match_dup 5))]
6783 "if (GET_CODE (operands[0]) == SUBREG)
6784 operands[0] = alter_subreg (operands[0]);
6785 if (GET_CODE (operands[1]) == SUBREG)
6786 operands[1] = alter_subreg (operands[1]);
6787 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6788 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6789 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6790 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6792 (define_expand "absdf2"
6793 [(set (match_operand:DF 0 "register_operand" "")
6794 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6798 (define_insn "*absdf2_notv9"
6799 [(set (match_operand:DF 0 "register_operand" "=e,e")
6800 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6801 "TARGET_FPU && ! TARGET_V9"
6805 [(set_attr "type" "fpmove")
6806 (set_attr "length" "1,2")])
6809 [(set (match_operand:DF 0 "register_operand" "=e,e")
6810 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6814 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6815 [(set (match_dup 2) (abs:SF (match_dup 3)))
6816 (set (match_dup 4) (match_dup 5))]
6817 "if (GET_CODE (operands[0]) == SUBREG)
6818 operands[0] = alter_subreg (operands[0]);
6819 if (GET_CODE (operands[1]) == SUBREG)
6820 operands[1] = alter_subreg (operands[1]);
6821 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6822 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6823 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6824 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6826 (define_insn "*absdf2_v9"
6827 [(set (match_operand:DF 0 "register_operand" "=e")
6828 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6829 "TARGET_FPU && TARGET_V9"
6831 [(set_attr "type" "fpmove")
6832 (set_attr "length" "1")])
6834 (define_insn "abssf2"
6835 [(set (match_operand:SF 0 "register_operand" "=f")
6836 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6839 [(set_attr "type" "fpmove")
6840 (set_attr "length" "1")])
6842 (define_insn "sqrttf2"
6843 [(set (match_operand:TF 0 "register_operand" "=e")
6844 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6845 "TARGET_FPU && TARGET_HARD_QUAD"
6847 [(set_attr "type" "fpsqrt")
6848 (set_attr "length" "1")])
6850 (define_insn "sqrtdf2"
6851 [(set (match_operand:DF 0 "register_operand" "=e")
6852 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6855 [(set_attr "type" "fpsqrt")
6856 (set_attr "length" "1")])
6858 (define_insn "sqrtsf2"
6859 [(set (match_operand:SF 0 "register_operand" "=f")
6860 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6863 [(set_attr "type" "fpsqrt")
6864 (set_attr "length" "1")])
6866 ;;- arithmetic shift instructions
6868 (define_insn "ashlsi3"
6869 [(set (match_operand:SI 0 "register_operand" "=r")
6870 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6871 (match_operand:SI 2 "arith_operand" "rI")))]
6875 if (GET_CODE (operands[2]) == CONST_INT
6876 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
6877 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6879 return \"sll\\t%1, %2, %0\";
6881 [(set_attr "type" "shift")
6882 (set_attr "length" "1")])
6884 (define_expand "ashldi3"
6885 [(set (match_operand:DI 0 "register_operand" "=r")
6886 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6887 (match_operand:SI 2 "arith_operand" "rI")))]
6888 "TARGET_ARCH64 || TARGET_V8PLUS"
6891 if (! TARGET_ARCH64)
6893 if (GET_CODE (operands[2]) == CONST_INT)
6895 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6901 [(set (match_operand:DI 0 "register_operand" "=r")
6902 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6903 (match_operand:SI 2 "arith_operand" "rI")))]
6907 if (GET_CODE (operands[2]) == CONST_INT
6908 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
6909 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6911 return \"sllx\\t%1, %2, %0\";
6913 [(set_attr "type" "shift")
6914 (set_attr "length" "1")])
6917 (define_insn "ashldi3_v8plus"
6918 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6919 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6920 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6921 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6923 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
6924 [(set_attr "length" "5,5,6")])
6926 ;; Optimize (1LL<<x)-1
6927 ;; XXX this also needs to be fixed to handle equal subregs
6928 ;; XXX first before we could re-enable it.
6930 [(set (match_operand:DI 0 "register_operand" "=h")
6931 (plus:DI (ashift:DI (const_int 1)
6932 (match_operand:SI 2 "arith_operand" "rI"))
6934 "0 && TARGET_V8PLUS"
6937 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
6938 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
6939 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
6941 [(set_attr "length" "4")])
6943 (define_insn "*cmp_cc_ashift_1"
6944 [(set (reg:CC_NOOV 100)
6945 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6949 "addcc\\t%0, %0, %%g0"
6950 [(set_attr "type" "compare")
6951 (set_attr "length" "1")])
6953 (define_insn "*cmp_cc_set_ashift_1"
6954 [(set (reg:CC_NOOV 100)
6955 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6958 (set (match_operand:SI 0 "register_operand" "=r")
6959 (ashift:SI (match_dup 1) (const_int 1)))]
6961 "addcc\\t%1, %1, %0"
6962 [(set_attr "type" "compare")
6963 (set_attr "length" "1")])
6965 (define_insn "ashrsi3"
6966 [(set (match_operand:SI 0 "register_operand" "=r")
6967 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6968 (match_operand:SI 2 "arith_operand" "rI")))]
6972 if (GET_CODE (operands[2]) == CONST_INT
6973 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
6974 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6976 return \"sra\\t%1, %2, %0\";
6978 [(set_attr "type" "shift")
6979 (set_attr "length" "1")])
6981 (define_expand "ashrdi3"
6982 [(set (match_operand:DI 0 "register_operand" "=r")
6983 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6984 (match_operand:SI 2 "arith_operand" "rI")))]
6985 "TARGET_ARCH64 || TARGET_V8PLUS"
6988 if (! TARGET_ARCH64)
6990 if (GET_CODE (operands[2]) == CONST_INT)
6991 FAIL; /* prefer generic code in this case */
6992 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6998 [(set (match_operand:DI 0 "register_operand" "=r")
6999 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7000 (match_operand:SI 2 "arith_operand" "rI")))]
7004 if (GET_CODE (operands[2]) == CONST_INT
7005 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7006 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7008 return \"srax\\t%1, %2, %0\";
7010 [(set_attr "type" "shift")
7011 (set_attr "length" "1")])
7014 (define_insn "ashrdi3_v8plus"
7015 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7016 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7017 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7018 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7020 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7021 [(set_attr "length" "5,5,6")])
7023 (define_insn "lshrsi3"
7024 [(set (match_operand:SI 0 "register_operand" "=r")
7025 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7026 (match_operand:SI 2 "arith_operand" "rI")))]
7030 if (GET_CODE (operands[2]) == CONST_INT
7031 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7032 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7034 return \"srl\\t%1, %2, %0\";
7036 [(set_attr "type" "shift")
7037 (set_attr "length" "1")])
7039 (define_expand "lshrdi3"
7040 [(set (match_operand:DI 0 "register_operand" "=r")
7041 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7042 (match_operand:SI 2 "arith_operand" "rI")))]
7043 "TARGET_ARCH64 || TARGET_V8PLUS"
7046 if (! TARGET_ARCH64)
7048 if (GET_CODE (operands[2]) == CONST_INT)
7050 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7056 [(set (match_operand:DI 0 "register_operand" "=r")
7057 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7058 (match_operand:SI 2 "arith_operand" "rI")))]
7062 if (GET_CODE (operands[2]) == CONST_INT
7063 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7064 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7066 return \"srlx\\t%1, %2, %0\";
7068 [(set_attr "type" "shift")
7069 (set_attr "length" "1")])
7072 (define_insn "lshrdi3_v8plus"
7073 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7074 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7075 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7076 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7078 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7079 [(set_attr "length" "5,5,6")])
7081 ;; Unconditional and other jump instructions
7082 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7083 ;; following insn is never executed. This saves us a nop. Dbx does not
7084 ;; handle such branches though, so we only use them when optimizing.
7086 [(set (pc) (label_ref (match_operand 0 "" "")))]
7090 /* TurboSparc is reported to have problems with
7093 i.e. an empty loop with the annul bit set. The workaround is to use
7097 if (! TARGET_V9 && flag_delayed_branch
7098 && (insn_addresses[INSN_UID (operands[0])]
7099 == insn_addresses[INSN_UID (insn)]))
7100 return \"b\\t%l0%#\";
7102 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7104 [(set_attr "type" "uncond_branch")])
7106 (define_expand "tablejump"
7107 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7108 (use (label_ref (match_operand 1 "" "")))])]
7112 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7115 /* In pic mode, our address differences are against the base of the
7116 table. Add that base value back in; CSE ought to be able to combine
7117 the two address loads. */
7121 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7123 if (CASE_VECTOR_MODE != Pmode)
7124 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7125 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7126 operands[0] = memory_address (Pmode, tmp);
7130 (define_insn "*tablejump_sp32"
7131 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7132 (use (label_ref (match_operand 1 "" "")))]
7135 [(set_attr "type" "uncond_branch")])
7137 (define_insn "*tablejump_sp64"
7138 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7139 (use (label_ref (match_operand 1 "" "")))]
7142 [(set_attr "type" "uncond_branch")])
7144 ;; This pattern recognizes the "instruction" that appears in
7145 ;; a function call that wants a structure value,
7146 ;; to inform the called function if compiled with Sun CC.
7147 ;(define_insn "*unimp_insn"
7148 ; [(match_operand:SI 0 "immediate_operand" "")]
7149 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7151 ; [(set_attr "type" "marker")])
7153 ;;- jump to subroutine
7154 (define_expand "call"
7155 ;; Note that this expression is not used for generating RTL.
7156 ;; All the RTL is generated explicitly below.
7157 [(call (match_operand 0 "call_operand" "")
7158 (match_operand 3 "" "i"))]
7159 ;; operands[2] is next_arg_register
7160 ;; operands[3] is struct_value_size_rtx.
7164 rtx fn_rtx, nregs_rtx;
7166 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7169 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7171 /* This is really a PIC sequence. We want to represent
7172 it as a funny jump so its delay slots can be filled.
7174 ??? But if this really *is* a CALL, will not it clobber the
7175 call-clobbered registers? We lose this if it is a JUMP_INSN.
7176 Why cannot we have delay slots filled if it were a CALL? */
7178 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7180 (gen_rtx_PARALLEL (VOIDmode,
7182 gen_rtx_SET (VOIDmode, pc_rtx,
7183 XEXP (operands[0], 0)),
7184 GEN_INT (INTVAL (operands[3]) & 0xfff),
7185 gen_rtx_CLOBBER (VOIDmode,
7186 gen_rtx_REG (Pmode, 15)))));
7189 (gen_rtx_PARALLEL (VOIDmode,
7191 gen_rtx_SET (VOIDmode, pc_rtx,
7192 XEXP (operands[0], 0)),
7193 gen_rtx_CLOBBER (VOIDmode,
7194 gen_rtx_REG (Pmode, 15)))));
7198 fn_rtx = operands[0];
7200 /* Count the number of parameter registers being used by this call.
7201 if that argument is NULL, it means we are using them all, which
7202 means 6 on the sparc. */
7205 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7207 nregs_rtx = GEN_INT (6);
7209 nregs_rtx = const0_rtx;
7212 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7214 (gen_rtx_PARALLEL (VOIDmode,
7215 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7216 GEN_INT (INTVAL (operands[3]) & 0xfff),
7217 gen_rtx_CLOBBER (VOIDmode,
7218 gen_rtx_REG (Pmode, 15)))));
7221 (gen_rtx_PARALLEL (VOIDmode,
7222 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7223 gen_rtx_CLOBBER (VOIDmode,
7224 gen_rtx_REG (Pmode, 15)))));
7228 /* If this call wants a structure value,
7229 emit an unimp insn to let the called function know about this. */
7230 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7232 rtx insn = emit_insn (operands[3]);
7233 SCHED_GROUP_P (insn) = 1;
7240 ;; We can't use the same pattern for these two insns, because then registers
7241 ;; in the address may not be properly reloaded.
7243 (define_insn "*call_address_sp32"
7244 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7245 (match_operand 1 "" ""))
7246 (clobber (reg:SI 15))]
7247 ;;- Do not use operand 1 for most machines.
7250 [(set_attr "type" "call")])
7252 (define_insn "*call_symbolic_sp32"
7253 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7254 (match_operand 1 "" ""))
7255 (clobber (reg:SI 15))]
7256 ;;- Do not use operand 1 for most machines.
7259 [(set_attr "type" "call")])
7261 (define_insn "*call_address_sp64"
7262 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
7263 (match_operand 1 "" ""))
7264 (clobber (reg:DI 15))]
7265 ;;- Do not use operand 1 for most machines.
7268 [(set_attr "type" "call")])
7270 (define_insn "*call_symbolic_sp64"
7271 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
7272 (match_operand 1 "" ""))
7273 (clobber (reg:DI 15))]
7274 ;;- Do not use operand 1 for most machines.
7277 [(set_attr "type" "call")])
7279 ;; This is a call that wants a structure value.
7280 ;; There is no such critter for v9 (??? we may need one anyway).
7281 (define_insn "*call_address_struct_value_sp32"
7282 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7283 (match_operand 1 "" ""))
7284 (match_operand 2 "immediate_operand" "")
7285 (clobber (reg:SI 15))]
7286 ;;- Do not use operand 1 for most machines.
7287 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7288 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7289 [(set_attr "type" "call_no_delay_slot")])
7291 ;; This is a call that wants a structure value.
7292 ;; There is no such critter for v9 (??? we may need one anyway).
7293 (define_insn "*call_symbolic_struct_value_sp32"
7294 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7295 (match_operand 1 "" ""))
7296 (match_operand 2 "immediate_operand" "")
7297 (clobber (reg:SI 15))]
7298 ;;- Do not use operand 1 for most machines.
7299 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7300 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7301 [(set_attr "type" "call_no_delay_slot")])
7303 ;; This is a call that may want a structure value. This is used for
7305 (define_insn "*call_address_untyped_struct_value_sp32"
7306 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7307 (match_operand 1 "" ""))
7308 (match_operand 2 "immediate_operand" "")
7309 (clobber (reg:SI 15))]
7310 ;;- Do not use operand 1 for most machines.
7311 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7312 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7313 [(set_attr "type" "call_no_delay_slot")])
7315 ;; This is a call that wants a structure value.
7316 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7317 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7318 (match_operand 1 "" ""))
7319 (match_operand 2 "immediate_operand" "")
7320 (clobber (reg:SI 15))]
7321 ;;- Do not use operand 1 for most machines.
7322 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7323 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7324 [(set_attr "type" "call_no_delay_slot")])
7326 (define_expand "call_value"
7327 ;; Note that this expression is not used for generating RTL.
7328 ;; All the RTL is generated explicitly below.
7329 [(set (match_operand 0 "register_operand" "=rf")
7330 (call (match_operand:SI 1 "" "")
7331 (match_operand 4 "" "")))]
7332 ;; operand 2 is stack_size_rtx
7333 ;; operand 3 is next_arg_register
7337 rtx fn_rtx, nregs_rtx;
7340 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7343 fn_rtx = operands[1];
7347 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7349 nregs_rtx = GEN_INT (6);
7351 nregs_rtx = const0_rtx;
7355 gen_rtx_SET (VOIDmode, operands[0],
7356 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7357 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7359 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7364 (define_insn "*call_value_address_sp32"
7365 [(set (match_operand 0 "" "=rf")
7366 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7367 (match_operand 2 "" "")))
7368 (clobber (reg:SI 15))]
7369 ;;- Do not use operand 2 for most machines.
7372 [(set_attr "type" "call")])
7374 (define_insn "*call_value_symbolic_sp32"
7375 [(set (match_operand 0 "" "=rf")
7376 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7377 (match_operand 2 "" "")))
7378 (clobber (reg:SI 15))]
7379 ;;- Do not use operand 2 for most machines.
7382 [(set_attr "type" "call")])
7384 (define_insn "*call_value_address_sp64"
7385 [(set (match_operand 0 "" "")
7386 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
7387 (match_operand 2 "" "")))
7388 (clobber (reg:DI 15))]
7389 ;;- Do not use operand 2 for most machines.
7392 [(set_attr "type" "call")])
7394 (define_insn "*call_value_symbolic_sp64"
7395 [(set (match_operand 0 "" "")
7396 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
7397 (match_operand 2 "" "")))
7398 (clobber (reg:DI 15))]
7399 ;;- Do not use operand 2 for most machines.
7402 [(set_attr "type" "call")])
7404 (define_expand "untyped_call"
7405 [(parallel [(call (match_operand 0 "" "")
7407 (match_operand 1 "" "")
7408 (match_operand 2 "" "")])]
7414 /* Pass constm1 to indicate that it may expect a structure value, but
7415 we don't know what size it is. */
7416 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7418 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7420 rtx set = XVECEXP (operands[2], 0, i);
7421 emit_move_insn (SET_DEST (set), SET_SRC (set));
7424 /* The optimizer does not know that the call sets the function value
7425 registers we stored in the result block. We avoid problems by
7426 claiming that all hard registers are used and clobbered at this
7428 emit_insn (gen_blockage ());
7433 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7434 ;; all of memory. This blocks insns from being moved across this point.
7436 (define_insn "blockage"
7437 [(unspec_volatile [(const_int 0)] 0)]
7441 ;; Prepare to return any type including a structure value.
7443 (define_expand "untyped_return"
7444 [(match_operand:BLK 0 "memory_operand" "")
7445 (match_operand 1 "" "")]
7449 rtx valreg1 = gen_rtx_REG (DImode, 24);
7450 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7451 rtx result = operands[0];
7453 if (! TARGET_ARCH64)
7455 rtx rtnreg = gen_rtx_REG (SImode, (leaf_function ? 15 : 31));
7456 rtx value = gen_reg_rtx (SImode);
7458 /* Fetch the instruction where we will return to and see if it's an unimp
7459 instruction (the most significant 10 bits will be zero). If so,
7460 update the return address to skip the unimp instruction. */
7461 emit_move_insn (value,
7462 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7463 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7464 emit_insn (gen_update_return (rtnreg, value));
7467 /* Reload the function value registers. */
7468 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
7469 emit_move_insn (valreg2,
7470 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
7471 plus_constant (XEXP (result, 0), 8)));
7473 /* Put USE insns before the return. */
7474 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7475 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7477 /* Construct the return. */
7478 expand_null_return ();
7483 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7484 ;; and parts of the compiler don't want to believe that the add is needed.
7486 (define_insn "update_return"
7487 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7488 (match_operand:SI 1 "register_operand" "r")] 1)]
7490 "cmp %1,0\;be,a .+8\;add %0,4,%0"
7491 [(set_attr "type" "multi")])
7493 (define_insn "return"
7497 "* return output_return (operands);"
7498 [(set_attr "type" "return")])
7501 [(set (match_operand:SI 0 "register_operand" "=r")
7502 (match_operand:SI 1 "arith_operand" "rI"))
7504 (use (reg:SI 31))])]
7505 "sparc_return_peephole_ok (operands[0], operands[1])"
7506 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
7512 [(set_attr "type" "ialu")
7513 (set_attr "length" "1")])
7515 (define_expand "indirect_jump"
7516 [(set (pc) (match_operand 0 "address_operand" "p"))]
7520 (define_insn "*branch_sp32"
7521 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7524 [(set_attr "type" "uncond_branch")])
7526 (define_insn "*branch_sp64"
7527 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7530 [(set_attr "type" "uncond_branch")])
7532 ;; ??? Doesn't work with -mflat.
7533 (define_expand "nonlocal_goto"
7534 [(match_operand:SI 0 "general_operand" "")
7535 (match_operand:SI 1 "general_operand" "")
7536 (match_operand:SI 2 "general_operand" "")
7537 (match_operand:SI 3 "" "")]
7541 rtx chain = operands[0];
7542 rtx fp = operands[1];
7543 rtx stack = operands[2];
7544 rtx lab = operands[3];
7547 /* Trap instruction to flush all the register windows. */
7548 emit_insn (gen_flush_register_windows ());
7550 /* Load the fp value for the containing fn into %fp. This is needed
7551 because STACK refers to %fp. Note that virtual register instantiation
7552 fails if the virtual %fp isn't set from a register. */
7553 if (GET_CODE (fp) != REG)
7554 fp = force_reg (Pmode, fp);
7555 emit_move_insn (virtual_stack_vars_rtx, fp);
7557 /* Find the containing function's current nonlocal goto handler,
7558 which will do any cleanups and then jump to the label. */
7559 labreg = gen_rtx_REG (Pmode, 8);
7560 emit_move_insn (labreg, lab);
7562 /* Restore %fp from stack pointer value for containing function.
7563 The restore insn that follows will move this to %sp,
7564 and reload the appropriate value into %fp. */
7565 emit_move_insn (frame_pointer_rtx, stack);
7567 /* USE of frame_pointer_rtx added for consistency; not clear if
7569 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7570 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7571 /* Return, restoring reg window and jumping to goto handler. */
7572 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7573 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7575 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
7580 /* Put in the static chain register the nonlocal label address. */
7581 emit_move_insn (static_chain_rtx, chain);
7582 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7583 emit_insn (gen_goto_handler_and_restore (labreg));
7588 ;; Special trap insn to flush register windows.
7589 (define_insn "flush_register_windows"
7590 [(unspec_volatile [(const_int 0)] 1)]
7592 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
7593 [(set_attr "type" "misc")
7594 (set_attr "length" "1")])
7596 (define_insn "goto_handler_and_restore"
7597 [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r")] 2)]
7599 "jmp\\t%0+0\\n\\trestore"
7600 [(set_attr "type" "misc")
7601 (set_attr "length" "2")])
7603 (define_insn "goto_handler_and_restore_v9"
7604 [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7605 (match_operand:SI 1 "register_operand" "=r,r")
7606 (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7607 "TARGET_V9 && ! TARGET_ARCH64"
7609 return\\t%0+0\\n\\tmov\\t%2, %Y1
7610 sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7611 [(set_attr "type" "misc")
7612 (set_attr "length" "2,3")])
7614 (define_insn "*goto_handler_and_restore_v9_sp64"
7615 [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7616 (match_operand:DI 1 "register_operand" "=r,r")
7617 (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7618 "TARGET_V9 && TARGET_ARCH64"
7620 return\\t%0+0\\n\\tmov\\t%2, %Y1
7621 sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7622 [(set_attr "type" "misc")
7623 (set_attr "length" "2,3")])
7625 ;; Pattern for use after a setjmp to store FP and the return register
7626 ;; into the stack area.
7628 (define_expand "setjmp"
7634 emit_insn (gen_setjmp_64 ());
7636 emit_insn (gen_setjmp_32 ());
7640 (define_expand "setjmp_32"
7641 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7642 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7645 { operands[0] = frame_pointer_rtx; }")
7647 (define_expand "setjmp_64"
7648 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7649 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7652 { operands[0] = frame_pointer_rtx; }")
7654 ;; Special pattern for the FLUSH instruction.
7656 (define_insn "flush"
7657 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 4)]
7659 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
7660 [(set_attr "type" "misc")
7661 (set_attr "length" "1")])
7665 ;; The scan instruction searches from the most significant bit while ffs
7666 ;; searches from the least significant bit. The bit index and treatment of
7667 ;; zero also differ. It takes at least 7 instructions to get the proper
7668 ;; result. Here is an obvious 8 instruction sequence.
7671 (define_insn "ffssi2"
7672 [(set (match_operand:SI 0 "register_operand" "=&r")
7673 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7674 (clobber (match_scratch:SI 2 "=&r"))]
7675 "TARGET_SPARCLITE || TARGET_SPARCLET"
7679 output_asm_insn (\"and %%g0,0,%%g0\", operands);
7680 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\";
7682 [(set_attr "type" "multi")
7683 (set_attr "length" "8")])
7685 ;; ??? This should be a define expand, so that the extra instruction have
7686 ;; a chance of being optimized away.
7688 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
7689 ;; does, but no one uses that and we don't have a switch for it.
7691 ;(define_insn "ffsdi2"
7692 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7693 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7694 ; (clobber (match_scratch:DI 2 "=&r"))]
7696 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
7697 ; [(set_attr "type" "multi")
7698 ; (set_attr "length" "4")])
7701 ;; Peepholes go at the end.
7703 ;; Optimize consecutive loads or stores into ldd and std when possible.
7704 ;; The conditions in which we do this are very restricted and are
7705 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7708 [(set (match_operand:SI 0 "memory_operand" "")
7710 (set (match_operand:SI 1 "memory_operand" "")
7713 && ! MEM_VOLATILE_P (operands[0])
7714 && ! MEM_VOLATILE_P (operands[1])
7715 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
7719 [(set (match_operand:SI 0 "memory_operand" "")
7721 (set (match_operand:SI 1 "memory_operand" "")
7724 && ! MEM_VOLATILE_P (operands[0])
7725 && ! MEM_VOLATILE_P (operands[1])
7726 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
7730 [(set (match_operand:SI 0 "register_operand" "=rf")
7731 (match_operand:SI 1 "memory_operand" ""))
7732 (set (match_operand:SI 2 "register_operand" "=rf")
7733 (match_operand:SI 3 "memory_operand" ""))]
7734 "registers_ok_for_ldd_peep (operands[0], operands[2])
7735 && ! MEM_VOLATILE_P (operands[1])
7736 && ! MEM_VOLATILE_P (operands[3])
7737 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7741 [(set (match_operand:SI 0 "memory_operand" "")
7742 (match_operand:SI 1 "register_operand" "rf"))
7743 (set (match_operand:SI 2 "memory_operand" "")
7744 (match_operand:SI 3 "register_operand" "rf"))]
7745 "registers_ok_for_ldd_peep (operands[1], operands[3])
7746 && ! MEM_VOLATILE_P (operands[0])
7747 && ! MEM_VOLATILE_P (operands[2])
7748 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
7752 [(set (match_operand:SF 0 "register_operand" "=fr")
7753 (match_operand:SF 1 "memory_operand" ""))
7754 (set (match_operand:SF 2 "register_operand" "=fr")
7755 (match_operand:SF 3 "memory_operand" ""))]
7756 "registers_ok_for_ldd_peep (operands[0], operands[2])
7757 && ! MEM_VOLATILE_P (operands[1])
7758 && ! MEM_VOLATILE_P (operands[3])
7759 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7763 [(set (match_operand:SF 0 "memory_operand" "")
7764 (match_operand:SF 1 "register_operand" "fr"))
7765 (set (match_operand:SF 2 "memory_operand" "")
7766 (match_operand:SF 3 "register_operand" "fr"))]
7767 "registers_ok_for_ldd_peep (operands[1], operands[3])
7768 && ! MEM_VOLATILE_P (operands[0])
7769 && ! MEM_VOLATILE_P (operands[2])
7770 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
7774 [(set (match_operand:SI 0 "register_operand" "=rf")
7775 (match_operand:SI 1 "memory_operand" ""))
7776 (set (match_operand:SI 2 "register_operand" "=rf")
7777 (match_operand:SI 3 "memory_operand" ""))]
7778 "registers_ok_for_ldd_peep (operands[2], operands[0])
7779 && ! MEM_VOLATILE_P (operands[3])
7780 && ! MEM_VOLATILE_P (operands[1])
7781 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
7785 [(set (match_operand:SI 0 "memory_operand" "")
7786 (match_operand:SI 1 "register_operand" "rf"))
7787 (set (match_operand:SI 2 "memory_operand" "")
7788 (match_operand:SI 3 "register_operand" "rf"))]
7789 "registers_ok_for_ldd_peep (operands[3], operands[1])
7790 && ! MEM_VOLATILE_P (operands[2])
7791 && ! MEM_VOLATILE_P (operands[0])
7792 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
7796 [(set (match_operand:SF 0 "register_operand" "=fr")
7797 (match_operand:SF 1 "memory_operand" ""))
7798 (set (match_operand:SF 2 "register_operand" "=fr")
7799 (match_operand:SF 3 "memory_operand" ""))]
7800 "registers_ok_for_ldd_peep (operands[2], operands[0])
7801 && ! MEM_VOLATILE_P (operands[3])
7802 && ! MEM_VOLATILE_P (operands[1])
7803 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
7807 [(set (match_operand:SF 0 "memory_operand" "")
7808 (match_operand:SF 1 "register_operand" "fr"))
7809 (set (match_operand:SF 2 "memory_operand" "")
7810 (match_operand:SF 3 "register_operand" "fr"))]
7811 "registers_ok_for_ldd_peep (operands[3], operands[1])
7812 && ! MEM_VOLATILE_P (operands[2])
7813 && ! MEM_VOLATILE_P (operands[0])
7814 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
7817 ;; Optimize the case of following a reg-reg move with a test
7818 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7819 ;; This can result from a float to fix conversion.
7822 [(set (match_operand:SI 0 "register_operand" "=r")
7823 (match_operand:SI 1 "register_operand" "r"))
7825 (compare:CC (match_operand:SI 2 "register_operand" "r")
7827 "(rtx_equal_p (operands[2], operands[0])
7828 || rtx_equal_p (operands[2], operands[1]))
7829 && ! FP_REG_P (operands[0])
7830 && ! FP_REG_P (operands[1])"
7834 [(set (match_operand:DI 0 "register_operand" "=r")
7835 (match_operand:DI 1 "register_operand" "r"))
7837 (compare:CCX (match_operand:DI 2 "register_operand" "r")
7840 && (rtx_equal_p (operands[2], operands[0])
7841 || rtx_equal_p (operands[2], operands[1]))
7842 && ! FP_REG_P (operands[0])
7843 && ! FP_REG_P (operands[1])"
7846 ;; Return peepholes. First the "normal" ones.
7847 ;; These are necessary to catch insns ending up in the epilogue delay list.
7849 (define_insn "*return_qi"
7850 [(set (match_operand:QI 0 "restore_operand" "")
7851 (match_operand:QI 1 "arith_operand" "rI"))
7853 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7856 if (! TARGET_ARCH64 && current_function_returns_struct)
7857 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7858 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
7859 || IN_OR_GLOBAL_P (operands[1])))
7860 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7862 return \"ret\\n\\trestore %%g0, %1, %Y0\";
7864 [(set_attr "type" "multi")])
7866 (define_insn "*return_hi"
7867 [(set (match_operand:HI 0 "restore_operand" "")
7868 (match_operand:HI 1 "arith_operand" "rI"))
7870 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7873 if (! TARGET_ARCH64 && current_function_returns_struct)
7874 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7875 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
7876 || IN_OR_GLOBAL_P (operands[1])))
7877 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7879 return \"ret\;restore %%g0, %1, %Y0\";
7881 [(set_attr "type" "multi")])
7883 (define_insn "*return_si"
7884 [(set (match_operand:SI 0 "restore_operand" "")
7885 (match_operand:SI 1 "arith_operand" "rI"))
7887 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7890 if (! TARGET_ARCH64 && current_function_returns_struct)
7891 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7892 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
7893 || IN_OR_GLOBAL_P (operands[1])))
7894 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7896 return \"ret\;restore %%g0, %1, %Y0\";
7898 [(set_attr "type" "multi")])
7900 ;; The following pattern is only generated by delayed-branch scheduling,
7901 ;; when the insn winds up in the epilogue. This can happen not only when
7902 ;; ! TARGET_FPU because we move complex types around by parts using
7904 (define_insn "*return_sf_no_fpu"
7905 [(set (match_operand:SF 0 "restore_operand" "r")
7906 (match_operand:SF 1 "register_operand" "r"))
7908 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7911 if (! TARGET_ARCH64 && current_function_returns_struct)
7912 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7913 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
7914 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7916 return \"ret\;restore %%g0, %1, %Y0\";
7918 [(set_attr "type" "multi")])
7920 (define_insn "*return_addsi"
7921 [(set (match_operand:SI 0 "restore_operand" "")
7922 (plus:SI (match_operand:SI 1 "register_operand" "r")
7923 (match_operand:SI 2 "arith_operand" "rI")))
7925 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7928 if (! TARGET_ARCH64 && current_function_returns_struct)
7929 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
7930 /* If operands are global or in registers, can use return */
7931 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
7932 && (GET_CODE (operands[2]) == CONST_INT
7933 || IN_OR_GLOBAL_P (operands[2])))
7934 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
7936 return \"ret\;restore %r1, %2, %Y0\";
7938 [(set_attr "type" "multi")])
7940 (define_insn "*return_di"
7941 [(set (match_operand:DI 0 "restore_operand" "")
7942 (match_operand:DI 1 "arith_double_operand" "rHI"))
7944 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
7945 "ret\;restore %%g0, %1, %Y0"
7946 [(set_attr "type" "multi")])
7948 (define_insn "*return_adddi"
7949 [(set (match_operand:DI 0 "restore_operand" "")
7950 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
7951 (match_operand:DI 2 "arith_double_operand" "rHI")))
7953 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
7954 "ret\;restore %r1, %2, %Y0"
7955 [(set_attr "type" "multi")])
7957 ;; The following pattern is only generated by delayed-branch scheduling,
7958 ;; when the insn winds up in the epilogue.
7959 (define_insn "*return_sf"
7961 (match_operand:SF 0 "register_operand" "f"))
7964 "ret\;fmovs\\t%0, %%f0"
7965 [(set_attr "type" "multi")])
7967 ;; Now peepholes to do a call followed by a jump.
7970 [(parallel [(set (match_operand 0 "" "")
7971 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
7972 (match_operand 2 "" "")))
7973 (clobber (reg:SI 15))])
7974 (set (pc) (label_ref (match_operand 3 "" "")))]
7975 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
7976 && in_same_eh_region (insn, operands[3])
7977 && in_same_eh_region (insn, ins1)"
7978 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
7981 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
7982 (match_operand 1 "" ""))
7983 (clobber (reg:SI 15))])
7984 (set (pc) (label_ref (match_operand 2 "" "")))]
7985 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
7986 && in_same_eh_region (insn, operands[2])
7987 && in_same_eh_region (insn, ins1)"
7988 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
7991 [(parallel [(set (match_operand 0 "" "")
7992 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
7993 (match_operand 2 "" "")))
7994 (clobber (reg:DI 15))])
7995 (set (pc) (label_ref (match_operand 3 "" "")))]
7997 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
7998 && in_same_eh_region (insn, operands[3])
7999 && in_same_eh_region (insn, ins1)"
8000 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8003 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
8004 (match_operand 1 "" ""))
8005 (clobber (reg:DI 15))])
8006 (set (pc) (label_ref (match_operand 2 "" "")))]
8008 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8009 && in_same_eh_region (insn, operands[2])
8010 && in_same_eh_region (insn, ins1)"
8011 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8013 ;; After a nonlocal goto, we need to restore the PIC register, but only
8014 ;; if we need it. So do nothing much here, but we'll check for this in
8017 ;; Make sure this unspec_volatile number agrees with finalize_pic.
8018 (define_insn "nonlocal_goto_receiver"
8019 [(unspec_volatile [(const_int 0)] 5)]
8024 [(trap_if (const_int 1) (const_int 5))]
8027 [(set_attr "type" "misc")
8028 (set_attr "length" "1")])
8030 (define_expand "conditional_trap"
8031 [(trap_if (match_operator 0 "noov_compare_op"
8032 [(match_dup 2) (match_dup 3)])
8033 (match_operand:SI 1 "arith_operand" ""))]
8035 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8036 sparc_compare_op0, sparc_compare_op1);
8037 operands[3] = const0_rtx;")
8040 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8041 (match_operand:SI 1 "arith_operand" "rM"))]
8044 [(set_attr "type" "misc")
8045 (set_attr "length" "1")])
8048 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8049 (match_operand:SI 1 "arith_operand" "rM"))]
8052 [(set_attr "type" "misc")
8053 (set_attr "length" "1")])