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,2,2")])
2952 ;; ?? This and split disabled on sparc64... When I change the destination
2953 ;; ?? reg to be DImode to emit the constant formation code, the instruction
2954 ;; ?? scheduler does not want to believe that it is the same as the DFmode
2955 ;; ?? subreg we started with... See the SFmode version of this above to
2956 ;; ?? see how it can be handled.
2957 (define_insn "*movdf_const_intreg_sp64"
2958 [(set (match_operand:DF 0 "general_operand" "=e,e,r")
2959 (match_operand:DF 1 "" "m,o,F"))]
2960 "0 && TARGET_FPU && TARGET_ARCH64
2961 && GET_CODE (operands[1]) == CONST_DOUBLE
2962 && GET_CODE (operands[0]) == REG"
2965 if (which_alternative == 0)
2966 return \"ldd\\t%1, %0\";
2970 [(set_attr "type" "move")
2971 (set_attr "length" "1")])
2974 [(set (match_operand:DF 0 "register_operand" "")
2975 (match_operand:DF 1 "const_double_operand" ""))]
2978 && GET_CODE (operands[1]) == CONST_DOUBLE
2979 && (GET_CODE (operands[0]) == REG
2980 && REGNO (operands[0]) < 32)
2981 && reload_completed"
2982 [(clobber (const_int 0))]
2988 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2989 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2990 if (GET_CODE (operands[0]) == SUBREG)
2991 operands[0] = alter_subreg (operands[0]);
2992 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2996 #if HOST_BITS_PER_WIDE_INT == 64
2999 val = ((HOST_WIDE_INT)l[1] |
3000 ((HOST_WIDE_INT)l[0] << 32));
3001 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3003 emit_insn (gen_movdi (operands[0],
3004 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3010 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3013 /* Slick... but this trick loses if this subreg constant part
3014 can be done in one insn. */
3016 && !(SPARC_SETHI_P (l[0])
3017 || SPARC_SIMM13_P (l[0])))
3019 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3020 gen_highpart (SImode, operands[0])));
3024 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3031 (define_expand "movdf"
3032 [(set (match_operand:DF 0 "general_operand" "")
3033 (match_operand:DF 1 "general_operand" ""))]
3037 /* Force DFmode constants into memory. */
3038 if (GET_CODE (operands[0]) == REG
3039 && CONSTANT_P (operands[1]))
3042 && GET_CODE (operands[1]) == CONST_DOUBLE
3043 && fp_zero_operand (operands[1]))
3046 /* emit_group_store will send such bogosity to us when it is
3047 not storing directly into memory. So fix this up to avoid
3048 crashes in output_constant_pool. */
3049 if (operands [1] == const0_rtx)
3050 operands[1] = CONST0_RTX (DFmode);
3051 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3055 /* Handle MEM cases first. */
3056 if (GET_CODE (operands[0]) == MEM)
3058 if (register_operand (operands[1], DFmode))
3061 if (! reload_in_progress)
3063 operands[0] = validize_mem (operands[0]);
3064 operands[1] = force_reg (DFmode, operands[1]);
3068 /* Fixup PIC cases. */
3071 if (CONSTANT_P (operands[1])
3072 && pic_address_needs_scratch (operands[1]))
3073 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3075 if (symbolic_operand (operands[1], DFmode))
3077 operands[1] = legitimize_pic_address (operands[1],
3079 (reload_in_progress ?
3089 ;; Be careful, fmovd does not exist when !v9.
3090 (define_insn "*movdf_insn_sp32"
3091 [(set (match_operand:DF 0 "general_operand" "=e,T,U,T,e,r,r,o,e,o")
3092 (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))]
3095 && (register_operand (operands[0], DFmode)
3096 || register_operand (operands[1], DFmode))"
3108 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3109 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3111 (define_insn "*movdf_no_e_insn_sp32"
3112 [(set (match_operand:DF 0 "general_operand" "=U,T,r,r,o")
3113 (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
3116 && (register_operand (operands[0], DFmode)
3117 || register_operand (operands[1], DFmode))"
3124 [(set_attr "type" "load,store,*,*,*")
3125 (set_attr "length" "1,1,2,2,2")])
3127 ;; We have available v9 double floats but not 64-bit
3128 ;; integer registers.
3129 (define_insn "*movdf_insn_v9only"
3130 [(set (match_operand:DF 0 "general_operand" "=e,e,m,U,T,r,r,o")
3131 (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
3135 && (register_operand (operands[0], DFmode)
3136 || register_operand (operands[1], DFmode))"
3146 [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
3147 (set_attr "length" "1,1,1,1,1,2,2,2")])
3149 ;; We have available both v9 double floats and 64-bit
3150 ;; integer registers.
3151 (define_insn "*movdf_insn_sp64"
3152 [(set (match_operand:DF 0 "general_operand" "=e,e,m,r,r,m")
3153 (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
3157 && (register_operand (operands[0], DFmode)
3158 || register_operand (operands[1], DFmode))"
3166 [(set_attr "type" "fpmove,load,store,move,load,store")
3167 (set_attr "length" "1")])
3169 (define_insn "*movdf_no_e_insn_sp64"
3170 [(set (match_operand:DF 0 "general_operand" "=r,r,m")
3171 (match_operand:DF 1 "input_operand" "r,m,r"))]
3174 && (register_operand (operands[0], DFmode)
3175 || register_operand (operands[1], DFmode))"
3180 [(set_attr "type" "move,load,store")
3181 (set_attr "length" "1")])
3183 ;; Ok, now the splits to handle all the multi insn and
3184 ;; mis-aligned memory address cases.
3185 ;; In these splits please take note that we must be
3186 ;; careful when V9 but not ARCH64 because the integer
3187 ;; register DFmode cases must be handled.
3189 [(set (match_operand:DF 0 "register_operand" "")
3190 (match_operand:DF 1 "register_operand" ""))]
3193 && ((GET_CODE (operands[0]) == REG
3194 && REGNO (operands[0]) < 32)
3195 || (GET_CODE (operands[0]) == SUBREG
3196 && GET_CODE (SUBREG_REG (operands[0])) == REG
3197 && REGNO (SUBREG_REG (operands[0])) < 32))))
3198 && reload_completed"
3199 [(clobber (const_int 0))]
3202 rtx set_dest = operands[0];
3203 rtx set_src = operands[1];
3207 if (GET_CODE (set_dest) == SUBREG)
3208 set_dest = alter_subreg (set_dest);
3209 if (GET_CODE (set_src) == SUBREG)
3210 set_src = alter_subreg (set_src);
3212 dest1 = gen_highpart (SFmode, set_dest);
3213 dest2 = gen_lowpart (SFmode, set_dest);
3214 src1 = gen_highpart (SFmode, set_src);
3215 src2 = gen_lowpart (SFmode, set_src);
3217 /* Now emit using the real source and destination we found, swapping
3218 the order if we detect overlap. */
3219 if (reg_overlap_mentioned_p (dest1, src2))
3221 emit_insn (gen_movsf (dest2, src2));
3222 emit_insn (gen_movsf (dest1, src1));
3226 emit_insn (gen_movsf (dest1, src1));
3227 emit_insn (gen_movsf (dest2, src2));
3233 [(set (match_operand:DF 0 "register_operand" "")
3234 (match_operand:DF 1 "memory_operand" ""))]
3237 && ((GET_CODE (operands[0]) == REG
3238 && REGNO (operands[0]) < 32)
3239 || (GET_CODE (operands[0]) == SUBREG
3240 && GET_CODE (SUBREG_REG (operands[0])) == REG
3241 && REGNO (SUBREG_REG (operands[0])) < 32))))
3242 && (reload_completed
3243 && (((REGNO (operands[0])) % 2) != 0
3244 || ! mem_min_alignment (operands[1], 8))
3245 && offsettable_memref_p (operands[1])))"
3246 [(clobber (const_int 0))]
3249 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3250 rtx word1 = change_address (operands[1], SFmode,
3251 plus_constant_for_output (XEXP (word0, 0), 4));
3253 if (GET_CODE (operands[0]) == SUBREG)
3254 operands[0] = alter_subreg (operands[0]);
3256 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3258 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3260 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3265 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3267 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3274 [(set (match_operand:DF 0 "memory_operand" "")
3275 (match_operand:DF 1 "register_operand" ""))]
3278 && ((GET_CODE (operands[1]) == REG
3279 && REGNO (operands[1]) < 32)
3280 || (GET_CODE (operands[1]) == SUBREG
3281 && GET_CODE (SUBREG_REG (operands[1])) == REG
3282 && REGNO (SUBREG_REG (operands[1])) < 32))))
3283 && (reload_completed
3284 && (((REGNO (operands[1])) % 2) != 0
3285 || ! mem_min_alignment (operands[0], 8))
3286 && offsettable_memref_p (operands[0])))"
3287 [(clobber (const_int 0))]
3290 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3291 rtx word1 = change_address (operands[0], SFmode,
3292 plus_constant_for_output (XEXP (word0, 0), 4));
3294 if (GET_CODE (operands[1]) == SUBREG)
3295 operands[1] = alter_subreg (operands[1]);
3296 emit_insn (gen_movsf (word0,
3297 gen_highpart (SFmode, operands[1])));
3298 emit_insn (gen_movsf (word1,
3299 gen_lowpart (SFmode, operands[1])));
3303 (define_expand "movtf"
3304 [(set (match_operand:TF 0 "general_operand" "")
3305 (match_operand:TF 1 "general_operand" ""))]
3309 /* Force TFmode constants into memory. */
3310 if (GET_CODE (operands[0]) == REG
3311 && CONSTANT_P (operands[1]))
3313 /* emit_group_store will send such bogosity to us when it is
3314 not storing directly into memory. So fix this up to avoid
3315 crashes in output_constant_pool. */
3316 if (operands [1] == const0_rtx)
3317 operands[1] = CONST0_RTX (TFmode);
3318 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3322 /* Handle MEM cases first, note that only v9 guarentees
3323 full 16-byte alignment for quads. */
3324 if (GET_CODE (operands[0]) == MEM)
3326 if (register_operand (operands[1], TFmode))
3329 if (! reload_in_progress)
3331 operands[0] = validize_mem (operands[0]);
3332 operands[1] = force_reg (TFmode, operands[1]);
3336 /* Fixup PIC cases. */
3339 if (CONSTANT_P (operands[1])
3340 && pic_address_needs_scratch (operands[1]))
3341 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3343 if (symbolic_operand (operands[1], TFmode))
3345 operands[1] = legitimize_pic_address (operands[1],
3347 (reload_in_progress ?
3357 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3358 ;; we must split them all. :-(
3359 (define_insn "*movtf_insn_sp32"
3360 [(set (match_operand:TF 0 "general_operand" "=e,o,U,o,e,r,r,o")
3361 (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
3364 && (register_operand (operands[0], TFmode)
3365 || register_operand (operands[1], TFmode))"
3367 [(set_attr "length" "4")])
3369 ;; Exactly the same as above, except that all `e' cases are deleted.
3370 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3373 (define_insn "*movtf_no_e_insn_sp32"
3374 [(set (match_operand:TF 0 "general_operand" "=U,o,r,r,o")
3375 (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
3378 && (register_operand (operands[0], TFmode)
3379 || register_operand (operands[1], TFmode))"
3381 [(set_attr "length" "4")])
3383 ;; Now handle the float reg cases directly when arch64,
3384 ;; hard_quad, and proper reg number alignment are all true.
3385 (define_insn "*movtf_insn_hq_sp64"
3386 [(set (match_operand:TF 0 "general_operand" "=e,e,m,r,r,o")
3387 (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
3392 && (register_operand (operands[0], TFmode)
3393 || register_operand (operands[1], TFmode))"
3401 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3402 (set_attr "length" "1,1,1,2,2,2")])
3404 ;; Now we allow the integer register cases even when
3405 ;; only arch64 is true.
3406 (define_insn "*movtf_insn_sp64"
3407 [(set (match_operand:TF 0 "general_operand" "=e,o,r,o,e,r")
3408 (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
3411 && ! TARGET_HARD_QUAD
3412 && (register_operand (operands[0], TFmode)
3413 || register_operand (operands[1], TFmode))"
3415 [(set_attr "length" "2")])
3417 (define_insn "*movtf_no_e_insn_sp64"
3418 [(set (match_operand:TF 0 "general_operand" "=r,o,r")
3419 (match_operand:TF 1 "input_operand" "o,r,r"))]
3422 && (register_operand (operands[0], TFmode)
3423 || register_operand (operands[1], TFmode))"
3425 [(set_attr "length" "2")])
3427 ;; Now all the splits to handle multi-insn TF mode moves.
3429 [(set (match_operand:TF 0 "register_operand" "")
3430 (match_operand:TF 1 "register_operand" ""))]
3434 && ! TARGET_HARD_QUAD))"
3435 [(clobber (const_int 0))]
3438 rtx set_dest = operands[0];
3439 rtx set_src = operands[1];
3443 if (GET_CODE (set_dest) == SUBREG)
3444 set_dest = alter_subreg (set_dest);
3445 if (GET_CODE (set_src) == SUBREG)
3446 set_src = alter_subreg (set_src);
3448 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3449 dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
3450 dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
3451 src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0);
3452 src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0);
3454 /* Now emit using the real source and destination we found, swapping
3455 the order if we detect overlap. */
3456 if (reg_overlap_mentioned_p (dest1, src2))
3458 emit_insn (gen_movdf (dest2, src2));
3459 emit_insn (gen_movdf (dest1, src1));
3463 emit_insn (gen_movdf (dest1, src1));
3464 emit_insn (gen_movdf (dest2, src2));
3470 [(set (match_operand:TF 0 "register_operand" "")
3471 (match_operand:TF 1 "memory_operand" ""))]
3473 && offsettable_memref_p (operands[1]))"
3474 [(clobber (const_int 0))]
3477 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3478 rtx word1 = change_address (operands[1], DFmode,
3479 plus_constant_for_output (XEXP (word0, 0), 8));
3482 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3483 dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
3484 dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
3486 /* Now output, ordering such that we don't clobber any registers
3487 mentioned in the address. */
3488 if (reg_overlap_mentioned_p (dest1, word1))
3491 emit_insn (gen_movdf (dest2, word1));
3492 emit_insn (gen_movdf (dest1, word0));
3496 emit_insn (gen_movdf (dest1, word0));
3497 emit_insn (gen_movdf (dest2, word1));
3503 [(set (match_operand:TF 0 "memory_operand" "")
3504 (match_operand:TF 1 "register_operand" ""))]
3506 && offsettable_memref_p (operands[0]))"
3507 [(clobber (const_int 0))]
3510 rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
3511 rtx word1 = change_address (operands[0], DFmode,
3512 plus_constant_for_output (XEXP (word0, 0), 8));
3515 /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
3516 src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
3517 src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
3518 emit_insn (gen_movdf (word0, src1));
3519 emit_insn (gen_movdf (word1, src2));
3523 ;; Sparc V9 conditional move instructions.
3525 ;; We can handle larger constants here for some flavors, but for now we keep
3526 ;; it simple and only allow those constants supported by all flavours.
3527 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3528 ;; 3 contains the constant if one is present, but we handle either for
3529 ;; generality (sparc.c puts a constant in operand 2).
3531 (define_expand "movqicc"
3532 [(set (match_operand:QI 0 "register_operand" "")
3533 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3534 (match_operand:QI 2 "arith10_operand" "")
3535 (match_operand:QI 3 "arith10_operand" "")))]
3539 enum rtx_code code = GET_CODE (operands[1]);
3541 if (GET_MODE (sparc_compare_op0) == DImode
3545 if (sparc_compare_op1 == const0_rtx
3546 && GET_CODE (sparc_compare_op0) == REG
3547 && GET_MODE (sparc_compare_op0) == DImode
3548 && v9_regcmp_p (code))
3550 operands[1] = gen_rtx_fmt_ee (code, DImode,
3551 sparc_compare_op0, sparc_compare_op1);
3555 rtx cc_reg = gen_compare_reg (code,
3556 sparc_compare_op0, sparc_compare_op1);
3557 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3561 (define_expand "movhicc"
3562 [(set (match_operand:HI 0 "register_operand" "")
3563 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3564 (match_operand:HI 2 "arith10_operand" "")
3565 (match_operand:HI 3 "arith10_operand" "")))]
3569 enum rtx_code code = GET_CODE (operands[1]);
3571 if (GET_MODE (sparc_compare_op0) == DImode
3575 if (sparc_compare_op1 == const0_rtx
3576 && GET_CODE (sparc_compare_op0) == REG
3577 && GET_MODE (sparc_compare_op0) == DImode
3578 && v9_regcmp_p (code))
3580 operands[1] = gen_rtx_fmt_ee (code, DImode,
3581 sparc_compare_op0, sparc_compare_op1);
3585 rtx cc_reg = gen_compare_reg (code,
3586 sparc_compare_op0, sparc_compare_op1);
3587 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3591 (define_expand "movsicc"
3592 [(set (match_operand:SI 0 "register_operand" "")
3593 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3594 (match_operand:SI 2 "arith10_operand" "")
3595 (match_operand:SI 3 "arith10_operand" "")))]
3599 enum rtx_code code = GET_CODE (operands[1]);
3600 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3602 if (sparc_compare_op1 == const0_rtx
3603 && GET_CODE (sparc_compare_op0) == REG
3604 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3606 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3607 sparc_compare_op0, sparc_compare_op1);
3611 rtx cc_reg = gen_compare_reg (code,
3612 sparc_compare_op0, sparc_compare_op1);
3613 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3614 cc_reg, const0_rtx);
3618 (define_expand "movdicc"
3619 [(set (match_operand:DI 0 "register_operand" "")
3620 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3621 (match_operand:DI 2 "arith10_double_operand" "")
3622 (match_operand:DI 3 "arith10_double_operand" "")))]
3626 enum rtx_code code = GET_CODE (operands[1]);
3628 if (sparc_compare_op1 == const0_rtx
3629 && GET_CODE (sparc_compare_op0) == REG
3630 && GET_MODE (sparc_compare_op0) == DImode
3631 && v9_regcmp_p (code))
3633 operands[1] = gen_rtx_fmt_ee (code, DImode,
3634 sparc_compare_op0, sparc_compare_op1);
3638 rtx cc_reg = gen_compare_reg (code,
3639 sparc_compare_op0, sparc_compare_op1);
3640 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3641 cc_reg, const0_rtx);
3645 (define_expand "movsfcc"
3646 [(set (match_operand:SF 0 "register_operand" "")
3647 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3648 (match_operand:SF 2 "register_operand" "")
3649 (match_operand:SF 3 "register_operand" "")))]
3650 "TARGET_V9 && TARGET_FPU"
3653 enum rtx_code code = GET_CODE (operands[1]);
3655 if (GET_MODE (sparc_compare_op0) == DImode
3659 if (sparc_compare_op1 == const0_rtx
3660 && GET_CODE (sparc_compare_op0) == REG
3661 && GET_MODE (sparc_compare_op0) == DImode
3662 && v9_regcmp_p (code))
3664 operands[1] = gen_rtx_fmt_ee (code, DImode,
3665 sparc_compare_op0, sparc_compare_op1);
3669 rtx cc_reg = gen_compare_reg (code,
3670 sparc_compare_op0, sparc_compare_op1);
3671 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3675 (define_expand "movdfcc"
3676 [(set (match_operand:DF 0 "register_operand" "")
3677 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3678 (match_operand:DF 2 "register_operand" "")
3679 (match_operand:DF 3 "register_operand" "")))]
3680 "TARGET_V9 && TARGET_FPU"
3683 enum rtx_code code = GET_CODE (operands[1]);
3685 if (GET_MODE (sparc_compare_op0) == DImode
3689 if (sparc_compare_op1 == const0_rtx
3690 && GET_CODE (sparc_compare_op0) == REG
3691 && GET_MODE (sparc_compare_op0) == DImode
3692 && v9_regcmp_p (code))
3694 operands[1] = gen_rtx_fmt_ee (code, DImode,
3695 sparc_compare_op0, sparc_compare_op1);
3699 rtx cc_reg = gen_compare_reg (code,
3700 sparc_compare_op0, sparc_compare_op1);
3701 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3705 (define_expand "movtfcc"
3706 [(set (match_operand:TF 0 "register_operand" "")
3707 (if_then_else:TF (match_operand 1 "comparison_operator" "")
3708 (match_operand:TF 2 "register_operand" "")
3709 (match_operand:TF 3 "register_operand" "")))]
3710 "TARGET_V9 && TARGET_FPU"
3713 enum rtx_code code = GET_CODE (operands[1]);
3715 if (GET_MODE (sparc_compare_op0) == DImode
3719 if (sparc_compare_op1 == const0_rtx
3720 && GET_CODE (sparc_compare_op0) == REG
3721 && GET_MODE (sparc_compare_op0) == DImode
3722 && v9_regcmp_p (code))
3724 operands[1] = gen_rtx_fmt_ee (code, DImode,
3725 sparc_compare_op0, sparc_compare_op1);
3729 rtx cc_reg = gen_compare_reg (code,
3730 sparc_compare_op0, sparc_compare_op1);
3731 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3735 ;; Conditional move define_insns.
3737 (define_insn "*movqi_cc_sp64"
3738 [(set (match_operand:QI 0 "register_operand" "=r,r")
3739 (if_then_else:QI (match_operator 1 "comparison_operator"
3740 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3742 (match_operand:QI 3 "arith11_operand" "rL,0")
3743 (match_operand:QI 4 "arith11_operand" "0,rL")))]
3746 mov%C1\\t%x2, %3, %0
3747 mov%c1\\t%x2, %4, %0"
3748 [(set_attr "type" "cmove")
3749 (set_attr "length" "1")])
3751 (define_insn "*movhi_cc_sp64"
3752 [(set (match_operand:HI 0 "register_operand" "=r,r")
3753 (if_then_else:HI (match_operator 1 "comparison_operator"
3754 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3756 (match_operand:HI 3 "arith11_operand" "rL,0")
3757 (match_operand:HI 4 "arith11_operand" "0,rL")))]
3760 mov%C1\\t%x2, %3, %0
3761 mov%c1\\t%x2, %4, %0"
3762 [(set_attr "type" "cmove")
3763 (set_attr "length" "1")])
3765 (define_insn "*movsi_cc_sp64"
3766 [(set (match_operand:SI 0 "register_operand" "=r,r")
3767 (if_then_else:SI (match_operator 1 "comparison_operator"
3768 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3770 (match_operand:SI 3 "arith11_operand" "rL,0")
3771 (match_operand:SI 4 "arith11_operand" "0,rL")))]
3774 mov%C1\\t%x2, %3, %0
3775 mov%c1\\t%x2, %4, %0"
3776 [(set_attr "type" "cmove")
3777 (set_attr "length" "1")])
3779 ;; ??? The constraints of operands 3,4 need work.
3780 (define_insn "*movdi_cc_sp64"
3781 [(set (match_operand:DI 0 "register_operand" "=r,r")
3782 (if_then_else:DI (match_operator 1 "comparison_operator"
3783 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3785 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3786 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3789 mov%C1\\t%x2, %3, %0
3790 mov%c1\\t%x2, %4, %0"
3791 [(set_attr "type" "cmove")
3792 (set_attr "length" "1")])
3794 (define_insn "*movdi_cc_sp64_trunc"
3795 [(set (match_operand:SI 0 "register_operand" "=r,r")
3796 (if_then_else:SI (match_operator 1 "comparison_operator"
3797 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3799 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3800 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3803 mov%C1\\t%x2, %3, %0
3804 mov%c1\\t%x2, %4, %0"
3805 [(set_attr "type" "cmove")
3806 (set_attr "length" "1")])
3808 (define_insn "*movsf_cc_sp64"
3809 [(set (match_operand:SF 0 "register_operand" "=f,f")
3810 (if_then_else:SF (match_operator 1 "comparison_operator"
3811 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3813 (match_operand:SF 3 "register_operand" "f,0")
3814 (match_operand:SF 4 "register_operand" "0,f")))]
3815 "TARGET_V9 && TARGET_FPU"
3817 fmovs%C1\\t%x2, %3, %0
3818 fmovs%c1\\t%x2, %4, %0"
3819 [(set_attr "type" "fpcmove")
3820 (set_attr "length" "1")])
3822 (define_insn "*movdf_cc_sp64"
3823 [(set (match_operand:DF 0 "register_operand" "=e,e")
3824 (if_then_else:DF (match_operator 1 "comparison_operator"
3825 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3827 (match_operand:DF 3 "register_operand" "e,0")
3828 (match_operand:DF 4 "register_operand" "0,e")))]
3829 "TARGET_V9 && TARGET_FPU"
3831 fmovd%C1\\t%x2, %3, %0
3832 fmovd%c1\\t%x2, %4, %0"
3833 [(set_attr "type" "fpcmove")
3834 (set_attr "length" "1")])
3836 (define_insn "*movtf_cc_sp64"
3837 [(set (match_operand:TF 0 "register_operand" "=e,e")
3838 (if_then_else:TF (match_operator 1 "comparison_operator"
3839 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3841 (match_operand:TF 3 "register_operand" "e,0")
3842 (match_operand:TF 4 "register_operand" "0,e")))]
3843 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3845 fmovq%C1\\t%x2, %3, %0
3846 fmovq%c1\\t%x2, %4, %0"
3847 [(set_attr "type" "fpcmove")
3848 (set_attr "length" "1")])
3850 (define_insn "*movqi_cc_reg_sp64"
3851 [(set (match_operand:QI 0 "register_operand" "=r,r")
3852 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3853 [(match_operand:DI 2 "register_operand" "r,r")
3855 (match_operand:QI 3 "arith10_operand" "rM,0")
3856 (match_operand:QI 4 "arith10_operand" "0,rM")))]
3859 movr%D1\\t%2, %r3, %0
3860 movr%d1\\t%2, %r4, %0"
3861 [(set_attr "type" "cmove")
3862 (set_attr "length" "1")])
3864 (define_insn "*movhi_cc_reg_sp64"
3865 [(set (match_operand:HI 0 "register_operand" "=r,r")
3866 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3867 [(match_operand:DI 2 "register_operand" "r,r")
3869 (match_operand:HI 3 "arith10_operand" "rM,0")
3870 (match_operand:HI 4 "arith10_operand" "0,rM")))]
3873 movr%D1\\t%2, %r3, %0
3874 movr%d1\\t%2, %r4, %0"
3875 [(set_attr "type" "cmove")
3876 (set_attr "length" "1")])
3878 (define_insn "*movsi_cc_reg_sp64"
3879 [(set (match_operand:SI 0 "register_operand" "=r,r")
3880 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3881 [(match_operand:DI 2 "register_operand" "r,r")
3883 (match_operand:SI 3 "arith10_operand" "rM,0")
3884 (match_operand:SI 4 "arith10_operand" "0,rM")))]
3887 movr%D1\\t%2, %r3, %0
3888 movr%d1\\t%2, %r4, %0"
3889 [(set_attr "type" "cmove")
3890 (set_attr "length" "1")])
3892 ;; ??? The constraints of operands 3,4 need work.
3893 (define_insn "*movdi_cc_reg_sp64"
3894 [(set (match_operand:DI 0 "register_operand" "=r,r")
3895 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3896 [(match_operand:DI 2 "register_operand" "r,r")
3898 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3899 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3902 movr%D1\\t%2, %r3, %0
3903 movr%d1\\t%2, %r4, %0"
3904 [(set_attr "type" "cmove")
3905 (set_attr "length" "1")])
3907 (define_insn "*movdi_cc_reg_sp64_trunc"
3908 [(set (match_operand:SI 0 "register_operand" "=r,r")
3909 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3910 [(match_operand:DI 2 "register_operand" "r,r")
3912 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3913 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3916 movr%D1\\t%2, %r3, %0
3917 movr%d1\\t%2, %r4, %0"
3918 [(set_attr "type" "cmove")
3919 (set_attr "length" "1")])
3921 (define_insn "*movsf_cc_reg_sp64"
3922 [(set (match_operand:SF 0 "register_operand" "=f,f")
3923 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3924 [(match_operand:DI 2 "register_operand" "r,r")
3926 (match_operand:SF 3 "register_operand" "f,0")
3927 (match_operand:SF 4 "register_operand" "0,f")))]
3928 "TARGET_ARCH64 && TARGET_FPU"
3930 fmovrs%D1\\t%2, %3, %0
3931 fmovrs%d1\\t%2, %4, %0"
3932 [(set_attr "type" "fpcmove")
3933 (set_attr "length" "1")])
3935 (define_insn "*movdf_cc_reg_sp64"
3936 [(set (match_operand:DF 0 "register_operand" "=e,e")
3937 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3938 [(match_operand:DI 2 "register_operand" "r,r")
3940 (match_operand:DF 3 "register_operand" "e,0")
3941 (match_operand:DF 4 "register_operand" "0,e")))]
3942 "TARGET_ARCH64 && TARGET_FPU"
3944 fmovrd%D1\\t%2, %3, %0
3945 fmovrd%d1\\t%2, %4, %0"
3946 [(set_attr "type" "fpcmove")
3947 (set_attr "length" "1")])
3949 (define_insn "*movtf_cc_reg_sp64"
3950 [(set (match_operand:TF 0 "register_operand" "=e,e")
3951 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3952 [(match_operand:DI 2 "register_operand" "r,r")
3954 (match_operand:TF 3 "register_operand" "e,0")
3955 (match_operand:TF 4 "register_operand" "0,e")))]
3956 "TARGET_ARCH64 && TARGET_FPU"
3958 fmovrq%D1\\t%2, %3, %0
3959 fmovrq%d1\\t%2, %4, %0"
3960 [(set_attr "type" "fpcmove")
3961 (set_attr "length" "1")])
3963 ;;- zero extension instructions
3965 ;; These patterns originally accepted general_operands, however, slightly
3966 ;; better code is generated by only accepting register_operands, and then
3967 ;; letting combine generate the ldu[hb] insns.
3969 (define_expand "zero_extendhisi2"
3970 [(set (match_operand:SI 0 "register_operand" "")
3971 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3975 rtx temp = gen_reg_rtx (SImode);
3976 rtx shift_16 = GEN_INT (16);
3977 int op1_subword = 0;
3979 if (GET_CODE (operand1) == SUBREG)
3981 op1_subword = SUBREG_WORD (operand1);
3982 operand1 = XEXP (operand1, 0);
3985 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
3988 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3992 (define_insn "*zero_extendhisi2_insn"
3993 [(set (match_operand:SI 0 "register_operand" "=r")
3994 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3997 [(set_attr "type" "load")
3998 (set_attr "length" "1")])
4000 (define_expand "zero_extendqihi2"
4001 [(set (match_operand:HI 0 "register_operand" "")
4002 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4006 (define_insn "*zero_extendqihi2_insn"
4007 [(set (match_operand:HI 0 "register_operand" "=r,r")
4008 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4009 "GET_CODE (operands[1]) != CONST_INT"
4013 [(set_attr "type" "unary,load")
4014 (set_attr "length" "1")])
4016 (define_expand "zero_extendqisi2"
4017 [(set (match_operand:SI 0 "register_operand" "")
4018 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4022 (define_insn "*zero_extendqisi2_insn"
4023 [(set (match_operand:SI 0 "register_operand" "=r,r")
4024 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4025 "GET_CODE (operands[1]) != CONST_INT"
4029 [(set_attr "type" "unary,load")
4030 (set_attr "length" "1")])
4032 (define_expand "zero_extendqidi2"
4033 [(set (match_operand:DI 0 "register_operand" "")
4034 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4038 (define_insn "*zero_extendqidi2_insn"
4039 [(set (match_operand:DI 0 "register_operand" "=r,r")
4040 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4041 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4045 [(set_attr "type" "unary,load")
4046 (set_attr "length" "1")])
4048 (define_expand "zero_extendhidi2"
4049 [(set (match_operand:DI 0 "register_operand" "")
4050 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4054 rtx temp = gen_reg_rtx (DImode);
4055 rtx shift_48 = GEN_INT (48);
4056 int op1_subword = 0;
4058 if (GET_CODE (operand1) == SUBREG)
4060 op1_subword = SUBREG_WORD (operand1);
4061 operand1 = XEXP (operand1, 0);
4064 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4067 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4071 (define_insn "*zero_extendhidi2_insn"
4072 [(set (match_operand:DI 0 "register_operand" "=r")
4073 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4076 [(set_attr "type" "load")
4077 (set_attr "length" "1")])
4080 ;; ??? Write truncdisi pattern using sra?
4082 (define_expand "zero_extendsidi2"
4083 [(set (match_operand:DI 0 "register_operand" "")
4084 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4088 (define_insn "*zero_extendsidi2_insn_sp64"
4089 [(set (match_operand:DI 0 "register_operand" "=r,r")
4090 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4091 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4095 [(set_attr "type" "shift,load")
4096 (set_attr "length" "1")])
4098 (define_insn "*zero_extendsidi2_insn_sp32"
4099 [(set (match_operand:DI 0 "register_operand" "=r")
4100 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4103 [(set_attr "type" "unary")
4104 (set_attr "length" "2")])
4107 [(set (match_operand:DI 0 "register_operand" "")
4108 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4109 "! TARGET_ARCH64 && reload_completed"
4110 [(set (match_dup 2) (match_dup 3))
4111 (set (match_dup 4) (match_dup 5))]
4116 if (GET_CODE (operands[0]) == SUBREG)
4117 operands[0] = alter_subreg (operands[0]);
4119 dest1 = gen_highpart (SImode, operands[0]);
4120 dest2 = gen_lowpart (SImode, operands[0]);
4122 /* Swap the order in case of overlap. */
4123 if (REGNO (dest1) == REGNO (operands[1]))
4125 operands[2] = dest2;
4126 operands[3] = operands[1];
4127 operands[4] = dest1;
4128 operands[5] = const0_rtx;
4132 operands[2] = dest1;
4133 operands[3] = const0_rtx;
4134 operands[4] = dest2;
4135 operands[5] = operands[1];
4139 ;; Simplify comparisons of extended values.
4141 (define_insn "*cmp_zero_extendqisi2"
4143 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4146 "andcc\\t%0, 0xff, %%g0"
4147 [(set_attr "type" "compare")
4148 (set_attr "length" "1")])
4150 (define_insn "*cmp_zero_extendqisi2_set"
4152 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4154 (set (match_operand:SI 0 "register_operand" "=r")
4155 (zero_extend:SI (match_dup 1)))]
4157 "andcc\\t%1, 0xff, %0"
4158 [(set_attr "type" "compare")
4159 (set_attr "length" "1")])
4161 (define_insn "*cmp_zero_extendqidi2"
4163 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4166 "andcc\\t%0, 0xff, %%g0"
4167 [(set_attr "type" "compare")
4168 (set_attr "length" "1")])
4170 (define_insn "*cmp_zero_extendqidi2_set"
4172 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4174 (set (match_operand:DI 0 "register_operand" "=r")
4175 (zero_extend:DI (match_dup 1)))]
4177 "andcc\\t%1, 0xff, %0"
4178 [(set_attr "type" "compare")
4179 (set_attr "length" "1")])
4181 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4183 (define_insn "*cmp_siqi_trunc"
4185 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4188 "andcc\\t%0, 0xff, %%g0"
4189 [(set_attr "type" "compare")
4190 (set_attr "length" "1")])
4192 (define_insn "*cmp_siqi_trunc_set"
4194 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4196 (set (match_operand:QI 0 "register_operand" "=r")
4197 (subreg:QI (match_dup 1) 0))]
4199 "andcc\\t%1, 0xff, %0"
4200 [(set_attr "type" "compare")
4201 (set_attr "length" "1")])
4203 (define_insn "*cmp_diqi_trunc"
4205 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4208 "andcc\\t%0, 0xff, %%g0"
4209 [(set_attr "type" "compare")
4210 (set_attr "length" "1")])
4212 (define_insn "*cmp_diqi_trunc_set"
4214 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4216 (set (match_operand:QI 0 "register_operand" "=r")
4217 (subreg:QI (match_dup 1) 0))]
4219 "andcc\\t%1, 0xff, %0"
4220 [(set_attr "type" "compare")
4221 (set_attr "length" "1")])
4223 ;;- sign extension instructions
4225 ;; These patterns originally accepted general_operands, however, slightly
4226 ;; better code is generated by only accepting register_operands, and then
4227 ;; letting combine generate the lds[hb] insns.
4229 (define_expand "extendhisi2"
4230 [(set (match_operand:SI 0 "register_operand" "")
4231 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4235 rtx temp = gen_reg_rtx (SImode);
4236 rtx shift_16 = GEN_INT (16);
4237 int op1_subword = 0;
4239 if (GET_CODE (operand1) == SUBREG)
4241 op1_subword = SUBREG_WORD (operand1);
4242 operand1 = XEXP (operand1, 0);
4245 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4248 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4252 (define_insn "*sign_extendhisi2_insn"
4253 [(set (match_operand:SI 0 "register_operand" "=r")
4254 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4257 [(set_attr "type" "sload")
4258 (set_attr "length" "1")])
4260 (define_expand "extendqihi2"
4261 [(set (match_operand:HI 0 "register_operand" "")
4262 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4266 rtx temp = gen_reg_rtx (SImode);
4267 rtx shift_24 = GEN_INT (24);
4268 int op1_subword = 0;
4269 int op0_subword = 0;
4271 if (GET_CODE (operand1) == SUBREG)
4273 op1_subword = SUBREG_WORD (operand1);
4274 operand1 = XEXP (operand1, 0);
4276 if (GET_CODE (operand0) == SUBREG)
4278 op0_subword = SUBREG_WORD (operand0);
4279 operand0 = XEXP (operand0, 0);
4281 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4284 if (GET_MODE (operand0) != SImode)
4285 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4286 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4290 (define_insn "*sign_extendqihi2_insn"
4291 [(set (match_operand:HI 0 "register_operand" "=r")
4292 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4295 [(set_attr "type" "sload")
4296 (set_attr "length" "1")])
4298 (define_expand "extendqisi2"
4299 [(set (match_operand:SI 0 "register_operand" "")
4300 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4304 rtx temp = gen_reg_rtx (SImode);
4305 rtx shift_24 = GEN_INT (24);
4306 int op1_subword = 0;
4308 if (GET_CODE (operand1) == SUBREG)
4310 op1_subword = SUBREG_WORD (operand1);
4311 operand1 = XEXP (operand1, 0);
4314 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1,
4317 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4321 (define_insn "*sign_extendqisi2_insn"
4322 [(set (match_operand:SI 0 "register_operand" "=r")
4323 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4326 [(set_attr "type" "sload")
4327 (set_attr "length" "1")])
4329 (define_expand "extendqidi2"
4330 [(set (match_operand:DI 0 "register_operand" "")
4331 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4335 rtx temp = gen_reg_rtx (DImode);
4336 rtx shift_56 = GEN_INT (56);
4337 int op1_subword = 0;
4339 if (GET_CODE (operand1) == SUBREG)
4341 op1_subword = SUBREG_WORD (operand1);
4342 operand1 = XEXP (operand1, 0);
4345 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4348 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4352 (define_insn "*sign_extendqidi2_insn"
4353 [(set (match_operand:DI 0 "register_operand" "=r")
4354 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4357 [(set_attr "type" "sload")
4358 (set_attr "length" "1")])
4360 (define_expand "extendhidi2"
4361 [(set (match_operand:DI 0 "register_operand" "")
4362 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4366 rtx temp = gen_reg_rtx (DImode);
4367 rtx shift_48 = GEN_INT (48);
4368 int op1_subword = 0;
4370 if (GET_CODE (operand1) == SUBREG)
4372 op1_subword = SUBREG_WORD (operand1);
4373 operand1 = XEXP (operand1, 0);
4376 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1,
4379 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4383 (define_insn "*sign_extendhidi2_insn"
4384 [(set (match_operand:DI 0 "register_operand" "=r")
4385 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4388 [(set_attr "type" "sload")
4389 (set_attr "length" "1")])
4391 (define_expand "extendsidi2"
4392 [(set (match_operand:DI 0 "register_operand" "")
4393 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4397 (define_insn "*sign_extendsidi2_insn"
4398 [(set (match_operand:DI 0 "register_operand" "=r,r")
4399 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4404 [(set_attr "type" "shift,sload")
4405 (set_attr "length" "1")])
4407 ;; Special pattern for optimizing bit-field compares. This is needed
4408 ;; because combine uses this as a canonical form.
4410 (define_insn "*cmp_zero_extract"
4413 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4414 (match_operand:SI 1 "small_int_or_double" "n")
4415 (match_operand:SI 2 "small_int_or_double" "n"))
4418 && ((GET_CODE (operands[2]) == CONST_INT
4419 && INTVAL (operands[2]) > 19)
4420 || (GET_CODE (operands[2]) == CONST_DOUBLE
4421 && CONST_DOUBLE_LOW (operands[2]) > 19))"
4424 int len = (GET_CODE (operands[1]) == CONST_INT
4425 ? INTVAL (operands[1])
4426 : CONST_DOUBLE_LOW (operands[1]));
4428 (GET_CODE (operands[2]) == CONST_INT
4429 ? INTVAL (operands[2])
4430 : CONST_DOUBLE_LOW (operands[2])) - len;
4431 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4433 operands[1] = GEN_INT (mask);
4434 return \"andcc\\t%0, %1, %%g0\";
4436 [(set_attr "type" "compare")
4437 (set_attr "length" "1")])
4439 (define_insn "*cmp_zero_extract_sp64"
4442 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4443 (match_operand:SI 1 "small_int_or_double" "n")
4444 (match_operand:SI 2 "small_int_or_double" "n"))
4447 && ((GET_CODE (operands[2]) == CONST_INT
4448 && INTVAL (operands[2]) > 51)
4449 || (GET_CODE (operands[2]) == CONST_DOUBLE
4450 && CONST_DOUBLE_LOW (operands[2]) > 51))"
4453 int len = (GET_CODE (operands[1]) == CONST_INT
4454 ? INTVAL (operands[1])
4455 : CONST_DOUBLE_LOW (operands[1]));
4457 (GET_CODE (operands[2]) == CONST_INT
4458 ? INTVAL (operands[2])
4459 : CONST_DOUBLE_LOW (operands[2])) - len;
4460 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4462 operands[1] = GEN_INT (mask);
4463 return \"andcc\\t%0, %1, %%g0\";
4465 [(set_attr "type" "compare")
4466 (set_attr "length" "1")])
4468 ;; Conversions between float, double and long double.
4470 (define_insn "extendsfdf2"
4471 [(set (match_operand:DF 0 "register_operand" "=e")
4473 (match_operand:SF 1 "register_operand" "f")))]
4476 [(set_attr "type" "fp")
4477 (set_attr "length" "1")])
4479 (define_insn "extendsftf2"
4480 [(set (match_operand:TF 0 "register_operand" "=e")
4482 (match_operand:SF 1 "register_operand" "f")))]
4483 "TARGET_FPU && TARGET_HARD_QUAD"
4485 [(set_attr "type" "fp")
4486 (set_attr "length" "1")])
4488 (define_insn "extenddftf2"
4489 [(set (match_operand:TF 0 "register_operand" "=e")
4491 (match_operand:DF 1 "register_operand" "e")))]
4492 "TARGET_FPU && TARGET_HARD_QUAD"
4494 [(set_attr "type" "fp")
4495 (set_attr "length" "1")])
4497 (define_insn "truncdfsf2"
4498 [(set (match_operand:SF 0 "register_operand" "=f")
4500 (match_operand:DF 1 "register_operand" "e")))]
4503 [(set_attr "type" "fp")
4504 (set_attr "length" "1")])
4506 (define_insn "trunctfsf2"
4507 [(set (match_operand:SF 0 "register_operand" "=f")
4509 (match_operand:TF 1 "register_operand" "e")))]
4510 "TARGET_FPU && TARGET_HARD_QUAD"
4512 [(set_attr "type" "fp")
4513 (set_attr "length" "1")])
4515 (define_insn "trunctfdf2"
4516 [(set (match_operand:DF 0 "register_operand" "=e")
4518 (match_operand:TF 1 "register_operand" "e")))]
4519 "TARGET_FPU && TARGET_HARD_QUAD"
4521 [(set_attr "type" "fp")
4522 (set_attr "length" "1")])
4524 ;; Conversion between fixed point and floating point.
4526 (define_insn "floatsisf2"
4527 [(set (match_operand:SF 0 "register_operand" "=f")
4528 (float:SF (match_operand:SI 1 "register_operand" "f")))]
4531 [(set_attr "type" "fp")
4532 (set_attr "length" "1")])
4534 (define_insn "floatsidf2"
4535 [(set (match_operand:DF 0 "register_operand" "=e")
4536 (float:DF (match_operand:SI 1 "register_operand" "f")))]
4539 [(set_attr "type" "fp")
4540 (set_attr "length" "1")])
4542 (define_insn "floatsitf2"
4543 [(set (match_operand:TF 0 "register_operand" "=e")
4544 (float:TF (match_operand:SI 1 "register_operand" "f")))]
4545 "TARGET_FPU && TARGET_HARD_QUAD"
4547 [(set_attr "type" "fp")
4548 (set_attr "length" "1")])
4550 ;; Now the same for 64 bit sources.
4552 (define_insn "floatdisf2"
4553 [(set (match_operand:SF 0 "register_operand" "=f")
4554 (float:SF (match_operand:DI 1 "register_operand" "e")))]
4555 "TARGET_V9 && TARGET_FPU"
4557 [(set_attr "type" "fp")
4558 (set_attr "length" "1")])
4560 (define_insn "floatdidf2"
4561 [(set (match_operand:DF 0 "register_operand" "=e")
4562 (float:DF (match_operand:DI 1 "register_operand" "e")))]
4563 "TARGET_V9 && TARGET_FPU"
4565 [(set_attr "type" "fp")
4566 (set_attr "length" "1")])
4568 (define_insn "floatditf2"
4569 [(set (match_operand:TF 0 "register_operand" "=e")
4570 (float:TF (match_operand:DI 1 "register_operand" "e")))]
4571 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4573 [(set_attr "type" "fp")
4574 (set_attr "length" "1")])
4576 ;; Convert a float to an actual integer.
4577 ;; Truncation is performed as part of the conversion.
4579 (define_insn "fix_truncsfsi2"
4580 [(set (match_operand:SI 0 "register_operand" "=f")
4581 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4584 [(set_attr "type" "fp")
4585 (set_attr "length" "1")])
4587 (define_insn "fix_truncdfsi2"
4588 [(set (match_operand:SI 0 "register_operand" "=f")
4589 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4592 [(set_attr "type" "fp")
4593 (set_attr "length" "1")])
4595 (define_insn "fix_trunctfsi2"
4596 [(set (match_operand:SI 0 "register_operand" "=f")
4597 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4598 "TARGET_FPU && TARGET_HARD_QUAD"
4600 [(set_attr "type" "fp")
4601 (set_attr "length" "1")])
4603 ;; Now the same, for V9 targets
4605 (define_insn "fix_truncsfdi2"
4606 [(set (match_operand:DI 0 "register_operand" "=e")
4607 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4608 "TARGET_V9 && TARGET_FPU"
4610 [(set_attr "type" "fp")
4611 (set_attr "length" "1")])
4613 (define_insn "fix_truncdfdi2"
4614 [(set (match_operand:DI 0 "register_operand" "=e")
4615 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4616 "TARGET_V9 && TARGET_FPU"
4618 [(set_attr "type" "fp")
4619 (set_attr "length" "1")])
4621 (define_insn "fix_trunctfdi2"
4622 [(set (match_operand:DI 0 "register_operand" "=e")
4623 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
4624 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4626 [(set_attr "type" "fp")
4627 (set_attr "length" "1")])
4629 ;;- arithmetic instructions
4631 (define_expand "adddi3"
4632 [(set (match_operand:DI 0 "register_operand" "=r")
4633 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4634 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4638 if (! TARGET_ARCH64)
4640 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4641 gen_rtx_SET (VOIDmode, operands[0],
4642 gen_rtx_PLUS (DImode, operands[1],
4644 gen_rtx_CLOBBER (VOIDmode,
4645 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4648 if (arith_double_4096_operand(operands[2], DImode))
4650 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4651 gen_rtx_MINUS (DImode, operands[1],
4657 (define_insn "adddi3_insn_sp32"
4658 [(set (match_operand:DI 0 "register_operand" "=r")
4659 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4660 (match_operand:DI 2 "arith_double_operand" "rHI")))
4661 (clobber (reg:CC 100))]
4664 [(set_attr "length" "2")])
4667 [(set (match_operand:DI 0 "register_operand" "=r")
4668 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4669 (match_operand:DI 2 "arith_double_operand" "rHI")))
4670 (clobber (reg:CC 100))]
4671 "! TARGET_ARCH64 && reload_completed"
4672 [(parallel [(set (reg:CC_NOOV 100)
4673 (compare:CC_NOOV (plus:SI (match_dup 4)
4677 (plus:SI (match_dup 4) (match_dup 5)))])
4679 (plus:SI (plus:SI (match_dup 7)
4681 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4684 operands[3] = gen_lowpart (SImode, operands[0]);
4685 operands[4] = gen_lowpart (SImode, operands[1]);
4686 operands[5] = gen_lowpart (SImode, operands[2]);
4687 operands[6] = gen_highpart (SImode, operands[0]);
4688 operands[7] = gen_highpart (SImode, operands[1]);
4689 if (GET_CODE (operands[2]) == CONST_INT)
4691 if (INTVAL (operands[2]) < 0)
4692 operands[8] = constm1_rtx;
4694 operands[8] = const0_rtx;
4697 operands[8] = gen_highpart (SImode, operands[2]);
4701 [(set (match_operand:DI 0 "register_operand" "=r")
4702 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
4703 (match_operand:DI 2 "arith_double_operand" "rHI")))
4704 (clobber (reg:CC 100))]
4705 "! TARGET_ARCH64 && reload_completed"
4706 [(parallel [(set (reg:CC_NOOV 100)
4707 (compare:CC_NOOV (minus:SI (match_dup 4)
4711 (minus:SI (match_dup 4) (match_dup 5)))])
4713 (minus:SI (minus:SI (match_dup 7)
4715 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4718 operands[3] = gen_lowpart (SImode, operands[0]);
4719 operands[4] = gen_lowpart (SImode, operands[1]);
4720 operands[5] = gen_lowpart (SImode, operands[2]);
4721 operands[6] = gen_highpart (SImode, operands[0]);
4722 operands[7] = gen_highpart (SImode, operands[1]);
4723 if (GET_CODE (operands[2]) == CONST_INT)
4725 if (INTVAL (operands[2]) < 0)
4726 operands[8] = constm1_rtx;
4728 operands[8] = const0_rtx;
4731 operands[8] = gen_highpart (SImode, operands[2]);
4734 ;; LTU here means "carry set"
4736 [(set (match_operand:SI 0 "register_operand" "=r")
4737 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4738 (match_operand:SI 2 "arith_operand" "rI"))
4739 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4742 [(set_attr "type" "unary")
4743 (set_attr "length" "1")])
4745 (define_insn "*addx_extend_sp32"
4746 [(set (match_operand:DI 0 "register_operand" "=r")
4747 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4748 (match_operand:SI 2 "arith_operand" "rI"))
4749 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4752 [(set_attr "type" "unary")
4753 (set_attr "length" "2")])
4756 [(set (match_operand:DI 0 "register_operand" "")
4757 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
4758 (match_operand:SI 2 "arith_operand" ""))
4759 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4760 "! TARGET_ARCH64 && reload_completed"
4761 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4762 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4763 (set (match_dup 4) (const_int 0))]
4764 "operands[3] = gen_lowpart (SImode, operands[0]);
4765 operands[4] = gen_highpart (SImode, operands[1]);")
4767 (define_insn "*addx_extend_sp64"
4768 [(set (match_operand:DI 0 "register_operand" "=r")
4769 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4770 (match_operand:SI 2 "arith_operand" "rI"))
4771 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4773 "addx\\t%r1, %2, %0"
4774 [(set_attr "type" "misc")
4775 (set_attr "length" "1")])
4778 [(set (match_operand:SI 0 "register_operand" "=r")
4779 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4780 (match_operand:SI 2 "arith_operand" "rI"))
4781 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4783 "subx\\t%r1, %2, %0"
4784 [(set_attr "type" "misc")
4785 (set_attr "length" "1")])
4787 (define_insn "*subx_extend_sp64"
4788 [(set (match_operand:DI 0 "register_operand" "=r")
4789 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4790 (match_operand:SI 2 "arith_operand" "rI"))
4791 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4793 "subx\\t%r1, %2, %0"
4794 [(set_attr "type" "misc")
4795 (set_attr "length" "1")])
4797 (define_insn "*subx_extend"
4798 [(set (match_operand:DI 0 "register_operand" "=r")
4799 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4800 (match_operand:SI 2 "arith_operand" "rI"))
4801 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4804 [(set_attr "type" "unary")
4805 (set_attr "length" "2")])
4808 [(set (match_operand:DI 0 "register_operand" "=r")
4809 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4810 (match_operand:SI 2 "arith_operand" "rI"))
4811 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4812 "! TARGET_ARCH64 && reload_completed"
4813 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4814 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4815 (set (match_dup 4) (const_int 0))]
4816 "operands[3] = gen_lowpart (SImode, operands[0]);
4817 operands[4] = gen_highpart (SImode, operands[0]);")
4820 [(set (match_operand:DI 0 "register_operand" "=r")
4821 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4822 (match_operand:DI 2 "register_operand" "r")))
4823 (clobber (reg:CC 100))]
4826 [(set_attr "type" "multi")
4827 (set_attr "length" "2")])
4830 [(set (match_operand:DI 0 "register_operand" "")
4831 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4832 (match_operand:DI 2 "register_operand" "")))
4833 (clobber (reg:CC 100))]
4834 "! TARGET_ARCH64 && reload_completed"
4835 [(parallel [(set (reg:CC_NOOV 100)
4836 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4838 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4840 (plus:SI (plus:SI (match_dup 4) (const_int 0))
4841 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4842 "operands[3] = gen_lowpart (SImode, operands[2]);
4843 operands[4] = gen_highpart (SImode, operands[2]);
4844 operands[5] = gen_lowpart (SImode, operands[0]);
4845 operands[6] = gen_highpart (SImode, operands[0]);")
4847 (define_insn "*adddi3_sp64"
4848 [(set (match_operand:DI 0 "register_operand" "=r")
4849 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4850 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4853 [(set_attr "type" "binary")
4854 (set_attr "length" "1")])
4856 (define_expand "addsi3"
4857 [(set (match_operand:SI 0 "register_operand" "=r,d")
4858 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4859 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
4863 if (arith_4096_operand(operands[2], DImode))
4865 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4866 gen_rtx_MINUS (SImode, operands[1],
4872 (define_insn "*addsi3"
4873 [(set (match_operand:SI 0 "register_operand" "=r,d")
4874 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
4875 (match_operand:SI 2 "arith_operand" "rI,d")))]
4879 fpadd32s\\t%1, %2, %0"
4880 [(set_attr "type" "ialu,fp")
4881 (set_attr "length" "1")])
4883 (define_insn "*cmp_cc_plus"
4884 [(set (reg:CC_NOOV 100)
4885 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4886 (match_operand:SI 1 "arith_operand" "rI"))
4889 "addcc\\t%0, %1, %%g0"
4890 [(set_attr "type" "compare")
4891 (set_attr "length" "1")])
4893 (define_insn "*cmp_ccx_plus"
4894 [(set (reg:CCX_NOOV 100)
4895 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4896 (match_operand:DI 1 "arith_double_operand" "rHI"))
4899 "addcc\\t%0, %1, %%g0"
4900 [(set_attr "type" "compare")
4901 (set_attr "length" "1")])
4903 (define_insn "*cmp_cc_plus_set"
4904 [(set (reg:CC_NOOV 100)
4905 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4906 (match_operand:SI 2 "arith_operand" "rI"))
4908 (set (match_operand:SI 0 "register_operand" "=r")
4909 (plus:SI (match_dup 1) (match_dup 2)))]
4911 "addcc\\t%1, %2, %0"
4912 [(set_attr "type" "compare")
4913 (set_attr "length" "1")])
4915 (define_insn "*cmp_ccx_plus_set"
4916 [(set (reg:CCX_NOOV 100)
4917 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4918 (match_operand:DI 2 "arith_double_operand" "rHI"))
4920 (set (match_operand:DI 0 "register_operand" "=r")
4921 (plus:DI (match_dup 1) (match_dup 2)))]
4923 "addcc\\t%1, %2, %0"
4924 [(set_attr "type" "compare")
4925 (set_attr "length" "1")])
4927 (define_expand "subdi3"
4928 [(set (match_operand:DI 0 "register_operand" "=r")
4929 (minus:DI (match_operand:DI 1 "register_operand" "r")
4930 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
4934 if (! TARGET_ARCH64)
4936 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4937 gen_rtx_SET (VOIDmode, operands[0],
4938 gen_rtx_MINUS (DImode, operands[1],
4940 gen_rtx_CLOBBER (VOIDmode,
4941 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4944 if (arith_double_4096_operand(operands[2], DImode))
4946 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4947 gen_rtx_PLUS (DImode, operands[1],
4953 (define_insn "*subdi3_sp32"
4954 [(set (match_operand:DI 0 "register_operand" "=r")
4955 (minus:DI (match_operand:DI 1 "register_operand" "r")
4956 (match_operand:DI 2 "arith_double_operand" "rHI")))
4957 (clobber (reg:CC 100))]
4960 [(set_attr "length" "2")])
4963 [(set (match_operand:DI 0 "register_operand" "")
4964 (minus:DI (match_operand:DI 1 "register_operand" "")
4965 (match_operand:DI 2 "arith_double_operand" "")))
4966 (clobber (reg:CC 100))]
4969 && (GET_CODE (operands[2]) == CONST_INT
4970 || GET_CODE (operands[2]) == CONST_DOUBLE)"
4971 [(clobber (const_int 0))]
4976 highp = gen_highpart (SImode, operands[2]);
4977 lowp = gen_lowpart (SImode, operands[2]);
4978 if ((lowp == const0_rtx)
4979 && (operands[0] == operands[1]))
4981 emit_insn (gen_rtx_SET (VOIDmode,
4982 gen_highpart (SImode, operands[0]),
4983 gen_rtx_MINUS (SImode,
4984 gen_highpart (SImode, operands[1]),
4989 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
4990 gen_lowpart (SImode, operands[1]),
4992 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
4993 gen_highpart (SImode, operands[1]),
5000 [(set (match_operand:DI 0 "register_operand" "")
5001 (minus:DI (match_operand:DI 1 "register_operand" "")
5002 (match_operand:DI 2 "register_operand" "")))
5003 (clobber (reg:CC 100))]
5005 && reload_completed"
5006 [(clobber (const_int 0))]
5009 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5010 gen_lowpart (SImode, operands[1]),
5011 gen_lowpart (SImode, operands[2])));
5012 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5013 gen_highpart (SImode, operands[1]),
5014 gen_highpart (SImode, operands[2])));
5019 [(set (match_operand:DI 0 "register_operand" "=r")
5020 (minus:DI (match_operand:DI 1 "register_operand" "r")
5021 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5022 (clobber (reg:CC 100))]
5025 [(set_attr "type" "multi")
5026 (set_attr "length" "2")])
5029 [(set (match_operand:DI 0 "register_operand" "")
5030 (minus:DI (match_operand:DI 1 "register_operand" "")
5031 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5032 (clobber (reg:CC 100))]
5033 "! TARGET_ARCH64 && reload_completed"
5034 [(parallel [(set (reg:CC_NOOV 100)
5035 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5037 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5039 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5040 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5041 "operands[3] = gen_lowpart (SImode, operands[1]);
5042 operands[4] = gen_highpart (SImode, operands[1]);
5043 operands[5] = gen_lowpart (SImode, operands[0]);
5044 operands[6] = gen_highpart (SImode, operands[0]);")
5046 (define_insn "*subdi3_sp64"
5047 [(set (match_operand:DI 0 "register_operand" "=r")
5048 (minus:DI (match_operand:DI 1 "register_operand" "r")
5049 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5052 [(set_attr "type" "binary")
5053 (set_attr "length" "1")])
5055 (define_expand "subsi3"
5056 [(set (match_operand:SI 0 "register_operand" "=r,d")
5057 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5058 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5062 if (arith_4096_operand(operands[2], DImode))
5064 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5065 gen_rtx_PLUS (SImode, operands[1],
5071 (define_insn "*subsi3"
5072 [(set (match_operand:SI 0 "register_operand" "=r,d")
5073 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5074 (match_operand:SI 2 "arith_operand" "rI,d")))]
5078 fpsub32s\\t%1, %2, %0"
5079 [(set_attr "type" "ialu,fp")
5080 (set_attr "length" "1")])
5082 (define_insn "*cmp_minus_cc"
5083 [(set (reg:CC_NOOV 100)
5084 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5085 (match_operand:SI 1 "arith_operand" "rI"))
5088 "subcc\\t%r0, %1, %%g0"
5089 [(set_attr "type" "compare")
5090 (set_attr "length" "1")])
5092 (define_insn "*cmp_minus_ccx"
5093 [(set (reg:CCX_NOOV 100)
5094 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5095 (match_operand:DI 1 "arith_double_operand" "rHI"))
5098 "subcc\\t%0, %1, %%g0"
5099 [(set_attr "type" "compare")
5100 (set_attr "length" "1")])
5102 (define_insn "cmp_minus_cc_set"
5103 [(set (reg:CC_NOOV 100)
5104 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5105 (match_operand:SI 2 "arith_operand" "rI"))
5107 (set (match_operand:SI 0 "register_operand" "=r")
5108 (minus:SI (match_dup 1) (match_dup 2)))]
5110 "subcc\\t%r1, %2, %0"
5111 [(set_attr "type" "compare")
5112 (set_attr "length" "1")])
5114 (define_insn "*cmp_minus_ccx_set"
5115 [(set (reg:CCX_NOOV 100)
5116 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5117 (match_operand:DI 2 "arith_double_operand" "rHI"))
5119 (set (match_operand:DI 0 "register_operand" "=r")
5120 (minus:DI (match_dup 1) (match_dup 2)))]
5122 "subcc\\t%1, %2, %0"
5123 [(set_attr "type" "compare")
5124 (set_attr "length" "1")])
5126 ;; Integer Multiply/Divide.
5128 ;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't
5129 ;; we used. We still use them in 32 bit v9 compilers.
5130 ;; The 64 bit v9 compiler will (/should) widen the args and use muldi3.
5132 (define_insn "mulsi3"
5133 [(set (match_operand:SI 0 "register_operand" "=r")
5134 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5135 (match_operand:SI 2 "arith_operand" "rI")))]
5138 [(set_attr "type" "imul")
5139 (set_attr "length" "1")])
5141 (define_expand "muldi3"
5142 [(set (match_operand:DI 0 "register_operand" "=r")
5143 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5144 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5145 "TARGET_ARCH64 || TARGET_V8PLUS"
5150 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5155 (define_insn "*muldi3_sp64"
5156 [(set (match_operand:DI 0 "register_operand" "=r")
5157 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5158 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5161 [(set_attr "type" "imul")
5162 (set_attr "length" "1")])
5164 ;; V8plus wide multiply.
5166 (define_insn "muldi3_v8plus"
5167 [(set (match_operand:DI 0 "register_operand" "=r,h")
5168 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5169 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
5170 (clobber (match_scratch:SI 3 "=&h,X"))
5171 (clobber (match_scratch:SI 4 "=&h,X"))]
5175 if (sparc_check_64 (operands[1], insn) <= 0)
5176 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
5177 if (which_alternative == 1)
5178 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
5179 if (sparc_check_64 (operands[2], insn) <= 0)
5180 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
5181 if (which_alternative == 1)
5182 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\";
5184 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\";
5186 [(set_attr "length" "9,8")])
5188 ;; It is not known whether this will match.
5190 (define_insn "*cmp_mul_set"
5191 [(set (match_operand:SI 0 "register_operand" "=r")
5192 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5193 (match_operand:SI 2 "arith_operand" "rI")))
5194 (set (reg:CC_NOOV 100)
5195 (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2))
5197 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5198 "smulcc\\t%1, %2, %0"
5199 [(set_attr "type" "imul")
5200 (set_attr "length" "1")])
5202 (define_expand "mulsidi3"
5203 [(set (match_operand:DI 0 "register_operand" "")
5204 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5205 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5209 if (CONSTANT_P (operands[2]))
5213 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5217 emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
5222 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5227 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
5228 ;; registers can hold 64 bit values in the V8plus environment.
5230 (define_insn "mulsidi3_v8plus"
5231 [(set (match_operand:DI 0 "register_operand" "=h,r")
5232 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5233 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5234 (clobber (match_scratch:SI 3 "=X,&h"))]
5237 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5238 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5239 [(set_attr "length" "2,3")])
5242 (define_insn "const_mulsidi3_v8plus"
5243 [(set (match_operand:DI 0 "register_operand" "=h,r")
5244 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5245 (match_operand:SI 2 "small_int" "I,I")))
5246 (clobber (match_scratch:SI 3 "=X,&h"))]
5249 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5250 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5251 [(set_attr "length" "2,3")])
5254 (define_insn "*mulsidi3_sp32"
5255 [(set (match_operand:DI 0 "register_operand" "=r")
5256 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5257 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5261 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5263 [(set (attr "length")
5264 (if_then_else (eq_attr "isa" "sparclet")
5265 (const_int 1) (const_int 2)))])
5267 ;; Extra pattern, because sign_extend of a constant isn't valid.
5270 (define_insn "const_mulsidi3"
5271 [(set (match_operand:DI 0 "register_operand" "=r")
5272 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5273 (match_operand:SI 2 "small_int" "I")))]
5277 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5279 [(set (attr "length")
5280 (if_then_else (eq_attr "isa" "sparclet")
5281 (const_int 1) (const_int 2)))])
5283 (define_expand "smulsi3_highpart"
5284 [(set (match_operand:SI 0 "register_operand" "")
5286 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5287 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5292 if (CONSTANT_P (operands[2]))
5296 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5302 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5307 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5308 operands[2], GEN_INT (32)));
5314 (define_insn "smulsi3_highpart_v8plus"
5315 [(set (match_operand:SI 0 "register_operand" "=h,r")
5317 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5318 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5319 (match_operand:SI 3 "const_int_operand" "i,i"))))
5320 (clobber (match_scratch:SI 4 "=X,&h"))]
5323 smul %1,%2,%0\;srlx %0,%3,%0
5324 smul %1,%2,%4\;srlx %4,%3,%0"
5325 [(set_attr "length" "2")])
5327 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5330 [(set (match_operand:SI 0 "register_operand" "=h,r")
5333 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5334 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5335 (match_operand:SI 3 "const_int_operand" "i,i"))
5337 (clobber (match_scratch:SI 4 "=X,&h"))]
5340 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5341 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5342 [(set_attr "length" "2")])
5345 (define_insn "const_smulsi3_highpart_v8plus"
5346 [(set (match_operand:SI 0 "register_operand" "=h,r")
5348 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5349 (match_operand 2 "small_int" "i,i"))
5350 (match_operand:SI 3 "const_int_operand" "i,i"))))
5351 (clobber (match_scratch:SI 4 "=X,&h"))]
5354 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5355 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5356 [(set_attr "length" "2")])
5359 (define_insn "*smulsi3_highpart_sp32"
5360 [(set (match_operand:SI 0 "register_operand" "=r")
5362 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5363 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5366 && ! TARGET_LIVE_G0"
5367 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5368 [(set_attr "length" "2")])
5371 (define_insn "const_smulsi3_highpart"
5372 [(set (match_operand:SI 0 "register_operand" "=r")
5374 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5375 (match_operand:SI 2 "register_operand" "r"))
5378 && ! TARGET_LIVE_G0"
5379 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5380 [(set_attr "length" "2")])
5382 (define_expand "umulsidi3"
5383 [(set (match_operand:DI 0 "register_operand" "")
5384 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5385 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5389 if (CONSTANT_P (operands[2]))
5393 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5397 emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
5402 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5408 (define_insn "umulsidi3_v8plus"
5409 [(set (match_operand:DI 0 "register_operand" "=h,r")
5410 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5411 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5412 (clobber (match_scratch:SI 3 "=X,&h"))]
5415 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5416 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5417 [(set_attr "length" "2,3")])
5420 (define_insn "*umulsidi3_sp32"
5421 [(set (match_operand:DI 0 "register_operand" "=r")
5422 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5423 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5427 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5429 [(set (attr "length")
5430 (if_then_else (eq_attr "isa" "sparclet")
5431 (const_int 1) (const_int 2)))])
5433 ;; Extra pattern, because sign_extend of a constant isn't valid.
5436 (define_insn "const_umulsidi3"
5437 [(set (match_operand:DI 0 "register_operand" "=r")
5438 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5439 (match_operand:SI 2 "uns_small_int" "")))]
5443 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
5445 [(set (attr "length")
5446 (if_then_else (eq_attr "isa" "sparclet")
5447 (const_int 1) (const_int 2)))])
5450 (define_insn "const_umulsidi3_v8plus"
5451 [(set (match_operand:DI 0 "register_operand" "=h,r")
5452 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5453 (match_operand:SI 2 "uns_small_int" "")))
5454 (clobber (match_scratch:SI 3 "=X,h"))]
5457 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
5458 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
5459 [(set_attr "length" "2,3")])
5461 (define_expand "umulsi3_highpart"
5462 [(set (match_operand:SI 0 "register_operand" "")
5464 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5465 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5470 if (CONSTANT_P (operands[2]))
5474 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5480 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5485 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5486 operands[2], GEN_INT (32)));
5492 (define_insn "umulsi3_highpart_v8plus"
5493 [(set (match_operand:SI 0 "register_operand" "=h,r")
5495 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5496 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5497 (match_operand:SI 3 "const_int_operand" "i,i"))))
5498 (clobber (match_scratch:SI 4 "=X,h"))]
5501 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5502 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5503 [(set_attr "length" "2")])
5506 (define_insn "const_umulsi3_highpart_v8plus"
5507 [(set (match_operand:SI 0 "register_operand" "=h,r")
5509 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5510 (match_operand:SI 2 "uns_small_int" ""))
5511 (match_operand:SI 3 "const_int_operand" "i,i"))))
5512 (clobber (match_scratch:SI 4 "=X,h"))]
5515 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
5516 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
5517 [(set_attr "length" "2")])
5520 (define_insn "*umulsi3_highpart_sp32"
5521 [(set (match_operand:SI 0 "register_operand" "=r")
5523 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5524 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5527 && ! TARGET_LIVE_G0"
5528 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5529 [(set_attr "length" "2")])
5532 (define_insn "const_umulsi3_highpart"
5533 [(set (match_operand:SI 0 "register_operand" "=r")
5535 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5536 (match_operand:SI 2 "uns_small_int" ""))
5539 && ! TARGET_LIVE_G0"
5540 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
5541 [(set_attr "length" "2")])
5543 ;; The v8 architecture specifies that there must be 3 instructions between
5544 ;; a y register write and a use of it for correct results.
5547 (define_insn "divsi3"
5548 [(set (match_operand:SI 0 "register_operand" "=r,r")
5549 (div:SI (match_operand:SI 1 "register_operand" "r,r")
5550 (match_operand:SI 2 "input_operand" "rI,m")))
5551 (clobber (match_scratch:SI 3 "=&r,&r"))]
5553 || TARGET_DEPRECATED_V8_INSNS)
5554 && ! TARGET_LIVE_G0"
5557 if (which_alternative == 0)
5559 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0\";
5561 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
5564 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
5566 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\";
5568 [(set (attr "length")
5569 (if_then_else (eq_attr "isa" "v9")
5570 (const_int 4) (const_int 7)))])
5572 (define_insn "divdi3"
5573 [(set (match_operand:DI 0 "register_operand" "=r")
5574 (div:DI (match_operand:DI 1 "register_operand" "r")
5575 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5577 "sdivx\\t%1, %2, %0")
5579 ;; It is not known whether this will match.
5581 ;; XXX I hope it doesn't fucking match...
5582 (define_insn "*cmp_sdiv_cc_set"
5583 [(set (match_operand:SI 0 "register_operand" "=r")
5584 (div:SI (match_operand:SI 1 "register_operand" "r")
5585 (match_operand:SI 2 "arith_operand" "rI")))
5587 (compare:CC (div:SI (match_dup 1) (match_dup 2))
5589 (clobber (match_scratch:SI 3 "=&r"))]
5591 || TARGET_DEPRECATED_V8_INSNS)
5592 && ! TARGET_LIVE_G0"
5596 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdivcc\\t%1, %2, %0\";
5598 return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
5600 [(set (attr "length")
5601 (if_then_else (eq_attr "isa" "v9")
5602 (const_int 3) (const_int 6)))])
5605 (define_insn "udivsi3"
5606 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5607 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5608 (match_operand:SI 2 "input_operand" "rI,m,r")))]
5610 || TARGET_DEPRECATED_V8_INSNS)
5611 && ! TARGET_LIVE_G0"
5614 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
5615 switch (which_alternative)
5619 return \"udiv\\t%1, %2, %0\";
5620 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
5622 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
5624 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
5627 [(set (attr "length")
5628 (if_then_else (and (eq_attr "isa" "v9")
5629 (eq_attr "alternative" "0"))
5630 (const_int 2) (const_int 5)))])
5632 (define_insn "udivdi3"
5633 [(set (match_operand:DI 0 "register_operand" "=r")
5634 (udiv:DI (match_operand:DI 1 "register_operand" "r")
5635 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5637 "udivx\\t%1, %2, %0")
5639 ;; It is not known whether this will match.
5641 ;; XXX I hope it doesn't fucking match...
5642 (define_insn "*cmp_udiv_cc_set"
5643 [(set (match_operand:SI 0 "register_operand" "=r")
5644 (udiv:SI (match_operand:SI 1 "register_operand" "r")
5645 (match_operand:SI 2 "arith_operand" "rI")))
5647 (compare:CC (udiv:SI (match_dup 1) (match_dup 2))
5650 || TARGET_DEPRECATED_V8_INSNS)
5651 && ! TARGET_LIVE_G0"
5655 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
5657 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
5659 [(set (attr "length")
5660 (if_then_else (eq_attr "isa" "v9")
5661 (const_int 2) (const_int 5)))])
5663 ; sparclet multiply/accumulate insns
5665 (define_insn "*smacsi"
5666 [(set (match_operand:SI 0 "register_operand" "=r")
5667 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5668 (match_operand:SI 2 "arith_operand" "rI"))
5669 (match_operand:SI 3 "register_operand" "0")))]
5672 [(set_attr "type" "imul")
5673 (set_attr "length" "1")])
5675 (define_insn "*smacdi"
5676 [(set (match_operand:DI 0 "register_operand" "=r")
5677 (plus:DI (mult:DI (sign_extend:DI
5678 (match_operand:SI 1 "register_operand" "%r"))
5680 (match_operand:SI 2 "register_operand" "r")))
5681 (match_operand:DI 3 "register_operand" "0")))]
5683 "smacd\\t%1, %2, %L0"
5684 [(set_attr "type" "imul")
5685 (set_attr "length" "1")])
5687 (define_insn "*umacdi"
5688 [(set (match_operand:DI 0 "register_operand" "=r")
5689 (plus:DI (mult:DI (zero_extend:DI
5690 (match_operand:SI 1 "register_operand" "%r"))
5692 (match_operand:SI 2 "register_operand" "r")))
5693 (match_operand:DI 3 "register_operand" "0")))]
5695 "umacd\\t%1, %2, %L0"
5696 [(set_attr "type" "imul")
5697 (set_attr "length" "1")])
5699 ;;- Boolean instructions
5700 ;; We define DImode `and' so with DImode `not' we can get
5701 ;; DImode `andn'. Other combinations are possible.
5703 (define_expand "anddi3"
5704 [(set (match_operand:DI 0 "register_operand" "")
5705 (and:DI (match_operand:DI 1 "arith_double_operand" "")
5706 (match_operand:DI 2 "arith_double_operand" "")))]
5710 (define_insn "*anddi3_sp32"
5711 [(set (match_operand:DI 0 "register_operand" "=r,b")
5712 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5713 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5718 [(set_attr "type" "ialu,fp")
5719 (set_attr "length" "2,1")])
5721 (define_insn "*anddi3_sp64"
5722 [(set (match_operand:DI 0 "register_operand" "=r,b")
5723 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5724 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5729 [(set_attr "type" "ialu,fp")
5730 (set_attr "length" "1,1")])
5732 (define_insn "andsi3"
5733 [(set (match_operand:SI 0 "register_operand" "=r,d")
5734 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5735 (match_operand:SI 2 "arith_operand" "rI,d")))]
5740 [(set_attr "type" "ialu,fp")
5741 (set_attr "length" "1,1")])
5744 [(set (match_operand:SI 0 "register_operand" "")
5745 (and:SI (match_operand:SI 1 "register_operand" "")
5746 (match_operand:SI 2 "" "")))
5747 (clobber (match_operand:SI 3 "register_operand" ""))]
5748 "GET_CODE (operands[2]) == CONST_INT
5749 && !SMALL_INT32 (operands[2])
5750 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5751 [(set (match_dup 3) (match_dup 4))
5752 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5755 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5758 ;; Split DImode logical operations requiring two instructions.
5760 [(set (match_operand:DI 0 "register_operand" "")
5761 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
5762 [(match_operand:DI 2 "register_operand" "")
5763 (match_operand:DI 3 "arith_double_operand" "")]))]
5766 && ((GET_CODE (operands[0]) == REG
5767 && REGNO (operands[0]) < 32)
5768 || (GET_CODE (operands[0]) == SUBREG
5769 && GET_CODE (SUBREG_REG (operands[0])) == REG
5770 && REGNO (SUBREG_REG (operands[0])) < 32))"
5771 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5772 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5775 if (GET_CODE (operands[0]) == SUBREG)
5776 operands[0] = alter_subreg (operands[0]);
5777 operands[4] = gen_highpart (SImode, operands[0]);
5778 operands[5] = gen_lowpart (SImode, operands[0]);
5779 operands[6] = gen_highpart (SImode, operands[2]);
5780 operands[7] = gen_lowpart (SImode, operands[2]);
5781 if (GET_CODE (operands[3]) == CONST_INT)
5783 if (INTVAL (operands[3]) < 0)
5784 operands[8] = constm1_rtx;
5786 operands[8] = const0_rtx;
5789 operands[8] = gen_highpart (SImode, operands[3]);
5790 operands[9] = gen_lowpart (SImode, operands[3]);
5793 (define_insn "*and_not_di_sp32"
5794 [(set (match_operand:DI 0 "register_operand" "=r,b")
5795 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5796 (match_operand:DI 2 "register_operand" "r,b")))]
5800 fandnot1\\t%1, %2, %0"
5801 [(set_attr "type" "ialu,fp")
5802 (set_attr "length" "2,1")])
5805 [(set (match_operand:DI 0 "register_operand" "")
5806 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5807 (match_operand:DI 2 "register_operand" "")))]
5810 && ((GET_CODE (operands[0]) == REG
5811 && REGNO (operands[0]) < 32)
5812 || (GET_CODE (operands[0]) == SUBREG
5813 && GET_CODE (SUBREG_REG (operands[0])) == REG
5814 && REGNO (SUBREG_REG (operands[0])) < 32))"
5815 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5816 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5817 "if (GET_CODE (operands[0]) == SUBREG)
5818 operands[0] = alter_subreg (operands[0]);
5819 operands[3] = gen_highpart (SImode, operands[0]);
5820 operands[4] = gen_highpart (SImode, operands[1]);
5821 operands[5] = gen_highpart (SImode, operands[2]);
5822 operands[6] = gen_lowpart (SImode, operands[0]);
5823 operands[7] = gen_lowpart (SImode, operands[1]);
5824 operands[8] = gen_lowpart (SImode, operands[2]);")
5826 (define_insn "*and_not_di_sp64"
5827 [(set (match_operand:DI 0 "register_operand" "=r,b")
5828 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5829 (match_operand:DI 2 "register_operand" "r,b")))]
5833 fandnot1\\t%1, %2, %0"
5834 [(set_attr "type" "ialu,fp")
5835 (set_attr "length" "1,1")])
5837 (define_insn "*and_not_si"
5838 [(set (match_operand:SI 0 "register_operand" "=r,d")
5839 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5840 (match_operand:SI 2 "register_operand" "r,d")))]
5844 fandnot1s\\t%1, %2, %0"
5845 [(set_attr "type" "ialu,fp")
5846 (set_attr "length" "1,1")])
5848 (define_expand "iordi3"
5849 [(set (match_operand:DI 0 "register_operand" "")
5850 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5851 (match_operand:DI 2 "arith_double_operand" "")))]
5855 (define_insn "*iordi3_sp32"
5856 [(set (match_operand:DI 0 "register_operand" "=r,b")
5857 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5858 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5863 [(set_attr "type" "ialu,fp")
5864 (set_attr "length" "2,1")])
5866 (define_insn "*iordi3_sp64"
5867 [(set (match_operand:DI 0 "register_operand" "=r,b")
5868 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5869 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5874 [(set_attr "type" "ialu,fp")
5875 (set_attr "length" "1,1")])
5877 (define_insn "iorsi3"
5878 [(set (match_operand:SI 0 "register_operand" "=r,d")
5879 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
5880 (match_operand:SI 2 "arith_operand" "rI,d")))]
5885 [(set_attr "type" "ialu,fp")
5886 (set_attr "length" "1,1")])
5889 [(set (match_operand:SI 0 "register_operand" "")
5890 (ior:SI (match_operand:SI 1 "register_operand" "")
5891 (match_operand:SI 2 "" "")))
5892 (clobber (match_operand:SI 3 "register_operand" ""))]
5893 "GET_CODE (operands[2]) == CONST_INT
5894 && !SMALL_INT32 (operands[2])
5895 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5896 [(set (match_dup 3) (match_dup 4))
5897 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5900 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
5903 (define_insn "*or_not_di_sp32"
5904 [(set (match_operand:DI 0 "register_operand" "=r,b")
5905 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5906 (match_operand:DI 2 "register_operand" "r,b")))]
5910 fornot1\\t%1, %2, %0"
5911 [(set_attr "type" "ialu,fp")
5912 (set_attr "length" "2,1")])
5915 [(set (match_operand:DI 0 "register_operand" "")
5916 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
5917 (match_operand:DI 2 "register_operand" "")))]
5920 && ((GET_CODE (operands[0]) == REG
5921 && REGNO (operands[0]) < 32)
5922 || (GET_CODE (operands[0]) == SUBREG
5923 && GET_CODE (SUBREG_REG (operands[0])) == REG
5924 && REGNO (SUBREG_REG (operands[0])) < 32))"
5925 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5926 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5927 "if (GET_CODE (operands[0]) == SUBREG)
5928 operands[0] = alter_subreg (operands[0]);
5929 operands[3] = gen_highpart (SImode, operands[0]);
5930 operands[4] = gen_highpart (SImode, operands[1]);
5931 operands[5] = gen_highpart (SImode, operands[2]);
5932 operands[6] = gen_lowpart (SImode, operands[0]);
5933 operands[7] = gen_lowpart (SImode, operands[1]);
5934 operands[8] = gen_lowpart (SImode, operands[2]);")
5936 (define_insn "*or_not_di_sp64"
5937 [(set (match_operand:DI 0 "register_operand" "=r,b")
5938 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5939 (match_operand:DI 2 "register_operand" "r,b")))]
5943 fornot1\\t%1, %2, %0"
5944 [(set_attr "type" "ialu,fp")
5945 (set_attr "length" "1,1")])
5947 (define_insn "*or_not_si"
5948 [(set (match_operand:SI 0 "register_operand" "=r,d")
5949 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5950 (match_operand:SI 2 "register_operand" "r,d")))]
5954 fornot1s\\t%1, %2, %0"
5955 [(set_attr "type" "ialu,fp")
5956 (set_attr "length" "1,1")])
5958 (define_expand "xordi3"
5959 [(set (match_operand:DI 0 "register_operand" "")
5960 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
5961 (match_operand:DI 2 "arith_double_operand" "")))]
5965 (define_insn "*xordi3_sp32"
5966 [(set (match_operand:DI 0 "register_operand" "=r,b")
5967 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5968 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5973 [(set_attr "length" "2,1")
5974 (set_attr "type" "ialu,fp")])
5976 (define_insn "*xordi3_sp64"
5977 [(set (match_operand:DI 0 "register_operand" "=r,b")
5978 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
5979 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5984 [(set_attr "type" "ialu,fp")
5985 (set_attr "length" "1,1")])
5987 (define_insn "*xordi3_sp64_dbl"
5988 [(set (match_operand:DI 0 "register_operand" "=r")
5989 (xor:DI (match_operand:DI 1 "register_operand" "r")
5990 (match_operand:DI 2 "const64_operand" "")))]
5992 && HOST_BITS_PER_WIDE_INT != 64)"
5994 [(set_attr "type" "ialu")
5995 (set_attr "length" "1")])
5997 (define_insn "xorsi3"
5998 [(set (match_operand:SI 0 "register_operand" "=r,d")
5999 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6000 (match_operand:SI 2 "arith_operand" "rI,d")))]
6005 [(set_attr "type" "ialu,fp")
6006 (set_attr "length" "1,1")])
6009 [(set (match_operand:SI 0 "register_operand" "")
6010 (xor:SI (match_operand:SI 1 "register_operand" "")
6011 (match_operand:SI 2 "" "")))
6012 (clobber (match_operand:SI 3 "register_operand" ""))]
6013 "GET_CODE (operands[2]) == CONST_INT
6014 && !SMALL_INT32 (operands[2])
6015 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6016 [(set (match_dup 3) (match_dup 4))
6017 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6020 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6024 [(set (match_operand:SI 0 "register_operand" "")
6025 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6026 (match_operand:SI 2 "" ""))))
6027 (clobber (match_operand:SI 3 "register_operand" ""))]
6028 "GET_CODE (operands[2]) == CONST_INT
6029 && !SMALL_INT32 (operands[2])
6030 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6031 [(set (match_dup 3) (match_dup 4))
6032 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6035 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6038 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6039 ;; Combine now canonicalizes to the rightmost expression.
6040 (define_insn "*xor_not_di_sp32"
6041 [(set (match_operand:DI 0 "register_operand" "=r,b")
6042 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6043 (match_operand:DI 2 "register_operand" "r,b"))))]
6048 [(set_attr "length" "2,1")
6049 (set_attr "type" "ialu,fp")])
6052 [(set (match_operand:DI 0 "register_operand" "")
6053 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6054 (match_operand:DI 2 "register_operand" ""))))]
6057 && ((GET_CODE (operands[0]) == REG
6058 && REGNO (operands[0]) < 32)
6059 || (GET_CODE (operands[0]) == SUBREG
6060 && GET_CODE (SUBREG_REG (operands[0])) == REG
6061 && REGNO (SUBREG_REG (operands[0])) < 32))"
6062 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6063 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6064 "if (GET_CODE (operands[0]) == SUBREG)
6065 operands[0] = alter_subreg (operands[0]);
6066 operands[3] = gen_highpart (SImode, operands[0]);
6067 operands[4] = gen_highpart (SImode, operands[1]);
6068 operands[5] = gen_highpart (SImode, operands[2]);
6069 operands[6] = gen_lowpart (SImode, operands[0]);
6070 operands[7] = gen_lowpart (SImode, operands[1]);
6071 operands[8] = gen_lowpart (SImode, operands[2]);")
6073 (define_insn "*xor_not_di_sp64"
6074 [(set (match_operand:DI 0 "register_operand" "=r,b")
6075 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6076 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6081 [(set_attr "type" "ialu,fp")
6082 (set_attr "length" "1,1")])
6084 (define_insn "*xor_not_si"
6085 [(set (match_operand:SI 0 "register_operand" "=r,d")
6086 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6087 (match_operand:SI 2 "arith_operand" "rI,d"))))]
6091 fxnors\\t%1, %2, %0"
6092 [(set_attr "type" "ialu,fp")
6093 (set_attr "length" "1,1")])
6095 ;; These correspond to the above in the case where we also (or only)
6096 ;; want to set the condition code.
6098 (define_insn "*cmp_cc_arith_op"
6101 (match_operator:SI 2 "cc_arithop"
6102 [(match_operand:SI 0 "arith_operand" "%r")
6103 (match_operand:SI 1 "arith_operand" "rI")])
6106 "%A2cc\\t%0, %1, %%g0"
6107 [(set_attr "type" "compare")
6108 (set_attr "length" "1")])
6110 (define_insn "*cmp_ccx_arith_op"
6113 (match_operator:DI 2 "cc_arithop"
6114 [(match_operand:DI 0 "arith_double_operand" "%r")
6115 (match_operand:DI 1 "arith_double_operand" "rHI")])
6118 "%A2cc\\t%0, %1, %%g0"
6119 [(set_attr "type" "compare")
6120 (set_attr "length" "1")])
6122 (define_insn "*cmp_cc_arith_op_set"
6125 (match_operator:SI 3 "cc_arithop"
6126 [(match_operand:SI 1 "arith_operand" "%r")
6127 (match_operand:SI 2 "arith_operand" "rI")])
6129 (set (match_operand:SI 0 "register_operand" "=r")
6132 "%A3cc\\t%1, %2, %0"
6133 [(set_attr "type" "compare")
6134 (set_attr "length" "1")])
6136 (define_insn "*cmp_ccx_arith_op_set"
6139 (match_operator:DI 3 "cc_arithop"
6140 [(match_operand:DI 1 "arith_double_operand" "%r")
6141 (match_operand:DI 2 "arith_double_operand" "rHI")])
6143 (set (match_operand:DI 0 "register_operand" "=r")
6146 "%A3cc\\t%1, %2, %0"
6147 [(set_attr "type" "compare")
6148 (set_attr "length" "1")])
6150 (define_insn "*cmp_cc_xor_not"
6153 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6154 (match_operand:SI 1 "arith_operand" "rI")))
6157 "xnorcc\\t%r0, %1, %%g0"
6158 [(set_attr "type" "compare")
6159 (set_attr "length" "1")])
6161 (define_insn "*cmp_ccx_xor_not"
6164 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6165 (match_operand:DI 1 "arith_double_operand" "rHI")))
6168 "xnorcc\\t%r0, %1, %%g0"
6169 [(set_attr "type" "compare")
6170 (set_attr "length" "1")])
6172 (define_insn "*cmp_cc_xor_not_set"
6175 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6176 (match_operand:SI 2 "arith_operand" "rI")))
6178 (set (match_operand:SI 0 "register_operand" "=r")
6179 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6181 "xnorcc\\t%r1, %2, %0"
6182 [(set_attr "type" "compare")
6183 (set_attr "length" "1")])
6185 (define_insn "*cmp_ccx_xor_not_set"
6188 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6189 (match_operand:DI 2 "arith_double_operand" "rHI")))
6191 (set (match_operand:DI 0 "register_operand" "=r")
6192 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6194 "xnorcc\\t%r1, %2, %0"
6195 [(set_attr "type" "compare")
6196 (set_attr "length" "1")])
6198 (define_insn "*cmp_cc_arith_op_not"
6201 (match_operator:SI 2 "cc_arithopn"
6202 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6203 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6206 "%B2cc\\t%r1, %0, %%g0"
6207 [(set_attr "type" "compare")
6208 (set_attr "length" "1")])
6210 (define_insn "*cmp_ccx_arith_op_not"
6213 (match_operator:DI 2 "cc_arithopn"
6214 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6215 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6218 "%B2cc\\t%r1, %0, %%g0"
6219 [(set_attr "type" "compare")
6220 (set_attr "length" "1")])
6222 (define_insn "*cmp_cc_arith_op_not_set"
6225 (match_operator:SI 3 "cc_arithopn"
6226 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6227 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6229 (set (match_operand:SI 0 "register_operand" "=r")
6232 "%B3cc\\t%r2, %1, %0"
6233 [(set_attr "type" "compare")
6234 (set_attr "length" "1")])
6236 (define_insn "*cmp_ccx_arith_op_not_set"
6239 (match_operator:DI 3 "cc_arithopn"
6240 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6241 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6243 (set (match_operand:DI 0 "register_operand" "=r")
6246 "%B3cc\\t%r2, %1, %0"
6247 [(set_attr "type" "compare")
6248 (set_attr "length" "1")])
6250 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6251 ;; does not know how to make it work for constants.
6253 (define_expand "negdi2"
6254 [(set (match_operand:DI 0 "register_operand" "=r")
6255 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6259 if (! TARGET_ARCH64)
6261 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
6262 gen_rtx_SET (VOIDmode, operand0,
6263 gen_rtx_NEG (DImode, operand1)),
6264 gen_rtx_CLOBBER (VOIDmode,
6265 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
6270 (define_insn "*negdi2_sp32"
6271 [(set (match_operand:DI 0 "register_operand" "=r")
6272 (neg:DI (match_operand:DI 1 "register_operand" "r")))
6273 (clobber (reg:CC 100))]
6275 && ! TARGET_LIVE_G0"
6277 [(set_attr "type" "unary")
6278 (set_attr "length" "2")])
6281 [(set (match_operand:DI 0 "register_operand" "")
6282 (neg:DI (match_operand:DI 1 "register_operand" "")))
6283 (clobber (reg:CC 100))]
6286 && reload_completed"
6287 [(parallel [(set (reg:CC_NOOV 100)
6288 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6290 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6291 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6292 (ltu:SI (reg:CC 100) (const_int 0))))]
6293 "operands[2] = gen_highpart (SImode, operands[0]);
6294 operands[3] = gen_highpart (SImode, operands[1]);
6295 operands[4] = gen_lowpart (SImode, operands[0]);
6296 operands[5] = gen_lowpart (SImode, operands[1]);")
6298 (define_insn "*negdi2_sp64"
6299 [(set (match_operand:DI 0 "register_operand" "=r")
6300 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6302 "sub\\t%%g0, %1, %0"
6303 [(set_attr "type" "unary")
6304 (set_attr "length" "1")])
6306 (define_expand "negsi2"
6307 [(set (match_operand:SI 0 "register_operand" "")
6308 (neg:SI (match_operand:SI 1 "arith_operand" "")))]
6314 rtx zero_reg = gen_reg_rtx (SImode);
6316 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6317 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
6318 gen_rtx_MINUS (SImode, zero_reg,
6324 (define_insn "*negsi2_not_liveg0"
6325 [(set (match_operand:SI 0 "register_operand" "=r")
6326 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6328 "sub\\t%%g0, %1, %0"
6329 [(set_attr "type" "unary")
6330 (set_attr "length" "1")])
6332 (define_insn "*cmp_cc_neg"
6333 [(set (reg:CC_NOOV 100)
6334 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6337 "subcc\\t%%g0, %0, %%g0"
6338 [(set_attr "type" "compare")
6339 (set_attr "length" "1")])
6341 (define_insn "*cmp_ccx_neg"
6342 [(set (reg:CCX_NOOV 100)
6343 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6346 "subcc\\t%%g0, %0, %%g0"
6347 [(set_attr "type" "compare")
6348 (set_attr "length" "1")])
6350 (define_insn "*cmp_cc_set_neg"
6351 [(set (reg:CC_NOOV 100)
6352 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6354 (set (match_operand:SI 0 "register_operand" "=r")
6355 (neg:SI (match_dup 1)))]
6357 "subcc\\t%%g0, %1, %0"
6358 [(set_attr "type" "compare")
6359 (set_attr "length" "1")])
6361 (define_insn "*cmp_ccx_set_neg"
6362 [(set (reg:CCX_NOOV 100)
6363 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6365 (set (match_operand:DI 0 "register_operand" "=r")
6366 (neg:DI (match_dup 1)))]
6368 "subcc\\t%%g0, %1, %0"
6369 [(set_attr "type" "compare")
6370 (set_attr "length" "1")])
6372 ;; We cannot use the "not" pseudo insn because the Sun assembler
6373 ;; does not know how to make it work for constants.
6374 (define_expand "one_cmpldi2"
6375 [(set (match_operand:DI 0 "register_operand" "")
6376 (not:DI (match_operand:DI 1 "register_operand" "")))]
6380 (define_insn "*one_cmpldi2_sp32"
6381 [(set (match_operand:DI 0 "register_operand" "=r,b")
6382 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6387 [(set_attr "type" "unary,fp")
6388 (set_attr "length" "2,1")])
6391 [(set (match_operand:DI 0 "register_operand" "")
6392 (not:DI (match_operand:DI 1 "register_operand" "")))]
6395 && ((GET_CODE (operands[0]) == REG
6396 && REGNO (operands[0]) < 32)
6397 || (GET_CODE (operands[0]) == SUBREG
6398 && GET_CODE (SUBREG_REG (operands[0])) == REG
6399 && REGNO (SUBREG_REG (operands[0])) < 32))"
6400 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6401 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6402 "if (GET_CODE (operands[0]) == SUBREG)
6403 operands[0] = alter_subreg (operands[0]);
6404 operands[2] = gen_highpart (SImode, operands[0]);
6405 operands[3] = gen_highpart (SImode, operands[1]);
6406 operands[4] = gen_lowpart (SImode, operands[0]);
6407 operands[5] = gen_lowpart (SImode, operands[1]);")
6409 (define_insn "*one_cmpldi2_sp64"
6410 [(set (match_operand:DI 0 "register_operand" "=r,b")
6411 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6416 [(set_attr "type" "unary,fp")
6417 (set_attr "length" "1")])
6419 (define_expand "one_cmplsi2"
6420 [(set (match_operand:SI 0 "register_operand" "")
6421 (not:SI (match_operand:SI 1 "arith_operand" "")))]
6426 && GET_CODE (operands[1]) == CONST_INT)
6428 rtx zero_reg = gen_reg_rtx (SImode);
6430 emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx));
6431 emit_insn (gen_rtx_SET (VOIDmode,
6433 gen_rtx_NOT (SImode,
6434 gen_rtx_XOR (SImode,
6441 (define_insn "*one_cmplsi2_not_liveg0"
6442 [(set (match_operand:SI 0 "register_operand" "=r,d")
6443 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6448 [(set_attr "type" "unary,fp")
6449 (set_attr "length" "1,1")])
6451 (define_insn "*one_cmplsi2_liveg0"
6452 [(set (match_operand:SI 0 "register_operand" "=r,d")
6453 (not:SI (match_operand:SI 1 "arith_operand" "r,d")))]
6458 [(set_attr "type" "unary,fp")
6459 (set_attr "length" "1,1")])
6461 (define_insn "*cmp_cc_not"
6463 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6466 "xnorcc\\t%%g0, %0, %%g0"
6467 [(set_attr "type" "compare")
6468 (set_attr "length" "1")])
6470 (define_insn "*cmp_ccx_not"
6472 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6475 "xnorcc\\t%%g0, %0, %%g0"
6476 [(set_attr "type" "compare")
6477 (set_attr "length" "1")])
6479 (define_insn "*cmp_cc_set_not"
6481 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6483 (set (match_operand:SI 0 "register_operand" "=r")
6484 (not:SI (match_dup 1)))]
6486 "xnorcc\\t%%g0, %1, %0"
6487 [(set_attr "type" "compare")
6488 (set_attr "length" "1")])
6490 (define_insn "*cmp_ccx_set_not"
6492 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6494 (set (match_operand:DI 0 "register_operand" "=r")
6495 (not:DI (match_dup 1)))]
6497 "xnorcc\\t%%g0, %1, %0"
6498 [(set_attr "type" "compare")
6499 (set_attr "length" "1")])
6501 ;; Floating point arithmetic instructions.
6503 (define_insn "addtf3"
6504 [(set (match_operand:TF 0 "register_operand" "=e")
6505 (plus:TF (match_operand:TF 1 "register_operand" "e")
6506 (match_operand:TF 2 "register_operand" "e")))]
6507 "TARGET_FPU && TARGET_HARD_QUAD"
6508 "faddq\\t%1, %2, %0"
6509 [(set_attr "type" "fp")
6510 (set_attr "length" "1")])
6512 (define_insn "adddf3"
6513 [(set (match_operand:DF 0 "register_operand" "=e")
6514 (plus:DF (match_operand:DF 1 "register_operand" "e")
6515 (match_operand:DF 2 "register_operand" "e")))]
6517 "faddd\\t%1, %2, %0"
6518 [(set_attr "type" "fp")
6519 (set_attr "length" "1")])
6521 (define_insn "addsf3"
6522 [(set (match_operand:SF 0 "register_operand" "=f")
6523 (plus:SF (match_operand:SF 1 "register_operand" "f")
6524 (match_operand:SF 2 "register_operand" "f")))]
6526 "fadds\\t%1, %2, %0"
6527 [(set_attr "type" "fp")
6528 (set_attr "length" "1")])
6530 (define_insn "subtf3"
6531 [(set (match_operand:TF 0 "register_operand" "=e")
6532 (minus:TF (match_operand:TF 1 "register_operand" "e")
6533 (match_operand:TF 2 "register_operand" "e")))]
6534 "TARGET_FPU && TARGET_HARD_QUAD"
6535 "fsubq\\t%1, %2, %0"
6536 [(set_attr "type" "fp")
6537 (set_attr "length" "1")])
6539 (define_insn "subdf3"
6540 [(set (match_operand:DF 0 "register_operand" "=e")
6541 (minus:DF (match_operand:DF 1 "register_operand" "e")
6542 (match_operand:DF 2 "register_operand" "e")))]
6544 "fsubd\\t%1, %2, %0"
6545 [(set_attr "type" "fp")
6546 (set_attr "length" "1")])
6548 (define_insn "subsf3"
6549 [(set (match_operand:SF 0 "register_operand" "=f")
6550 (minus:SF (match_operand:SF 1 "register_operand" "f")
6551 (match_operand:SF 2 "register_operand" "f")))]
6553 "fsubs\\t%1, %2, %0"
6554 [(set_attr "type" "fp")
6555 (set_attr "length" "1")])
6557 (define_insn "multf3"
6558 [(set (match_operand:TF 0 "register_operand" "=e")
6559 (mult:TF (match_operand:TF 1 "register_operand" "e")
6560 (match_operand:TF 2 "register_operand" "e")))]
6561 "TARGET_FPU && TARGET_HARD_QUAD"
6562 "fmulq\\t%1, %2, %0"
6563 [(set_attr "type" "fpmul")
6564 (set_attr "length" "1")])
6566 (define_insn "muldf3"
6567 [(set (match_operand:DF 0 "register_operand" "=e")
6568 (mult:DF (match_operand:DF 1 "register_operand" "e")
6569 (match_operand:DF 2 "register_operand" "e")))]
6571 "fmuld\\t%1, %2, %0"
6572 [(set_attr "type" "fpmul")
6573 (set_attr "length" "1")])
6575 (define_insn "mulsf3"
6576 [(set (match_operand:SF 0 "register_operand" "=f")
6577 (mult:SF (match_operand:SF 1 "register_operand" "f")
6578 (match_operand:SF 2 "register_operand" "f")))]
6580 "fmuls\\t%1, %2, %0"
6581 [(set_attr "type" "fpmul")
6582 (set_attr "length" "1")])
6584 (define_insn "*muldf3_extend"
6585 [(set (match_operand:DF 0 "register_operand" "=e")
6586 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6587 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6588 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6589 "fsmuld\\t%1, %2, %0"
6590 [(set_attr "type" "fpmul")
6591 (set_attr "length" "1")])
6593 (define_insn "*multf3_extend"
6594 [(set (match_operand:TF 0 "register_operand" "=e")
6595 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6596 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6597 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6598 "fdmulq\\t%1, %2, %0"
6599 [(set_attr "type" "fpmul")
6600 (set_attr "length" "1")])
6602 ;; don't have timing for quad-prec. divide.
6603 (define_insn "divtf3"
6604 [(set (match_operand:TF 0 "register_operand" "=e")
6605 (div:TF (match_operand:TF 1 "register_operand" "e")
6606 (match_operand:TF 2 "register_operand" "e")))]
6607 "TARGET_FPU && TARGET_HARD_QUAD"
6608 "fdivq\\t%1, %2, %0"
6609 [(set_attr "type" "fpdivd")
6610 (set_attr "length" "1")])
6612 (define_insn "divdf3"
6613 [(set (match_operand:DF 0 "register_operand" "=e")
6614 (div:DF (match_operand:DF 1 "register_operand" "e")
6615 (match_operand:DF 2 "register_operand" "e")))]
6617 "fdivd\\t%1, %2, %0"
6618 [(set_attr "type" "fpdivd")
6619 (set_attr "length" "1")])
6621 (define_insn "divsf3"
6622 [(set (match_operand:SF 0 "register_operand" "=f")
6623 (div:SF (match_operand:SF 1 "register_operand" "f")
6624 (match_operand:SF 2 "register_operand" "f")))]
6626 "fdivs\\t%1, %2, %0"
6627 [(set_attr "type" "fpdivs")
6628 (set_attr "length" "1")])
6630 (define_expand "negtf2"
6631 [(set (match_operand:TF 0 "register_operand" "=e,e")
6632 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6636 (define_insn "*negtf2_notv9"
6637 [(set (match_operand:TF 0 "register_operand" "=e,e")
6638 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6639 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6645 [(set_attr "type" "fpmove")
6646 (set_attr "length" "1,2")])
6649 [(set (match_operand:TF 0 "register_operand" "")
6650 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6654 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6655 [(set (match_dup 2) (neg:SF (match_dup 3)))
6656 (set (match_dup 4) (match_dup 5))
6657 (set (match_dup 6) (match_dup 7))]
6658 "if (GET_CODE (operands[0]) == SUBREG)
6659 operands[0] = alter_subreg (operands[0]);
6660 if (GET_CODE (operands[1]) == SUBREG)
6661 operands[1] = alter_subreg (operands[1]);
6662 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6663 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6664 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6665 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6666 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6667 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6669 (define_insn "*negtf2_v9"
6670 [(set (match_operand:TF 0 "register_operand" "=e,e")
6671 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6672 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6673 "TARGET_FPU && TARGET_V9"
6677 [(set_attr "type" "fpmove")
6678 (set_attr "length" "1,2")])
6681 [(set (match_operand:TF 0 "register_operand" "")
6682 (neg:TF (match_operand:TF 1 "register_operand" "")))]
6686 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6687 [(set (match_dup 2) (neg:DF (match_dup 3)))
6688 (set (match_dup 4) (match_dup 5))]
6689 "if (GET_CODE (operands[0]) == SUBREG)
6690 operands[0] = alter_subreg (operands[0]);
6691 if (GET_CODE (operands[1]) == SUBREG)
6692 operands[1] = alter_subreg (operands[1]);
6693 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6694 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6695 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6696 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6698 (define_expand "negdf2"
6699 [(set (match_operand:DF 0 "register_operand" "")
6700 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6704 (define_insn "*negdf2_notv9"
6705 [(set (match_operand:DF 0 "register_operand" "=e,e")
6706 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6707 "TARGET_FPU && ! TARGET_V9"
6711 [(set_attr "type" "fpmove")
6712 (set_attr "length" "1,2")])
6715 [(set (match_operand:DF 0 "register_operand" "")
6716 (neg:DF (match_operand:DF 1 "register_operand" "")))]
6720 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6721 [(set (match_dup 2) (neg:SF (match_dup 3)))
6722 (set (match_dup 4) (match_dup 5))]
6723 "if (GET_CODE (operands[0]) == SUBREG)
6724 operands[0] = alter_subreg (operands[0]);
6725 if (GET_CODE (operands[1]) == SUBREG)
6726 operands[1] = alter_subreg (operands[1]);
6727 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6728 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6729 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6730 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6732 (define_insn "*negdf2_v9"
6733 [(set (match_operand:DF 0 "register_operand" "=e")
6734 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6735 "TARGET_FPU && TARGET_V9"
6737 [(set_attr "type" "fpmove")
6738 (set_attr "length" "1")])
6740 (define_insn "negsf2"
6741 [(set (match_operand:SF 0 "register_operand" "=f")
6742 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6745 [(set_attr "type" "fpmove")
6746 (set_attr "length" "1")])
6748 (define_insn "abstf2"
6749 [(set (match_operand:TF 0 "register_operand" "")
6750 (abs:TF (match_operand:TF 1 "register_operand" "")))]
6754 (define_insn "*abstf2_notv9"
6755 [(set (match_operand:TF 0 "register_operand" "=e,e")
6756 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6757 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6758 "TARGET_FPU && ! TARGET_V9"
6762 [(set_attr "type" "fpmove")
6763 (set_attr "length" "1,2")])
6766 [(set (match_operand:TF 0 "register_operand" "=e,e")
6767 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6771 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6772 [(set (match_dup 2) (abs:SF (match_dup 3)))
6773 (set (match_dup 4) (match_dup 5))
6774 (set (match_dup 6) (match_dup 7))]
6775 "if (GET_CODE (operands[0]) == SUBREG)
6776 operands[0] = alter_subreg (operands[0]);
6777 if (GET_CODE (operands[1]) == SUBREG)
6778 operands[1] = alter_subreg (operands[1]);
6779 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6780 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6781 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6782 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6783 operands[6] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 2);
6784 operands[7] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 2);")
6786 (define_insn "*abstf2_v9"
6787 [(set (match_operand:TF 0 "register_operand" "=e,e")
6788 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6789 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6790 "TARGET_FPU && TARGET_V9"
6794 [(set_attr "type" "fpmove")
6795 (set_attr "length" "1,2")])
6798 [(set (match_operand:TF 0 "register_operand" "=e,e")
6799 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6803 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6804 [(set (match_dup 2) (abs:DF (match_dup 3)))
6805 (set (match_dup 4) (match_dup 5))]
6806 "if (GET_CODE (operands[0]) == SUBREG)
6807 operands[0] = alter_subreg (operands[0]);
6808 if (GET_CODE (operands[1]) == SUBREG)
6809 operands[1] = alter_subreg (operands[1]);
6810 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6811 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6812 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6813 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
6815 (define_expand "absdf2"
6816 [(set (match_operand:DF 0 "register_operand" "")
6817 (abs:DF (match_operand:DF 1 "register_operand" "")))]
6821 (define_insn "*absdf2_notv9"
6822 [(set (match_operand:DF 0 "register_operand" "=e,e")
6823 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6824 "TARGET_FPU && ! TARGET_V9"
6828 [(set_attr "type" "fpmove")
6829 (set_attr "length" "1,2")])
6832 [(set (match_operand:DF 0 "register_operand" "=e,e")
6833 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6837 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6838 [(set (match_dup 2) (abs:SF (match_dup 3)))
6839 (set (match_dup 4) (match_dup 5))]
6840 "if (GET_CODE (operands[0]) == SUBREG)
6841 operands[0] = alter_subreg (operands[0]);
6842 if (GET_CODE (operands[1]) == SUBREG)
6843 operands[1] = alter_subreg (operands[1]);
6844 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6845 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6846 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6847 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
6849 (define_insn "*absdf2_v9"
6850 [(set (match_operand:DF 0 "register_operand" "=e")
6851 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6852 "TARGET_FPU && TARGET_V9"
6854 [(set_attr "type" "fpmove")
6855 (set_attr "length" "1")])
6857 (define_insn "abssf2"
6858 [(set (match_operand:SF 0 "register_operand" "=f")
6859 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6862 [(set_attr "type" "fpmove")
6863 (set_attr "length" "1")])
6865 (define_insn "sqrttf2"
6866 [(set (match_operand:TF 0 "register_operand" "=e")
6867 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6868 "TARGET_FPU && TARGET_HARD_QUAD"
6870 [(set_attr "type" "fpsqrt")
6871 (set_attr "length" "1")])
6873 (define_insn "sqrtdf2"
6874 [(set (match_operand:DF 0 "register_operand" "=e")
6875 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6878 [(set_attr "type" "fpsqrt")
6879 (set_attr "length" "1")])
6881 (define_insn "sqrtsf2"
6882 [(set (match_operand:SF 0 "register_operand" "=f")
6883 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6886 [(set_attr "type" "fpsqrt")
6887 (set_attr "length" "1")])
6889 ;;- arithmetic shift instructions
6891 (define_insn "ashlsi3"
6892 [(set (match_operand:SI 0 "register_operand" "=r")
6893 (ashift:SI (match_operand:SI 1 "register_operand" "r")
6894 (match_operand:SI 2 "arith_operand" "rI")))]
6898 if (GET_CODE (operands[2]) == CONST_INT
6899 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
6900 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6902 return \"sll\\t%1, %2, %0\";
6904 [(set_attr "type" "shift")
6905 (set_attr "length" "1")])
6907 (define_expand "ashldi3"
6908 [(set (match_operand:DI 0 "register_operand" "=r")
6909 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6910 (match_operand:SI 2 "arith_operand" "rI")))]
6911 "TARGET_ARCH64 || TARGET_V8PLUS"
6914 if (! TARGET_ARCH64)
6916 if (GET_CODE (operands[2]) == CONST_INT)
6918 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6924 [(set (match_operand:DI 0 "register_operand" "=r")
6925 (ashift:DI (match_operand:DI 1 "register_operand" "r")
6926 (match_operand:SI 2 "arith_operand" "rI")))]
6930 if (GET_CODE (operands[2]) == CONST_INT
6931 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
6932 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6934 return \"sllx\\t%1, %2, %0\";
6936 [(set_attr "type" "shift")
6937 (set_attr "length" "1")])
6940 (define_insn "ashldi3_v8plus"
6941 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6942 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6943 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6944 (clobber (match_scratch:SI 3 "=X,X,&h"))]
6946 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
6947 [(set_attr "length" "5,5,6")])
6949 ;; Optimize (1LL<<x)-1
6950 ;; XXX this also needs to be fixed to handle equal subregs
6951 ;; XXX first before we could re-enable it.
6953 [(set (match_operand:DI 0 "register_operand" "=h")
6954 (plus:DI (ashift:DI (const_int 1)
6955 (match_operand:SI 2 "arith_operand" "rI"))
6957 "0 && TARGET_V8PLUS"
6960 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
6961 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
6962 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
6964 [(set_attr "length" "4")])
6966 (define_insn "*cmp_cc_ashift_1"
6967 [(set (reg:CC_NOOV 100)
6968 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6972 "addcc\\t%0, %0, %%g0"
6973 [(set_attr "type" "compare")
6974 (set_attr "length" "1")])
6976 (define_insn "*cmp_cc_set_ashift_1"
6977 [(set (reg:CC_NOOV 100)
6978 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6981 (set (match_operand:SI 0 "register_operand" "=r")
6982 (ashift:SI (match_dup 1) (const_int 1)))]
6984 "addcc\\t%1, %1, %0"
6985 [(set_attr "type" "compare")
6986 (set_attr "length" "1")])
6988 (define_insn "ashrsi3"
6989 [(set (match_operand:SI 0 "register_operand" "=r")
6990 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6991 (match_operand:SI 2 "arith_operand" "rI")))]
6995 if (GET_CODE (operands[2]) == CONST_INT
6996 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
6997 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6999 return \"sra\\t%1, %2, %0\";
7001 [(set_attr "type" "shift")
7002 (set_attr "length" "1")])
7004 (define_expand "ashrdi3"
7005 [(set (match_operand:DI 0 "register_operand" "=r")
7006 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7007 (match_operand:SI 2 "arith_operand" "rI")))]
7008 "TARGET_ARCH64 || TARGET_V8PLUS"
7011 if (! TARGET_ARCH64)
7013 if (GET_CODE (operands[2]) == CONST_INT)
7014 FAIL; /* prefer generic code in this case */
7015 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7021 [(set (match_operand:DI 0 "register_operand" "=r")
7022 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7023 (match_operand:SI 2 "arith_operand" "rI")))]
7027 if (GET_CODE (operands[2]) == CONST_INT
7028 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7029 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7031 return \"srax\\t%1, %2, %0\";
7033 [(set_attr "type" "shift")
7034 (set_attr "length" "1")])
7037 (define_insn "ashrdi3_v8plus"
7038 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7039 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7040 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7041 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7043 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
7044 [(set_attr "length" "5,5,6")])
7046 (define_insn "lshrsi3"
7047 [(set (match_operand:SI 0 "register_operand" "=r")
7048 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7049 (match_operand:SI 2 "arith_operand" "rI")))]
7053 if (GET_CODE (operands[2]) == CONST_INT
7054 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7055 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7057 return \"srl\\t%1, %2, %0\";
7059 [(set_attr "type" "shift")
7060 (set_attr "length" "1")])
7062 (define_expand "lshrdi3"
7063 [(set (match_operand:DI 0 "register_operand" "=r")
7064 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7065 (match_operand:SI 2 "arith_operand" "rI")))]
7066 "TARGET_ARCH64 || TARGET_V8PLUS"
7069 if (! TARGET_ARCH64)
7071 if (GET_CODE (operands[2]) == CONST_INT)
7073 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7079 [(set (match_operand:DI 0 "register_operand" "=r")
7080 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7081 (match_operand:SI 2 "arith_operand" "rI")))]
7085 if (GET_CODE (operands[2]) == CONST_INT
7086 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
7087 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7089 return \"srlx\\t%1, %2, %0\";
7091 [(set_attr "type" "shift")
7092 (set_attr "length" "1")])
7095 (define_insn "lshrdi3_v8plus"
7096 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7097 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7098 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7099 (clobber (match_scratch:SI 3 "=X,X,&h"))]
7101 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
7102 [(set_attr "length" "5,5,6")])
7104 ;; Unconditional and other jump instructions
7105 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
7106 ;; following insn is never executed. This saves us a nop. Dbx does not
7107 ;; handle such branches though, so we only use them when optimizing.
7109 [(set (pc) (label_ref (match_operand 0 "" "")))]
7113 /* TurboSparc is reported to have problems with
7116 i.e. an empty loop with the annul bit set. The workaround is to use
7120 if (! TARGET_V9 && flag_delayed_branch
7121 && (insn_addresses[INSN_UID (operands[0])]
7122 == insn_addresses[INSN_UID (insn)]))
7123 return \"b\\t%l0%#\";
7125 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
7127 [(set_attr "type" "uncond_branch")])
7129 (define_expand "tablejump"
7130 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7131 (use (label_ref (match_operand 1 "" "")))])]
7135 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7138 /* In pic mode, our address differences are against the base of the
7139 table. Add that base value back in; CSE ought to be able to combine
7140 the two address loads. */
7144 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7146 if (CASE_VECTOR_MODE != Pmode)
7147 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7148 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7149 operands[0] = memory_address (Pmode, tmp);
7153 (define_insn "*tablejump_sp32"
7154 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7155 (use (label_ref (match_operand 1 "" "")))]
7158 [(set_attr "type" "uncond_branch")])
7160 (define_insn "*tablejump_sp64"
7161 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7162 (use (label_ref (match_operand 1 "" "")))]
7165 [(set_attr "type" "uncond_branch")])
7167 ;; This pattern recognizes the "instruction" that appears in
7168 ;; a function call that wants a structure value,
7169 ;; to inform the called function if compiled with Sun CC.
7170 ;(define_insn "*unimp_insn"
7171 ; [(match_operand:SI 0 "immediate_operand" "")]
7172 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7174 ; [(set_attr "type" "marker")])
7176 ;;- jump to subroutine
7177 (define_expand "call"
7178 ;; Note that this expression is not used for generating RTL.
7179 ;; All the RTL is generated explicitly below.
7180 [(call (match_operand 0 "call_operand" "")
7181 (match_operand 3 "" "i"))]
7182 ;; operands[2] is next_arg_register
7183 ;; operands[3] is struct_value_size_rtx.
7187 rtx fn_rtx, nregs_rtx;
7189 if (GET_MODE (operands[0]) != FUNCTION_MODE)
7192 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7194 /* This is really a PIC sequence. We want to represent
7195 it as a funny jump so its delay slots can be filled.
7197 ??? But if this really *is* a CALL, will not it clobber the
7198 call-clobbered registers? We lose this if it is a JUMP_INSN.
7199 Why cannot we have delay slots filled if it were a CALL? */
7201 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7203 (gen_rtx_PARALLEL (VOIDmode,
7205 gen_rtx_SET (VOIDmode, pc_rtx,
7206 XEXP (operands[0], 0)),
7207 GEN_INT (INTVAL (operands[3]) & 0xfff),
7208 gen_rtx_CLOBBER (VOIDmode,
7209 gen_rtx_REG (Pmode, 15)))));
7212 (gen_rtx_PARALLEL (VOIDmode,
7214 gen_rtx_SET (VOIDmode, pc_rtx,
7215 XEXP (operands[0], 0)),
7216 gen_rtx_CLOBBER (VOIDmode,
7217 gen_rtx_REG (Pmode, 15)))));
7221 fn_rtx = operands[0];
7223 /* Count the number of parameter registers being used by this call.
7224 if that argument is NULL, it means we are using them all, which
7225 means 6 on the sparc. */
7228 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7230 nregs_rtx = GEN_INT (6);
7232 nregs_rtx = const0_rtx;
7235 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7237 (gen_rtx_PARALLEL (VOIDmode,
7238 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7239 GEN_INT (INTVAL (operands[3]) & 0xfff),
7240 gen_rtx_CLOBBER (VOIDmode,
7241 gen_rtx_REG (Pmode, 15)))));
7244 (gen_rtx_PARALLEL (VOIDmode,
7245 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7246 gen_rtx_CLOBBER (VOIDmode,
7247 gen_rtx_REG (Pmode, 15)))));
7251 /* If this call wants a structure value,
7252 emit an unimp insn to let the called function know about this. */
7253 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7255 rtx insn = emit_insn (operands[3]);
7256 SCHED_GROUP_P (insn) = 1;
7263 ;; We can't use the same pattern for these two insns, because then registers
7264 ;; in the address may not be properly reloaded.
7266 (define_insn "*call_address_sp32"
7267 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7268 (match_operand 1 "" ""))
7269 (clobber (reg:SI 15))]
7270 ;;- Do not use operand 1 for most machines.
7273 [(set_attr "type" "call")])
7275 (define_insn "*call_symbolic_sp32"
7276 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7277 (match_operand 1 "" ""))
7278 (clobber (reg:SI 15))]
7279 ;;- Do not use operand 1 for most machines.
7282 [(set_attr "type" "call")])
7284 (define_insn "*call_address_sp64"
7285 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
7286 (match_operand 1 "" ""))
7287 (clobber (reg:DI 15))]
7288 ;;- Do not use operand 1 for most machines.
7291 [(set_attr "type" "call")])
7293 (define_insn "*call_symbolic_sp64"
7294 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
7295 (match_operand 1 "" ""))
7296 (clobber (reg:DI 15))]
7297 ;;- Do not use operand 1 for most machines.
7300 [(set_attr "type" "call")])
7302 ;; This is a call that wants a structure value.
7303 ;; There is no such critter for v9 (??? we may need one anyway).
7304 (define_insn "*call_address_struct_value_sp32"
7305 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7306 (match_operand 1 "" ""))
7307 (match_operand 2 "immediate_operand" "")
7308 (clobber (reg:SI 15))]
7309 ;;- Do not use operand 1 for most machines.
7310 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7311 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
7312 [(set_attr "type" "call_no_delay_slot")])
7314 ;; This is a call that wants a structure value.
7315 ;; There is no such critter for v9 (??? we may need one anyway).
7316 (define_insn "*call_symbolic_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\\tunimp\\t%2"
7324 [(set_attr "type" "call_no_delay_slot")])
7326 ;; This is a call that may want a structure value. This is used for
7328 (define_insn "*call_address_untyped_struct_value_sp32"
7329 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7330 (match_operand 1 "" ""))
7331 (match_operand 2 "immediate_operand" "")
7332 (clobber (reg:SI 15))]
7333 ;;- Do not use operand 1 for most machines.
7334 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7335 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7336 [(set_attr "type" "call_no_delay_slot")])
7338 ;; This is a call that wants a structure value.
7339 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7340 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7341 (match_operand 1 "" ""))
7342 (match_operand 2 "immediate_operand" "")
7343 (clobber (reg:SI 15))]
7344 ;;- Do not use operand 1 for most machines.
7345 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7346 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
7347 [(set_attr "type" "call_no_delay_slot")])
7349 (define_expand "call_value"
7350 ;; Note that this expression is not used for generating RTL.
7351 ;; All the RTL is generated explicitly below.
7352 [(set (match_operand 0 "register_operand" "=rf")
7353 (call (match_operand:SI 1 "" "")
7354 (match_operand 4 "" "")))]
7355 ;; operand 2 is stack_size_rtx
7356 ;; operand 3 is next_arg_register
7360 rtx fn_rtx, nregs_rtx;
7363 if (GET_MODE (operands[1]) != FUNCTION_MODE)
7366 fn_rtx = operands[1];
7370 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7372 nregs_rtx = GEN_INT (6);
7374 nregs_rtx = const0_rtx;
7378 gen_rtx_SET (VOIDmode, operands[0],
7379 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7380 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7382 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7387 (define_insn "*call_value_address_sp32"
7388 [(set (match_operand 0 "" "=rf")
7389 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7390 (match_operand 2 "" "")))
7391 (clobber (reg:SI 15))]
7392 ;;- Do not use operand 2 for most machines.
7395 [(set_attr "type" "call")])
7397 (define_insn "*call_value_symbolic_sp32"
7398 [(set (match_operand 0 "" "=rf")
7399 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7400 (match_operand 2 "" "")))
7401 (clobber (reg:SI 15))]
7402 ;;- Do not use operand 2 for most machines.
7405 [(set_attr "type" "call")])
7407 (define_insn "*call_value_address_sp64"
7408 [(set (match_operand 0 "" "")
7409 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
7410 (match_operand 2 "" "")))
7411 (clobber (reg:DI 15))]
7412 ;;- Do not use operand 2 for most machines.
7415 [(set_attr "type" "call")])
7417 (define_insn "*call_value_symbolic_sp64"
7418 [(set (match_operand 0 "" "")
7419 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
7420 (match_operand 2 "" "")))
7421 (clobber (reg:DI 15))]
7422 ;;- Do not use operand 2 for most machines.
7425 [(set_attr "type" "call")])
7427 (define_expand "untyped_call"
7428 [(parallel [(call (match_operand 0 "" "")
7430 (match_operand 1 "" "")
7431 (match_operand 2 "" "")])]
7437 /* Pass constm1 to indicate that it may expect a structure value, but
7438 we don't know what size it is. */
7439 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7441 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7443 rtx set = XVECEXP (operands[2], 0, i);
7444 emit_move_insn (SET_DEST (set), SET_SRC (set));
7447 /* The optimizer does not know that the call sets the function value
7448 registers we stored in the result block. We avoid problems by
7449 claiming that all hard registers are used and clobbered at this
7451 emit_insn (gen_blockage ());
7456 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7457 ;; all of memory. This blocks insns from being moved across this point.
7459 (define_insn "blockage"
7460 [(unspec_volatile [(const_int 0)] 0)]
7464 ;; Prepare to return any type including a structure value.
7466 (define_expand "untyped_return"
7467 [(match_operand:BLK 0 "memory_operand" "")
7468 (match_operand 1 "" "")]
7472 rtx valreg1 = gen_rtx_REG (DImode, 24);
7473 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7474 rtx result = operands[0];
7476 if (! TARGET_ARCH64)
7478 rtx rtnreg = gen_rtx_REG (SImode, (leaf_function ? 15 : 31));
7479 rtx value = gen_reg_rtx (SImode);
7481 /* Fetch the instruction where we will return to and see if it's an unimp
7482 instruction (the most significant 10 bits will be zero). If so,
7483 update the return address to skip the unimp instruction. */
7484 emit_move_insn (value,
7485 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7486 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7487 emit_insn (gen_update_return (rtnreg, value));
7490 /* Reload the function value registers. */
7491 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
7492 emit_move_insn (valreg2,
7493 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
7494 plus_constant (XEXP (result, 0), 8)));
7496 /* Put USE insns before the return. */
7497 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7498 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7500 /* Construct the return. */
7501 expand_null_return ();
7506 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
7507 ;; and parts of the compiler don't want to believe that the add is needed.
7509 (define_insn "update_return"
7510 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7511 (match_operand:SI 1 "register_operand" "r")] 1)]
7513 "cmp %1,0\;be,a .+8\;add %0,4,%0"
7514 [(set_attr "type" "multi")])
7516 (define_insn "return"
7520 "* return output_return (operands);"
7521 [(set_attr "type" "return")])
7524 [(set (match_operand:SI 0 "register_operand" "=r")
7525 (match_operand:SI 1 "arith_operand" "rI"))
7527 (use (reg:SI 31))])]
7528 "sparc_return_peephole_ok (operands[0], operands[1])"
7529 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
7535 [(set_attr "type" "ialu")
7536 (set_attr "length" "1")])
7538 (define_expand "indirect_jump"
7539 [(set (pc) (match_operand 0 "address_operand" "p"))]
7543 (define_insn "*branch_sp32"
7544 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7547 [(set_attr "type" "uncond_branch")])
7549 (define_insn "*branch_sp64"
7550 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7553 [(set_attr "type" "uncond_branch")])
7555 ;; ??? Doesn't work with -mflat.
7556 (define_expand "nonlocal_goto"
7557 [(match_operand:SI 0 "general_operand" "")
7558 (match_operand:SI 1 "general_operand" "")
7559 (match_operand:SI 2 "general_operand" "")
7560 (match_operand:SI 3 "" "")]
7564 rtx chain = operands[0];
7565 rtx fp = operands[1];
7566 rtx stack = operands[2];
7567 rtx lab = operands[3];
7570 /* Trap instruction to flush all the register windows. */
7571 emit_insn (gen_flush_register_windows ());
7573 /* Load the fp value for the containing fn into %fp. This is needed
7574 because STACK refers to %fp. Note that virtual register instantiation
7575 fails if the virtual %fp isn't set from a register. */
7576 if (GET_CODE (fp) != REG)
7577 fp = force_reg (Pmode, fp);
7578 emit_move_insn (virtual_stack_vars_rtx, fp);
7580 /* Find the containing function's current nonlocal goto handler,
7581 which will do any cleanups and then jump to the label. */
7582 labreg = gen_rtx_REG (Pmode, 8);
7583 emit_move_insn (labreg, lab);
7585 /* Restore %fp from stack pointer value for containing function.
7586 The restore insn that follows will move this to %sp,
7587 and reload the appropriate value into %fp. */
7588 emit_move_insn (frame_pointer_rtx, stack);
7590 /* USE of frame_pointer_rtx added for consistency; not clear if
7592 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7593 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7594 /* Return, restoring reg window and jumping to goto handler. */
7595 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7596 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7598 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
7603 /* Put in the static chain register the nonlocal label address. */
7604 emit_move_insn (static_chain_rtx, chain);
7605 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7606 emit_insn (gen_goto_handler_and_restore (labreg));
7611 ;; Special trap insn to flush register windows.
7612 (define_insn "flush_register_windows"
7613 [(unspec_volatile [(const_int 0)] 1)]
7615 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
7616 [(set_attr "type" "misc")
7617 (set_attr "length" "1")])
7619 (define_insn "goto_handler_and_restore"
7620 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
7622 "jmp\\t%0+0\\n\\trestore"
7623 [(set_attr "type" "misc")
7624 (set_attr "length" "2")])
7626 (define_insn "goto_handler_and_restore_v9"
7627 [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7628 (match_operand:SI 1 "register_operand" "=r,r")
7629 (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7630 "TARGET_V9 && ! TARGET_ARCH64"
7632 return\\t%0+0\\n\\tmov\\t%2, %Y1
7633 sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7634 [(set_attr "type" "misc")
7635 (set_attr "length" "2,3")])
7637 (define_insn "*goto_handler_and_restore_v9_sp64"
7638 [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7639 (match_operand:DI 1 "register_operand" "=r,r")
7640 (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
7641 "TARGET_V9 && TARGET_ARCH64"
7643 return\\t%0+0\\n\\tmov\\t%2, %Y1
7644 sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
7645 [(set_attr "type" "misc")
7646 (set_attr "length" "2,3")])
7648 ;; Pattern for use after a setjmp to store FP and the return register
7649 ;; into the stack area.
7651 (define_expand "setjmp"
7657 emit_insn (gen_setjmp_64 ());
7659 emit_insn (gen_setjmp_32 ());
7663 (define_expand "setjmp_32"
7664 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7665 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7668 { operands[0] = frame_pointer_rtx; }")
7670 (define_expand "setjmp_64"
7671 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7672 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7675 { operands[0] = frame_pointer_rtx; }")
7677 ;; Special pattern for the FLUSH instruction.
7679 (define_insn "flush"
7680 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 4)]
7682 "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";"
7683 [(set_attr "type" "misc")
7684 (set_attr "length" "1")])
7688 ;; The scan instruction searches from the most significant bit while ffs
7689 ;; searches from the least significant bit. The bit index and treatment of
7690 ;; zero also differ. It takes at least 7 instructions to get the proper
7691 ;; result. Here is an obvious 8 instruction sequence.
7694 (define_insn "ffssi2"
7695 [(set (match_operand:SI 0 "register_operand" "=&r")
7696 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7697 (clobber (match_scratch:SI 2 "=&r"))]
7698 "TARGET_SPARCLITE || TARGET_SPARCLET"
7702 output_asm_insn (\"and %%g0,0,%%g0\", operands);
7703 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\";
7705 [(set_attr "type" "multi")
7706 (set_attr "length" "8")])
7708 ;; ??? This should be a define expand, so that the extra instruction have
7709 ;; a chance of being optimized away.
7711 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
7712 ;; does, but no one uses that and we don't have a switch for it.
7714 ;(define_insn "ffsdi2"
7715 ; [(set (match_operand:DI 0 "register_operand" "=&r")
7716 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7717 ; (clobber (match_scratch:DI 2 "=&r"))]
7719 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
7720 ; [(set_attr "type" "multi")
7721 ; (set_attr "length" "4")])
7724 ;; Peepholes go at the end.
7726 ;; Optimize consecutive loads or stores into ldd and std when possible.
7727 ;; The conditions in which we do this are very restricted and are
7728 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7731 [(set (match_operand:SI 0 "memory_operand" "")
7733 (set (match_operand:SI 1 "memory_operand" "")
7736 && ! MEM_VOLATILE_P (operands[0])
7737 && ! MEM_VOLATILE_P (operands[1])
7738 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
7742 [(set (match_operand:SI 0 "memory_operand" "")
7744 (set (match_operand:SI 1 "memory_operand" "")
7747 && ! MEM_VOLATILE_P (operands[0])
7748 && ! MEM_VOLATILE_P (operands[1])
7749 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
7753 [(set (match_operand:SI 0 "register_operand" "=rf")
7754 (match_operand:SI 1 "memory_operand" ""))
7755 (set (match_operand:SI 2 "register_operand" "=rf")
7756 (match_operand:SI 3 "memory_operand" ""))]
7757 "registers_ok_for_ldd_peep (operands[0], operands[2])
7758 && ! MEM_VOLATILE_P (operands[1])
7759 && ! MEM_VOLATILE_P (operands[3])
7760 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7764 [(set (match_operand:SI 0 "memory_operand" "")
7765 (match_operand:SI 1 "register_operand" "rf"))
7766 (set (match_operand:SI 2 "memory_operand" "")
7767 (match_operand:SI 3 "register_operand" "rf"))]
7768 "registers_ok_for_ldd_peep (operands[1], operands[3])
7769 && ! MEM_VOLATILE_P (operands[0])
7770 && ! MEM_VOLATILE_P (operands[2])
7771 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
7775 [(set (match_operand:SF 0 "register_operand" "=fr")
7776 (match_operand:SF 1 "memory_operand" ""))
7777 (set (match_operand:SF 2 "register_operand" "=fr")
7778 (match_operand:SF 3 "memory_operand" ""))]
7779 "registers_ok_for_ldd_peep (operands[0], operands[2])
7780 && ! MEM_VOLATILE_P (operands[1])
7781 && ! MEM_VOLATILE_P (operands[3])
7782 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
7786 [(set (match_operand:SF 0 "memory_operand" "")
7787 (match_operand:SF 1 "register_operand" "fr"))
7788 (set (match_operand:SF 2 "memory_operand" "")
7789 (match_operand:SF 3 "register_operand" "fr"))]
7790 "registers_ok_for_ldd_peep (operands[1], operands[3])
7791 && ! MEM_VOLATILE_P (operands[0])
7792 && ! MEM_VOLATILE_P (operands[2])
7793 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
7797 [(set (match_operand:SI 0 "register_operand" "=rf")
7798 (match_operand:SI 1 "memory_operand" ""))
7799 (set (match_operand:SI 2 "register_operand" "=rf")
7800 (match_operand:SI 3 "memory_operand" ""))]
7801 "registers_ok_for_ldd_peep (operands[2], operands[0])
7802 && ! MEM_VOLATILE_P (operands[3])
7803 && ! MEM_VOLATILE_P (operands[1])
7804 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
7808 [(set (match_operand:SI 0 "memory_operand" "")
7809 (match_operand:SI 1 "register_operand" "rf"))
7810 (set (match_operand:SI 2 "memory_operand" "")
7811 (match_operand:SI 3 "register_operand" "rf"))]
7812 "registers_ok_for_ldd_peep (operands[3], operands[1])
7813 && ! MEM_VOLATILE_P (operands[2])
7814 && ! MEM_VOLATILE_P (operands[0])
7815 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
7819 [(set (match_operand:SF 0 "register_operand" "=fr")
7820 (match_operand:SF 1 "memory_operand" ""))
7821 (set (match_operand:SF 2 "register_operand" "=fr")
7822 (match_operand:SF 3 "memory_operand" ""))]
7823 "registers_ok_for_ldd_peep (operands[2], operands[0])
7824 && ! MEM_VOLATILE_P (operands[3])
7825 && ! MEM_VOLATILE_P (operands[1])
7826 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
7830 [(set (match_operand:SF 0 "memory_operand" "")
7831 (match_operand:SF 1 "register_operand" "fr"))
7832 (set (match_operand:SF 2 "memory_operand" "")
7833 (match_operand:SF 3 "register_operand" "fr"))]
7834 "registers_ok_for_ldd_peep (operands[3], operands[1])
7835 && ! MEM_VOLATILE_P (operands[2])
7836 && ! MEM_VOLATILE_P (operands[0])
7837 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
7840 ;; Optimize the case of following a reg-reg move with a test
7841 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
7842 ;; This can result from a float to fix conversion.
7845 [(set (match_operand:SI 0 "register_operand" "=r")
7846 (match_operand:SI 1 "register_operand" "r"))
7848 (compare:CC (match_operand:SI 2 "register_operand" "r")
7850 "(rtx_equal_p (operands[2], operands[0])
7851 || rtx_equal_p (operands[2], operands[1]))
7852 && ! FP_REG_P (operands[0])
7853 && ! FP_REG_P (operands[1])"
7857 [(set (match_operand:DI 0 "register_operand" "=r")
7858 (match_operand:DI 1 "register_operand" "r"))
7860 (compare:CCX (match_operand:DI 2 "register_operand" "r")
7863 && (rtx_equal_p (operands[2], operands[0])
7864 || rtx_equal_p (operands[2], operands[1]))
7865 && ! FP_REG_P (operands[0])
7866 && ! FP_REG_P (operands[1])"
7869 ;; Return peepholes. First the "normal" ones.
7870 ;; These are necessary to catch insns ending up in the epilogue delay list.
7872 (define_insn "*return_qi"
7873 [(set (match_operand:QI 0 "restore_operand" "")
7874 (match_operand:QI 1 "arith_operand" "rI"))
7876 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7879 if (! TARGET_ARCH64 && current_function_returns_struct)
7880 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7881 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
7882 || IN_OR_GLOBAL_P (operands[1])))
7883 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7885 return \"ret\\n\\trestore %%g0, %1, %Y0\";
7887 [(set_attr "type" "multi")])
7889 (define_insn "*return_hi"
7890 [(set (match_operand:HI 0 "restore_operand" "")
7891 (match_operand:HI 1 "arith_operand" "rI"))
7893 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7896 if (! TARGET_ARCH64 && current_function_returns_struct)
7897 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7898 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
7899 || IN_OR_GLOBAL_P (operands[1])))
7900 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7902 return \"ret\;restore %%g0, %1, %Y0\";
7904 [(set_attr "type" "multi")])
7906 (define_insn "*return_si"
7907 [(set (match_operand:SI 0 "restore_operand" "")
7908 (match_operand:SI 1 "arith_operand" "rI"))
7910 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7913 if (! TARGET_ARCH64 && current_function_returns_struct)
7914 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7915 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
7916 || IN_OR_GLOBAL_P (operands[1])))
7917 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7919 return \"ret\;restore %%g0, %1, %Y0\";
7921 [(set_attr "type" "multi")])
7923 ;; The following pattern is only generated by delayed-branch scheduling,
7924 ;; when the insn winds up in the epilogue. This can happen not only when
7925 ;; ! TARGET_FPU because we move complex types around by parts using
7927 (define_insn "*return_sf_no_fpu"
7928 [(set (match_operand:SF 0 "restore_operand" "r")
7929 (match_operand:SF 1 "register_operand" "r"))
7931 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7934 if (! TARGET_ARCH64 && current_function_returns_struct)
7935 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
7936 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
7937 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
7939 return \"ret\;restore %%g0, %1, %Y0\";
7941 [(set_attr "type" "multi")])
7943 (define_insn "*return_addsi"
7944 [(set (match_operand:SI 0 "restore_operand" "")
7945 (plus:SI (match_operand:SI 1 "register_operand" "r")
7946 (match_operand:SI 2 "arith_operand" "rI")))
7948 "! TARGET_EPILOGUE && ! TARGET_LIVE_G0"
7951 if (! TARGET_ARCH64 && current_function_returns_struct)
7952 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
7953 /* If operands are global or in registers, can use return */
7954 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
7955 && (GET_CODE (operands[2]) == CONST_INT
7956 || IN_OR_GLOBAL_P (operands[2])))
7957 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
7959 return \"ret\;restore %r1, %2, %Y0\";
7961 [(set_attr "type" "multi")])
7963 (define_insn "*return_di"
7964 [(set (match_operand:DI 0 "restore_operand" "")
7965 (match_operand:DI 1 "arith_double_operand" "rHI"))
7967 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
7968 "ret\;restore %%g0, %1, %Y0"
7969 [(set_attr "type" "multi")])
7971 (define_insn "*return_adddi"
7972 [(set (match_operand:DI 0 "restore_operand" "")
7973 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
7974 (match_operand:DI 2 "arith_double_operand" "rHI")))
7976 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
7977 "ret\;restore %r1, %2, %Y0"
7978 [(set_attr "type" "multi")])
7980 ;; The following pattern is only generated by delayed-branch scheduling,
7981 ;; when the insn winds up in the epilogue.
7982 (define_insn "*return_sf"
7984 (match_operand:SF 0 "register_operand" "f"))
7987 "ret\;fmovs\\t%0, %%f0"
7988 [(set_attr "type" "multi")])
7990 ;; Now peepholes to do a call followed by a jump.
7993 [(parallel [(set (match_operand 0 "" "")
7994 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
7995 (match_operand 2 "" "")))
7996 (clobber (reg:SI 15))])
7997 (set (pc) (label_ref (match_operand 3 "" "")))]
7998 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
7999 && in_same_eh_region (insn, operands[3])
8000 && in_same_eh_region (insn, ins1)"
8001 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8004 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
8005 (match_operand 1 "" ""))
8006 (clobber (reg:SI 15))])
8007 (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")
8014 [(parallel [(set (match_operand 0 "" "")
8015 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
8016 (match_operand 2 "" "")))
8017 (clobber (reg:DI 15))])
8018 (set (pc) (label_ref (match_operand 3 "" "")))]
8020 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
8021 && in_same_eh_region (insn, operands[3])
8022 && in_same_eh_region (insn, ins1)"
8023 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
8026 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
8027 (match_operand 1 "" ""))
8028 (clobber (reg:DI 15))])
8029 (set (pc) (label_ref (match_operand 2 "" "")))]
8031 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
8032 && in_same_eh_region (insn, operands[2])
8033 && in_same_eh_region (insn, ins1)"
8034 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
8036 ;; After a nonlocal goto, we need to restore the PIC register, but only
8037 ;; if we need it. So do nothing much here, but we'll check for this in
8040 ;; Make sure this unspec_volatile number agrees with finalize_pic.
8041 (define_insn "nonlocal_goto_receiver"
8042 [(unspec_volatile [(const_int 0)] 5)]
8047 [(trap_if (const_int 1) (const_int 5))]
8050 [(set_attr "type" "misc")
8051 (set_attr "length" "1")])
8053 (define_expand "conditional_trap"
8054 [(trap_if (match_operator 0 "noov_compare_op"
8055 [(match_dup 2) (match_dup 3)])
8056 (match_operand:SI 1 "arith_operand" ""))]
8058 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8059 sparc_compare_op0, sparc_compare_op1);
8060 operands[3] = const0_rtx;")
8063 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8064 (match_operand:SI 1 "arith_operand" "rM"))]
8067 [(set_attr "type" "misc")
8068 (set_attr "length" "1")])
8071 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8072 (match_operand:SI 1 "arith_operand" "rM"))]
8075 [(set_attr "type" "misc")
8076 (set_attr "length" "1")])