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 [(set (match_dup 0) (const_int 0))
1192 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1198 (define_insn "*neg_snedi_zero"
1199 [(set (match_operand:DI 0 "register_operand" "=&r")
1200 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
1204 [(set_attr "type" "cmove")
1205 (set_attr "length" "2")])
1208 [(set (match_operand:DI 0 "register_operand" "")
1209 (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
1212 [(set (match_dup 0) (const_int 0))
1213 (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
1219 (define_insn "*snedi_zero_trunc"
1220 [(set (match_operand:SI 0 "register_operand" "=&r")
1221 (ne:SI (match_operand:DI 1 "register_operand" "r")
1225 [(set_attr "type" "cmove")
1226 (set_attr "length" "2")])
1229 [(set (match_operand:SI 0 "register_operand" "")
1230 (ne:SI (match_operand:DI 1 "register_operand" "")
1233 [(set (match_dup 0) (const_int 0))
1234 (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
1240 (define_insn "*seqsi_zero"
1241 [(set (match_operand:SI 0 "register_operand" "=r")
1242 (eq:SI (match_operand:SI 1 "register_operand" "r")
1244 (clobber (reg:CC 100))]
1247 [(set_attr "length" "2")])
1250 [(set (match_operand:SI 0 "register_operand" "")
1251 (eq:SI (match_operand:SI 1 "register_operand" "")
1253 (clobber (reg:CC 100))]
1255 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1257 (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
1260 (define_insn "*neg_seqsi_zero"
1261 [(set (match_operand:SI 0 "register_operand" "=r")
1262 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1264 (clobber (reg:CC 100))]
1267 [(set_attr "length" "2")])
1270 [(set (match_operand:SI 0 "register_operand" "")
1271 (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1273 (clobber (reg:CC 100))]
1275 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1277 (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1280 (define_insn "*seqsi_zero_extend"
1281 [(set (match_operand:DI 0 "register_operand" "=r")
1282 (eq:DI (match_operand:SI 1 "register_operand" "r")
1284 (clobber (reg:CC 100))]
1287 [(set_attr "type" "unary")
1288 (set_attr "length" "2")])
1291 [(set (match_operand:DI 0 "register_operand" "")
1292 (eq:DI (match_operand:SI 1 "register_operand" "")
1294 (clobber (reg:CC 100))]
1296 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1))
1298 (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1300 (ltu:SI (reg:CC_NOOV 100)
1304 (define_insn "*seqdi_zero"
1305 [(set (match_operand:DI 0 "register_operand" "=&r")
1306 (eq:DI (match_operand:DI 1 "register_operand" "r")
1310 [(set_attr "type" "cmove")
1311 (set_attr "length" "2")])
1314 [(set (match_operand:DI 0 "register_operand" "")
1315 (eq:DI (match_operand:DI 1 "register_operand" "")
1318 [(set (match_dup 0) (const_int 0))
1319 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1325 (define_insn "*neg_seqdi_zero"
1326 [(set (match_operand:DI 0 "register_operand" "=&r")
1327 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1331 [(set_attr "type" "cmove")
1332 (set_attr "length" "2")])
1335 [(set (match_operand:DI 0 "register_operand" "")
1336 (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
1339 [(set (match_dup 0) (const_int 0))
1340 (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1346 (define_insn "*seqdi_zero_trunc"
1347 [(set (match_operand:SI 0 "register_operand" "=&r")
1348 (eq:SI (match_operand:DI 1 "register_operand" "r")
1352 [(set_attr "type" "cmove")
1353 (set_attr "length" "2")])
1356 [(set (match_operand:SI 0 "register_operand" "")
1357 (eq:SI (match_operand:DI 1 "register_operand" "")
1360 [(set (match_dup 0) (const_int 0))
1361 (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1367 ;; We can also do (x + (i == 0)) and related, so put them in.
1368 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1371 (define_insn "*x_plus_i_ne_0"
1372 [(set (match_operand:SI 0 "register_operand" "=r")
1373 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1375 (match_operand:SI 2 "register_operand" "r")))
1376 (clobber (reg:CC 100))]
1379 [(set_attr "length" "2")])
1382 [(set (match_operand:SI 0 "register_operand" "")
1383 (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "")
1385 (match_operand:SI 2 "register_operand" "")))
1386 (clobber (reg:CC 100))]
1388 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1390 (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1394 (define_insn "*x_minus_i_ne_0"
1395 [(set (match_operand:SI 0 "register_operand" "=r")
1396 (minus:SI (match_operand:SI 2 "register_operand" "r")
1397 (ne:SI (match_operand:SI 1 "register_operand" "r")
1399 (clobber (reg:CC 100))]
1402 [(set_attr "length" "2")])
1405 [(set (match_operand:SI 0 "register_operand" "")
1406 (minus:SI (match_operand:SI 2 "register_operand" "")
1407 (ne:SI (match_operand:SI 1 "register_operand" "")
1409 (clobber (reg:CC 100))]
1411 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1413 (set (match_dup 0) (minus:SI (match_dup 2)
1414 (ltu:SI (reg:CC 100) (const_int 0))))]
1417 (define_insn "*x_plus_i_eq_0"
1418 [(set (match_operand:SI 0 "register_operand" "=r")
1419 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1421 (match_operand:SI 2 "register_operand" "r")))
1422 (clobber (reg:CC 100))]
1425 [(set_attr "length" "2")])
1428 [(set (match_operand:SI 0 "register_operand" "")
1429 (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "")
1431 (match_operand:SI 2 "register_operand" "")))
1432 (clobber (reg:CC 100))]
1434 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1436 (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1440 (define_insn "*x_minus_i_eq_0"
1441 [(set (match_operand:SI 0 "register_operand" "=r")
1442 (minus:SI (match_operand:SI 2 "register_operand" "r")
1443 (eq:SI (match_operand:SI 1 "register_operand" "r")
1445 (clobber (reg:CC 100))]
1448 [(set_attr "length" "2")])
1451 [(set (match_operand:SI 0 "register_operand" "")
1452 (minus:SI (match_operand:SI 2 "register_operand" "")
1453 (eq:SI (match_operand:SI 1 "register_operand" "")
1455 (clobber (reg:CC 100))]
1457 [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1459 (set (match_dup 0) (minus:SI (match_dup 2)
1460 (geu:SI (reg:CC 100) (const_int 0))))]
1463 ;; We can also do GEU and LTU directly, but these operate after a compare.
1464 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1467 (define_insn "*sltu_insn"
1468 [(set (match_operand:SI 0 "register_operand" "=r")
1469 (ltu:SI (reg:CC 100) (const_int 0)))]
1471 "addx\\t%%g0, 0, %0"
1472 [(set_attr "type" "misc")
1473 (set_attr "length" "1")])
1475 (define_insn "*neg_sltu_insn"
1476 [(set (match_operand:SI 0 "register_operand" "=r")
1477 (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1479 "subx\\t%%g0, 0, %0"
1480 [(set_attr "type" "misc")
1481 (set_attr "length" "1")])
1483 ;; ??? Combine should canonicalize these next two to the same pattern.
1484 (define_insn "*neg_sltu_minus_x"
1485 [(set (match_operand:SI 0 "register_operand" "=r")
1486 (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1487 (match_operand:SI 1 "arith_operand" "rI")))]
1489 "subx\\t%%g0, %1, %0"
1490 [(set_attr "type" "misc")
1491 (set_attr "length" "1")])
1493 (define_insn "*neg_sltu_plus_x"
1494 [(set (match_operand:SI 0 "register_operand" "=r")
1495 (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1496 (match_operand:SI 1 "arith_operand" "rI"))))]
1498 "subx\\t%%g0, %1, %0"
1499 [(set_attr "type" "misc")
1500 (set_attr "length" "1")])
1502 (define_insn "*sgeu_insn"
1503 [(set (match_operand:SI 0 "register_operand" "=r")
1504 (geu:SI (reg:CC 100) (const_int 0)))]
1506 "subx\\t%%g0, -1, %0"
1507 [(set_attr "type" "misc")
1508 (set_attr "length" "1")])
1510 (define_insn "*neg_sgeu_insn"
1511 [(set (match_operand:SI 0 "register_operand" "=r")
1512 (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1514 "addx\\t%%g0, -1, %0"
1515 [(set_attr "type" "misc")
1516 (set_attr "length" "1")])
1518 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1519 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1522 (define_insn "*sltu_plus_x"
1523 [(set (match_operand:SI 0 "register_operand" "=r")
1524 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1525 (match_operand:SI 1 "arith_operand" "rI")))]
1527 "addx\\t%%g0, %1, %0"
1528 [(set_attr "type" "misc")
1529 (set_attr "length" "1")])
1531 (define_insn "*sltu_plus_x_plus_y"
1532 [(set (match_operand:SI 0 "register_operand" "=r")
1533 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1534 (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1535 (match_operand:SI 2 "arith_operand" "rI"))))]
1538 [(set_attr "type" "misc")
1539 (set_attr "length" "1")])
1541 (define_insn "*x_minus_sltu"
1542 [(set (match_operand:SI 0 "register_operand" "=r")
1543 (minus:SI (match_operand:SI 1 "register_operand" "r")
1544 (ltu:SI (reg:CC 100) (const_int 0))))]
1547 [(set_attr "type" "misc")
1548 (set_attr "length" "1")])
1550 ;; ??? Combine should canonicalize these next two to the same pattern.
1551 (define_insn "*x_minus_y_minus_sltu"
1552 [(set (match_operand:SI 0 "register_operand" "=r")
1553 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1554 (match_operand:SI 2 "arith_operand" "rI"))
1555 (ltu:SI (reg:CC 100) (const_int 0))))]
1557 "subx\\t%r1, %2, %0"
1558 [(set_attr "type" "misc")
1559 (set_attr "length" "1")])
1561 (define_insn "*x_minus_sltu_plus_y"
1562 [(set (match_operand:SI 0 "register_operand" "=r")
1563 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1564 (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1565 (match_operand:SI 2 "arith_operand" "rI"))))]
1567 "subx\\t%r1, %2, %0"
1568 [(set_attr "type" "misc")
1569 (set_attr "length" "1")])
1571 (define_insn "*sgeu_plus_x"
1572 [(set (match_operand:SI 0 "register_operand" "=r")
1573 (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1574 (match_operand:SI 1 "register_operand" "r")))]
1577 [(set_attr "type" "misc")
1578 (set_attr "length" "1")])
1580 (define_insn "*x_minus_sgeu"
1581 [(set (match_operand:SI 0 "register_operand" "=r")
1582 (minus:SI (match_operand:SI 1 "register_operand" "r")
1583 (geu:SI (reg:CC 100) (const_int 0))))]
1586 [(set_attr "type" "misc")
1587 (set_attr "length" "1")])
1590 [(set (match_operand:SI 0 "register_operand" "=r")
1591 (match_operator:SI 2 "noov_compare_op"
1592 [(match_operand 1 "icc_or_fcc_reg_operand" "")
1594 ;; 32 bit LTU/GEU are better implemented using addx/subx
1595 "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1596 && (GET_MODE (operands[1]) == CCXmode
1597 || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1598 [(set (match_dup 0) (const_int 0))
1600 (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1606 ;; These control RTL generation for conditional jump insns
1608 ;; The quad-word fp compare library routines all return nonzero to indicate
1609 ;; true, which is different from the equivalent libgcc routines, so we must
1610 ;; handle them specially here.
1612 (define_expand "beq"
1614 (if_then_else (eq (match_dup 1) (const_int 0))
1615 (label_ref (match_operand 0 "" ""))
1620 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1621 && GET_CODE (sparc_compare_op0) == REG
1622 && GET_MODE (sparc_compare_op0) == DImode)
1624 emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1627 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1629 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1630 emit_jump_insn (gen_bne (operands[0]));
1633 operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1636 (define_expand "bne"
1638 (if_then_else (ne (match_dup 1) (const_int 0))
1639 (label_ref (match_operand 0 "" ""))
1644 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1645 && GET_CODE (sparc_compare_op0) == REG
1646 && GET_MODE (sparc_compare_op0) == DImode)
1648 emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1651 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1653 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1654 emit_jump_insn (gen_bne (operands[0]));
1657 operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1660 (define_expand "bgt"
1662 (if_then_else (gt (match_dup 1) (const_int 0))
1663 (label_ref (match_operand 0 "" ""))
1668 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1669 && GET_CODE (sparc_compare_op0) == REG
1670 && GET_MODE (sparc_compare_op0) == DImode)
1672 emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1675 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1677 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1678 emit_jump_insn (gen_bne (operands[0]));
1681 operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1684 (define_expand "bgtu"
1686 (if_then_else (gtu (match_dup 1) (const_int 0))
1687 (label_ref (match_operand 0 "" ""))
1691 { operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1694 (define_expand "blt"
1696 (if_then_else (lt (match_dup 1) (const_int 0))
1697 (label_ref (match_operand 0 "" ""))
1702 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1703 && GET_CODE (sparc_compare_op0) == REG
1704 && GET_MODE (sparc_compare_op0) == DImode)
1706 emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1709 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1711 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1712 emit_jump_insn (gen_bne (operands[0]));
1715 operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1718 (define_expand "bltu"
1720 (if_then_else (ltu (match_dup 1) (const_int 0))
1721 (label_ref (match_operand 0 "" ""))
1725 { operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1728 (define_expand "bge"
1730 (if_then_else (ge (match_dup 1) (const_int 0))
1731 (label_ref (match_operand 0 "" ""))
1736 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1737 && GET_CODE (sparc_compare_op0) == REG
1738 && GET_MODE (sparc_compare_op0) == DImode)
1740 emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1743 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1745 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1746 emit_jump_insn (gen_bne (operands[0]));
1749 operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1752 (define_expand "bgeu"
1754 (if_then_else (geu (match_dup 1) (const_int 0))
1755 (label_ref (match_operand 0 "" ""))
1759 { operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1762 (define_expand "ble"
1764 (if_then_else (le (match_dup 1) (const_int 0))
1765 (label_ref (match_operand 0 "" ""))
1770 if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1771 && GET_CODE (sparc_compare_op0) == REG
1772 && GET_MODE (sparc_compare_op0) == DImode)
1774 emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1777 else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1779 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1780 emit_jump_insn (gen_bne (operands[0]));
1783 operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1786 (define_expand "bleu"
1788 (if_then_else (leu (match_dup 1) (const_int 0))
1789 (label_ref (match_operand 0 "" ""))
1793 { operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1796 (define_expand "bunordered"
1798 (if_then_else (unordered (match_dup 1) (const_int 0))
1799 (label_ref (match_operand 0 "" ""))
1804 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1806 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1808 emit_jump_insn (gen_beq (operands[0]));
1811 operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1815 (define_expand "bordered"
1817 (if_then_else (ordered (match_dup 1) (const_int 0))
1818 (label_ref (match_operand 0 "" ""))
1823 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1825 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1826 emit_jump_insn (gen_bne (operands[0]));
1829 operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1833 (define_expand "bungt"
1835 (if_then_else (ungt (match_dup 1) (const_int 0))
1836 (label_ref (match_operand 0 "" ""))
1841 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1843 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1844 emit_jump_insn (gen_bgt (operands[0]));
1847 operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1850 (define_expand "bunlt"
1852 (if_then_else (unlt (match_dup 1) (const_int 0))
1853 (label_ref (match_operand 0 "" ""))
1858 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1860 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1861 emit_jump_insn (gen_bne (operands[0]));
1864 operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1867 (define_expand "buneq"
1869 (if_then_else (uneq (match_dup 1) (const_int 0))
1870 (label_ref (match_operand 0 "" ""))
1875 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1877 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1878 emit_jump_insn (gen_beq (operands[0]));
1881 operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1884 (define_expand "bunge"
1886 (if_then_else (unge (match_dup 1) (const_int 0))
1887 (label_ref (match_operand 0 "" ""))
1892 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1894 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1895 emit_jump_insn (gen_bne (operands[0]));
1898 operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1901 (define_expand "bunle"
1903 (if_then_else (unle (match_dup 1) (const_int 0))
1904 (label_ref (match_operand 0 "" ""))
1909 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1911 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1912 emit_jump_insn (gen_bne (operands[0]));
1915 operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1918 (define_expand "bltgt"
1920 (if_then_else (ltgt (match_dup 1) (const_int 0))
1921 (label_ref (match_operand 0 "" ""))
1926 if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1928 sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1929 emit_jump_insn (gen_bne (operands[0]));
1932 operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1935 ;; Now match both normal and inverted jump.
1937 ;; XXX fpcmp nop braindamage
1938 (define_insn "*normal_branch"
1940 (if_then_else (match_operator 0 "noov_compare_op"
1941 [(reg 100) (const_int 0)])
1942 (label_ref (match_operand 1 "" ""))
1947 return output_cbranch (operands[0], 1, 0,
1948 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1949 ! final_sequence, insn);
1951 [(set_attr "type" "branch")])
1953 ;; XXX fpcmp nop braindamage
1954 (define_insn "*inverted_branch"
1956 (if_then_else (match_operator 0 "noov_compare_op"
1957 [(reg 100) (const_int 0)])
1959 (label_ref (match_operand 1 "" ""))))]
1963 return output_cbranch (operands[0], 1, 1,
1964 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1965 ! final_sequence, insn);
1967 [(set_attr "type" "branch")])
1969 ;; XXX fpcmp nop braindamage
1970 (define_insn "*normal_fp_branch"
1972 (if_then_else (match_operator 1 "comparison_operator"
1973 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1975 (label_ref (match_operand 2 "" ""))
1980 return output_cbranch (operands[1], 2, 0,
1981 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1982 ! final_sequence, insn);
1984 [(set_attr "type" "branch")])
1986 ;; XXX fpcmp nop braindamage
1987 (define_insn "*inverted_fp_branch"
1989 (if_then_else (match_operator 1 "comparison_operator"
1990 [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1993 (label_ref (match_operand 2 "" ""))))]
1997 return output_cbranch (operands[1], 2, 1,
1998 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1999 ! final_sequence, insn);
2001 [(set_attr "type" "branch")])
2003 ;; XXX fpcmp nop braindamage
2004 (define_insn "*normal_fpe_branch"
2006 (if_then_else (match_operator 1 "comparison_operator"
2007 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2009 (label_ref (match_operand 2 "" ""))
2014 return output_cbranch (operands[1], 2, 0,
2015 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2016 ! final_sequence, insn);
2018 [(set_attr "type" "branch")])
2020 ;; XXX fpcmp nop braindamage
2021 (define_insn "*inverted_fpe_branch"
2023 (if_then_else (match_operator 1 "comparison_operator"
2024 [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
2027 (label_ref (match_operand 2 "" ""))))]
2031 return output_cbranch (operands[1], 2, 1,
2032 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2033 ! final_sequence, insn);
2035 [(set_attr "type" "branch")])
2037 ;; Sparc V9-specific jump insns. None of these are guaranteed to be
2038 ;; in the architecture.
2040 ;; There are no 32 bit brreg insns.
2043 (define_insn "*normal_int_branch_sp64"
2045 (if_then_else (match_operator 0 "v9_regcmp_op"
2046 [(match_operand:DI 1 "register_operand" "r")
2048 (label_ref (match_operand 2 "" ""))
2053 return output_v9branch (operands[0], 1, 2, 0,
2054 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2055 ! final_sequence, insn);
2057 [(set_attr "type" "branch")])
2060 (define_insn "*inverted_int_branch_sp64"
2062 (if_then_else (match_operator 0 "v9_regcmp_op"
2063 [(match_operand:DI 1 "register_operand" "r")
2066 (label_ref (match_operand 2 "" ""))))]
2070 return output_v9branch (operands[0], 1, 2, 1,
2071 final_sequence && INSN_ANNULLED_BRANCH_P (insn),
2072 ! final_sequence, insn);
2074 [(set_attr "type" "branch")])
2076 ;; Load program counter insns.
2078 (define_insn "get_pc"
2079 [(clobber (reg:SI 15))
2080 (set (match_operand 0 "register_operand" "=r")
2081 (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
2082 "flag_pic && REGNO (operands[0]) == 23"
2083 "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0"
2084 [(set_attr "length" "3")])
2086 ;; Currently unused...
2087 ;; (define_insn "get_pc_via_rdpc"
2088 ;; [(set (match_operand 0 "register_operand" "=r") (pc))]
2091 ;; [(set_attr "type" "move")])
2094 ;; Move instructions
2096 (define_expand "movqi"
2097 [(set (match_operand:QI 0 "general_operand" "")
2098 (match_operand:QI 1 "general_operand" ""))]
2102 /* Working with CONST_INTs is easier, so convert
2103 a double if needed. */
2104 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2106 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff);
2108 else if (GET_CODE (operands[1]) == CONST_INT)
2110 /* And further, we know for all QI cases that only the
2111 low byte is significant, which we can always process
2112 in a single insn. So mask it now. */
2113 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
2116 /* Handle sets of MEM first. */
2117 if (GET_CODE (operands[0]) == MEM)
2119 if (reg_or_0_operand (operands[1], QImode))
2122 if (! reload_in_progress)
2124 operands[0] = validize_mem (operands[0]);
2125 operands[1] = force_reg (QImode, operands[1]);
2129 /* Fixup PIC cases. */
2132 if (CONSTANT_P (operands[1])
2133 && pic_address_needs_scratch (operands[1]))
2134 operands[1] = legitimize_pic_address (operands[1], QImode, 0);
2136 if (symbolic_operand (operands[1], QImode))
2138 operands[1] = legitimize_pic_address (operands[1],
2140 (reload_in_progress ?
2147 /* All QI constants require only one insn, so proceed. */
2153 (define_insn "*movqi_insn"
2154 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
2155 (match_operand:QI 1 "input_operand" "rI,m,rJ"))]
2156 "(register_operand (operands[0], QImode)
2157 || reg_or_0_operand (operands[1], QImode))"
2162 [(set_attr "type" "move,load,store")
2163 (set_attr "length" "1")])
2165 (define_expand "movhi"
2166 [(set (match_operand:HI 0 "general_operand" "")
2167 (match_operand:HI 1 "general_operand" ""))]
2171 /* Working with CONST_INTs is easier, so convert
2172 a double if needed. */
2173 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2174 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2176 /* Handle sets of MEM first. */
2177 if (GET_CODE (operands[0]) == MEM)
2179 if (reg_or_0_operand (operands[1], HImode))
2182 if (! reload_in_progress)
2184 operands[0] = validize_mem (operands[0]);
2185 operands[1] = force_reg (HImode, operands[1]);
2189 /* Fixup PIC cases. */
2192 if (CONSTANT_P (operands[1])
2193 && pic_address_needs_scratch (operands[1]))
2194 operands[1] = legitimize_pic_address (operands[1], HImode, 0);
2196 if (symbolic_operand (operands[1], HImode))
2198 operands[1] = legitimize_pic_address (operands[1],
2200 (reload_in_progress ?
2207 /* This makes sure we will not get rematched due to splittage. */
2208 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
2210 else if (CONSTANT_P (operands[1])
2211 && GET_CODE (operands[1]) != HIGH
2212 && GET_CODE (operands[1]) != LO_SUM)
2214 sparc_emit_set_const32 (operands[0], operands[1]);
2221 (define_insn "*movhi_const64_special"
2222 [(set (match_operand:HI 0 "register_operand" "=r")
2223 (match_operand:HI 1 "const64_high_operand" ""))]
2225 "sethi\\t%%hi(%a1), %0"
2226 [(set_attr "type" "move")
2227 (set_attr "length" "1")])
2229 (define_insn "*movhi_insn"
2230 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2231 (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))]
2232 "(register_operand (operands[0], HImode)
2233 || reg_or_0_operand (operands[1], HImode))"
2236 sethi\\t%%hi(%a1), %0
2239 [(set_attr "type" "move,move,load,store")
2240 (set_attr "length" "1")])
2242 ;; We always work with constants here.
2243 (define_insn "*movhi_lo_sum"
2244 [(set (match_operand:HI 0 "register_operand" "=r")
2245 (ior:HI (match_operand:HI 1 "arith_operand" "%r")
2246 (match_operand:HI 2 "arith_operand" "I")))]
2249 [(set_attr "type" "ialu")
2250 (set_attr "length" "1")])
2252 (define_expand "movsi"
2253 [(set (match_operand:SI 0 "general_operand" "")
2254 (match_operand:SI 1 "general_operand" ""))]
2258 /* Working with CONST_INTs is easier, so convert
2259 a double if needed. */
2260 if (GET_CODE (operands[1]) == CONST_DOUBLE)
2261 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2263 /* Handle sets of MEM first. */
2264 if (GET_CODE (operands[0]) == MEM)
2266 if (reg_or_0_operand (operands[1], SImode))
2269 if (! reload_in_progress)
2271 operands[0] = validize_mem (operands[0]);
2272 operands[1] = force_reg (SImode, operands[1]);
2276 /* Fixup PIC cases. */
2279 if (CONSTANT_P (operands[1])
2280 && pic_address_needs_scratch (operands[1]))
2281 operands[1] = legitimize_pic_address (operands[1], SImode, 0);
2283 if (GET_CODE (operands[1]) == LABEL_REF)
2286 emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
2290 if (symbolic_operand (operands[1], SImode))
2292 operands[1] = legitimize_pic_address (operands[1],
2294 (reload_in_progress ?
2301 /* If we are trying to toss an integer constant into the
2302 FPU registers, force it into memory. */
2303 if (GET_CODE (operands[0]) == REG
2304 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2305 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2306 && CONSTANT_P (operands[1]))
2307 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2310 /* This makes sure we will not get rematched due to splittage. */
2311 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
2313 else if (CONSTANT_P (operands[1])
2314 && GET_CODE (operands[1]) != HIGH
2315 && GET_CODE (operands[1]) != LO_SUM)
2317 sparc_emit_set_const32 (operands[0], operands[1]);
2324 ;; This is needed to show CSE exactly which bits are set
2325 ;; in a 64-bit register by sethi instructions.
2326 (define_insn "*movsi_const64_special"
2327 [(set (match_operand:SI 0 "register_operand" "=r")
2328 (match_operand:SI 1 "const64_high_operand" ""))]
2330 "sethi\\t%%hi(%a1), %0"
2331 [(set_attr "type" "move")
2332 (set_attr "length" "1")])
2334 (define_insn "*movsi_insn"
2335 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
2336 (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))]
2337 "(register_operand (operands[0], SImode)
2338 || reg_or_0_operand (operands[1], SImode))"
2342 sethi\\t%%hi(%a1), %0
2349 [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove")
2350 (set_attr "length" "1")])
2352 (define_insn "*movsi_lo_sum"
2353 [(set (match_operand:SI 0 "register_operand" "=r")
2354 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2355 (match_operand:SI 2 "immediate_operand" "in")))]
2357 "or\\t%1, %%lo(%a2), %0"
2358 [(set_attr "type" "ialu")
2359 (set_attr "length" "1")])
2361 (define_insn "*movsi_high"
2362 [(set (match_operand:SI 0 "register_operand" "=r")
2363 (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
2365 "sethi\\t%%hi(%a1), %0"
2366 [(set_attr "type" "move")
2367 (set_attr "length" "1")])
2369 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
2370 ;; so that CSE won't optimize the address computation away.
2371 (define_insn "movsi_lo_sum_pic"
2372 [(set (match_operand:SI 0 "register_operand" "=r")
2373 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2374 (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))]
2376 "or\\t%1, %%lo(%a2), %0"
2377 [(set_attr "type" "ialu")
2378 (set_attr "length" "1")])
2380 (define_insn "movsi_high_pic"
2381 [(set (match_operand:SI 0 "register_operand" "=r")
2382 (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))]
2383 "flag_pic && check_pic (1)"
2384 "sethi\\t%%hi(%a1), %0"
2385 [(set_attr "type" "move")
2386 (set_attr "length" "1")])
2388 (define_expand "movsi_pic_label_ref"
2389 [(set (match_dup 3) (high:SI
2390 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2392 (set (match_dup 4) (lo_sum:SI (match_dup 3)
2393 (unspec:SI [(match_dup 1) (match_dup 2)] 5)))
2394 (set (match_operand:SI 0 "register_operand" "=r")
2395 (minus:SI (match_dup 5) (match_dup 4)))]
2399 current_function_uses_pic_offset_table = 1;
2400 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2403 operands[3] = operands[0];
2404 operands[4] = operands[0];
2408 operands[3] = gen_reg_rtx (SImode);
2409 operands[4] = gen_reg_rtx (SImode);
2411 operands[5] = pic_offset_table_rtx;
2414 (define_insn "*movsi_high_pic_label_ref"
2415 [(set (match_operand:SI 0 "register_operand" "=r")
2417 (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2418 (match_operand:SI 2 "" "")] 5)))]
2420 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2421 [(set_attr "type" "move")
2422 (set_attr "length" "1")])
2424 (define_insn "*movsi_lo_sum_pic_label_ref"
2425 [(set (match_operand:SI 0 "register_operand" "=r")
2426 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2427 (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2428 (match_operand:SI 3 "" "")] 5)))]
2430 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2431 [(set_attr "type" "ialu")
2432 (set_attr "length" "1")])
2434 (define_expand "movdi"
2435 [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2436 (match_operand:DI 1 "general_operand" ""))]
2440 /* Where possible, convert CONST_DOUBLE into a CONST_INT. */
2441 if (GET_CODE (operands[1]) == CONST_DOUBLE
2442 #if HOST_BITS_PER_WIDE_INT == 32
2443 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2444 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2445 || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2446 && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2449 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2451 /* Handle MEM cases first. */
2452 if (GET_CODE (operands[0]) == MEM)
2454 /* If it's a REG, we can always do it.
2455 The const zero case is more complex, on v9
2456 we can always perform it. */
2457 if (register_operand (operands[1], DImode)
2459 && (operands[1] == const0_rtx)))
2462 if (! reload_in_progress)
2464 operands[0] = validize_mem (operands[0]);
2465 operands[1] = force_reg (DImode, operands[1]);
2471 if (CONSTANT_P (operands[1])
2472 && pic_address_needs_scratch (operands[1]))
2473 operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2475 if (GET_CODE (operands[1]) == LABEL_REF)
2477 if (! TARGET_ARCH64)
2479 emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2483 if (symbolic_operand (operands[1], DImode))
2485 operands[1] = legitimize_pic_address (operands[1],
2487 (reload_in_progress ?
2494 /* If we are trying to toss an integer constant into the
2495 FPU registers, force it into memory. */
2496 if (GET_CODE (operands[0]) == REG
2497 && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2498 && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2499 && CONSTANT_P (operands[1]))
2500 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2503 /* This makes sure we will not get rematched due to splittage. */
2504 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2506 else if (TARGET_ARCH64
2507 && CONSTANT_P (operands[1])
2508 && GET_CODE (operands[1]) != HIGH
2509 && GET_CODE (operands[1]) != LO_SUM)
2511 sparc_emit_set_const64 (operands[0], operands[1]);
2519 ;; Be careful, fmovd does not exist when !arch64.
2520 ;; We match MEM moves directly when we have correct even
2521 ;; numbered registers, but fall into splits otherwise.
2522 ;; The constraint ordering here is really important to
2523 ;; avoid insane problems in reload, especially for patterns
2526 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2527 ;; (const_int -5016)))
2530 (define_insn "*movdi_insn_sp32"
2531 [(set (match_operand:DI 0 "nonimmediate_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f")
2532 (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))]
2534 (register_operand (operands[0], DImode)
2535 || register_operand (operands[1], DImode))"
2548 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*")
2549 (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")])
2551 ;; The following are generated by sparc_emit_set_const64
2552 (define_insn "*movdi_sp64_dbl"
2553 [(set (match_operand:DI 0 "register_operand" "=r")
2554 (match_operand:DI 1 "const64_operand" ""))]
2556 && HOST_BITS_PER_WIDE_INT != 64)"
2558 [(set_attr "type" "move")
2559 (set_attr "length" "1")])
2561 ;; This is needed to show CSE exactly which bits are set
2562 ;; in a 64-bit register by sethi instructions.
2563 (define_insn "*movdi_const64_special"
2564 [(set (match_operand:DI 0 "register_operand" "=r")
2565 (match_operand:DI 1 "const64_high_operand" ""))]
2567 "sethi\\t%%hi(%a1), %0"
2568 [(set_attr "type" "move")
2569 (set_attr "length" "1")])
2571 (define_insn "*movdi_insn_sp64_novis"
2572 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
2573 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
2574 "TARGET_ARCH64 && ! TARGET_VIS &&
2575 (register_operand (operands[0], DImode)
2576 || reg_or_0_operand (operands[1], DImode))"
2579 sethi\\t%%hi(%a1), %0
2586 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore")
2587 (set_attr "length" "1")])
2589 (define_insn "*movdi_insn_sp64_vis"
2590 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
2591 (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))]
2592 "TARGET_ARCH64 && TARGET_VIS &&
2593 (register_operand (operands[0], DImode)
2594 || reg_or_0_operand (operands[1], DImode))"
2597 sethi\\t%%hi(%a1), %0
2605 [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove")
2606 (set_attr "length" "1")])
2608 (define_expand "movdi_pic_label_ref"
2609 [(set (match_dup 3) (high:DI
2610 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2612 (set (match_dup 4) (lo_sum:DI (match_dup 3)
2613 (unspec:DI [(match_dup 1) (match_dup 2)] 5)))
2614 (set (match_operand:DI 0 "register_operand" "=r")
2615 (minus:DI (match_dup 5) (match_dup 4)))]
2616 "TARGET_ARCH64 && flag_pic"
2619 current_function_uses_pic_offset_table = 1;
2620 operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
2623 operands[3] = operands[0];
2624 operands[4] = operands[0];
2628 operands[3] = gen_reg_rtx (DImode);
2629 operands[4] = gen_reg_rtx (DImode);
2631 operands[5] = pic_offset_table_rtx;
2634 (define_insn "*movdi_high_pic_label_ref"
2635 [(set (match_operand:DI 0 "register_operand" "=r")
2637 (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2638 (match_operand:DI 2 "" "")] 5)))]
2639 "TARGET_ARCH64 && flag_pic"
2640 "sethi\\t%%hi(%a2-(%a1-.)), %0"
2641 [(set_attr "type" "move")
2642 (set_attr "length" "1")])
2644 (define_insn "*movdi_lo_sum_pic_label_ref"
2645 [(set (match_operand:DI 0 "register_operand" "=r")
2646 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2647 (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2648 (match_operand:DI 3 "" "")] 5)))]
2649 "TARGET_ARCH64 && flag_pic"
2650 "or\\t%1, %%lo(%a3-(%a2-.)), %0"
2651 [(set_attr "type" "ialu")
2652 (set_attr "length" "1")])
2654 ;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64
2655 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2657 (define_insn "movdi_lo_sum_pic"
2658 [(set (match_operand:DI 0 "register_operand" "=r")
2659 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2660 (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))]
2661 "TARGET_ARCH64 && flag_pic"
2662 "or\\t%1, %%lo(%a2), %0"
2663 [(set_attr "type" "ialu")
2664 (set_attr "length" "1")])
2666 (define_insn "movdi_high_pic"
2667 [(set (match_operand:DI 0 "register_operand" "=r")
2668 (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))]
2669 "TARGET_ARCH64 && flag_pic && check_pic (1)"
2670 "sethi\\t%%hi(%a1), %0"
2671 [(set_attr "type" "move")
2672 (set_attr "length" "1")])
2674 (define_insn "*sethi_di_medlow_embmedany_pic"
2675 [(set (match_operand:DI 0 "register_operand" "=r")
2676 (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2677 "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2678 "sethi\\t%%hi(%a1), %0"
2679 [(set_attr "type" "move")
2680 (set_attr "length" "1")])
2682 (define_insn "*sethi_di_medlow"
2683 [(set (match_operand:DI 0 "register_operand" "=r")
2684 (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2685 "TARGET_CM_MEDLOW && check_pic (1)"
2686 "sethi\\t%%hi(%a1), %0"
2687 [(set_attr "type" "move")
2688 (set_attr "length" "1")])
2690 (define_insn "*losum_di_medlow"
2691 [(set (match_operand:DI 0 "register_operand" "=r")
2692 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2693 (match_operand:DI 2 "symbolic_operand" "")))]
2695 "or\\t%1, %%lo(%a2), %0"
2696 [(set_attr "type" "ialu")
2697 (set_attr "length" "1")])
2699 (define_insn "seth44"
2700 [(set (match_operand:DI 0 "register_operand" "=r")
2701 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))]
2703 "sethi\\t%%h44(%a1), %0"
2704 [(set_attr "type" "move")
2705 (set_attr "length" "1")])
2707 (define_insn "setm44"
2708 [(set (match_operand:DI 0 "register_operand" "=r")
2709 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2710 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))]
2712 "or\\t%1, %%m44(%a2), %0"
2713 [(set_attr "type" "move")
2714 (set_attr "length" "1")])
2716 (define_insn "setl44"
2717 [(set (match_operand:DI 0 "register_operand" "=r")
2718 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2719 (match_operand:DI 2 "symbolic_operand" "")))]
2721 "or\\t%1, %%l44(%a2), %0"
2722 [(set_attr "type" "ialu")
2723 (set_attr "length" "1")])
2725 (define_insn "sethh"
2726 [(set (match_operand:DI 0 "register_operand" "=r")
2727 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))]
2729 "sethi\\t%%hh(%a1), %0"
2730 [(set_attr "type" "move")
2731 (set_attr "length" "1")])
2733 (define_insn "setlm"
2734 [(set (match_operand:DI 0 "register_operand" "=r")
2735 (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))]
2737 "sethi\\t%%lm(%a1), %0"
2738 [(set_attr "type" "move")
2739 (set_attr "length" "1")])
2741 (define_insn "sethm"
2742 [(set (match_operand:DI 0 "register_operand" "=r")
2743 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2744 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))]
2746 "or\\t%1, %%hm(%a2), %0"
2747 [(set_attr "type" "ialu")
2748 (set_attr "length" "1")])
2750 (define_insn "setlo"
2751 [(set (match_operand:DI 0 "register_operand" "=r")
2752 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2753 (match_operand:DI 2 "symbolic_operand" "")))]
2755 "or\\t%1, %%lo(%a2), %0"
2756 [(set_attr "type" "ialu")
2757 (set_attr "length" "1")])
2759 (define_insn "embmedany_sethi"
2760 [(set (match_operand:DI 0 "register_operand" "=r")
2761 (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))]
2762 "TARGET_CM_EMBMEDANY && check_pic (1)"
2763 "sethi\\t%%hi(%a1), %0"
2764 [(set_attr "type" "move")
2765 (set_attr "length" "1")])
2767 (define_insn "embmedany_losum"
2768 [(set (match_operand:DI 0 "register_operand" "=r")
2769 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2770 (match_operand:DI 2 "data_segment_operand" "")))]
2771 "TARGET_CM_EMBMEDANY"
2772 "add\\t%1, %%lo(%a2), %0"
2773 [(set_attr "type" "ialu")
2774 (set_attr "length" "1")])
2776 (define_insn "embmedany_brsum"
2777 [(set (match_operand:DI 0 "register_operand" "=r")
2778 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))]
2779 "TARGET_CM_EMBMEDANY"
2781 [(set_attr "length" "1")])
2783 (define_insn "embmedany_textuhi"
2784 [(set (match_operand:DI 0 "register_operand" "=r")
2785 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))]
2786 "TARGET_CM_EMBMEDANY && check_pic (1)"
2787 "sethi\\t%%uhi(%a1), %0"
2788 [(set_attr "type" "move")
2789 (set_attr "length" "1")])
2791 (define_insn "embmedany_texthi"
2792 [(set (match_operand:DI 0 "register_operand" "=r")
2793 (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))]
2794 "TARGET_CM_EMBMEDANY && check_pic (1)"
2795 "sethi\\t%%hi(%a1), %0"
2796 [(set_attr "type" "move")
2797 (set_attr "length" "1")])
2799 (define_insn "embmedany_textulo"
2800 [(set (match_operand:DI 0 "register_operand" "=r")
2801 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2802 (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))]
2803 "TARGET_CM_EMBMEDANY"
2804 "or\\t%1, %%ulo(%a2), %0"
2805 [(set_attr "type" "ialu")
2806 (set_attr "length" "1")])
2808 (define_insn "embmedany_textlo"
2809 [(set (match_operand:DI 0 "register_operand" "=r")
2810 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2811 (match_operand:DI 2 "text_segment_operand" "")))]
2812 "TARGET_CM_EMBMEDANY"
2813 "or\\t%1, %%lo(%a2), %0"
2814 [(set_attr "type" "ialu")
2815 (set_attr "length" "1")])
2817 ;; Now some patterns to help reload out a bit.
2818 (define_expand "reload_indi"
2819 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2820 (match_operand:DI 1 "immediate_operand" "")
2821 (match_operand:TI 2 "register_operand" "=&r")])]
2823 || TARGET_CM_EMBMEDANY)
2827 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2828 gen_rtx_REG (DImode, REGNO (operands[2])));
2832 (define_expand "reload_outdi"
2833 [(parallel [(match_operand:DI 0 "register_operand" "=r")
2834 (match_operand:DI 1 "immediate_operand" "")
2835 (match_operand:TI 2 "register_operand" "=&r")])]
2837 || TARGET_CM_EMBMEDANY)
2841 sparc_emit_set_symbolic_const64 (operands[0], operands[1],
2842 gen_rtx_REG (DImode, REGNO (operands[2])));
2846 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2848 [(set (match_operand:DI 0 "register_operand" "")
2849 (match_operand:DI 1 "const_int_operand" ""))]
2850 "! TARGET_ARCH64 && reload_completed"
2851 [(clobber (const_int 0))]
2854 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2855 (INTVAL (operands[1]) < 0) ?
2858 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2864 [(set (match_operand:DI 0 "register_operand" "")
2865 (match_operand:DI 1 "const_double_operand" ""))]
2866 "! TARGET_ARCH64 && reload_completed"
2867 [(clobber (const_int 0))]
2870 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2871 GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2873 /* Slick... but this trick loses if this subreg constant part
2874 can be done in one insn. */
2875 if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2876 && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1]))
2877 || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2879 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2880 gen_highpart (SImode, operands[0])));
2884 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2885 GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2891 [(set (match_operand:DI 0 "register_operand" "")
2892 (match_operand:DI 1 "register_operand" ""))]
2893 "! TARGET_ARCH64 && reload_completed"
2894 [(clobber (const_int 0))]
2897 rtx set_dest = operands[0];
2898 rtx set_src = operands[1];
2902 if (GET_CODE (set_dest) == SUBREG)
2903 set_dest = alter_subreg (set_dest);
2904 if (GET_CODE (set_src) == SUBREG)
2905 set_src = alter_subreg (set_src);
2907 dest1 = gen_highpart (SImode, set_dest);
2908 dest2 = gen_lowpart (SImode, set_dest);
2909 src1 = gen_highpart (SImode, set_src);
2910 src2 = gen_lowpart (SImode, set_src);
2912 /* Now emit using the real source and destination we found, swapping
2913 the order if we detect overlap. */
2914 if (reg_overlap_mentioned_p (dest1, src2))
2916 emit_insn (gen_movsi (dest2, src2));
2917 emit_insn (gen_movsi (dest1, src1));
2921 emit_insn (gen_movsi (dest1, src1));
2922 emit_insn (gen_movsi (dest2, src2));
2927 ;; Now handle the cases of memory moves from/to non-even
2928 ;; DI mode register pairs.
2930 [(set (match_operand:DI 0 "register_operand" "")
2931 (match_operand:DI 1 "memory_operand" ""))]
2934 && sparc_splitdi_legitimate (operands[0], operands[1]))"
2935 [(clobber (const_int 0))]
2938 rtx word0 = change_address (operands[1], SImode, NULL_RTX);
2939 rtx word1 = change_address (operands[1], SImode,
2940 plus_constant_for_output (XEXP (word0, 0), 4));
2941 rtx high_part = gen_highpart (SImode, operands[0]);
2942 rtx low_part = gen_lowpart (SImode, operands[0]);
2944 if (reg_overlap_mentioned_p (high_part, word1))
2946 emit_insn (gen_movsi (low_part, word1));
2947 emit_insn (gen_movsi (high_part, word0));
2951 emit_insn (gen_movsi (high_part, word0));
2952 emit_insn (gen_movsi (low_part, word1));
2958 [(set (match_operand:DI 0 "memory_operand" "")
2959 (match_operand:DI 1 "register_operand" ""))]
2962 && sparc_splitdi_legitimate (operands[1], operands[0]))"
2963 [(clobber (const_int 0))]
2966 rtx word0 = change_address (operands[0], SImode, NULL_RTX);
2967 rtx word1 = change_address (operands[0], SImode,
2968 plus_constant_for_output (XEXP (word0, 0), 4));
2969 rtx high_part = gen_highpart (SImode, operands[1]);
2970 rtx low_part = gen_lowpart (SImode, operands[1]);
2972 emit_insn (gen_movsi (word0, high_part));
2973 emit_insn (gen_movsi (word1, low_part));
2978 ;; Floating point move insns
2980 (define_insn "*movsf_insn_novis"
2981 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2982 (match_operand:SF 1 "input_operand" "f,G,Q,*rR,S,m,m,f,*rG"))]
2983 "(TARGET_FPU && ! TARGET_VIS)
2984 && (register_operand (operands[0], SFmode)
2985 || register_operand (operands[1], SFmode)
2986 || fp_zero_operand (operands[1], SFmode))"
2989 if (GET_CODE (operands[1]) == CONST_DOUBLE
2990 && (which_alternative == 2
2991 || which_alternative == 3
2992 || which_alternative == 4))
2997 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2998 REAL_VALUE_TO_TARGET_SINGLE (r, i);
2999 operands[1] = GEN_INT (i);
3002 switch (which_alternative)
3005 return \"fmovs\\t%1, %0\";
3007 return \"clr\\t%0\";
3009 return \"sethi\\t%%hi(%a1), %0\";
3011 return \"mov\\t%1, %0\";
3016 return \"ld\\t%1, %0\";
3019 return \"st\\t%r1, %0\";
3024 [(set_attr "type" "fpmove,move,move,move,*,load,fpload,fpstore,store")
3025 (set_attr "length" "1")])
3027 (define_insn "*movsf_insn_vis"
3028 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
3029 (match_operand:SF 1 "input_operand" "f,G,G,Q,*rR,S,m,m,f,*rG"))]
3030 "(TARGET_FPU && TARGET_VIS)
3031 && (register_operand (operands[0], SFmode)
3032 || register_operand (operands[1], SFmode)
3033 || fp_zero_operand (operands[1], SFmode))"
3036 if (GET_CODE (operands[1]) == CONST_DOUBLE
3037 && (which_alternative == 3
3038 || which_alternative == 4
3039 || which_alternative == 5))
3044 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3045 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3046 operands[1] = GEN_INT (i);
3049 switch (which_alternative)
3052 return \"fmovs\\t%1, %0\";
3054 return \"fzeros\\t%0\";
3056 return \"clr\\t%0\";
3058 return \"sethi\\t%%hi(%a1), %0\";
3060 return \"mov\\t%1, %0\";
3065 return \"ld\\t%1, %0\";
3068 return \"st\\t%r1, %0\";
3073 [(set_attr "type" "fpmove,fpmove,move,move,move,*,load,fpload,fpstore,store")
3074 (set_attr "length" "1")])
3076 (define_insn "*movsf_lo_sum"
3077 [(set (match_operand:SF 0 "register_operand" "")
3078 (lo_sum:SF (match_operand:SF 1 "register_operand" "")
3079 (match_operand:SF 2 "const_double_operand" "")))]
3080 "TARGET_FPU && fp_high_losum_p (operands[2])"
3086 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
3087 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3088 operands[2] = GEN_INT (i);
3089 return \"or\\t%1, %%lo(%a2), %0\";
3091 [(set_attr "type" "ialu")
3092 (set_attr "length" "1")])
3094 (define_insn "*movsf_high"
3095 [(set (match_operand:SF 0 "register_operand" "")
3096 (high:SF (match_operand:SF 1 "const_double_operand" "")))]
3097 "TARGET_FPU && fp_high_losum_p (operands[1])"
3103 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3104 REAL_VALUE_TO_TARGET_SINGLE (r, i);
3105 operands[1] = GEN_INT (i);
3106 return \"sethi\\t%%hi(%1), %0\";
3108 [(set_attr "type" "move")
3109 (set_attr "length" "1")])
3112 [(set (match_operand:SF 0 "register_operand" "")
3113 (match_operand:SF 1 "const_double_operand" ""))]
3115 && fp_high_losum_p (operands[1])
3116 && (GET_CODE (operands[0]) == REG
3117 && REGNO (operands[0]) < 32)"
3118 [(set (match_dup 0) (high:SF (match_dup 1)))
3119 (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
3121 ;; Exactly the same as above, except that all `f' cases are deleted.
3122 ;; This is necessary to prevent reload from ever trying to use a `f' reg
3125 (define_insn "*movsf_no_f_insn"
3126 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
3127 (match_operand:SF 1 "input_operand" "r,m,r"))]
3129 && (register_operand (operands[0], SFmode)
3130 || register_operand (operands[1], SFmode))"
3135 [(set_attr "type" "move,load,store")
3136 (set_attr "length" "1")])
3138 (define_expand "movsf"
3139 [(set (match_operand:SF 0 "general_operand" "")
3140 (match_operand:SF 1 "general_operand" ""))]
3144 /* Force SFmode constants into memory. */
3145 if (GET_CODE (operands[0]) == REG
3146 && CONSTANT_P (operands[1]))
3148 /* emit_group_store will send such bogosity to us when it is
3149 not storing directly into memory. So fix this up to avoid
3150 crashes in output_constant_pool. */
3151 if (operands [1] == const0_rtx)
3152 operands[1] = CONST0_RTX (SFmode);
3154 if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
3157 /* We are able to build any SF constant in integer registers
3158 with at most 2 instructions. */
3159 if (REGNO (operands[0]) < 32)
3162 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3166 /* Handle sets of MEM first. */
3167 if (GET_CODE (operands[0]) == MEM)
3169 if (register_operand (operands[1], SFmode)
3170 || fp_zero_operand (operands[1], SFmode))
3173 if (! reload_in_progress)
3175 operands[0] = validize_mem (operands[0]);
3176 operands[1] = force_reg (SFmode, operands[1]);
3180 /* Fixup PIC cases. */
3183 if (CONSTANT_P (operands[1])
3184 && pic_address_needs_scratch (operands[1]))
3185 operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
3187 if (symbolic_operand (operands[1], SFmode))
3189 operands[1] = legitimize_pic_address (operands[1],
3191 (reload_in_progress ?
3201 (define_expand "movdf"
3202 [(set (match_operand:DF 0 "general_operand" "")
3203 (match_operand:DF 1 "general_operand" ""))]
3207 /* Force DFmode constants into memory. */
3208 if (GET_CODE (operands[0]) == REG
3209 && CONSTANT_P (operands[1]))
3211 /* emit_group_store will send such bogosity to us when it is
3212 not storing directly into memory. So fix this up to avoid
3213 crashes in output_constant_pool. */
3214 if (operands [1] == const0_rtx)
3215 operands[1] = CONST0_RTX (DFmode);
3217 if ((TARGET_VIS || REGNO (operands[0]) < 32)
3218 && fp_zero_operand (operands[1], DFmode))
3221 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3225 /* Handle MEM cases first. */
3226 if (GET_CODE (operands[0]) == MEM)
3228 if (register_operand (operands[1], DFmode)
3229 || fp_zero_operand (operands[1], DFmode))
3232 if (! reload_in_progress)
3234 operands[0] = validize_mem (operands[0]);
3235 operands[1] = force_reg (DFmode, operands[1]);
3239 /* Fixup PIC cases. */
3242 if (CONSTANT_P (operands[1])
3243 && pic_address_needs_scratch (operands[1]))
3244 operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
3246 if (symbolic_operand (operands[1], DFmode))
3248 operands[1] = legitimize_pic_address (operands[1],
3250 (reload_in_progress ?
3260 ;; Be careful, fmovd does not exist when !v9.
3261 (define_insn "*movdf_insn_sp32"
3262 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
3263 (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
3266 && (register_operand (operands[0], DFmode)
3267 || register_operand (operands[1], DFmode)
3268 || fp_zero_operand (operands[1], DFmode))"
3280 [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
3281 (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
3283 (define_insn "*movdf_no_e_insn_sp32"
3284 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
3285 (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
3289 && (register_operand (operands[0], DFmode)
3290 || register_operand (operands[1], DFmode)
3291 || fp_zero_operand (operands[1], DFmode))"
3298 [(set_attr "type" "load,store,*,*,*")
3299 (set_attr "length" "1,1,2,2,2")])
3301 (define_insn "*movdf_no_e_insn_v9_sp32"
3302 [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
3303 (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
3307 && (register_operand (operands[0], DFmode)
3308 || register_operand (operands[1], DFmode)
3309 || fp_zero_operand (operands[1], DFmode))"
3316 [(set_attr "type" "load,store,store,*,*")
3317 (set_attr "length" "1,1,1,2,2")])
3319 ;; We have available v9 double floats but not 64-bit
3320 ;; integer registers and no VIS.
3321 (define_insn "*movdf_insn_v9only_novis"
3322 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
3323 (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
3328 && (register_operand (operands[0], DFmode)
3329 || register_operand (operands[1], DFmode)
3330 || fp_zero_operand (operands[1], DFmode))"
3341 [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
3342 (set_attr "length" "1,1,1,1,1,1,2,2,2")])
3344 ;; We have available v9 double floats but not 64-bit
3345 ;; integer registers but we have VIS.
3346 (define_insn "*movdf_insn_v9only_vis"
3347 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
3348 (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
3352 && (register_operand (operands[0], DFmode)
3353 || register_operand (operands[1], DFmode)
3354 || fp_zero_operand (operands[1], DFmode))"
3366 [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
3367 (set_attr "length" "1,1,1,1,1,1,1,2,2,2")])
3369 ;; We have available both v9 double floats and 64-bit
3370 ;; integer registers. No VIS though.
3371 (define_insn "*movdf_insn_sp64_novis"
3372 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
3373 (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
3377 && (register_operand (operands[0], DFmode)
3378 || register_operand (operands[1], DFmode)
3379 || fp_zero_operand (operands[1], DFmode))"
3388 [(set_attr "type" "fpmove,load,store,move,load,store,*")
3389 (set_attr "length" "1,1,1,1,1,1,2")])
3391 ;; We have available both v9 double floats and 64-bit
3392 ;; integer registers. And we have VIS.
3393 (define_insn "*movdf_insn_sp64_vis"
3394 [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
3395 (match_operand:DF 1 "input_operand" "G,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))"
3411 [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*")
3412 (set_attr "length" "1,1,1,1,1,1,1,2")])
3414 (define_insn "*movdf_no_e_insn_sp64"
3415 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3416 (match_operand:DF 1 "input_operand" "r,m,rG"))]
3419 && (register_operand (operands[0], DFmode)
3420 || register_operand (operands[1], DFmode)
3421 || fp_zero_operand (operands[1], DFmode))"
3426 [(set_attr "type" "move,load,store")
3427 (set_attr "length" "1")])
3430 [(set (match_operand:DF 0 "register_operand" "")
3431 (match_operand:DF 1 "const_double_operand" ""))]
3433 && (GET_CODE (operands[0]) == REG
3434 && REGNO (operands[0]) < 32)
3435 && ! fp_zero_operand(operands[1], DFmode)
3436 && reload_completed"
3437 [(clobber (const_int 0))]
3443 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3444 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3445 if (GET_CODE (operands[0]) == SUBREG)
3446 operands[0] = alter_subreg (operands[0]);
3447 operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3451 #if HOST_BITS_PER_WIDE_INT == 64
3454 val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3455 ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3456 emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3458 emit_insn (gen_movdi (operands[0],
3459 gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
3465 emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3468 /* Slick... but this trick loses if this subreg constant part
3469 can be done in one insn. */
3471 && !(SPARC_SETHI_P (l[0])
3472 || SPARC_SIMM13_P (l[0])))
3474 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3475 gen_highpart (SImode, operands[0])));
3479 emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3486 ;; Ok, now the splits to handle all the multi insn and
3487 ;; mis-aligned memory address cases.
3488 ;; In these splits please take note that we must be
3489 ;; careful when V9 but not ARCH64 because the integer
3490 ;; register DFmode cases must be handled.
3492 [(set (match_operand:DF 0 "register_operand" "")
3493 (match_operand:DF 1 "register_operand" ""))]
3496 && ((GET_CODE (operands[0]) == REG
3497 && REGNO (operands[0]) < 32)
3498 || (GET_CODE (operands[0]) == SUBREG
3499 && GET_CODE (SUBREG_REG (operands[0])) == REG
3500 && REGNO (SUBREG_REG (operands[0])) < 32))))
3501 && reload_completed"
3502 [(clobber (const_int 0))]
3505 rtx set_dest = operands[0];
3506 rtx set_src = operands[1];
3510 if (GET_CODE (set_dest) == SUBREG)
3511 set_dest = alter_subreg (set_dest);
3512 if (GET_CODE (set_src) == SUBREG)
3513 set_src = alter_subreg (set_src);
3515 dest1 = gen_highpart (SFmode, set_dest);
3516 dest2 = gen_lowpart (SFmode, set_dest);
3517 src1 = gen_highpart (SFmode, set_src);
3518 src2 = gen_lowpart (SFmode, set_src);
3520 /* Now emit using the real source and destination we found, swapping
3521 the order if we detect overlap. */
3522 if (reg_overlap_mentioned_p (dest1, src2))
3524 emit_insn (gen_movsf (dest2, src2));
3525 emit_insn (gen_movsf (dest1, src1));
3529 emit_insn (gen_movsf (dest1, src1));
3530 emit_insn (gen_movsf (dest2, src2));
3536 [(set (match_operand:DF 0 "register_operand" "")
3537 (match_operand:DF 1 "memory_operand" ""))]
3540 && (((REGNO (operands[0]) % 2) != 0)
3541 || ! mem_min_alignment (operands[1], 8))
3542 && offsettable_memref_p (operands[1])"
3543 [(clobber (const_int 0))]
3546 rtx word0 = change_address (operands[1], SFmode, NULL_RTX);
3547 rtx word1 = change_address (operands[1], SFmode,
3548 plus_constant_for_output (XEXP (word0, 0), 4));
3550 if (GET_CODE (operands[0]) == SUBREG)
3551 operands[0] = alter_subreg (operands[0]);
3553 if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3555 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3557 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3562 emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3564 emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3571 [(set (match_operand:DF 0 "memory_operand" "")
3572 (match_operand:DF 1 "register_operand" ""))]
3575 && (((REGNO (operands[1]) % 2) != 0)
3576 || ! mem_min_alignment (operands[0], 8))
3577 && offsettable_memref_p (operands[0])"
3578 [(clobber (const_int 0))]
3581 rtx word0 = change_address (operands[0], SFmode, NULL_RTX);
3582 rtx word1 = change_address (operands[0], SFmode,
3583 plus_constant_for_output (XEXP (word0, 0), 4));
3585 if (GET_CODE (operands[1]) == SUBREG)
3586 operands[1] = alter_subreg (operands[1]);
3587 emit_insn (gen_movsf (word0,
3588 gen_highpart (SFmode, operands[1])));
3589 emit_insn (gen_movsf (word1,
3590 gen_lowpart (SFmode, operands[1])));
3595 [(set (match_operand:DF 0 "memory_operand" "")
3596 (match_operand:DF 1 "fp_zero_operand" ""))]
3600 && ! mem_min_alignment (operands[0], 8)))
3601 && offsettable_memref_p (operands[0])"
3602 [(clobber (const_int 0))]
3607 dest1 = change_address (operands[0], SFmode, NULL_RTX);
3608 dest2 = change_address (operands[0], SFmode,
3609 plus_constant_for_output (XEXP (dest1, 0), 4));
3610 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3611 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3616 [(set (match_operand:DF 0 "register_operand" "")
3617 (match_operand:DF 1 "fp_zero_operand" ""))]
3620 && ((GET_CODE (operands[0]) == REG
3621 && REGNO (operands[0]) < 32)
3622 || (GET_CODE (operands[0]) == SUBREG
3623 && GET_CODE (SUBREG_REG (operands[0])) == REG
3624 && REGNO (SUBREG_REG (operands[0])) < 32))"
3625 [(clobber (const_int 0))]
3628 rtx set_dest = operands[0];
3631 if (GET_CODE (set_dest) == SUBREG)
3632 set_dest = alter_subreg (set_dest);
3633 dest1 = gen_highpart (SFmode, set_dest);
3634 dest2 = gen_lowpart (SFmode, set_dest);
3635 emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3636 emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3640 (define_expand "movtf"
3641 [(set (match_operand:TF 0 "general_operand" "")
3642 (match_operand:TF 1 "general_operand" ""))]
3646 /* Force TFmode constants into memory. */
3647 if (GET_CODE (operands[0]) == REG
3648 && CONSTANT_P (operands[1]))
3650 /* emit_group_store will send such bogosity to us when it is
3651 not storing directly into memory. So fix this up to avoid
3652 crashes in output_constant_pool. */
3653 if (operands [1] == const0_rtx)
3654 operands[1] = CONST0_RTX (TFmode);
3656 if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3659 operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3663 /* Handle MEM cases first, note that only v9 guarentees
3664 full 16-byte alignment for quads. */
3665 if (GET_CODE (operands[0]) == MEM)
3667 if (register_operand (operands[1], TFmode)
3668 || fp_zero_operand (operands[1], TFmode))
3671 if (! reload_in_progress)
3673 operands[0] = validize_mem (operands[0]);
3674 operands[1] = force_reg (TFmode, operands[1]);
3678 /* Fixup PIC cases. */
3681 if (CONSTANT_P (operands[1])
3682 && pic_address_needs_scratch (operands[1]))
3683 operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3685 if (symbolic_operand (operands[1], TFmode))
3687 operands[1] = legitimize_pic_address (operands[1],
3689 (reload_in_progress ?
3699 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3700 ;; we must split them all. :-(
3701 (define_insn "*movtf_insn_sp32"
3702 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,r,o")
3703 (match_operand:TF 1 "input_operand" "oe,Ge,o,U,ro,r"))]
3707 && (register_operand (operands[0], TFmode)
3708 || register_operand (operands[1], TFmode)
3709 || fp_zero_operand (operands[1], TFmode))"
3711 [(set_attr "length" "4")])
3713 (define_insn "*movtf_insn_vis_sp32"
3714 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,r,o")
3715 (match_operand:TF 1 "input_operand" "Goe,Ge,o,U,ro,r"))]
3719 && (register_operand (operands[0], TFmode)
3720 || register_operand (operands[1], TFmode)
3721 || fp_zero_operand (operands[1], TFmode))"
3723 [(set_attr "length" "4")])
3725 ;; Exactly the same as above, except that all `e' cases are deleted.
3726 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3729 (define_insn "*movtf_no_e_insn_sp32"
3730 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3731 (match_operand:TF 1 "input_operand" "G,o,U,ro,r"))]
3734 && (register_operand (operands[0], TFmode)
3735 || register_operand (operands[1], TFmode)
3736 || fp_zero_operand (operands[1], TFmode))"
3738 [(set_attr "length" "4")])
3740 ;; Now handle the float reg cases directly when arch64,
3741 ;; hard_quad, and proper reg number alignment are all true.
3742 (define_insn "*movtf_insn_hq_sp64"
3743 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r,o")
3744 (match_operand:TF 1 "input_operand" "e,m,e,G,ro,r"))]
3749 && (register_operand (operands[0], TFmode)
3750 || register_operand (operands[1], TFmode)
3751 || fp_zero_operand (operands[1], TFmode))"
3759 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3760 (set_attr "length" "1,1,1,2,2,2")])
3762 (define_insn "*movtf_insn_hq_vis_sp64"
3763 [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3764 (match_operand:TF 1 "input_operand" "e,m,e,G,ro,r"))]
3769 && (register_operand (operands[0], TFmode)
3770 || register_operand (operands[1], TFmode)
3771 || fp_zero_operand (operands[1], TFmode))"
3779 [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3780 (set_attr "length" "1,1,1,2,2,2")])
3782 ;; Now we allow the integer register cases even when
3783 ;; only arch64 is true.
3784 (define_insn "*movtf_insn_sp64"
3785 [(set (match_operand:TF 0 "nonimmediate_operand" "=o,e,r")
3786 (match_operand:TF 1 "input_operand" "Ge,oe,or"))]
3790 && ! TARGET_HARD_QUAD
3791 && (register_operand (operands[0], TFmode)
3792 || register_operand (operands[1], TFmode)
3793 || fp_zero_operand (operands[1], TFmode))"
3795 [(set_attr "length" "2")])
3797 (define_insn "*movtf_insn_vis_sp64"
3798 [(set (match_operand:TF 0 "nonimmediate_operand" "=eo,e,r")
3799 (match_operand:TF 1 "input_operand" "Ge,o,or"))]
3803 && ! TARGET_HARD_QUAD
3804 && (register_operand (operands[0], TFmode)
3805 || register_operand (operands[1], TFmode)
3806 || fp_zero_operand (operands[1], TFmode))"
3808 [(set_attr "length" "2")])
3810 (define_insn "*movtf_no_e_insn_sp64"
3811 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3812 (match_operand:TF 1 "input_operand" "or,rG"))]
3815 && (register_operand (operands[0], TFmode)
3816 || register_operand (operands[1], TFmode)
3817 || fp_zero_operand (operands[1], TFmode))"
3819 [(set_attr "length" "2")])
3821 ;; Now all the splits to handle multi-insn TF mode moves.
3823 [(set (match_operand:TF 0 "register_operand" "")
3824 (match_operand:TF 1 "register_operand" ""))]
3828 && ! TARGET_HARD_QUAD))"
3829 [(clobber (const_int 0))]
3832 rtx set_dest = operands[0];
3833 rtx set_src = operands[1];
3837 if (GET_CODE (set_dest) == SUBREG)
3838 set_dest = alter_subreg (set_dest);
3839 if (GET_CODE (set_src) == SUBREG)
3840 set_src = alter_subreg (set_src);
3842 dest1 = gen_df_reg (set_dest, 0);
3843 dest2 = gen_df_reg (set_dest, 1);
3844 src1 = gen_df_reg (set_src, 0);
3845 src2 = gen_df_reg (set_src, 1);
3847 /* Now emit using the real source and destination we found, swapping
3848 the order if we detect overlap. */
3849 if (reg_overlap_mentioned_p (dest1, src2))
3851 emit_insn (gen_movdf (dest2, src2));
3852 emit_insn (gen_movdf (dest1, src1));
3856 emit_insn (gen_movdf (dest1, src1));
3857 emit_insn (gen_movdf (dest2, src2));
3863 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3864 (match_operand:TF 1 "fp_zero_operand" ""))]
3866 [(clobber (const_int 0))]
3869 rtx set_dest = operands[0];
3872 switch (GET_CODE (set_dest))
3875 set_dest = alter_subreg (set_dest);
3878 dest1 = gen_df_reg (set_dest, 0);
3879 dest2 = gen_df_reg (set_dest, 1);
3882 dest1 = change_address (set_dest, DFmode, NULL_RTX);
3883 dest2 = change_address (set_dest, DFmode,
3884 plus_constant_for_output (XEXP (dest1, 0), 8));
3890 emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3891 emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3896 [(set (match_operand:TF 0 "register_operand" "")
3897 (match_operand:TF 1 "memory_operand" ""))]
3899 && offsettable_memref_p (operands[1]))"
3900 [(clobber (const_int 0))]
3903 rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
3904 rtx word1 = change_address (operands[1], DFmode,
3905 plus_constant_for_output (XEXP (word0, 0), 8));
3906 rtx set_dest, dest1, dest2;
3908 set_dest = operands[0];
3909 if (GET_CODE (set_dest) == SUBREG)
3910 set_dest = alter_subreg (set_dest);
3912 dest1 = gen_df_reg (set_dest, 0);
3913 dest2 = gen_df_reg (set_dest, 1);
3915 /* Now output, ordering such that we don't clobber any registers
3916 mentioned in the address. */
3917 if (reg_overlap_mentioned_p (dest1, word1))
3920 emit_insn (gen_movdf (dest2, word1));
3921 emit_insn (gen_movdf (dest1, word0));
3925 emit_insn (gen_movdf (dest1, word0));
3926 emit_insn (gen_movdf (dest2, word1));
3932 [(set (match_operand:TF 0 "memory_operand" "")
3933 (match_operand:TF 1 "register_operand" ""))]
3935 && offsettable_memref_p (operands[0]))"
3936 [(clobber (const_int 0))]
3939 rtx word1 = change_address (operands[0], DFmode, NULL_RTX);
3940 rtx word2 = change_address (operands[0], DFmode,
3941 plus_constant_for_output (XEXP (word1, 0), 8));
3944 set_src = operands[1];
3945 if (GET_CODE (set_src) == SUBREG)
3946 set_src = alter_subreg (set_src);
3948 emit_insn (gen_movdf (word1, gen_df_reg (set_src, 0)));
3949 emit_insn (gen_movdf (word2, gen_df_reg (set_src, 1)));
3953 ;; Sparc V9 conditional move instructions.
3955 ;; We can handle larger constants here for some flavors, but for now we keep
3956 ;; it simple and only allow those constants supported by all flavours.
3957 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3958 ;; 3 contains the constant if one is present, but we handle either for
3959 ;; generality (sparc.c puts a constant in operand 2).
3961 (define_expand "movqicc"
3962 [(set (match_operand:QI 0 "register_operand" "")
3963 (if_then_else:QI (match_operand 1 "comparison_operator" "")
3964 (match_operand:QI 2 "arith10_operand" "")
3965 (match_operand:QI 3 "arith10_operand" "")))]
3969 enum rtx_code code = GET_CODE (operands[1]);
3971 if (GET_MODE (sparc_compare_op0) == DImode
3975 if (sparc_compare_op1 == const0_rtx
3976 && GET_CODE (sparc_compare_op0) == REG
3977 && GET_MODE (sparc_compare_op0) == DImode
3978 && v9_regcmp_p (code))
3980 operands[1] = gen_rtx_fmt_ee (code, DImode,
3981 sparc_compare_op0, sparc_compare_op1);
3985 rtx cc_reg = gen_compare_reg (code,
3986 sparc_compare_op0, sparc_compare_op1);
3987 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3991 (define_expand "movhicc"
3992 [(set (match_operand:HI 0 "register_operand" "")
3993 (if_then_else:HI (match_operand 1 "comparison_operator" "")
3994 (match_operand:HI 2 "arith10_operand" "")
3995 (match_operand:HI 3 "arith10_operand" "")))]
3999 enum rtx_code code = GET_CODE (operands[1]);
4001 if (GET_MODE (sparc_compare_op0) == DImode
4005 if (sparc_compare_op1 == const0_rtx
4006 && GET_CODE (sparc_compare_op0) == REG
4007 && GET_MODE (sparc_compare_op0) == DImode
4008 && v9_regcmp_p (code))
4010 operands[1] = gen_rtx_fmt_ee (code, DImode,
4011 sparc_compare_op0, sparc_compare_op1);
4015 rtx cc_reg = gen_compare_reg (code,
4016 sparc_compare_op0, sparc_compare_op1);
4017 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4021 (define_expand "movsicc"
4022 [(set (match_operand:SI 0 "register_operand" "")
4023 (if_then_else:SI (match_operand 1 "comparison_operator" "")
4024 (match_operand:SI 2 "arith10_operand" "")
4025 (match_operand:SI 3 "arith10_operand" "")))]
4029 enum rtx_code code = GET_CODE (operands[1]);
4030 enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
4032 if (sparc_compare_op1 == const0_rtx
4033 && GET_CODE (sparc_compare_op0) == REG
4034 && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
4036 operands[1] = gen_rtx_fmt_ee (code, op0_mode,
4037 sparc_compare_op0, sparc_compare_op1);
4041 rtx cc_reg = gen_compare_reg (code,
4042 sparc_compare_op0, sparc_compare_op1);
4043 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4044 cc_reg, const0_rtx);
4048 (define_expand "movdicc"
4049 [(set (match_operand:DI 0 "register_operand" "")
4050 (if_then_else:DI (match_operand 1 "comparison_operator" "")
4051 (match_operand:DI 2 "arith10_double_operand" "")
4052 (match_operand:DI 3 "arith10_double_operand" "")))]
4056 enum rtx_code code = GET_CODE (operands[1]);
4058 if (sparc_compare_op1 == const0_rtx
4059 && GET_CODE (sparc_compare_op0) == REG
4060 && GET_MODE (sparc_compare_op0) == DImode
4061 && v9_regcmp_p (code))
4063 operands[1] = gen_rtx_fmt_ee (code, DImode,
4064 sparc_compare_op0, sparc_compare_op1);
4068 rtx cc_reg = gen_compare_reg (code,
4069 sparc_compare_op0, sparc_compare_op1);
4070 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
4071 cc_reg, const0_rtx);
4075 (define_expand "movsfcc"
4076 [(set (match_operand:SF 0 "register_operand" "")
4077 (if_then_else:SF (match_operand 1 "comparison_operator" "")
4078 (match_operand:SF 2 "register_operand" "")
4079 (match_operand:SF 3 "register_operand" "")))]
4080 "TARGET_V9 && TARGET_FPU"
4083 enum rtx_code code = GET_CODE (operands[1]);
4085 if (GET_MODE (sparc_compare_op0) == DImode
4089 if (sparc_compare_op1 == const0_rtx
4090 && GET_CODE (sparc_compare_op0) == REG
4091 && GET_MODE (sparc_compare_op0) == DImode
4092 && v9_regcmp_p (code))
4094 operands[1] = gen_rtx_fmt_ee (code, DImode,
4095 sparc_compare_op0, sparc_compare_op1);
4099 rtx cc_reg = gen_compare_reg (code,
4100 sparc_compare_op0, sparc_compare_op1);
4101 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4105 (define_expand "movdfcc"
4106 [(set (match_operand:DF 0 "register_operand" "")
4107 (if_then_else:DF (match_operand 1 "comparison_operator" "")
4108 (match_operand:DF 2 "register_operand" "")
4109 (match_operand:DF 3 "register_operand" "")))]
4110 "TARGET_V9 && TARGET_FPU"
4113 enum rtx_code code = GET_CODE (operands[1]);
4115 if (GET_MODE (sparc_compare_op0) == DImode
4119 if (sparc_compare_op1 == const0_rtx
4120 && GET_CODE (sparc_compare_op0) == REG
4121 && GET_MODE (sparc_compare_op0) == DImode
4122 && v9_regcmp_p (code))
4124 operands[1] = gen_rtx_fmt_ee (code, DImode,
4125 sparc_compare_op0, sparc_compare_op1);
4129 rtx cc_reg = gen_compare_reg (code,
4130 sparc_compare_op0, sparc_compare_op1);
4131 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4135 (define_expand "movtfcc"
4136 [(set (match_operand:TF 0 "register_operand" "")
4137 (if_then_else:TF (match_operand 1 "comparison_operator" "")
4138 (match_operand:TF 2 "register_operand" "")
4139 (match_operand:TF 3 "register_operand" "")))]
4140 "TARGET_V9 && TARGET_FPU"
4143 enum rtx_code code = GET_CODE (operands[1]);
4145 if (GET_MODE (sparc_compare_op0) == DImode
4149 if (sparc_compare_op1 == const0_rtx
4150 && GET_CODE (sparc_compare_op0) == REG
4151 && GET_MODE (sparc_compare_op0) == DImode
4152 && v9_regcmp_p (code))
4154 operands[1] = gen_rtx_fmt_ee (code, DImode,
4155 sparc_compare_op0, sparc_compare_op1);
4159 rtx cc_reg = gen_compare_reg (code,
4160 sparc_compare_op0, sparc_compare_op1);
4161 operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
4165 ;; Conditional move define_insns.
4167 (define_insn "*movqi_cc_sp64"
4168 [(set (match_operand:QI 0 "register_operand" "=r,r")
4169 (if_then_else:QI (match_operator 1 "comparison_operator"
4170 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4172 (match_operand:QI 3 "arith11_operand" "rL,0")
4173 (match_operand:QI 4 "arith11_operand" "0,rL")))]
4176 mov%C1\\t%x2, %3, %0
4177 mov%c1\\t%x2, %4, %0"
4178 [(set_attr "type" "cmove")
4179 (set_attr "length" "1")])
4181 (define_insn "*movhi_cc_sp64"
4182 [(set (match_operand:HI 0 "register_operand" "=r,r")
4183 (if_then_else:HI (match_operator 1 "comparison_operator"
4184 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4186 (match_operand:HI 3 "arith11_operand" "rL,0")
4187 (match_operand:HI 4 "arith11_operand" "0,rL")))]
4190 mov%C1\\t%x2, %3, %0
4191 mov%c1\\t%x2, %4, %0"
4192 [(set_attr "type" "cmove")
4193 (set_attr "length" "1")])
4195 (define_insn "*movsi_cc_sp64"
4196 [(set (match_operand:SI 0 "register_operand" "=r,r")
4197 (if_then_else:SI (match_operator 1 "comparison_operator"
4198 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4200 (match_operand:SI 3 "arith11_operand" "rL,0")
4201 (match_operand:SI 4 "arith11_operand" "0,rL")))]
4204 mov%C1\\t%x2, %3, %0
4205 mov%c1\\t%x2, %4, %0"
4206 [(set_attr "type" "cmove")
4207 (set_attr "length" "1")])
4209 ;; ??? The constraints of operands 3,4 need work.
4210 (define_insn "*movdi_cc_sp64"
4211 [(set (match_operand:DI 0 "register_operand" "=r,r")
4212 (if_then_else:DI (match_operator 1 "comparison_operator"
4213 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4215 (match_operand:DI 3 "arith11_double_operand" "rLH,0")
4216 (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
4219 mov%C1\\t%x2, %3, %0
4220 mov%c1\\t%x2, %4, %0"
4221 [(set_attr "type" "cmove")
4222 (set_attr "length" "1")])
4224 (define_insn "*movdi_cc_sp64_trunc"
4225 [(set (match_operand:SI 0 "register_operand" "=r,r")
4226 (if_then_else:SI (match_operator 1 "comparison_operator"
4227 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4229 (match_operand:SI 3 "arith11_double_operand" "rLH,0")
4230 (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
4233 mov%C1\\t%x2, %3, %0
4234 mov%c1\\t%x2, %4, %0"
4235 [(set_attr "type" "cmove")
4236 (set_attr "length" "1")])
4238 (define_insn "*movsf_cc_sp64"
4239 [(set (match_operand:SF 0 "register_operand" "=f,f")
4240 (if_then_else:SF (match_operator 1 "comparison_operator"
4241 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4243 (match_operand:SF 3 "register_operand" "f,0")
4244 (match_operand:SF 4 "register_operand" "0,f")))]
4245 "TARGET_V9 && TARGET_FPU"
4247 fmovs%C1\\t%x2, %3, %0
4248 fmovs%c1\\t%x2, %4, %0"
4249 [(set_attr "type" "fpcmove")
4250 (set_attr "length" "1")])
4252 (define_insn "movdf_cc_sp64"
4253 [(set (match_operand:DF 0 "register_operand" "=e,e")
4254 (if_then_else:DF (match_operator 1 "comparison_operator"
4255 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4257 (match_operand:DF 3 "register_operand" "e,0")
4258 (match_operand:DF 4 "register_operand" "0,e")))]
4259 "TARGET_V9 && TARGET_FPU"
4261 fmovd%C1\\t%x2, %3, %0
4262 fmovd%c1\\t%x2, %4, %0"
4263 [(set_attr "type" "fpcmove")
4264 (set_attr "length" "1")])
4266 (define_insn "*movtf_cc_hq_sp64"
4267 [(set (match_operand:TF 0 "register_operand" "=e,e")
4268 (if_then_else:TF (match_operator 1 "comparison_operator"
4269 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4271 (match_operand:TF 3 "register_operand" "e,0")
4272 (match_operand:TF 4 "register_operand" "0,e")))]
4273 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4275 fmovq%C1\\t%x2, %3, %0
4276 fmovq%c1\\t%x2, %4, %0"
4277 [(set_attr "type" "fpcmove")
4278 (set_attr "length" "1")])
4280 (define_insn "*movtf_cc_sp64"
4281 [(set (match_operand:TF 0 "register_operand" "=e,e")
4282 (if_then_else:TF (match_operator 1 "comparison_operator"
4283 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4285 (match_operand:TF 3 "register_operand" "e,0")
4286 (match_operand:TF 4 "register_operand" "0,e")))]
4287 "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4289 [(set_attr "type" "fpcmove")
4290 (set_attr "length" "2")])
4293 [(set (match_operand:TF 0 "register_operand" "=e,e")
4294 (if_then_else:TF (match_operator 1 "comparison_operator"
4295 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
4297 (match_operand:TF 3 "register_operand" "e,0")
4298 (match_operand:TF 4 "register_operand" "0,e")))]
4299 "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
4300 [(clobber (const_int 0))]
4303 rtx set_dest = operands[0];
4304 rtx set_srca = operands[3];
4305 rtx set_srcb = operands[4];
4306 int third = rtx_equal_p (set_dest, set_srca);
4308 rtx srca1, srca2, srcb1, srcb2;
4310 if (GET_CODE (set_dest) == SUBREG)
4311 set_dest = alter_subreg (set_dest);
4312 if (GET_CODE (set_srca) == SUBREG)
4313 set_srca = alter_subreg (set_srca);
4314 if (GET_CODE (set_srcb) == SUBREG)
4315 set_srcb = alter_subreg (set_srcb);
4317 dest1 = gen_df_reg (set_dest, 0);
4318 dest2 = gen_df_reg (set_dest, 1);
4319 srca1 = gen_df_reg (set_srca, 0);
4320 srca2 = gen_df_reg (set_srca, 1);
4321 srcb1 = gen_df_reg (set_srcb, 0);
4322 srcb2 = gen_df_reg (set_srcb, 1);
4324 /* Now emit using the real source and destination we found, swapping
4325 the order if we detect overlap. */
4326 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4327 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4329 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4330 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4334 emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4335 emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4340 (define_insn "*movqi_cc_reg_sp64"
4341 [(set (match_operand:QI 0 "register_operand" "=r,r")
4342 (if_then_else:QI (match_operator 1 "v9_regcmp_op"
4343 [(match_operand:DI 2 "register_operand" "r,r")
4345 (match_operand:QI 3 "arith10_operand" "rM,0")
4346 (match_operand:QI 4 "arith10_operand" "0,rM")))]
4349 movr%D1\\t%2, %r3, %0
4350 movr%d1\\t%2, %r4, %0"
4351 [(set_attr "type" "cmove")
4352 (set_attr "length" "1")])
4354 (define_insn "*movhi_cc_reg_sp64"
4355 [(set (match_operand:HI 0 "register_operand" "=r,r")
4356 (if_then_else:HI (match_operator 1 "v9_regcmp_op"
4357 [(match_operand:DI 2 "register_operand" "r,r")
4359 (match_operand:HI 3 "arith10_operand" "rM,0")
4360 (match_operand:HI 4 "arith10_operand" "0,rM")))]
4363 movr%D1\\t%2, %r3, %0
4364 movr%d1\\t%2, %r4, %0"
4365 [(set_attr "type" "cmove")
4366 (set_attr "length" "1")])
4368 (define_insn "*movsi_cc_reg_sp64"
4369 [(set (match_operand:SI 0 "register_operand" "=r,r")
4370 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4371 [(match_operand:DI 2 "register_operand" "r,r")
4373 (match_operand:SI 3 "arith10_operand" "rM,0")
4374 (match_operand:SI 4 "arith10_operand" "0,rM")))]
4377 movr%D1\\t%2, %r3, %0
4378 movr%d1\\t%2, %r4, %0"
4379 [(set_attr "type" "cmove")
4380 (set_attr "length" "1")])
4382 ;; ??? The constraints of operands 3,4 need work.
4383 (define_insn "*movdi_cc_reg_sp64"
4384 [(set (match_operand:DI 0 "register_operand" "=r,r")
4385 (if_then_else:DI (match_operator 1 "v9_regcmp_op"
4386 [(match_operand:DI 2 "register_operand" "r,r")
4388 (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4389 (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4392 movr%D1\\t%2, %r3, %0
4393 movr%d1\\t%2, %r4, %0"
4394 [(set_attr "type" "cmove")
4395 (set_attr "length" "1")])
4397 (define_insn "*movdi_cc_reg_sp64_trunc"
4398 [(set (match_operand:SI 0 "register_operand" "=r,r")
4399 (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4400 [(match_operand:DI 2 "register_operand" "r,r")
4402 (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4403 (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4406 movr%D1\\t%2, %r3, %0
4407 movr%d1\\t%2, %r4, %0"
4408 [(set_attr "type" "cmove")
4409 (set_attr "length" "1")])
4411 (define_insn "*movsf_cc_reg_sp64"
4412 [(set (match_operand:SF 0 "register_operand" "=f,f")
4413 (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4414 [(match_operand:DI 2 "register_operand" "r,r")
4416 (match_operand:SF 3 "register_operand" "f,0")
4417 (match_operand:SF 4 "register_operand" "0,f")))]
4418 "TARGET_ARCH64 && TARGET_FPU"
4420 fmovrs%D1\\t%2, %3, %0
4421 fmovrs%d1\\t%2, %4, %0"
4422 [(set_attr "type" "fpcmove")
4423 (set_attr "length" "1")])
4425 (define_insn "movdf_cc_reg_sp64"
4426 [(set (match_operand:DF 0 "register_operand" "=e,e")
4427 (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4428 [(match_operand:DI 2 "register_operand" "r,r")
4430 (match_operand:DF 3 "register_operand" "e,0")
4431 (match_operand:DF 4 "register_operand" "0,e")))]
4432 "TARGET_ARCH64 && TARGET_FPU"
4434 fmovrd%D1\\t%2, %3, %0
4435 fmovrd%d1\\t%2, %4, %0"
4436 [(set_attr "type" "fpcmove")
4437 (set_attr "length" "1")])
4439 (define_insn "*movtf_cc_reg_hq_sp64"
4440 [(set (match_operand:TF 0 "register_operand" "=e,e")
4441 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4442 [(match_operand:DI 2 "register_operand" "r,r")
4444 (match_operand:TF 3 "register_operand" "e,0")
4445 (match_operand:TF 4 "register_operand" "0,e")))]
4446 "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4448 fmovrq%D1\\t%2, %3, %0
4449 fmovrq%d1\\t%2, %4, %0"
4450 [(set_attr "type" "fpcmove")
4451 (set_attr "length" "1")])
4453 (define_insn "*movtf_cc_reg_sp64"
4454 [(set (match_operand:TF 0 "register_operand" "=e,e")
4455 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4456 [(match_operand:DI 2 "register_operand" "r,r")
4458 (match_operand:TF 3 "register_operand" "e,0")
4459 (match_operand:TF 4 "register_operand" "0,e")))]
4460 "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4462 [(set_attr "type" "fpcmove")
4463 (set_attr "length" "2")])
4466 [(set (match_operand:TF 0 "register_operand" "=e,e")
4467 (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4468 [(match_operand:DI 2 "register_operand" "r,r")
4470 (match_operand:TF 3 "register_operand" "e,0")
4471 (match_operand:TF 4 "register_operand" "0,e")))]
4472 "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4473 [(clobber (const_int 0))]
4476 rtx set_dest = operands[0];
4477 rtx set_srca = operands[3];
4478 rtx set_srcb = operands[4];
4479 int third = rtx_equal_p (set_dest, set_srca);
4481 rtx srca1, srca2, srcb1, srcb2;
4483 if (GET_CODE (set_dest) == SUBREG)
4484 set_dest = alter_subreg (set_dest);
4485 if (GET_CODE (set_srca) == SUBREG)
4486 set_srca = alter_subreg (set_srca);
4487 if (GET_CODE (set_srcb) == SUBREG)
4488 set_srcb = alter_subreg (set_srcb);
4490 dest1 = gen_df_reg (set_dest, 0);
4491 dest2 = gen_df_reg (set_dest, 1);
4492 srca1 = gen_df_reg (set_srca, 0);
4493 srca2 = gen_df_reg (set_srca, 1);
4494 srcb1 = gen_df_reg (set_srcb, 0);
4495 srcb2 = gen_df_reg (set_srcb, 1);
4497 /* Now emit using the real source and destination we found, swapping
4498 the order if we detect overlap. */
4499 if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4500 || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4502 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4503 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4507 emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4508 emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4514 ;;- zero extension instructions
4516 ;; These patterns originally accepted general_operands, however, slightly
4517 ;; better code is generated by only accepting register_operands, and then
4518 ;; letting combine generate the ldu[hb] insns.
4520 (define_expand "zero_extendhisi2"
4521 [(set (match_operand:SI 0 "register_operand" "")
4522 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4526 rtx temp = gen_reg_rtx (SImode);
4527 rtx shift_16 = GEN_INT (16);
4528 int op1_subword = 0;
4530 if (GET_CODE (operand1) == SUBREG)
4532 op1_subword = SUBREG_WORD (operand1);
4533 operand1 = XEXP (operand1, 0);
4536 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4538 emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4542 (define_insn "*zero_extendhisi2_insn"
4543 [(set (match_operand:SI 0 "register_operand" "=r")
4544 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4547 [(set_attr "type" "load")
4548 (set_attr "length" "1")])
4550 (define_expand "zero_extendqihi2"
4551 [(set (match_operand:HI 0 "register_operand" "")
4552 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4556 (define_insn "*zero_extendqihi2_insn"
4557 [(set (match_operand:HI 0 "register_operand" "=r,r")
4558 (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4559 "GET_CODE (operands[1]) != CONST_INT"
4563 [(set_attr "type" "unary,load")
4564 (set_attr "length" "1")])
4566 (define_expand "zero_extendqisi2"
4567 [(set (match_operand:SI 0 "register_operand" "")
4568 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4572 (define_insn "*zero_extendqisi2_insn"
4573 [(set (match_operand:SI 0 "register_operand" "=r,r")
4574 (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4575 "GET_CODE (operands[1]) != CONST_INT"
4579 [(set_attr "type" "unary,load")
4580 (set_attr "length" "1")])
4582 (define_expand "zero_extendqidi2"
4583 [(set (match_operand:DI 0 "register_operand" "")
4584 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4588 (define_insn "*zero_extendqidi2_insn"
4589 [(set (match_operand:DI 0 "register_operand" "=r,r")
4590 (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4591 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4595 [(set_attr "type" "unary,load")
4596 (set_attr "length" "1")])
4598 (define_expand "zero_extendhidi2"
4599 [(set (match_operand:DI 0 "register_operand" "")
4600 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4604 rtx temp = gen_reg_rtx (DImode);
4605 rtx shift_48 = GEN_INT (48);
4606 int op1_subword = 0;
4608 if (GET_CODE (operand1) == SUBREG)
4610 op1_subword = SUBREG_WORD (operand1);
4611 operand1 = XEXP (operand1, 0);
4614 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4616 emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4620 (define_insn "*zero_extendhidi2_insn"
4621 [(set (match_operand:DI 0 "register_operand" "=r")
4622 (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4625 [(set_attr "type" "load")
4626 (set_attr "length" "1")])
4629 ;; ??? Write truncdisi pattern using sra?
4631 (define_expand "zero_extendsidi2"
4632 [(set (match_operand:DI 0 "register_operand" "")
4633 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4637 (define_insn "*zero_extendsidi2_insn_sp64"
4638 [(set (match_operand:DI 0 "register_operand" "=r,r")
4639 (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4640 "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4644 [(set_attr "type" "shift,load")
4645 (set_attr "length" "1")])
4647 (define_insn "*zero_extendsidi2_insn_sp32"
4648 [(set (match_operand:DI 0 "register_operand" "=r")
4649 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4652 [(set_attr "type" "unary")
4653 (set_attr "length" "2")])
4656 [(set (match_operand:DI 0 "register_operand" "")
4657 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4658 "! TARGET_ARCH64 && reload_completed"
4659 [(set (match_dup 2) (match_dup 3))
4660 (set (match_dup 4) (match_dup 5))]
4665 if (GET_CODE (operands[0]) == SUBREG)
4666 operands[0] = alter_subreg (operands[0]);
4668 dest1 = gen_highpart (SImode, operands[0]);
4669 dest2 = gen_lowpart (SImode, operands[0]);
4671 /* Swap the order in case of overlap. */
4672 if (REGNO (dest1) == REGNO (operands[1]))
4674 operands[2] = dest2;
4675 operands[3] = operands[1];
4676 operands[4] = dest1;
4677 operands[5] = const0_rtx;
4681 operands[2] = dest1;
4682 operands[3] = const0_rtx;
4683 operands[4] = dest2;
4684 operands[5] = operands[1];
4688 ;; Simplify comparisons of extended values.
4690 (define_insn "*cmp_zero_extendqisi2"
4692 (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4695 "andcc\\t%0, 0xff, %%g0"
4696 [(set_attr "type" "compare")
4697 (set_attr "length" "1")])
4699 (define_insn "*cmp_zero_qi"
4701 (compare:CC (match_operand:QI 0 "register_operand" "r")
4704 "andcc\\t%0, 0xff, %%g0"
4705 [(set_attr "type" "compare")
4706 (set_attr "length" "1")])
4708 (define_insn "*cmp_zero_extendqisi2_set"
4710 (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4712 (set (match_operand:SI 0 "register_operand" "=r")
4713 (zero_extend:SI (match_dup 1)))]
4715 "andcc\\t%1, 0xff, %0"
4716 [(set_attr "type" "compare")
4717 (set_attr "length" "1")])
4719 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4721 (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4724 (set (match_operand:SI 0 "register_operand" "=r")
4725 (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4727 "andcc\\t%1, 0xff, %0"
4728 [(set_attr "type" "compare")
4729 (set_attr "length" "1")])
4731 (define_insn "*cmp_zero_extendqidi2"
4733 (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4736 "andcc\\t%0, 0xff, %%g0"
4737 [(set_attr "type" "compare")
4738 (set_attr "length" "1")])
4740 (define_insn "*cmp_zero_qi_sp64"
4742 (compare:CCX (match_operand:QI 0 "register_operand" "r")
4745 "andcc\\t%0, 0xff, %%g0"
4746 [(set_attr "type" "compare")
4747 (set_attr "length" "1")])
4749 (define_insn "*cmp_zero_extendqidi2_set"
4751 (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4753 (set (match_operand:DI 0 "register_operand" "=r")
4754 (zero_extend:DI (match_dup 1)))]
4756 "andcc\\t%1, 0xff, %0"
4757 [(set_attr "type" "compare")
4758 (set_attr "length" "1")])
4760 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4762 (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4765 (set (match_operand:DI 0 "register_operand" "=r")
4766 (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4768 "andcc\\t%1, 0xff, %0"
4769 [(set_attr "type" "compare")
4770 (set_attr "length" "1")])
4772 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4774 (define_insn "*cmp_siqi_trunc"
4776 (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0)
4779 "andcc\\t%0, 0xff, %%g0"
4780 [(set_attr "type" "compare")
4781 (set_attr "length" "1")])
4783 (define_insn "*cmp_siqi_trunc_set"
4785 (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0)
4787 (set (match_operand:QI 0 "register_operand" "=r")
4788 (subreg:QI (match_dup 1) 0))]
4790 "andcc\\t%1, 0xff, %0"
4791 [(set_attr "type" "compare")
4792 (set_attr "length" "1")])
4794 (define_insn "*cmp_diqi_trunc"
4796 (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0)
4799 "andcc\\t%0, 0xff, %%g0"
4800 [(set_attr "type" "compare")
4801 (set_attr "length" "1")])
4803 (define_insn "*cmp_diqi_trunc_set"
4805 (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0)
4807 (set (match_operand:QI 0 "register_operand" "=r")
4808 (subreg:QI (match_dup 1) 0))]
4810 "andcc\\t%1, 0xff, %0"
4811 [(set_attr "type" "compare")
4812 (set_attr "length" "1")])
4814 ;;- sign extension instructions
4816 ;; These patterns originally accepted general_operands, however, slightly
4817 ;; better code is generated by only accepting register_operands, and then
4818 ;; letting combine generate the lds[hb] insns.
4820 (define_expand "extendhisi2"
4821 [(set (match_operand:SI 0 "register_operand" "")
4822 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4826 rtx temp = gen_reg_rtx (SImode);
4827 rtx shift_16 = GEN_INT (16);
4828 int op1_subword = 0;
4830 if (GET_CODE (operand1) == SUBREG)
4832 op1_subword = SUBREG_WORD (operand1);
4833 operand1 = XEXP (operand1, 0);
4836 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4838 emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4842 (define_insn "*sign_extendhisi2_insn"
4843 [(set (match_operand:SI 0 "register_operand" "=r")
4844 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4847 [(set_attr "type" "sload")
4848 (set_attr "length" "1")])
4850 (define_expand "extendqihi2"
4851 [(set (match_operand:HI 0 "register_operand" "")
4852 (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4856 rtx temp = gen_reg_rtx (SImode);
4857 rtx shift_24 = GEN_INT (24);
4858 int op1_subword = 0;
4859 int op0_subword = 0;
4861 if (GET_CODE (operand1) == SUBREG)
4863 op1_subword = SUBREG_WORD (operand1);
4864 operand1 = XEXP (operand1, 0);
4866 if (GET_CODE (operand0) == SUBREG)
4868 op0_subword = SUBREG_WORD (operand0);
4869 operand0 = XEXP (operand0, 0);
4871 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4873 if (GET_MODE (operand0) != SImode)
4874 operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subword);
4875 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4879 (define_insn "*sign_extendqihi2_insn"
4880 [(set (match_operand:HI 0 "register_operand" "=r")
4881 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4884 [(set_attr "type" "sload")
4885 (set_attr "length" "1")])
4887 (define_expand "extendqisi2"
4888 [(set (match_operand:SI 0 "register_operand" "")
4889 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4893 rtx temp = gen_reg_rtx (SImode);
4894 rtx shift_24 = GEN_INT (24);
4895 int op1_subword = 0;
4897 if (GET_CODE (operand1) == SUBREG)
4899 op1_subword = SUBREG_WORD (operand1);
4900 operand1 = XEXP (operand1, 0);
4903 emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subword),
4905 emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4909 (define_insn "*sign_extendqisi2_insn"
4910 [(set (match_operand:SI 0 "register_operand" "=r")
4911 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4914 [(set_attr "type" "sload")
4915 (set_attr "length" "1")])
4917 (define_expand "extendqidi2"
4918 [(set (match_operand:DI 0 "register_operand" "")
4919 (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4923 rtx temp = gen_reg_rtx (DImode);
4924 rtx shift_56 = GEN_INT (56);
4925 int op1_subword = 0;
4927 if (GET_CODE (operand1) == SUBREG)
4929 op1_subword = SUBREG_WORD (operand1);
4930 operand1 = XEXP (operand1, 0);
4933 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4935 emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4939 (define_insn "*sign_extendqidi2_insn"
4940 [(set (match_operand:DI 0 "register_operand" "=r")
4941 (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4944 [(set_attr "type" "sload")
4945 (set_attr "length" "1")])
4947 (define_expand "extendhidi2"
4948 [(set (match_operand:DI 0 "register_operand" "")
4949 (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4953 rtx temp = gen_reg_rtx (DImode);
4954 rtx shift_48 = GEN_INT (48);
4955 int op1_subword = 0;
4957 if (GET_CODE (operand1) == SUBREG)
4959 op1_subword = SUBREG_WORD (operand1);
4960 operand1 = XEXP (operand1, 0);
4963 emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subword),
4965 emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4969 (define_insn "*sign_extendhidi2_insn"
4970 [(set (match_operand:DI 0 "register_operand" "=r")
4971 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4974 [(set_attr "type" "sload")
4975 (set_attr "length" "1")])
4977 (define_expand "extendsidi2"
4978 [(set (match_operand:DI 0 "register_operand" "")
4979 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4983 (define_insn "*sign_extendsidi2_insn"
4984 [(set (match_operand:DI 0 "register_operand" "=r,r")
4985 (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4990 [(set_attr "type" "shift,sload")
4991 (set_attr "length" "1")])
4993 ;; Special pattern for optimizing bit-field compares. This is needed
4994 ;; because combine uses this as a canonical form.
4996 (define_insn "*cmp_zero_extract"
4999 (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
5000 (match_operand:SI 1 "small_int_or_double" "n")
5001 (match_operand:SI 2 "small_int_or_double" "n"))
5003 "(GET_CODE (operands[2]) == CONST_INT
5004 && INTVAL (operands[2]) > 19)
5005 || (GET_CODE (operands[2]) == CONST_DOUBLE
5006 && CONST_DOUBLE_LOW (operands[2]) > 19)"
5009 int len = (GET_CODE (operands[1]) == CONST_INT
5010 ? INTVAL (operands[1])
5011 : CONST_DOUBLE_LOW (operands[1]));
5013 (GET_CODE (operands[2]) == CONST_INT
5014 ? INTVAL (operands[2])
5015 : CONST_DOUBLE_LOW (operands[2])) - len;
5016 HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
5018 operands[1] = GEN_INT (mask);
5019 return \"andcc\\t%0, %1, %%g0\";
5021 [(set_attr "type" "compare")
5022 (set_attr "length" "1")])
5024 (define_insn "*cmp_zero_extract_sp64"
5027 (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
5028 (match_operand:SI 1 "small_int_or_double" "n")
5029 (match_operand:SI 2 "small_int_or_double" "n"))
5032 && ((GET_CODE (operands[2]) == CONST_INT
5033 && INTVAL (operands[2]) > 51)
5034 || (GET_CODE (operands[2]) == CONST_DOUBLE
5035 && CONST_DOUBLE_LOW (operands[2]) > 51))"
5038 int len = (GET_CODE (operands[1]) == CONST_INT
5039 ? INTVAL (operands[1])
5040 : CONST_DOUBLE_LOW (operands[1]));
5042 (GET_CODE (operands[2]) == CONST_INT
5043 ? INTVAL (operands[2])
5044 : CONST_DOUBLE_LOW (operands[2])) - len;
5045 HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
5047 operands[1] = GEN_INT (mask);
5048 return \"andcc\\t%0, %1, %%g0\";
5050 [(set_attr "type" "compare")
5051 (set_attr "length" "1")])
5053 ;; Conversions between float, double and long double.
5055 (define_insn "extendsfdf2"
5056 [(set (match_operand:DF 0 "register_operand" "=e")
5058 (match_operand:SF 1 "register_operand" "f")))]
5061 [(set_attr "type" "fp")
5062 (set_attr "length" "1")])
5064 (define_expand "extendsftf2"
5065 [(set (match_operand:TF 0 "register_operand" "=e")
5067 (match_operand:SF 1 "register_operand" "f")))]
5068 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5071 if (! TARGET_HARD_QUAD)
5075 if (GET_CODE (operands[0]) != MEM)
5076 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5078 slot0 = operands[0];
5080 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_stoq\"), 0,
5082 XEXP (slot0, 0), Pmode,
5083 operands[1], SFmode);
5085 if (GET_CODE (operands[0]) != MEM)
5086 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5091 (define_insn "*extendsftf2_hq"
5092 [(set (match_operand:TF 0 "register_operand" "=e")
5094 (match_operand:SF 1 "register_operand" "f")))]
5095 "TARGET_FPU && TARGET_HARD_QUAD"
5097 [(set_attr "type" "fp")
5098 (set_attr "length" "1")])
5100 (define_expand "extenddftf2"
5101 [(set (match_operand:TF 0 "register_operand" "=e")
5103 (match_operand:DF 1 "register_operand" "e")))]
5104 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5107 if (! TARGET_HARD_QUAD)
5111 if (GET_CODE (operands[0]) != MEM)
5112 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5114 slot0 = operands[0];
5116 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_dtoq\"), 0,
5118 XEXP (slot0, 0), Pmode,
5119 operands[1], DFmode);
5121 if (GET_CODE (operands[0]) != MEM)
5122 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5127 (define_insn "*extenddftf2_hq"
5128 [(set (match_operand:TF 0 "register_operand" "=e")
5130 (match_operand:DF 1 "register_operand" "e")))]
5131 "TARGET_FPU && TARGET_HARD_QUAD"
5133 [(set_attr "type" "fp")
5134 (set_attr "length" "1")])
5136 (define_insn "truncdfsf2"
5137 [(set (match_operand:SF 0 "register_operand" "=f")
5139 (match_operand:DF 1 "register_operand" "e")))]
5142 [(set_attr "type" "fp")
5143 (set_attr "length" "1")])
5145 (define_expand "trunctfsf2"
5146 [(set (match_operand:SF 0 "register_operand" "=f")
5148 (match_operand:TF 1 "register_operand" "e")))]
5149 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5152 if (! TARGET_HARD_QUAD)
5156 if (GET_CODE (operands[1]) != MEM)
5158 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5159 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5162 slot0 = operands[1];
5164 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtos\"),
5165 operands[0], 0, SFmode, 1,
5166 XEXP (slot0, 0), Pmode);
5171 (define_insn "*trunctfsf2_hq"
5172 [(set (match_operand:SF 0 "register_operand" "=f")
5174 (match_operand:TF 1 "register_operand" "e")))]
5175 "TARGET_FPU && TARGET_HARD_QUAD"
5177 [(set_attr "type" "fp")
5178 (set_attr "length" "1")])
5180 (define_expand "trunctfdf2"
5181 [(set (match_operand:DF 0 "register_operand" "=f")
5183 (match_operand:TF 1 "register_operand" "e")))]
5184 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5187 if (! TARGET_HARD_QUAD)
5191 if (GET_CODE (operands[1]) != MEM)
5193 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5194 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5197 slot0 = operands[1];
5199 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtod\"),
5200 operands[0], 0, DFmode, 1,
5201 XEXP (slot0, 0), Pmode);
5206 (define_insn "*trunctfdf2_hq"
5207 [(set (match_operand:DF 0 "register_operand" "=e")
5209 (match_operand:TF 1 "register_operand" "e")))]
5210 "TARGET_FPU && TARGET_HARD_QUAD"
5212 [(set_attr "type" "fp")
5213 (set_attr "length" "1")])
5215 ;; Conversion between fixed point and floating point.
5217 (define_insn "floatsisf2"
5218 [(set (match_operand:SF 0 "register_operand" "=f")
5219 (float:SF (match_operand:SI 1 "register_operand" "f")))]
5222 [(set_attr "type" "fp")
5223 (set_attr "length" "1")])
5225 (define_insn "floatsidf2"
5226 [(set (match_operand:DF 0 "register_operand" "=e")
5227 (float:DF (match_operand:SI 1 "register_operand" "f")))]
5230 [(set_attr "type" "fp")
5231 (set_attr "length" "1")])
5233 (define_expand "floatsitf2"
5234 [(set (match_operand:TF 0 "register_operand" "=e")
5235 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5236 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5239 if (! TARGET_HARD_QUAD)
5243 if (GET_CODE (operands[1]) != MEM)
5244 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5246 slot0 = operands[1];
5248 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_itoq\"), 0,
5250 XEXP (slot0, 0), Pmode,
5251 operands[1], SImode);
5253 if (GET_CODE (operands[0]) != MEM)
5254 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5259 (define_insn "*floatsitf2_hq"
5260 [(set (match_operand:TF 0 "register_operand" "=e")
5261 (float:TF (match_operand:SI 1 "register_operand" "f")))]
5262 "TARGET_FPU && TARGET_HARD_QUAD"
5264 [(set_attr "type" "fp")
5265 (set_attr "length" "1")])
5267 (define_expand "floatunssitf2"
5268 [(set (match_operand:TF 0 "register_operand" "=e")
5269 (unsigned_float:TF (match_operand:SI 1 "register_operand" "e")))]
5270 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5275 if (GET_CODE (operands[1]) != MEM)
5276 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5278 slot0 = operands[1];
5280 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uitoq\"), 0,
5282 XEXP (slot0, 0), Pmode,
5283 operands[1], SImode);
5285 if (GET_CODE (operands[0]) != MEM)
5286 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5290 ;; Now the same for 64 bit sources.
5292 (define_insn "floatdisf2"
5293 [(set (match_operand:SF 0 "register_operand" "=f")
5294 (float:SF (match_operand:DI 1 "register_operand" "e")))]
5295 "TARGET_V9 && TARGET_FPU"
5297 [(set_attr "type" "fp")
5298 (set_attr "length" "1")])
5300 (define_insn "floatdidf2"
5301 [(set (match_operand:DF 0 "register_operand" "=e")
5302 (float:DF (match_operand:DI 1 "register_operand" "e")))]
5303 "TARGET_V9 && TARGET_FPU"
5305 [(set_attr "type" "fp")
5306 (set_attr "length" "1")])
5308 (define_expand "floatditf2"
5309 [(set (match_operand:TF 0 "register_operand" "=e")
5310 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5311 "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5314 if (! TARGET_HARD_QUAD)
5318 if (GET_CODE (operands[1]) != MEM)
5319 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5321 slot0 = operands[1];
5323 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_xtoq\"), 0,
5325 XEXP (slot0, 0), Pmode,
5326 operands[1], DImode);
5328 if (GET_CODE (operands[0]) != MEM)
5329 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5334 (define_insn "*floatditf2_hq"
5335 [(set (match_operand:TF 0 "register_operand" "=e")
5336 (float:TF (match_operand:DI 1 "register_operand" "e")))]
5337 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5339 [(set_attr "type" "fp")
5340 (set_attr "length" "1")])
5342 (define_expand "floatunsditf2"
5343 [(set (match_operand:TF 0 "register_operand" "=e")
5344 (unsigned_float:TF (match_operand:DI 1 "register_operand" "e")))]
5345 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5350 if (GET_CODE (operands[1]) != MEM)
5351 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5353 slot0 = operands[1];
5355 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_uxtoq\"), 0,
5357 XEXP (slot0, 0), Pmode,
5358 operands[1], DImode);
5360 if (GET_CODE (operands[0]) != MEM)
5361 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
5365 ;; Convert a float to an actual integer.
5366 ;; Truncation is performed as part of the conversion.
5368 (define_insn "fix_truncsfsi2"
5369 [(set (match_operand:SI 0 "register_operand" "=f")
5370 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5373 [(set_attr "type" "fp")
5374 (set_attr "length" "1")])
5376 (define_insn "fix_truncdfsi2"
5377 [(set (match_operand:SI 0 "register_operand" "=f")
5378 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5381 [(set_attr "type" "fp")
5382 (set_attr "length" "1")])
5384 (define_expand "fix_trunctfsi2"
5385 [(set (match_operand:SI 0 "register_operand" "=f")
5386 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5387 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5390 if (! TARGET_HARD_QUAD)
5394 if (GET_CODE (operands[1]) != MEM)
5396 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5397 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5400 slot0 = operands[1];
5402 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoi\"),
5403 operands[0], 0, SImode, 1,
5404 XEXP (slot0, 0), Pmode);
5409 (define_insn "*fix_trunctfsi2_hq"
5410 [(set (match_operand:SI 0 "register_operand" "=f")
5411 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5412 "TARGET_FPU && TARGET_HARD_QUAD"
5414 [(set_attr "type" "fp")
5415 (set_attr "length" "1")])
5417 (define_expand "fixuns_trunctfsi2"
5418 [(set (match_operand:SI 0 "register_operand" "=f")
5419 (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5420 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5425 if (GET_CODE (operands[1]) != MEM)
5427 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5428 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5431 slot0 = operands[1];
5433 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoui\"),
5434 operands[0], 0, SImode, 1,
5435 XEXP (slot0, 0), Pmode);
5439 ;; Now the same, for V9 targets
5441 (define_insn "fix_truncsfdi2"
5442 [(set (match_operand:DI 0 "register_operand" "=e")
5443 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
5444 "TARGET_V9 && TARGET_FPU"
5446 [(set_attr "type" "fp")
5447 (set_attr "length" "1")])
5449 (define_insn "fix_truncdfdi2"
5450 [(set (match_operand:DI 0 "register_operand" "=e")
5451 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
5452 "TARGET_V9 && TARGET_FPU"
5454 [(set_attr "type" "fp")
5455 (set_attr "length" "1")])
5457 (define_expand "fix_trunctfdi2"
5458 [(set (match_operand:DI 0 "register_operand" "=e")
5459 (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5460 "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5463 if (! TARGET_HARD_QUAD)
5467 if (GET_CODE (operands[1]) != MEM)
5469 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5470 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5473 slot0 = operands[1];
5475 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtox\"),
5476 operands[0], 0, DImode, 1,
5477 XEXP (slot0, 0), Pmode);
5482 (define_insn "*fix_trunctfdi2_hq"
5483 [(set (match_operand:DI 0 "register_operand" "=e")
5484 (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5485 "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
5487 [(set_attr "type" "fp")
5488 (set_attr "length" "1")])
5490 (define_expand "fixuns_trunctfdi2"
5491 [(set (match_operand:DI 0 "register_operand" "=f")
5492 (unsigned_fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))]
5493 "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
5498 if (GET_CODE (operands[1]) != MEM)
5500 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
5501 emit_insn (gen_rtx_SET (VOIDmode, slot0, operands[1]));
5504 slot0 = operands[1];
5506 emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_qtoux\"),
5507 operands[0], 0, DImode, 1,
5508 XEXP (slot0, 0), Pmode);
5513 ;;- arithmetic instructions
5515 (define_expand "adddi3"
5516 [(set (match_operand:DI 0 "register_operand" "=r")
5517 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5518 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5522 if (! TARGET_ARCH64)
5524 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5525 gen_rtx_SET (VOIDmode, operands[0],
5526 gen_rtx_PLUS (DImode, operands[1],
5528 gen_rtx_CLOBBER (VOIDmode,
5529 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5532 if (arith_double_4096_operand(operands[2], DImode))
5534 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5535 gen_rtx_MINUS (DImode, operands[1],
5541 (define_insn "adddi3_insn_sp32"
5542 [(set (match_operand:DI 0 "register_operand" "=r")
5543 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5544 (match_operand:DI 2 "arith_double_operand" "rHI")))
5545 (clobber (reg:CC 100))]
5548 [(set_attr "length" "2")])
5551 [(set (match_operand:DI 0 "register_operand" "=r")
5552 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5553 (match_operand:DI 2 "arith_double_operand" "rHI")))
5554 (clobber (reg:CC 100))]
5555 "! TARGET_ARCH64 && reload_completed"
5556 [(parallel [(set (reg:CC_NOOV 100)
5557 (compare:CC_NOOV (plus:SI (match_dup 4)
5561 (plus:SI (match_dup 4) (match_dup 5)))])
5563 (plus:SI (plus:SI (match_dup 7)
5565 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5568 operands[3] = gen_lowpart (SImode, operands[0]);
5569 operands[4] = gen_lowpart (SImode, operands[1]);
5570 operands[5] = gen_lowpart (SImode, operands[2]);
5571 operands[6] = gen_highpart (SImode, operands[0]);
5572 operands[7] = gen_highpart (SImode, operands[1]);
5573 if (GET_CODE (operands[2]) == CONST_INT)
5575 if (INTVAL (operands[2]) < 0)
5576 operands[8] = constm1_rtx;
5578 operands[8] = const0_rtx;
5581 operands[8] = gen_highpart (SImode, operands[2]);
5585 [(set (match_operand:DI 0 "register_operand" "=r")
5586 (minus:DI (match_operand:DI 1 "arith_double_operand" "r")
5587 (match_operand:DI 2 "arith_double_operand" "rHI")))
5588 (clobber (reg:CC 100))]
5589 "! TARGET_ARCH64 && reload_completed"
5590 [(parallel [(set (reg:CC_NOOV 100)
5591 (compare:CC_NOOV (minus:SI (match_dup 4)
5595 (minus:SI (match_dup 4) (match_dup 5)))])
5597 (minus:SI (minus:SI (match_dup 7)
5599 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5602 operands[3] = gen_lowpart (SImode, operands[0]);
5603 operands[4] = gen_lowpart (SImode, operands[1]);
5604 operands[5] = gen_lowpart (SImode, operands[2]);
5605 operands[6] = gen_highpart (SImode, operands[0]);
5606 operands[7] = gen_highpart (SImode, operands[1]);
5607 if (GET_CODE (operands[2]) == CONST_INT)
5609 if (INTVAL (operands[2]) < 0)
5610 operands[8] = constm1_rtx;
5612 operands[8] = const0_rtx;
5615 operands[8] = gen_highpart (SImode, operands[2]);
5618 ;; LTU here means "carry set"
5620 [(set (match_operand:SI 0 "register_operand" "=r")
5621 (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5622 (match_operand:SI 2 "arith_operand" "rI"))
5623 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5626 [(set_attr "type" "unary")
5627 (set_attr "length" "1")])
5629 (define_insn "*addx_extend_sp32"
5630 [(set (match_operand:DI 0 "register_operand" "=r")
5631 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5632 (match_operand:SI 2 "arith_operand" "rI"))
5633 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5636 [(set_attr "type" "unary")
5637 (set_attr "length" "2")])
5640 [(set (match_operand:DI 0 "register_operand" "")
5641 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
5642 (match_operand:SI 2 "arith_operand" ""))
5643 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5644 "! TARGET_ARCH64 && reload_completed"
5645 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
5646 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5647 (set (match_dup 4) (const_int 0))]
5648 "operands[3] = gen_lowpart (SImode, operands[0]);
5649 operands[4] = gen_highpart (SImode, operands[1]);")
5651 (define_insn "*addx_extend_sp64"
5652 [(set (match_operand:DI 0 "register_operand" "=r")
5653 (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5654 (match_operand:SI 2 "arith_operand" "rI"))
5655 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5657 "addx\\t%r1, %2, %0"
5658 [(set_attr "type" "misc")
5659 (set_attr "length" "1")])
5662 [(set (match_operand:SI 0 "register_operand" "=r")
5663 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5664 (match_operand:SI 2 "arith_operand" "rI"))
5665 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5667 "subx\\t%r1, %2, %0"
5668 [(set_attr "type" "misc")
5669 (set_attr "length" "1")])
5671 (define_insn "*subx_extend_sp64"
5672 [(set (match_operand:DI 0 "register_operand" "=r")
5673 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5674 (match_operand:SI 2 "arith_operand" "rI"))
5675 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5677 "subx\\t%r1, %2, %0"
5678 [(set_attr "type" "misc")
5679 (set_attr "length" "1")])
5681 (define_insn "*subx_extend"
5682 [(set (match_operand:DI 0 "register_operand" "=r")
5683 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5684 (match_operand:SI 2 "arith_operand" "rI"))
5685 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5688 [(set_attr "type" "unary")
5689 (set_attr "length" "2")])
5692 [(set (match_operand:DI 0 "register_operand" "=r")
5693 (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5694 (match_operand:SI 2 "arith_operand" "rI"))
5695 (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5696 "! TARGET_ARCH64 && reload_completed"
5697 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5698 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5699 (set (match_dup 4) (const_int 0))]
5700 "operands[3] = gen_lowpart (SImode, operands[0]);
5701 operands[4] = gen_highpart (SImode, operands[0]);")
5704 [(set (match_operand:DI 0 "register_operand" "=r")
5705 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5706 (match_operand:DI 2 "register_operand" "r")))
5707 (clobber (reg:CC 100))]
5710 [(set_attr "type" "multi")
5711 (set_attr "length" "2")])
5714 [(set (match_operand:DI 0 "register_operand" "")
5715 (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5716 (match_operand:DI 2 "register_operand" "")))
5717 (clobber (reg:CC 100))]
5718 "! TARGET_ARCH64 && reload_completed"
5719 [(parallel [(set (reg:CC_NOOV 100)
5720 (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5722 (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5724 (plus:SI (plus:SI (match_dup 4) (const_int 0))
5725 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5726 "operands[3] = gen_lowpart (SImode, operands[2]);
5727 operands[4] = gen_highpart (SImode, operands[2]);
5728 operands[5] = gen_lowpart (SImode, operands[0]);
5729 operands[6] = gen_highpart (SImode, operands[0]);")
5731 (define_insn "*adddi3_sp64"
5732 [(set (match_operand:DI 0 "register_operand" "=r")
5733 (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5734 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5737 [(set_attr "type" "binary")
5738 (set_attr "length" "1")])
5740 (define_expand "addsi3"
5741 [(set (match_operand:SI 0 "register_operand" "=r,d")
5742 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5743 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5747 if (arith_4096_operand(operands[2], DImode))
5749 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5750 gen_rtx_MINUS (SImode, operands[1],
5756 (define_insn "*addsi3"
5757 [(set (match_operand:SI 0 "register_operand" "=r,d")
5758 (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
5759 (match_operand:SI 2 "arith_operand" "rI,d")))]
5763 fpadd32s\\t%1, %2, %0"
5764 [(set_attr "type" "ialu,fp")
5765 (set_attr "length" "1")])
5767 (define_insn "*cmp_cc_plus"
5768 [(set (reg:CC_NOOV 100)
5769 (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5770 (match_operand:SI 1 "arith_operand" "rI"))
5773 "addcc\\t%0, %1, %%g0"
5774 [(set_attr "type" "compare")
5775 (set_attr "length" "1")])
5777 (define_insn "*cmp_ccx_plus"
5778 [(set (reg:CCX_NOOV 100)
5779 (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5780 (match_operand:DI 1 "arith_double_operand" "rHI"))
5783 "addcc\\t%0, %1, %%g0"
5784 [(set_attr "type" "compare")
5785 (set_attr "length" "1")])
5787 (define_insn "*cmp_cc_plus_set"
5788 [(set (reg:CC_NOOV 100)
5789 (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5790 (match_operand:SI 2 "arith_operand" "rI"))
5792 (set (match_operand:SI 0 "register_operand" "=r")
5793 (plus:SI (match_dup 1) (match_dup 2)))]
5795 "addcc\\t%1, %2, %0"
5796 [(set_attr "type" "compare")
5797 (set_attr "length" "1")])
5799 (define_insn "*cmp_ccx_plus_set"
5800 [(set (reg:CCX_NOOV 100)
5801 (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5802 (match_operand:DI 2 "arith_double_operand" "rHI"))
5804 (set (match_operand:DI 0 "register_operand" "=r")
5805 (plus:DI (match_dup 1) (match_dup 2)))]
5807 "addcc\\t%1, %2, %0"
5808 [(set_attr "type" "compare")
5809 (set_attr "length" "1")])
5811 (define_expand "subdi3"
5812 [(set (match_operand:DI 0 "register_operand" "=r")
5813 (minus:DI (match_operand:DI 1 "register_operand" "r")
5814 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
5818 if (! TARGET_ARCH64)
5820 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5821 gen_rtx_SET (VOIDmode, operands[0],
5822 gen_rtx_MINUS (DImode, operands[1],
5824 gen_rtx_CLOBBER (VOIDmode,
5825 gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5828 if (arith_double_4096_operand(operands[2], DImode))
5830 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5831 gen_rtx_PLUS (DImode, operands[1],
5837 (define_insn "*subdi3_sp32"
5838 [(set (match_operand:DI 0 "register_operand" "=r")
5839 (minus:DI (match_operand:DI 1 "register_operand" "r")
5840 (match_operand:DI 2 "arith_double_operand" "rHI")))
5841 (clobber (reg:CC 100))]
5844 [(set_attr "length" "2")])
5847 [(set (match_operand:DI 0 "register_operand" "")
5848 (minus:DI (match_operand:DI 1 "register_operand" "")
5849 (match_operand:DI 2 "arith_double_operand" "")))
5850 (clobber (reg:CC 100))]
5853 && (GET_CODE (operands[2]) == CONST_INT
5854 || GET_CODE (operands[2]) == CONST_DOUBLE)"
5855 [(clobber (const_int 0))]
5860 highp = gen_highpart (SImode, operands[2]);
5861 lowp = gen_lowpart (SImode, operands[2]);
5862 if ((lowp == const0_rtx)
5863 && (operands[0] == operands[1]))
5865 emit_insn (gen_rtx_SET (VOIDmode,
5866 gen_highpart (SImode, operands[0]),
5867 gen_rtx_MINUS (SImode,
5868 gen_highpart (SImode, operands[1]),
5873 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5874 gen_lowpart (SImode, operands[1]),
5876 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5877 gen_highpart (SImode, operands[1]),
5884 [(set (match_operand:DI 0 "register_operand" "")
5885 (minus:DI (match_operand:DI 1 "register_operand" "")
5886 (match_operand:DI 2 "register_operand" "")))
5887 (clobber (reg:CC 100))]
5889 && reload_completed"
5890 [(clobber (const_int 0))]
5893 emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5894 gen_lowpart (SImode, operands[1]),
5895 gen_lowpart (SImode, operands[2])));
5896 emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5897 gen_highpart (SImode, operands[1]),
5898 gen_highpart (SImode, operands[2])));
5903 [(set (match_operand:DI 0 "register_operand" "=r")
5904 (minus:DI (match_operand:DI 1 "register_operand" "r")
5905 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5906 (clobber (reg:CC 100))]
5909 [(set_attr "type" "multi")
5910 (set_attr "length" "2")])
5913 [(set (match_operand:DI 0 "register_operand" "")
5914 (minus:DI (match_operand:DI 1 "register_operand" "")
5915 (zero_extend:DI (match_operand:SI 2 "register_operand" ""))))
5916 (clobber (reg:CC 100))]
5917 "! TARGET_ARCH64 && reload_completed"
5918 [(parallel [(set (reg:CC_NOOV 100)
5919 (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5921 (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5923 (minus:SI (minus:SI (match_dup 4) (const_int 0))
5924 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5925 "operands[3] = gen_lowpart (SImode, operands[1]);
5926 operands[4] = gen_highpart (SImode, operands[1]);
5927 operands[5] = gen_lowpart (SImode, operands[0]);
5928 operands[6] = gen_highpart (SImode, operands[0]);")
5930 (define_insn "*subdi3_sp64"
5931 [(set (match_operand:DI 0 "register_operand" "=r")
5932 (minus:DI (match_operand:DI 1 "register_operand" "r")
5933 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5936 [(set_attr "type" "binary")
5937 (set_attr "length" "1")])
5939 (define_expand "subsi3"
5940 [(set (match_operand:SI 0 "register_operand" "=r,d")
5941 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5942 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
5946 if (arith_4096_operand(operands[2], DImode))
5948 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
5949 gen_rtx_PLUS (SImode, operands[1],
5955 (define_insn "*subsi3"
5956 [(set (match_operand:SI 0 "register_operand" "=r,d")
5957 (minus:SI (match_operand:SI 1 "register_operand" "r,d")
5958 (match_operand:SI 2 "arith_operand" "rI,d")))]
5962 fpsub32s\\t%1, %2, %0"
5963 [(set_attr "type" "ialu,fp")
5964 (set_attr "length" "1")])
5966 (define_insn "*cmp_minus_cc"
5967 [(set (reg:CC_NOOV 100)
5968 (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5969 (match_operand:SI 1 "arith_operand" "rI"))
5972 "subcc\\t%r0, %1, %%g0"
5973 [(set_attr "type" "compare")
5974 (set_attr "length" "1")])
5976 (define_insn "*cmp_minus_ccx"
5977 [(set (reg:CCX_NOOV 100)
5978 (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5979 (match_operand:DI 1 "arith_double_operand" "rHI"))
5982 "subcc\\t%0, %1, %%g0"
5983 [(set_attr "type" "compare")
5984 (set_attr "length" "1")])
5986 (define_insn "cmp_minus_cc_set"
5987 [(set (reg:CC_NOOV 100)
5988 (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5989 (match_operand:SI 2 "arith_operand" "rI"))
5991 (set (match_operand:SI 0 "register_operand" "=r")
5992 (minus:SI (match_dup 1) (match_dup 2)))]
5994 "subcc\\t%r1, %2, %0"
5995 [(set_attr "type" "compare")
5996 (set_attr "length" "1")])
5998 (define_insn "*cmp_minus_ccx_set"
5999 [(set (reg:CCX_NOOV 100)
6000 (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
6001 (match_operand:DI 2 "arith_double_operand" "rHI"))
6003 (set (match_operand:DI 0 "register_operand" "=r")
6004 (minus:DI (match_dup 1) (match_dup 2)))]
6006 "subcc\\t%1, %2, %0"
6007 [(set_attr "type" "compare")
6008 (set_attr "length" "1")])
6010 ;; Integer Multiply/Divide.
6012 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
6013 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
6015 (define_insn "mulsi3"
6016 [(set (match_operand:SI 0 "register_operand" "=r")
6017 (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6018 (match_operand:SI 2 "arith_operand" "rI")))]
6021 [(set_attr "type" "imul")
6022 (set_attr "length" "1")])
6024 (define_expand "muldi3"
6025 [(set (match_operand:DI 0 "register_operand" "=r")
6026 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6027 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6028 "TARGET_ARCH64 || TARGET_V8PLUS"
6033 emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
6038 (define_insn "*muldi3_sp64"
6039 [(set (match_operand:DI 0 "register_operand" "=r")
6040 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
6041 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6044 [(set_attr "type" "imul")
6045 (set_attr "length" "1")])
6047 ;; V8plus wide multiply.
6049 (define_insn "muldi3_v8plus"
6050 [(set (match_operand:DI 0 "register_operand" "=r,h")
6051 (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
6052 (match_operand:DI 2 "arith_double_operand" "rHI,rHI")))
6053 (clobber (match_scratch:SI 3 "=&h,X"))
6054 (clobber (match_scratch:SI 4 "=&h,X"))]
6058 if (sparc_check_64 (operands[1], insn) <= 0)
6059 output_asm_insn (\"srl\\t%L1, 0, %L1\", operands);
6060 if (which_alternative == 1)
6061 output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands);
6062 if (sparc_check_64 (operands[2], insn) <= 0)
6063 output_asm_insn (\"srl\\t%L2, 0, %L2\", operands);
6064 if (which_alternative == 1)
6065 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\";
6067 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\";
6069 [(set_attr "length" "9,8")])
6071 (define_insn "*cmp_mul_set"
6073 (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
6074 (match_operand:SI 2 "arith_operand" "rI"))
6076 (set (match_operand:SI 0 "register_operand" "=r")
6077 (mult:SI (match_dup 1) (match_dup 2)))]
6078 "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
6079 "smulcc\\t%1, %2, %0"
6080 [(set_attr "type" "imul")
6081 (set_attr "length" "1")])
6083 (define_expand "mulsidi3"
6084 [(set (match_operand:DI 0 "register_operand" "")
6085 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6086 (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
6090 if (CONSTANT_P (operands[2]))
6093 emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
6096 emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
6102 emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
6107 ;; V9 puts the 64 bit product in a 64 bit register. Only out or global
6108 ;; registers can hold 64 bit values in the V8plus environment.
6110 (define_insn "mulsidi3_v8plus"
6111 [(set (match_operand:DI 0 "register_operand" "=h,r")
6112 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6113 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6114 (clobber (match_scratch:SI 3 "=X,&h"))]
6117 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6118 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6119 [(set_attr "length" "2,3")])
6122 (define_insn "const_mulsidi3_v8plus"
6123 [(set (match_operand:DI 0 "register_operand" "=h,r")
6124 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6125 (match_operand:SI 2 "small_int" "I,I")))
6126 (clobber (match_scratch:SI 3 "=X,&h"))]
6129 smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6130 smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6131 [(set_attr "length" "2,3")])
6134 (define_insn "*mulsidi3_sp32"
6135 [(set (match_operand:DI 0 "register_operand" "=r")
6136 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6137 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6141 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6143 [(set (attr "length")
6144 (if_then_else (eq_attr "isa" "sparclet")
6145 (const_int 1) (const_int 2)))])
6147 (define_insn "*mulsidi3_sp64"
6148 [(set (match_operand:DI 0 "register_operand" "=r")
6149 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6150 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6151 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6153 [(set_attr "length" "1")])
6155 ;; Extra pattern, because sign_extend of a constant isn't valid.
6158 (define_insn "const_mulsidi3_sp32"
6159 [(set (match_operand:DI 0 "register_operand" "=r")
6160 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6161 (match_operand:SI 2 "small_int" "I")))]
6165 return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6167 [(set (attr "length")
6168 (if_then_else (eq_attr "isa" "sparclet")
6169 (const_int 1) (const_int 2)))])
6171 (define_insn "const_mulsidi3_sp64"
6172 [(set (match_operand:DI 0 "register_operand" "=r")
6173 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6174 (match_operand:SI 2 "small_int" "I")))]
6175 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6177 [(set_attr "length" "1")])
6179 (define_expand "smulsi3_highpart"
6180 [(set (match_operand:SI 0 "register_operand" "")
6182 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
6183 (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
6185 "TARGET_HARD_MUL && TARGET_ARCH32"
6188 if (CONSTANT_P (operands[2]))
6192 emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
6198 emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
6203 emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
6204 operands[2], GEN_INT (32)));
6210 (define_insn "smulsi3_highpart_v8plus"
6211 [(set (match_operand:SI 0 "register_operand" "=h,r")
6213 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6214 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6215 (match_operand:SI 3 "const_int_operand" "i,i"))))
6216 (clobber (match_scratch:SI 4 "=X,&h"))]
6219 smul %1,%2,%0\;srlx %0,%3,%0
6220 smul %1,%2,%4\;srlx %4,%3,%0"
6221 [(set_attr "length" "2")])
6223 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
6226 [(set (match_operand:SI 0 "register_operand" "=h,r")
6229 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6230 (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6231 (match_operand:SI 3 "const_int_operand" "i,i"))
6233 (clobber (match_scratch:SI 4 "=X,&h"))]
6236 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6237 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6238 [(set_attr "length" "2")])
6241 (define_insn "const_smulsi3_highpart_v8plus"
6242 [(set (match_operand:SI 0 "register_operand" "=h,r")
6244 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6245 (match_operand 2 "small_int" "i,i"))
6246 (match_operand:SI 3 "const_int_operand" "i,i"))))
6247 (clobber (match_scratch:SI 4 "=X,&h"))]
6250 smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6251 smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6252 [(set_attr "length" "2")])
6255 (define_insn "*smulsi3_highpart_sp32"
6256 [(set (match_operand:SI 0 "register_operand" "=r")
6258 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6259 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
6262 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6263 [(set_attr "length" "2")])
6266 (define_insn "const_smulsi3_highpart"
6267 [(set (match_operand:SI 0 "register_operand" "=r")
6269 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
6270 (match_operand:SI 2 "register_operand" "r"))
6273 "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6274 [(set_attr "length" "2")])
6276 (define_expand "umulsidi3"
6277 [(set (match_operand:DI 0 "register_operand" "")
6278 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6279 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
6283 if (CONSTANT_P (operands[2]))
6286 emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
6289 emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
6295 emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
6301 (define_insn "umulsidi3_v8plus"
6302 [(set (match_operand:DI 0 "register_operand" "=h,r")
6303 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6304 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
6305 (clobber (match_scratch:SI 3 "=X,&h"))]
6308 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6309 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6310 [(set_attr "length" "2,3")])
6313 (define_insn "*umulsidi3_sp32"
6314 [(set (match_operand:DI 0 "register_operand" "=r")
6315 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6316 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6320 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6322 [(set (attr "length")
6323 (if_then_else (eq_attr "isa" "sparclet")
6324 (const_int 1) (const_int 2)))])
6326 (define_insn "*umulsidi3_sp64"
6327 [(set (match_operand:DI 0 "register_operand" "=r")
6328 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6329 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
6330 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6332 [(set_attr "length" "1")])
6334 ;; Extra pattern, because sign_extend of a constant isn't valid.
6337 (define_insn "const_umulsidi3_sp32"
6338 [(set (match_operand:DI 0 "register_operand" "=r")
6339 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6340 (match_operand:SI 2 "uns_small_int" "")))]
6344 return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\";
6346 [(set (attr "length")
6347 (if_then_else (eq_attr "isa" "sparclet")
6348 (const_int 1) (const_int 2)))])
6350 (define_insn "const_umulsidi3_sp64"
6351 [(set (match_operand:DI 0 "register_operand" "=r")
6352 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6353 (match_operand:SI 2 "uns_small_int" "")))]
6354 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6356 [(set_attr "length" "1")])
6359 (define_insn "const_umulsidi3_v8plus"
6360 [(set (match_operand:DI 0 "register_operand" "=h,r")
6361 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6362 (match_operand:SI 2 "uns_small_int" "")))
6363 (clobber (match_scratch:SI 3 "=X,h"))]
6366 umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0
6367 umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0"
6368 [(set_attr "length" "2,3")])
6370 (define_expand "umulsi3_highpart"
6371 [(set (match_operand:SI 0 "register_operand" "")
6373 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
6374 (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
6376 "TARGET_HARD_MUL && TARGET_ARCH32"
6379 if (CONSTANT_P (operands[2]))
6383 emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
6389 emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
6394 emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
6395 operands[2], GEN_INT (32)));
6401 (define_insn "umulsi3_highpart_v8plus"
6402 [(set (match_operand:SI 0 "register_operand" "=h,r")
6404 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6405 (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
6406 (match_operand:SI 3 "const_int_operand" "i,i"))))
6407 (clobber (match_scratch:SI 4 "=X,h"))]
6410 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6411 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6412 [(set_attr "length" "2")])
6415 (define_insn "const_umulsi3_highpart_v8plus"
6416 [(set (match_operand:SI 0 "register_operand" "=h,r")
6418 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
6419 (match_operand:SI 2 "uns_small_int" ""))
6420 (match_operand:SI 3 "const_int_operand" "i,i"))))
6421 (clobber (match_scratch:SI 4 "=X,h"))]
6424 umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0
6425 umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0"
6426 [(set_attr "length" "2")])
6429 (define_insn "*umulsi3_highpart_sp32"
6430 [(set (match_operand:SI 0 "register_operand" "=r")
6432 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6433 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
6436 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6437 [(set_attr "length" "2")])
6440 (define_insn "const_umulsi3_highpart"
6441 [(set (match_operand:SI 0 "register_operand" "=r")
6443 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
6444 (match_operand:SI 2 "uns_small_int" ""))
6447 "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0"
6448 [(set_attr "length" "2")])
6450 ;; The v8 architecture specifies that there must be 3 instructions between
6451 ;; a y register write and a use of it for correct results.
6453 (define_expand "divsi3"
6454 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
6455 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6456 (match_operand:SI 2 "input_operand" "rI,m")))
6457 (clobber (match_scratch:SI 3 "=&r,&r"))])]
6458 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6463 operands[3] = gen_reg_rtx(SImode);
6464 emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
6465 emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
6471 (define_insn "divsi3_sp32"
6472 [(set (match_operand:SI 0 "register_operand" "=r,r")
6473 (div:SI (match_operand:SI 1 "register_operand" "r,r")
6474 (match_operand:SI 2 "input_operand" "rI,m")))
6475 (clobber (match_scratch:SI 3 "=&r,&r"))]
6476 "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
6480 if (which_alternative == 0)
6482 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdiv\\t%1, %2, %0\";
6484 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\";
6487 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\";
6489 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\";
6491 [(set (attr "length")
6492 (if_then_else (eq_attr "isa" "v9")
6493 (const_int 4) (const_int 7)))])
6495 (define_insn "divsi3_sp64"
6496 [(set (match_operand:SI 0 "register_operand" "=r")
6497 (div:SI (match_operand:SI 1 "register_operand" "r")
6498 (match_operand:SI 2 "input_operand" "rI")))
6499 (use (match_operand:SI 3 "register_operand" "r"))]
6500 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6501 "wr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0"
6502 [(set_attr "length" "2")])
6504 (define_insn "divdi3"
6505 [(set (match_operand:DI 0 "register_operand" "=r")
6506 (div:DI (match_operand:DI 1 "register_operand" "r")
6507 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6509 "sdivx\\t%1, %2, %0")
6511 (define_insn "*cmp_sdiv_cc_set"
6513 (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
6514 (match_operand:SI 2 "arith_operand" "rI"))
6516 (set (match_operand:SI 0 "register_operand" "=r")
6517 (div:SI (match_dup 1) (match_dup 2)))
6518 (clobber (match_scratch:SI 3 "=&r"))]
6519 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6523 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tsdivcc\\t%1, %2, %0\";
6525 return \"sra\\t%1, 31, %3\\n\\twr\\t%3, 0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\";
6527 [(set (attr "length")
6528 (if_then_else (eq_attr "isa" "v9")
6529 (const_int 3) (const_int 6)))])
6532 (define_expand "udivsi3"
6533 [(set (match_operand:SI 0 "register_operand" "")
6534 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
6535 (match_operand:SI 2 "input_operand" "")))]
6536 "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
6539 (define_insn "udivsi3_sp32"
6540 [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
6541 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
6542 (match_operand:SI 2 "input_operand" "rI,m,r")))]
6544 || TARGET_DEPRECATED_V8_INSNS)
6548 output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands);
6549 switch (which_alternative)
6552 return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\";
6554 return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\";
6556 return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\";
6559 [(set_attr "length" "5")])
6561 (define_insn "udivsi3_sp64"
6562 [(set (match_operand:SI 0 "register_operand" "=r")
6563 (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
6564 (match_operand:SI 2 "input_operand" "rI")))]
6565 "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
6566 "wr\\t%%g0, 0, %%y\\n\\tudiv\\t%1, %2, %0"
6567 [(set_attr "length" "2")])
6569 (define_insn "udivdi3"
6570 [(set (match_operand:DI 0 "register_operand" "=r")
6571 (udiv:DI (match_operand:DI 1 "register_operand" "r")
6572 (match_operand:DI 2 "arith_double_operand" "rHI")))]
6574 "udivx\\t%1, %2, %0")
6576 (define_insn "*cmp_udiv_cc_set"
6578 (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
6579 (match_operand:SI 2 "arith_operand" "rI"))
6581 (set (match_operand:SI 0 "register_operand" "=r")
6582 (udiv:SI (match_dup 1) (match_dup 2)))]
6584 || TARGET_DEPRECATED_V8_INSNS"
6588 return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\";
6590 return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\";
6592 [(set (attr "length")
6593 (if_then_else (eq_attr "isa" "v9")
6594 (const_int 2) (const_int 5)))])
6596 ; sparclet multiply/accumulate insns
6598 (define_insn "*smacsi"
6599 [(set (match_operand:SI 0 "register_operand" "=r")
6600 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
6601 (match_operand:SI 2 "arith_operand" "rI"))
6602 (match_operand:SI 3 "register_operand" "0")))]
6605 [(set_attr "type" "imul")
6606 (set_attr "length" "1")])
6608 (define_insn "*smacdi"
6609 [(set (match_operand:DI 0 "register_operand" "=r")
6610 (plus:DI (mult:DI (sign_extend:DI
6611 (match_operand:SI 1 "register_operand" "%r"))
6613 (match_operand:SI 2 "register_operand" "r")))
6614 (match_operand:DI 3 "register_operand" "0")))]
6616 "smacd\\t%1, %2, %L0"
6617 [(set_attr "type" "imul")
6618 (set_attr "length" "1")])
6620 (define_insn "*umacdi"
6621 [(set (match_operand:DI 0 "register_operand" "=r")
6622 (plus:DI (mult:DI (zero_extend:DI
6623 (match_operand:SI 1 "register_operand" "%r"))
6625 (match_operand:SI 2 "register_operand" "r")))
6626 (match_operand:DI 3 "register_operand" "0")))]
6628 "umacd\\t%1, %2, %L0"
6629 [(set_attr "type" "imul")
6630 (set_attr "length" "1")])
6632 ;;- Boolean instructions
6633 ;; We define DImode `and' so with DImode `not' we can get
6634 ;; DImode `andn'. Other combinations are possible.
6636 (define_expand "anddi3"
6637 [(set (match_operand:DI 0 "register_operand" "")
6638 (and:DI (match_operand:DI 1 "arith_double_operand" "")
6639 (match_operand:DI 2 "arith_double_operand" "")))]
6643 (define_insn "*anddi3_sp32"
6644 [(set (match_operand:DI 0 "register_operand" "=r,b")
6645 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6646 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6651 [(set_attr "type" "ialu,fp")
6652 (set_attr "length" "2,1")])
6654 (define_insn "*anddi3_sp64"
6655 [(set (match_operand:DI 0 "register_operand" "=r,b")
6656 (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6657 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6662 [(set_attr "type" "ialu,fp")
6663 (set_attr "length" "1,1")])
6665 (define_insn "andsi3"
6666 [(set (match_operand:SI 0 "register_operand" "=r,d")
6667 (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
6668 (match_operand:SI 2 "arith_operand" "rI,d")))]
6673 [(set_attr "type" "ialu,fp")
6674 (set_attr "length" "1,1")])
6677 [(set (match_operand:SI 0 "register_operand" "")
6678 (and:SI (match_operand:SI 1 "register_operand" "")
6679 (match_operand:SI 2 "" "")))
6680 (clobber (match_operand:SI 3 "register_operand" ""))]
6681 "GET_CODE (operands[2]) == CONST_INT
6682 && !SMALL_INT32 (operands[2])
6683 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6684 [(set (match_dup 3) (match_dup 4))
6685 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6688 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6691 ;; Split DImode logical operations requiring two instructions.
6693 [(set (match_operand:DI 0 "register_operand" "")
6694 (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR
6695 [(match_operand:DI 2 "register_operand" "")
6696 (match_operand:DI 3 "arith_double_operand" "")]))]
6699 && ((GET_CODE (operands[0]) == REG
6700 && REGNO (operands[0]) < 32)
6701 || (GET_CODE (operands[0]) == SUBREG
6702 && GET_CODE (SUBREG_REG (operands[0])) == REG
6703 && REGNO (SUBREG_REG (operands[0])) < 32))"
6704 [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6705 (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6708 if (GET_CODE (operands[0]) == SUBREG)
6709 operands[0] = alter_subreg (operands[0]);
6710 operands[4] = gen_highpart (SImode, operands[0]);
6711 operands[5] = gen_lowpart (SImode, operands[0]);
6712 operands[6] = gen_highpart (SImode, operands[2]);
6713 operands[7] = gen_lowpart (SImode, operands[2]);
6714 if (GET_CODE (operands[3]) == CONST_INT)
6716 if (INTVAL (operands[3]) < 0)
6717 operands[8] = constm1_rtx;
6719 operands[8] = const0_rtx;
6722 operands[8] = gen_highpart (SImode, operands[3]);
6723 operands[9] = gen_lowpart (SImode, operands[3]);
6726 (define_insn "*and_not_di_sp32"
6727 [(set (match_operand:DI 0 "register_operand" "=r,b")
6728 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6729 (match_operand:DI 2 "register_operand" "r,b")))]
6733 fandnot1\\t%1, %2, %0"
6734 [(set_attr "type" "ialu,fp")
6735 (set_attr "length" "2,1")])
6738 [(set (match_operand:DI 0 "register_operand" "")
6739 (and:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6740 (match_operand:DI 2 "register_operand" "")))]
6743 && ((GET_CODE (operands[0]) == REG
6744 && REGNO (operands[0]) < 32)
6745 || (GET_CODE (operands[0]) == SUBREG
6746 && GET_CODE (SUBREG_REG (operands[0])) == REG
6747 && REGNO (SUBREG_REG (operands[0])) < 32))"
6748 [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6749 (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6750 "if (GET_CODE (operands[0]) == SUBREG)
6751 operands[0] = alter_subreg (operands[0]);
6752 operands[3] = gen_highpart (SImode, operands[0]);
6753 operands[4] = gen_highpart (SImode, operands[1]);
6754 operands[5] = gen_highpart (SImode, operands[2]);
6755 operands[6] = gen_lowpart (SImode, operands[0]);
6756 operands[7] = gen_lowpart (SImode, operands[1]);
6757 operands[8] = gen_lowpart (SImode, operands[2]);")
6759 (define_insn "*and_not_di_sp64"
6760 [(set (match_operand:DI 0 "register_operand" "=r,b")
6761 (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6762 (match_operand:DI 2 "register_operand" "r,b")))]
6766 fandnot1\\t%1, %2, %0"
6767 [(set_attr "type" "ialu,fp")
6768 (set_attr "length" "1,1")])
6770 (define_insn "*and_not_si"
6771 [(set (match_operand:SI 0 "register_operand" "=r,d")
6772 (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6773 (match_operand:SI 2 "register_operand" "r,d")))]
6777 fandnot1s\\t%1, %2, %0"
6778 [(set_attr "type" "ialu,fp")
6779 (set_attr "length" "1,1")])
6781 (define_expand "iordi3"
6782 [(set (match_operand:DI 0 "register_operand" "")
6783 (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6784 (match_operand:DI 2 "arith_double_operand" "")))]
6788 (define_insn "*iordi3_sp32"
6789 [(set (match_operand:DI 0 "register_operand" "=r,b")
6790 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6791 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6796 [(set_attr "type" "ialu,fp")
6797 (set_attr "length" "2,1")])
6799 (define_insn "*iordi3_sp64"
6800 [(set (match_operand:DI 0 "register_operand" "=r,b")
6801 (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6802 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6807 [(set_attr "type" "ialu,fp")
6808 (set_attr "length" "1,1")])
6810 (define_insn "iorsi3"
6811 [(set (match_operand:SI 0 "register_operand" "=r,d")
6812 (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6813 (match_operand:SI 2 "arith_operand" "rI,d")))]
6818 [(set_attr "type" "ialu,fp")
6819 (set_attr "length" "1,1")])
6822 [(set (match_operand:SI 0 "register_operand" "")
6823 (ior:SI (match_operand:SI 1 "register_operand" "")
6824 (match_operand:SI 2 "" "")))
6825 (clobber (match_operand:SI 3 "register_operand" ""))]
6826 "GET_CODE (operands[2]) == CONST_INT
6827 && !SMALL_INT32 (operands[2])
6828 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6829 [(set (match_dup 3) (match_dup 4))
6830 (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6833 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6836 (define_insn "*or_not_di_sp32"
6837 [(set (match_operand:DI 0 "register_operand" "=r,b")
6838 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6839 (match_operand:DI 2 "register_operand" "r,b")))]
6843 fornot1\\t%1, %2, %0"
6844 [(set_attr "type" "ialu,fp")
6845 (set_attr "length" "2,1")])
6848 [(set (match_operand:DI 0 "register_operand" "")
6849 (ior:DI (not:DI (match_operand:DI 1 "register_operand" ""))
6850 (match_operand:DI 2 "register_operand" "")))]
6853 && ((GET_CODE (operands[0]) == REG
6854 && REGNO (operands[0]) < 32)
6855 || (GET_CODE (operands[0]) == SUBREG
6856 && GET_CODE (SUBREG_REG (operands[0])) == REG
6857 && REGNO (SUBREG_REG (operands[0])) < 32))"
6858 [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6859 (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6860 "if (GET_CODE (operands[0]) == SUBREG)
6861 operands[0] = alter_subreg (operands[0]);
6862 operands[3] = gen_highpart (SImode, operands[0]);
6863 operands[4] = gen_highpart (SImode, operands[1]);
6864 operands[5] = gen_highpart (SImode, operands[2]);
6865 operands[6] = gen_lowpart (SImode, operands[0]);
6866 operands[7] = gen_lowpart (SImode, operands[1]);
6867 operands[8] = gen_lowpart (SImode, operands[2]);")
6869 (define_insn "*or_not_di_sp64"
6870 [(set (match_operand:DI 0 "register_operand" "=r,b")
6871 (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6872 (match_operand:DI 2 "register_operand" "r,b")))]
6876 fornot1\\t%1, %2, %0"
6877 [(set_attr "type" "ialu,fp")
6878 (set_attr "length" "1,1")])
6880 (define_insn "*or_not_si"
6881 [(set (match_operand:SI 0 "register_operand" "=r,d")
6882 (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6883 (match_operand:SI 2 "register_operand" "r,d")))]
6887 fornot1s\\t%1, %2, %0"
6888 [(set_attr "type" "ialu,fp")
6889 (set_attr "length" "1,1")])
6891 (define_expand "xordi3"
6892 [(set (match_operand:DI 0 "register_operand" "")
6893 (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6894 (match_operand:DI 2 "arith_double_operand" "")))]
6898 (define_insn "*xordi3_sp32"
6899 [(set (match_operand:DI 0 "register_operand" "=r,b")
6900 (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6901 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6906 [(set_attr "length" "2,1")
6907 (set_attr "type" "ialu,fp")])
6909 (define_insn "*xordi3_sp64"
6910 [(set (match_operand:DI 0 "register_operand" "=r,b")
6911 (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6912 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6917 [(set_attr "type" "ialu,fp")
6918 (set_attr "length" "1,1")])
6920 (define_insn "*xordi3_sp64_dbl"
6921 [(set (match_operand:DI 0 "register_operand" "=r")
6922 (xor:DI (match_operand:DI 1 "register_operand" "r")
6923 (match_operand:DI 2 "const64_operand" "")))]
6925 && HOST_BITS_PER_WIDE_INT != 64)"
6927 [(set_attr "type" "ialu")
6928 (set_attr "length" "1")])
6930 (define_insn "xorsi3"
6931 [(set (match_operand:SI 0 "register_operand" "=r,d")
6932 (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6933 (match_operand:SI 2 "arith_operand" "rI,d")))]
6938 [(set_attr "type" "ialu,fp")
6939 (set_attr "length" "1,1")])
6942 [(set (match_operand:SI 0 "register_operand" "")
6943 (xor:SI (match_operand:SI 1 "register_operand" "")
6944 (match_operand:SI 2 "" "")))
6945 (clobber (match_operand:SI 3 "register_operand" ""))]
6946 "GET_CODE (operands[2]) == CONST_INT
6947 && !SMALL_INT32 (operands[2])
6948 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6949 [(set (match_dup 3) (match_dup 4))
6950 (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6953 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6957 [(set (match_operand:SI 0 "register_operand" "")
6958 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6959 (match_operand:SI 2 "" ""))))
6960 (clobber (match_operand:SI 3 "register_operand" ""))]
6961 "GET_CODE (operands[2]) == CONST_INT
6962 && !SMALL_INT32 (operands[2])
6963 && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6964 [(set (match_dup 3) (match_dup 4))
6965 (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6968 operands[4] = GEN_INT (~INTVAL (operands[2]) & 0xffffffff);
6971 ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6972 ;; Combine now canonicalizes to the rightmost expression.
6973 (define_insn "*xor_not_di_sp32"
6974 [(set (match_operand:DI 0 "register_operand" "=r,b")
6975 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6976 (match_operand:DI 2 "register_operand" "r,b"))))]
6981 [(set_attr "length" "2,1")
6982 (set_attr "type" "ialu,fp")])
6985 [(set (match_operand:DI 0 "register_operand" "")
6986 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "")
6987 (match_operand:DI 2 "register_operand" ""))))]
6990 && ((GET_CODE (operands[0]) == REG
6991 && REGNO (operands[0]) < 32)
6992 || (GET_CODE (operands[0]) == SUBREG
6993 && GET_CODE (SUBREG_REG (operands[0])) == REG
6994 && REGNO (SUBREG_REG (operands[0])) < 32))"
6995 [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6996 (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6997 "if (GET_CODE (operands[0]) == SUBREG)
6998 operands[0] = alter_subreg (operands[0]);
6999 operands[3] = gen_highpart (SImode, operands[0]);
7000 operands[4] = gen_highpart (SImode, operands[1]);
7001 operands[5] = gen_highpart (SImode, operands[2]);
7002 operands[6] = gen_lowpart (SImode, operands[0]);
7003 operands[7] = gen_lowpart (SImode, operands[1]);
7004 operands[8] = gen_lowpart (SImode, operands[2]);")
7006 (define_insn "*xor_not_di_sp64"
7007 [(set (match_operand:DI 0 "register_operand" "=r,b")
7008 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
7009 (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
7014 [(set_attr "type" "ialu,fp")
7015 (set_attr "length" "1,1")])
7017 (define_insn "*xor_not_si"
7018 [(set (match_operand:SI 0 "register_operand" "=r,d")
7019 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
7020 (match_operand:SI 2 "arith_operand" "rI,d"))))]
7024 fxnors\\t%1, %2, %0"
7025 [(set_attr "type" "ialu,fp")
7026 (set_attr "length" "1,1")])
7028 ;; These correspond to the above in the case where we also (or only)
7029 ;; want to set the condition code.
7031 (define_insn "*cmp_cc_arith_op"
7034 (match_operator:SI 2 "cc_arithop"
7035 [(match_operand:SI 0 "arith_operand" "%r")
7036 (match_operand:SI 1 "arith_operand" "rI")])
7039 "%A2cc\\t%0, %1, %%g0"
7040 [(set_attr "type" "compare")
7041 (set_attr "length" "1")])
7043 (define_insn "*cmp_ccx_arith_op"
7046 (match_operator:DI 2 "cc_arithop"
7047 [(match_operand:DI 0 "arith_double_operand" "%r")
7048 (match_operand:DI 1 "arith_double_operand" "rHI")])
7051 "%A2cc\\t%0, %1, %%g0"
7052 [(set_attr "type" "compare")
7053 (set_attr "length" "1")])
7055 (define_insn "*cmp_cc_arith_op_set"
7058 (match_operator:SI 3 "cc_arithop"
7059 [(match_operand:SI 1 "arith_operand" "%r")
7060 (match_operand:SI 2 "arith_operand" "rI")])
7062 (set (match_operand:SI 0 "register_operand" "=r")
7065 "%A3cc\\t%1, %2, %0"
7066 [(set_attr "type" "compare")
7067 (set_attr "length" "1")])
7069 (define_insn "*cmp_ccx_arith_op_set"
7072 (match_operator:DI 3 "cc_arithop"
7073 [(match_operand:DI 1 "arith_double_operand" "%r")
7074 (match_operand:DI 2 "arith_double_operand" "rHI")])
7076 (set (match_operand:DI 0 "register_operand" "=r")
7079 "%A3cc\\t%1, %2, %0"
7080 [(set_attr "type" "compare")
7081 (set_attr "length" "1")])
7083 (define_insn "*cmp_cc_xor_not"
7086 (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
7087 (match_operand:SI 1 "arith_operand" "rI")))
7090 "xnorcc\\t%r0, %1, %%g0"
7091 [(set_attr "type" "compare")
7092 (set_attr "length" "1")])
7094 (define_insn "*cmp_ccx_xor_not"
7097 (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
7098 (match_operand:DI 1 "arith_double_operand" "rHI")))
7101 "xnorcc\\t%r0, %1, %%g0"
7102 [(set_attr "type" "compare")
7103 (set_attr "length" "1")])
7105 (define_insn "*cmp_cc_xor_not_set"
7108 (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
7109 (match_operand:SI 2 "arith_operand" "rI")))
7111 (set (match_operand:SI 0 "register_operand" "=r")
7112 (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
7114 "xnorcc\\t%r1, %2, %0"
7115 [(set_attr "type" "compare")
7116 (set_attr "length" "1")])
7118 (define_insn "*cmp_ccx_xor_not_set"
7121 (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
7122 (match_operand:DI 2 "arith_double_operand" "rHI")))
7124 (set (match_operand:DI 0 "register_operand" "=r")
7125 (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
7127 "xnorcc\\t%r1, %2, %0"
7128 [(set_attr "type" "compare")
7129 (set_attr "length" "1")])
7131 (define_insn "*cmp_cc_arith_op_not"
7134 (match_operator:SI 2 "cc_arithopn"
7135 [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
7136 (match_operand:SI 1 "reg_or_0_operand" "rJ")])
7139 "%B2cc\\t%r1, %0, %%g0"
7140 [(set_attr "type" "compare")
7141 (set_attr "length" "1")])
7143 (define_insn "*cmp_ccx_arith_op_not"
7146 (match_operator:DI 2 "cc_arithopn"
7147 [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7148 (match_operand:DI 1 "reg_or_0_operand" "rJ")])
7151 "%B2cc\\t%r1, %0, %%g0"
7152 [(set_attr "type" "compare")
7153 (set_attr "length" "1")])
7155 (define_insn "*cmp_cc_arith_op_not_set"
7158 (match_operator:SI 3 "cc_arithopn"
7159 [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
7160 (match_operand:SI 2 "reg_or_0_operand" "rJ")])
7162 (set (match_operand:SI 0 "register_operand" "=r")
7165 "%B3cc\\t%r2, %1, %0"
7166 [(set_attr "type" "compare")
7167 (set_attr "length" "1")])
7169 (define_insn "*cmp_ccx_arith_op_not_set"
7172 (match_operator:DI 3 "cc_arithopn"
7173 [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7174 (match_operand:DI 2 "reg_or_0_operand" "rJ")])
7176 (set (match_operand:DI 0 "register_operand" "=r")
7179 "%B3cc\\t%r2, %1, %0"
7180 [(set_attr "type" "compare")
7181 (set_attr "length" "1")])
7183 ;; We cannot use the "neg" pseudo insn because the Sun assembler
7184 ;; does not know how to make it work for constants.
7186 (define_expand "negdi2"
7187 [(set (match_operand:DI 0 "register_operand" "=r")
7188 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7192 if (! TARGET_ARCH64)
7194 emit_insn (gen_rtx_PARALLEL
7197 gen_rtx_SET (VOIDmode, operand0,
7198 gen_rtx_NEG (DImode, operand1)),
7199 gen_rtx_CLOBBER (VOIDmode,
7200 gen_rtx_REG (CCmode,
7206 (define_insn "*negdi2_sp32"
7207 [(set (match_operand:DI 0 "register_operand" "=r")
7208 (neg:DI (match_operand:DI 1 "register_operand" "r")))
7209 (clobber (reg:CC 100))]
7212 [(set_attr "type" "unary")
7213 (set_attr "length" "2")])
7216 [(set (match_operand:DI 0 "register_operand" "")
7217 (neg:DI (match_operand:DI 1 "register_operand" "")))
7218 (clobber (reg:CC 100))]
7220 && reload_completed"
7221 [(parallel [(set (reg:CC_NOOV 100)
7222 (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
7224 (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
7225 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
7226 (ltu:SI (reg:CC 100) (const_int 0))))]
7227 "operands[2] = gen_highpart (SImode, operands[0]);
7228 operands[3] = gen_highpart (SImode, operands[1]);
7229 operands[4] = gen_lowpart (SImode, operands[0]);
7230 operands[5] = gen_lowpart (SImode, operands[1]);")
7232 (define_insn "*negdi2_sp64"
7233 [(set (match_operand:DI 0 "register_operand" "=r")
7234 (neg:DI (match_operand:DI 1 "register_operand" "r")))]
7236 "sub\\t%%g0, %1, %0"
7237 [(set_attr "type" "unary")
7238 (set_attr "length" "1")])
7240 (define_insn "negsi2"
7241 [(set (match_operand:SI 0 "register_operand" "=r")
7242 (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
7244 "sub\\t%%g0, %1, %0"
7245 [(set_attr "type" "unary")
7246 (set_attr "length" "1")])
7248 (define_insn "*cmp_cc_neg"
7249 [(set (reg:CC_NOOV 100)
7250 (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
7253 "subcc\\t%%g0, %0, %%g0"
7254 [(set_attr "type" "compare")
7255 (set_attr "length" "1")])
7257 (define_insn "*cmp_ccx_neg"
7258 [(set (reg:CCX_NOOV 100)
7259 (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7262 "subcc\\t%%g0, %0, %%g0"
7263 [(set_attr "type" "compare")
7264 (set_attr "length" "1")])
7266 (define_insn "*cmp_cc_set_neg"
7267 [(set (reg:CC_NOOV 100)
7268 (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
7270 (set (match_operand:SI 0 "register_operand" "=r")
7271 (neg:SI (match_dup 1)))]
7273 "subcc\\t%%g0, %1, %0"
7274 [(set_attr "type" "compare")
7275 (set_attr "length" "1")])
7277 (define_insn "*cmp_ccx_set_neg"
7278 [(set (reg:CCX_NOOV 100)
7279 (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7281 (set (match_operand:DI 0 "register_operand" "=r")
7282 (neg:DI (match_dup 1)))]
7284 "subcc\\t%%g0, %1, %0"
7285 [(set_attr "type" "compare")
7286 (set_attr "length" "1")])
7288 ;; We cannot use the "not" pseudo insn because the Sun assembler
7289 ;; does not know how to make it work for constants.
7290 (define_expand "one_cmpldi2"
7291 [(set (match_operand:DI 0 "register_operand" "")
7292 (not:DI (match_operand:DI 1 "register_operand" "")))]
7296 (define_insn "*one_cmpldi2_sp32"
7297 [(set (match_operand:DI 0 "register_operand" "=r,b")
7298 (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
7303 [(set_attr "type" "unary,fp")
7304 (set_attr "length" "2,1")])
7307 [(set (match_operand:DI 0 "register_operand" "")
7308 (not:DI (match_operand:DI 1 "register_operand" "")))]
7311 && ((GET_CODE (operands[0]) == REG
7312 && REGNO (operands[0]) < 32)
7313 || (GET_CODE (operands[0]) == SUBREG
7314 && GET_CODE (SUBREG_REG (operands[0])) == REG
7315 && REGNO (SUBREG_REG (operands[0])) < 32))"
7316 [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
7317 (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
7318 "if (GET_CODE (operands[0]) == SUBREG)
7319 operands[0] = alter_subreg (operands[0]);
7320 operands[2] = gen_highpart (SImode, operands[0]);
7321 operands[3] = gen_highpart (SImode, operands[1]);
7322 operands[4] = gen_lowpart (SImode, operands[0]);
7323 operands[5] = gen_lowpart (SImode, operands[1]);")
7325 (define_insn "*one_cmpldi2_sp64"
7326 [(set (match_operand:DI 0 "register_operand" "=r,b")
7327 (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
7332 [(set_attr "type" "unary,fp")
7333 (set_attr "length" "1")])
7335 (define_insn "one_cmplsi2"
7336 [(set (match_operand:SI 0 "register_operand" "=r,d")
7337 (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
7342 [(set_attr "type" "unary,fp")
7343 (set_attr "length" "1,1")])
7345 (define_insn "*cmp_cc_not"
7347 (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
7350 "xnorcc\\t%%g0, %0, %%g0"
7351 [(set_attr "type" "compare")
7352 (set_attr "length" "1")])
7354 (define_insn "*cmp_ccx_not"
7356 (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
7359 "xnorcc\\t%%g0, %0, %%g0"
7360 [(set_attr "type" "compare")
7361 (set_attr "length" "1")])
7363 (define_insn "*cmp_cc_set_not"
7365 (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
7367 (set (match_operand:SI 0 "register_operand" "=r")
7368 (not:SI (match_dup 1)))]
7370 "xnorcc\\t%%g0, %1, %0"
7371 [(set_attr "type" "compare")
7372 (set_attr "length" "1")])
7374 (define_insn "*cmp_ccx_set_not"
7376 (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
7378 (set (match_operand:DI 0 "register_operand" "=r")
7379 (not:DI (match_dup 1)))]
7381 "xnorcc\\t%%g0, %1, %0"
7382 [(set_attr "type" "compare")
7383 (set_attr "length" "1")])
7385 ;; Floating point arithmetic instructions.
7387 (define_expand "addtf3"
7388 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7389 (plus:TF (match_operand:TF 1 "general_operand" "")
7390 (match_operand:TF 2 "general_operand" "")))]
7391 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7394 if (! TARGET_HARD_QUAD)
7396 rtx slot0, slot1, slot2;
7398 if (GET_CODE (operands[0]) != MEM)
7399 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7401 slot0 = operands[0];
7402 if (GET_CODE (operands[1]) != MEM)
7404 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7405 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7408 slot1 = operands[1];
7409 if (GET_CODE (operands[2]) != MEM)
7411 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7412 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7415 slot2 = operands[2];
7417 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_add\"), 0,
7419 XEXP (slot0, 0), Pmode,
7420 XEXP (slot1, 0), Pmode,
7421 XEXP (slot2, 0), Pmode);
7423 if (GET_CODE (operands[0]) != MEM)
7424 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7429 (define_insn "*addtf3_hq"
7430 [(set (match_operand:TF 0 "register_operand" "=e")
7431 (plus:TF (match_operand:TF 1 "register_operand" "e")
7432 (match_operand:TF 2 "register_operand" "e")))]
7433 "TARGET_FPU && TARGET_HARD_QUAD"
7434 "faddq\\t%1, %2, %0"
7435 [(set_attr "type" "fp")
7436 (set_attr "length" "1")])
7438 (define_insn "adddf3"
7439 [(set (match_operand:DF 0 "register_operand" "=e")
7440 (plus:DF (match_operand:DF 1 "register_operand" "e")
7441 (match_operand:DF 2 "register_operand" "e")))]
7443 "faddd\\t%1, %2, %0"
7444 [(set_attr "type" "fp")
7445 (set_attr "length" "1")])
7447 (define_insn "addsf3"
7448 [(set (match_operand:SF 0 "register_operand" "=f")
7449 (plus:SF (match_operand:SF 1 "register_operand" "f")
7450 (match_operand:SF 2 "register_operand" "f")))]
7452 "fadds\\t%1, %2, %0"
7453 [(set_attr "type" "fp")
7454 (set_attr "length" "1")])
7456 (define_expand "subtf3"
7457 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7458 (minus:TF (match_operand:TF 1 "general_operand" "")
7459 (match_operand:TF 2 "general_operand" "")))]
7460 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7463 if (! TARGET_HARD_QUAD)
7465 rtx slot0, slot1, slot2;
7467 if (GET_CODE (operands[0]) != MEM)
7468 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7470 slot0 = operands[0];
7471 if (GET_CODE (operands[1]) != MEM)
7473 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7474 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7477 slot1 = operands[1];
7478 if (GET_CODE (operands[2]) != MEM)
7480 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7481 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7484 slot2 = operands[2];
7486 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sub\"), 0,
7488 XEXP (slot0, 0), Pmode,
7489 XEXP (slot1, 0), Pmode,
7490 XEXP (slot2, 0), Pmode);
7492 if (GET_CODE (operands[0]) != MEM)
7493 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7498 (define_insn "*subtf3_hq"
7499 [(set (match_operand:TF 0 "register_operand" "=e")
7500 (minus:TF (match_operand:TF 1 "register_operand" "e")
7501 (match_operand:TF 2 "register_operand" "e")))]
7502 "TARGET_FPU && TARGET_HARD_QUAD"
7503 "fsubq\\t%1, %2, %0"
7504 [(set_attr "type" "fp")
7505 (set_attr "length" "1")])
7507 (define_insn "subdf3"
7508 [(set (match_operand:DF 0 "register_operand" "=e")
7509 (minus:DF (match_operand:DF 1 "register_operand" "e")
7510 (match_operand:DF 2 "register_operand" "e")))]
7512 "fsubd\\t%1, %2, %0"
7513 [(set_attr "type" "fp")
7514 (set_attr "length" "1")])
7516 (define_insn "subsf3"
7517 [(set (match_operand:SF 0 "register_operand" "=f")
7518 (minus:SF (match_operand:SF 1 "register_operand" "f")
7519 (match_operand:SF 2 "register_operand" "f")))]
7521 "fsubs\\t%1, %2, %0"
7522 [(set_attr "type" "fp")
7523 (set_attr "length" "1")])
7525 (define_expand "multf3"
7526 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7527 (mult:TF (match_operand:TF 1 "general_operand" "")
7528 (match_operand:TF 2 "general_operand" "")))]
7529 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7532 if (! TARGET_HARD_QUAD)
7534 rtx slot0, slot1, slot2;
7536 if (GET_CODE (operands[0]) != MEM)
7537 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7539 slot0 = operands[0];
7540 if (GET_CODE (operands[1]) != MEM)
7542 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7543 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7546 slot1 = operands[1];
7547 if (GET_CODE (operands[2]) != MEM)
7549 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7550 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7553 slot2 = operands[2];
7555 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_mul\"), 0,
7557 XEXP (slot0, 0), Pmode,
7558 XEXP (slot1, 0), Pmode,
7559 XEXP (slot2, 0), Pmode);
7561 if (GET_CODE (operands[0]) != MEM)
7562 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7567 (define_insn "*multf3_hq"
7568 [(set (match_operand:TF 0 "register_operand" "=e")
7569 (mult:TF (match_operand:TF 1 "register_operand" "e")
7570 (match_operand:TF 2 "register_operand" "e")))]
7571 "TARGET_FPU && TARGET_HARD_QUAD"
7572 "fmulq\\t%1, %2, %0"
7573 [(set_attr "type" "fpmul")
7574 (set_attr "length" "1")])
7576 (define_insn "muldf3"
7577 [(set (match_operand:DF 0 "register_operand" "=e")
7578 (mult:DF (match_operand:DF 1 "register_operand" "e")
7579 (match_operand:DF 2 "register_operand" "e")))]
7581 "fmuld\\t%1, %2, %0"
7582 [(set_attr "type" "fpmul")
7583 (set_attr "length" "1")])
7585 (define_insn "mulsf3"
7586 [(set (match_operand:SF 0 "register_operand" "=f")
7587 (mult:SF (match_operand:SF 1 "register_operand" "f")
7588 (match_operand:SF 2 "register_operand" "f")))]
7590 "fmuls\\t%1, %2, %0"
7591 [(set_attr "type" "fpmul")
7592 (set_attr "length" "1")])
7594 (define_insn "*muldf3_extend"
7595 [(set (match_operand:DF 0 "register_operand" "=e")
7596 (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
7597 (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
7598 "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
7599 "fsmuld\\t%1, %2, %0"
7600 [(set_attr "type" "fpmul")
7601 (set_attr "length" "1")])
7603 (define_insn "*multf3_extend"
7604 [(set (match_operand:TF 0 "register_operand" "=e")
7605 (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
7606 (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
7607 "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
7608 "fdmulq\\t%1, %2, %0"
7609 [(set_attr "type" "fpmul")
7610 (set_attr "length" "1")])
7612 (define_expand "divtf3"
7613 [(set (match_operand:TF 0 "nonimmediate_operand" "")
7614 (div:TF (match_operand:TF 1 "general_operand" "")
7615 (match_operand:TF 2 "general_operand" "")))]
7616 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7619 if (! TARGET_HARD_QUAD)
7621 rtx slot0, slot1, slot2;
7623 if (GET_CODE (operands[0]) != MEM)
7624 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7626 slot0 = operands[0];
7627 if (GET_CODE (operands[1]) != MEM)
7629 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7630 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7633 slot1 = operands[1];
7634 if (GET_CODE (operands[2]) != MEM)
7636 slot2 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7637 emit_insn (gen_rtx_SET (VOIDmode, slot2, operands[2]));
7640 slot2 = operands[2];
7642 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_div\"), 0,
7644 XEXP (slot0, 0), Pmode,
7645 XEXP (slot1, 0), Pmode,
7646 XEXP (slot2, 0), Pmode);
7648 if (GET_CODE (operands[0]) != MEM)
7649 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7654 ;; don't have timing for quad-prec. divide.
7655 (define_insn "*divtf3_hq"
7656 [(set (match_operand:TF 0 "register_operand" "=e")
7657 (div:TF (match_operand:TF 1 "register_operand" "e")
7658 (match_operand:TF 2 "register_operand" "e")))]
7659 "TARGET_FPU && TARGET_HARD_QUAD"
7660 "fdivq\\t%1, %2, %0"
7661 [(set_attr "type" "fpdivd")
7662 (set_attr "length" "1")])
7664 (define_insn "divdf3"
7665 [(set (match_operand:DF 0 "register_operand" "=e")
7666 (div:DF (match_operand:DF 1 "register_operand" "e")
7667 (match_operand:DF 2 "register_operand" "e")))]
7669 "fdivd\\t%1, %2, %0"
7670 [(set_attr "type" "fpdivd")
7671 (set_attr "length" "1")])
7673 (define_insn "divsf3"
7674 [(set (match_operand:SF 0 "register_operand" "=f")
7675 (div:SF (match_operand:SF 1 "register_operand" "f")
7676 (match_operand:SF 2 "register_operand" "f")))]
7678 "fdivs\\t%1, %2, %0"
7679 [(set_attr "type" "fpdivs")
7680 (set_attr "length" "1")])
7682 (define_expand "negtf2"
7683 [(set (match_operand:TF 0 "register_operand" "=e,e")
7684 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7688 (define_insn "*negtf2_notv9"
7689 [(set (match_operand:TF 0 "register_operand" "=e,e")
7690 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7691 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7697 [(set_attr "type" "fpmove")
7698 (set_attr "length" "1,2")])
7701 [(set (match_operand:TF 0 "register_operand" "")
7702 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7706 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7707 [(set (match_dup 2) (neg:SF (match_dup 3)))
7708 (set (match_dup 4) (match_dup 5))
7709 (set (match_dup 6) (match_dup 7))]
7710 "if (GET_CODE (operands[0]) == SUBREG)
7711 operands[0] = alter_subreg (operands[0]);
7712 if (GET_CODE (operands[1]) == SUBREG)
7713 operands[1] = alter_subreg (operands[1]);
7714 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7715 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7716 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7717 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7718 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7719 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7721 (define_insn "*negtf2_v9"
7722 [(set (match_operand:TF 0 "register_operand" "=e,e")
7723 (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
7724 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7725 "TARGET_FPU && TARGET_V9"
7729 [(set_attr "type" "fpmove")
7730 (set_attr "length" "1,2")])
7733 [(set (match_operand:TF 0 "register_operand" "")
7734 (neg:TF (match_operand:TF 1 "register_operand" "")))]
7738 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7739 [(set (match_dup 2) (neg:DF (match_dup 3)))
7740 (set (match_dup 4) (match_dup 5))]
7741 "if (GET_CODE (operands[0]) == SUBREG)
7742 operands[0] = alter_subreg (operands[0]);
7743 if (GET_CODE (operands[1]) == SUBREG)
7744 operands[1] = alter_subreg (operands[1]);
7745 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7746 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7747 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7748 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7750 (define_expand "negdf2"
7751 [(set (match_operand:DF 0 "register_operand" "")
7752 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7756 (define_insn "*negdf2_notv9"
7757 [(set (match_operand:DF 0 "register_operand" "=e,e")
7758 (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
7759 "TARGET_FPU && ! TARGET_V9"
7763 [(set_attr "type" "fpmove")
7764 (set_attr "length" "1,2")])
7767 [(set (match_operand:DF 0 "register_operand" "")
7768 (neg:DF (match_operand:DF 1 "register_operand" "")))]
7772 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7773 [(set (match_dup 2) (neg:SF (match_dup 3)))
7774 (set (match_dup 4) (match_dup 5))]
7775 "if (GET_CODE (operands[0]) == SUBREG)
7776 operands[0] = alter_subreg (operands[0]);
7777 if (GET_CODE (operands[1]) == SUBREG)
7778 operands[1] = alter_subreg (operands[1]);
7779 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7780 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7781 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7782 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7784 (define_insn "*negdf2_v9"
7785 [(set (match_operand:DF 0 "register_operand" "=e")
7786 (neg:DF (match_operand:DF 1 "register_operand" "e")))]
7787 "TARGET_FPU && TARGET_V9"
7789 [(set_attr "type" "fpmove")
7790 (set_attr "length" "1")])
7792 (define_insn "negsf2"
7793 [(set (match_operand:SF 0 "register_operand" "=f")
7794 (neg:SF (match_operand:SF 1 "register_operand" "f")))]
7797 [(set_attr "type" "fpmove")
7798 (set_attr "length" "1")])
7800 (define_expand "abstf2"
7801 [(set (match_operand:TF 0 "register_operand" "")
7802 (abs:TF (match_operand:TF 1 "register_operand" "")))]
7806 (define_insn "*abstf2_notv9"
7807 [(set (match_operand:TF 0 "register_operand" "=e,e")
7808 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7809 ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
7810 "TARGET_FPU && ! TARGET_V9"
7814 [(set_attr "type" "fpmove")
7815 (set_attr "length" "1,2")])
7818 [(set (match_operand:TF 0 "register_operand" "=e,e")
7819 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7823 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7824 [(set (match_dup 2) (abs:SF (match_dup 3)))
7825 (set (match_dup 4) (match_dup 5))
7826 (set (match_dup 6) (match_dup 7))]
7827 "if (GET_CODE (operands[0]) == SUBREG)
7828 operands[0] = alter_subreg (operands[0]);
7829 if (GET_CODE (operands[1]) == SUBREG)
7830 operands[1] = alter_subreg (operands[1]);
7831 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7832 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7833 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7834 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
7835 operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7836 operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7838 (define_insn "*abstf2_hq_v9"
7839 [(set (match_operand:TF 0 "register_operand" "=e,e")
7840 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7841 "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
7845 [(set_attr "type" "fpmove")
7846 (set_attr "length" "1")])
7848 (define_insn "*abstf2_v9"
7849 [(set (match_operand:TF 0 "register_operand" "=e,e")
7850 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7851 "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
7855 [(set_attr "type" "fpmove")
7856 (set_attr "length" "1,2")])
7859 [(set (match_operand:TF 0 "register_operand" "=e,e")
7860 (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
7864 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7865 [(set (match_dup 2) (abs:DF (match_dup 3)))
7866 (set (match_dup 4) (match_dup 5))]
7867 "if (GET_CODE (operands[0]) == SUBREG)
7868 operands[0] = alter_subreg (operands[0]);
7869 if (GET_CODE (operands[1]) == SUBREG)
7870 operands[1] = alter_subreg (operands[1]);
7871 operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
7872 operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
7873 operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
7874 operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);")
7876 (define_expand "absdf2"
7877 [(set (match_operand:DF 0 "register_operand" "")
7878 (abs:DF (match_operand:DF 1 "register_operand" "")))]
7882 (define_insn "*absdf2_notv9"
7883 [(set (match_operand:DF 0 "register_operand" "=e,e")
7884 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7885 "TARGET_FPU && ! TARGET_V9"
7889 [(set_attr "type" "fpmove")
7890 (set_attr "length" "1,2")])
7893 [(set (match_operand:DF 0 "register_operand" "=e,e")
7894 (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
7898 && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
7899 [(set (match_dup 2) (abs:SF (match_dup 3)))
7900 (set (match_dup 4) (match_dup 5))]
7901 "if (GET_CODE (operands[0]) == SUBREG)
7902 operands[0] = alter_subreg (operands[0]);
7903 if (GET_CODE (operands[1]) == SUBREG)
7904 operands[1] = alter_subreg (operands[1]);
7905 operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
7906 operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
7907 operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
7908 operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);")
7910 (define_insn "*absdf2_v9"
7911 [(set (match_operand:DF 0 "register_operand" "=e")
7912 (abs:DF (match_operand:DF 1 "register_operand" "e")))]
7913 "TARGET_FPU && TARGET_V9"
7915 [(set_attr "type" "fpmove")
7916 (set_attr "length" "1")])
7918 (define_insn "abssf2"
7919 [(set (match_operand:SF 0 "register_operand" "=f")
7920 (abs:SF (match_operand:SF 1 "register_operand" "f")))]
7923 [(set_attr "type" "fpmove")
7924 (set_attr "length" "1")])
7926 (define_expand "sqrttf2"
7927 [(set (match_operand:TF 0 "register_operand" "=e")
7928 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7929 "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
7932 if (! TARGET_HARD_QUAD)
7936 if (GET_CODE (operands[0]) != MEM)
7937 slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7939 slot0 = operands[0];
7940 if (GET_CODE (operands[1]) != MEM)
7942 slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
7943 emit_insn (gen_rtx_SET (VOIDmode, slot1, operands[1]));
7946 slot1 = operands[1];
7948 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, \"_Qp_sqrt\"), 0,
7950 XEXP (slot0, 0), Pmode,
7951 XEXP (slot1, 0), Pmode);
7953 if (GET_CODE (operands[0]) != MEM)
7954 emit_insn (gen_rtx_SET (VOIDmode, operands[0], slot0));
7959 (define_insn "*sqrttf2_hq"
7960 [(set (match_operand:TF 0 "register_operand" "=e")
7961 (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
7962 "TARGET_FPU && TARGET_HARD_QUAD"
7964 [(set_attr "type" "fpsqrtd")
7965 (set_attr "length" "1")])
7967 (define_insn "sqrtdf2"
7968 [(set (match_operand:DF 0 "register_operand" "=e")
7969 (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7972 [(set_attr "type" "fpsqrtd")
7973 (set_attr "length" "1")])
7975 (define_insn "sqrtsf2"
7976 [(set (match_operand:SF 0 "register_operand" "=f")
7977 (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7980 [(set_attr "type" "fpsqrts")
7981 (set_attr "length" "1")])
7983 ;;- arithmetic shift instructions
7985 (define_insn "ashlsi3"
7986 [(set (match_operand:SI 0 "register_operand" "=r")
7987 (ashift:SI (match_operand:SI 1 "register_operand" "r")
7988 (match_operand:SI 2 "arith_operand" "rI")))]
7992 if (GET_CODE (operands[2]) == CONST_INT
7993 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
7994 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7996 return \"sll\\t%1, %2, %0\";
7998 [(set_attr "type" "shift")
7999 (set_attr "length" "1")])
8001 ;; We special case multiplication by two, as add can be done
8002 ;; in both ALUs, while shift only in IEU0 on UltraSPARC.
8003 (define_insn "*ashlsi3_const1"
8004 [(set (match_operand:SI 0 "register_operand" "=r")
8005 (ashift:SI (match_operand:SI 1 "register_operand" "r")
8009 [(set_attr "type" "binary")
8010 (set_attr "length" "1")])
8012 (define_expand "ashldi3"
8013 [(set (match_operand:DI 0 "register_operand" "=r")
8014 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8015 (match_operand:SI 2 "arith_operand" "rI")))]
8016 "TARGET_ARCH64 || TARGET_V8PLUS"
8019 if (! TARGET_ARCH64)
8021 if (GET_CODE (operands[2]) == CONST_INT)
8023 emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
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 "*ashldi3_const1"
8031 [(set (match_operand:DI 0 "register_operand" "=r")
8032 (ashift:DI (match_operand:DI 1 "register_operand" "r")
8036 [(set_attr "type" "binary")
8037 (set_attr "length" "1")])
8039 (define_insn "*ashldi3_sp64"
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")))]
8046 if (GET_CODE (operands[2]) == CONST_INT
8047 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8048 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8050 return \"sllx\\t%1, %2, %0\";
8052 [(set_attr "type" "shift")
8053 (set_attr "length" "1")])
8056 (define_insn "ashldi3_v8plus"
8057 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8058 (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8059 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8060 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8062 "*return sparc_v8plus_shift (operands, insn, \"sllx\");"
8063 [(set_attr "length" "5,5,6")])
8065 ;; Optimize (1LL<<x)-1
8066 ;; XXX this also needs to be fixed to handle equal subregs
8067 ;; XXX first before we could re-enable it.
8069 [(set (match_operand:DI 0 "register_operand" "=h")
8070 (plus:DI (ashift:DI (const_int 1)
8071 (match_operand:SI 2 "arith_operand" "rI"))
8073 "0 && TARGET_V8PLUS"
8076 if (GET_CODE (operands[2]) == REG && REGNO (operands[2]) == REGNO (operands[0]))
8077 return \"mov 1,%L0\;sllx %L0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
8078 return \"mov 1,%H0\;sllx %H0,%2,%L0\;sub %L0,1,%L0\;srlx %L0,32,%H0\";
8080 [(set_attr "length" "4")])
8082 (define_insn "*cmp_cc_ashift_1"
8083 [(set (reg:CC_NOOV 100)
8084 (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
8088 "addcc\\t%0, %0, %%g0"
8089 [(set_attr "type" "compare")
8090 (set_attr "length" "1")])
8092 (define_insn "*cmp_cc_set_ashift_1"
8093 [(set (reg:CC_NOOV 100)
8094 (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
8097 (set (match_operand:SI 0 "register_operand" "=r")
8098 (ashift:SI (match_dup 1) (const_int 1)))]
8100 "addcc\\t%1, %1, %0"
8101 [(set_attr "type" "compare")
8102 (set_attr "length" "1")])
8104 (define_insn "ashrsi3"
8105 [(set (match_operand:SI 0 "register_operand" "=r")
8106 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8107 (match_operand:SI 2 "arith_operand" "rI")))]
8111 if (GET_CODE (operands[2]) == CONST_INT
8112 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8113 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8115 return \"sra\\t%1, %2, %0\";
8117 [(set_attr "type" "shift")
8118 (set_attr "length" "1")])
8120 (define_insn "*ashrsi3_extend"
8121 [(set (match_operand:DI 0 "register_operand" "=r")
8122 (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
8123 (match_operand:SI 2 "arith_operand" "r"))))]
8126 [(set_attr "type" "shift")
8127 (set_attr "length" "1")])
8129 ;; This handles the case as above, but with constant shift instead of
8130 ;; register. Combiner "simplifies" it for us a little bit though.
8131 (define_insn "*ashrsi3_extend2"
8132 [(set (match_operand:DI 0 "register_operand" "=r")
8133 (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8135 (match_operand:SI 2 "small_int_or_double" "n")))]
8137 && ((GET_CODE (operands[2]) == CONST_INT
8138 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
8139 || (GET_CODE (operands[2]) == CONST_DOUBLE
8140 && !CONST_DOUBLE_HIGH (operands[2])
8141 && CONST_DOUBLE_LOW (operands[2]) >= 32
8142 && CONST_DOUBLE_LOW (operands[2]) < 64))"
8145 operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
8147 return \"sra\\t%1, %2, %0\";
8149 [(set_attr "type" "shift")
8150 (set_attr "length" "1")])
8152 (define_expand "ashrdi3"
8153 [(set (match_operand:DI 0 "register_operand" "=r")
8154 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8155 (match_operand:SI 2 "arith_operand" "rI")))]
8156 "TARGET_ARCH64 || TARGET_V8PLUS"
8159 if (! TARGET_ARCH64)
8161 if (GET_CODE (operands[2]) == CONST_INT)
8162 FAIL; /* prefer generic code in this case */
8163 emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
8169 [(set (match_operand:DI 0 "register_operand" "=r")
8170 (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8171 (match_operand:SI 2 "arith_operand" "rI")))]
8175 if (GET_CODE (operands[2]) == CONST_INT
8176 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8177 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8179 return \"srax\\t%1, %2, %0\";
8181 [(set_attr "type" "shift")
8182 (set_attr "length" "1")])
8185 (define_insn "ashrdi3_v8plus"
8186 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8187 (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8188 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8189 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8191 "*return sparc_v8plus_shift (operands, insn, \"srax\");"
8192 [(set_attr "length" "5,5,6")])
8194 (define_insn "lshrsi3"
8195 [(set (match_operand:SI 0 "register_operand" "=r")
8196 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8197 (match_operand:SI 2 "arith_operand" "rI")))]
8201 if (GET_CODE (operands[2]) == CONST_INT
8202 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31)
8203 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
8205 return \"srl\\t%1, %2, %0\";
8207 [(set_attr "type" "shift")
8208 (set_attr "length" "1")])
8210 ;; This handles the case where
8211 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
8212 ;; but combiner "simplifies" it for us.
8213 (define_insn "*lshrsi3_extend"
8214 [(set (match_operand:DI 0 "register_operand" "=r")
8215 (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8216 (match_operand:SI 2 "arith_operand" "r")) 0)
8217 (match_operand 3 "" "")))]
8219 && ((GET_CODE (operands[3]) == CONST_DOUBLE
8220 && CONST_DOUBLE_HIGH (operands[3]) == 0
8221 && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
8222 #if HOST_BITS_PER_WIDE_INT >= 64
8223 || (GET_CODE (operands[3]) == CONST_INT
8224 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff)
8228 [(set_attr "type" "shift")
8229 (set_attr "length" "1")])
8231 ;; This handles the case where
8232 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
8233 ;; but combiner "simplifies" it for us.
8234 (define_insn "*lshrsi3_extend2"
8235 [(set (match_operand:DI 0 "register_operand" "=r")
8236 (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
8237 (match_operand 2 "small_int_or_double" "n")
8240 && ((GET_CODE (operands[2]) == CONST_INT
8241 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8242 || (GET_CODE (operands[2]) == CONST_DOUBLE
8243 && CONST_DOUBLE_HIGH (operands[2]) == 0
8244 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8247 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
8249 return \"srl\\t%1, %2, %0\";
8251 [(set_attr "type" "shift")
8252 (set_attr "length" "1")])
8254 (define_expand "lshrdi3"
8255 [(set (match_operand:DI 0 "register_operand" "=r")
8256 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8257 (match_operand:SI 2 "arith_operand" "rI")))]
8258 "TARGET_ARCH64 || TARGET_V8PLUS"
8261 if (! TARGET_ARCH64)
8263 if (GET_CODE (operands[2]) == CONST_INT)
8265 emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
8271 [(set (match_operand:DI 0 "register_operand" "=r")
8272 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8273 (match_operand:SI 2 "arith_operand" "rI")))]
8277 if (GET_CODE (operands[2]) == CONST_INT
8278 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63)
8279 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
8281 return \"srlx\\t%1, %2, %0\";
8283 [(set_attr "type" "shift")
8284 (set_attr "length" "1")])
8287 (define_insn "lshrdi3_v8plus"
8288 [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
8289 (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
8290 (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
8291 (clobber (match_scratch:SI 3 "=X,X,&h"))]
8293 "*return sparc_v8plus_shift (operands, insn, \"srlx\");"
8294 [(set_attr "length" "5,5,6")])
8297 [(set (match_operand:SI 0 "register_operand" "=r")
8298 (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8300 (match_operand:SI 2 "small_int_or_double" "n")))]
8302 && ((GET_CODE (operands[2]) == CONST_INT
8303 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8304 || (GET_CODE (operands[2]) == CONST_DOUBLE
8305 && !CONST_DOUBLE_HIGH (operands[2])
8306 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8309 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8311 return \"srax\\t%1, %2, %0\";
8313 [(set_attr "type" "shift")
8314 (set_attr "length" "1")])
8317 [(set (match_operand:SI 0 "register_operand" "=r")
8318 (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8320 (match_operand:SI 2 "small_int_or_double" "n")))]
8322 && ((GET_CODE (operands[2]) == CONST_INT
8323 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
8324 || (GET_CODE (operands[2]) == CONST_DOUBLE
8325 && !CONST_DOUBLE_HIGH (operands[2])
8326 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
8329 operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
8331 return \"srlx\\t%1, %2, %0\";
8333 [(set_attr "type" "shift")
8334 (set_attr "length" "1")])
8337 [(set (match_operand:SI 0 "register_operand" "=r")
8338 (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
8339 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8340 (match_operand:SI 3 "small_int_or_double" "n")))]
8342 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8343 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8344 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8345 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8348 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8350 return \"srax\\t%1, %2, %0\";
8352 [(set_attr "type" "shift")
8353 (set_attr "length" "1")])
8356 [(set (match_operand:SI 0 "register_operand" "=r")
8357 (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8358 (match_operand:SI 2 "small_int_or_double" "n")) 0)
8359 (match_operand:SI 3 "small_int_or_double" "n")))]
8361 && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
8362 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
8363 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
8364 && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
8367 operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
8369 return \"srlx\\t%1, %2, %0\";
8371 [(set_attr "type" "shift")
8372 (set_attr "length" "1")])
8374 ;; Unconditional and other jump instructions
8375 ;; On the Sparc, by setting the annul bit on an unconditional branch, the
8376 ;; following insn is never executed. This saves us a nop. Dbx does not
8377 ;; handle such branches though, so we only use them when optimizing.
8379 [(set (pc) (label_ref (match_operand 0 "" "")))]
8383 /* TurboSparc is reported to have problems with
8386 i.e. an empty loop with the annul bit set. The workaround is to use
8390 if (! TARGET_V9 && flag_delayed_branch
8391 && (insn_addresses[INSN_UID (operands[0])]
8392 == insn_addresses[INSN_UID (insn)]))
8393 return \"b\\t%l0%#\";
8395 return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\";
8397 [(set_attr "type" "uncond_branch")])
8399 (define_expand "tablejump"
8400 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
8401 (use (label_ref (match_operand 1 "" "")))])]
8405 if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
8408 /* In pic mode, our address differences are against the base of the
8409 table. Add that base value back in; CSE ought to be able to combine
8410 the two address loads. */
8414 tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
8416 if (CASE_VECTOR_MODE != Pmode)
8417 tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
8418 tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
8419 operands[0] = memory_address (Pmode, tmp);
8423 (define_insn "*tablejump_sp32"
8424 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
8425 (use (label_ref (match_operand 1 "" "")))]
8428 [(set_attr "type" "uncond_branch")])
8430 (define_insn "*tablejump_sp64"
8431 [(set (pc) (match_operand:DI 0 "address_operand" "p"))
8432 (use (label_ref (match_operand 1 "" "")))]
8435 [(set_attr "type" "uncond_branch")])
8437 ;; This pattern recognizes the "instruction" that appears in
8438 ;; a function call that wants a structure value,
8439 ;; to inform the called function if compiled with Sun CC.
8440 ;(define_insn "*unimp_insn"
8441 ; [(match_operand:SI 0 "immediate_operand" "")]
8442 ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
8444 ; [(set_attr "type" "marker")])
8446 ;;- jump to subroutine
8447 (define_expand "call"
8448 ;; Note that this expression is not used for generating RTL.
8449 ;; All the RTL is generated explicitly below.
8450 [(call (match_operand 0 "call_operand" "")
8451 (match_operand 3 "" "i"))]
8452 ;; operands[2] is next_arg_register
8453 ;; operands[3] is struct_value_size_rtx.
8457 rtx fn_rtx, nregs_rtx;
8459 if (GET_MODE (operands[0]) != FUNCTION_MODE)
8462 if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
8464 /* This is really a PIC sequence. We want to represent
8465 it as a funny jump so its delay slots can be filled.
8467 ??? But if this really *is* a CALL, will not it clobber the
8468 call-clobbered registers? We lose this if it is a JUMP_INSN.
8469 Why cannot we have delay slots filled if it were a CALL? */
8471 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8476 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8478 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8484 gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
8485 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8489 fn_rtx = operands[0];
8491 /* Count the number of parameter registers being used by this call.
8492 if that argument is NULL, it means we are using them all, which
8493 means 6 on the sparc. */
8496 nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
8498 nregs_rtx = GEN_INT (6);
8500 nregs_rtx = const0_rtx;
8503 if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
8507 gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8509 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8514 gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
8515 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
8519 /* If this call wants a structure value,
8520 emit an unimp insn to let the called function know about this. */
8521 if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
8523 rtx insn = emit_insn (operands[3]);
8524 SCHED_GROUP_P (insn) = 1;
8531 ;; We can't use the same pattern for these two insns, because then registers
8532 ;; in the address may not be properly reloaded.
8534 (define_insn "*call_address_sp32"
8535 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8536 (match_operand 1 "" ""))
8537 (clobber (reg:SI 15))]
8538 ;;- Do not use operand 1 for most machines.
8541 [(set_attr "type" "call")])
8543 (define_insn "*call_symbolic_sp32"
8544 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8545 (match_operand 1 "" ""))
8546 (clobber (reg:SI 15))]
8547 ;;- Do not use operand 1 for most machines.
8550 [(set_attr "type" "call")])
8552 (define_insn "*call_address_sp64"
8553 [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
8554 (match_operand 1 "" ""))
8555 (clobber (reg:DI 15))]
8556 ;;- Do not use operand 1 for most machines.
8559 [(set_attr "type" "call")])
8561 (define_insn "*call_symbolic_sp64"
8562 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
8563 (match_operand 1 "" ""))
8564 (clobber (reg:DI 15))]
8565 ;;- Do not use operand 1 for most machines.
8568 [(set_attr "type" "call")])
8570 ;; This is a call that wants a structure value.
8571 ;; There is no such critter for v9 (??? we may need one anyway).
8572 (define_insn "*call_address_struct_value_sp32"
8573 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8574 (match_operand 1 "" ""))
8575 (match_operand 2 "immediate_operand" "")
8576 (clobber (reg:SI 15))]
8577 ;;- Do not use operand 1 for most machines.
8578 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8579 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8580 [(set_attr "type" "call_no_delay_slot")])
8582 ;; This is a call that wants a structure value.
8583 ;; There is no such critter for v9 (??? we may need one anyway).
8584 (define_insn "*call_symbolic_struct_value_sp32"
8585 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8586 (match_operand 1 "" ""))
8587 (match_operand 2 "immediate_operand" "")
8588 (clobber (reg:SI 15))]
8589 ;;- Do not use operand 1 for most machines.
8590 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
8591 "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2"
8592 [(set_attr "type" "call_no_delay_slot")])
8594 ;; This is a call that may want a structure value. This is used for
8596 (define_insn "*call_address_untyped_struct_value_sp32"
8597 [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
8598 (match_operand 1 "" ""))
8599 (match_operand 2 "immediate_operand" "")
8600 (clobber (reg:SI 15))]
8601 ;;- Do not use operand 1 for most machines.
8602 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8603 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8604 [(set_attr "type" "call_no_delay_slot")])
8606 ;; This is a call that wants a structure value.
8607 (define_insn "*call_symbolic_untyped_struct_value_sp32"
8608 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8609 (match_operand 1 "" ""))
8610 (match_operand 2 "immediate_operand" "")
8611 (clobber (reg:SI 15))]
8612 ;;- Do not use operand 1 for most machines.
8613 "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
8614 "call\\t%a0, %1\\n\\tnop\\n\\tnop"
8615 [(set_attr "type" "call_no_delay_slot")])
8617 (define_expand "call_value"
8618 ;; Note that this expression is not used for generating RTL.
8619 ;; All the RTL is generated explicitly below.
8620 [(set (match_operand 0 "register_operand" "=rf")
8621 (call (match_operand:SI 1 "" "")
8622 (match_operand 4 "" "")))]
8623 ;; operand 2 is stack_size_rtx
8624 ;; operand 3 is next_arg_register
8628 rtx fn_rtx, nregs_rtx;
8631 if (GET_MODE (operands[1]) != FUNCTION_MODE)
8634 fn_rtx = operands[1];
8638 nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
8640 nregs_rtx = GEN_INT (6);
8642 nregs_rtx = const0_rtx;
8646 gen_rtx_SET (VOIDmode, operands[0],
8647 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
8648 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
8650 emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
8655 (define_insn "*call_value_address_sp32"
8656 [(set (match_operand 0 "" "=rf")
8657 (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
8658 (match_operand 2 "" "")))
8659 (clobber (reg:SI 15))]
8660 ;;- Do not use operand 2 for most machines.
8663 [(set_attr "type" "call")])
8665 (define_insn "*call_value_symbolic_sp32"
8666 [(set (match_operand 0 "" "=rf")
8667 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8668 (match_operand 2 "" "")))
8669 (clobber (reg:SI 15))]
8670 ;;- Do not use operand 2 for most machines.
8673 [(set_attr "type" "call")])
8675 (define_insn "*call_value_address_sp64"
8676 [(set (match_operand 0 "" "")
8677 (call (mem:SI (match_operand:DI 1 "address_operand" "p"))
8678 (match_operand 2 "" "")))
8679 (clobber (reg:DI 15))]
8680 ;;- Do not use operand 2 for most machines.
8683 [(set_attr "type" "call")])
8685 (define_insn "*call_value_symbolic_sp64"
8686 [(set (match_operand 0 "" "")
8687 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
8688 (match_operand 2 "" "")))
8689 (clobber (reg:DI 15))]
8690 ;;- Do not use operand 2 for most machines.
8693 [(set_attr "type" "call")])
8695 (define_expand "untyped_call"
8696 [(parallel [(call (match_operand 0 "" "")
8698 (match_operand 1 "" "")
8699 (match_operand 2 "" "")])]
8705 /* Pass constm1 to indicate that it may expect a structure value, but
8706 we don't know what size it is. */
8707 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
8709 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8711 rtx set = XVECEXP (operands[2], 0, i);
8712 emit_move_insn (SET_DEST (set), SET_SRC (set));
8715 /* The optimizer does not know that the call sets the function value
8716 registers we stored in the result block. We avoid problems by
8717 claiming that all hard registers are used and clobbered at this
8719 emit_insn (gen_blockage ());
8725 (define_expand "sibcall"
8726 [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
8731 (define_insn "*sibcall_symbolic_sp32"
8732 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
8733 (match_operand 1 "" ""))
8736 "* return output_sibcall(insn, operands[0]);"
8737 [(set_attr "type" "sibcall")])
8739 (define_insn "*sibcall_symbolic_sp64"
8740 [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
8741 (match_operand 1 "" ""))
8744 "* return output_sibcall(insn, operands[0]);"
8745 [(set_attr "type" "sibcall")])
8747 (define_expand "sibcall_value"
8748 [(parallel [(set (match_operand 0 "register_operand" "=rf")
8749 (call (match_operand:SI 1 "" "") (const_int 0)))
8754 (define_insn "*sibcall_value_symbolic_sp32"
8755 [(set (match_operand 0 "" "=rf")
8756 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
8757 (match_operand 2 "" "")))
8760 "* return output_sibcall(insn, operands[1]);"
8761 [(set_attr "type" "sibcall")])
8763 (define_insn "*sibcall_value_symbolic_sp64"
8764 [(set (match_operand 0 "" "")
8765 (call (mem:SI (match_operand:DI 1 "symbolic_operand" "s"))
8766 (match_operand 2 "" "")))
8769 "* return output_sibcall(insn, operands[1]);"
8770 [(set_attr "type" "sibcall")])
8772 (define_expand "sibcall_epilogue"
8777 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8778 ;; all of memory. This blocks insns from being moved across this point.
8780 (define_insn "blockage"
8781 [(unspec_volatile [(const_int 0)] 0)]
8784 [(set_attr "length" "0")])
8786 ;; Prepare to return any type including a structure value.
8788 (define_expand "untyped_return"
8789 [(match_operand:BLK 0 "memory_operand" "")
8790 (match_operand 1 "" "")]
8794 rtx valreg1 = gen_rtx_REG (DImode, 24);
8795 rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
8796 rtx result = operands[0];
8798 if (! TARGET_ARCH64)
8800 rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
8802 rtx value = gen_reg_rtx (SImode);
8804 /* Fetch the instruction where we will return to and see if it's an unimp
8805 instruction (the most significant 10 bits will be zero). If so,
8806 update the return address to skip the unimp instruction. */
8807 emit_move_insn (value,
8808 gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
8809 emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
8810 emit_insn (gen_update_return (rtnreg, value));
8813 /* Reload the function value registers. */
8814 emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
8815 emit_move_insn (valreg2,
8816 change_address (result, TARGET_ARCH64 ? TFmode : DFmode,
8817 plus_constant (XEXP (result, 0), 8)));
8819 /* Put USE insns before the return. */
8820 emit_insn (gen_rtx_USE (VOIDmode, valreg1));
8821 emit_insn (gen_rtx_USE (VOIDmode, valreg2));
8823 /* Construct the return. */
8824 expand_null_return ();
8829 ;; This is a bit of a hack. We're incrementing a fixed register (%i7),
8830 ;; and parts of the compiler don't want to believe that the add is needed.
8832 (define_insn "update_return"
8833 [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
8834 (match_operand:SI 1 "register_operand" "r")] 1)]
8836 "cmp %1,0\;be,a .+8\;add %0,4,%0"
8837 [(set_attr "type" "multi")])
8839 (define_insn "return"
8843 "* return output_return (operands);"
8844 [(set_attr "type" "return")])
8847 [(set (match_operand:SI 0 "register_operand" "=r")
8848 (match_operand:SI 1 "arith_operand" "rI"))
8850 (use (reg:SI 31))])]
8851 "sparc_return_peephole_ok (operands[0], operands[1])"
8852 "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0")
8858 [(set_attr "type" "ialu")
8859 (set_attr "length" "1")])
8861 (define_expand "indirect_jump"
8862 [(set (pc) (match_operand 0 "address_operand" "p"))]
8866 (define_insn "*branch_sp32"
8867 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
8870 [(set_attr "type" "uncond_branch")])
8872 (define_insn "*branch_sp64"
8873 [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
8876 [(set_attr "type" "uncond_branch")])
8878 ;; ??? Doesn't work with -mflat.
8879 (define_expand "nonlocal_goto"
8880 [(match_operand:SI 0 "general_operand" "")
8881 (match_operand:SI 1 "general_operand" "")
8882 (match_operand:SI 2 "general_operand" "")
8883 (match_operand:SI 3 "" "")]
8888 rtx chain = operands[0];
8890 rtx fp = operands[1];
8891 rtx stack = operands[2];
8892 rtx lab = operands[3];
8895 /* Trap instruction to flush all the register windows. */
8896 emit_insn (gen_flush_register_windows ());
8898 /* Load the fp value for the containing fn into %fp. This is needed
8899 because STACK refers to %fp. Note that virtual register instantiation
8900 fails if the virtual %fp isn't set from a register. */
8901 if (GET_CODE (fp) != REG)
8902 fp = force_reg (Pmode, fp);
8903 emit_move_insn (virtual_stack_vars_rtx, fp);
8905 /* Find the containing function's current nonlocal goto handler,
8906 which will do any cleanups and then jump to the label. */
8907 labreg = gen_rtx_REG (Pmode, 8);
8908 emit_move_insn (labreg, lab);
8910 /* Restore %fp from stack pointer value for containing function.
8911 The restore insn that follows will move this to %sp,
8912 and reload the appropriate value into %fp. */
8913 emit_move_insn (frame_pointer_rtx, stack);
8915 /* USE of frame_pointer_rtx added for consistency; not clear if
8917 /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
8918 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
8921 /* Return, restoring reg window and jumping to goto handler. */
8922 if (TARGET_V9 && GET_CODE (chain) == CONST_INT
8923 && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
8925 emit_insn (gen_goto_handler_and_restore_v9 (labreg, static_chain_rtx,
8930 /* Put in the static chain register the nonlocal label address. */
8931 emit_move_insn (static_chain_rtx, chain);
8934 emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
8935 emit_insn (gen_goto_handler_and_restore (labreg));
8940 ;; Special trap insn to flush register windows.
8941 (define_insn "flush_register_windows"
8942 [(unspec_volatile [(const_int 0)] 1)]
8944 "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";"
8945 [(set_attr "type" "misc")
8946 (set_attr "length" "1")])
8948 (define_insn "goto_handler_and_restore"
8949 [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
8950 "GET_MODE (operands[0]) == Pmode"
8951 "jmp\\t%0+0\\n\\trestore"
8952 [(set_attr "type" "misc")
8953 (set_attr "length" "2")])
8955 ;;(define_insn "goto_handler_and_restore_v9"
8956 ;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
8957 ;; (match_operand:SI 1 "register_operand" "=r,r")
8958 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8959 ;; "TARGET_V9 && ! TARGET_ARCH64"
8961 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8962 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8963 ;; [(set_attr "type" "misc")
8964 ;; (set_attr "length" "2,3")])
8966 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
8967 ;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
8968 ;; (match_operand:DI 1 "register_operand" "=r,r")
8969 ;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)]
8970 ;; "TARGET_V9 && TARGET_ARCH64"
8972 ;; return\\t%0+0\\n\\tmov\\t%2, %Y1
8973 ;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1"
8974 ;; [(set_attr "type" "misc")
8975 ;; (set_attr "length" "2,3")])
8977 ;; Pattern for use after a setjmp to store FP and the return register
8978 ;; into the stack area.
8980 (define_expand "setjmp"
8986 emit_insn (gen_setjmp_64 ());
8988 emit_insn (gen_setjmp_32 ());
8992 (define_expand "setjmp_32"
8993 [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
8994 (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
8997 { operands[0] = frame_pointer_rtx; }")
8999 (define_expand "setjmp_64"
9000 [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
9001 (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
9004 { operands[0] = frame_pointer_rtx; }")
9006 ;; Special pattern for the FLUSH instruction.
9008 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
9009 ; of the define_insn otherwise missing a mode. We make "flush", aka
9010 ; gen_flush, the default one since sparc_initialize_trampoline uses
9011 ; it on SImode mem values.
9013 (define_insn "flush"
9014 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 3)]
9016 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
9017 [(set_attr "type" "misc")])
9019 (define_insn "flushdi"
9020 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] 3)]
9022 "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";"
9023 [(set_attr "type" "misc")])
9028 ;; The scan instruction searches from the most significant bit while ffs
9029 ;; searches from the least significant bit. The bit index and treatment of
9030 ;; zero also differ. It takes at least 7 instructions to get the proper
9031 ;; result. Here is an obvious 8 instruction sequence.
9034 (define_insn "ffssi2"
9035 [(set (match_operand:SI 0 "register_operand" "=&r")
9036 (ffs:SI (match_operand:SI 1 "register_operand" "r")))
9037 (clobber (match_scratch:SI 2 "=&r"))]
9038 "TARGET_SPARCLITE || TARGET_SPARCLET"
9041 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\";
9043 [(set_attr "type" "multi")
9044 (set_attr "length" "8")])
9046 ;; ??? This should be a define expand, so that the extra instruction have
9047 ;; a chance of being optimized away.
9049 ;; Disabled because none of the UltraSparcs implement popc. The HAL R1
9050 ;; does, but no one uses that and we don't have a switch for it.
9052 ;(define_insn "ffsdi2"
9053 ; [(set (match_operand:DI 0 "register_operand" "=&r")
9054 ; (ffs:DI (match_operand:DI 1 "register_operand" "r")))
9055 ; (clobber (match_scratch:DI 2 "=&r"))]
9057 ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0"
9058 ; [(set_attr "type" "multi")
9059 ; (set_attr "length" "4")])
9063 ;; Peepholes go at the end.
9065 ;; Optimize consecutive loads or stores into ldd and std when possible.
9066 ;; The conditions in which we do this are very restricted and are
9067 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
9070 [(set (match_operand:SI 0 "memory_operand" "")
9072 (set (match_operand:SI 1 "memory_operand" "")
9075 && ! MEM_VOLATILE_P (operands[0])
9076 && ! MEM_VOLATILE_P (operands[1])
9077 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))"
9081 [(set (match_operand:SI 0 "memory_operand" "")
9083 (set (match_operand:SI 1 "memory_operand" "")
9086 && ! MEM_VOLATILE_P (operands[0])
9087 && ! MEM_VOLATILE_P (operands[1])
9088 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))"
9092 [(set (match_operand:SI 0 "register_operand" "=rf")
9093 (match_operand:SI 1 "memory_operand" ""))
9094 (set (match_operand:SI 2 "register_operand" "=rf")
9095 (match_operand:SI 3 "memory_operand" ""))]
9096 "registers_ok_for_ldd_peep (operands[0], operands[2])
9097 && ! MEM_VOLATILE_P (operands[1])
9098 && ! MEM_VOLATILE_P (operands[3])
9099 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9103 [(set (match_operand:SI 0 "memory_operand" "")
9104 (match_operand:SI 1 "register_operand" "rf"))
9105 (set (match_operand:SI 2 "memory_operand" "")
9106 (match_operand:SI 3 "register_operand" "rf"))]
9107 "registers_ok_for_ldd_peep (operands[1], operands[3])
9108 && ! MEM_VOLATILE_P (operands[0])
9109 && ! MEM_VOLATILE_P (operands[2])
9110 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9114 [(set (match_operand:SF 0 "register_operand" "=fr")
9115 (match_operand:SF 1 "memory_operand" ""))
9116 (set (match_operand:SF 2 "register_operand" "=fr")
9117 (match_operand:SF 3 "memory_operand" ""))]
9118 "registers_ok_for_ldd_peep (operands[0], operands[2])
9119 && ! MEM_VOLATILE_P (operands[1])
9120 && ! MEM_VOLATILE_P (operands[3])
9121 && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
9125 [(set (match_operand:SF 0 "memory_operand" "")
9126 (match_operand:SF 1 "register_operand" "fr"))
9127 (set (match_operand:SF 2 "memory_operand" "")
9128 (match_operand:SF 3 "register_operand" "fr"))]
9129 "registers_ok_for_ldd_peep (operands[1], operands[3])
9130 && ! MEM_VOLATILE_P (operands[0])
9131 && ! MEM_VOLATILE_P (operands[2])
9132 && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
9136 [(set (match_operand:SI 0 "register_operand" "=rf")
9137 (match_operand:SI 1 "memory_operand" ""))
9138 (set (match_operand:SI 2 "register_operand" "=rf")
9139 (match_operand:SI 3 "memory_operand" ""))]
9140 "registers_ok_for_ldd_peep (operands[2], operands[0])
9141 && ! MEM_VOLATILE_P (operands[3])
9142 && ! MEM_VOLATILE_P (operands[1])
9143 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9147 [(set (match_operand:SI 0 "memory_operand" "")
9148 (match_operand:SI 1 "register_operand" "rf"))
9149 (set (match_operand:SI 2 "memory_operand" "")
9150 (match_operand:SI 3 "register_operand" "rf"))]
9151 "registers_ok_for_ldd_peep (operands[3], operands[1])
9152 && ! MEM_VOLATILE_P (operands[2])
9153 && ! MEM_VOLATILE_P (operands[0])
9154 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9158 [(set (match_operand:SF 0 "register_operand" "=fr")
9159 (match_operand:SF 1 "memory_operand" ""))
9160 (set (match_operand:SF 2 "register_operand" "=fr")
9161 (match_operand:SF 3 "memory_operand" ""))]
9162 "registers_ok_for_ldd_peep (operands[2], operands[0])
9163 && ! MEM_VOLATILE_P (operands[3])
9164 && ! MEM_VOLATILE_P (operands[1])
9165 && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
9169 [(set (match_operand:SF 0 "memory_operand" "")
9170 (match_operand:SF 1 "register_operand" "fr"))
9171 (set (match_operand:SF 2 "memory_operand" "")
9172 (match_operand:SF 3 "register_operand" "fr"))]
9173 "registers_ok_for_ldd_peep (operands[3], operands[1])
9174 && ! MEM_VOLATILE_P (operands[2])
9175 && ! MEM_VOLATILE_P (operands[0])
9176 && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
9179 ;; Optimize the case of following a reg-reg move with a test
9180 ;; of reg just moved. Don't allow floating point regs for operand 0 or 1.
9181 ;; This can result from a float to fix conversion.
9184 [(set (match_operand:SI 0 "register_operand" "=r")
9185 (match_operand:SI 1 "register_operand" "r"))
9187 (compare:CC (match_operand:SI 2 "register_operand" "r")
9189 "(rtx_equal_p (operands[2], operands[0])
9190 || rtx_equal_p (operands[2], operands[1]))
9191 && ! FP_REG_P (operands[0])
9192 && ! FP_REG_P (operands[1])"
9196 [(set (match_operand:DI 0 "register_operand" "=r")
9197 (match_operand:DI 1 "register_operand" "r"))
9199 (compare:CCX (match_operand:DI 2 "register_operand" "r")
9202 && (rtx_equal_p (operands[2], operands[0])
9203 || rtx_equal_p (operands[2], operands[1]))
9204 && ! FP_REG_P (operands[0])
9205 && ! FP_REG_P (operands[1])"
9208 ;; Return peepholes. First the "normal" ones.
9209 ;; These are necessary to catch insns ending up in the epilogue delay list.
9211 (define_insn "*return_qi"
9212 [(set (match_operand:QI 0 "restore_operand" "")
9213 (match_operand:QI 1 "arith_operand" "rI"))
9218 if (! TARGET_ARCH64 && current_function_returns_struct)
9219 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9220 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9221 || IN_OR_GLOBAL_P (operands[1])))
9222 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9224 return \"ret\\n\\trestore %%g0, %1, %Y0\";
9226 [(set_attr "type" "multi")])
9228 (define_insn "*return_hi"
9229 [(set (match_operand:HI 0 "restore_operand" "")
9230 (match_operand:HI 1 "arith_operand" "rI"))
9235 if (! TARGET_ARCH64 && current_function_returns_struct)
9236 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9237 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9238 || IN_OR_GLOBAL_P (operands[1])))
9239 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9241 return \"ret\;restore %%g0, %1, %Y0\";
9243 [(set_attr "type" "multi")])
9245 (define_insn "*return_si"
9246 [(set (match_operand:SI 0 "restore_operand" "")
9247 (match_operand:SI 1 "arith_operand" "rI"))
9252 if (! TARGET_ARCH64 && current_function_returns_struct)
9253 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9254 else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
9255 || IN_OR_GLOBAL_P (operands[1])))
9256 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9258 return \"ret\;restore %%g0, %1, %Y0\";
9260 [(set_attr "type" "multi")])
9262 ;; The following pattern is only generated by delayed-branch scheduling,
9263 ;; when the insn winds up in the epilogue. This can happen not only when
9264 ;; ! TARGET_FPU because we move complex types around by parts using
9266 (define_insn "*return_sf_no_fpu"
9267 [(set (match_operand:SF 0 "restore_operand" "=r")
9268 (match_operand:SF 1 "register_operand" "r"))
9273 if (! TARGET_ARCH64 && current_function_returns_struct)
9274 return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\";
9275 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9276 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9278 return \"ret\;restore %%g0, %1, %Y0\";
9280 [(set_attr "type" "multi")])
9282 (define_insn "*return_df_no_fpu"
9283 [(set (match_operand:DF 0 "restore_operand" "=r")
9284 (match_operand:DF 1 "register_operand" "r"))
9286 "! TARGET_EPILOGUE && TARGET_ARCH64"
9289 if (IN_OR_GLOBAL_P (operands[1]))
9290 return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\";
9292 return \"ret\;restore %%g0, %1, %Y0\";
9294 [(set_attr "type" "multi")])
9296 (define_insn "*return_addsi"
9297 [(set (match_operand:SI 0 "restore_operand" "")
9298 (plus:SI (match_operand:SI 1 "register_operand" "r")
9299 (match_operand:SI 2 "arith_operand" "rI")))
9304 if (! TARGET_ARCH64 && current_function_returns_struct)
9305 return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\";
9306 /* If operands are global or in registers, can use return */
9307 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
9308 && (GET_CODE (operands[2]) == CONST_INT
9309 || IN_OR_GLOBAL_P (operands[2])))
9310 return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\";
9312 return \"ret\;restore %r1, %2, %Y0\";
9314 [(set_attr "type" "multi")])
9316 (define_insn "*return_losum_si"
9317 [(set (match_operand:SI 0 "restore_operand" "")
9318 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
9319 (match_operand:SI 2 "immediate_operand" "in")))
9321 "! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9324 if (! TARGET_ARCH64 && current_function_returns_struct)
9325 return \"jmp\\t%%i7+12\\n\\trestore %r1, %%lo(%a2), %Y0\";
9326 /* If operands are global or in registers, can use return */
9327 else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
9328 return \"return\\t%%i7+8\\n\\tor\\t%Y1, %%lo(%a2), %Y0\";
9330 return \"ret\;restore %r1, %%lo(%a2), %Y0\";
9332 [(set_attr "type" "multi")])
9334 (define_insn "*return_di"
9335 [(set (match_operand:DI 0 "restore_operand" "")
9336 (match_operand:DI 1 "arith_double_operand" "rHI"))
9338 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9339 "ret\;restore %%g0, %1, %Y0"
9340 [(set_attr "type" "multi")])
9342 (define_insn "*return_adddi"
9343 [(set (match_operand:DI 0 "restore_operand" "")
9344 (plus:DI (match_operand:DI 1 "arith_operand" "%r")
9345 (match_operand:DI 2 "arith_double_operand" "rHI")))
9347 "TARGET_ARCH64 && ! TARGET_EPILOGUE"
9348 "ret\;restore %r1, %2, %Y0"
9349 [(set_attr "type" "multi")])
9351 (define_insn "*return_losum_di"
9352 [(set (match_operand:DI 0 "restore_operand" "")
9353 (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
9354 (match_operand:DI 2 "immediate_operand" "in")))
9356 "TARGET_ARCH64 && ! TARGET_EPILOGUE && ! TARGET_CM_MEDMID"
9357 "ret\;restore %r1, %%lo(%a2), %Y0"
9358 [(set_attr "type" "multi")])
9360 ;; The following pattern is only generated by delayed-branch scheduling,
9361 ;; when the insn winds up in the epilogue.
9362 (define_insn "*return_sf"
9364 (match_operand:SF 0 "register_operand" "f"))
9367 "ret\;fmovs\\t%0, %%f0"
9368 [(set_attr "type" "multi")])
9370 ;; Now peepholes to do a call followed by a jump.
9373 [(parallel [(set (match_operand 0 "" "")
9374 (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
9375 (match_operand 2 "" "")))
9376 (clobber (reg:SI 15))])
9377 (set (pc) (label_ref (match_operand 3 "" "")))]
9378 "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9379 && in_same_eh_region (insn, operands[3])
9380 && in_same_eh_region (insn, ins1)"
9381 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9384 [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
9385 (match_operand 1 "" ""))
9386 (clobber (reg:SI 15))])
9387 (set (pc) (label_ref (match_operand 2 "" "")))]
9388 "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9389 && in_same_eh_region (insn, operands[2])
9390 && in_same_eh_region (insn, ins1)"
9391 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9394 [(parallel [(set (match_operand 0 "" "")
9395 (call (mem:SI (match_operand:DI 1 "call_operand_address" "ps"))
9396 (match_operand 2 "" "")))
9397 (clobber (reg:DI 15))])
9398 (set (pc) (label_ref (match_operand 3 "" "")))]
9400 && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
9401 && in_same_eh_region (insn, operands[3])
9402 && in_same_eh_region (insn, ins1)"
9403 "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
9406 [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps"))
9407 (match_operand 1 "" ""))
9408 (clobber (reg:DI 15))])
9409 (set (pc) (label_ref (match_operand 2 "" "")))]
9411 && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
9412 && in_same_eh_region (insn, operands[2])
9413 && in_same_eh_region (insn, ins1)"
9414 "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
9416 ;; After a nonlocal goto, we need to restore the PIC register, but only
9417 ;; if we need it. So do nothing much here, but we'll check for this in
9420 ;; Make sure this unspec_volatile number agrees with finalize_pic.
9421 (define_insn "nonlocal_goto_receiver"
9422 [(unspec_volatile [(const_int 0)] 5)]
9425 [(set_attr "length" "0")])
9428 [(trap_if (const_int 1) (const_int 5))]
9431 [(set_attr "type" "misc")
9432 (set_attr "length" "1")])
9434 (define_expand "conditional_trap"
9435 [(trap_if (match_operator 0 "noov_compare_op"
9436 [(match_dup 2) (match_dup 3)])
9437 (match_operand:SI 1 "arith_operand" ""))]
9439 "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
9440 sparc_compare_op0, sparc_compare_op1);
9441 operands[3] = const0_rtx;")
9444 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
9445 (match_operand:SI 1 "arith_operand" "rM"))]
9448 [(set_attr "type" "misc")
9449 (set_attr "length" "1")])
9452 [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
9453 (match_operand:SI 1 "arith_operand" "rM"))]
9456 [(set_attr "type" "misc")
9457 (set_attr "length" "1")])