1 ;;- Machine description for SPARC chip for GNU C compiler
2 ;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000 Free Software Foundation, Inc.
4 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
8 ;; This file is part of GNU CC.
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; Uses of UNSPEC and UNSPEC_VOLATILE in this file:
29 ;; UNSPEC: 0 movsi_{lo_sum,high}_pic
34 ;; 5 movsi_{,lo_sum_,high_}pic_label_ref
40 ;; 11 embmedany_sethi, embmedany_brsum
41 ;; 13 embmedany_textuhi
42 ;; 14 embmedany_texthi
43 ;; 15 embmedany_textulo
44 ;; 16 embmedany_textlo
48 ;; UNSPEC_VOLATILE: 0 blockage
49 ;; 1 flush_register_windows
50 ;; 2 goto_handler_and_restore
51 ;; 3 goto_handler_and_restore_v9*
53 ;; 5 nonlocal_goto_receiver
56 ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
57 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
58 ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
59 ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of
60 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
62 ;; Attribute for cpu type.
63 ;; These must match the values for enum processor_type in sparc.h.
64 (define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc"
65 (const (symbol_ref "sparc_cpu_attr")))
67 ;; Attribute for the instruction set.
68 ;; At present we only need to distinguish v9/!v9, but for clarity we
69 ;; test TARGET_V8 too.
70 (define_attr "isa" "v6,v8,v9,sparclet"
72 (cond [(symbol_ref "TARGET_V9") (const_string "v9")
73 (symbol_ref "TARGET_V8") (const_string "v8")
74 (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
75 (const_string "v6"))))
78 (define_attr "arch" "arch32bit,arch64bit"
80 (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")]
81 (const_string "arch32bit"))))
83 ;; Insn type. Used to default other attribute values.
85 ;; type "unary" insns have one input operand (1) and one output operand (0)
86 ;; type "binary" insns have two input operands (1,2) and one output (0)
87 ;; type "compare" insns have one or two input operands (0,1) and no output
88 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
91 "move,unary,binary,compare,load,sload,store,ialu,shift,uncond_branch,branch,call,sibcall,call_no_delay_slot,return,address,imul,fpload,fpstore,fp,fpmove,fpcmove,fpcmp,fpmul,fpdivs,fpdivd,fpsqrts,fpsqrtd,cmove,multi,misc"
92 (const_string "binary"))
94 ;; Set true if insn uses call-clobbered intermediate register.
95 (define_attr "use_clobbered" "false,true"
96 (if_then_else (and (eq_attr "type" "address")
97 (match_operand 0 "clobbered_register" ""))
99 (const_string "false")))
101 ;; Length (in # of insns).
102 (define_attr "length" ""
103 (cond [(eq_attr "type" "load,sload,fpload")
104 (if_then_else (match_operand 1 "symbolic_memory_operand" "")
105 (const_int 2) (const_int 1))
107 (eq_attr "type" "store,fpstore")
108 (if_then_else (match_operand 0 "symbolic_memory_operand" "")
109 (const_int 2) (const_int 1))
111 (eq_attr "type" "address") (const_int 2)
113 (eq_attr "type" "binary")
114 (if_then_else (ior (match_operand 2 "arith_operand" "")
115 (match_operand 2 "arith_double_operand" ""))
116 (const_int 1) (const_int 3))
118 (eq_attr "type" "multi") (const_int 2)
120 (eq_attr "type" "move,unary")
121 (if_then_else (ior (match_operand 1 "arith_operand" "")
122 (match_operand 1 "arith_double_operand" ""))
123 (const_int 1) (const_int 2))]
127 (define_asm_attributes
128 [(set_attr "length" "1")
129 (set_attr "type" "multi")])
131 ;; Attributes for instruction and branch scheduling
133 (define_attr "in_call_delay" "false,true"
134 (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,return,multi")
135 (const_string "false")
136 (eq_attr "type" "load,fpload,store,fpstore")
137 (if_then_else (eq_attr "length" "1")
138 (const_string "true")
139 (const_string "false"))
140 (eq_attr "type" "address")
141 (if_then_else (eq_attr "use_clobbered" "false")
142 (const_string "true")
143 (const_string "false"))]
144 (if_then_else (eq_attr "length" "1")
145 (const_string "true")
146 (const_string "false"))))
148 (define_delay (eq_attr "type" "call")
149 [(eq_attr "in_call_delay" "true") (nil) (nil)])
151 (define_attr "eligible_for_sibcall_delay" "false,true"
152 (symbol_ref "eligible_for_sibcall_delay(insn)"))
154 (define_delay (eq_attr "type" "sibcall")
155 [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
157 (define_attr "leaf_function" "false,true"
158 (const (symbol_ref "current_function_uses_only_leaf_regs")))
160 (define_attr "eligible_for_return_delay" "false,true"
161 (symbol_ref "eligible_for_return_delay(insn)"))
163 (define_attr "in_return_delay" "false,true"
164 (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
165 (eq_attr "length" "1"))
166 (eq_attr "leaf_function" "false"))
167 (eq_attr "eligible_for_return_delay" "false"))
168 (const_string "true")
169 (const_string "false")))
171 (define_delay (and (eq_attr "type" "return")
172 (eq_attr "isa" "v9"))
173 [(eq_attr "in_return_delay" "true") (nil) (nil)])
175 ;; ??? Should implement the notion of predelay slots for floating point
176 ;; branches. This would allow us to remove the nop always inserted before
177 ;; a floating point branch.
179 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
180 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
181 ;; This is because doing so will add several pipeline stalls to the path
182 ;; that the load/store did not come from. Unfortunately, there is no way
183 ;; to prevent fill_eager_delay_slots from using load/store without completely
184 ;; disabling them. For the SPEC benchmark set, this is a serious lose,
185 ;; because it prevents us from moving back the final store of inner loops.
187 (define_attr "in_branch_delay" "false,true"
188 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
189 (eq_attr "length" "1"))
190 (const_string "true")
191 (const_string "false")))
193 (define_attr "in_uncond_branch_delay" "false,true"
194 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
195 (eq_attr "length" "1"))
196 (const_string "true")
197 (const_string "false")))
199 (define_attr "in_annul_branch_delay" "false,true"
200 (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
201 (eq_attr "length" "1"))
202 (const_string "true")
203 (const_string "false")))
205 (define_delay (eq_attr "type" "branch")
206 [(eq_attr "in_branch_delay" "true")
207 (nil) (eq_attr "in_annul_branch_delay" "true")])
209 (define_delay (eq_attr "type" "uncond_branch")
210 [(eq_attr "in_uncond_branch_delay" "true")
213 ;; Function units of the SPARC
215 ;; (define_function_unit {name} {num-units} {n-users} {test}
216 ;; {ready-delay} {issue-delay} [{conflict-list}])
219 ;; (Noted only for documentation; units that take one cycle do not need to
222 ;; On the sparclite, integer multiply takes 1, 3, or 5 cycles depending on
225 ;; (define_function_unit "alu" 1 0
226 ;; (eq_attr "type" "unary,binary,move,address") 1 0)
228 ;; ---- cypress CY7C602 scheduling:
229 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
231 (define_function_unit "memory" 1 0
232 (and (eq_attr "cpu" "cypress")
233 (eq_attr "type" "load,sload,fpload"))
236 ;; SPARC has two floating-point units: the FP ALU,
237 ;; and the FP MUL/DIV/SQRT unit.
238 ;; Instruction timings on the CY7C602 are as follows
252 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
253 ;; More insns cause the chip to stall.
255 (define_function_unit "fp_alu" 1 0
256 (and (eq_attr "cpu" "cypress")
257 (eq_attr "type" "fp,fpmove"))
260 (define_function_unit "fp_mds" 1 0
261 (and (eq_attr "cpu" "cypress")
262 (eq_attr "type" "fpmul"))
265 (define_function_unit "fp_mds" 1 0
266 (and (eq_attr "cpu" "cypress")
267 (eq_attr "type" "fpdivs,fpdivd"))
270 (define_function_unit "fp_mds" 1 0
271 (and (eq_attr "cpu" "cypress")
272 (eq_attr "type" "fpsqrts,fpsqrtd"))
275 ;; ----- The TMS390Z55 scheduling
276 ;; The Supersparc can issue 1 - 3 insns per cycle: up to two integer,
277 ;; one ld/st, one fp.
278 ;; Memory delivers its result in one cycle to IU, zero cycles to FP
280 (define_function_unit "memory" 1 0
281 (and (eq_attr "cpu" "supersparc")
282 (eq_attr "type" "load,sload"))
285 (define_function_unit "memory" 1 0
286 (and (eq_attr "cpu" "supersparc")
287 (eq_attr "type" "fpload"))
290 (define_function_unit "memory" 1 0
291 (and (eq_attr "cpu" "supersparc")
292 (eq_attr "type" "store,fpstore"))
295 (define_function_unit "shift" 1 0
296 (and (eq_attr "cpu" "supersparc")
297 (eq_attr "type" "shift"))
300 ;; There are only two write ports to the integer register file
301 ;; A store also uses a write port
303 (define_function_unit "iwport" 2 0
304 (and (eq_attr "cpu" "supersparc")
305 (eq_attr "type" "load,sload,store,shift,ialu"))
308 ;; Timings; throughput/latency
309 ;; FADD 1/3 add/sub, format conv, compar, abs, neg
317 (define_function_unit "fp_alu" 1 0
318 (and (eq_attr "cpu" "supersparc")
319 (eq_attr "type" "fp,fpmove,fpcmp"))
322 (define_function_unit "fp_mds" 1 0
323 (and (eq_attr "cpu" "supersparc")
324 (eq_attr "type" "fpmul"))
327 (define_function_unit "fp_mds" 1 0
328 (and (eq_attr "cpu" "supersparc")
329 (eq_attr "type" "fpdivs"))
332 (define_function_unit "fp_mds" 1 0
333 (and (eq_attr "cpu" "supersparc")
334 (eq_attr "type" "fpdivd"))
337 (define_function_unit "fp_mds" 1 0
338 (and (eq_attr "cpu" "supersparc")
339 (eq_attr "type" "fpsqrts,fpsqrtd"))
342 (define_function_unit "fp_mds" 1 0
343 (and (eq_attr "cpu" "supersparc")
344 (eq_attr "type" "imul"))
347 ;; ----- hypersparc/sparclite86x scheduling
348 ;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are:
349 ;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB
350 ;; II/FF case is only when loading a 32 bit hi/lo constant
351 ;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp
352 ;; Memory delivers its result in one cycle to IU
354 (define_function_unit "memory" 1 0
355 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
356 (eq_attr "type" "load,sload,fpload"))
359 (define_function_unit "memory" 1 0
360 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
361 (eq_attr "type" "store,fpstore"))
364 (define_function_unit "sparclite86x_branch" 1 0
365 (and (eq_attr "cpu" "sparclite86x")
366 (eq_attr "type" "branch"))
369 ;; integer multiply insns
370 (define_function_unit "sparclite86x_shift" 1 0
371 (and (eq_attr "cpu" "sparclite86x")
372 (eq_attr "type" "shift"))
375 (define_function_unit "fp_alu" 1 0
376 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
377 (eq_attr "type" "fp,fpmove,fpcmp"))
380 (define_function_unit "fp_mds" 1 0
381 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
382 (eq_attr "type" "fpmul"))
385 (define_function_unit "fp_mds" 1 0
386 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
387 (eq_attr "type" "fpdivs"))
390 (define_function_unit "fp_mds" 1 0
391 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
392 (eq_attr "type" "fpdivd"))
395 (define_function_unit "fp_mds" 1 0
396 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
397 (eq_attr "type" "fpsqrts,fpsqrtd"))
400 (define_function_unit "fp_mds" 1 0
401 (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x"))
402 (eq_attr "type" "imul"))
405 ;; ----- sparclet tsc701 scheduling
406 ;; The tsc701 issues 1 insn per cycle.
407 ;; Results may be written back out of order.
409 ;; Loads take 2 extra cycles to complete and 4 can be buffered at a time.
411 (define_function_unit "tsc701_load" 4 1
412 (and (eq_attr "cpu" "tsc701")
413 (eq_attr "type" "load,sload"))
416 ;; Stores take 2(?) extra cycles to complete.
417 ;; It is desirable to not have any memory operation in the following 2 cycles.
418 ;; (??? or 2 memory ops in the case of std).
420 (define_function_unit "tsc701_store" 1 0
421 (and (eq_attr "cpu" "tsc701")
422 (eq_attr "type" "store"))
424 [(eq_attr "type" "load,sload,store")])
426 ;; The multiply unit has a latency of 5.
427 (define_function_unit "tsc701_mul" 1 0
428 (and (eq_attr "cpu" "tsc701")
429 (eq_attr "type" "imul"))
432 ;; ----- The UltraSPARC-1 scheduling
433 ;; UltraSPARC has two integer units. Shift instructions can only execute
434 ;; on IE0. Condition code setting instructions, call, and jmpl (including
435 ;; the ret and retl pseudo-instructions) can only execute on IE1.
436 ;; Branch on register uses IE1, but branch on condition code does not.
437 ;; Conditional moves take 2 cycles. No other instruction can issue in the
438 ;; same cycle as a conditional move.
439 ;; Multiply and divide take many cycles during which no other instructions
441 ;; Memory delivers its result in two cycles (except for signed loads,
442 ;; which take one cycle more). One memory instruction can be issued per
445 (define_function_unit "memory" 1 0
446 (and (eq_attr "cpu" "ultrasparc")
447 (eq_attr "type" "load,fpload"))
450 (define_function_unit "memory" 1 0
451 (and (eq_attr "cpu" "ultrasparc")
452 (eq_attr "type" "sload"))
455 (define_function_unit "memory" 1 0
456 (and (eq_attr "cpu" "ultrasparc")
457 (eq_attr "type" "store,fpstore"))
460 (define_function_unit "ieuN" 2 0
461 (and (eq_attr "cpu" "ultrasparc")
462 (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,sibcall,call_no_delay_slot,uncond_branch"))
465 (define_function_unit "ieu0" 1 0
466 (and (eq_attr "cpu" "ultrasparc")
467 (eq_attr "type" "shift"))
470 (define_function_unit "ieu0" 1 0
471 (and (eq_attr "cpu" "ultrasparc")
472 (eq_attr "type" "cmove"))
475 (define_function_unit "ieu1" 1 0
476 (and (eq_attr "cpu" "ultrasparc")
477 (eq_attr "type" "compare,call,sibcall,call_no_delay_slot,uncond_branch"))
480 (define_function_unit "cti" 1 0
481 (and (eq_attr "cpu" "ultrasparc")
482 (eq_attr "type" "branch"))
485 ;; Timings; throughput/latency
486 ;; FMOV 1/1 fmov, fabs, fneg
488 ;; FADD 1/3 add/sub, format conv, compar
494 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move.
496 ;; FDIV{s,d}/FSQRT{s,d} are given their own unit since they only
497 ;; use the FPM multiplier for final rounding 3 cycles before the
498 ;; end of their latency and we have no real way to model that.
500 ;; ??? This is really bogus because the timings really depend upon
501 ;; who uses the result. We should record who the user is with
502 ;; more descriptive 'type' attribute names and account for these
503 ;; issues in ultrasparc_adjust_cost.
505 (define_function_unit "fadd" 1 0
506 (and (eq_attr "cpu" "ultrasparc")
507 (eq_attr "type" "fpmove"))
510 (define_function_unit "fadd" 1 0
511 (and (eq_attr "cpu" "ultrasparc")
512 (eq_attr "type" "fpcmove"))
515 (define_function_unit "fadd" 1 0
516 (and (eq_attr "cpu" "ultrasparc")
517 (eq_attr "type" "fp"))
520 (define_function_unit "fadd" 1 0
521 (and (eq_attr "cpu" "ultrasparc")
522 (eq_attr "type" "fpcmp"))
525 (define_function_unit "fmul" 1 0
526 (and (eq_attr "cpu" "ultrasparc")
527 (eq_attr "type" "fpmul"))
530 (define_function_unit "fadd" 1 0
531 (and (eq_attr "cpu" "ultrasparc")
532 (eq_attr "type" "fpcmove"))
535 (define_function_unit "fdiv" 1 0
536 (and (eq_attr "cpu" "ultrasparc")
537 (eq_attr "type" "fpdivs"))
540 (define_function_unit "fdiv" 1 0
541 (and (eq_attr "cpu" "ultrasparc")
542 (eq_attr "type" "fpdivd"))
545 (define_function_unit "fdiv" 1 0
546 (and (eq_attr "cpu" "ultrasparc")
547 (eq_attr "type" "fpsqrts"))
550 (define_function_unit "fdiv" 1 0
551 (and (eq_attr "cpu" "ultrasparc")
552 (eq_attr "type" "fpsqrtd"))
555 ;; Compare instructions.
556 ;; This controls RTL generation and register allocation.
558 ;; We generate RTL for comparisons and branches by having the cmpxx
559 ;; patterns store away the operands. Then, the scc and bcc patterns
560 ;; emit RTL for both the compare and the branch.
562 ;; We do this because we want to generate different code for an sne and
563 ;; seq insn. In those cases, if the second operand of the compare is not
564 ;; const0_rtx, we want to compute the xor of the two operands and test
567 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
568 ;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
569 ;; insns that actually require more than one machine instruction.
571 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
573 (define_expand "cmpsi"
575 (compare:CC (match_operand:SI 0 "register_operand" "")
576 (match_operand:SI 1 "arith_operand" "")))]
580 sparc_compare_op0 = operands[0];
581 sparc_compare_op1 = operands[1];
585 (define_expand "cmpdi"
587 (compare:CCX (match_operand:DI 0 "register_operand" "")
588 (match_operand:DI 1 "arith_double_operand" "")))]
592 sparc_compare_op0 = operands[0];
593 sparc_compare_op1 = operands[1];
597 (define_expand "cmpsf"
598 ;; The 96 here isn't ever used by anyone.
600 (compare:CCFP (match_operand:SF 0 "register_operand" "")
601 (match_operand:SF 1 "register_operand" "")))]
605 sparc_compare_op0 = operands[0];
606 sparc_compare_op1 = operands[1];
610 (define_expand "cmpdf"
611 ;; The 96 here isn't ever used by anyone.
613 (compare:CCFP (match_operand:DF 0 "register_operand" "")
614 (match_operand:DF 1 "register_operand" "")))]
618 sparc_compare_op0 = operands[0];
619 sparc_compare_op1 = operands[1];
623 (define_expand "cmptf"
624 ;; The 96 here isn't ever used by anyone.
626 (compare:CCFP (match_operand:TF 0 "register_operand" "")
627 (match_operand:TF 1 "register_operand" "")))]
631 sparc_compare_op0 = operands[0];
632 sparc_compare_op1 = operands[1];
636 ;; Now the compare DEFINE_INSNs.
638 (define_insn "*cmpsi_insn"
640 (compare:CC (match_operand:SI 0 "register_operand" "r")
641 (match_operand:SI 1 "arith_operand" "rI")))]
644 [(set_attr "type" "compare")])
646 (define_insn "*cmpdi_sp64"
648 (compare:CCX (match_operand:DI 0 "register_operand" "r")
649 (match_operand:DI 1 "arith_double_operand" "rHI")))]
652 [(set_attr "type" "compare")])
654 (define_insn "*cmpsf_fpe"
655 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
656 (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
657 (match_operand:SF 2 "register_operand" "f")))]
662 return \"fcmpes\\t%0, %1, %2\";
663 return \"fcmpes\\t%1, %2\";
665 [(set_attr "type" "fpcmp")])
667 (define_insn "*cmpdf_fpe"
668 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
669 (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
670 (match_operand:DF 2 "register_operand" "e")))]
675 return \"fcmped\\t%0, %1, %2\";
676 return \"fcmped\\t%1, %2\";
678 [(set_attr "type" "fpcmp")])
680 (define_insn "*cmptf_fpe"
681 [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
682 (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
683 (match_operand:TF 2 "register_operand" "e")))]
684 "TARGET_FPU && TARGET_HARD_QUAD"
688 return \"fcmpeq\\t%0, %1, %2\";
689 return \"fcmpeq\\t%1, %2\";
691 [(set_attr "type" "fpcmp")])
693 (define_insn "*cmpsf_fp"
694 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
695 (compare:CCFP (match_operand:SF 1 "register_operand" "f")
696 (match_operand:SF 2 "register_operand" "f")))]
701 return \"fcmps\\t%0, %1, %2\";
702 return \"fcmps\\t%1, %2\";
704 [(set_attr "type" "fpcmp")])
706 (define_insn "*cmpdf_fp"
707 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
708 (compare:CCFP (match_operand:DF 1 "register_operand" "e")
709 (match_operand:DF 2 "register_operand" "e")))]
714 return \"fcmpd\\t%0, %1, %2\";
715 return \"fcmpd\\t%1, %2\";
717 [(set_attr "type" "fpcmp")])
719 (define_insn "*cmptf_fp"
720 [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
721 (compare:CCFP (match_operand:TF 1 "register_operand" "e")
722 (match_operand:TF 2 "register_operand" "e")))]
723 "TARGET_FPU && TARGET_HARD_QUAD"
727 return \"fcmpq\\t%0, %1, %2\";
728 return \"fcmpq\\t%1, %2\";
730 [(set_attr "type" "fpcmp")])
732 ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
733 ;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
734 ;; the same code as v8 (the addx/subx method has more applications). The
735 ;; exception to this is "reg != 0" which can be done in one instruction on v9
736 ;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
739 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
740 ;; generate addcc/subcc instructions.
742 (define_expand "seqsi_special"
744 (xor:SI (match_operand:SI 1 "register_operand" "")
745 (match_operand:SI 2 "register_operand" "")))
746 (parallel [(set (match_operand:SI 0 "register_operand" "")
747 (eq:SI (match_dup 3) (const_int 0)))
748 (clobber (reg:CC 100))])]
750 "{ operands[3] = gen_reg_rtx (SImode); }")
752 (define_expand "seqdi_special"
754 (xor:DI (match_operand:DI 1 "register_operand" "")
755 (match_operand:DI 2 "register_operand" "")))
756 (set (match_operand:DI 0 "register_operand" "")
757 (eq:DI (match_dup 3) (const_int 0)))]
759 "{ operands[3] = gen_reg_rtx (DImode); }")
761 (define_expand "snesi_special"
763 (xor:SI (match_operand:SI 1 "register_operand" "")
764 (match_operand:SI 2 "register_operand" "")))
765 (parallel [(set (match_operand:SI 0 "register_operand" "")
766 (ne:SI (match_dup 3) (const_int 0)))
767 (clobber (reg:CC 100))])]
769 "{ operands[3] = gen_reg_rtx (SImode); }")
771 (define_expand "snedi_special"
773 (xor:DI (match_operand:DI 1 "register_operand" "")
774 (match_operand:DI 2 "register_operand" "")))
775 (set (match_operand:DI 0 "register_operand" "")
776 (ne:DI (match_dup 3) (const_int 0)))]
778 "{ operands[3] = gen_reg_rtx (DImode); }")
780 (define_expand "seqdi_special_trunc"
782 (xor:DI (match_operand:DI 1 "register_operand" "")
783 (match_operand:DI 2 "register_operand" "")))
784 (set (match_operand:SI 0 "register_operand" "")
785 (eq:SI (match_dup 3) (const_int 0)))]
787 "{ operands[3] = gen_reg_rtx (DImode); }")
789 (define_expand "snedi_special_trunc"
791 (xor:DI (match_operand:DI 1 "register_operand" "")
792 (match_operand:DI 2 "register_operand" "")))
793 (set (match_operand:SI 0 "register_operand" "")
794 (ne:SI (match_dup 3) (const_int 0)))]
796 "{ operands[3] = gen_reg_rtx (DImode); }")
798 (define_expand "seqsi_special_extend"
800 (xor:SI (match_operand:SI 1 "register_operand" "")
801 (match_operand:SI 2 "register_operand" "")))
802 (parallel [(set (match_operand:DI 0 "register_operand" "")
803 (eq:DI (match_dup 3) (const_int 0)))
804 (clobber (reg:CC 100))])]
806 "{ operands[3] = gen_reg_rtx (SImode); }")
808 (define_expand "snesi_special_extend"
810 (xor:SI (match_operand:SI 1 "register_operand" "")
811 (match_operand:SI 2 "register_operand" "")))
812 (parallel [(set (match_operand:DI 0 "register_operand" "")
813 (ne:DI (match_dup 3) (const_int 0)))
814 (clobber (reg:CC 100))])]
816 "{ operands[3] = gen_reg_rtx (SImode); }")
818 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
819 ;; However, the code handles both SImode and DImode.
821 [(set (match_operand:SI 0 "intreg_operand" "")
822 (eq:SI (match_dup 1) (const_int 0)))]
826 if (GET_MODE (sparc_compare_op0) == SImode)
830 if (GET_MODE (operands[0]) == SImode)
831 pat = gen_seqsi_special (operands[0], sparc_compare_op0,
833 else if (! TARGET_ARCH64)
836 pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
841 else if (GET_MODE (sparc_compare_op0) == DImode)
847 else if (GET_MODE (operands[0]) == SImode)
848 pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
851 pat = gen_seqdi_special (operands[0], sparc_compare_op0,
856 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
858 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
859 emit_jump_insn (gen_sne (operands[0]));
864 if (gen_v9_scc (EQ, operands))
871 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
872 ;; However, the code handles both SImode and DImode.
874 [(set (match_operand:SI 0 "intreg_operand" "")
875 (ne:SI (match_dup 1) (const_int 0)))]
879 if (GET_MODE (sparc_compare_op0) == SImode)
883 if (GET_MODE (operands[0]) == SImode)
884 pat = gen_snesi_special (operands[0], sparc_compare_op0,
886 else if (! TARGET_ARCH64)
889 pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
894 else if (GET_MODE (sparc_compare_op0) == DImode)
900 else if (GET_MODE (operands[0]) == SImode)
901 pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
904 pat = gen_snedi_special (operands[0], sparc_compare_op0,
909 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
911 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
912 emit_jump_insn (gen_sne (operands[0]));
917 if (gen_v9_scc (NE, operands))
925 [(set (match_operand:SI 0 "intreg_operand" "")
926 (gt:SI (match_dup 1) (const_int 0)))]
930 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
932 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
933 emit_jump_insn (gen_sne (operands[0]));
938 if (gen_v9_scc (GT, operands))
946 [(set (match_operand:SI 0 "intreg_operand" "")
947 (lt:SI (match_dup 1) (const_int 0)))]
951 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
953 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
954 emit_jump_insn (gen_sne (operands[0]));
959 if (gen_v9_scc (LT, operands))
967 [(set (match_operand:SI 0 "intreg_operand" "")
968 (ge:SI (match_dup 1) (const_int 0)))]
972 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
974 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
975 emit_jump_insn (gen_sne (operands[0]));
980 if (gen_v9_scc (GE, operands))
988 [(set (match_operand:SI 0 "intreg_operand" "")
989 (le:SI (match_dup 1) (const_int 0)))]
993 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
995 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
996 emit_jump_insn (gen_sne (operands[0]));
1001 if (gen_v9_scc (LE, operands))
1008 (define_expand "sgtu"
1009 [(set (match_operand:SI 0 "intreg_operand" "")
1010 (gtu:SI (match_dup 1) (const_int 0)))]
1018 /* We can do ltu easily, so if both operands are registers, swap them and
1020 if ((GET_CODE (sparc_compare_op0) == REG
1021 || GET_CODE (sparc_compare_op0) == SUBREG)
1022 && (GET_CODE (sparc_compare_op1) == REG
1023 || GET_CODE (sparc_compare_op1) == SUBREG))
1025 tem = sparc_compare_op0;
1026 sparc_compare_op0 = sparc_compare_op1;
1027 sparc_compare_op1 = tem;
1028 pat = gen_sltu (operands[0]);
1029 if (pat == NULL_RTX)
1037 if (gen_v9_scc (GTU, operands))
1043 (define_expand "sltu"
1044 [(set (match_operand:SI 0 "intreg_operand" "")
1045 (ltu:SI (match_dup 1) (const_int 0)))]
1051 if (gen_v9_scc (LTU, operands))
1054 operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1057 (define_expand "sgeu"
1058 [(set (match_operand:SI 0 "intreg_operand" "")
1059 (geu:SI (match_dup 1) (const_int 0)))]
1065 if (gen_v9_scc (GEU, operands))
1068 operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1071 (define_expand "sleu"
1072 [(set (match_operand:SI 0 "intreg_operand" "")
1073 (leu:SI (match_dup 1) (const_int 0)))]
1081 /* We can do geu easily, so if both operands are registers, swap them and
1083 if ((GET_CODE (sparc_compare_op0) == REG
1084 || GET_CODE (sparc_compare_op0) == SUBREG)
1085 && (GET_CODE (sparc_compare_op1) == REG
1086 || GET_CODE (sparc_compare_op1) == SUBREG))
1088 tem = sparc_compare_op0;
1089 sparc_compare_op0 = sparc_compare_op1;
1090 sparc_compare_op1 = tem;
1091 pat = gen_sgeu (operands[0]);
1092 if (pat == NULL_RTX)
1100 if (gen_v9_scc (LEU, operands))
1106 ;; Now the DEFINE_INSNs for the scc cases.
1108 ;; The SEQ and SNE patterns are special because they can be done
1109 ;; without any branching and do not involve a COMPARE. We want
1110 ;; them to always use the splitz below so the results can be
1113 (define_insn "*snesi_zero"
1114 [(set (match_operand:SI 0 "register_operand" "=r")
1115 (ne:SI (match_operand:SI 1 "register_operand" "r")
1117 (clobber (reg:CC 100))]
1120 [(set_attr "length" "2")])
1123 [(set (match_operand:SI 0 "register_operand" "")
1124 (ne:SI (match_operand:SI 1 "register_operand" "")
1126 (clobber (reg:CC 100))]
1128 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1130 (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
1133 (define_insn "*neg_snesi_zero"
1134 [(set (match_operand:SI 0 "register_operand" "=r")
1135 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1137 (clobber (reg:CC 100))]
1140 [(set_attr "length" "2")])
1143 [(set (match_operand:SI 0 "register_operand" "")
1144 (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1146 (clobber (reg:CC 100))]
1148 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1150 (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1153 (define_insn "*snesi_zero_extend"
1154 [(set (match_operand:DI 0 "register_operand" "=r")
1155 (ne:DI (match_operand:SI 1 "register_operand" "r")
1157 (clobber (reg:CC 100))]
1160 [(set_attr "type" "unary")
1161 (set_attr "length" "2")])
1164 [(set (match_operand:DI 0 "register_operand" "")
1165 (ne:DI (match_operand:SI 1 "register_operand" "")
1167 (clobber (reg:CC 100))]
1169 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1171 (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
1173 (ltu:SI (reg:CC_NOOV 100)
1177 (define_insn "*snedi_zero"
1178 [(set (match_operand:DI 0 "register_operand" "=&r")
1179 (ne:DI (match_operand:DI 1 "register_operand" "r")
1183 [(set_attr "type" "cmove")
1184 (set_attr "length" "2")])
1187 [(set (match_operand:DI 0 "register_operand" "")
1188 (ne:DI (match_operand:DI 1 "register_operand" "")
1191 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1192 [(set (match_dup 0) (const_int 0))
1193 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1199 (define_insn "*neg_snedi_zero"
1200 [(set (match_operand:DI 0 "register_operand" "=&r")
1201 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1205 [(set_attr "type" "cmove")
1206 (set_attr "length" "2")])
1209 [(set (match_operand:DI 0 "register_operand" "")
1210 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1213 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1214 [(set (match_dup 0) (const_int 0))
1215 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1221 (define_insn "*snedi_zero_trunc"
1222 [(set (match_operand:SI 0 "register_operand" "=&r")
1223 (ne:SI (match_operand:DI 1 "register_operand" "r")
1227 [(set_attr "type" "cmove")
1228 (set_attr "length" "2")])
1231 [(set (match_operand:SI 0 "register_operand" "")
1232 (ne:SI (match_operand:DI 1 "register_operand" "")
1235 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1236 [(set (match_dup 0) (const_int 0))
1237 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1243 (define_insn "*seqsi_zero"
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (eq:SI (match_operand:SI 1 "register_operand" "r")
1247 (clobber (reg:CC 100))]
1250 [(set_attr "length" "2")])
1253 [(set (match_operand:SI 0 "register_operand" "")
1254 (eq:SI (match_operand:SI 1 "register_operand" "")
1256 (clobber (reg:CC 100))]
1258 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1260 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1263 (define_insn "*neg_seqsi_zero"
1264 [(set (match_operand:SI 0 "register_operand" "=r")
1265 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1267 (clobber (reg:CC 100))]
1270 [(set_attr "length" "2")])
1273 [(set (match_operand:SI 0 "register_operand" "")
1274 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1276 (clobber (reg:CC 100))]
1278 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1280 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1283 (define_insn "*seqsi_zero_extend"
1284 [(set (match_operand:DI 0 "register_operand" "=r")
1285 (eq:DI (match_operand:SI 1 "register_operand" "r")
1287 (clobber (reg:CC 100))]
1290 [(set_attr "type" "unary")
1291 (set_attr "length" "2")])
1294 [(set (match_operand:DI 0 "register_operand" "")
1295 (eq:DI (match_operand:SI 1 "register_operand" "")
1297 (clobber (reg:CC 100))]
1299 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1301 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1303 (ltu:SI (reg:CC_NOOV 100)
1307 (define_insn "*seqdi_zero"
1308 [(set (match_operand:DI 0 "register_operand" "=&r")
1309 (eq:DI (match_operand:DI 1 "register_operand" "r")
1313 [(set_attr "type" "cmove")
1314 (set_attr "length" "2")])
1317 [(set (match_operand:DI 0 "register_operand" "")
1318 (eq:DI (match_operand:DI 1 "register_operand" "")
1321 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1322 [(set (match_dup 0) (const_int 0))
1323 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1329 (define_insn "*neg_seqdi_zero"
1330 [(set (match_operand:DI 0 "register_operand" "=&r")
1331 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1335 [(set_attr "type" "cmove")
1336 (set_attr "length" "2")])
1339 [(set (match_operand:DI 0 "register_operand" "")
1340 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1343 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1344 [(set (match_dup 0) (const_int 0))
1345 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1351 (define_insn "*seqdi_zero_trunc"
1352 [(set (match_operand:SI 0 "register_operand" "=&r")
1353 (eq:SI (match_operand:DI 1 "register_operand" "r")
1357 [(set_attr "type" "cmove")
1358 (set_attr "length" "2")])
1361 [(set (match_operand:SI 0 "register_operand" "")
1362 (eq:SI (match_operand:DI 1 "register_operand" "")
1365 && ! reg_overlap_mentioned_p (operands[1], operands[0])"
1366 [(set (match_dup 0) (const_int 0))
1367 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1373 ;; We can also do (x + (i == 0)) and related, so put them in.
1374 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1377 (define_insn "*x_plus_i_ne_0"
1378 [(set (match_operand:SI 0 "register_operand" "=r")
1379 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1381 (match_operand:SI 2 "register_operand" "r")))
1382 (clobber (reg:CC 100))]
1385 [(set_attr "length" "2")])
1388 [(set (match_operand:SI 0 "register_operand" "")
1389 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1391 (match_operand:SI 2 "register_operand" "")))
1392 (clobber (reg:CC 100))]
1394 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1396 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1400 (define_insn "*x_minus_i_ne_0"
1401 [(set (match_operand:SI 0 "register_operand" "=r")
1402 (minus:SI (match_operand:SI 2 "register_operand" "r")
1403 (ne:SI (match_operand:SI 1 "register_operand" "r")
1405 (clobber (reg:CC 100))]
1408 [(set_attr "length" "2")])
1411 [(set (match_operand:SI 0 "register_operand" "")
1412 (minus:SI (match_operand:SI 2 "register_operand" "")
1413 (ne:SI (match_operand:SI 1 "register_operand" "")
1415 (clobber (reg:CC 100))]
1417 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1419 (set (match_dup 0) (minus:SI (match_dup 2)
1420 (ltu:SI (reg:CC 100) (const_int 0))))]
1423 (define_insn "*x_plus_i_eq_0"
1424 [(set (match_operand:SI 0 "register_operand" "=r")
1425 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1427 (match_operand:SI 2 "register_operand" "r")))
1428 (clobber (reg:CC 100))]
1431 [(set_attr "length" "2")])
1434 [(set (match_operand:SI 0 "register_operand" "")
1435 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1437 (match_operand:SI 2 "register_operand" "")))
1438 (clobber (reg:CC 100))]
1440 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1442 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1446 (define_insn "*x_minus_i_eq_0"
1447 [(set (match_operand:SI 0 "register_operand" "=r")
1448 (minus:SI (match_operand:SI 2 "register_operand" "r")
1449 (eq:SI (match_operand:SI 1 "register_operand" "r")
1451 (clobber (reg:CC 100))]
1454 [(set_attr "length" "2")])
1457 [(set (match_operand:SI 0 "register_operand" "")
1458 (minus:SI (match_operand:SI 2 "register_operand" "")
1459 (eq:SI (match_operand:SI 1 "register_operand" "")
1461 (clobber (reg:CC 100))]
1463 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1465 (set (match_dup 0) (minus:SI (match_dup 2)
1466 (geu:SI (reg:CC 100) (const_int 0))))]
1469 ;; We can also do GEU and LTU directly, but these operate after a compare.
1470 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1473 (define_insn "*sltu_insn"
1474 [(set (match_operand:SI 0 "register_operand" "=r")
1475 (ltu:SI (reg:CC 100) (const_int 0)))]
1477 "addx\\t%%g0, 0, %0"
1478 [(set_attr "type" "misc")
1479 (set_attr "length" "1")])
1481 (define_insn "*neg_sltu_insn"
1482 [(set (match_operand:SI 0 "register_operand" "=r")
1483 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1485 "subx\\t%%g0, 0, %0"
1486 [(set_attr "type" "misc")
1487 (set_attr "length" "1")])
1489 ;; ??? Combine should canonicalize these next two to the same pattern.
1490 (define_insn "*neg_sltu_minus_x"
1491 [(set (match_operand:SI 0 "register_operand" "=r")
1492 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1493 (match_operand:SI 1 "arith_operand" "rI")))]
1495 "subx\\t%%g0, %1, %0"
1496 [(set_attr "type" "misc")
1497 (set_attr "length" "1")])
1499 (define_insn "*neg_sltu_plus_x"
1500 [(set (match_operand:SI 0 "register_operand" "=r")
1501 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1502 (match_operand:SI 1 "arith_operand" "rI"))))]
1504 "subx\\t%%g0, %1, %0"
1505 [(set_attr "type" "misc")
1506 (set_attr "length" "1")])
1508 (define_insn "*sgeu_insn"
1509 [(set (match_operand:SI 0 "register_operand" "=r")
1510 (geu:SI (reg:CC 100) (const_int 0)))]
1512 "subx\\t%%g0, -1, %0"
1513 [(set_attr "type" "misc")
1514 (set_attr "length" "1")])
1516 (define_insn "*neg_sgeu_insn"
1517 [(set (match_operand:SI 0 "register_operand" "=r")
1518 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1520 "addx\\t%%g0, -1, %0"
1521 [(set_attr "type" "misc")
1522 (set_attr "length" "1")])
1524 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1525 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1528 (define_insn "*sltu_plus_x"
1529 [(set (match_operand:SI 0 "register_operand" "=r")
1530 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1531 (match_operand:SI 1 "arith_operand" "rI")))]
1533 "addx\\t%%g0, %1, %0"
1534 [(set_attr "type" "misc")
1535 (set_attr "length" "1")])
1537 (define_insn "*sltu_plus_x_plus_y"
1538 [(set (match_operand:SI 0 "register_operand" "=r")
1539 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1540 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1541 (match_operand:SI 2 "arith_operand" "rI"))))]
1544 [(set_attr "type" "misc")
1545 (set_attr "length" "1")])
1547 (define_insn "*x_minus_sltu"
1548 [(set (match_operand:SI 0 "register_operand" "=r")
1549 (minus:SI (match_operand:SI 1 "register_operand" "r")
1550 (ltu:SI (reg:CC 100) (const_int 0))))]
1553 [(set_attr "type" "misc")
1554 (set_attr "length" "1")])
1556 ;; ??? Combine should canonicalize these next two to the same pattern.
1557 (define_insn "*x_minus_y_minus_sltu"
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1560 (match_operand:SI 2 "arith_operand" "rI"))
1561 (ltu:SI (reg:CC 100) (const_int 0))))]
1563 "subx\\t%r1, %2, %0"
1564 [(set_attr "type" "misc")
1565 (set_attr "length" "1")])
1567 (define_insn "*x_minus_sltu_plus_y"
1568 [(set (match_operand:SI 0 "register_operand" "=r")
1569 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1570 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1571 (match_operand:SI 2 "arith_operand" "rI"))))]
1573 "subx\\t%r1, %2, %0"
1574 [(set_attr "type" "misc")
1575 (set_attr "length" "1")])
1577 (define_insn "*sgeu_plus_x"
1578 [(set (match_operand:SI 0 "register_operand" "=r")
1579 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1580 (match_operand:SI 1 "register_operand" "r")))]
1583 [(set_attr "type" "misc")
1584 (set_attr "length" "1")])
1586 (define_insn "*x_minus_sgeu"
1587 [(set (match_operand:SI 0 "register_operand" "=r")
1588 (minus:SI (match_operand:SI 1 "register_operand" "r")
1589 (geu:SI (reg:CC 100) (const_int 0))))]
1592 [(set_attr "type" "misc")
1593 (set_attr "length" "1")])
1596 [(set (match_operand:SI 0 "register_operand" "=r")
1597 (match_operator:SI 2 "noov_compare_op"
1598 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1600 ;; 32 bit LTU/GEU are better implemented using addx/subx
1601 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1602 && (GET_MODE (operands[1]) == CCXmode
1603 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1604 [(set (match_dup 0) (const_int 0))
1606 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1612 ;; These control RTL generation for conditional jump insns
1614 ;; The quad-word fp compare library routines all return nonzero to indicate
1615 ;; true, which is different from the equivalent libgcc routines, so we must
1616 ;; handle them specially here.
1618 (define_expand "beq"
1620 (if_then_else (eq (match_dup 1) (const_int 0))
1621 (label_ref (match_operand 0 "" ""))
1626 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1627 && GET_CODE (sparc_compare_op0) == REG
1628 && GET_MODE (sparc_compare_op0) == DImode)
1630 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1633 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1635 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1636 emit_jump_insn (gen_bne (operands[0]));
1639 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1642 (define_expand "bne"
1644 (if_then_else (ne (match_dup 1) (const_int 0))
1645 (label_ref (match_operand 0 "" ""))
1650 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1651 && GET_CODE (sparc_compare_op0) == REG
1652 && GET_MODE (sparc_compare_op0) == DImode)
1654 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1657 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1659 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1660 emit_jump_insn (gen_bne (operands[0]));
1663 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1666 (define_expand "bgt"
1668 (if_then_else (gt (match_dup 1) (const_int 0))
1669 (label_ref (match_operand 0 "" ""))
1674 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1675 && GET_CODE (sparc_compare_op0) == REG
1676 && GET_MODE (sparc_compare_op0) == DImode)
1678 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1681 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1683 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1684 emit_jump_insn (gen_bne (operands[0]));
1687 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1690 (define_expand "bgtu"
1692 (if_then_else (gtu (match_dup 1) (const_int 0))
1693 (label_ref (match_operand 0 "" ""))
1697 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1700 (define_expand "blt"
1702 (if_then_else (lt (match_dup 1) (const_int 0))
1703 (label_ref (match_operand 0 "" ""))
1708 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1709 && GET_CODE (sparc_compare_op0) == REG
1710 && GET_MODE (sparc_compare_op0) == DImode)
1712 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1715 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1717 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1718 emit_jump_insn (gen_bne (operands[0]));
1721 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1724 (define_expand "bltu"
1726 (if_then_else (ltu (match_dup 1) (const_int 0))
1727 (label_ref (match_operand 0 "" ""))
1731 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1734 (define_expand "bge"
1736 (if_then_else (ge (match_dup 1) (const_int 0))
1737 (label_ref (match_operand 0 "" ""))
1742 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1743 && GET_CODE (sparc_compare_op0) == REG
1744 && GET_MODE (sparc_compare_op0) == DImode)
1746 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1749 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1751 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1752 emit_jump_insn (gen_bne (operands[0]));
1755 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1758 (define_expand "bgeu"
1760 (if_then_else (geu (match_dup 1) (const_int 0))
1761 (label_ref (match_operand 0 "" ""))
1765 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1768 (define_expand "ble"
1770 (if_then_else (le (match_dup 1) (const_int 0))
1771 (label_ref (match_operand 0 "" ""))
1776 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1777 && GET_CODE (sparc_compare_op0) == REG
1778 && GET_MODE (sparc_compare_op0) == DImode)
1780 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1783 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1785 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1786 emit_jump_insn (gen_bne (operands[0]));
1789 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1792 (define_expand "bleu"
1794 (if_then_else (leu (match_dup 1) (const_int 0))
1795 (label_ref (match_operand 0 "" ""))
1799 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1802 (define_expand "bunordered"
1804 (if_then_else (unordered (match_dup 1) (const_int 0))
1805 (label_ref (match_operand 0 "" ""))
1810 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1812 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1814 emit_jump_insn (gen_beq (operands[0]));
1817 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1821 (define_expand "bordered"
1823 (if_then_else (ordered (match_dup 1) (const_int 0))
1824 (label_ref (match_operand 0 "" ""))
1829 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1831 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1832 emit_jump_insn (gen_bne (operands[0]));
1835 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1839 (define_expand "bungt"
1841 (if_then_else (ungt (match_dup 1) (const_int 0))
1842 (label_ref (match_operand 0 "" ""))
1847 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1849 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1850 emit_jump_insn (gen_bgt (operands[0]));
1853 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1856 (define_expand "bunlt"
1858 (if_then_else (unlt (match_dup 1) (const_int 0))
1859 (label_ref (match_operand 0 "" ""))
1864 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1866 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1867 emit_jump_insn (gen_bne (operands[0]));
1870 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1873 (define_expand "buneq"
1875 (if_then_else (uneq (match_dup 1) (const_int 0))
1876 (label_ref (match_operand 0 "" ""))
1881 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1883 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1884 emit_jump_insn (gen_beq (operands[0]));
1887 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1890 (define_expand "bunge"
1892 (if_then_else (unge (match_dup 1) (const_int 0))
1893 (label_ref (match_operand 0 "" ""))
1898 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1900 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1901 emit_jump_insn (gen_bne (operands[0]));
1904 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1907 (define_expand "bunle"
1909 (if_then_else (unle (match_dup 1) (const_int 0))
1910 (label_ref (match_operand 0 "" ""))
1915 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1917 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1918 emit_jump_insn (gen_bne (operands[0]));
1921 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1924 (define_expand "bltgt"
1926 (if_then_else (ltgt (match_dup 1) (const_int 0))
1927 (label_ref (match_operand 0 "" ""))
1932 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1934 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1935 emit_jump_insn (gen_bne (operands[0]));
1938 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1941 ;; Now match both normal and inverted jump.
1943 ;; XXX fpcmp nop braindamage
1944 (define_insn "*normal_branch"
1946 (if_then_else (match_operator 0 "noov_compare_op"
1947 [(reg 100) (const_int 0)])
1948 (label_ref (match_operand 1 "" ""))
1953 return output_cbranch (operands[0], 1, 0,
1954 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1955 ! final_sequence, insn);
1957 [(set_attr "type" "branch")])
1959 ;; XXX fpcmp nop braindamage
1960 (define_insn "*inverted_branch"
1962 (if_then_else (match_operator 0 "noov_compare_op"
1963 [(reg 100) (const_int 0)])
1965 (label_ref (match_operand 1 "" ""))))]
1969 return output_cbranch (operands[0], 1, 1,
1970 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1971 ! final_sequence, insn);
1973 [(set_attr "type" "branch")])
1975 ;; XXX fpcmp nop braindamage
1976 (define_insn "*normal_fp_branch"
1978 (if_then_else (match_operator 1 "comparison_operator"
1979 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1981 (label_ref (match_operand 2 "" ""))
1986 return output_cbranch (operands[1], 2, 0,
1987 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1988 ! final_sequence, insn);
1990 [(set_attr "type" "branch")])
1992 ;; XXX fpcmp nop braindamage
1993 (define_insn "*inverted_fp_branch"
1995 (if_then_else (match_operator 1 "comparison_operator"
1996 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1999 (label_ref (match_operand 2 "" ""))))]
2003 return output_cbranch (operands[1], 2, 1,
2004 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2005 ! final_sequence, insn);
2007 [(set_attr "type" "branch")])
2009 ;; XXX fpcmp nop braindamage
2010 (define_insn "*normal_fpe_branch"
2012 (if_then_else (match_operator 1 "comparison_operator"
2013 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2015 (label_ref (match_operand 2 "" ""))
2020 return output_cbranch (operands[1], 2, 0,
2021 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2022 ! final_sequence, insn);
2024 [(set_attr "type" "branch")])
2026 ;; XXX fpcmp nop braindamage
2027 (define_insn "*inverted_fpe_branch"
2029 (if_then_else (match_operator 1 "comparison_operator"
2030 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2033 (label_ref (match_operand 2 "" ""))))]
2037 return output_cbranch (operands[1], 2, 1,
2038 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2039 ! final_sequence, insn);
2041 [(set_attr "type" "branch")])
2043 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2044 ;; in the architecture.
2046 ;; There are no 32 bit brreg insns.
2049 (define_insn "*normal_int_branch_sp64"
2051 (if_then_else (match_operator 0 "v9_regcmp_op"
2052 [(match_operand:DI 1 "register_operand" "r")
2054 (label_ref (match_operand 2 "" ""))
2059 return output_v9branch (operands[0], 1, 2, 0,
2060 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2061 ! final_sequence, insn);
2063 [(set_attr "type" "branch")])
2066 (define_insn "*inverted_int_branch_sp64"
2068 (if_then_else (match_operator 0 "v9_regcmp_op"
2069 [(match_operand:DI 1 "register_operand" "r")
2072 (label_ref (match_operand 2 "" ""))))]
2076 return output_v9branch (operands[0], 1, 2, 1,
2077 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2078 ! final_sequence, insn);
2080 [(set_attr "type" "branch")])
2082 ;; Load program counter insns.
2084 (define_insn "get_pc"
2085 [(clobber (reg:SI 15))
2086 (set (match_operand 0 "register_operand" "=r")
2087 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2088 "flag_pic && REGNO (operands[0]) == 23"
2089 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2090 [(set_attr "length" "3")])
2092 ;; Currently unused...
2093 ;; (define_insn "get_pc_via_rdpc"
2094 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2097 ;; [(set_attr "type" "move")])
2100 ;; Move instructions
2102 (define_expand "movqi"
2103 [(set (match_operand:QI 0 "general_operand" "")
2104 (match_operand:QI 1 "general_operand" ""))]
2108 /* Working with CONST_INTs is easier, so convert
2109 a double if needed. */
2110 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2112 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2114 else if (GET_CODE (operands[1]) == CONST_INT)
2116 /* And further, we know for all QI cases that only the
2117 low byte is significant, which we can always process
2118 in a single insn. So mask it now. */
2119 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2122 /* Handle sets of MEM first. */
2123 if (GET_CODE (operands[0]) == MEM)
2125 if (reg_or_0_operand (operands[1], QImode))
2128 if (! reload_in_progress)
2130 operands[0] = validize_mem (operands[0]);
2131 operands[1] = force_reg (QImode, operands[1]);
2135 /* Fixup PIC cases. */
2138 if (CONSTANT_P (operands[1])
2139 && pic_address_needs_scratch (operands[1]))
2140 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2142 if (symbolic_operand (operands[1], QImode))
2144 operands[1] = legitimize_pic_address (operands[1],
2146 (reload_in_progress ?
2153 /* All QI constants require only one insn, so proceed. */
2159 (define_insn "*movqi_insn"
2160 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2161 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2162 "(register_operand (operands[0], QImode)
2163 || reg_or_0_operand (operands[1], QImode))"
2168 [(set_attr "type" "move,load,store")
2169 (set_attr "length" "1")])
2171 (define_expand "movhi"
2172 [(set (match_operand:HI 0 "general_operand" "")
2173 (match_operand:HI 1 "general_operand" ""))]
2177 /* Working with CONST_INTs is easier, so convert
2178 a double if needed. */
2179 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2180 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2182 /* Handle sets of MEM first. */
2183 if (GET_CODE (operands[0]) == MEM)
2185 if (reg_or_0_operand (operands[1], HImode))
2188 if (! reload_in_progress)
2190 operands[0] = validize_mem (operands[0]);
2191 operands[1] = force_reg (HImode, operands[1]);
2195 /* Fixup PIC cases. */
2198 if (CONSTANT_P (operands[1])
2199 && pic_address_needs_scratch (operands[1]))
2200 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2202 if (symbolic_operand (operands[1], HImode))
2204 operands[1] = legitimize_pic_address (operands[1],
2206 (reload_in_progress ?
2213 /* This makes sure we will not get rematched due to splittage. */
2214 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2216 else if (CONSTANT_P (operands[1])
2217 && GET_CODE (operands[1]) != HIGH
2218 && GET_CODE (operands[1]) != LO_SUM)
2220 sparc_emit_set_const32 (operands[0], operands[1]);
2227 (define_insn "*movhi_const64_special"
2228 [(set (match_operand:HI 0 "register_operand" "=r")
2229 (match_operand:HI 1 "const64_high_operand" ""))]
2231 "sethi\\t%%hi(%a1), %0"
2232 [(set_attr "type" "move")
2233 (set_attr "length" "1")])
2235 (define_insn "*movhi_insn"
2236 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2237 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2238 "(register_operand (operands[0], HImode)
2239 || reg_or_0_operand (operands[1], HImode))"
2242 sethi\\t%%hi(%a1), %0
2245 [(set_attr "type" "move,move,load,store")
2246 (set_attr "length" "1")])
2248 ;; We always work with constants here.
2249 (define_insn "*movhi_lo_sum"
2250 [(set (match_operand:HI 0 "register_operand" "=r")
2251 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2252 (match_operand:HI 2 "arith_operand" "I")))]
2255 [(set_attr "type" "ialu")
2256 (set_attr "length" "1")])
2258 (define_expand "movsi"
2259 [(set (match_operand:SI 0 "general_operand" "")
2260 (match_operand:SI 1 "general_operand" ""))]
2264 /* Working with CONST_INTs is easier, so convert
2265 a double if needed. */
2266 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2267 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2269 /* Handle sets of MEM first. */
2270 if (GET_CODE (operands[0]) == MEM)
2272 if (reg_or_0_operand (operands[1], SImode))
2275 if (! reload_in_progress)
2277 operands[0] = validize_mem (operands[0]);
2278 operands[1] = force_reg (SImode, operands[1]);
2282 /* Fixup PIC cases. */
2285 if (CONSTANT_P (operands[1])
2286 && pic_address_needs_scratch (operands[1]))
2287 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2289 if (GET_CODE (operands[1]) == LABEL_REF)
2292 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2296 if (symbolic_operand (operands[1], SImode))
2298 operands[1] = legitimize_pic_address (operands[1],
2300 (reload_in_progress ?
2307 /* If we are trying to toss an integer constant into the
2308 FPU registers, force it into memory. */
2309 if (GET_CODE (operands[0]) == REG
2310 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2311 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2312 && CONSTANT_P (operands[1]))
2313 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2316 /* This makes sure we will not get rematched due to splittage. */
2317 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2319 else if (CONSTANT_P (operands[1])
2320 && GET_CODE (operands[1]) != HIGH
2321 && GET_CODE (operands[1]) != LO_SUM)
2323 sparc_emit_set_const32 (operands[0], operands[1]);
2330 ;; This is needed to show CSE exactly which bits are set
2331 ;; in a 64-bit register by sethi instructions.
2332 (define_insn "*movsi_const64_special"
2333 [(set (match_operand:SI 0 "register_operand" "=r")
2334 (match_operand:SI 1 "const64_high_operand" ""))]
2336 "sethi\\t%%hi(%a1), %0"
2337 [(set_attr "type" "move")
2338 (set_attr "length" "1")])
2340 (define_insn "*movsi_insn"
2341 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2342 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2343 "(register_operand (operands[0], SImode)
2344 || reg_or_0_operand (operands[1], SImode))"
2348 sethi\\t%%hi(%a1), %0
2355 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2356 (set_attr "length" "1")])
2358 (define_insn "*movsi_lo_sum"
2359 [(set (match_operand:SI 0 "register_operand" "=r")
2360 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2361 (match_operand:SI 2 "immediate_operand" "in")))]
2363 "or\\t%1, %%lo(%a2), %0"
2364 [(set_attr "type" "ialu")
2365 (set_attr "length" "1")])
2367 (define_insn "*movsi_high"
2368 [(set (match_operand:SI 0 "register_operand" "=r")
2369 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2371 "sethi\\t%%hi(%a1), %0"
2372 [(set_attr "type" "move")
2373 (set_attr "length" "1")])
2375 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2376 ;; so that CSE won't optimize the address computation away.
2377 (define_insn "movsi_lo_sum_pic"
2378 [(set (match_operand:SI 0 "register_operand" "=r")
2379 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2380 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2382 "or\\t%1, %%lo(%a2), %0"
2383 [(set_attr "type" "ialu")
2384 (set_attr "length" "1")])
2386 (define_insn "movsi_high_pic"
2387 [(set (match_operand:SI 0 "register_operand" "=r")
2388 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2389 "flag_pic && check_pic (1)"
2390 "sethi\\t%%hi(%a1), %0"
2391 [(set_attr "type" "move")
2392 (set_attr "length" "1")])
2394 (define_expand "movsi_pic_label_ref"
2395 [(set (match_dup 3) (high:SI
2396 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2398 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2399 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2400 (set (match_operand:SI 0 "register_operand" "=r")
2401 (minus:SI (match_dup 5) (match_dup 4)))]
2405 current_function_uses_pic_offset_table = 1;
2406 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2409 operands[3] = operands[0];
2410 operands[4] = operands[0];
2414 operands[3] = gen_reg_rtx (SImode);
2415 operands[4] = gen_reg_rtx (SImode);
2417 operands[5] = pic_offset_table_rtx;
2420 (define_insn "*movsi_high_pic_label_ref"
2421 [(set (match_operand:SI 0 "register_operand" "=r")
2423 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2424 (match_operand:SI 2 "" "")] 5)))]
2426 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2427 [(set_attr "type" "move")
2428 (set_attr "length" "1")])
2430 (define_insn "*movsi_lo_sum_pic_label_ref"
2431 [(set (match_operand:SI 0 "register_operand" "=r")
2432 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2433 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2434 (match_operand:SI 3 "" "")] 5)))]
2436 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2437 [(set_attr "type" "ialu")
2438 (set_attr "length" "1")])
2440 (define_expand "movdi"
2441 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2442 (match_operand:DI 1 "general_operand" ""))]
2446 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2447 if (GET_CODE (operands[1]) == CONST_DOUBLE
2448 #if HOST_BITS_PER_WIDE_INT == 32
2449 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2450 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2451 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2452 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2455 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2457 /* Handle MEM cases first. */
2458 if (GET_CODE (operands[0]) == MEM)
2460 /* If it's a REG, we can always do it.
2461 The const zero case is more complex, on v9
2462 we can always perform it. */
2463 if (register_operand (operands[1], DImode)
2465 && (operands[1] == const0_rtx)))
2468 if (! reload_in_progress)
2470 operands[0] = validize_mem (operands[0]);
2471 operands[1] = force_reg (DImode, operands[1]);
2477 if (CONSTANT_P (operands[1])
2478 && pic_address_needs_scratch (operands[1]))
2479 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2481 if (GET_CODE (operands[1]) == LABEL_REF)
2483 if (! TARGET_ARCH64)
2485 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2489 if (symbolic_operand (operands[1], DImode))
2491 operands[1] = legitimize_pic_address (operands[1],
2493 (reload_in_progress ?
2500 /* If we are trying to toss an integer constant into the
2501 FPU registers, force it into memory. */
2502 if (GET_CODE (operands[0]) == REG
2503 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2504 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2505 && CONSTANT_P (operands[1]))
2506 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2509 /* This makes sure we will not get rematched due to splittage. */
2510 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2512 else if (TARGET_ARCH64
2513 && CONSTANT_P (operands[1])
2514 && GET_CODE (operands[1]) != HIGH
2515 && GET_CODE (operands[1]) != LO_SUM)
2517 sparc_emit_set_const64 (operands[0], operands[1]);
2525 ;; Be careful, fmovd does not exist when !arch64.
2526 ;; We match MEM moves directly when we have correct even
2527 ;; numbered registers, but fall into splits otherwise.
2528 ;; The constraint ordering here is really important to
2529 ;; avoid insane problems in reload, especially for patterns
2532 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2533 ;; (const_int -5016)))
2536 (define_insn "*movdi_insn_sp32"
2537 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2538 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2540 (register_operand (operands[0], DImode)
2541 || register_operand (operands[1], DImode))"
2554 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2555 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2557 ;; The following are generated by sparc_emit_set_const64
2558 (define_insn "*movdi_sp64_dbl"
2559 [(set (match_operand:DI 0 "register_operand" "=r")
2560 (match_operand:DI 1 "const64_operand" ""))]
2562 && HOST_BITS_PER_WIDE_INT != 64)"
2564 [(set_attr "type" "move")
2565 (set_attr "length" "1")])
2567 ;; This is needed to show CSE exactly which bits are set
2568 ;; in a 64-bit register by sethi instructions.
2569 (define_insn "*movdi_const64_special"
2570 [(set (match_operand:DI 0 "register_operand" "=r")
2571 (match_operand:DI 1 "const64_high_operand" ""))]
2573 "sethi\\t%%hi(%a1), %0"
2574 [(set_attr "type" "move")
2575 (set_attr "length" "1")])
2577 (define_insn "*movdi_insn_sp64_novis"
2578 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2579 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2580 "TARGET_ARCH64 && ! TARGET_VIS &&
2581 (register_operand (operands[0], DImode)
2582 || reg_or_0_operand (operands[1], DImode))"
2585 sethi\\t%%hi(%a1), %0
2592 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore")
2593 (set_attr "length" "1")])
2595 (define_insn "*movdi_insn_sp64_vis"
2596 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2597 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2598 "TARGET_ARCH64 && TARGET_VIS &&
2599 (register_operand (operands[0], DImode)
2600 || reg_or_0_operand (operands[1], DImode))"
2603 sethi\\t%%hi(%a1), %0
2611 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove")
2612 (set_attr "length" "1")])
2614 (define_expand "movdi_pic_label_ref"
2615 [(set (match_dup 3) (high:DI
2616 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2618 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2619 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2620 (set (match_operand:DI 0 "register_operand" "=r")
2621 (minus:DI (match_dup 5) (match_dup 4)))]
2622 "TARGET_ARCH64 && flag_pic"
2625 current_function_uses_pic_offset_table = 1;
2626 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2629 operands[3] = operands[0];
2630 operands[4] = operands[0];
2634 operands[3] = gen_reg_rtx (DImode);
2635 operands[4] = gen_reg_rtx (DImode);
2637 operands[5] = pic_offset_table_rtx;
2640 (define_insn "*movdi_high_pic_label_ref"
2641 [(set (match_operand:DI 0 "register_operand" "=r")
2643 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2644 (match_operand:DI 2 "" "")] 5)))]
2645 "TARGET_ARCH64 && flag_pic"
2646 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2647 [(set_attr "type" "move")
2648 (set_attr "length" "1")])
2650 (define_insn "*movdi_lo_sum_pic_label_ref"
2651 [(set (match_operand:DI 0 "register_operand" "=r")
2652 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2653 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2654 (match_operand:DI 3 "" "")] 5)))]
2655 "TARGET_ARCH64 && flag_pic"
2656 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2657 [(set_attr "type" "ialu")
2658 (set_attr "length" "1")])
2660 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2661 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2663 (define_insn "movdi_lo_sum_pic"
2664 [(set (match_operand:DI 0 "register_operand" "=r")
2665 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2666 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2667 "TARGET_ARCH64 && flag_pic"
2668 "or\\t%1, %%lo(%a2), %0"
2669 [(set_attr "type" "ialu")
2670 (set_attr "length" "1")])
2672 (define_insn "movdi_high_pic"
2673 [(set (match_operand:DI 0 "register_operand" "=r")
2674 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2675 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2676 "sethi\\t%%hi(%a1), %0"
2677 [(set_attr "type" "move")
2678 (set_attr "length" "1")])
2680 (define_insn "*sethi_di_medlow_embmedany_pic"
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2682 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2683 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2684 "sethi\\t%%hi(%a1), %0"
2685 [(set_attr "type" "move")
2686 (set_attr "length" "1")])
2688 (define_insn "*sethi_di_medlow"
2689 [(set (match_operand:DI 0 "register_operand" "=r")
2690 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2691 "TARGET_CM_MEDLOW && check_pic (1)"
2692 "sethi\\t%%hi(%a1), %0"
2693 [(set_attr "type" "move")
2694 (set_attr "length" "1")])
2696 (define_insn "*losum_di_medlow"
2697 [(set (match_operand:DI 0 "register_operand" "=r")
2698 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2699 (match_operand:DI 2 "symbolic_operand" "")))]
2701 "or\\t%1, %%lo(%a2), %0"
2702 [(set_attr "type" "ialu")
2703 (set_attr "length" "1")])
2705 (define_insn "seth44"
2706 [(set (match_operand:DI 0 "register_operand" "=r")
2707 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2709 "sethi\\t%%h44(%a1), %0"
2710 [(set_attr "type" "move")
2711 (set_attr "length" "1")])
2713 (define_insn "setm44"
2714 [(set (match_operand:DI 0 "register_operand" "=r")
2715 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2716 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2718 "or\\t%1, %%m44(%a2), %0"
2719 [(set_attr "type" "move")
2720 (set_attr "length" "1")])
2722 (define_insn "setl44"
2723 [(set (match_operand:DI 0 "register_operand" "=r")
2724 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2725 (match_operand:DI 2 "symbolic_operand" "")))]
2727 "or\\t%1, %%l44(%a2), %0"
2728 [(set_attr "type" "ialu")
2729 (set_attr "length" "1")])
2731 (define_insn "sethh"
2732 [(set (match_operand:DI 0 "register_operand" "=r")
2733 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2735 "sethi\\t%%hh(%a1), %0"
2736 [(set_attr "type" "move")
2737 (set_attr "length" "1")])
2739 (define_insn "setlm"
2740 [(set (match_operand:DI 0 "register_operand" "=r")
2741 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2743 "sethi\\t%%lm(%a1), %0"
2744 [(set_attr "type" "move")
2745 (set_attr "length" "1")])
2747 (define_insn "sethm"
2748 [(set (match_operand:DI 0 "register_operand" "=r")
2749 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2750 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2752 "or\\t%1, %%hm(%a2), %0"
2753 [(set_attr "type" "ialu")
2754 (set_attr "length" "1")])
2756 (define_insn "setlo"
2757 [(set (match_operand:DI 0 "register_operand" "=r")
2758 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2759 (match_operand:DI 2 "symbolic_operand" "")))]
2761 "or\\t%1, %%lo(%a2), %0"
2762 [(set_attr "type" "ialu")
2763 (set_attr "length" "1")])
2765 (define_insn "embmedany_sethi"
2766 [(set (match_operand:DI 0 "register_operand" "=r")
2767 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2768 "TARGET_CM_EMBMEDANY && check_pic (1)"
2769 "sethi\\t%%hi(%a1), %0"
2770 [(set_attr "type" "move")
2771 (set_attr "length" "1")])
2773 (define_insn "embmedany_losum"
2774 [(set (match_operand:DI 0 "register_operand" "=r")
2775 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2776 (match_operand:DI 2 "data_segment_operand" "")))]
2777 "TARGET_CM_EMBMEDANY"
2778 "add\\t%1, %%lo(%a2), %0"
2779 [(set_attr "type" "ialu")
2780 (set_attr "length" "1")])
2782 (define_insn "embmedany_brsum"
2783 [(set (match_operand:DI 0 "register_operand" "=r")
2784 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2785 "TARGET_CM_EMBMEDANY"
2787 [(set_attr "length" "1")])
2789 (define_insn "embmedany_textuhi"
2790 [(set (match_operand:DI 0 "register_operand" "=r")
2791 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2792 "TARGET_CM_EMBMEDANY && check_pic (1)"
2793 "sethi\\t%%uhi(%a1), %0"
2794 [(set_attr "type" "move")
2795 (set_attr "length" "1")])
2797 (define_insn "embmedany_texthi"
2798 [(set (match_operand:DI 0 "register_operand" "=r")
2799 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2800 "TARGET_CM_EMBMEDANY && check_pic (1)"
2801 "sethi\\t%%hi(%a1), %0"
2802 [(set_attr "type" "move")
2803 (set_attr "length" "1")])
2805 (define_insn "embmedany_textulo"
2806 [(set (match_operand:DI 0 "register_operand" "=r")
2807 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2808 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2809 "TARGET_CM_EMBMEDANY"
2810 "or\\t%1, %%ulo(%a2), %0"
2811 [(set_attr "type" "ialu")
2812 (set_attr "length" "1")])
2814 (define_insn "embmedany_textlo"
2815 [(set (match_operand:DI 0 "register_operand" "=r")
2816 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2817 (match_operand:DI 2 "text_segment_operand" "")))]
2818 "TARGET_CM_EMBMEDANY"
2819 "or\\t%1, %%lo(%a2), %0"
2820 [(set_attr "type" "ialu")
2821 (set_attr "length" "1")])
2823 ;; Now some patterns to help reload out a bit.
2824 (define_expand "reload_indi"
2825 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2826 (match_operand:DI 1 "immediate_operand" "")
2827 (match_operand:TI 2 "register_operand" "=&r")])]
2829 || TARGET_CM_EMBMEDANY)
2833 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2834 gen_rtx_REG (DImode, REGNO (operands[2])));
2838 (define_expand "reload_outdi"
2839 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2840 (match_operand:DI 1 "immediate_operand" "")
2841 (match_operand:TI 2 "register_operand" "=&r")])]
2843 || TARGET_CM_EMBMEDANY)
2847 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2848 gen_rtx_REG (DImode, REGNO (operands[2])));
2852 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2854 [(set (match_operand:DI 0 "register_operand" "")
2855 (match_operand:DI 1 "const_int_operand" ""))]
2856 "! TARGET_ARCH64 && reload_completed"
2857 [(clobber (const_int 0))]
2860 #if HOST_BITS_PER_WIDE_INT == 32
2861 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2862 (INTVAL (operands[1]) < 0) ?
2865 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2868 unsigned int low, high;
2870 low = INTVAL (operands[1]) & 0xffffffff;
2871 high = (INTVAL (operands[1]) >> 32) & 0xffffffff;
2872 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2874 /* Slick... but this trick loses if this subreg constant part
2875 can be done in one insn. */
2876 if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2877 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2878 gen_highpart (SImode, operands[0])));
2880 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2886 [(set (match_operand:DI 0 "register_operand" "")
2887 (match_operand:DI 1 "const_double_operand" ""))]
2888 "! TARGET_ARCH64 && reload_completed"
2889 [(clobber (const_int 0))]
2892 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2893 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2895 /* Slick... but this trick loses if this subreg constant part
2896 can be done in one insn. */
2897 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2898 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2899 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2901 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2902 gen_highpart (SImode, operands[0])));
2906 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2907 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2913 [(set (match_operand:DI 0 "register_operand" "")
2914 (match_operand:DI 1 "register_operand" ""))]
2915 "! TARGET_ARCH64 && reload_completed"
2916 [(clobber (const_int 0))]
2919 rtx set_dest = operands[0];
2920 rtx set_src = operands[1];
2924 if (GET_CODE (set_dest) == SUBREG)
2925 set_dest = alter_subreg (set_dest);
2926 if (GET_CODE (set_src) == SUBREG)
2927 set_src = alter_subreg (set_src);
2929 dest1 = gen_highpart (SImode, set_dest);
2930 dest2 = gen_lowpart (SImode, set_dest);
2931 src1 = gen_highpart (SImode, set_src);
2932 src2 = gen_lowpart (SImode, set_src);
2934 /* Now emit using the real source and destination we found, swapping
2935 the order if we detect overlap. */
2936 if (reg_overlap_mentioned_p (dest1, src2))
2938 emit_insn (gen_movsi (dest2, src2));
2939 emit_insn (gen_movsi (dest1, src1));
2943 emit_insn (gen_movsi (dest1, src1));
2944 emit_insn (gen_movsi (dest2, src2));
2949 ;; Now handle the cases of memory moves from/to non-even
2950 ;; DI mode register pairs.
2952 [(set (match_operand:DI 0 "register_operand" "")
2953 (match_operand:DI 1 "memory_operand" ""))]
2956 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2957 [(clobber (const_int 0))]
2960 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2961 rtx word1 = change_address (operands[1], SImode,
2962 plus_constant_for_output (XEXP (word0, 0), 4));
2963 rtx high_part = gen_highpart (SImode, operands[0]);
2964 rtx low_part = gen_lowpart (SImode, operands[0]);
2966 if (reg_overlap_mentioned_p (high_part, word1))
2968 emit_insn (gen_movsi (low_part, word1));
2969 emit_insn (gen_movsi (high_part, word0));
2973 emit_insn (gen_movsi (high_part, word0));
2974 emit_insn (gen_movsi (low_part, word1));
2980 [(set (match_operand:DI 0 "memory_operand" "")
2981 (match_operand:DI 1 "register_operand" ""))]
2984 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2985 [(clobber (const_int 0))]
2988 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2989 rtx word1 = change_address (operands[0], SImode,
2990 plus_constant_for_output (XEXP (word0, 0), 4));
2991 rtx high_part = gen_highpart (SImode, operands[1]);
2992 rtx low_part = gen_lowpart (SImode, operands[1]);
2994 emit_insn (gen_movsi (word0, high_part));
2995 emit_insn (gen_movsi (word1, low_part));
3000 ;; Floating point move insns
3002 (define_insn "*movsf_insn_novis"
3003 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
3004 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
3005 "(TARGET_FPU && ! TARGET_VIS)
3006 && (register_operand (operands[0], SFmode)
3007 || register_operand (operands[1], SFmode)
3008 || fp_zero_operand (operands[1], SFmode))"
3011 if (GET_CODE (operands[1]) == CONST_DOUBLE
3012 && (which_alternative == 2
3013 || which_alternative == 3
3014 || which_alternative == 4))
3019 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3020 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3021 operands[1] = GEN_INT (i);
3024 switch (which_alternative)
3027 return \"fmovs\\t%1, %0\";
3029 return \"clr\\t%0\";
3031 return \"sethi\\t%%hi(%a1), %0\";
3033 return \"mov\\t%1, %0\";
3038 return \"ld\\t%1, %0\";
3041 return \"st\\t%r1, %0\";
3046 [(set_attr "type" "fpmove,move,move,move,*,load,fpload,fpstore,store")
3047 (set_attr "length" "1")])
3049 (define_insn "*movsf_insn_vis"
3050 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3051 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3052 "(TARGET_FPU && TARGET_VIS)
3053 && (register_operand (operands[0], SFmode)
3054 || register_operand (operands[1], SFmode)
3055 || fp_zero_operand (operands[1], SFmode))"
3058 if (GET_CODE (operands[1]) == CONST_DOUBLE
3059 && (which_alternative == 3
3060 || which_alternative == 4
3061 || which_alternative == 5))
3066 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3067 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3068 operands[1] = GEN_INT (i);
3071 switch (which_alternative)
3074 return \"fmovs\\t%1, %0\";
3076 return \"fzeros\\t%0\";
3078 return \"clr\\t%0\";
3080 return \"sethi\\t%%hi(%a1), %0\";
3082 return \"mov\\t%1, %0\";
3087 return \"ld\\t%1, %0\";
3090 return \"st\\t%r1, %0\";
3095 [(set_attr "type" "fpmove,fpmove,move,move,move,*,load,fpload,fpstore,store")
3096 (set_attr "length" "1")])
3098 (define_insn "*movsf_lo_sum"
3099 [(set (match_operand:SF 0 "register_operand" "")
3100 (lo_sum:SF (match_operand:SF 1 "register_operand" "")
3101 (match_operand:SF 2 "const_double_operand" "")))]
3102 "TARGET_FPU && fp_high_losum_p (operands[2])"
3108 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3109 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3110 operands[2] = GEN_INT (i);
3111 return \"or\\t%1, %%lo(%a2), %0\";
3113 [(set_attr "type" "ialu")
3114 (set_attr "length" "1")])
3116 (define_insn "*movsf_high"
3117 [(set (match_operand:SF 0 "register_operand" "")
3118 (high:SF (match_operand:SF 1 "const_double_operand" "")))]
3119 "TARGET_FPU && fp_high_losum_p (operands[1])"
3125 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3126 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3127 operands[1] = GEN_INT (i);
3128 return \"sethi\\t%%hi(%1), %0\";
3130 [(set_attr "type" "move")
3131 (set_attr "length" "1")])
3134 [(set (match_operand:SF 0 "register_operand" "")
3135 (match_operand:SF 1 "const_double_operand" ""))]
3137 && fp_high_losum_p (operands[1])
3138 && (GET_CODE (operands[0]) == REG
3139 && REGNO (operands[0]) < 32)"
3140 [(set (match_dup 0) (high:SF (match_dup 1)))
3141 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3143 ;; Exactly the same as above, except that all `f' cases are deleted.
3144 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3147 (define_insn "*movsf_no_f_insn"
3148 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
3149 (match_operand:SF 1 "input_operand" "r,m,r"))]
3151 && (register_operand (operands[0], SFmode)
3152 || register_operand (operands[1], SFmode))"
3157 [(set_attr "type" "move,load,store")
3158 (set_attr "length" "1")])
3160 (define_expand "movsf"
3161 [(set (match_operand:SF 0 "general_operand" "")
3162 (match_operand:SF 1 "general_operand" ""))]
3166 /* Force SFmode constants into memory. */
3167 if (GET_CODE (operands[0]) == REG
3168 && CONSTANT_P (operands[1]))
3170 /* emit_group_store will send such bogosity to us when it is
3171 not storing directly into memory. So fix this up to avoid
3172 crashes in output_constant_pool. */
3173 if (operands [1] == const0_rtx)
3174 operands[1] = CONST0_RTX (SFmode);
3176 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3179 /* We are able to build any SF constant in integer registers
3180 with at most 2 instructions. */
3181 if (REGNO (operands[0]) < 32)
3184 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3188 /* Handle sets of MEM first. */
3189 if (GET_CODE (operands[0]) == MEM)
3191 if (register_operand (operands[1], SFmode)
3192 || fp_zero_operand (operands[1], SFmode))
3195 if (! reload_in_progress)
3197 operands[0] = validize_mem (operands[0]);
3198 operands[1] = force_reg (SFmode, operands[1]);
3202 /* Fixup PIC cases. */
3205 if (CONSTANT_P (operands[1])
3206 && pic_address_needs_scratch (operands[1]))
3207 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3209 if (symbolic_operand (operands[1], SFmode))
3211 operands[1] = legitimize_pic_address (operands[1],
3213 (reload_in_progress ?
3223 (define_expand "movdf"
3224 [(set (match_operand:DF 0 "general_operand" "")
3225 (match_operand:DF 1 "general_operand" ""))]
3229 /* Force DFmode constants into memory. */
3230 if (GET_CODE (operands[0]) == REG
3231 && CONSTANT_P (operands[1]))
3233 /* emit_group_store will send such bogosity to us when it is
3234 not storing directly into memory. So fix this up to avoid
3235 crashes in output_constant_pool. */
3236 if (operands [1] == const0_rtx)
3237 operands[1] = CONST0_RTX (DFmode);
3239 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3240 && fp_zero_operand (operands[1], DFmode))
3243 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3247 /* Handle MEM cases first. */
3248 if (GET_CODE (operands[0]) == MEM)
3250 if (register_operand (operands[1], DFmode)
3251 || fp_zero_operand (operands[1], DFmode))
3254 if (! reload_in_progress)
3256 operands[0] = validize_mem (operands[0]);
3257 operands[1] = force_reg (DFmode, operands[1]);
3261 /* Fixup PIC cases. */
3264 if (CONSTANT_P (operands[1])
3265 && pic_address_needs_scratch (operands[1]))
3266 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3268 if (symbolic_operand (operands[1], DFmode))
3270 operands[1] = legitimize_pic_address (operands[1],
3272 (reload_in_progress ?
3282 ;; Be careful, fmovd does not exist when !v9.
3283 (define_insn "*movdf_insn_sp32"
3284 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3285 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3288 && (register_operand (operands[0], DFmode)
3289 || register_operand (operands[1], DFmode)
3290 || fp_zero_operand (operands[1], DFmode))"
3302 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3303 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3305 (define_insn "*movdf_no_e_insn_sp32"
3306 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3307 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3311 && (register_operand (operands[0], DFmode)
3312 || register_operand (operands[1], DFmode)
3313 || fp_zero_operand (operands[1], DFmode))"
3320 [(set_attr "type" "load,store,*,*,*")
3321 (set_attr "length" "1,1,2,2,2")])
3323 (define_insn "*movdf_no_e_insn_v9_sp32"
3324 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3325 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3329 && (register_operand (operands[0], DFmode)
3330 || register_operand (operands[1], DFmode)
3331 || fp_zero_operand (operands[1], DFmode))"
3338 [(set_attr "type" "load,store,store,*,*")
3339 (set_attr "length" "1,1,1,2,2")])
3341 ;; We have available v9 double floats but not 64-bit
3342 ;; integer registers and no VIS.
3343 (define_insn "*movdf_insn_v9only_novis"
3344 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3345 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3350 && (register_operand (operands[0], DFmode)
3351 || register_operand (operands[1], DFmode)
3352 || fp_zero_operand (operands[1], DFmode))"
3363 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3364 (set_attr "length" "1,1,1,1,1,1,2,2,2")])
3366 ;; We have available v9 double floats but not 64-bit
3367 ;; integer registers but we have VIS.
3368 (define_insn "*movdf_insn_v9only_vis"
3369 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3370 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3374 && (register_operand (operands[0], DFmode)
3375 || register_operand (operands[1], DFmode)
3376 || fp_zero_operand (operands[1], DFmode))"
3388 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3389 (set_attr "length" "1,1,1,1,1,1,1,2,2,2")])
3391 ;; We have available both v9 double floats and 64-bit
3392 ;; integer registers. No VIS though.
3393 (define_insn "*movdf_insn_sp64_novis"
3394 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3395 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3399 && (register_operand (operands[0], DFmode)
3400 || register_operand (operands[1], DFmode)
3401 || fp_zero_operand (operands[1], DFmode))"
3410 [(set_attr "type" "fpmove,load,store,move,load,store,*")
3411 (set_attr "length" "1,1,1,1,1,1,2")])
3413 ;; We have available both v9 double floats and 64-bit
3414 ;; integer registers. And we have VIS.
3415 (define_insn "*movdf_insn_sp64_vis"
3416 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3417 (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
3421 && (register_operand (operands[0], DFmode)
3422 || register_operand (operands[1], DFmode)
3423 || fp_zero_operand (operands[1], DFmode))"
3433 [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*")
3434 (set_attr "length" "1,1,1,1,1,1,1,2")])
3436 (define_insn "*movdf_no_e_insn_sp64"
3437 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3438 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3441 && (register_operand (operands[0], DFmode)
3442 || register_operand (operands[1], DFmode)
3443 || fp_zero_operand (operands[1], DFmode))"
3448 [(set_attr "type" "move,load,store")
3449 (set_attr "length" "1")])
3452 [(set (match_operand:DF 0 "register_operand" "")
3453 (match_operand:DF 1 "const_double_operand" ""))]
3455 && (GET_CODE (operands[0]) == REG
3456 && REGNO (operands[0]) < 32)
3457 && ! fp_zero_operand(operands[1], DFmode)
3458 && reload_completed"
3459 [(clobber (const_int 0))]
3465 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3466 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3467 if (GET_CODE (operands[0]) == SUBREG)
3468 operands[0] = alter_subreg (operands[0]);
3469 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3473 #if HOST_BITS_PER_WIDE_INT == 64
3476 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3477 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3478 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3480 emit_insn (gen_movdi (operands[0],
3481 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3487 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3490 /* Slick... but this trick loses if this subreg constant part
3491 can be done in one insn. */
3493 && !(SPARC_SETHI_P (l[0])
3494 || SPARC_SIMM13_P (l[0])))
3496 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3497 gen_highpart (SImode, operands[0])));
3501 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3508 ;; Ok, now the splits to handle all the multi insn and
3509 ;; mis-aligned memory address cases.
3510 ;; In these splits please take note that we must be
3511 ;; careful when V9 but not ARCH64 because the integer
3512 ;; register DFmode cases must be handled.
3514 [(set (match_operand:DF 0 "register_operand" "")
3515 (match_operand:DF 1 "register_operand" ""))]
3518 && ((GET_CODE (operands[0]) == REG
3519 && REGNO (operands[0]) < 32)
3520 || (GET_CODE (operands[0]) == SUBREG
3521 && GET_CODE (SUBREG_REG (operands[0])) == REG
3522 && REGNO (SUBREG_REG (operands[0])) < 32))))
3523 && reload_completed"
3524 [(clobber (const_int 0))]
3527 rtx set_dest = operands[0];
3528 rtx set_src = operands[1];
3532 if (GET_CODE (set_dest) == SUBREG)
3533 set_dest = alter_subreg (set_dest);
3534 if (GET_CODE (set_src) == SUBREG)
3535 set_src = alter_subreg (set_src);
3537 dest1 = gen_highpart (SFmode, set_dest);
3538 dest2 = gen_lowpart (SFmode, set_dest);
3539 src1 = gen_highpart (SFmode, set_src);
3540 src2 = gen_lowpart (SFmode, set_src);
3542 /* Now emit using the real source and destination we found, swapping
3543 the order if we detect overlap. */
3544 if (reg_overlap_mentioned_p (dest1, src2))
3546 emit_insn (gen_movsf (dest2, src2));
3547 emit_insn (gen_movsf (dest1, src1));
3551 emit_insn (gen_movsf (dest1, src1));
3552 emit_insn (gen_movsf (dest2, src2));
3558 [(set (match_operand:DF 0 "register_operand" "")
3559 (match_operand:DF 1 "memory_operand" ""))]
3562 && (((REGNO (operands[0]) % 2) != 0)
3563 || ! mem_min_alignment (operands[1], 8))
3564 && offsettable_memref_p (operands[1])"
3565 [(clobber (const_int 0))]
3568 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3569 rtx word1 = change_address (operands[1], SFmode,
3570 plus_constant_for_output (XEXP (word0, 0), 4));
3572 if (GET_CODE (operands[0]) == SUBREG)
3573 operands[0] = alter_subreg (operands[0]);
3575 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3577 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3579 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3584 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3586 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3593 [(set (match_operand:DF 0 "memory_operand" "")
3594 (match_operand:DF 1 "register_operand" ""))]
3597 && (((REGNO (operands[1]) % 2) != 0)
3598 || ! mem_min_alignment (operands[0], 8))
3599 && offsettable_memref_p (operands[0])"
3600 [(clobber (const_int 0))]
3603 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3604 rtx word1 = change_address (operands[0], SFmode,
3605 plus_constant_for_output (XEXP (word0, 0), 4));
3607 if (GET_CODE (operands[1]) == SUBREG)
3608 operands[1] = alter_subreg (operands[1]);
3609 emit_insn (gen_movsf (word0,
3610 gen_highpart (SFmode, operands[1])));
3611 emit_insn (gen_movsf (word1,
3612 gen_lowpart (SFmode, operands[1])));
3617 [(set (match_operand:DF 0 "memory_operand" "")
3618 (match_operand:DF 1 "fp_zero_operand" ""))]
3622 && ! mem_min_alignment (operands[0], 8)))
3623 && offsettable_memref_p (operands[0])"
3624 [(clobber (const_int 0))]
3629 dest1 = change_address (operands[0], SFmode, NULL_RTX);
3630 dest2 = change_address (operands[0], SFmode,
3631 plus_constant_for_output (XEXP (dest1, 0), 4));
3632 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3633 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3638 [(set (match_operand:DF 0 "register_operand" "")
3639 (match_operand:DF 1 "fp_zero_operand" ""))]
3642 && ((GET_CODE (operands[0]) == REG
3643 && REGNO (operands[0]) < 32)
3644 || (GET_CODE (operands[0]) == SUBREG
3645 && GET_CODE (SUBREG_REG (operands[0])) == REG
3646 && REGNO (SUBREG_REG (operands[0])) < 32))"
3647 [(clobber (const_int 0))]
3650 rtx set_dest = operands[0];
3653 if (GET_CODE (set_dest) == SUBREG)
3654 set_dest = alter_subreg (set_dest);
3655 dest1 = gen_highpart (SFmode, set_dest);
3656 dest2 = gen_lowpart (SFmode, set_dest);
3657 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3658 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3662 (define_expand "movtf"
3663 [(set (match_operand:TF 0 "general_operand" "")
3664 (match_operand:TF 1 "general_operand" ""))]
3668 /* Force TFmode constants into memory. */
3669 if (GET_CODE (operands[0]) == REG
3670 && CONSTANT_P (operands[1]))
3672 /* emit_group_store will send such bogosity to us when it is
3673 not storing directly into memory. So fix this up to avoid
3674 crashes in output_constant_pool. */
3675 if (operands [1] == const0_rtx)
3676 operands[1] = CONST0_RTX (TFmode);
3678 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3681 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3685 /* Handle MEM cases first, note that only v9 guarentees
3686 full 16-byte alignment for quads. */
3687 if (GET_CODE (operands[0]) == MEM)
3689 if (register_operand (operands[1], TFmode)
3690 || fp_zero_operand (operands[1], TFmode))
3693 if (! reload_in_progress)
3695 operands[0] = validize_mem (operands[0]);
3696 operands[1] = force_reg (TFmode, operands[1]);
3700 /* Fixup PIC cases. */
3703 if (CONSTANT_P (operands[1])
3704 && pic_address_needs_scratch (operands[1]))
3705 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3707 if (symbolic_operand (operands[1], TFmode))
3709 operands[1] = legitimize_pic_address (operands[1],
3711 (reload_in_progress ?
3721 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3722 ;; we must split them all. :-(
3723 (define_insn "*movtf_insn_sp32"
3724 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3725 (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
3729 && (register_operand (operands[0], TFmode)
3730 || register_operand (operands[1], TFmode)
3731 || fp_zero_operand (operands[1], TFmode))"
3733 [(set_attr "length" "4")])
3735 (define_insn "*movtf_insn_vis_sp32"
3736 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3737 (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
3741 && (register_operand (operands[0], TFmode)
3742 || register_operand (operands[1], TFmode)
3743 || fp_zero_operand (operands[1], TFmode))"
3745 [(set_attr "length" "4")])
3747 ;; Exactly the same as above, except that all `e' cases are deleted.
3748 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3751 (define_insn "*movtf_no_e_insn_sp32"
3752 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3753 (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
3756 && (register_operand (operands[0], TFmode)
3757 || register_operand (operands[1], TFmode)
3758 || fp_zero_operand (operands[1], TFmode))"
3760 [(set_attr "length" "4")])
3762 ;; Now handle the float reg cases directly when arch64,
3763 ;; hard_quad, and proper reg number alignment are all true.
3764 (define_insn "*movtf_insn_hq_sp64"
3765 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3766 (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
3771 && (register_operand (operands[0], TFmode)
3772 || register_operand (operands[1], TFmode)
3773 || fp_zero_operand (operands[1], TFmode))"
3780 [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3781 (set_attr "length" "1,1,1,2,2")])
3783 (define_insn "*movtf_insn_hq_vis_sp64"
3784 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3785 (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
3790 && (register_operand (operands[0], TFmode)
3791 || register_operand (operands[1], TFmode)
3792 || fp_zero_operand (operands[1], TFmode))"
3800 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3801 (set_attr "length" "1,1,1,2,2,2")])
3803 ;; Now we allow the integer register cases even when
3804 ;; only arch64 is true.
3805 (define_insn "*movtf_insn_sp64"
3806 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3807 (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
3811 && ! TARGET_HARD_QUAD
3812 && (register_operand (operands[0], TFmode)
3813 || register_operand (operands[1], TFmode)
3814 || fp_zero_operand (operands[1], TFmode))"
3816 [(set_attr "length" "2")])
3818 (define_insn "*movtf_insn_vis_sp64"
3819 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3820 (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
3824 && ! TARGET_HARD_QUAD
3825 && (register_operand (operands[0], TFmode)
3826 || register_operand (operands[1], TFmode)
3827 || fp_zero_operand (operands[1], TFmode))"
3829 [(set_attr "length" "2")])
3831 (define_insn "*movtf_no_e_insn_sp64"
3832 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3833 (match_operand:TF 1 "input_operand" "orG,rG"))]
3836 && (register_operand (operands[0], TFmode)
3837 || register_operand (operands[1], TFmode)
3838 || fp_zero_operand (operands[1], TFmode))"
3840 [(set_attr "length" "2")])
3842 ;; Now all the splits to handle multi-insn TF mode moves.
3844 [(set (match_operand:TF 0 "register_operand" "")
3845 (match_operand:TF 1 "register_operand" ""))]
3849 && ! TARGET_HARD_QUAD))"
3850 [(clobber (const_int 0))]
3853 rtx set_dest = operands[0];
3854 rtx set_src = operands[1];
3858 if (GET_CODE (set_dest) == SUBREG)
3859 set_dest = alter_subreg (set_dest);
3860 if (GET_CODE (set_src) == SUBREG)
3861 set_src = alter_subreg (set_src);
3863 dest1 = gen_df_reg (set_dest, 0);
3864 dest2 = gen_df_reg (set_dest, 1);
3865 src1 = gen_df_reg (set_src, 0);
3866 src2 = gen_df_reg (set_src, 1);
3868 /* Now emit using the real source and destination we found, swapping
3869 the order if we detect overlap. */
3870 if (reg_overlap_mentioned_p (dest1, src2))
3872 emit_insn (gen_movdf (dest2, src2));
3873 emit_insn (gen_movdf (dest1, src1));
3877 emit_insn (gen_movdf (dest1, src1));
3878 emit_insn (gen_movdf (dest2, src2));
3884 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3885 (match_operand:TF 1 "fp_zero_operand" ""))]
3887 [(clobber (const_int 0))]
3890 rtx set_dest = operands[0];
3893 switch (GET_CODE (set_dest))
3896 set_dest = alter_subreg (set_dest);
3899 dest1 = gen_df_reg (set_dest, 0);
3900 dest2 = gen_df_reg (set_dest, 1);
3903 dest1 = change_address (set_dest, DFmode, NULL_RTX);
3904 dest2 = change_address (set_dest, DFmode,
3905 plus_constant_for_output (XEXP (dest1, 0), 8));
3911 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3912 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3917 [(set (match_operand:TF 0 "register_operand" "")
3918 (match_operand:TF 1 "memory_operand" ""))]
3920 && offsettable_memref_p (operands[1]))"
3921 [(clobber (const_int 0))]
3924 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3925 rtx word1 = change_address (operands[1], DFmode,
3926 plus_constant_for_output (XEXP (word0, 0), 8));
3927 rtx set_dest, dest1, dest2;
3929 set_dest = operands[0];
3930 if (GET_CODE (set_dest) == SUBREG)
3931 set_dest = alter_subreg (set_dest);
3933 dest1 = gen_df_reg (set_dest, 0);
3934 dest2 = gen_df_reg (set_dest, 1);
3936 /* Now output, ordering such that we don't clobber any registers
3937 mentioned in the address. */
3938 if (reg_overlap_mentioned_p (dest1, word1))
3941 emit_insn (gen_movdf (dest2, word1));
3942 emit_insn (gen_movdf (dest1, word0));
3946 emit_insn (gen_movdf (dest1, word0));
3947 emit_insn (gen_movdf (dest2, word1));
3953 [(set (match_operand:TF 0 "memory_operand" "")
3954 (match_operand:TF 1 "register_operand" ""))]
3956 && offsettable_memref_p (operands[0]))"
3957 [(clobber (const_int 0))]
3960 rtx word1 = change_address (operands[0], DFmode, NULL_RTX);
3961 rtx word2 = change_address (operands[0], DFmode,
3962 plus_constant_for_output (XEXP (word1, 0), 8));
3965 set_src = operands[1];
3966 if (GET_CODE (set_src) == SUBREG)
3967 set_src = alter_subreg (set_src);
3969 emit_insn (gen_movdf (word1, gen_df_reg (set_src, 0)));
3970 emit_insn (gen_movdf (word2, gen_df_reg (set_src, 1)));
3974 ;; Sparc V9 conditional move instructions.
3976 ;; We can handle larger constants here for some flavors, but for now we keep
3977 ;; it simple and only allow those constants supported by all flavours.
3978 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3979 ;; 3 contains the constant if one is present, but we handle either for
3980 ;; generality (sparc.c puts a constant in operand 2).
3982 (define_expand "movqicc"
3983 [(set (match_operand:QI 0 "register_operand" "")
3984 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3985 (match_operand:QI 2 "arith10_operand" "")
3986 (match_operand:QI 3 "arith10_operand" "")))]
3990 enum rtx_code code = GET_CODE (operands[1]);
3992 if (GET_MODE (sparc_compare_op0) == DImode
3996 if (sparc_compare_op1 == const0_rtx
3997 && GET_CODE (sparc_compare_op0) == REG
3998 && GET_MODE (sparc_compare_op0) == DImode
3999 && v9_regcmp_p (code))
4001 operands[1] = gen_rtx_fmt_ee (code, DImode,
4002 sparc_compare_op0, sparc_compare_op1);
4006 rtx cc_reg = gen_compare_reg (code,
4007 sparc_compare_op0, sparc_compare_op1);
4008 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4012 (define_expand "movhicc"
4013 [(set (match_operand:HI 0 "register_operand" "")
4014 (if_then_else:HI (match_operand 1 "comparison_operator" "")
4015 (match_operand:HI 2 "arith10_operand" "")
4016 (match_operand:HI 3 "arith10_operand" "")))]
4020 enum rtx_code code = GET_CODE (operands[1]);
4022 if (GET_MODE (sparc_compare_op0) == DImode
4026 if (sparc_compare_op1 == const0_rtx
4027 && GET_CODE (sparc_compare_op0) == REG
4028 && GET_MODE (sparc_compare_op0) == DImode
4029 && v9_regcmp_p (code))
4031 operands[1] = gen_rtx_fmt_ee (code, DImode,
4032 sparc_compare_op0, sparc_compare_op1);
4036 rtx cc_reg = gen_compare_reg (code,
4037 sparc_compare_op0, sparc_compare_op1);
4038 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4042 (define_expand "movsicc"
4043 [(set (match_operand:SI 0 "register_operand" "")
4044 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4045 (match_operand:SI 2 "arith10_operand" "")
4046 (match_operand:SI 3 "arith10_operand" "")))]
4050 enum rtx_code code = GET_CODE (operands[1]);
4051 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4053 if (sparc_compare_op1 == const0_rtx
4054 && GET_CODE (sparc_compare_op0) == REG
4055 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4057 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4058 sparc_compare_op0, sparc_compare_op1);
4062 rtx cc_reg = gen_compare_reg (code,
4063 sparc_compare_op0, sparc_compare_op1);
4064 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4065 cc_reg, const0_rtx);
4069 (define_expand "movdicc"
4070 [(set (match_operand:DI 0 "register_operand" "")
4071 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4072 (match_operand:DI 2 "arith10_double_operand" "")
4073 (match_operand:DI 3 "arith10_double_operand" "")))]
4077 enum rtx_code code = GET_CODE (operands[1]);
4079 if (sparc_compare_op1 == const0_rtx
4080 && GET_CODE (sparc_compare_op0) == REG
4081 && GET_MODE (sparc_compare_op0) == DImode
4082 && v9_regcmp_p (code))
4084 operands[1] = gen_rtx_fmt_ee (code, DImode,
4085 sparc_compare_op0, sparc_compare_op1);
4089 rtx cc_reg = gen_compare_reg (code,
4090 sparc_compare_op0, sparc_compare_op1);
4091 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4092 cc_reg, const0_rtx);
4096 (define_expand "movsfcc"
4097 [(set (match_operand:SF 0 "register_operand" "")
4098 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4099 (match_operand:SF 2 "register_operand" "")
4100 (match_operand:SF 3 "register_operand" "")))]
4101 "TARGET_V9 && TARGET_FPU"
4104 enum rtx_code code = GET_CODE (operands[1]);
4106 if (GET_MODE (sparc_compare_op0) == DImode
4110 if (sparc_compare_op1 == const0_rtx
4111 && GET_CODE (sparc_compare_op0) == REG
4112 && GET_MODE (sparc_compare_op0) == DImode
4113 && v9_regcmp_p (code))
4115 operands[1] = gen_rtx_fmt_ee (code, DImode,
4116 sparc_compare_op0, sparc_compare_op1);
4120 rtx cc_reg = gen_compare_reg (code,
4121 sparc_compare_op0, sparc_compare_op1);
4122 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4126 (define_expand "movdfcc"
4127 [(set (match_operand:DF 0 "register_operand" "")
4128 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4129 (match_operand:DF 2 "register_operand" "")
4130 (match_operand:DF 3 "register_operand" "")))]
4131 "TARGET_V9 && TARGET_FPU"
4134 enum rtx_code code = GET_CODE (operands[1]);
4136 if (GET_MODE (sparc_compare_op0) == DImode
4140 if (sparc_compare_op1 == const0_rtx
4141 && GET_CODE (sparc_compare_op0) == REG
4142 && GET_MODE (sparc_compare_op0) == DImode
4143 && v9_regcmp_p (code))
4145 operands[1] = gen_rtx_fmt_ee (code, DImode,
4146 sparc_compare_op0, sparc_compare_op1);
4150 rtx cc_reg = gen_compare_reg (code,
4151 sparc_compare_op0, sparc_compare_op1);
4152 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4156 (define_expand "movtfcc"
4157 [(set (match_operand:TF 0 "register_operand" "")
4158 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4159 (match_operand:TF 2 "register_operand" "")
4160 (match_operand:TF 3 "register_operand" "")))]
4161 "TARGET_V9 && TARGET_FPU"
4164 enum rtx_code code = GET_CODE (operands[1]);
4166 if (GET_MODE (sparc_compare_op0) == DImode
4170 if (sparc_compare_op1 == const0_rtx
4171 && GET_CODE (sparc_compare_op0) == REG
4172 && GET_MODE (sparc_compare_op0) == DImode
4173 && v9_regcmp_p (code))
4175 operands[1] = gen_rtx_fmt_ee (code, DImode,
4176 sparc_compare_op0, sparc_compare_op1);
4180 rtx cc_reg = gen_compare_reg (code,
4181 sparc_compare_op0, sparc_compare_op1);
4182 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4186 ;; Conditional move define_insns.
4188 (define_insn "*movqi_cc_sp64"
4189 [(set (match_operand:QI 0 "register_operand" "=r,r")
4190 (if_then_else:QI (match_operator 1 "comparison_operator"
4191 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4193 (match_operand:QI 3 "arith11_operand" "rL,0")
4194 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4197 mov%C1\\t%x2, %3, %0
4198 mov%c1\\t%x2, %4, %0"
4199 [(set_attr "type" "cmove")
4200 (set_attr "length" "1")])
4202 (define_insn "*movhi_cc_sp64"
4203 [(set (match_operand:HI 0 "register_operand" "=r,r")
4204 (if_then_else:HI (match_operator 1 "comparison_operator"
4205 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4207 (match_operand:HI 3 "arith11_operand" "rL,0")
4208 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4211 mov%C1\\t%x2, %3, %0
4212 mov%c1\\t%x2, %4, %0"
4213 [(set_attr "type" "cmove")
4214 (set_attr "length" "1")])
4216 (define_insn "*movsi_cc_sp64"
4217 [(set (match_operand:SI 0 "register_operand" "=r,r")
4218 (if_then_else:SI (match_operator 1 "comparison_operator"
4219 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4221 (match_operand:SI 3 "arith11_operand" "rL,0")
4222 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4225 mov%C1\\t%x2, %3, %0
4226 mov%c1\\t%x2, %4, %0"
4227 [(set_attr "type" "cmove")
4228 (set_attr "length" "1")])
4230 ;; ??? The constraints of operands 3,4 need work.
4231 (define_insn "*movdi_cc_sp64"
4232 [(set (match_operand:DI 0 "register_operand" "=r,r")
4233 (if_then_else:DI (match_operator 1 "comparison_operator"
4234 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4236 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4237 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4240 mov%C1\\t%x2, %3, %0
4241 mov%c1\\t%x2, %4, %0"
4242 [(set_attr "type" "cmove")
4243 (set_attr "length" "1")])
4245 (define_insn "*movdi_cc_sp64_trunc"
4246 [(set (match_operand:SI 0 "register_operand" "=r,r")
4247 (if_then_else:SI (match_operator 1 "comparison_operator"
4248 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4250 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4251 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4254 mov%C1\\t%x2, %3, %0
4255 mov%c1\\t%x2, %4, %0"
4256 [(set_attr "type" "cmove")
4257 (set_attr "length" "1")])
4259 (define_insn "*movsf_cc_sp64"
4260 [(set (match_operand:SF 0 "register_operand" "=f,f")
4261 (if_then_else:SF (match_operator 1 "comparison_operator"
4262 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4264 (match_operand:SF 3 "register_operand" "f,0")
4265 (match_operand:SF 4 "register_operand" "0,f")))]
4266 "TARGET_V9 && TARGET_FPU"
4268 fmovs%C1\\t%x2, %3, %0
4269 fmovs%c1\\t%x2, %4, %0"
4270 [(set_attr "type" "fpcmove")
4271 (set_attr "length" "1")])
4273 (define_insn "movdf_cc_sp64"
4274 [(set (match_operand:DF 0 "register_operand" "=e,e")
4275 (if_then_else:DF (match_operator 1 "comparison_operator"
4276 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4278 (match_operand:DF 3 "register_operand" "e,0")
4279 (match_operand:DF 4 "register_operand" "0,e")))]
4280 "TARGET_V9 && TARGET_FPU"
4282 fmovd%C1\\t%x2, %3, %0
4283 fmovd%c1\\t%x2, %4, %0"
4284 [(set_attr "type" "fpcmove")
4285 (set_attr "length" "1")])
4287 (define_insn "*movtf_cc_hq_sp64"
4288 [(set (match_operand:TF 0 "register_operand" "=e,e")
4289 (if_then_else:TF (match_operator 1 "comparison_operator"
4290 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4292 (match_operand:TF 3 "register_operand" "e,0")
4293 (match_operand:TF 4 "register_operand" "0,e")))]
4294 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4296 fmovq%C1\\t%x2, %3, %0
4297 fmovq%c1\\t%x2, %4, %0"
4298 [(set_attr "type" "fpcmove")
4299 (set_attr "length" "1")])
4301 (define_insn "*movtf_cc_sp64"
4302 [(set (match_operand:TF 0 "register_operand" "=e,e")
4303 (if_then_else:TF (match_operator 1 "comparison_operator"
4304 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4306 (match_operand:TF 3 "register_operand" "e,0")
4307 (match_operand:TF 4 "register_operand" "0,e")))]
4308 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4310 [(set_attr "type" "fpcmove")
4311 (set_attr "length" "2")])
4314 [(set (match_operand:TF 0 "register_operand" "=e,e")
4315 (if_then_else:TF (match_operator 1 "comparison_operator"
4316 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4318 (match_operand:TF 3 "register_operand" "e,0")
4319 (match_operand:TF 4 "register_operand" "0,e")))]
4320 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4321 [(clobber (const_int 0))]
4324 rtx set_dest = operands[0];
4325 rtx set_srca = operands[3];
4326 rtx set_srcb = operands[4];
4327 int third = rtx_equal_p (set_dest, set_srca);
4329 rtx srca1, srca2, srcb1, srcb2;
4331 if (GET_CODE (set_dest) == SUBREG)
4332 set_dest = alter_subreg (set_dest);
4333 if (GET_CODE (set_srca) == SUBREG)
4334 set_srca = alter_subreg (set_srca);
4335 if (GET_CODE (set_srcb) == SUBREG)
4336 set_srcb = alter_subreg (set_srcb);
4338 dest1 = gen_df_reg (set_dest, 0);
4339 dest2 = gen_df_reg (set_dest, 1);
4340 srca1 = gen_df_reg (set_srca, 0);
4341 srca2 = gen_df_reg (set_srca, 1);
4342 srcb1 = gen_df_reg (set_srcb, 0);
4343 srcb2 = gen_df_reg (set_srcb, 1);
4345 /* Now emit using the real source and destination we found, swapping
4346 the order if we detect overlap. */
4347 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4348 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4350 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4351 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4355 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4356 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4361 (define_insn "*movqi_cc_reg_sp64"
4362 [(set (match_operand:QI 0 "register_operand" "=r,r")
4363 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4364 [(match_operand:DI 2 "register_operand" "r,r")
4366 (match_operand:QI 3 "arith10_operand" "rM,0")
4367 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4370 movr%D1\\t%2, %r3, %0
4371 movr%d1\\t%2, %r4, %0"
4372 [(set_attr "type" "cmove")
4373 (set_attr "length" "1")])
4375 (define_insn "*movhi_cc_reg_sp64"
4376 [(set (match_operand:HI 0 "register_operand" "=r,r")
4377 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4378 [(match_operand:DI 2 "register_operand" "r,r")
4380 (match_operand:HI 3 "arith10_operand" "rM,0")
4381 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4384 movr%D1\\t%2, %r3, %0
4385 movr%d1\\t%2, %r4, %0"
4386 [(set_attr "type" "cmove")
4387 (set_attr "length" "1")])
4389 (define_insn "*movsi_cc_reg_sp64"
4390 [(set (match_operand:SI 0 "register_operand" "=r,r")
4391 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4392 [(match_operand:DI 2 "register_operand" "r,r")
4394 (match_operand:SI 3 "arith10_operand" "rM,0")
4395 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4398 movr%D1\\t%2, %r3, %0
4399 movr%d1\\t%2, %r4, %0"
4400 [(set_attr "type" "cmove")
4401 (set_attr "length" "1")])
4403 ;; ??? The constraints of operands 3,4 need work.
4404 (define_insn "*movdi_cc_reg_sp64"
4405 [(set (match_operand:DI 0 "register_operand" "=r,r")
4406 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4407 [(match_operand:DI 2 "register_operand" "r,r")
4409 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4410 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4413 movr%D1\\t%2, %r3, %0
4414 movr%d1\\t%2, %r4, %0"
4415 [(set_attr "type" "cmove")
4416 (set_attr "length" "1")])
4418 (define_insn "*movdi_cc_reg_sp64_trunc"
4419 [(set (match_operand:SI 0 "register_operand" "=r,r")
4420 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4421 [(match_operand:DI 2 "register_operand" "r,r")
4423 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4424 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4427 movr%D1\\t%2, %r3, %0
4428 movr%d1\\t%2, %r4, %0"
4429 [(set_attr "type" "cmove")
4430 (set_attr "length" "1")])
4432 (define_insn "*movsf_cc_reg_sp64"
4433 [(set (match_operand:SF 0 "register_operand" "=f,f")
4434 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4435 [(match_operand:DI 2 "register_operand" "r,r")
4437 (match_operand:SF 3 "register_operand" "f,0")
4438 (match_operand:SF 4 "register_operand" "0,f")))]
4439 "TARGET_ARCH64 && TARGET_FPU"
4441 fmovrs%D1\\t%2, %3, %0
4442 fmovrs%d1\\t%2, %4, %0"
4443 [(set_attr "type" "fpcmove")
4444 (set_attr "length" "1")])
4446 (define_insn "movdf_cc_reg_sp64"
4447 [(set (match_operand:DF 0 "register_operand" "=e,e")
4448 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4449 [(match_operand:DI 2 "register_operand" "r,r")
4451 (match_operand:DF 3 "register_operand" "e,0")
4452 (match_operand:DF 4 "register_operand" "0,e")))]
4453 "TARGET_ARCH64 && TARGET_FPU"
4455 fmovrd%D1\\t%2, %3, %0
4456 fmovrd%d1\\t%2, %4, %0"
4457 [(set_attr "type" "fpcmove")
4458 (set_attr "length" "1")])
4460 (define_insn "*movtf_cc_reg_hq_sp64"
4461 [(set (match_operand:TF 0 "register_operand" "=e,e")
4462 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4463 [(match_operand:DI 2 "register_operand" "r,r")
4465 (match_operand:TF 3 "register_operand" "e,0")
4466 (match_operand:TF 4 "register_operand" "0,e")))]
4467 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4469 fmovrq%D1\\t%2, %3, %0
4470 fmovrq%d1\\t%2, %4, %0"
4471 [(set_attr "type" "fpcmove")
4472 (set_attr "length" "1")])
4474 (define_insn "*movtf_cc_reg_sp64"
4475 [(set (match_operand:TF 0 "register_operand" "=e,e")
4476 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4477 [(match_operand:DI 2 "register_operand" "r,r")
4479 (match_operand:TF 3 "register_operand" "e,0")
4480 (match_operand:TF 4 "register_operand" "0,e")))]
4481 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4483 [(set_attr "type" "fpcmove")
4484 (set_attr "length" "2")])
4487 [(set (match_operand:TF 0 "register_operand" "=e,e")
4488 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4489 [(match_operand:DI 2 "register_operand" "r,r")
4491 (match_operand:TF 3 "register_operand" "e,0")
4492 (match_operand:TF 4 "register_operand" "0,e")))]
4493 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4494 [(clobber (const_int 0))]
4497 rtx set_dest = operands[0];
4498 rtx set_srca = operands[3];
4499 rtx set_srcb = operands[4];
4500 int third = rtx_equal_p (set_dest, set_srca);
4502 rtx srca1, srca2, srcb1, srcb2;
4504 if (GET_CODE (set_dest) == SUBREG)
4505 set_dest = alter_subreg (set_dest);
4506 if (GET_CODE (set_srca) == SUBREG)
4507 set_srca = alter_subreg (set_srca);
4508 if (GET_CODE (set_srcb) == SUBREG)
4509 set_srcb = alter_subreg (set_srcb);
4511 dest1 = gen_df_reg (set_dest, 0);
4512 dest2 = gen_df_reg (set_dest, 1);
4513 srca1 = gen_df_reg (set_srca, 0);
4514 srca2 = gen_df_reg (set_srca, 1);
4515 srcb1 = gen_df_reg (set_srcb, 0);
4516 srcb2 = gen_df_reg (set_srcb, 1);
4518 /* Now emit using the real source and destination we found, swapping
4519 the order if we detect overlap. */
4520 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4521 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4523 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4524 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4528 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4529 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4535 ;;- zero extension instructions
4537 ;; These patterns originally accepted general_operands, however, slightly
4538 ;; better code is generated by only accepting register_operands, and then
4539 ;; letting combine generate the ldu[hb] insns.
4541 (define_expand "zero_extendhisi2"
4542 [(set (match_operand:SI 0 "register_operand" "")
4543 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4547 rtx temp = gen_reg_rtx (SImode);
4548 rtx shift_16 = GEN_INT (16);
4549 int op1_subword = 0;
4551 if (GET_CODE (operand1) == SUBREG)
4553 op1_subword = SUBREG_WORD (operand1);
4554 operand1 = XEXP (operand1, 0);
4557 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4559 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4563 (define_insn "*zero_extendhisi2_insn"
4564 [(set (match_operand:SI 0 "register_operand" "=r")
4565 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4568 [(set_attr "type" "load")
4569 (set_attr "length" "1")])
4571 (define_expand "zero_extendqihi2"
4572 [(set (match_operand:HI 0 "register_operand" "")
4573 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4577 (define_insn "*zero_extendqihi2_insn"
4578 [(set (match_operand:HI 0 "register_operand" "=r,r")
4579 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4580 "GET_CODE (operands[1]) != CONST_INT"
4584 [(set_attr "type" "unary,load")
4585 (set_attr "length" "1")])
4587 (define_expand "zero_extendqisi2"
4588 [(set (match_operand:SI 0 "register_operand" "")
4589 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4593 (define_insn "*zero_extendqisi2_insn"
4594 [(set (match_operand:SI 0 "register_operand" "=r,r")
4595 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4596 "GET_CODE (operands[1]) != CONST_INT"
4600 [(set_attr "type" "unary,load")
4601 (set_attr "length" "1")])
4603 (define_expand "zero_extendqidi2"
4604 [(set (match_operand:DI 0 "register_operand" "")
4605 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4609 (define_insn "*zero_extendqidi2_insn"
4610 [(set (match_operand:DI 0 "register_operand" "=r,r")
4611 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4612 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4616 [(set_attr "type" "unary,load")
4617 (set_attr "length" "1")])
4619 (define_expand "zero_extendhidi2"
4620 [(set (match_operand:DI 0 "register_operand" "")
4621 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4625 rtx temp = gen_reg_rtx (DImode);
4626 rtx shift_48 = GEN_INT (48);
4627 int op1_subword = 0;
4629 if (GET_CODE (operand1) == SUBREG)
4631 op1_subword = SUBREG_WORD (operand1);
4632 operand1 = XEXP (operand1, 0);
4635 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4637 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4641 (define_insn "*zero_extendhidi2_insn"
4642 [(set (match_operand:DI 0 "register_operand" "=r")
4643 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4646 [(set_attr "type" "load")
4647 (set_attr "length" "1")])
4650 ;; ??? Write truncdisi pattern using sra?
4652 (define_expand "zero_extendsidi2"
4653 [(set (match_operand:DI 0 "register_operand" "")
4654 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4658 (define_insn "*zero_extendsidi2_insn_sp64"
4659 [(set (match_operand:DI 0 "register_operand" "=r,r")
4660 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4661 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4665 [(set_attr "type" "shift,load")
4666 (set_attr "length" "1")])
4668 (define_insn "*zero_extendsidi2_insn_sp32"
4669 [(set (match_operand:DI 0 "register_operand" "=r")
4670 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4673 [(set_attr "type" "unary")
4674 (set_attr "length" "2")])
4677 [(set (match_operand:DI 0 "register_operand" "")
4678 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4679 "! TARGET_ARCH64 && reload_completed"
4680 [(set (match_dup 2) (match_dup 3))
4681 (set (match_dup 4) (match_dup 5))]
4686 if (GET_CODE (operands[0]) == SUBREG)
4687 operands[0] = alter_subreg (operands[0]);
4689 dest1 = gen_highpart (SImode, operands[0]);
4690 dest2 = gen_lowpart (SImode, operands[0]);
4692 /* Swap the order in case of overlap. */
4693 if (REGNO (dest1) == REGNO (operands[1]))
4695 operands[2] = dest2;
4696 operands[3] = operands[1];
4697 operands[4] = dest1;
4698 operands[5] = const0_rtx;
4702 operands[2] = dest1;
4703 operands[3] = const0_rtx;
4704 operands[4] = dest2;
4705 operands[5] = operands[1];
4709 ;; Simplify comparisons of extended values.
4711 (define_insn "*cmp_zero_extendqisi2"
4713 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4716 "andcc\\t%0, 0xff, %%g0"
4717 [(set_attr "type" "compare")
4718 (set_attr "length" "1")])
4720 (define_insn "*cmp_zero_qi"
4722 (compare:CC (match_operand:QI 0 "register_operand" "r")
4725 "andcc\\t%0, 0xff, %%g0"
4726 [(set_attr "type" "compare")
4727 (set_attr "length" "1")])
4729 (define_insn "*cmp_zero_extendqisi2_set"
4731 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4733 (set (match_operand:SI 0 "register_operand" "=r")
4734 (zero_extend:SI (match_dup 1)))]
4736 "andcc\\t%1, 0xff, %0"
4737 [(set_attr "type" "compare")
4738 (set_attr "length" "1")])
4740 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4742 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4745 (set (match_operand:SI 0 "register_operand" "=r")
4746 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4748 "andcc\\t%1, 0xff, %0"
4749 [(set_attr "type" "compare")
4750 (set_attr "length" "1")])
4752 (define_insn "*cmp_zero_extendqidi2"
4754 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4757 "andcc\\t%0, 0xff, %%g0"
4758 [(set_attr "type" "compare")
4759 (set_attr "length" "1")])
4761 (define_insn "*cmp_zero_qi_sp64"
4763 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4766 "andcc\\t%0, 0xff, %%g0"
4767 [(set_attr "type" "compare")
4768 (set_attr "length" "1")])
4770 (define_insn "*cmp_zero_extendqidi2_set"
4772 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4774 (set (match_operand:DI 0 "register_operand" "=r")
4775 (zero_extend:DI (match_dup 1)))]
4777 "andcc\\t%1, 0xff, %0"
4778 [(set_attr "type" "compare")
4779 (set_attr "length" "1")])
4781 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4783 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4786 (set (match_operand:DI 0 "register_operand" "=r")
4787 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4789 "andcc\\t%1, 0xff, %0"
4790 [(set_attr "type" "compare")
4791 (set_attr "length" "1")])
4793 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4795 (define_insn "*cmp_siqi_trunc"
4797 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4800 "andcc\\t%0, 0xff, %%g0"
4801 [(set_attr "type" "compare")
4802 (set_attr "length" "1")])
4804 (define_insn "*cmp_siqi_trunc_set"
4806 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4808 (set (match_operand:QI 0 "register_operand" "=r")
4809 (subreg:QI (match_dup 1) 0))]
4811 "andcc\\t%1, 0xff, %0"
4812 [(set_attr "type" "compare")
4813 (set_attr "length" "1")])
4815 (define_insn "*cmp_diqi_trunc"
4817 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4820 "andcc\\t%0, 0xff, %%g0"
4821 [(set_attr "type" "compare")
4822 (set_attr "length" "1")])
4824 (define_insn "*cmp_diqi_trunc_set"
4826 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4828 (set (match_operand:QI 0 "register_operand" "=r")
4829 (subreg:QI (match_dup 1) 0))]
4831 "andcc\\t%1, 0xff, %0"
4832 [(set_attr "type" "compare")
4833 (set_attr "length" "1")])
4835 ;;- sign extension instructions
4837 ;; These patterns originally accepted general_operands, however, slightly
4838 ;; better code is generated by only accepting register_operands, and then
4839 ;; letting combine generate the lds[hb] insns.
4841 (define_expand "extendhisi2"
4842 [(set (match_operand:SI 0 "register_operand" "")
4843 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4847 rtx temp = gen_reg_rtx (SImode);
4848 rtx shift_16 = GEN_INT (16);
4849 int op1_subword = 0;
4851 if (GET_CODE (operand1) == SUBREG)
4853 op1_subword = SUBREG_WORD (operand1);
4854 operand1 = XEXP (operand1, 0);
4857 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4859 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4863 (define_insn "*sign_extendhisi2_insn"
4864 [(set (match_operand:SI 0 "register_operand" "=r")
4865 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4868 [(set_attr "type" "sload")
4869 (set_attr "length" "1")])
4871 (define_expand "extendqihi2"
4872 [(set (match_operand:HI 0 "register_operand" "")
4873 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4877 rtx temp = gen_reg_rtx (SImode);
4878 rtx shift_24 = GEN_INT (24);
4879 int op1_subword = 0;
4880 int op0_subword = 0;
4882 if (GET_CODE (operand1) == SUBREG)
4884 op1_subword = SUBREG_WORD (operand1);
4885 operand1 = XEXP (operand1, 0);
4887 if (GET_CODE (operand0) == SUBREG)
4889 op0_subword = SUBREG_WORD (operand0);
4890 operand0 = XEXP (operand0, 0);
4892 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4894 if (GET_MODE (operand0) != SImode)
4895 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4896 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4900 (define_insn "*sign_extendqihi2_insn"
4901 [(set (match_operand:HI 0 "register_operand" "=r")
4902 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4905 [(set_attr "type" "sload")
4906 (set_attr "length" "1")])
4908 (define_expand "extendqisi2"
4909 [(set (match_operand:SI 0 "register_operand" "")
4910 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4914 rtx temp = gen_reg_rtx (SImode);
4915 rtx shift_24 = GEN_INT (24);
4916 int op1_subword = 0;
4918 if (GET_CODE (operand1) == SUBREG)
4920 op1_subword = SUBREG_WORD (operand1);
4921 operand1 = XEXP (operand1, 0);
4924 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4926 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4930 (define_insn "*sign_extendqisi2_insn"
4931 [(set (match_operand:SI 0 "register_operand" "=r")
4932 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4935 [(set_attr "type" "sload")
4936 (set_attr "length" "1")])
4938 (define_expand "extendqidi2"
4939 [(set (match_operand:DI 0 "register_operand" "")
4940 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4944 rtx temp = gen_reg_rtx (DImode);
4945 rtx shift_56 = GEN_INT (56);
4946 int op1_subword = 0;
4948 if (GET_CODE (operand1) == SUBREG)
4950 op1_subword = SUBREG_WORD (operand1);
4951 operand1 = XEXP (operand1, 0);
4954 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4956 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4960 (define_insn "*sign_extendqidi2_insn"
4961 [(set (match_operand:DI 0 "register_operand" "=r")
4962 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4965 [(set_attr "type" "sload")
4966 (set_attr "length" "1")])
4968 (define_expand "extendhidi2"
4969 [(set (match_operand:DI 0 "register_operand" "")
4970 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4974 rtx temp = gen_reg_rtx (DImode);
4975 rtx shift_48 = GEN_INT (48);
4976 int op1_subword = 0;
4978 if (GET_CODE (operand1) == SUBREG)
4980 op1_subword = SUBREG_WORD (operand1);
4981 operand1 = XEXP (operand1, 0);
4984 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4986 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4990 (define_insn "*sign_extendhidi2_insn"
4991 [(set (match_operand:DI 0 "register_operand" "=r")
4992 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4995 [(set_attr "type" "sload")
4996 (set_attr "length" "1")])
4998 (define_expand "extendsidi2"
4999 [(set (match_operand:DI 0 "register_operand" "")
5000 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
5004 (define_insn "*sign_extendsidi2_insn"
5005 [(set (match_operand:DI 0 "register_operand" "=r,r")
5006 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
5011 [(set_attr "type" "shift,sload")
5012 (set_attr "length" "1")])
5014 ;; Special pattern for optimizing bit-field compares. This is needed
5015 ;; because combine uses this as a canonical form.
5017 (define_insn "*cmp_zero_extract"
5020 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5021 (match_operand:SI 1 "small_int_or_double" "n")
5022 (match_operand:SI 2 "small_int_or_double" "n"))
5024 "(GET_CODE (operands[2]) == CONST_INT
5025 && INTVAL (operands[2]) > 19)
5026 || (GET_CODE (operands[2]) == CONST_DOUBLE
5027 && CONST_DOUBLE_LOW (operands[2]) > 19)"
5030 int len = (GET_CODE (operands[1]) == CONST_INT
5031 ? INTVAL (operands[1])
5032 : CONST_DOUBLE_LOW (operands[1]));
5034 (GET_CODE (operands[2]) == CONST_INT
5035 ? INTVAL (operands[2])
5036 : CONST_DOUBLE_LOW (operands[2])) - len;
5037 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5039 operands[1] = GEN_INT (mask);
5040 return \"andcc\\t%0, %1, %%g0\";
5042 [(set_attr "type" "compare")
5043 (set_attr "length" "1")])
5045 (define_insn "*cmp_zero_extract_sp64"
5048 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5049 (match_operand:SI 1 "small_int_or_double" "n")
5050 (match_operand:SI 2 "small_int_or_double" "n"))
5053 && ((GET_CODE (operands[2]) == CONST_INT
5054 && INTVAL (operands[2]) > 51)
5055 || (GET_CODE (operands[2]) == CONST_DOUBLE
5056 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5059 int len = (GET_CODE (operands[1]) == CONST_INT
5060 ? INTVAL (operands[1])
5061 : CONST_DOUBLE_LOW (operands[1]));
5063 (GET_CODE (operands[2]) == CONST_INT
5064 ? INTVAL (operands[2])
5065 : CONST_DOUBLE_LOW (operands[2])) - len;
5066 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5068 operands[1] = GEN_INT (mask);
5069 return \"andcc\\t%0, %1, %%g0\";
5071 [(set_attr "type" "compare")
5072 (set_attr "length" "1")])
5074 ;; Conversions between float, double and long double.
5076 (define_insn "extendsfdf2"
5077 [(set (match_operand:DF 0 "register_operand" "=e")
5079 (match_operand:SF 1 "register_operand" "f")))]
5082 [(set_attr "type" "fp")
5083 (set_attr "length" "1")])
5085 (define_expand "extendsftf2"
5086 [(set (match_operand:TF 0 "register_operand" "=e")
5088 (match_operand:SF 1 "register_operand" "f")))]
5089 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5092 if (! TARGET_HARD_QUAD)
5096 if (GET_CODE (operands[0]) != MEM)
5097 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5099 slot0 = operands[0];
5101 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5103 XEXP (slot0, 0), Pmode,
5104 operands[1], SFmode);
5106 if (GET_CODE (operands[0]) != MEM)
5107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5112 (define_insn "*extendsftf2_hq"
5113 [(set (match_operand:TF 0 "register_operand" "=e")
5115 (match_operand:SF 1 "register_operand" "f")))]
5116 "TARGET_FPU && TARGET_HARD_QUAD"
5118 [(set_attr "type" "fp")
5119 (set_attr "length" "1")])
5121 (define_expand "extenddftf2"
5122 [(set (match_operand:TF 0 "register_operand" "=e")
5124 (match_operand:DF 1 "register_operand" "e")))]
5125 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5128 if (! TARGET_HARD_QUAD)
5132 if (GET_CODE (operands[0]) != MEM)
5133 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5135 slot0 = operands[0];
5137 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5139 XEXP (slot0, 0), Pmode,
5140 operands[1], DFmode);
5142 if (GET_CODE (operands[0]) != MEM)
5143 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5148 (define_insn "*extenddftf2_hq"
5149 [(set (match_operand:TF 0 "register_operand" "=e")
5151 (match_operand:DF 1 "register_operand" "e")))]
5152 "TARGET_FPU && TARGET_HARD_QUAD"
5154 [(set_attr "type" "fp")
5155 (set_attr "length" "1")])
5157 (define_insn "truncdfsf2"
5158 [(set (match_operand:SF 0 "register_operand" "=f")
5160 (match_operand:DF 1 "register_operand" "e")))]
5163 [(set_attr "type" "fp")
5164 (set_attr "length" "1")])
5166 (define_expand "trunctfsf2"
5167 [(set (match_operand:SF 0 "register_operand" "=f")
5169 (match_operand:TF 1 "register_operand" "e")))]
5170 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5173 if (! TARGET_HARD_QUAD)
5177 if (GET_CODE (operands[1]) != MEM)
5179 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5180 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5183 slot0 = operands[1];
5185 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5186 operands[0], 0, SFmode, 1,
5187 XEXP (slot0, 0), Pmode);
5192 (define_insn "*trunctfsf2_hq"
5193 [(set (match_operand:SF 0 "register_operand" "=f")
5195 (match_operand:TF 1 "register_operand" "e")))]
5196 "TARGET_FPU && TARGET_HARD_QUAD"
5198 [(set_attr "type" "fp")
5199 (set_attr "length" "1")])
5201 (define_expand "trunctfdf2"
5202 [(set (match_operand:DF 0 "register_operand" "=f")
5204 (match_operand:TF 1 "register_operand" "e")))]
5205 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5208 if (! TARGET_HARD_QUAD)
5212 if (GET_CODE (operands[1]) != MEM)
5214 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5215 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5218 slot0 = operands[1];
5220 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5221 operands[0], 0, DFmode, 1,
5222 XEXP (slot0, 0), Pmode);
5227 (define_insn "*trunctfdf2_hq"
5228 [(set (match_operand:DF 0 "register_operand" "=e")
5230 (match_operand:TF 1 "register_operand" "e")))]
5231 "TARGET_FPU && TARGET_HARD_QUAD"
5233 [(set_attr "type" "fp")
5234 (set_attr "length" "1")])
5236 ;; Conversion between fixed point and floating point.
5238 (define_insn "floatsisf2"
5239 [(set (match_operand:SF 0 "register_operand" "=f")
5240 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5243 [(set_attr "type" "fp")
5244 (set_attr "length" "1")])
5246 (define_insn "floatsidf2"
5247 [(set (match_operand:DF 0 "register_operand" "=e")
5248 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5251 [(set_attr "type" "fp")
5252 (set_attr "length" "1")])
5254 (define_expand "floatsitf2"
5255 [(set (match_operand:TF 0 "register_operand" "=e")
5256 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5257 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5260 if (! TARGET_HARD_QUAD)
5264 if (GET_CODE (operands[1]) != MEM)
5265 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5267 slot0 = operands[1];
5269 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5271 XEXP (slot0, 0), Pmode,
5272 operands[1], SImode);
5274 if (GET_CODE (operands[0]) != MEM)
5275 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5280 (define_insn "*floatsitf2_hq"
5281 [(set (match_operand:TF 0 "register_operand" "=e")
5282 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5283 "TARGET_FPU && TARGET_HARD_QUAD"
5285 [(set_attr "type" "fp")
5286 (set_attr "length" "1")])
5288 (define_expand "floatunssitf2"
5289 [(set (match_operand:TF 0 "register_operand" "=e")
5290 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5291 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5296 if (GET_CODE (operands[1]) != MEM)
5297 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5299 slot0 = operands[1];
5301 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5303 XEXP (slot0, 0), Pmode,
5304 operands[1], SImode);
5306 if (GET_CODE (operands[0]) != MEM)
5307 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5311 ;; Now the same for 64 bit sources.
5313 (define_insn "floatdisf2"
5314 [(set (match_operand:SF 0 "register_operand" "=f")
5315 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5316 "TARGET_V9 && TARGET_FPU"
5318 [(set_attr "type" "fp")
5319 (set_attr "length" "1")])
5321 (define_insn "floatdidf2"
5322 [(set (match_operand:DF 0 "register_operand" "=e")
5323 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5324 "TARGET_V9 && TARGET_FPU"
5326 [(set_attr "type" "fp")
5327 (set_attr "length" "1")])
5329 (define_expand "floatditf2"
5330 [(set (match_operand:TF 0 "register_operand" "=e")
5331 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5332 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5335 if (! TARGET_HARD_QUAD)
5339 if (GET_CODE (operands[1]) != MEM)
5340 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5342 slot0 = operands[1];
5344 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5346 XEXP (slot0, 0), Pmode,
5347 operands[1], DImode);
5349 if (GET_CODE (operands[0]) != MEM)
5350 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5355 (define_insn "*floatditf2_hq"
5356 [(set (match_operand:TF 0 "register_operand" "=e")
5357 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5358 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5360 [(set_attr "type" "fp")
5361 (set_attr "length" "1")])
5363 (define_expand "floatunsditf2"
5364 [(set (match_operand:TF 0 "register_operand" "=e")
5365 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5366 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5371 if (GET_CODE (operands[1]) != MEM)
5372 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5374 slot0 = operands[1];
5376 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5378 XEXP (slot0, 0), Pmode,
5379 operands[1], DImode);
5381 if (GET_CODE (operands[0]) != MEM)
5382 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5386 ;; Convert a float to an actual integer.
5387 ;; Truncation is performed as part of the conversion.
5389 (define_insn "fix_truncsfsi2"
5390 [(set (match_operand:SI 0 "register_operand" "=f")
5391 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5394 [(set_attr "type" "fp")
5395 (set_attr "length" "1")])
5397 (define_insn "fix_truncdfsi2"
5398 [(set (match_operand:SI 0 "register_operand" "=f")
5399 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5402 [(set_attr "type" "fp")
5403 (set_attr "length" "1")])
5405 (define_expand "fix_trunctfsi2"
5406 [(set (match_operand:SI 0 "register_operand" "=f")
5407 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5408 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5411 if (! TARGET_HARD_QUAD)
5415 if (GET_CODE (operands[1]) != MEM)
5417 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5418 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5421 slot0 = operands[1];
5423 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5424 operands[0], 0, SImode, 1,
5425 XEXP (slot0, 0), Pmode);
5430 (define_insn "*fix_trunctfsi2_hq"
5431 [(set (match_operand:SI 0 "register_operand" "=f")
5432 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5433 "TARGET_FPU && TARGET_HARD_QUAD"
5435 [(set_attr "type" "fp")
5436 (set_attr "length" "1")])
5438 (define_expand "fixuns_trunctfsi2"
5439 [(set (match_operand:SI 0 "register_operand" "=f")
5440 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5441 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5446 if (GET_CODE (operands[1]) != MEM)
5448 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5449 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5452 slot0 = operands[1];
5454 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5455 operands[0], 0, SImode, 1,
5456 XEXP (slot0, 0), Pmode);
5460 ;; Now the same, for V9 targets
5462 (define_insn "fix_truncsfdi2"
5463 [(set (match_operand:DI 0 "register_operand" "=e")
5464 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5465 "TARGET_V9 && TARGET_FPU"
5467 [(set_attr "type" "fp")
5468 (set_attr "length" "1")])
5470 (define_insn "fix_truncdfdi2"
5471 [(set (match_operand:DI 0 "register_operand" "=e")
5472 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5473 "TARGET_V9 && TARGET_FPU"
5475 [(set_attr "type" "fp")
5476 (set_attr "length" "1")])
5478 (define_expand "fix_trunctfdi2"
5479 [(set (match_operand:DI 0 "register_operand" "=e")
5480 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5481 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5484 if (! TARGET_HARD_QUAD)
5488 if (GET_CODE (operands[1]) != MEM)
5490 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5491 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5494 slot0 = operands[1];
5496 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5497 operands[0], 0, DImode, 1,
5498 XEXP (slot0, 0), Pmode);
5503 (define_insn "*fix_trunctfdi2_hq"
5504 [(set (match_operand:DI 0 "register_operand" "=e")
5505 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5506 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5508 [(set_attr "type" "fp")
5509 (set_attr "length" "1")])
5511 (define_expand "fixuns_trunctfdi2"
5512 [(set (match_operand:DI 0 "register_operand" "=f")
5513 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5514 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5519 if (GET_CODE (operands[1]) != MEM)
5521 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5522 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5525 slot0 = operands[1];
5527 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5528 operands[0], 0, DImode, 1,
5529 XEXP (slot0, 0), Pmode);
5534 ;;- arithmetic instructions
5536 (define_expand "adddi3"
5537 [(set (match_operand:DI 0 "register_operand" "=r")
5538 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5539 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5543 if (! TARGET_ARCH64)
5545 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5546 gen_rtx_SET (VOIDmode, operands[0],
5547 gen_rtx_PLUS (DImode, operands[1],
5549 gen_rtx_CLOBBER (VOIDmode,
5550 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5553 if (arith_double_4096_operand(operands[2], DImode))
5555 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5556 gen_rtx_MINUS (DImode, operands[1],
5562 (define_insn "adddi3_insn_sp32"
5563 [(set (match_operand:DI 0 "register_operand" "=r")
5564 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5565 (match_operand:DI 2 "arith_double_operand" "rHI")))
5566 (clobber (reg:CC 100))]
5569 [(set_attr "length" "2")])
5572 [(set (match_operand:DI 0 "register_operand" "=r")
5573 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5574 (match_operand:DI 2 "arith_double_operand" "rHI")))
5575 (clobber (reg:CC 100))]
5576 "! TARGET_ARCH64 && reload_completed"
5577 [(parallel [(set (reg:CC_NOOV 100)
5578 (compare:CC_NOOV (plus:SI (match_dup 4)
5582 (plus:SI (match_dup 4) (match_dup 5)))])
5584 (plus:SI (plus:SI (match_dup 7)
5586 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5589 operands[3] = gen_lowpart (SImode, operands[0]);
5590 operands[4] = gen_lowpart (SImode, operands[1]);
5591 operands[5] = gen_lowpart (SImode, operands[2]);
5592 operands[6] = gen_highpart (SImode, operands[0]);
5593 operands[7] = gen_highpart (SImode, operands[1]);
5594 #if HOST_BITS_PER_WIDE_INT == 32
5595 if (GET_CODE (operands[2]) == CONST_INT)
5597 if (INTVAL (operands[2]) < 0)
5598 operands[8] = constm1_rtx;
5600 operands[8] = const0_rtx;
5604 operands[8] = gen_highpart (SImode, operands[2]);
5608 [(set (match_operand:DI 0 "register_operand" "=r")
5609 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
5610 (match_operand:DI 2 "arith_double_operand" "rHI")))
5611 (clobber (reg:CC 100))]
5612 "! TARGET_ARCH64 && reload_completed"
5613 [(parallel [(set (reg:CC_NOOV 100)
5614 (compare:CC_NOOV (minus:SI (match_dup 4)
5618 (minus:SI (match_dup 4) (match_dup 5)))])
5620 (minus:SI (minus:SI (match_dup 7)
5622 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5625 operands[3] = gen_lowpart (SImode, operands[0]);
5626 operands[4] = gen_lowpart (SImode, operands[1]);
5627 operands[5] = gen_lowpart (SImode, operands[2]);
5628 operands[6] = gen_highpart (SImode, operands[0]);
5629 operands[7] = gen_highpart (SImode, operands[1]);
5630 #if HOST_BITS_PER_WIDE_INT == 32
5631 if (GET_CODE (operands[2]) == CONST_INT)
5633 if (INTVAL (operands[2]) < 0)
5634 operands[8] = constm1_rtx;
5636 operands[8] = const0_rtx;
5640 operands[8] = gen_highpart (SImode, operands[2]);
5643 ;; LTU here means "carry set"
5645 [(set (match_operand:SI 0 "register_operand" "=r")
5646 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5647 (match_operand:SI 2 "arith_operand" "rI"))
5648 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5651 [(set_attr "type" "unary")
5652 (set_attr "length" "1")])
5654 (define_insn "*addx_extend_sp32"
5655 [(set (match_operand:DI 0 "register_operand" "=r")
5656 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5657 (match_operand:SI 2 "arith_operand" "rI"))
5658 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5661 [(set_attr "type" "unary")
5662 (set_attr "length" "2")])
5665 [(set (match_operand:DI 0 "register_operand" "")
5666 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5667 (match_operand:SI 2 "arith_operand" ""))
5668 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5669 "! TARGET_ARCH64 && reload_completed"
5670 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5671 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5672 (set (match_dup 4) (const_int 0))]
5673 "operands[3] = gen_lowpart (SImode, operands[0]);
5674 operands[4] = gen_highpart (SImode, operands[1]);")
5676 (define_insn "*addx_extend_sp64"
5677 [(set (match_operand:DI 0 "register_operand" "=r")
5678 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5679 (match_operand:SI 2 "arith_operand" "rI"))
5680 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5682 "addx\\t%r1, %2, %0"
5683 [(set_attr "type" "misc")
5684 (set_attr "length" "1")])
5687 [(set (match_operand:SI 0 "register_operand" "=r")
5688 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5689 (match_operand:SI 2 "arith_operand" "rI"))
5690 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5692 "subx\\t%r1, %2, %0"
5693 [(set_attr "type" "misc")
5694 (set_attr "length" "1")])
5696 (define_insn "*subx_extend_sp64"
5697 [(set (match_operand:DI 0 "register_operand" "=r")
5698 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5699 (match_operand:SI 2 "arith_operand" "rI"))
5700 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5702 "subx\\t%r1, %2, %0"
5703 [(set_attr "type" "misc")
5704 (set_attr "length" "1")])
5706 (define_insn "*subx_extend"
5707 [(set (match_operand:DI 0 "register_operand" "=r")
5708 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5709 (match_operand:SI 2 "arith_operand" "rI"))
5710 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5713 [(set_attr "type" "unary")
5714 (set_attr "length" "2")])
5717 [(set (match_operand:DI 0 "register_operand" "=r")
5718 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5719 (match_operand:SI 2 "arith_operand" "rI"))
5720 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5721 "! TARGET_ARCH64 && reload_completed"
5722 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5723 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5724 (set (match_dup 4) (const_int 0))]
5725 "operands[3] = gen_lowpart (SImode, operands[0]);
5726 operands[4] = gen_highpart (SImode, operands[0]);")
5729 [(set (match_operand:DI 0 "register_operand" "=r")
5730 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5731 (match_operand:DI 2 "register_operand" "r")))
5732 (clobber (reg:CC 100))]
5735 [(set_attr "type" "multi")
5736 (set_attr "length" "2")])
5739 [(set (match_operand:DI 0 "register_operand" "")
5740 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5741 (match_operand:DI 2 "register_operand" "")))
5742 (clobber (reg:CC 100))]
5743 "! TARGET_ARCH64 && reload_completed"
5744 [(parallel [(set (reg:CC_NOOV 100)
5745 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5747 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5749 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5750 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5751 "operands[3] = gen_lowpart (SImode, operands[2]);
5752 operands[4] = gen_highpart (SImode, operands[2]);
5753 operands[5] = gen_lowpart (SImode, operands[0]);
5754 operands[6] = gen_highpart (SImode, operands[0]);")
5756 (define_insn "*adddi3_sp64"
5757 [(set (match_operand:DI 0 "register_operand" "=r")
5758 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5759 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5762 [(set_attr "type" "binary")
5763 (set_attr "length" "1")])
5765 (define_expand "addsi3"
5766 [(set (match_operand:SI 0 "register_operand" "=r,d")
5767 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5768 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5772 if (arith_4096_operand(operands[2], DImode))
5774 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5775 gen_rtx_MINUS (SImode, operands[1],
5781 (define_insn "*addsi3"
5782 [(set (match_operand:SI 0 "register_operand" "=r,d")
5783 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5784 (match_operand:SI 2 "arith_operand" "rI,d")))]
5788 fpadd32s\\t%1, %2, %0"
5789 [(set_attr "type" "ialu,fp")
5790 (set_attr "length" "1")])
5792 (define_insn "*cmp_cc_plus"
5793 [(set (reg:CC_NOOV 100)
5794 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5795 (match_operand:SI 1 "arith_operand" "rI"))
5798 "addcc\\t%0, %1, %%g0"
5799 [(set_attr "type" "compare")
5800 (set_attr "length" "1")])
5802 (define_insn "*cmp_ccx_plus"
5803 [(set (reg:CCX_NOOV 100)
5804 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5805 (match_operand:DI 1 "arith_double_operand" "rHI"))
5808 "addcc\\t%0, %1, %%g0"
5809 [(set_attr "type" "compare")
5810 (set_attr "length" "1")])
5812 (define_insn "*cmp_cc_plus_set"
5813 [(set (reg:CC_NOOV 100)
5814 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5815 (match_operand:SI 2 "arith_operand" "rI"))
5817 (set (match_operand:SI 0 "register_operand" "=r")
5818 (plus:SI (match_dup 1) (match_dup 2)))]
5820 "addcc\\t%1, %2, %0"
5821 [(set_attr "type" "compare")
5822 (set_attr "length" "1")])
5824 (define_insn "*cmp_ccx_plus_set"
5825 [(set (reg:CCX_NOOV 100)
5826 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5827 (match_operand:DI 2 "arith_double_operand" "rHI"))
5829 (set (match_operand:DI 0 "register_operand" "=r")
5830 (plus:DI (match_dup 1) (match_dup 2)))]
5832 "addcc\\t%1, %2, %0"
5833 [(set_attr "type" "compare")
5834 (set_attr "length" "1")])
5836 (define_expand "subdi3"
5837 [(set (match_operand:DI 0 "register_operand" "=r")
5838 (minus:DI (match_operand:DI 1 "register_operand" "r")
5839 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5843 if (! TARGET_ARCH64)
5845 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5846 gen_rtx_SET (VOIDmode, operands[0],
5847 gen_rtx_MINUS (DImode, operands[1],
5849 gen_rtx_CLOBBER (VOIDmode,
5850 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5853 if (arith_double_4096_operand(operands[2], DImode))
5855 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5856 gen_rtx_PLUS (DImode, operands[1],
5862 (define_insn "*subdi3_sp32"
5863 [(set (match_operand:DI 0 "register_operand" "=r")
5864 (minus:DI (match_operand:DI 1 "register_operand" "r")
5865 (match_operand:DI 2 "arith_double_operand" "rHI")))
5866 (clobber (reg:CC 100))]
5869 [(set_attr "length" "2")])
5872 [(set (match_operand:DI 0 "register_operand" "")
5873 (minus:DI (match_operand:DI 1 "register_operand" "")
5874 (match_operand:DI 2 "arith_double_operand" "")))
5875 (clobber (reg:CC 100))]
5878 && (GET_CODE (operands[2]) == CONST_INT
5879 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5880 [(clobber (const_int 0))]
5885 highp = gen_highpart (SImode, operands[2]);
5886 lowp = gen_lowpart (SImode, operands[2]);
5887 if ((lowp == const0_rtx)
5888 && (operands[0] == operands[1]))
5890 emit_insn (gen_rtx_SET (VOIDmode,
5891 gen_highpart (SImode, operands[0]),
5892 gen_rtx_MINUS (SImode,
5893 gen_highpart (SImode, operands[1]),
5898 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5899 gen_lowpart (SImode, operands[1]),
5901 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5902 gen_highpart (SImode, operands[1]),
5909 [(set (match_operand:DI 0 "register_operand" "")
5910 (minus:DI (match_operand:DI 1 "register_operand" "")
5911 (match_operand:DI 2 "register_operand" "")))
5912 (clobber (reg:CC 100))]
5914 && reload_completed"
5915 [(clobber (const_int 0))]
5918 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5919 gen_lowpart (SImode, operands[1]),
5920 gen_lowpart (SImode, operands[2])));
5921 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5922 gen_highpart (SImode, operands[1]),
5923 gen_highpart (SImode, operands[2])));
5928 [(set (match_operand:DI 0 "register_operand" "=r")
5929 (minus:DI (match_operand:DI 1 "register_operand" "r")
5930 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5931 (clobber (reg:CC 100))]
5934 [(set_attr "type" "multi")
5935 (set_attr "length" "2")])
5938 [(set (match_operand:DI 0 "register_operand" "")
5939 (minus:DI (match_operand:DI 1 "register_operand" "")
5940 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5941 (clobber (reg:CC 100))]
5942 "! TARGET_ARCH64 && reload_completed"
5943 [(parallel [(set (reg:CC_NOOV 100)
5944 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5946 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5948 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5949 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5950 "operands[3] = gen_lowpart (SImode, operands[1]);
5951 operands[4] = gen_highpart (SImode, operands[1]);
5952 operands[5] = gen_lowpart (SImode, operands[0]);
5953 operands[6] = gen_highpart (SImode, operands[0]);")
5955 (define_insn "*subdi3_sp64"
5956 [(set (match_operand:DI 0 "register_operand" "=r")
5957 (minus:DI (match_operand:DI 1 "register_operand" "r")
5958 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5961 [(set_attr "type" "binary")
5962 (set_attr "length" "1")])
5964 (define_expand "subsi3"
5965 [(set (match_operand:SI 0 "register_operand" "=r,d")
5966 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5967 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5971 if (arith_4096_operand(operands[2], DImode))
5973 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5974 gen_rtx_PLUS (SImode, operands[1],
5980 (define_insn "*subsi3"
5981 [(set (match_operand:SI 0 "register_operand" "=r,d")
5982 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5983 (match_operand:SI 2 "arith_operand" "rI,d")))]
5987 fpsub32s\\t%1, %2, %0"
5988 [(set_attr "type" "ialu,fp")
5989 (set_attr "length" "1")])
5991 (define_insn "*cmp_minus_cc"
5992 [(set (reg:CC_NOOV 100)
5993 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5994 (match_operand:SI 1 "arith_operand" "rI"))
5997 "subcc\\t%r0, %1, %%g0"
5998 [(set_attr "type" "compare")
5999 (set_attr "length" "1")])
6001 (define_insn "*cmp_minus_ccx"
6002 [(set (reg:CCX_NOOV 100)
6003 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
6004 (match_operand:DI 1 "arith_double_operand" "rHI"))
6007 "subcc\\t%0, %1, %%g0"
6008 [(set_attr "type" "compare")
6009 (set_attr "length" "1")])
6011 (define_insn "cmp_minus_cc_set"
6012 [(set (reg:CC_NOOV 100)
6013 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
6014 (match_operand:SI 2 "arith_operand" "rI"))
6016 (set (match_operand:SI 0 "register_operand" "=r")
6017 (minus:SI (match_dup 1) (match_dup 2)))]
6019 "subcc\\t%r1, %2, %0"
6020 [(set_attr "type" "compare")
6021 (set_attr "length" "1")])
6023 (define_insn "*cmp_minus_ccx_set"
6024 [(set (reg:CCX_NOOV 100)
6025 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6026 (match_operand:DI 2 "arith_double_operand" "rHI"))
6028 (set (match_operand:DI 0 "register_operand" "=r")
6029 (minus:DI (match_dup 1) (match_dup 2)))]
6031 "subcc\\t%1, %2, %0"
6032 [(set_attr "type" "compare")
6033 (set_attr "length" "1")])
6035 ;; Integer Multiply/Divide.
6037 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6038 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6040 (define_insn "mulsi3"
6041 [(set (match_operand:SI 0 "register_operand" "=r")
6042 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6043 (match_operand:SI 2 "arith_operand" "rI")))]
6046 [(set_attr "type" "imul")
6047 (set_attr "length" "1")])
6049 (define_expand "muldi3"
6050 [(set (match_operand:DI 0 "register_operand" "=r")
6051 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6052 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6053 "TARGET_ARCH64 || TARGET_V8PLUS"
6058 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6063 (define_insn "*muldi3_sp64"
6064 [(set (match_operand:DI 0 "register_operand" "=r")
6065 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6066 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6069 [(set_attr "type" "imul")
6070 (set_attr "length" "1")])
6072 ;; V8plus wide multiply.
6074 (define_insn "muldi3_v8plus"
6075 [(set (match_operand:DI 0 "register_operand" "=r,h")
6076 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6077 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
6078 (clobber (match_scratch:SI 3 "=&h,X"))
6079 (clobber (match_scratch:SI 4 "=&h,X"))]
6083 if (sparc_check_64 (operands[1], insn) <= 0)
6084 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6085 if (which_alternative == 1)
6086 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6087 if (sparc_check_64 (operands[2], insn) <= 0)
6088 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6089 if (which_alternative == 1)
6090 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\";
6092 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\";
6094 [(set_attr "length" "9,8")])
6096 (define_insn "*cmp_mul_set"
6098 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6099 (match_operand:SI 2 "arith_operand" "rI"))
6101 (set (match_operand:SI 0 "register_operand" "=r")
6102 (mult:SI (match_dup 1) (match_dup 2)))]
6103 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6104 "smulcc\\t%1, %2, %0"
6105 [(set_attr "type" "imul")
6106 (set_attr "length" "1")])
6108 (define_expand "mulsidi3"
6109 [(set (match_operand:DI 0 "register_operand" "")
6110 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6111 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6115 if (CONSTANT_P (operands[2]))
6118 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6121 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6127 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6132 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6133 ;; registers can hold 64 bit values in the V8plus environment.
6135 (define_insn "mulsidi3_v8plus"
6136 [(set (match_operand:DI 0 "register_operand" "=h,r")
6137 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6138 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6139 (clobber (match_scratch:SI 3 "=X,&h"))]
6142 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6143 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6144 [(set_attr "length" "2,3")])
6147 (define_insn "const_mulsidi3_v8plus"
6148 [(set (match_operand:DI 0 "register_operand" "=h,r")
6149 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6150 (match_operand:SI 2 "small_int" "I,I")))
6151 (clobber (match_scratch:SI 3 "=X,&h"))]
6154 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6155 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6156 [(set_attr "length" "2,3")])
6159 (define_insn "*mulsidi3_sp32"
6160 [(set (match_operand:DI 0 "register_operand" "=r")
6161 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6162 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6166 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6168 [(set (attr "length")
6169 (if_then_else (eq_attr "isa" "sparclet")
6170 (const_int 1) (const_int 2)))])
6172 (define_insn "*mulsidi3_sp64"
6173 [(set (match_operand:DI 0 "register_operand" "=r")
6174 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6175 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6176 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6178 [(set_attr "length" "1")])
6180 ;; Extra pattern, because sign_extend of a constant isn't valid.
6183 (define_insn "const_mulsidi3_sp32"
6184 [(set (match_operand:DI 0 "register_operand" "=r")
6185 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6186 (match_operand:SI 2 "small_int" "I")))]
6190 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6192 [(set (attr "length")
6193 (if_then_else (eq_attr "isa" "sparclet")
6194 (const_int 1) (const_int 2)))])
6196 (define_insn "const_mulsidi3_sp64"
6197 [(set (match_operand:DI 0 "register_operand" "=r")
6198 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6199 (match_operand:SI 2 "small_int" "I")))]
6200 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6202 [(set_attr "length" "1")])
6204 (define_expand "smulsi3_highpart"
6205 [(set (match_operand:SI 0 "register_operand" "")
6207 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6208 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6210 "TARGET_HARD_MUL && TARGET_ARCH32"
6213 if (CONSTANT_P (operands[2]))
6217 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6223 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6228 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6229 operands[2], GEN_INT (32)));
6235 (define_insn "smulsi3_highpart_v8plus"
6236 [(set (match_operand:SI 0 "register_operand" "=h,r")
6238 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6239 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6240 (match_operand:SI 3 "const_int_operand" "i,i"))))
6241 (clobber (match_scratch:SI 4 "=X,&h"))]
6244 smul %1,%2,%0\;srlx %0,%3,%0
6245 smul %1,%2,%4\;srlx %4,%3,%0"
6246 [(set_attr "length" "2")])
6248 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6251 [(set (match_operand:SI 0 "register_operand" "=h,r")
6254 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6255 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6256 (match_operand:SI 3 "const_int_operand" "i,i"))
6258 (clobber (match_scratch:SI 4 "=X,&h"))]
6261 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6262 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6263 [(set_attr "length" "2")])
6266 (define_insn "const_smulsi3_highpart_v8plus"
6267 [(set (match_operand:SI 0 "register_operand" "=h,r")
6269 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6270 (match_operand 2 "small_int" "i,i"))
6271 (match_operand:SI 3 "const_int_operand" "i,i"))))
6272 (clobber (match_scratch:SI 4 "=X,&h"))]
6275 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6276 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6277 [(set_attr "length" "2")])
6280 (define_insn "*smulsi3_highpart_sp32"
6281 [(set (match_operand:SI 0 "register_operand" "=r")
6283 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6284 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6287 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6288 [(set_attr "length" "2")])
6291 (define_insn "const_smulsi3_highpart"
6292 [(set (match_operand:SI 0 "register_operand" "=r")
6294 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6295 (match_operand:SI 2 "register_operand" "r"))
6298 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6299 [(set_attr "length" "2")])
6301 (define_expand "umulsidi3"
6302 [(set (match_operand:DI 0 "register_operand" "")
6303 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6304 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6308 if (CONSTANT_P (operands[2]))
6311 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6314 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6320 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6326 (define_insn "umulsidi3_v8plus"
6327 [(set (match_operand:DI 0 "register_operand" "=h,r")
6328 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6329 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6330 (clobber (match_scratch:SI 3 "=X,&h"))]
6333 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6334 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6335 [(set_attr "length" "2,3")])
6338 (define_insn "*umulsidi3_sp32"
6339 [(set (match_operand:DI 0 "register_operand" "=r")
6340 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6341 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6345 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6347 [(set (attr "length")
6348 (if_then_else (eq_attr "isa" "sparclet")
6349 (const_int 1) (const_int 2)))])
6351 (define_insn "*umulsidi3_sp64"
6352 [(set (match_operand:DI 0 "register_operand" "=r")
6353 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6354 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6355 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6357 [(set_attr "length" "1")])
6359 ;; Extra pattern, because sign_extend of a constant isn't valid.
6362 (define_insn "const_umulsidi3_sp32"
6363 [(set (match_operand:DI 0 "register_operand" "=r")
6364 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6365 (match_operand:SI 2 "uns_small_int" "")))]
6369 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6371 [(set (attr "length")
6372 (if_then_else (eq_attr "isa" "sparclet")
6373 (const_int 1) (const_int 2)))])
6375 (define_insn "const_umulsidi3_sp64"
6376 [(set (match_operand:DI 0 "register_operand" "=r")
6377 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6378 (match_operand:SI 2 "uns_small_int" "")))]
6379 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6381 [(set_attr "length" "1")])
6384 (define_insn "const_umulsidi3_v8plus"
6385 [(set (match_operand:DI 0 "register_operand" "=h,r")
6386 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6387 (match_operand:SI 2 "uns_small_int" "")))
6388 (clobber (match_scratch:SI 3 "=X,h"))]
6391 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6392 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6393 [(set_attr "length" "2,3")])
6395 (define_expand "umulsi3_highpart"
6396 [(set (match_operand:SI 0 "register_operand" "")
6398 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6399 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6401 "TARGET_HARD_MUL && TARGET_ARCH32"
6404 if (CONSTANT_P (operands[2]))
6408 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6414 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6419 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6420 operands[2], GEN_INT (32)));
6426 (define_insn "umulsi3_highpart_v8plus"
6427 [(set (match_operand:SI 0 "register_operand" "=h,r")
6429 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6430 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6431 (match_operand:SI 3 "const_int_operand" "i,i"))))
6432 (clobber (match_scratch:SI 4 "=X,h"))]
6435 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6436 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6437 [(set_attr "length" "2")])
6440 (define_insn "const_umulsi3_highpart_v8plus"
6441 [(set (match_operand:SI 0 "register_operand" "=h,r")
6443 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6444 (match_operand:SI 2 "uns_small_int" ""))
6445 (match_operand:SI 3 "const_int_operand" "i,i"))))
6446 (clobber (match_scratch:SI 4 "=X,h"))]
6449 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6450 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6451 [(set_attr "length" "2")])
6454 (define_insn "*umulsi3_highpart_sp32"
6455 [(set (match_operand:SI 0 "register_operand" "=r")
6457 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6458 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6461 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6462 [(set_attr "length" "2")])
6465 (define_insn "const_umulsi3_highpart"
6466 [(set (match_operand:SI 0 "register_operand" "=r")
6468 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6469 (match_operand:SI 2 "uns_small_int" ""))
6472 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6473 [(set_attr "length" "2")])
6475 ;; The v8 architecture specifies that there must be 3 instructions between
6476 ;; a y register write and a use of it for correct results.
6478 (define_expand "divsi3"
6479 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6480 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6481 (match_operand:SI 2 "input_operand" "rI,m")))
6482 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6483 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6488 operands[3] = gen_reg_rtx(SImode);
6489 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6490 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6496 (define_insn "divsi3_sp32"
6497 [(set (match_operand:SI 0 "register_operand" "=r,r")
6498 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6499 (match_operand:SI 2 "input_operand" "rI,m")))
6500 (clobber (match_scratch:SI 3 "=&r,&r"))]
6501 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6505 if (which_alternative == 0)
6507 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6509 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6512 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6514 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\";
6516 [(set (attr "length")
6517 (if_then_else (eq_attr "isa" "v9")
6518 (const_int 4) (const_int 7)))])
6520 (define_insn "divsi3_sp64"
6521 [(set (match_operand:SI 0 "register_operand" "=r")
6522 (div:SI (match_operand:SI 1 "register_operand" "r")
6523 (match_operand:SI 2 "input_operand" "rI")))
6524 (use (match_operand:SI 3 "register_operand" "r"))]
6525 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6526 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6527 [(set_attr "length" "2")])
6529 (define_insn "divdi3"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (div:DI (match_operand:DI 1 "register_operand" "r")
6532 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6534 "sdivx\\t%1, %2, %0")
6536 (define_insn "*cmp_sdiv_cc_set"
6538 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6539 (match_operand:SI 2 "arith_operand" "rI"))
6541 (set (match_operand:SI 0 "register_operand" "=r")
6542 (div:SI (match_dup 1) (match_dup 2)))
6543 (clobber (match_scratch:SI 3 "=&r"))]
6544 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6548 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6550 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6552 [(set (attr "length")
6553 (if_then_else (eq_attr "isa" "v9")
6554 (const_int 3) (const_int 6)))])
6557 (define_expand "udivsi3"
6558 [(set (match_operand:SI 0 "register_operand" "")
6559 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6560 (match_operand:SI 2 "input_operand" "")))]
6561 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6564 (define_insn "udivsi3_sp32"
6565 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6566 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6567 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6569 || TARGET_DEPRECATED_V8_INSNS)
6573 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6574 switch (which_alternative)
6577 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6579 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6581 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6584 [(set_attr "length" "5")])
6586 (define_insn "udivsi3_sp64"
6587 [(set (match_operand:SI 0 "register_operand" "=r")
6588 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6589 (match_operand:SI 2 "input_operand" "rI")))]
6590 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6591 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6592 [(set_attr "length" "2")])
6594 (define_insn "udivdi3"
6595 [(set (match_operand:DI 0 "register_operand" "=r")
6596 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6597 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6599 "udivx\\t%1, %2, %0")
6601 (define_insn "*cmp_udiv_cc_set"
6603 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6604 (match_operand:SI 2 "arith_operand" "rI"))
6606 (set (match_operand:SI 0 "register_operand" "=r")
6607 (udiv:SI (match_dup 1) (match_dup 2)))]
6609 || TARGET_DEPRECATED_V8_INSNS"
6613 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6615 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6617 [(set (attr "length")
6618 (if_then_else (eq_attr "isa" "v9")
6619 (const_int 2) (const_int 5)))])
6621 ; sparclet multiply/accumulate insns
6623 (define_insn "*smacsi"
6624 [(set (match_operand:SI 0 "register_operand" "=r")
6625 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6626 (match_operand:SI 2 "arith_operand" "rI"))
6627 (match_operand:SI 3 "register_operand" "0")))]
6630 [(set_attr "type" "imul")
6631 (set_attr "length" "1")])
6633 (define_insn "*smacdi"
6634 [(set (match_operand:DI 0 "register_operand" "=r")
6635 (plus:DI (mult:DI (sign_extend:DI
6636 (match_operand:SI 1 "register_operand" "%r"))
6638 (match_operand:SI 2 "register_operand" "r")))
6639 (match_operand:DI 3 "register_operand" "0")))]
6641 "smacd\\t%1, %2, %L0"
6642 [(set_attr "type" "imul")
6643 (set_attr "length" "1")])
6645 (define_insn "*umacdi"
6646 [(set (match_operand:DI 0 "register_operand" "=r")
6647 (plus:DI (mult:DI (zero_extend:DI
6648 (match_operand:SI 1 "register_operand" "%r"))
6650 (match_operand:SI 2 "register_operand" "r")))
6651 (match_operand:DI 3 "register_operand" "0")))]
6653 "umacd\\t%1, %2, %L0"
6654 [(set_attr "type" "imul")
6655 (set_attr "length" "1")])
6657 ;;- Boolean instructions
6658 ;; We define DImode `and' so with DImode `not' we can get
6659 ;; DImode `andn'. Other combinations are possible.
6661 (define_expand "anddi3"
6662 [(set (match_operand:DI 0 "register_operand" "")
6663 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6664 (match_operand:DI 2 "arith_double_operand" "")))]
6668 (define_insn "*anddi3_sp32"
6669 [(set (match_operand:DI 0 "register_operand" "=r,b")
6670 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6671 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6676 [(set_attr "type" "ialu,fp")
6677 (set_attr "length" "2,1")])
6679 (define_insn "*anddi3_sp64"
6680 [(set (match_operand:DI 0 "register_operand" "=r,b")
6681 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6682 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6687 [(set_attr "type" "ialu,fp")
6688 (set_attr "length" "1,1")])
6690 (define_insn "andsi3"
6691 [(set (match_operand:SI 0 "register_operand" "=r,d")
6692 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6693 (match_operand:SI 2 "arith_operand" "rI,d")))]
6698 [(set_attr "type" "ialu,fp")
6699 (set_attr "length" "1,1")])
6702 [(set (match_operand:SI 0 "register_operand" "")
6703 (and:SI (match_operand:SI 1 "register_operand" "")
6704 (match_operand:SI 2 "" "")))
6705 (clobber (match_operand:SI 3 "register_operand" ""))]
6706 "GET_CODE (operands[2]) == CONST_INT
6707 && !SMALL_INT32 (operands[2])
6708 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6709 [(set (match_dup 3) (match_dup 4))
6710 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6713 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6716 ;; Split DImode logical operations requiring two instructions.
6718 [(set (match_operand:DI 0 "register_operand" "")
6719 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6720 [(match_operand:DI 2 "register_operand" "")
6721 (match_operand:DI 3 "arith_double_operand" "")]))]
6724 && ((GET_CODE (operands[0]) == REG
6725 && REGNO (operands[0]) < 32)
6726 || (GET_CODE (operands[0]) == SUBREG
6727 && GET_CODE (SUBREG_REG (operands[0])) == REG
6728 && REGNO (SUBREG_REG (operands[0])) < 32))"
6729 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6730 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6733 if (GET_CODE (operands[0]) == SUBREG)
6734 operands[0] = alter_subreg (operands[0]);
6735 operands[4] = gen_highpart (SImode, operands[0]);
6736 operands[5] = gen_lowpart (SImode, operands[0]);
6737 operands[6] = gen_highpart (SImode, operands[2]);
6738 operands[7] = gen_lowpart (SImode, operands[2]);
6739 #if HOST_BITS_PER_WIDE_INT == 32
6740 if (GET_CODE (operands[3]) == CONST_INT)
6742 if (INTVAL (operands[3]) < 0)
6743 operands[8] = constm1_rtx;
6745 operands[8] = const0_rtx;
6749 operands[8] = gen_highpart (SImode, operands[3]);
6750 operands[9] = gen_lowpart (SImode, operands[3]);
6753 (define_insn "*and_not_di_sp32"
6754 [(set (match_operand:DI 0 "register_operand" "=r,b")
6755 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6756 (match_operand:DI 2 "register_operand" "r,b")))]
6760 fandnot1\\t%1, %2, %0"
6761 [(set_attr "type" "ialu,fp")
6762 (set_attr "length" "2,1")])
6765 [(set (match_operand:DI 0 "register_operand" "")
6766 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6767 (match_operand:DI 2 "register_operand" "")))]
6770 && ((GET_CODE (operands[0]) == REG
6771 && REGNO (operands[0]) < 32)
6772 || (GET_CODE (operands[0]) == SUBREG
6773 && GET_CODE (SUBREG_REG (operands[0])) == REG
6774 && REGNO (SUBREG_REG (operands[0])) < 32))"
6775 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6776 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6777 "if (GET_CODE (operands[0]) == SUBREG)
6778 operands[0] = alter_subreg (operands[0]);
6779 operands[3] = gen_highpart (SImode, operands[0]);
6780 operands[4] = gen_highpart (SImode, operands[1]);
6781 operands[5] = gen_highpart (SImode, operands[2]);
6782 operands[6] = gen_lowpart (SImode, operands[0]);
6783 operands[7] = gen_lowpart (SImode, operands[1]);
6784 operands[8] = gen_lowpart (SImode, operands[2]);")
6786 (define_insn "*and_not_di_sp64"
6787 [(set (match_operand:DI 0 "register_operand" "=r,b")
6788 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6789 (match_operand:DI 2 "register_operand" "r,b")))]
6793 fandnot1\\t%1, %2, %0"
6794 [(set_attr "type" "ialu,fp")
6795 (set_attr "length" "1,1")])
6797 (define_insn "*and_not_si"
6798 [(set (match_operand:SI 0 "register_operand" "=r,d")
6799 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6800 (match_operand:SI 2 "register_operand" "r,d")))]
6804 fandnot1s\\t%1, %2, %0"
6805 [(set_attr "type" "ialu,fp")
6806 (set_attr "length" "1,1")])
6808 (define_expand "iordi3"
6809 [(set (match_operand:DI 0 "register_operand" "")
6810 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6811 (match_operand:DI 2 "arith_double_operand" "")))]
6815 (define_insn "*iordi3_sp32"
6816 [(set (match_operand:DI 0 "register_operand" "=r,b")
6817 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6818 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6823 [(set_attr "type" "ialu,fp")
6824 (set_attr "length" "2,1")])
6826 (define_insn "*iordi3_sp64"
6827 [(set (match_operand:DI 0 "register_operand" "=r,b")
6828 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6829 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6834 [(set_attr "type" "ialu,fp")
6835 (set_attr "length" "1,1")])
6837 (define_insn "iorsi3"
6838 [(set (match_operand:SI 0 "register_operand" "=r,d")
6839 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6840 (match_operand:SI 2 "arith_operand" "rI,d")))]
6845 [(set_attr "type" "ialu,fp")
6846 (set_attr "length" "1,1")])
6849 [(set (match_operand:SI 0 "register_operand" "")
6850 (ior:SI (match_operand:SI 1 "register_operand" "")
6851 (match_operand:SI 2 "" "")))
6852 (clobber (match_operand:SI 3 "register_operand" ""))]
6853 "GET_CODE (operands[2]) == CONST_INT
6854 && !SMALL_INT32 (operands[2])
6855 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6856 [(set (match_dup 3) (match_dup 4))
6857 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6860 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6863 (define_insn "*or_not_di_sp32"
6864 [(set (match_operand:DI 0 "register_operand" "=r,b")
6865 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6866 (match_operand:DI 2 "register_operand" "r,b")))]
6870 fornot1\\t%1, %2, %0"
6871 [(set_attr "type" "ialu,fp")
6872 (set_attr "length" "2,1")])
6875 [(set (match_operand:DI 0 "register_operand" "")
6876 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6877 (match_operand:DI 2 "register_operand" "")))]
6880 && ((GET_CODE (operands[0]) == REG
6881 && REGNO (operands[0]) < 32)
6882 || (GET_CODE (operands[0]) == SUBREG
6883 && GET_CODE (SUBREG_REG (operands[0])) == REG
6884 && REGNO (SUBREG_REG (operands[0])) < 32))"
6885 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6886 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6887 "if (GET_CODE (operands[0]) == SUBREG)
6888 operands[0] = alter_subreg (operands[0]);
6889 operands[3] = gen_highpart (SImode, operands[0]);
6890 operands[4] = gen_highpart (SImode, operands[1]);
6891 operands[5] = gen_highpart (SImode, operands[2]);
6892 operands[6] = gen_lowpart (SImode, operands[0]);
6893 operands[7] = gen_lowpart (SImode, operands[1]);
6894 operands[8] = gen_lowpart (SImode, operands[2]);")
6896 (define_insn "*or_not_di_sp64"
6897 [(set (match_operand:DI 0 "register_operand" "=r,b")
6898 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6899 (match_operand:DI 2 "register_operand" "r,b")))]
6903 fornot1\\t%1, %2, %0"
6904 [(set_attr "type" "ialu,fp")
6905 (set_attr "length" "1,1")])
6907 (define_insn "*or_not_si"
6908 [(set (match_operand:SI 0 "register_operand" "=r,d")
6909 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6910 (match_operand:SI 2 "register_operand" "r,d")))]
6914 fornot1s\\t%1, %2, %0"
6915 [(set_attr "type" "ialu,fp")
6916 (set_attr "length" "1,1")])
6918 (define_expand "xordi3"
6919 [(set (match_operand:DI 0 "register_operand" "")
6920 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6921 (match_operand:DI 2 "arith_double_operand" "")))]
6925 (define_insn "*xordi3_sp32"
6926 [(set (match_operand:DI 0 "register_operand" "=r,b")
6927 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6928 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6933 [(set_attr "length" "2,1")
6934 (set_attr "type" "ialu,fp")])
6936 (define_insn "*xordi3_sp64"
6937 [(set (match_operand:DI 0 "register_operand" "=r,b")
6938 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6939 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6944 [(set_attr "type" "ialu,fp")
6945 (set_attr "length" "1,1")])
6947 (define_insn "*xordi3_sp64_dbl"
6948 [(set (match_operand:DI 0 "register_operand" "=r")
6949 (xor:DI (match_operand:DI 1 "register_operand" "r")
6950 (match_operand:DI 2 "const64_operand" "")))]
6952 && HOST_BITS_PER_WIDE_INT != 64)"
6954 [(set_attr "type" "ialu")
6955 (set_attr "length" "1")])
6957 (define_insn "xorsi3"
6958 [(set (match_operand:SI 0 "register_operand" "=r,d")
6959 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6960 (match_operand:SI 2 "arith_operand" "rI,d")))]
6965 [(set_attr "type" "ialu,fp")
6966 (set_attr "length" "1,1")])
6969 [(set (match_operand:SI 0 "register_operand" "")
6970 (xor:SI (match_operand:SI 1 "register_operand" "")
6971 (match_operand:SI 2 "" "")))
6972 (clobber (match_operand:SI 3 "register_operand" ""))]
6973 "GET_CODE (operands[2]) == CONST_INT
6974 && !SMALL_INT32 (operands[2])
6975 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6976 [(set (match_dup 3) (match_dup 4))
6977 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6980 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6984 [(set (match_operand:SI 0 "register_operand" "")
6985 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6986 (match_operand:SI 2 "" ""))))
6987 (clobber (match_operand:SI 3 "register_operand" ""))]
6988 "GET_CODE (operands[2]) == CONST_INT
6989 && !SMALL_INT32 (operands[2])
6990 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6991 [(set (match_dup 3) (match_dup 4))
6992 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6995 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6998 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6999 ;; Combine now canonicalizes to the rightmost expression.
7000 (define_insn "*xor_not_di_sp32"
7001 [(set (match_operand:DI 0 "register_operand" "=r,b")
7002 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
7003 (match_operand:DI 2 "register_operand" "r,b"))))]
7008 [(set_attr "length" "2,1")
7009 (set_attr "type" "ialu,fp")])
7012 [(set (match_operand:DI 0 "register_operand" "")
7013 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
7014 (match_operand:DI 2 "register_operand" ""))))]
7017 && ((GET_CODE (operands[0]) == REG
7018 && REGNO (operands[0]) < 32)
7019 || (GET_CODE (operands[0]) == SUBREG
7020 && GET_CODE (SUBREG_REG (operands[0])) == REG
7021 && REGNO (SUBREG_REG (operands[0])) < 32))"
7022 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
7023 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
7024 "if (GET_CODE (operands[0]) == SUBREG)
7025 operands[0] = alter_subreg (operands[0]);
7026 operands[3] = gen_highpart (SImode, operands[0]);
7027 operands[4] = gen_highpart (SImode, operands[1]);
7028 operands[5] = gen_highpart (SImode, operands[2]);
7029 operands[6] = gen_lowpart (SImode, operands[0]);
7030 operands[7] = gen_lowpart (SImode, operands[1]);
7031 operands[8] = gen_lowpart (SImode, operands[2]);")
7033 (define_insn "*xor_not_di_sp64"
7034 [(set (match_operand:DI 0 "register_operand" "=r,b")
7035 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7036 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7041 [(set_attr "type" "ialu,fp")
7042 (set_attr "length" "1,1")])
7044 (define_insn "*xor_not_si"
7045 [(set (match_operand:SI 0 "register_operand" "=r,d")
7046 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7047 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7051 fxnors\\t%1, %2, %0"
7052 [(set_attr "type" "ialu,fp")
7053 (set_attr "length" "1,1")])
7055 ;; These correspond to the above in the case where we also (or only)
7056 ;; want to set the condition code.
7058 (define_insn "*cmp_cc_arith_op"
7061 (match_operator:SI 2 "cc_arithop"
7062 [(match_operand:SI 0 "arith_operand" "%r")
7063 (match_operand:SI 1 "arith_operand" "rI")])
7066 "%A2cc\\t%0, %1, %%g0"
7067 [(set_attr "type" "compare")
7068 (set_attr "length" "1")])
7070 (define_insn "*cmp_ccx_arith_op"
7073 (match_operator:DI 2 "cc_arithop"
7074 [(match_operand:DI 0 "arith_double_operand" "%r")
7075 (match_operand:DI 1 "arith_double_operand" "rHI")])
7078 "%A2cc\\t%0, %1, %%g0"
7079 [(set_attr "type" "compare")
7080 (set_attr "length" "1")])
7082 (define_insn "*cmp_cc_arith_op_set"
7085 (match_operator:SI 3 "cc_arithop"
7086 [(match_operand:SI 1 "arith_operand" "%r")
7087 (match_operand:SI 2 "arith_operand" "rI")])
7089 (set (match_operand:SI 0 "register_operand" "=r")
7092 "%A3cc\\t%1, %2, %0"
7093 [(set_attr "type" "compare")
7094 (set_attr "length" "1")])
7096 (define_insn "*cmp_ccx_arith_op_set"
7099 (match_operator:DI 3 "cc_arithop"
7100 [(match_operand:DI 1 "arith_double_operand" "%r")
7101 (match_operand:DI 2 "arith_double_operand" "rHI")])
7103 (set (match_operand:DI 0 "register_operand" "=r")
7106 "%A3cc\\t%1, %2, %0"
7107 [(set_attr "type" "compare")
7108 (set_attr "length" "1")])
7110 (define_insn "*cmp_cc_xor_not"
7113 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7114 (match_operand:SI 1 "arith_operand" "rI")))
7117 "xnorcc\\t%r0, %1, %%g0"
7118 [(set_attr "type" "compare")
7119 (set_attr "length" "1")])
7121 (define_insn "*cmp_ccx_xor_not"
7124 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7125 (match_operand:DI 1 "arith_double_operand" "rHI")))
7128 "xnorcc\\t%r0, %1, %%g0"
7129 [(set_attr "type" "compare")
7130 (set_attr "length" "1")])
7132 (define_insn "*cmp_cc_xor_not_set"
7135 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7136 (match_operand:SI 2 "arith_operand" "rI")))
7138 (set (match_operand:SI 0 "register_operand" "=r")
7139 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7141 "xnorcc\\t%r1, %2, %0"
7142 [(set_attr "type" "compare")
7143 (set_attr "length" "1")])
7145 (define_insn "*cmp_ccx_xor_not_set"
7148 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7149 (match_operand:DI 2 "arith_double_operand" "rHI")))
7151 (set (match_operand:DI 0 "register_operand" "=r")
7152 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7154 "xnorcc\\t%r1, %2, %0"
7155 [(set_attr "type" "compare")
7156 (set_attr "length" "1")])
7158 (define_insn "*cmp_cc_arith_op_not"
7161 (match_operator:SI 2 "cc_arithopn"
7162 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7163 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7166 "%B2cc\\t%r1, %0, %%g0"
7167 [(set_attr "type" "compare")
7168 (set_attr "length" "1")])
7170 (define_insn "*cmp_ccx_arith_op_not"
7173 (match_operator:DI 2 "cc_arithopn"
7174 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7175 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7178 "%B2cc\\t%r1, %0, %%g0"
7179 [(set_attr "type" "compare")
7180 (set_attr "length" "1")])
7182 (define_insn "*cmp_cc_arith_op_not_set"
7185 (match_operator:SI 3 "cc_arithopn"
7186 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7187 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7189 (set (match_operand:SI 0 "register_operand" "=r")
7192 "%B3cc\\t%r2, %1, %0"
7193 [(set_attr "type" "compare")
7194 (set_attr "length" "1")])
7196 (define_insn "*cmp_ccx_arith_op_not_set"
7199 (match_operator:DI 3 "cc_arithopn"
7200 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7201 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7203 (set (match_operand:DI 0 "register_operand" "=r")
7206 "%B3cc\\t%r2, %1, %0"
7207 [(set_attr "type" "compare")
7208 (set_attr "length" "1")])
7210 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7211 ;; does not know how to make it work for constants.
7213 (define_expand "negdi2"
7214 [(set (match_operand:DI 0 "register_operand" "=r")
7215 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7219 if (! TARGET_ARCH64)
7221 emit_insn (gen_rtx_PARALLEL
7224 gen_rtx_SET (VOIDmode, operand0,
7225 gen_rtx_NEG (DImode, operand1)),
7226 gen_rtx_CLOBBER (VOIDmode,
7227 gen_rtx_REG (CCmode,
7233 (define_insn "*negdi2_sp32"
7234 [(set (match_operand:DI 0 "register_operand" "=r")
7235 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7236 (clobber (reg:CC 100))]
7239 [(set_attr "type" "unary")
7240 (set_attr "length" "2")])
7243 [(set (match_operand:DI 0 "register_operand" "")
7244 (neg:DI (match_operand:DI 1 "register_operand" "")))
7245 (clobber (reg:CC 100))]
7247 && reload_completed"
7248 [(parallel [(set (reg:CC_NOOV 100)
7249 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7251 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7252 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7253 (ltu:SI (reg:CC 100) (const_int 0))))]
7254 "operands[2] = gen_highpart (SImode, operands[0]);
7255 operands[3] = gen_highpart (SImode, operands[1]);
7256 operands[4] = gen_lowpart (SImode, operands[0]);
7257 operands[5] = gen_lowpart (SImode, operands[1]);")
7259 (define_insn "*negdi2_sp64"
7260 [(set (match_operand:DI 0 "register_operand" "=r")
7261 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7263 "sub\\t%%g0, %1, %0"
7264 [(set_attr "type" "unary")
7265 (set_attr "length" "1")])
7267 (define_insn "negsi2"
7268 [(set (match_operand:SI 0 "register_operand" "=r")
7269 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7271 "sub\\t%%g0, %1, %0"
7272 [(set_attr "type" "unary")
7273 (set_attr "length" "1")])
7275 (define_insn "*cmp_cc_neg"
7276 [(set (reg:CC_NOOV 100)
7277 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7280 "subcc\\t%%g0, %0, %%g0"
7281 [(set_attr "type" "compare")
7282 (set_attr "length" "1")])
7284 (define_insn "*cmp_ccx_neg"
7285 [(set (reg:CCX_NOOV 100)
7286 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7289 "subcc\\t%%g0, %0, %%g0"
7290 [(set_attr "type" "compare")
7291 (set_attr "length" "1")])
7293 (define_insn "*cmp_cc_set_neg"
7294 [(set (reg:CC_NOOV 100)
7295 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7297 (set (match_operand:SI 0 "register_operand" "=r")
7298 (neg:SI (match_dup 1)))]
7300 "subcc\\t%%g0, %1, %0"
7301 [(set_attr "type" "compare")
7302 (set_attr "length" "1")])
7304 (define_insn "*cmp_ccx_set_neg"
7305 [(set (reg:CCX_NOOV 100)
7306 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7308 (set (match_operand:DI 0 "register_operand" "=r")
7309 (neg:DI (match_dup 1)))]
7311 "subcc\\t%%g0, %1, %0"
7312 [(set_attr "type" "compare")
7313 (set_attr "length" "1")])
7315 ;; We cannot use the "not" pseudo insn because the Sun assembler
7316 ;; does not know how to make it work for constants.
7317 (define_expand "one_cmpldi2"
7318 [(set (match_operand:DI 0 "register_operand" "")
7319 (not:DI (match_operand:DI 1 "register_operand" "")))]
7323 (define_insn "*one_cmpldi2_sp32"
7324 [(set (match_operand:DI 0 "register_operand" "=r,b")
7325 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7330 [(set_attr "type" "unary,fp")
7331 (set_attr "length" "2,1")])
7334 [(set (match_operand:DI 0 "register_operand" "")
7335 (not:DI (match_operand:DI 1 "register_operand" "")))]
7338 && ((GET_CODE (operands[0]) == REG
7339 && REGNO (operands[0]) < 32)
7340 || (GET_CODE (operands[0]) == SUBREG
7341 && GET_CODE (SUBREG_REG (operands[0])) == REG
7342 && REGNO (SUBREG_REG (operands[0])) < 32))"
7343 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7344 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7345 "if (GET_CODE (operands[0]) == SUBREG)
7346 operands[0] = alter_subreg (operands[0]);
7347 operands[2] = gen_highpart (SImode, operands[0]);
7348 operands[3] = gen_highpart (SImode, operands[1]);
7349 operands[4] = gen_lowpart (SImode, operands[0]);
7350 operands[5] = gen_lowpart (SImode, operands[1]);")
7352 (define_insn "*one_cmpldi2_sp64"
7353 [(set (match_operand:DI 0 "register_operand" "=r,b")
7354 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7359 [(set_attr "type" "unary,fp")
7360 (set_attr "length" "1")])
7362 (define_insn "one_cmplsi2"
7363 [(set (match_operand:SI 0 "register_operand" "=r,d")
7364 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7369 [(set_attr "type" "unary,fp")
7370 (set_attr "length" "1,1")])
7372 (define_insn "*cmp_cc_not"
7374 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7377 "xnorcc\\t%%g0, %0, %%g0"
7378 [(set_attr "type" "compare")
7379 (set_attr "length" "1")])
7381 (define_insn "*cmp_ccx_not"
7383 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7386 "xnorcc\\t%%g0, %0, %%g0"
7387 [(set_attr "type" "compare")
7388 (set_attr "length" "1")])
7390 (define_insn "*cmp_cc_set_not"
7392 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7394 (set (match_operand:SI 0 "register_operand" "=r")
7395 (not:SI (match_dup 1)))]
7397 "xnorcc\\t%%g0, %1, %0"
7398 [(set_attr "type" "compare")
7399 (set_attr "length" "1")])
7401 (define_insn "*cmp_ccx_set_not"
7403 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7405 (set (match_operand:DI 0 "register_operand" "=r")
7406 (not:DI (match_dup 1)))]
7408 "xnorcc\\t%%g0, %1, %0"
7409 [(set_attr "type" "compare")
7410 (set_attr "length" "1")])
7412 ;; Floating point arithmetic instructions.
7414 (define_expand "addtf3"
7415 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7416 (plus:TF (match_operand:TF 1 "general_operand" "")
7417 (match_operand:TF 2 "general_operand" "")))]
7418 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7421 if (! TARGET_HARD_QUAD)
7423 rtx slot0, slot1, slot2;
7425 if (GET_CODE (operands[0]) != MEM)
7426 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7428 slot0 = operands[0];
7429 if (GET_CODE (operands[1]) != MEM)
7431 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7432 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7435 slot1 = operands[1];
7436 if (GET_CODE (operands[2]) != MEM)
7438 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7439 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7442 slot2 = operands[2];
7444 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7446 XEXP (slot0, 0), Pmode,
7447 XEXP (slot1, 0), Pmode,
7448 XEXP (slot2, 0), Pmode);
7450 if (GET_CODE (operands[0]) != MEM)
7451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7456 (define_insn "*addtf3_hq"
7457 [(set (match_operand:TF 0 "register_operand" "=e")
7458 (plus:TF (match_operand:TF 1 "register_operand" "e")
7459 (match_operand:TF 2 "register_operand" "e")))]
7460 "TARGET_FPU && TARGET_HARD_QUAD"
7461 "faddq\\t%1, %2, %0"
7462 [(set_attr "type" "fp")
7463 (set_attr "length" "1")])
7465 (define_insn "adddf3"
7466 [(set (match_operand:DF 0 "register_operand" "=e")
7467 (plus:DF (match_operand:DF 1 "register_operand" "e")
7468 (match_operand:DF 2 "register_operand" "e")))]
7470 "faddd\\t%1, %2, %0"
7471 [(set_attr "type" "fp")
7472 (set_attr "length" "1")])
7474 (define_insn "addsf3"
7475 [(set (match_operand:SF 0 "register_operand" "=f")
7476 (plus:SF (match_operand:SF 1 "register_operand" "f")
7477 (match_operand:SF 2 "register_operand" "f")))]
7479 "fadds\\t%1, %2, %0"
7480 [(set_attr "type" "fp")
7481 (set_attr "length" "1")])
7483 (define_expand "subtf3"
7484 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7485 (minus:TF (match_operand:TF 1 "general_operand" "")
7486 (match_operand:TF 2 "general_operand" "")))]
7487 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7490 if (! TARGET_HARD_QUAD)
7492 rtx slot0, slot1, slot2;
7494 if (GET_CODE (operands[0]) != MEM)
7495 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7497 slot0 = operands[0];
7498 if (GET_CODE (operands[1]) != MEM)
7500 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7501 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7504 slot1 = operands[1];
7505 if (GET_CODE (operands[2]) != MEM)
7507 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7508 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7511 slot2 = operands[2];
7513 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7515 XEXP (slot0, 0), Pmode,
7516 XEXP (slot1, 0), Pmode,
7517 XEXP (slot2, 0), Pmode);
7519 if (GET_CODE (operands[0]) != MEM)
7520 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7525 (define_insn "*subtf3_hq"
7526 [(set (match_operand:TF 0 "register_operand" "=e")
7527 (minus:TF (match_operand:TF 1 "register_operand" "e")
7528 (match_operand:TF 2 "register_operand" "e")))]
7529 "TARGET_FPU && TARGET_HARD_QUAD"
7530 "fsubq\\t%1, %2, %0"
7531 [(set_attr "type" "fp")
7532 (set_attr "length" "1")])
7534 (define_insn "subdf3"
7535 [(set (match_operand:DF 0 "register_operand" "=e")
7536 (minus:DF (match_operand:DF 1 "register_operand" "e")
7537 (match_operand:DF 2 "register_operand" "e")))]
7539 "fsubd\\t%1, %2, %0"
7540 [(set_attr "type" "fp")
7541 (set_attr "length" "1")])
7543 (define_insn "subsf3"
7544 [(set (match_operand:SF 0 "register_operand" "=f")
7545 (minus:SF (match_operand:SF 1 "register_operand" "f")
7546 (match_operand:SF 2 "register_operand" "f")))]
7548 "fsubs\\t%1, %2, %0"
7549 [(set_attr "type" "fp")
7550 (set_attr "length" "1")])
7552 (define_expand "multf3"
7553 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7554 (mult:TF (match_operand:TF 1 "general_operand" "")
7555 (match_operand:TF 2 "general_operand" "")))]
7556 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7559 if (! TARGET_HARD_QUAD)
7561 rtx slot0, slot1, slot2;
7563 if (GET_CODE (operands[0]) != MEM)
7564 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7566 slot0 = operands[0];
7567 if (GET_CODE (operands[1]) != MEM)
7569 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7570 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7573 slot1 = operands[1];
7574 if (GET_CODE (operands[2]) != MEM)
7576 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7577 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7580 slot2 = operands[2];
7582 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7584 XEXP (slot0, 0), Pmode,
7585 XEXP (slot1, 0), Pmode,
7586 XEXP (slot2, 0), Pmode);
7588 if (GET_CODE (operands[0]) != MEM)
7589 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7594 (define_insn "*multf3_hq"
7595 [(set (match_operand:TF 0 "register_operand" "=e")
7596 (mult:TF (match_operand:TF 1 "register_operand" "e")
7597 (match_operand:TF 2 "register_operand" "e")))]
7598 "TARGET_FPU && TARGET_HARD_QUAD"
7599 "fmulq\\t%1, %2, %0"
7600 [(set_attr "type" "fpmul")
7601 (set_attr "length" "1")])
7603 (define_insn "muldf3"
7604 [(set (match_operand:DF 0 "register_operand" "=e")
7605 (mult:DF (match_operand:DF 1 "register_operand" "e")
7606 (match_operand:DF 2 "register_operand" "e")))]
7608 "fmuld\\t%1, %2, %0"
7609 [(set_attr "type" "fpmul")
7610 (set_attr "length" "1")])
7612 (define_insn "mulsf3"
7613 [(set (match_operand:SF 0 "register_operand" "=f")
7614 (mult:SF (match_operand:SF 1 "register_operand" "f")
7615 (match_operand:SF 2 "register_operand" "f")))]
7617 "fmuls\\t%1, %2, %0"
7618 [(set_attr "type" "fpmul")
7619 (set_attr "length" "1")])
7621 (define_insn "*muldf3_extend"
7622 [(set (match_operand:DF 0 "register_operand" "=e")
7623 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7624 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7625 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7626 "fsmuld\\t%1, %2, %0"
7627 [(set_attr "type" "fpmul")
7628 (set_attr "length" "1")])
7630 (define_insn "*multf3_extend"
7631 [(set (match_operand:TF 0 "register_operand" "=e")
7632 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7633 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7634 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7635 "fdmulq\\t%1, %2, %0"
7636 [(set_attr "type" "fpmul")
7637 (set_attr "length" "1")])
7639 (define_expand "divtf3"
7640 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7641 (div:TF (match_operand:TF 1 "general_operand" "")
7642 (match_operand:TF 2 "general_operand" "")))]
7643 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7646 if (! TARGET_HARD_QUAD)
7648 rtx slot0, slot1, slot2;
7650 if (GET_CODE (operands[0]) != MEM)
7651 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7653 slot0 = operands[0];
7654 if (GET_CODE (operands[1]) != MEM)
7656 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7657 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7660 slot1 = operands[1];
7661 if (GET_CODE (operands[2]) != MEM)
7663 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7664 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7667 slot2 = operands[2];
7669 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7671 XEXP (slot0, 0), Pmode,
7672 XEXP (slot1, 0), Pmode,
7673 XEXP (slot2, 0), Pmode);
7675 if (GET_CODE (operands[0]) != MEM)
7676 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7681 ;; don't have timing for quad-prec. divide.
7682 (define_insn "*divtf3_hq"
7683 [(set (match_operand:TF 0 "register_operand" "=e")
7684 (div:TF (match_operand:TF 1 "register_operand" "e")
7685 (match_operand:TF 2 "register_operand" "e")))]
7686 "TARGET_FPU && TARGET_HARD_QUAD"
7687 "fdivq\\t%1, %2, %0"
7688 [(set_attr "type" "fpdivd")
7689 (set_attr "length" "1")])
7691 (define_insn "divdf3"
7692 [(set (match_operand:DF 0 "register_operand" "=e")
7693 (div:DF (match_operand:DF 1 "register_operand" "e")
7694 (match_operand:DF 2 "register_operand" "e")))]
7696 "fdivd\\t%1, %2, %0"
7697 [(set_attr "type" "fpdivd")
7698 (set_attr "length" "1")])
7700 (define_insn "divsf3"
7701 [(set (match_operand:SF 0 "register_operand" "=f")
7702 (div:SF (match_operand:SF 1 "register_operand" "f")
7703 (match_operand:SF 2 "register_operand" "f")))]
7705 "fdivs\\t%1, %2, %0"
7706 [(set_attr "type" "fpdivs")
7707 (set_attr "length" "1")])
7709 (define_expand "negtf2"
7710 [(set (match_operand:TF 0 "register_operand" "=e,e")
7711 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7715 (define_insn "*negtf2_notv9"
7716 [(set (match_operand:TF 0 "register_operand" "=e,e")
7717 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7718 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7724 [(set_attr "type" "fpmove")
7725 (set_attr "length" "1,2")])
7728 [(set (match_operand:TF 0 "register_operand" "")
7729 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7733 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7734 [(set (match_dup 2) (neg:SF (match_dup 3)))
7735 (set (match_dup 4) (match_dup 5))
7736 (set (match_dup 6) (match_dup 7))]
7737 "if (GET_CODE (operands[0]) == SUBREG)
7738 operands[0] = alter_subreg (operands[0]);
7739 if (GET_CODE (operands[1]) == SUBREG)
7740 operands[1] = alter_subreg (operands[1]);
7741 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7742 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7743 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7744 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7745 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7746 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7748 (define_insn "*negtf2_v9"
7749 [(set (match_operand:TF 0 "register_operand" "=e,e")
7750 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7751 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7752 "TARGET_FPU && TARGET_V9"
7756 [(set_attr "type" "fpmove")
7757 (set_attr "length" "1,2")])
7760 [(set (match_operand:TF 0 "register_operand" "")
7761 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7765 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7766 [(set (match_dup 2) (neg:DF (match_dup 3)))
7767 (set (match_dup 4) (match_dup 5))]
7768 "if (GET_CODE (operands[0]) == SUBREG)
7769 operands[0] = alter_subreg (operands[0]);
7770 if (GET_CODE (operands[1]) == SUBREG)
7771 operands[1] = alter_subreg (operands[1]);
7772 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7773 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7774 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7775 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7777 (define_expand "negdf2"
7778 [(set (match_operand:DF 0 "register_operand" "")
7779 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7783 (define_insn "*negdf2_notv9"
7784 [(set (match_operand:DF 0 "register_operand" "=e,e")
7785 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7786 "TARGET_FPU && ! TARGET_V9"
7790 [(set_attr "type" "fpmove")
7791 (set_attr "length" "1,2")])
7794 [(set (match_operand:DF 0 "register_operand" "")
7795 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7799 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7800 [(set (match_dup 2) (neg:SF (match_dup 3)))
7801 (set (match_dup 4) (match_dup 5))]
7802 "if (GET_CODE (operands[0]) == SUBREG)
7803 operands[0] = alter_subreg (operands[0]);
7804 if (GET_CODE (operands[1]) == SUBREG)
7805 operands[1] = alter_subreg (operands[1]);
7806 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7807 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7808 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7809 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7811 (define_insn "*negdf2_v9"
7812 [(set (match_operand:DF 0 "register_operand" "=e")
7813 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7814 "TARGET_FPU && TARGET_V9"
7816 [(set_attr "type" "fpmove")
7817 (set_attr "length" "1")])
7819 (define_insn "negsf2"
7820 [(set (match_operand:SF 0 "register_operand" "=f")
7821 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7824 [(set_attr "type" "fpmove")
7825 (set_attr "length" "1")])
7827 (define_expand "abstf2"
7828 [(set (match_operand:TF 0 "register_operand" "")
7829 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7833 (define_insn "*abstf2_notv9"
7834 [(set (match_operand:TF 0 "register_operand" "=e,e")
7835 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7836 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7837 "TARGET_FPU && ! TARGET_V9"
7841 [(set_attr "type" "fpmove")
7842 (set_attr "length" "1,2")])
7845 [(set (match_operand:TF 0 "register_operand" "=e,e")
7846 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7850 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7851 [(set (match_dup 2) (abs:SF (match_dup 3)))
7852 (set (match_dup 4) (match_dup 5))
7853 (set (match_dup 6) (match_dup 7))]
7854 "if (GET_CODE (operands[0]) == SUBREG)
7855 operands[0] = alter_subreg (operands[0]);
7856 if (GET_CODE (operands[1]) == SUBREG)
7857 operands[1] = alter_subreg (operands[1]);
7858 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7859 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7860 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7861 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7862 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7863 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7865 (define_insn "*abstf2_hq_v9"
7866 [(set (match_operand:TF 0 "register_operand" "=e,e")
7867 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7868 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7872 [(set_attr "type" "fpmove")
7873 (set_attr "length" "1")])
7875 (define_insn "*abstf2_v9"
7876 [(set (match_operand:TF 0 "register_operand" "=e,e")
7877 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7878 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7882 [(set_attr "type" "fpmove")
7883 (set_attr "length" "1,2")])
7886 [(set (match_operand:TF 0 "register_operand" "=e,e")
7887 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7891 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7892 [(set (match_dup 2) (abs:DF (match_dup 3)))
7893 (set (match_dup 4) (match_dup 5))]
7894 "if (GET_CODE (operands[0]) == SUBREG)
7895 operands[0] = alter_subreg (operands[0]);
7896 if (GET_CODE (operands[1]) == SUBREG)
7897 operands[1] = alter_subreg (operands[1]);
7898 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7899 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7900 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7901 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7903 (define_expand "absdf2"
7904 [(set (match_operand:DF 0 "register_operand" "")
7905 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7909 (define_insn "*absdf2_notv9"
7910 [(set (match_operand:DF 0 "register_operand" "=e,e")
7911 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7912 "TARGET_FPU && ! TARGET_V9"
7916 [(set_attr "type" "fpmove")
7917 (set_attr "length" "1,2")])
7920 [(set (match_operand:DF 0 "register_operand" "=e,e")
7921 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7925 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7926 [(set (match_dup 2) (abs:SF (match_dup 3)))
7927 (set (match_dup 4) (match_dup 5))]
7928 "if (GET_CODE (operands[0]) == SUBREG)
7929 operands[0] = alter_subreg (operands[0]);
7930 if (GET_CODE (operands[1]) == SUBREG)
7931 operands[1] = alter_subreg (operands[1]);
7932 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7933 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7934 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7935 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7937 (define_insn "*absdf2_v9"
7938 [(set (match_operand:DF 0 "register_operand" "=e")
7939 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7940 "TARGET_FPU && TARGET_V9"
7942 [(set_attr "type" "fpmove")
7943 (set_attr "length" "1")])
7945 (define_insn "abssf2"
7946 [(set (match_operand:SF 0 "register_operand" "=f")
7947 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7950 [(set_attr "type" "fpmove")
7951 (set_attr "length" "1")])
7953 (define_expand "sqrttf2"
7954 [(set (match_operand:TF 0 "register_operand" "=e")
7955 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7956 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7959 if (! TARGET_HARD_QUAD)
7963 if (GET_CODE (operands[0]) != MEM)
7964 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7966 slot0 = operands[0];
7967 if (GET_CODE (operands[1]) != MEM)
7969 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7970 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7973 slot1 = operands[1];
7975 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7977 XEXP (slot0, 0), Pmode,
7978 XEXP (slot1, 0), Pmode);
7980 if (GET_CODE (operands[0]) != MEM)
7981 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7986 (define_insn "*sqrttf2_hq"
7987 [(set (match_operand:TF 0 "register_operand" "=e")
7988 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7989 "TARGET_FPU && TARGET_HARD_QUAD"
7991 [(set_attr "type" "fpsqrtd")
7992 (set_attr "length" "1")])
7994 (define_insn "sqrtdf2"
7995 [(set (match_operand:DF 0 "register_operand" "=e")
7996 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7999 [(set_attr "type" "fpsqrtd")
8000 (set_attr "length" "1")])
8002 (define_insn "sqrtsf2"
8003 [(set (match_operand:SF 0 "register_operand" "=f")
8004 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
8007 [(set_attr "type" "fpsqrts")
8008 (set_attr "length" "1")])
8010 ;;- arithmetic shift instructions
8012 (define_insn "ashlsi3"
8013 [(set (match_operand:SI 0 "register_operand" "=r")
8014 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8015 (match_operand:SI 2 "arith_operand" "rI")))]
8019 if (GET_CODE (operands[2]) == CONST_INT
8020 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8021 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8023 return \"sll\\t%1, %2, %0\";
8025 [(set_attr "type" "shift")
8026 (set_attr "length" "1")])
8028 ;; We special case multiplication by two, as add can be done
8029 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8030 (define_insn "*ashlsi3_const1"
8031 [(set (match_operand:SI 0 "register_operand" "=r")
8032 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8036 [(set_attr "type" "binary")
8037 (set_attr "length" "1")])
8039 (define_expand "ashldi3"
8040 [(set (match_operand:DI 0 "register_operand" "=r")
8041 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8042 (match_operand:SI 2 "arith_operand" "rI")))]
8043 "TARGET_ARCH64 || TARGET_V8PLUS"
8046 if (! TARGET_ARCH64)
8048 if (GET_CODE (operands[2]) == CONST_INT)
8050 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
8055 ;; We special case multiplication by two, as add can be done
8056 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8057 (define_insn "*ashldi3_const1"
8058 [(set (match_operand:DI 0 "register_operand" "=r")
8059 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8063 [(set_attr "type" "binary")
8064 (set_attr "length" "1")])
8066 (define_insn "*ashldi3_sp64"
8067 [(set (match_operand:DI 0 "register_operand" "=r")
8068 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8069 (match_operand:SI 2 "arith_operand" "rI")))]
8073 if (GET_CODE (operands[2]) == CONST_INT
8074 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8075 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8077 return \"sllx\\t%1, %2, %0\";
8079 [(set_attr "type" "shift")
8080 (set_attr "length" "1")])
8083 (define_insn "ashldi3_v8plus"
8084 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8085 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8086 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8087 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8089 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8090 [(set_attr "length" "5,5,6")])
8092 ;; Optimize (1LL<<x)-1
8093 ;; XXX this also needs to be fixed to handle equal subregs
8094 ;; XXX first before we could re-enable it.
8096 [(set (match_operand:DI 0 "register_operand" "=h")
8097 (plus:DI (ashift:DI (const_int 1)
8098 (match_operand:SI 2 "arith_operand" "rI"))
8100 "0 && TARGET_V8PLUS"
8103 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
8104 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
8105 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
8107 [(set_attr "length" "4")])
8109 (define_insn "*cmp_cc_ashift_1"
8110 [(set (reg:CC_NOOV 100)
8111 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8115 "addcc\\t%0, %0, %%g0"
8116 [(set_attr "type" "compare")
8117 (set_attr "length" "1")])
8119 (define_insn "*cmp_cc_set_ashift_1"
8120 [(set (reg:CC_NOOV 100)
8121 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8124 (set (match_operand:SI 0 "register_operand" "=r")
8125 (ashift:SI (match_dup 1) (const_int 1)))]
8127 "addcc\\t%1, %1, %0"
8128 [(set_attr "type" "compare")
8129 (set_attr "length" "1")])
8131 (define_insn "ashrsi3"
8132 [(set (match_operand:SI 0 "register_operand" "=r")
8133 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8134 (match_operand:SI 2 "arith_operand" "rI")))]
8138 if (GET_CODE (operands[2]) == CONST_INT
8139 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8140 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8142 return \"sra\\t%1, %2, %0\";
8144 [(set_attr "type" "shift")
8145 (set_attr "length" "1")])
8147 (define_insn "*ashrsi3_extend"
8148 [(set (match_operand:DI 0 "register_operand" "=r")
8149 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8150 (match_operand:SI 2 "arith_operand" "r"))))]
8153 [(set_attr "type" "shift")
8154 (set_attr "length" "1")])
8156 ;; This handles the case as above, but with constant shift instead of
8157 ;; register. Combiner "simplifies" it for us a little bit though.
8158 (define_insn "*ashrsi3_extend2"
8159 [(set (match_operand:DI 0 "register_operand" "=r")
8160 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8162 (match_operand:SI 2 "small_int_or_double" "n")))]
8164 && ((GET_CODE (operands[2]) == CONST_INT
8165 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8166 || (GET_CODE (operands[2]) == CONST_DOUBLE
8167 && !CONST_DOUBLE_HIGH (operands[2])
8168 && CONST_DOUBLE_LOW (operands[2]) >= 32
8169 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8172 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8174 return \"sra\\t%1, %2, %0\";
8176 [(set_attr "type" "shift")
8177 (set_attr "length" "1")])
8179 (define_expand "ashrdi3"
8180 [(set (match_operand:DI 0 "register_operand" "=r")
8181 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8182 (match_operand:SI 2 "arith_operand" "rI")))]
8183 "TARGET_ARCH64 || TARGET_V8PLUS"
8186 if (! TARGET_ARCH64)
8188 if (GET_CODE (operands[2]) == CONST_INT)
8189 FAIL; /* prefer generic code in this case */
8190 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8196 [(set (match_operand:DI 0 "register_operand" "=r")
8197 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8198 (match_operand:SI 2 "arith_operand" "rI")))]
8202 if (GET_CODE (operands[2]) == CONST_INT
8203 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8204 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8206 return \"srax\\t%1, %2, %0\";
8208 [(set_attr "type" "shift")
8209 (set_attr "length" "1")])
8212 (define_insn "ashrdi3_v8plus"
8213 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8214 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8215 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8216 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8218 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8219 [(set_attr "length" "5,5,6")])
8221 (define_insn "lshrsi3"
8222 [(set (match_operand:SI 0 "register_operand" "=r")
8223 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8224 (match_operand:SI 2 "arith_operand" "rI")))]
8228 if (GET_CODE (operands[2]) == CONST_INT
8229 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8230 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8232 return \"srl\\t%1, %2, %0\";
8234 [(set_attr "type" "shift")
8235 (set_attr "length" "1")])
8237 ;; This handles the case where
8238 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8239 ;; but combiner "simplifies" it for us.
8240 (define_insn "*lshrsi3_extend"
8241 [(set (match_operand:DI 0 "register_operand" "=r")
8242 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8243 (match_operand:SI 2 "arith_operand" "r")) 0)
8244 (match_operand 3 "" "")))]
8246 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8247 && CONST_DOUBLE_HIGH (operands[3]) == 0
8248 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8249 #if HOST_BITS_PER_WIDE_INT >= 64
8250 || (GET_CODE (operands[3]) == CONST_INT
8251 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
8255 [(set_attr "type" "shift")
8256 (set_attr "length" "1")])
8258 ;; This handles the case where
8259 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8260 ;; but combiner "simplifies" it for us.
8261 (define_insn "*lshrsi3_extend2"
8262 [(set (match_operand:DI 0 "register_operand" "=r")
8263 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8264 (match_operand 2 "small_int_or_double" "n")
8267 && ((GET_CODE (operands[2]) == CONST_INT
8268 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8269 || (GET_CODE (operands[2]) == CONST_DOUBLE
8270 && CONST_DOUBLE_HIGH (operands[2]) == 0
8271 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8274 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8276 return \"srl\\t%1, %2, %0\";
8278 [(set_attr "type" "shift")
8279 (set_attr "length" "1")])
8281 (define_expand "lshrdi3"
8282 [(set (match_operand:DI 0 "register_operand" "=r")
8283 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8284 (match_operand:SI 2 "arith_operand" "rI")))]
8285 "TARGET_ARCH64 || TARGET_V8PLUS"
8288 if (! TARGET_ARCH64)
8290 if (GET_CODE (operands[2]) == CONST_INT)
8292 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8298 [(set (match_operand:DI 0 "register_operand" "=r")
8299 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8300 (match_operand:SI 2 "arith_operand" "rI")))]
8304 if (GET_CODE (operands[2]) == CONST_INT
8305 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8306 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8308 return \"srlx\\t%1, %2, %0\";
8310 [(set_attr "type" "shift")
8311 (set_attr "length" "1")])
8314 (define_insn "lshrdi3_v8plus"
8315 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8316 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8317 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8318 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8320 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8321 [(set_attr "length" "5,5,6")])
8324 [(set (match_operand:SI 0 "register_operand" "=r")
8325 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8327 (match_operand:SI 2 "small_int_or_double" "n")))]
8329 && ((GET_CODE (operands[2]) == CONST_INT
8330 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8331 || (GET_CODE (operands[2]) == CONST_DOUBLE
8332 && !CONST_DOUBLE_HIGH (operands[2])
8333 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8336 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8338 return \"srax\\t%1, %2, %0\";
8340 [(set_attr "type" "shift")
8341 (set_attr "length" "1")])
8344 [(set (match_operand:SI 0 "register_operand" "=r")
8345 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8347 (match_operand:SI 2 "small_int_or_double" "n")))]
8349 && ((GET_CODE (operands[2]) == CONST_INT
8350 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8351 || (GET_CODE (operands[2]) == CONST_DOUBLE
8352 && !CONST_DOUBLE_HIGH (operands[2])
8353 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8356 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8358 return \"srlx\\t%1, %2, %0\";
8360 [(set_attr "type" "shift")
8361 (set_attr "length" "1")])
8364 [(set (match_operand:SI 0 "register_operand" "=r")
8365 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8366 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8367 (match_operand:SI 3 "small_int_or_double" "n")))]
8369 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8370 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8371 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8372 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8375 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8377 return \"srax\\t%1, %2, %0\";
8379 [(set_attr "type" "shift")
8380 (set_attr "length" "1")])
8383 [(set (match_operand:SI 0 "register_operand" "=r")
8384 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8385 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8386 (match_operand:SI 3 "small_int_or_double" "n")))]
8388 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8389 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8390 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8391 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8394 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8396 return \"srlx\\t%1, %2, %0\";
8398 [(set_attr "type" "shift")
8399 (set_attr "length" "1")])
8401 ;; Unconditional and other jump instructions
8402 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8403 ;; following insn is never executed. This saves us a nop. Dbx does not
8404 ;; handle such branches though, so we only use them when optimizing.
8406 [(set (pc) (label_ref (match_operand 0 "" "")))]
8410 /* TurboSparc is reported to have problems with
8413 i.e. an empty loop with the annul bit set. The workaround is to use
8417 if (! TARGET_V9 && flag_delayed_branch
8418 && (INSN_ADDRESSES (INSN_UID (operands[0]))
8419 == INSN_ADDRESSES (INSN_UID (insn))))
8420 return \"b\\t%l0%#\";
8422 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8424 [(set_attr "type" "uncond_branch")])
8426 (define_expand "tablejump"
8427 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8428 (use (label_ref (match_operand 1 "" "")))])]
8432 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8435 /* In pic mode, our address differences are against the base of the
8436 table. Add that base value back in; CSE ought to be able to combine
8437 the two address loads. */
8441 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8443 if (CASE_VECTOR_MODE != Pmode)
8444 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8445 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8446 operands[0] = memory_address (Pmode, tmp);
8450 (define_insn "*tablejump_sp32"
8451 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8452 (use (label_ref (match_operand 1 "" "")))]
8455 [(set_attr "type" "uncond_branch")])
8457 (define_insn "*tablejump_sp64"
8458 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8459 (use (label_ref (match_operand 1 "" "")))]
8462 [(set_attr "type" "uncond_branch")])
8464 ;; This pattern recognizes the "instruction" that appears in
8465 ;; a function call that wants a structure value,
8466 ;; to inform the called function if compiled with Sun CC.
8467 ;(define_insn "*unimp_insn"
8468 ; [(match_operand:SI 0 "immediate_operand" "")]
8469 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8471 ; [(set_attr "type" "marker")])
8473 ;;- jump to subroutine
8474 (define_expand "call"
8475 ;; Note that this expression is not used for generating RTL.
8476 ;; All the RTL is generated explicitly below.
8477 [(call (match_operand 0 "call_operand" "")
8478 (match_operand 3 "" "i"))]
8479 ;; operands[2] is next_arg_register
8480 ;; operands[3] is struct_value_size_rtx.
8484 rtx fn_rtx, nregs_rtx;
8486 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8489 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8491 /* This is really a PIC sequence. We want to represent
8492 it as a funny jump so its delay slots can be filled.
8494 ??? But if this really *is* a CALL, will not it clobber the
8495 call-clobbered registers? We lose this if it is a JUMP_INSN.
8496 Why cannot we have delay slots filled if it were a CALL? */
8498 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8503 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8505 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8511 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8512 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8516 fn_rtx = operands[0];
8518 /* Count the number of parameter registers being used by this call.
8519 if that argument is NULL, it means we are using them all, which
8520 means 6 on the sparc. */
8523 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8525 nregs_rtx = GEN_INT (6);
8527 nregs_rtx = const0_rtx;
8530 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8534 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8536 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8541 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8542 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8546 /* If this call wants a structure value,
8547 emit an unimp insn to let the called function know about this. */
8548 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8550 rtx insn = emit_insn (operands[3]);
8551 SCHED_GROUP_P (insn) = 1;
8558 ;; We can't use the same pattern for these two insns, because then registers
8559 ;; in the address may not be properly reloaded.
8561 (define_insn "*call_address_sp32"
8562 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8563 (match_operand 1 "" ""))
8564 (clobber (reg:SI 15))]
8565 ;;- Do not use operand 1 for most machines.
8568 [(set_attr "type" "call")])
8570 (define_insn "*call_symbolic_sp32"
8571 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8572 (match_operand 1 "" ""))
8573 (clobber (reg:SI 15))]
8574 ;;- Do not use operand 1 for most machines.
8577 [(set_attr "type" "call")])
8579 (define_insn "*call_address_sp64"
8580 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
8581 (match_operand 1 "" ""))
8582 (clobber (reg:DI 15))]
8583 ;;- Do not use operand 1 for most machines.
8586 [(set_attr "type" "call")])
8588 (define_insn "*call_symbolic_sp64"
8589 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
8590 (match_operand 1 "" ""))
8591 (clobber (reg:DI 15))]
8592 ;;- Do not use operand 1 for most machines.
8595 [(set_attr "type" "call")])
8597 ;; This is a call that wants a structure value.
8598 ;; There is no such critter for v9 (??? we may need one anyway).
8599 (define_insn "*call_address_struct_value_sp32"
8600 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8601 (match_operand 1 "" ""))
8602 (match_operand 2 "immediate_operand" "")
8603 (clobber (reg:SI 15))]
8604 ;;- Do not use operand 1 for most machines.
8605 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8606 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8607 [(set_attr "type" "call_no_delay_slot")])
8609 ;; This is a call that wants a structure value.
8610 ;; There is no such critter for v9 (??? we may need one anyway).
8611 (define_insn "*call_symbolic_struct_value_sp32"
8612 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8613 (match_operand 1 "" ""))
8614 (match_operand 2 "immediate_operand" "")
8615 (clobber (reg:SI 15))]
8616 ;;- Do not use operand 1 for most machines.
8617 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8618 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8619 [(set_attr "type" "call_no_delay_slot")])
8621 ;; This is a call that may want a structure value. This is used for
8623 (define_insn "*call_address_untyped_struct_value_sp32"
8624 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8625 (match_operand 1 "" ""))
8626 (match_operand 2 "immediate_operand" "")
8627 (clobber (reg:SI 15))]
8628 ;;- Do not use operand 1 for most machines.
8629 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8630 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8631 [(set_attr "type" "call_no_delay_slot")])
8633 ;; This is a call that wants a structure value.
8634 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8635 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8636 (match_operand 1 "" ""))
8637 (match_operand 2 "immediate_operand" "")
8638 (clobber (reg:SI 15))]
8639 ;;- Do not use operand 1 for most machines.
8640 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8641 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8642 [(set_attr "type" "call_no_delay_slot")])
8644 (define_expand "call_value"
8645 ;; Note that this expression is not used for generating RTL.
8646 ;; All the RTL is generated explicitly below.
8647 [(set (match_operand 0 "register_operand" "=rf")
8648 (call (match_operand:SI 1 "" "")
8649 (match_operand 4 "" "")))]
8650 ;; operand 2 is stack_size_rtx
8651 ;; operand 3 is next_arg_register
8655 rtx fn_rtx, nregs_rtx;
8658 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8661 fn_rtx = operands[1];
8665 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8667 nregs_rtx = GEN_INT (6);
8669 nregs_rtx = const0_rtx;
8673 gen_rtx_SET (VOIDmode, operands[0],
8674 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8675 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8677 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8682 (define_insn "*call_value_address_sp32"
8683 [(set (match_operand 0 "" "=rf")
8684 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8685 (match_operand 2 "" "")))
8686 (clobber (reg:SI 15))]
8687 ;;- Do not use operand 2 for most machines.
8690 [(set_attr "type" "call")])
8692 (define_insn "*call_value_symbolic_sp32"
8693 [(set (match_operand 0 "" "=rf")
8694 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8695 (match_operand 2 "" "")))
8696 (clobber (reg:SI 15))]
8697 ;;- Do not use operand 2 for most machines.
8700 [(set_attr "type" "call")])
8702 (define_insn "*call_value_address_sp64"
8703 [(set (match_operand 0 "" "")
8704 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
8705 (match_operand 2 "" "")))
8706 (clobber (reg:DI 15))]
8707 ;;- Do not use operand 2 for most machines.
8710 [(set_attr "type" "call")])
8712 (define_insn "*call_value_symbolic_sp64"
8713 [(set (match_operand 0 "" "")
8714 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
8715 (match_operand 2 "" "")))
8716 (clobber (reg:DI 15))]
8717 ;;- Do not use operand 2 for most machines.
8720 [(set_attr "type" "call")])
8722 (define_expand "untyped_call"
8723 [(parallel [(call (match_operand 0 "" "")
8725 (match_operand 1 "" "")
8726 (match_operand 2 "" "")])]
8732 /* Pass constm1 to indicate that it may expect a structure value, but
8733 we don't know what size it is. */
8734 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
8736 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8738 rtx set = XVECEXP (operands[2], 0, i);
8739 emit_move_insn (SET_DEST (set), SET_SRC (set));
8742 /* The optimizer does not know that the call sets the function value
8743 registers we stored in the result block. We avoid problems by
8744 claiming that all hard registers are used and clobbered at this
8746 emit_insn (gen_blockage ());
8752 (define_expand "sibcall"
8753 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8758 (define_insn "*sibcall_symbolic_sp32"
8759 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8760 (match_operand 1 "" ""))
8763 "* return output_sibcall(insn, operands[0]);"
8764 [(set_attr "type" "sibcall")])
8766 (define_insn "*sibcall_symbolic_sp64"
8767 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
8768 (match_operand 1 "" ""))
8771 "* return output_sibcall(insn, operands[0]);"
8772 [(set_attr "type" "sibcall")])
8774 (define_expand "sibcall_value"
8775 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8776 (call (match_operand:SI 1 "" "") (const_int 0)))
8781 (define_insn "*sibcall_value_symbolic_sp32"
8782 [(set (match_operand 0 "" "=rf")
8783 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8784 (match_operand 2 "" "")))
8787 "* return output_sibcall(insn, operands[1]);"
8788 [(set_attr "type" "sibcall")])
8790 (define_insn "*sibcall_value_symbolic_sp64"
8791 [(set (match_operand 0 "" "")
8792 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
8793 (match_operand 2 "" "")))
8796 "* return output_sibcall(insn, operands[1]);"
8797 [(set_attr "type" "sibcall")])
8799 (define_expand "sibcall_epilogue"
8804 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8805 ;; all of memory. This blocks insns from being moved across this point.
8807 (define_insn "blockage"
8808 [(unspec_volatile [(const_int 0)] 0)]
8811 [(set_attr "length" "0")])
8813 ;; Prepare to return any type including a structure value.
8815 (define_expand "untyped_return"
8816 [(match_operand:BLK 0 "memory_operand" "")
8817 (match_operand 1 "" "")]
8821 rtx valreg1 = gen_rtx_REG (DImode, 24);
8822 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8823 rtx result = operands[0];
8825 if (! TARGET_ARCH64)
8827 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8829 rtx value = gen_reg_rtx (SImode);
8831 /* Fetch the instruction where we will return to and see if it's an unimp
8832 instruction (the most significant 10 bits will be zero). If so,
8833 update the return address to skip the unimp instruction. */
8834 emit_move_insn (value,
8835 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8836 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8837 emit_insn (gen_update_return (rtnreg, value));
8840 /* Reload the function value registers. */
8841 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
8842 emit_move_insn (valreg2,
8843 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
8844 plus_constant (XEXP (result, 0), 8)));
8846 /* Put USE insns before the return. */
8847 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8848 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8850 /* Construct the return. */
8851 expand_null_return ();
8856 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8857 ;; and parts of the compiler don't want to believe that the add is needed.
8859 (define_insn "update_return"
8860 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8861 (match_operand:SI 1 "register_operand" "r")] 1)]
8863 "cmp %1,0\;be,a .+8\;add %0,4,%0"
8864 [(set_attr "type" "multi")])
8866 (define_insn "return"
8870 "* return output_return (operands);"
8871 [(set_attr "type" "return")])
8874 [(set (match_operand:SI 0 "register_operand" "=r")
8875 (match_operand:SI 1 "arith_operand" "rI"))
8877 (use (reg:SI 31))])]
8878 "sparc_return_peephole_ok (operands[0], operands[1])"
8879 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8885 [(set_attr "type" "ialu")
8886 (set_attr "length" "1")])
8888 (define_expand "indirect_jump"
8889 [(set (pc) (match_operand 0 "address_operand" "p"))]
8893 (define_insn "*branch_sp32"
8894 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8897 [(set_attr "type" "uncond_branch")])
8899 (define_insn "*branch_sp64"
8900 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8903 [(set_attr "type" "uncond_branch")])
8905 ;; ??? Doesn't work with -mflat.
8906 (define_expand "nonlocal_goto"
8907 [(match_operand:SI 0 "general_operand" "")
8908 (match_operand:SI 1 "general_operand" "")
8909 (match_operand:SI 2 "general_operand" "")
8910 (match_operand:SI 3 "" "")]
8915 rtx chain = operands[0];
8917 rtx fp = operands[1];
8918 rtx stack = operands[2];
8919 rtx lab = operands[3];
8922 /* Trap instruction to flush all the register windows. */
8923 emit_insn (gen_flush_register_windows ());
8925 /* Load the fp value for the containing fn into %fp. This is needed
8926 because STACK refers to %fp. Note that virtual register instantiation
8927 fails if the virtual %fp isn't set from a register. */
8928 if (GET_CODE (fp) != REG)
8929 fp = force_reg (Pmode, fp);
8930 emit_move_insn (virtual_stack_vars_rtx, fp);
8932 /* Find the containing function's current nonlocal goto handler,
8933 which will do any cleanups and then jump to the label. */
8934 labreg = gen_rtx_REG (Pmode, 8);
8935 emit_move_insn (labreg, lab);
8937 /* Restore %fp from stack pointer value for containing function.
8938 The restore insn that follows will move this to %sp,
8939 and reload the appropriate value into %fp. */
8940 emit_move_insn (frame_pointer_rtx, stack);
8942 /* USE of frame_pointer_rtx added for consistency; not clear if
8944 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8945 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8948 /* Return, restoring reg window and jumping to goto handler. */
8949 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8950 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8952 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
8957 /* Put in the static chain register the nonlocal label address. */
8958 emit_move_insn (static_chain_rtx, chain);
8961 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8962 emit_insn (gen_goto_handler_and_restore (labreg));
8967 ;; Special trap insn to flush register windows.
8968 (define_insn "flush_register_windows"
8969 [(unspec_volatile [(const_int 0)] 1)]
8971 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8972 [(set_attr "type" "misc")
8973 (set_attr "length" "1")])
8975 (define_insn "goto_handler_and_restore"
8976 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8977 "GET_MODE (operands[0]) == Pmode"
8978 "jmp\\t%0+0\\n\\trestore"
8979 [(set_attr "type" "misc")
8980 (set_attr "length" "2")])
8982 ;;(define_insn "goto_handler_and_restore_v9"
8983 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8984 ;; (match_operand:SI 1 "register_operand" "=r,r")
8985 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8986 ;; "TARGET_V9 && ! TARGET_ARCH64"
8988 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8989 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8990 ;; [(set_attr "type" "misc")
8991 ;; (set_attr "length" "2,3")])
8993 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8994 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8995 ;; (match_operand:DI 1 "register_operand" "=r,r")
8996 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8997 ;; "TARGET_V9 && TARGET_ARCH64"
8999 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
9000 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
9001 ;; [(set_attr "type" "misc")
9002 ;; (set_attr "length" "2,3")])
9004 ;; Pattern for use after a setjmp to store FP and the return register
9005 ;; into the stack area.
9007 (define_expand "setjmp"
9013 emit_insn (gen_setjmp_64 ());
9015 emit_insn (gen_setjmp_32 ());
9019 (define_expand "setjmp_32"
9020 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
9021 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
9024 { operands[0] = frame_pointer_rtx; }")
9026 (define_expand "setjmp_64"
9027 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9028 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9031 { operands[0] = frame_pointer_rtx; }")
9033 ;; Special pattern for the FLUSH instruction.
9035 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9036 ; of the define_insn otherwise missing a mode. We make "flush", aka
9037 ; gen_flush, the default one since sparc_initialize_trampoline uses
9038 ; it on SImode mem values.
9040 (define_insn "flush"
9041 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9043 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
9044 [(set_attr "type" "misc")])
9046 (define_insn "flushdi"
9047 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9049 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
9050 [(set_attr "type" "misc")])
9055 ;; The scan instruction searches from the most significant bit while ffs
9056 ;; searches from the least significant bit. The bit index and treatment of
9057 ;; zero also differ. It takes at least 7 instructions to get the proper
9058 ;; result. Here is an obvious 8 instruction sequence.
9061 (define_insn "ffssi2"
9062 [(set (match_operand:SI 0 "register_operand" "=&r")
9063 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9064 (clobber (match_scratch:SI 2 "=&r"))]
9065 "TARGET_SPARCLITE || TARGET_SPARCLET"
9068 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\";
9070 [(set_attr "type" "multi")
9071 (set_attr "length" "8")])
9073 ;; ??? This should be a define expand, so that the extra instruction have
9074 ;; a chance of being optimized away.
9076 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9077 ;; does, but no one uses that and we don't have a switch for it.
9079 ;(define_insn "ffsdi2"
9080 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9081 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9082 ; (clobber (match_scratch:DI 2 "=&r"))]
9084 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
9085 ; [(set_attr "type" "multi")
9086 ; (set_attr "length" "4")])
9090 ;; Peepholes go at the end.
9092 ;; Optimize consecutive loads or stores into ldd and std when possible.
9093 ;; The conditions in which we do this are very restricted and are
9094 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9097 [(set (match_operand:SI 0 "memory_operand" "")
9099 (set (match_operand:SI 1 "memory_operand" "")
9102 && ! MEM_VOLATILE_P (operands[0])
9103 && ! MEM_VOLATILE_P (operands[1])
9104 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
9108 [(set (match_operand:SI 0 "memory_operand" "")
9110 (set (match_operand:SI 1 "memory_operand" "")
9113 && ! MEM_VOLATILE_P (operands[0])
9114 && ! MEM_VOLATILE_P (operands[1])
9115 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
9119 [(set (match_operand:SI 0 "register_operand" "=rf")
9120 (match_operand:SI 1 "memory_operand" ""))
9121 (set (match_operand:SI 2 "register_operand" "=rf")
9122 (match_operand:SI 3 "memory_operand" ""))]
9123 "registers_ok_for_ldd_peep (operands[0], operands[2])
9124 && ! MEM_VOLATILE_P (operands[1])
9125 && ! MEM_VOLATILE_P (operands[3])
9126 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9130 [(set (match_operand:SI 0 "memory_operand" "")
9131 (match_operand:SI 1 "register_operand" "rf"))
9132 (set (match_operand:SI 2 "memory_operand" "")
9133 (match_operand:SI 3 "register_operand" "rf"))]
9134 "registers_ok_for_ldd_peep (operands[1], operands[3])
9135 && ! MEM_VOLATILE_P (operands[0])
9136 && ! MEM_VOLATILE_P (operands[2])
9137 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9141 [(set (match_operand:SF 0 "register_operand" "=fr")
9142 (match_operand:SF 1 "memory_operand" ""))
9143 (set (match_operand:SF 2 "register_operand" "=fr")
9144 (match_operand:SF 3 "memory_operand" ""))]
9145 "registers_ok_for_ldd_peep (operands[0], operands[2])
9146 && ! MEM_VOLATILE_P (operands[1])
9147 && ! MEM_VOLATILE_P (operands[3])
9148 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9152 [(set (match_operand:SF 0 "memory_operand" "")
9153 (match_operand:SF 1 "register_operand" "fr"))
9154 (set (match_operand:SF 2 "memory_operand" "")
9155 (match_operand:SF 3 "register_operand" "fr"))]
9156 "registers_ok_for_ldd_peep (operands[1], operands[3])
9157 && ! MEM_VOLATILE_P (operands[0])
9158 && ! MEM_VOLATILE_P (operands[2])
9159 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9163 [(set (match_operand:SI 0 "register_operand" "=rf")
9164 (match_operand:SI 1 "memory_operand" ""))
9165 (set (match_operand:SI 2 "register_operand" "=rf")
9166 (match_operand:SI 3 "memory_operand" ""))]
9167 "registers_ok_for_ldd_peep (operands[2], operands[0])
9168 && ! MEM_VOLATILE_P (operands[3])
9169 && ! MEM_VOLATILE_P (operands[1])
9170 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9174 [(set (match_operand:SI 0 "memory_operand" "")
9175 (match_operand:SI 1 "register_operand" "rf"))
9176 (set (match_operand:SI 2 "memory_operand" "")
9177 (match_operand:SI 3 "register_operand" "rf"))]
9178 "registers_ok_for_ldd_peep (operands[3], operands[1])
9179 && ! MEM_VOLATILE_P (operands[2])
9180 && ! MEM_VOLATILE_P (operands[0])
9181 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9185 [(set (match_operand:SF 0 "register_operand" "=fr")
9186 (match_operand:SF 1 "memory_operand" ""))
9187 (set (match_operand:SF 2 "register_operand" "=fr")
9188 (match_operand:SF 3 "memory_operand" ""))]
9189 "registers_ok_for_ldd_peep (operands[2], operands[0])
9190 && ! MEM_VOLATILE_P (operands[3])
9191 && ! MEM_VOLATILE_P (operands[1])
9192 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9196 [(set (match_operand:SF 0 "memory_operand" "")
9197 (match_operand:SF 1 "register_operand" "fr"))
9198 (set (match_operand:SF 2 "memory_operand" "")
9199 (match_operand:SF 3 "register_operand" "fr"))]
9200 "registers_ok_for_ldd_peep (operands[3], operands[1])
9201 && ! MEM_VOLATILE_P (operands[2])
9202 && ! MEM_VOLATILE_P (operands[0])
9203 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9206 ;; Optimize the case of following a reg-reg move with a test
9207 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9208 ;; This can result from a float to fix conversion.
9211 [(set (match_operand:SI 0 "register_operand" "=r")
9212 (match_operand:SI 1 "register_operand" "r"))
9214 (compare:CC (match_operand:SI 2 "register_operand" "r")
9216 "(rtx_equal_p (operands[2], operands[0])
9217 || rtx_equal_p (operands[2], operands[1]))
9218 && ! FP_REG_P (operands[0])
9219 && ! FP_REG_P (operands[1])"
9223 [(set (match_operand:DI 0 "register_operand" "=r")
9224 (match_operand:DI 1 "register_operand" "r"))
9226 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9229 && (rtx_equal_p (operands[2], operands[0])
9230 || rtx_equal_p (operands[2], operands[1]))
9231 && ! FP_REG_P (operands[0])
9232 && ! FP_REG_P (operands[1])"
9235 ;; Return peepholes. First the "normal" ones.
9236 ;; These are necessary to catch insns ending up in the epilogue delay list.
9238 (define_insn "*return_qi"
9239 [(set (match_operand:QI 0 "restore_operand" "")
9240 (match_operand:QI 1 "arith_operand" "rI"))
9245 if (! TARGET_ARCH64 && current_function_returns_struct)
9246 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9247 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9248 || IN_OR_GLOBAL_P (operands[1])))
9249 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9251 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9253 [(set_attr "type" "multi")])
9255 (define_insn "*return_hi"
9256 [(set (match_operand:HI 0 "restore_operand" "")
9257 (match_operand:HI 1 "arith_operand" "rI"))
9262 if (! TARGET_ARCH64 && current_function_returns_struct)
9263 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9264 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9265 || IN_OR_GLOBAL_P (operands[1])))
9266 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9268 return \"ret\;restore %%g0, %1, %Y0\";
9270 [(set_attr "type" "multi")])
9272 (define_insn "*return_si"
9273 [(set (match_operand:SI 0 "restore_operand" "")
9274 (match_operand:SI 1 "arith_operand" "rI"))
9279 if (! TARGET_ARCH64 && current_function_returns_struct)
9280 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9281 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9282 || IN_OR_GLOBAL_P (operands[1])))
9283 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9285 return \"ret\;restore %%g0, %1, %Y0\";
9287 [(set_attr "type" "multi")])
9289 ;; The following pattern is only generated by delayed-branch scheduling,
9290 ;; when the insn winds up in the epilogue. This can happen not only when
9291 ;; ! TARGET_FPU because we move complex types around by parts using
9293 (define_insn "*return_sf_no_fpu"
9294 [(set (match_operand:SF 0 "restore_operand" "=r")
9295 (match_operand:SF 1 "register_operand" "r"))
9300 if (! TARGET_ARCH64 && current_function_returns_struct)
9301 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9302 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9303 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9305 return \"ret\;restore %%g0, %1, %Y0\";
9307 [(set_attr "type" "multi")])
9309 (define_insn "*return_df_no_fpu"
9310 [(set (match_operand:DF 0 "restore_operand" "=r")
9311 (match_operand:DF 1 "register_operand" "r"))
9313 "! TARGET_EPILOGUE && TARGET_ARCH64"
9316 if (IN_OR_GLOBAL_P (operands[1]))
9317 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9319 return \"ret\;restore %%g0, %1, %Y0\";
9321 [(set_attr "type" "multi")])
9323 (define_insn "*return_addsi"
9324 [(set (match_operand:SI 0 "restore_operand" "")
9325 (plus:SI (match_operand:SI 1 "register_operand" "r")
9326 (match_operand:SI 2 "arith_operand" "rI")))
9331 if (! TARGET_ARCH64 && current_function_returns_struct)
9332 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9333 /* If operands are global or in registers, can use return */
9334 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9335 && (GET_CODE (operands[2]) == CONST_INT
9336 || IN_OR_GLOBAL_P (operands[2])))
9337 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9339 return \"ret\;restore %r1, %2, %Y0\";
9341 [(set_attr "type" "multi")])
9343 (define_insn "*return_losum_si"
9344 [(set (match_operand:SI 0 "restore_operand" "")
9345 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9346 (match_operand:SI 2 "immediate_operand" "in")))
9348 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9351 if (! TARGET_ARCH64 && current_function_returns_struct)
9352 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9353 /* If operands are global or in registers, can use return */
9354 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9355 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9357 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9359 [(set_attr "type" "multi")])
9361 (define_insn "*return_di"
9362 [(set (match_operand:DI 0 "restore_operand" "")
9363 (match_operand:DI 1 "arith_double_operand" "rHI"))
9365 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9366 "ret\;restore %%g0, %1, %Y0"
9367 [(set_attr "type" "multi")])
9369 (define_insn "*return_adddi"
9370 [(set (match_operand:DI 0 "restore_operand" "")
9371 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9372 (match_operand:DI 2 "arith_double_operand" "rHI")))
9374 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9375 "ret\;restore %r1, %2, %Y0"
9376 [(set_attr "type" "multi")])
9378 (define_insn "*return_losum_di"
9379 [(set (match_operand:DI 0 "restore_operand" "")
9380 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9381 (match_operand:DI 2 "immediate_operand" "in")))
9383 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9384 "ret\;restore %r1, %%lo(%a2), %Y0"
9385 [(set_attr "type" "multi")])
9387 ;; The following pattern is only generated by delayed-branch scheduling,
9388 ;; when the insn winds up in the epilogue.
9389 (define_insn "*return_sf"
9391 (match_operand:SF 0 "register_operand" "f"))
9394 "ret\;fmovs\\t%0, %%f0"
9395 [(set_attr "type" "multi")])
9397 ;; Now peepholes to do a call followed by a jump.
9400 [(parallel [(set (match_operand 0 "" "")
9401 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9402 (match_operand 2 "" "")))
9403 (clobber (reg:SI 15))])
9404 (set (pc) (label_ref (match_operand 3 "" "")))]
9405 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9406 && in_same_eh_region (insn, operands[3])
9407 && in_same_eh_region (insn, ins1)"
9408 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9411 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9412 (match_operand 1 "" ""))
9413 (clobber (reg:SI 15))])
9414 (set (pc) (label_ref (match_operand 2 "" "")))]
9415 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9416 && in_same_eh_region (insn, operands[2])
9417 && in_same_eh_region (insn, ins1)"
9418 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9421 [(parallel [(set (match_operand 0 "" "")
9422 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9423 (match_operand 2 "" "")))
9424 (clobber (reg:DI 15))])
9425 (set (pc) (label_ref (match_operand 3 "" "")))]
9427 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9428 && in_same_eh_region (insn, operands[3])
9429 && in_same_eh_region (insn, ins1)"
9430 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9433 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9434 (match_operand 1 "" ""))
9435 (clobber (reg:DI 15))])
9436 (set (pc) (label_ref (match_operand 2 "" "")))]
9438 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9439 && in_same_eh_region (insn, operands[2])
9440 && in_same_eh_region (insn, ins1)"
9441 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9443 ;; After a nonlocal goto, we need to restore the PIC register, but only
9444 ;; if we need it. So do nothing much here, but we'll check for this in
9447 ;; Make sure this unspec_volatile number agrees with finalize_pic.
9448 (define_insn "nonlocal_goto_receiver"
9449 [(unspec_volatile [(const_int 0)] 5)]
9452 [(set_attr "length" "0")])
9455 [(trap_if (const_int 1) (const_int 5))]
9458 [(set_attr "type" "misc")
9459 (set_attr "length" "1")])
9461 (define_expand "conditional_trap"
9462 [(trap_if (match_operator 0 "noov_compare_op"
9463 [(match_dup 2) (match_dup 3)])
9464 (match_operand:SI 1 "arith_operand" ""))]
9466 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9467 sparc_compare_op0, sparc_compare_op1);
9468 operands[3] = const0_rtx;")
9471 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9472 (match_operand:SI 1 "arith_operand" "rM"))]
9475 [(set_attr "type" "misc")
9476 (set_attr "length" "1")])
9479 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9480 (match_operand:SI 1 "arith_operand" "rM"))]
9483 [(set_attr "type" "misc")
9484 (set_attr "length" "1")])